This repository has been archived by the owner on Dec 31, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
steram.go
136 lines (113 loc) · 3.4 KB
/
steram.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
package cmd
import (
"os"
"os/signal"
"time"
"github.com/ChimeraCoder/anaconda"
"github.com/arrow2nd/ishell"
"github.com/arrow2nd/twnyan/api"
)
func (cmd *Cmd) newStreamCmd() *ishell.Cmd {
return &ishell.Cmd{
Name: "stream",
Aliases: []string{"st"},
Func: cmd.execStreamCmd,
Help: "start a pseudo-UserStream",
LongHelp: createLongHelp(
"After accumulating up to 250 tweets in the first minute, the tweets will be displayed with a one-minute delay, just like the UserStream API.\nCtrl+C to exit.",
"st",
"stream",
"",
),
}
}
func (cmd *Cmd) execStreamCmd(c *ishell.Context) {
tweets, sinceId, err := cmd.fetchHomeTimelineTweets("25", "")
if err != nil {
cmd.showErrorMessage(err.Error())
return
}
// タイムラインを表示
cmd.view.ShowTweetsFromArray(*tweets, false)
// Ctrl+Cが入力されたら通知する
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
go cmd.startUserStream(sinceId, quit)
// 通知が来たら終了
<-quit
signal.Stop(quit)
close(quit)
}
// startUserStream 疑似UserStreamを開始
func (cmd *Cmd) startUserStream(startSinceId string, quit chan os.Signal) {
var (
accumulateTweets AccumulateTweets
err error
sinceId = startSinceId
)
for {
for i := 0; i < 60; i++ {
select {
case <-quit:
// 中断された
return
default:
// 蓄積したツイートを表示
accumulateTweets = cmd.showAccumulateTweet(accumulateTweets)
}
time.Sleep(1 * time.Second)
}
// 次の60秒間に表示するツイートを取得
accumulateTweets, sinceId, err = cmd.createNewAccumulateTweets(sinceId)
if err != nil {
cmd.showErrorMessage(err.Error())
}
}
}
// showAccumulateTweet 蓄積されたツイートを表示
func (cmd *Cmd) showAccumulateTweet(accumulateTweets AccumulateTweets) AccumulateTweets {
nowTime := time.Now().Local().Unix()
for displayTiming, tweet := range accumulateTweets {
if displayTiming <= nowTime {
cmd.view.ShowTweet(&tweet, " ", false)
delete(accumulateTweets, displayTiming)
}
}
return accumulateTweets
}
// createNewAccumulateTweets 新しい蓄積データを作成する
func (cmd *Cmd) createNewAccumulateTweets(sinceId string) (AccumulateTweets, string, error) {
tweets, newSinceId, err := cmd.fetchHomeTimelineTweets("200", sinceId)
if err != nil {
return nil, sinceId, err
}
// 画面に表示するタイミング(時間)をキーとした連想配列
accumulateTweets := make(AccumulateTweets, len(*tweets))
// 投稿時間の1分後をキーにして連想配列を作成
for _, tweet := range *tweets {
createdAtTime, _ := tweet.CreatedAtTime()
displayTiming := createdAtTime.Add(1 * time.Minute).Local().Unix()
accumulateTweets[displayTiming] = tweet
}
return accumulateTweets, newSinceId, nil
}
// fetchHomeTimelineTweets ホームタイムラインのツイートを取得
func (cmd *Cmd) fetchHomeTimelineTweets(count, sinceId string) (*[]anaconda.Tweet, string, error) {
// 取得件数が指定されていないならデフォルト値を代入
if count == "" {
count = cmd.cfg.Option.Counts
}
query := api.CreateQuery(count)
if sinceId != "" {
query.Add("since_id", sinceId)
}
tweets, err := cmd.api.FetchTimelineTweets("home", query)
if err != nil {
return nil, sinceId, err
}
newSinceId := sinceId
if len(*tweets) > 0 {
newSinceId = (*tweets)[0].IdStr
}
return tweets, newSinceId, nil
}