-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
153 lines (137 loc) · 3.78 KB
/
main.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/Songmu/prompter"
"github.com/kurrik/oauth1a"
"github.com/kurrik/twittergo"
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"time"
)
const ScreenName string = "JIDORI_OHASHI"
var TwitterCredentialFile string = os.Getenv("HOME") + "/.TWITTER_CREDENTIALS"
type tweetModel struct {
Text string `json:"text"`
IdStr string `json:"id_str"`
}
func (t *tweetModel) URL() string {
return "https://twitter.com/" + ScreenName + "/status/" + t.IdStr
}
type tweetViewModel struct {
Text string `json:"text"`
URL string `json:"url"`
}
func InitCredentials() {
consumerKey := prompter.Prompt("Enter your Twitter Application Consumer Key", "")
consumerSecret := prompter.Prompt("Enter your Twitter Application Consumer Secret", "")
accessToken := prompter.Prompt("Enter your Twitter Application Access Token", "")
accessTokenSecret := prompter.Prompt("Enter your Twitter Application Access Token Secret", "")
bf := bytes.NewBufferString(consumerKey + "\n" + consumerSecret + "\n" + accessToken + "\n" + accessTokenSecret)
err := ioutil.WriteFile(TwitterCredentialFile, bf.Bytes(), 0600)
if err != nil {
fmt.Errorf("%s", err.Error())
os.Exit(1)
return
}
}
func LoadCredentials() (client *twittergo.Client, err error) {
credentials, err := ioutil.ReadFile(TwitterCredentialFile)
if err != nil {
return
}
lines := strings.Split(string(credentials), "\n")
config := &oauth1a.ClientConfig{
ConsumerKey: lines[0],
ConsumerSecret: lines[1],
}
user := oauth1a.NewAuthorizedConfig(lines[2], lines[3])
client = twittergo.NewClient(config, user)
return
}
func main() {
if len(os.Args) >= 3 {
fmt.Println("Invalid argument count")
os.Exit(1)
}
if len(os.Args) == 2 && os.Args[1] == "init" {
InitCredentials()
}
var (
err error
client *twittergo.Client
req *http.Request
resp *twittergo.APIResponse
max_id uint64
query url.Values
results *twittergo.Timeline
text []byte
)
if client, err = LoadCredentials(); err != nil {
fmt.Printf("Could not parse TwitterCredentialFile: %v\n", err)
os.Exit(1)
}
const (
count int = 1
urltmpl = "/1.1/statuses/user_timeline.json?%v"
minwait = time.Duration(10) * time.Second
)
query = url.Values{}
query.Set("count", fmt.Sprintf("%v", count))
query.Set("screen_name", ScreenName)
if max_id != 0 {
query.Set("max_id", fmt.Sprintf("%v", max_id))
}
endpoint := fmt.Sprintf(urltmpl, query.Encode())
if req, err = http.NewRequest("GET", endpoint, nil); err != nil {
fmt.Printf("Could not parse request: %v\n", err)
os.Exit(1)
}
if resp, err = client.SendRequest(req); err != nil {
fmt.Printf("Could not send request: %v\n", err)
os.Exit(1)
}
results = &twittergo.Timeline{}
if err = resp.Parse(results); err != nil {
if rle, ok := err.(twittergo.RateLimitError); ok {
dur := rle.Reset.Sub(time.Now()) + time.Second
if dur < minwait {
// Don't wait less than minwait.
dur = minwait
}
msg := "Rate limited. Reset at %v. Waiting for %v\n"
fmt.Printf(msg, rle.Reset, dur)
os.Exit(-1)
} else {
fmt.Printf("Problem parsing response: %v\n", err)
}
}
batch := len(*results)
if batch == 0 {
fmt.Printf("No more results, end of timeline.\n")
os.Exit(-1)
}
for _, tweet := range *results {
if text, err = json.Marshal(tweet); err != nil {
fmt.Printf("Could not encode Tweet: %v\n", err)
os.Exit(1)
}
}
t := &tweetModel{}
if err = json.Unmarshal(text, t); err != nil {
fmt.Printf("Could not decode Tweet: %v\n", err)
os.Exit(1)
}
if text, err = json.Marshal(tweetViewModel{t.Text, t.URL()}); err != nil {
fmt.Printf("Could not encode Tweet: %v\n", err)
os.Exit(1)
}
fmt.Printf("%s\n", text)
//if resp.HasRateLimit() {
// fmt.Printf(", %v calls available", resp.RateLimitRemaining())
//}
}