-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmastobots.go
More file actions
164 lines (145 loc) · 4.22 KB
/
mastobots.go
File metadata and controls
164 lines (145 loc) · 4.22 KB
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
154
155
156
157
158
159
160
161
162
163
164
package mastobots
import (
"context"
"log"
"os/exec"
"strconv"
"time"
"github.com/comail/colog"
"github.com/ringsaturn/tzf"
"github.com/spf13/viper"
)
var (
version = "1"
f tzf.F
)
type commonSettings struct {
maxRetry int
retryInterval time.Duration
yahooClientID string
weatherKey string
langJobPool chan int
}
// Initialize は、config.ymlに従ってbotとデータベース接続を初期化する。
func Initialize() (bots []*Persona, db DB, err error) {
// colog 設定
if version == "" {
colog.SetDefaultLevel(colog.LDebug)
colog.SetMinLevel(colog.LTrace)
colog.SetFormatter(&colog.StdFormatter{
Colors: true,
Flag: log.Ldate | log.Ltime | log.Lshortfile,
})
} else {
colog.SetDefaultLevel(colog.LDebug)
colog.SetMinLevel(colog.LInfo)
colog.SetFormatter(&colog.StdFormatter{
Colors: true,
Flag: log.Ldate | log.Ltime,
})
}
colog.Register()
// 依存アプリの存在確認
for _, cmd := range []string{"jumanpp", "mysql"} {
_, err := exec.LookPath(cmd)
if err != nil {
log.Printf("alert: %s がインストールされていません!", cmd)
return nil, db, err
}
}
var cr map[string]string
// bot設定ファイル読み込み
conf := viper.New()
conf.SetConfigName("config")
conf.AddConfigPath(".")
conf.SetConfigType("yaml")
if err := conf.ReadInConfig(); err != nil {
log.Printf("alert: 設定ファイルが読み込めませんでした")
return nil, db, err
}
conf.UnmarshalKey("Personae", &bots)
var cmn commonSettings
cmn.maxRetry = 5
cmn.retryInterval = time.Duration(5) * time.Second
cmn.yahooClientID = conf.GetString("YahooClientID")
cmn.weatherKey = conf.GetString("OpenWeatherMapKey")
nOfJobs := conf.GetInt("NumConcurrentLangJobs")
if nOfJobs <= 0 {
nOfJobs = 1
} else if nOfJobs > 10 {
nOfJobs = 10
}
cmn.langJobPool = make(chan int, nOfJobs)
for _, bot := range bots {
bot.commonSettings = &cmn
}
cr = conf.GetStringMapString("DBCredentials")
// botをMastodonサーバに接続し、アカウントIDを取得
for _, bot := range bots {
if err := bot.getMastoID(); err != nil {
log.Printf("alert: %s のMastodonアカウントIDができませんでした。終了します", bot.Name)
return nil, db, err
}
}
// データベースへの接続
db, err = newDB(cr)
if err != nil {
log.Printf("alert: データベースへの接続が確保できませんでした")
return nil, db, err
}
// botがまだデータベースに登録されていなかったら登録
if err = db.addNewBots(bots); err != nil {
log.Printf("alert: データベースにbotが登録できませんでした")
return nil, db, err
}
// botのデータベース上のIDを取得
for _, bot := range bots {
id, err := db.botID(bot)
if err != nil {
log.Printf("alert: botのデータベース上のIDが取得できませんでした")
return nil, db, err
}
bot.DBID = id
}
// TZF(グローバル変数に設定)を初期化
f, err = tzf.NewDefaultFinder()
if err != nil {
log.Printf("info: %s", err)
return nil, db, err
}
// botの住処を登録
for _, bot := range bots {
if bot.LivesWithSun {
log.Printf("info: %s の所在地を設定しています……", bot.Name)
time.Sleep(1001 * time.Millisecond)
bot.PlaceName, bot.TimeZone, err = getLocDataFromCoordinates(bot.commonSettings.yahooClientID, bot.Latitude, bot.Longitude)
if err != nil {
log.Printf("alert: %s の所在地情報の設定に失敗しました:%s", bot.Name, err)
return nil, db, err
}
}
}
f = nil
return
}
// ActivateBots は、botたちを活動させる。
func ActivateBots(bots []*Persona, db DB, p int) (err error) {
// 全てをシャットダウンするタイムアウトの設定
ctx := context.Background()
var cancel context.CancelFunc
msg := "mastobots、時間無制限でスタートです!"
if p > 0 {
msg = "mastobots、" + strconv.Itoa(p) + "分間動きます!"
dur := time.Duration(p) * time.Minute
ctx, cancel = context.WithTimeout(ctx, dur)
defer cancel()
}
log.Printf("info: " + msg)
// 行ってらっしゃい
for _, bot := range bots {
go bot.spawn(ctx, db, true, false)
}
<-ctx.Done()
log.Printf("info: %d分経ったのでシャットダウンします", p)
return
}