1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
// Flickr50 -- given a search term, display 10x5 image grid, sorted by interestingness
package main
import (
"encoding/xml"
"fmt"
"net/http"
"net/url"
"os"
"github.com/ajstarks/svgo"
)
type FlickrResp struct {
Stat string `xml:"stat,attr"`
Photos Photos `xml:"photos"`
}
type Photos struct {
Page string `xml:"page,attr"`
Pages string `xml:"pages,attr"`
Perpage string `xml:"perpage,attr"`
Total string `xml:"total,attr"`
Photo []Photo `xml:"photo"`
}
type Photo struct {
Id string `xml:"id,attr"`
Owner string `xml:"owner,attr"`
Secret string `xml:"secret,attr"`
Server string `xml:"server,attr"`
Farm string `xml:"farm,attr"`
Title string `xml:"title,attr"`
Ispublic string `xml:"ispublic,attr"`
Isfriend string `xml:"isfriend,attr"`
IsFamily string `xml:"isfamily,attr"`
}
var (
width = 805
height = 500
canvas = svg.New(os.Stdout)
)
const (
apifmt = "http://api.flickr.com/services/rest/?method=%s&api_key=%s&%s=%s&per_page=50&sort=interestingness-desc"
urifmt = "http://farm%s.static.flickr.com/%s/%s.jpg"
apiKey = "YOURKEY"
textStyle = "font-family:Calibri,sans-serif; font-size:48px; fill:white; text-anchor:start"
imageWidth = 75
imageHeight = 75
)
// FlickrAPI calls the API given a method with single name/value pair
func flickrAPI(method, name, value string) string {
return fmt.Sprintf(apifmt, method, apiKey, name, value)
}
// makeURI converts the elements of a photo into a Flickr photo URI
func makeURI(p Photo, imsize string) string {
im := p.Id + "_" + p.Secret
if len(imsize) > 0 {
im += "_" + imsize
}
return fmt.Sprintf(urifmt, p.Farm, p.Server, im)
}
// imageGrid reads the response from Flickr, and creates a grid of images
func imageGrid(f FlickrResp, x, y, cols, gutter int, imgsize string) {
if f.Stat != "ok" {
fmt.Fprintf(os.Stderr, "Status: %v\n", f.Stat)
return
}
xpos := x
for i, p := range f.Photos.Photo {
if i%cols == 0 && i > 0 {
xpos = x
y += (imageHeight + gutter)
}
canvas.Link(makeURI(p, ""), p.Title)
canvas.Image(xpos, y, imageWidth, imageHeight, makeURI(p, "s"))
canvas.LinkEnd()
xpos += (imageWidth + gutter)
}
}
// fs calls the Flickr API to perform a photo search
func fs(s string) {
var f FlickrResp
r, weberr := http.Get(flickrAPI("flickr.photos.search", "text", s))
if weberr != nil {
fmt.Fprintf(os.Stderr, "%v\n", weberr)
return
}
defer r.Body.Close()
xmlerr := xml.NewDecoder(r.Body).Decode(&f)
if xmlerr != nil || r.StatusCode != http.StatusOK {
fmt.Fprintf(os.Stderr, "%v (status=%d)\n", xmlerr, r.StatusCode)
return
}
canvas.Title(s)
imageGrid(f, 5, 5, 10, 5, "s")
canvas.Text(20, height-40, s, textStyle)
}
// for each search term on the commandline, create a photo grid
func main() {
for i := 1; i < len(os.Args); i++ {
canvas.Start(width, height)
canvas.Rect(0, 0, width, height, "fill:black")
fs(url.QueryEscape(os.Args[i]))
canvas.End()
}
}
|