Skip to content

Instantly share code, notes, and snippets.

@mukulrawat1986
Created October 10, 2015 10:29
Show Gist options
  • Save mukulrawat1986/d8a35f7db6bf23baf64b to your computer and use it in GitHub Desktop.
Save mukulrawat1986/d8a35f7db6bf23baf64b to your computer and use it in GitHub Desktop.
// simple program to use json and download images from a subreddit
package main
import (
"encoding/json"
"errors"
"fmt"
"image"
"image/gif"
"image/jpeg"
"image/png"
"io/ioutil"
"log"
"net/http"
"os"
"time"
)
type Item struct {
Title string
URL string
Is_self bool
}
type Response struct {
Data struct {
Children []struct {
Data Item
}
After string
Before string
}
}
func (i Item) String() string {
return fmt.Sprintf("%s\n%s\n%v", i.Title, i.URL, i.Is_self)
}
func decode(subreddit string) ([]Item, error) {
url := fmt.Sprintf("http://www.reddit.com/r/%s.json", subreddit)
r, err := http.Get(url)
if err != nil {
return nil, err
}
defer r.Body.Close()
if r.StatusCode != http.StatusOK {
return nil, errors.New(r.Status)
}
resp := new(Response)
err = json.NewDecoder(r.Body).Decode(resp)
if err != nil {
return nil, err
}
items := make([]Item, len(resp.Data.Children))
for i, child := range resp.Data.Children {
items[i] = child.Data
}
// after := resp.Data.After
// fmt.Printf("%s\n", after)
return items, nil
}
func init() {
image.RegisterFormat("png", "png", png.Decode, png.DecodeConfig)
image.RegisterFormat("jpeg", "jpeg", jpeg.Decode, jpeg.DecodeConfig)
image.RegisterFormat("gif", "gif", gif.Decode, gif.DecodeConfig)
}
func download_images(url string, title string, sema chan bool) {
fmt.Println("Go routine waiting to start")
// We will not start work until we get something from the channel
<-sema
// Make a http Get request to the url
// We get back a response and an error
r, err := http.Get(url)
if err != nil {
log.Fatalf("http.Get error %v", err)
//return err
}
// We read all the bytes of the image
data, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatalf("io.ReadAll error %v", err)
//return err
}
// close the response body
r.Body.Close()
// Create a temp file to store image
file, err := ioutil.TempFile(os.TempDir(), "prefix")
defer os.Remove(file.Name())
if err != nil {
log.Fatalf("tempfile creating error %v", err)
}
// Store image in temp file
ioutil.WriteFile(file.Name(), data, 0666)
// Open temp file
f, _ := os.Open(file.Name())
defer f.Close()
// Find out format of image
_, format, _ := image.Decode(f)
if format == "jpeg" || format == "png" || format == "gif" {
// Now we save the file to disk
filename := fmt.Sprintf("(%s).%s", title, format)
log.Println("Saving image ", title)
ioutil.WriteFile(filename, data, 0666)
}
sema <- true
}
func main() {
// Call the Get function to get our structs filled with reddit data
items, err := decode("aww")
if err != nil {
log.Fatalf("Error while decoding %v", err)
}
// Create a channel of booleans. The capacity of the channel will decide,
// how many goroutines will be working at any point
sema := make(chan bool, 5)
// Download images from the link
for _, item := range items {
if !item.Is_self {
go download_images(item.URL, item.Title, sema)
} else {
continue
}
}
// Activate go routines
for i := 0; i < cap(sema); i++ {
sema <- true
}
time.Sleep(40 * time.Second)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment