Browse Source

Make bot automatically fill in averages

Toni Fadjukoff 7 years ago
parent
commit
01682bef79
1 changed files with 138 additions and 3 deletions
  1. 138 3
      bot.go

+ 138 - 3
bot.go View File

@@ -117,13 +117,13 @@ func getSongs() (SongPriorityQueue, error) {
117 117
 	return songs, nil
118 118
 }
119 119
 
120
-func task() {
120
+func submitSong() {
121 121
 	now := time.Now()
122 122
 	if len(songs) > 0 && songs[0].time.Before(now) {
123 123
 		fmt.Println("Time has passed for " + songs[0].song)
124 124
 		success, err := addSong("Levyraati 2018", songs[0].week, "Lamperi", songs[0].song)
125 125
 		if err != nil {
126
-			log.Fatal(err)
126
+			log.Println("Error while adding song:", err)
127 127
 		}
128 128
 		if success {
129 129
 			err := songSynced(songs[0].week)
@@ -136,6 +136,139 @@ func task() {
136 136
 	}
137 137
 }
138 138
 
139
+func isCurrentAuthor(line, author string) bool {
140
+	authorIndex := strings.Index(line, author)
141
+	endIndex := strings.Index(line, "-->")
142
+	return authorIndex != -1 && authorIndex < endIndex
143
+}
144
+
145
+func parseScore(line string) string {
146
+	parts := strings.Split(line, "-->")
147
+	if len(parts) < 2 {
148
+		return ""
149
+	}
150
+	score := strings.TrimRight(strings.Trim(parts[1], " \t\n"), "p")
151
+	if score == "" {
152
+		return score
153
+	}
154
+	number, _ := regexp.Compile("^\\d([.,]\\d)?$")
155
+	if number.MatchString(score) {
156
+		return strings.Replace(score, ",", ".", 1)
157
+	}
158
+	numberHalf, _ := regexp.Compile("^\\d½$")
159
+	if numberHalf.MatchString(score) {
160
+		return fmt.Sprintf("%c.5", score[0])
161
+	}
162
+	stars, _ := regexp.Compile("^\\*+$")
163
+	if stars.MatchString(score) {
164
+		return fmt.Sprintf("%d", len(score))
165
+	}
166
+	imageStars, _ := regexp.Compile("^(\\[\\[Image:[01]\\.png\\]\\]){5}$")
167
+	if imageStars.MatchString(score) {
168
+		return fmt.Sprintf("%d", strings.Count(score, "1"))
169
+	}
170
+	quarterScore, _ := regexp.Compile("^\\d-\\d½?$")
171
+	if quarterScore.MatchString(score) {
172
+		return fmt.Sprintf("%c.25", score[0])
173
+	}
174
+	thirdQuarterScore, _ := regexp.Compile("^\\d½?-\\d$")
175
+	if thirdQuarterScore.MatchString(score) {
176
+		return fmt.Sprintf("%c.75", score[0])
177
+	}
178
+	fmt.Printf("Could not match '%s'\n", score)
179
+	return ""
180
+}
181
+
182
+func appendAverages(wikiText string) string {
183
+	const AUTHOR_MARK = "<!-- Lisääjä -->"
184
+	const SONG_MARK = "<!-- Kappale -->"
185
+	const AVERAGE_MARK = "<!-- KA -->"
186
+	lines := strings.Split(wikiText, "\n")
187
+	isScore := false
188
+	scores := make([]string, 0)
189
+	count := 0
190
+	currentAuthor := ""
191
+
192
+	changedLines := make([]string, 0, len(lines))
193
+	for _, line := range lines {
194
+		if strings.Index(line, AUTHOR_MARK) != -1 {
195
+			currentAuthor = strings.Trim(strings.Split(line, AUTHOR_MARK)[1], " \t")
196
+		} else if strings.Index(line, SONG_MARK) != -1 {
197
+			isScore = true
198
+			scores = make([]string, 0)
199
+			count = 0
200
+		} else if isScore && strings.Index(line, AVERAGE_MARK) == -1 {
201
+			if !isCurrentAuthor(line, currentAuthor) {
202
+				score := parseScore(line)
203
+				if score != "" {
204
+					scores = append(scores, score)
205
+					count += 1
206
+				} else {
207
+					scores = append(scores, "0")
208
+				}
209
+
210
+			}
211
+		}
212
+		if strings.Index(line, AVERAGE_MARK) != -1 {
213
+			expression := fmt.Sprintf("'''{{#expr:(%s)/%d round 2}}'''", strings.Join(scores, "+"), count)
214
+			newLine := "| " + AVERAGE_MARK + " " + expression
215
+			changedLines = append(changedLines, newLine)
216
+			if newLine != line {
217
+				fmt.Printf("Difference for %s\n%s\n%s\n", currentAuthor, newLine, line)
218
+			}
219
+
220
+		} else {
221
+			changedLines = append(changedLines, line)
222
+		}
223
+	}
224
+	return strings.Join(changedLines, "\n")
225
+}
226
+
227
+func fixAverages(title string) error {
228
+	wiki := CreateWikiClient(credentials.APIURL, credentials.UserName, credentials.Password)
229
+
230
+	sections, err := wiki.GetWikiPageSections(title)
231
+	if err != nil {
232
+		return err
233
+	}
234
+
235
+	currentWeek := 2
236
+	numberReg, _ := regexp.Compile("\\d+")
237
+	for _, section := range sections {
238
+		weekStr := numberReg.FindString(section.title)
239
+		if weekStr != "" {
240
+			weekNumber, _ := strconv.Atoi(weekStr)
241
+			if weekNumber > currentWeek {
242
+				break
243
+			}
244
+
245
+			wikiText, err := wiki.GetWikiPageSectionText(title, section.index)
246
+			if err != nil {
247
+				return err
248
+			}
249
+			changedWikiText := appendAverages(wikiText)
250
+			if changedWikiText != wikiText {
251
+				//fmt.Println(wikiText)
252
+				//fmt.Println(changedWikiText)
253
+
254
+				_, err := wiki.EditWikiPageSection(title, section.index, changedWikiText,
255
+					fmt.Sprintf("Calculate averages for week %d", weekNumber))
256
+				if err != nil {
257
+					return err
258
+				}
259
+			}
260
+		}
261
+	}
262
+	return nil
263
+}
264
+
265
+func fixAveragesTask() {
266
+	err := fixAverages("Levyraati 2018")
267
+	if err != nil {
268
+		fmt.Println("Error while calculating averages:", err)
269
+	}
270
+}
271
+
139 272
 func initCreds() error {
140 273
 	f, err := os.Open("credentials.json")
141 274
 	if err != nil {
@@ -216,7 +349,9 @@ func main() {
216 349
 		}
217 350
 	}()
218 351
 
219
-	gocron.Every(1).Second().Do(task)
352
+	gocron.Every(1).Hour().Do(fixAveragesTask)
353
+
354
+	gocron.Every(1).Second().Do(submitSong)
220 355
 	<-gocron.Start()
221 356
 
222 357
 }