forked from mkouhei/golang-ajstarks-svgo-debian
/
tsg.go
125 lines (110 loc) · 2.67 KB
/
tsg.go
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
117
118
119
120
121
122
123
124
125
// tsg -- twitter search grid
package main
// +build !appengine
import (
"encoding/xml"
"flag"
"fmt"
"io"
"net/http"
"net/url"
"os"
"github.com/ajstarks/svgo"
)
var canvas = svg.New(os.Stdout)
// Feed is the Atom feed structure
type Feed struct {
XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
Entry []Entry `xml:"entry"`
}
// Entry defines an entry within an Aton feed
type Entry struct {
Link []Link `xml:"link"`
Title string `xml:"title"`
Author Person `xml:"author"`
}
// Link defines a link within an Atom feed
type Link struct {
Rel string `xml:"rel,attr"`
Href string `xml:"href,attr"`
}
// Person defines a person responsible for the tweet
type Person struct {
Name string `xml:"name"`
}
// Text defines the text of the tweet
type Text struct {
Type string `xml:",attr"`
Body string `xml:",chardata"`
}
var (
nresults = flag.Int("n", 100, "Maximum results (up to 100)")
since = flag.String("d", "", "Search since this date (YYYY-MM-DD)")
)
const (
queryURI = "http://search.twitter.com/search.atom?q=%s&since=%s&rpp=%d"
textfmt = "font-family:Calibri,Lucida,sans;fill:gray;text-anchor:middle;font-size:48px"
imw = 48
imh = 48
)
// ts dereferences the twitter search URL and reads the XML (Atom) response
func ts(s string, date string, n int) {
r, err := http.Get(fmt.Sprintf(queryURI, url.QueryEscape(s), date, n))
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
if r.StatusCode == http.StatusOK {
readatom(r.Body)
} else {
fmt.Fprintf(os.Stderr,
"Twitter is unable to search for %s (%s)\n", s, r.Status)
}
r.Body.Close()
}
// readatom unmarshals the twitter search response and formats the results into a grid
func readatom(r io.Reader) {
var twitter Feed
err := xml.NewDecoder(r).Decode(&twitter)
if err == nil {
tgrid(twitter, 25, 25, 50, 50, 10)
} else {
fmt.Fprintf(os.Stderr, "Unable to parse the Atom feed (%v)\n", err)
}
}
// tgrid makes a clickable grid of tweets from the Atom feed
func tgrid(t Feed, x, y, w, h, nc int) {
var slink, imlink string
xp := x
for i, entry := range t.Entry {
for _, link := range entry.Link {
switch link.Rel {
case "alternate":
slink = link.Href
case "image":
imlink = link.Href
}
}
if i%nc == 0 && i > 0 {
xp = x
y += h
}
canvas.Link(slink, slink)
canvas.Image(xp, y, imw, imh, imlink)
canvas.LinkEnd()
xp += w
}
}
// for every non-flag argument, make a twitter search grid
func main() {
flag.Parse()
width := 550
height := 700
canvas.Start(width, height)
for _, s := range flag.Args() {
canvas.Title("Twitter search for " + s)
ts(s, *since, *nresults)
canvas.Text(width/2, height-50, s, textfmt)
}
canvas.End()
}