4
4
"fmt"
5
5
"io"
6
6
"io/ioutil"
7
+ "log"
7
8
"os"
8
9
"strconv"
9
10
@@ -25,9 +26,10 @@ type TwitterConf struct {
25
26
Hash []string `yaml:"hash"`
26
27
}
27
28
28
- func check (e error ) {
29
- if e != nil {
30
- panic (e )
29
+ func closeFile (file * os.File ) {
30
+ err := file .Close ()
31
+ if err != nil {
32
+ log .Printf ("could not close file %s: %s" , file .Name (), err )
31
33
}
32
34
}
33
35
@@ -36,56 +38,93 @@ func check(e error) {
36
38
func WriteToFile (filename string , data string ) error {
37
39
file , err := os .Create (filename )
38
40
if err != nil {
39
- return err
41
+ return fmt . Errorf ( "could not open file: %s" , err )
40
42
}
41
- defer file . Close ( )
43
+ defer closeFile ( file )
42
44
43
45
_ , err = io .WriteString (file , data )
44
- check (err )
45
- return file .Sync ()
46
+ if err != nil {
47
+ return fmt .Errorf ("could not write string: %s" , err )
48
+ }
49
+ return nil
50
+ }
51
+
52
+ func getLastTweetID () (int64 , error ) {
53
+ lastTweetIdFile , err := os .Open ("lastTweetId" )
54
+ if err != nil {
55
+ return 0 , fmt .Errorf ("could not open lastTweetId: %s" , err )
56
+ }
57
+ defer closeFile (lastTweetIdFile )
58
+
59
+ lastTweetId , err := ioutil .ReadAll (lastTweetIdFile )
60
+ if err != nil {
61
+ return 0 , fmt .Errorf ("could not read lastTweetId content: %s" , err )
62
+ }
63
+
64
+ lastTweetIdValue , err := strconv .ParseInt (string (lastTweetId ), 10 , 64 )
65
+ if err != nil {
66
+ return 0 , fmt .Errorf ("could not parse lastTweetId content as int64: %s" , err )
67
+ }
68
+
69
+ return lastTweetIdValue , nil
46
70
}
47
71
48
72
func main () {
49
73
50
74
file , err := os .Open ("settings.yaml" )
51
75
if err != nil {
52
- panic ( err )
76
+ log . Fatalf ( "could not open file: %s" , err )
53
77
}
78
+ defer closeFile (file )
54
79
55
80
filecontent , err := ioutil .ReadAll (file )
56
- check (err )
81
+ if err != nil {
82
+ log .Fatalf ("could not read settings.yaml content: %s" , err )
83
+ }
57
84
58
85
var conf Configuration
59
86
err = yaml .Unmarshal (filecontent , & conf )
60
- check (err )
61
-
62
- fileReference , err := os .Open ("lastTweetId" )
63
- check (err )
87
+ if err != nil {
88
+ log .Fatalf ("could not unmarshal settings.yaml content: %s" , err )
89
+ }
64
90
65
- lastTweetId , err := ioutil .ReadAll (fileReference )
66
- check (err )
91
+ var lastTweetID int64
92
+ if id , err := getLastTweetID (); err != nil {
93
+ log .Printf ("could not get last tweet id: %s" , err )
94
+ } else {
95
+ lastTweetID = id
96
+ }
67
97
68
98
config := oauth1 .NewConfig (conf .Twitter .ConsumerKey , conf .Twitter .ConsumerSecret )
69
99
token := oauth1 .NewToken (conf .Twitter .OauthAccessToken , conf .Twitter .OauthAccessTokenSecret )
70
100
httpClient := config .Client (oauth1 .NoContext , token )
71
101
72
102
// Twitter client
73
103
client := twitter .NewClient (httpClient )
74
- lastTweetIdValue , err := strconv .ParseInt (string (lastTweetId ), 0 , 64 )
75
- check (err )
76
104
77
105
out := make (chan * twitter.Search )
78
106
79
107
for _ , h := range conf .Twitter .Hash {
80
108
go func (hash string ) {
81
109
// Search Tweets
82
- search , _ , err := client .Search .Tweets (& twitter.SearchTweetParams {
110
+
111
+ params := & twitter.SearchTweetParams {
83
112
Query : hash ,
84
113
Count : 5 ,
85
114
ResultType : "recent" ,
86
- SinceID : lastTweetIdValue ,
87
- })
88
- check (err )
115
+ }
116
+
117
+ if lastTweetID != 0 {
118
+ params .SinceID = lastTweetID
119
+ }
120
+
121
+ search , _ , err := client .Search .Tweets (params )
122
+ if err != nil {
123
+ log .Printf ("could not search tweets for hash '%s': %s" , hash , err )
124
+ // a search did not execute properly, send an empty object so we don't deadlock
125
+ out <- & twitter.Search {}
126
+ return
127
+ }
89
128
out <- search
90
129
}(h )
91
130
}
@@ -103,15 +142,21 @@ func main() {
103
142
fmt .Println (tweet .ID , tweet .Text )
104
143
105
144
var statusRetweetParam * twitter.StatusRetweetParams
106
- client .Statuses .Retweet (tweet .ID , statusRetweetParam )
107
-
145
+ _ , _ , err = client .Statuses .Retweet (tweet .ID , statusRetweetParam )
146
+ if err != nil {
147
+ log .Printf ("could not retweet for hash '%s': %s" , conf .Twitter .Hash [i ], err )
148
+ continue
149
+ }
108
150
}
109
151
}
110
152
close (out )
111
153
112
154
// Write latestTweetId to know where to start on next execution.
113
155
if 0 < len (tweetIds ) {
114
156
latestTweetId := strconv .Itoa (ix .MaxSlice (tweetIds ))
115
- WriteToFile ("lastTweetId" , latestTweetId )
157
+ err := WriteToFile ("lastTweetId" , latestTweetId )
158
+ if err != nil {
159
+ log .Fatalf ("could not write lastTweetId to file: %s" , err )
160
+ }
116
161
}
117
162
}
0 commit comments