|  | @@ -1,7 +1,6 @@
 | 
	
		
			
			| 1 | 1 |  package main
 | 
	
		
			
			| 2 | 2 |  
 | 
	
		
			
			| 3 | 3 |  import (
 | 
	
		
			
			| 4 |  | -	"container/heap"
 | 
	
		
			
			| 5 | 4 |  	"encoding/json"
 | 
	
		
			
			| 6 | 5 |  	"errors"
 | 
	
		
			
			| 7 | 6 |  	"fmt"
 | 
	
	
		
			
			|  | @@ -47,97 +46,99 @@ func appendSong(wikiText string, author string, newSong string) string {
 | 
	
		
			
			| 47 | 46 |  	return strings.Join(changedLines, "\n")
 | 
	
		
			
			| 48 | 47 |  }
 | 
	
		
			
			| 49 | 48 |  
 | 
	
		
			
			| 50 |  | -func addSong(title string, week int, author string, song string) (bool, error) {
 | 
	
		
			
			|  | 49 | +func addSong(updateTitle, updateSection, author, song string) (bool, error) {
 | 
	
		
			
			| 51 | 50 |  	wiki := CreateWikiClient(credentials.APIURL, credentials.UserName, credentials.Password)
 | 
	
		
			
			| 52 | 51 |  
 | 
	
		
			
			| 53 |  | -	sections, err := wiki.GetWikiPageSections(title)
 | 
	
		
			
			|  | 52 | +	sections, err := wiki.GetWikiPageSections(updateTitle)
 | 
	
		
			
			| 54 | 53 |  	if err != nil {
 | 
	
		
			
			| 55 | 54 |  		return false, err
 | 
	
		
			
			| 56 | 55 |  	}
 | 
	
		
			
			| 57 | 56 |  
 | 
	
		
			
			| 58 |  | -	numberReg, _ := regexp.Compile("\\d+")
 | 
	
		
			
			| 59 | 57 |  	for _, section := range sections {
 | 
	
		
			
			| 60 |  | -		weekStr := numberReg.FindString(section.title)
 | 
	
		
			
			| 61 |  | -		if weekStr != "" {
 | 
	
		
			
			| 62 |  | -			weekNumber, _ := strconv.Atoi(weekStr)
 | 
	
		
			
			| 63 |  | -			if weekNumber == week {
 | 
	
		
			
			| 64 |  | -				wikiText, err := wiki.GetWikiPageSectionText(title, section.index)
 | 
	
		
			
			| 65 |  | -				if err != nil {
 | 
	
		
			
			| 66 |  | -					return false, err
 | 
	
		
			
			| 67 |  | -				}
 | 
	
		
			
			| 68 |  | -				changedWikiText := appendSong(wikiText, author, song)
 | 
	
		
			
			|  | 58 | +		if updateSection == section.title {
 | 
	
		
			
			|  | 59 | +			wikiText, err := wiki.GetWikiPageSectionText(updateTitle, section.index)
 | 
	
		
			
			|  | 60 | +			if err != nil {
 | 
	
		
			
			|  | 61 | +				return false, err
 | 
	
		
			
			|  | 62 | +			}
 | 
	
		
			
			|  | 63 | +			changedWikiText := appendSong(wikiText, author, song)
 | 
	
		
			
			| 69 | 64 |  
 | 
	
		
			
			| 70 |  | -				return wiki.EditWikiPageSection(title, section.index, changedWikiText,
 | 
	
		
			
			| 71 |  | -					fmt.Sprintf("Added week %d song for %s", week, author))
 | 
	
		
			
			|  | 65 | +			if false {
 | 
	
		
			
			|  | 66 | +				// Stub
 | 
	
		
			
			|  | 67 | +				fmt.Println("Pretend to update wiki text to ", updateTitle, section.index, changedWikiText,
 | 
	
		
			
			|  | 68 | +					fmt.Sprintf("Added %s song for %s", updateSection, author))
 | 
	
		
			
			|  | 69 | +				return true, nil
 | 
	
		
			
			| 72 | 70 |  			}
 | 
	
		
			
			|  | 71 | +
 | 
	
		
			
			|  | 72 | +			return wiki.EditWikiPageSection(updateTitle, section.index, changedWikiText,
 | 
	
		
			
			|  | 73 | +				fmt.Sprintf("Added %s song for %s", updateSection, author))
 | 
	
		
			
			| 73 | 74 |  		}
 | 
	
		
			
			| 74 | 75 |  	}
 | 
	
		
			
			| 75 | 76 |  	return false, errors.New("Could not find matching section")
 | 
	
		
			
			| 76 | 77 |  }
 | 
	
		
			
			| 77 | 78 |  
 | 
	
		
			
			| 78 |  | -func songSynced(syncedWeek int) error {
 | 
	
		
			
			| 79 |  | -	v, err := loadDb()
 | 
	
		
			
			|  | 79 | +func songSynced(userId, roundId int) error {
 | 
	
		
			
			|  | 80 | +	query := `UPDATE public.entry SET synced = true WHERE user_id = $1 AND round_id = $2`
 | 
	
		
			
			|  | 81 | +	res, err := getDb().Exec(query, userId, roundId)
 | 
	
		
			
			|  | 82 | +
 | 
	
		
			
			| 80 | 83 |  	if err != nil {
 | 
	
		
			
			| 81 | 84 |  		return err
 | 
	
		
			
			| 82 | 85 |  	}
 | 
	
		
			
			| 83 | 86 |  
 | 
	
		
			
			| 84 |  | -	synced := false
 | 
	
		
			
			| 85 |  | -	for _, song := range v.Songs {
 | 
	
		
			
			| 86 |  | -		if song.Week == syncedWeek {
 | 
	
		
			
			| 87 |  | -			song.Sync = true
 | 
	
		
			
			| 88 |  | -			synced = true
 | 
	
		
			
			| 89 |  | -			err := saveDb(v)
 | 
	
		
			
			| 90 |  | -			if err != nil {
 | 
	
		
			
			| 91 |  | -				return err
 | 
	
		
			
			| 92 |  | -			}
 | 
	
		
			
			| 93 |  | -		}
 | 
	
		
			
			|  | 87 | +	affected, err := res.RowsAffected()
 | 
	
		
			
			|  | 88 | +	if err != nil {
 | 
	
		
			
			|  | 89 | +		return err
 | 
	
		
			
			| 94 | 90 |  	}
 | 
	
		
			
			| 95 |  | -	if !synced {
 | 
	
		
			
			| 96 |  | -		return errors.New("No week matched from JSON for synced song")
 | 
	
		
			
			|  | 91 | +
 | 
	
		
			
			|  | 92 | +	if affected != 1 {
 | 
	
		
			
			|  | 93 | +		return errors.New("Unknown entry ID")
 | 
	
		
			
			| 97 | 94 |  	}
 | 
	
		
			
			| 98 |  | -	return errors.New("Week not found")
 | 
	
		
			
			|  | 95 | +	return nil
 | 
	
		
			
			| 99 | 96 |  }
 | 
	
		
			
			| 100 | 97 |  
 | 
	
		
			
			| 101 |  | -func getSongs() (SongPriorityQueue, error) {
 | 
	
		
			
			| 102 |  | -	dbSongs, err := loadDb()
 | 
	
		
			
			|  | 98 | +func submitSong() {
 | 
	
		
			
			|  | 99 | +	query := `
 | 
	
		
			
			|  | 100 | +	SELECT e.user_id, e.round_id, e.artist, e.title, e.spotify_url, p.article, u.username, r.section
 | 
	
		
			
			|  | 101 | +	FROM public.entry e 
 | 
	
		
			
			|  | 102 | +	JOIN public."user" u ON u.id = e.user_id
 | 
	
		
			
			|  | 103 | +	JOIN public.round r ON r.id = e.round_id
 | 
	
		
			
			|  | 104 | +	JOIN public.panel p ON p.id = r.panel_id
 | 
	
		
			
			|  | 105 | +	WHERE r.start < current_timestamp AND e.synced = false`
 | 
	
		
			
			|  | 106 | +	rows, err := getDb().Query(query)
 | 
	
		
			
			| 103 | 107 |  	if err != nil {
 | 
	
		
			
			| 104 |  | -		return nil, err
 | 
	
		
			
			|  | 108 | +		log.Println("Error while reading songs from database:", err)
 | 
	
		
			
			|  | 109 | +		return
 | 
	
		
			
			| 105 | 110 |  	}
 | 
	
		
			
			| 106 |  | -
 | 
	
		
			
			| 107 |  | -	songs := make(SongPriorityQueue, len(dbSongs.Songs))
 | 
	
		
			
			| 108 |  | -	for index, songObj := range dbSongs.Songs {
 | 
	
		
			
			| 109 |  | -		songs[index] = &Song{
 | 
	
		
			
			| 110 |  | -			time:  targetTime(songObj),
 | 
	
		
			
			| 111 |  | -			song:  songEntryWikiText(songObj),
 | 
	
		
			
			| 112 |  | -			week:  songObj.Week,
 | 
	
		
			
			| 113 |  | -			sync:  songObj.Sync,
 | 
	
		
			
			| 114 |  | -			index: index,
 | 
	
		
			
			|  | 111 | +	defer rows.Close()
 | 
	
		
			
			|  | 112 | +	for rows.Next() {
 | 
	
		
			
			|  | 113 | +		var (
 | 
	
		
			
			|  | 114 | +			userId, roundId                                       int
 | 
	
		
			
			|  | 115 | +			artist, title, spotifyURL, article, username, section string
 | 
	
		
			
			|  | 116 | +		)
 | 
	
		
			
			|  | 117 | +		err := rows.Scan(&userId, &roundId, &artist, &title, &spotifyURL, &article, &username, §ion)
 | 
	
		
			
			|  | 118 | +		if err != nil {
 | 
	
		
			
			|  | 119 | +			log.Println("Error while scanning row:", err)
 | 
	
		
			
			|  | 120 | +			continue
 | 
	
		
			
			| 115 | 121 |  		}
 | 
	
		
			
			| 116 |  | -	}
 | 
	
		
			
			| 117 |  | -	heap.Init(&songs)
 | 
	
		
			
			| 118 |  | -	for len(songs) > 0 && songs[0].sync {
 | 
	
		
			
			| 119 |  | -		heap.Pop(&songs)
 | 
	
		
			
			| 120 |  | -	}
 | 
	
		
			
			| 121 |  | -	return songs, nil
 | 
	
		
			
			| 122 |  | -}
 | 
	
		
			
			|  | 122 | +		song := songWikiText(spotifyURL, artist, title)
 | 
	
		
			
			| 123 | 123 |  
 | 
	
		
			
			| 124 |  | -func submitSong() {
 | 
	
		
			
			| 125 |  | -	now := time.Now()
 | 
	
		
			
			| 126 |  | -	if len(songs) > 0 && songs[0].time.Before(now) {
 | 
	
		
			
			| 127 |  | -		fmt.Println("Time has passed for " + songs[0].song)
 | 
	
		
			
			| 128 |  | -		success, err := addSong("Levyraati 2018", songs[0].week, "Lamperi", songs[0].song)
 | 
	
		
			
			|  | 124 | +		fmt.Println("Time has passed for " + song)
 | 
	
		
			
			|  | 125 | +
 | 
	
		
			
			|  | 126 | +		success, err := addSong(article, section, username, song)
 | 
	
		
			
			| 129 | 127 |  		if err != nil {
 | 
	
		
			
			| 130 | 128 |  			log.Println("Error while adding song:", err)
 | 
	
		
			
			| 131 | 129 |  		}
 | 
	
		
			
			| 132 | 130 |  		if success {
 | 
	
		
			
			| 133 |  | -			err := songSynced(songs[0].week)
 | 
	
		
			
			| 134 |  | -			if err == nil {
 | 
	
		
			
			| 135 |  | -				heap.Pop(&songs)
 | 
	
		
			
			| 136 |  | -			} else {
 | 
	
		
			
			|  | 131 | +			err = songSynced(userId, roundId)
 | 
	
		
			
			|  | 132 | +			if err != nil {
 | 
	
		
			
			| 137 | 133 |  				fmt.Println("Error received:", err)
 | 
	
		
			
			| 138 | 134 |  			}
 | 
	
		
			
			| 139 | 135 |  		}
 | 
	
		
			
			| 140 | 136 |  	}
 | 
	
		
			
			|  | 137 | +	err = rows.Err()
 | 
	
		
			
			|  | 138 | +	if err != nil {
 | 
	
		
			
			|  | 139 | +		log.Println("Error after reading cursor:", err)
 | 
	
		
			
			|  | 140 | +		return
 | 
	
		
			
			|  | 141 | +	}
 | 
	
		
			
			| 141 | 142 |  }
 | 
	
		
			
			| 142 | 143 |  
 | 
	
		
			
			| 143 | 144 |  func isCurrentAuthor(line, author string) bool {
 | 
	
	
		
			
			|  | @@ -298,16 +299,6 @@ func initCreds() error {
 | 
	
		
			
			| 298 | 299 |  	return nil
 | 
	
		
			
			| 299 | 300 |  }
 | 
	
		
			
			| 300 | 301 |  
 | 
	
		
			
			| 301 |  | -func targetTime(entry *SongEntry) time.Time {
 | 
	
		
			
			| 302 |  | -	yearStart, _ := time.Parse(time.RFC3339, "2018-01-01T00:00:00+02:00")
 | 
	
		
			
			| 303 |  | -	target := yearStart.AddDate(0, 0, (entry.Week-1)*7)
 | 
	
		
			
			| 304 |  | -	return target
 | 
	
		
			
			| 305 |  | -}
 | 
	
		
			
			| 306 |  | -
 | 
	
		
			
			| 307 |  | -func songEntryWikiText(entry *SongEntry) string {
 | 
	
		
			
			| 308 |  | -	return songWikiText(entry.URL, entry.Artist, entry.Title)
 | 
	
		
			
			| 309 |  | -}
 | 
	
		
			
			| 310 |  | -
 | 
	
		
			
			| 311 | 302 |  func songWikiText(url string, artist string, title string) string {
 | 
	
		
			
			| 312 | 303 |  	return "[" + url + " " + artist + " - " + title + "]"
 | 
	
		
			
			| 313 | 304 |  }
 | 
	
	
		
			
			|  | @@ -317,45 +308,10 @@ func main() {
 | 
	
		
			
			| 317 | 308 |  	if err != nil {
 | 
	
		
			
			| 318 | 309 |  		panic(err)
 | 
	
		
			
			| 319 | 310 |  	}
 | 
	
		
			
			| 320 |  | -	songs, err = getSongs()
 | 
	
		
			
			| 321 |  | -	if err != nil {
 | 
	
		
			
			| 322 |  | -		panic(err)
 | 
	
		
			
			| 323 |  | -	}
 | 
	
		
			
			| 324 |  | -
 | 
	
		
			
			| 325 |  | -	modifiedSongChan := make(chan *SongEntry)
 | 
	
		
			
			| 326 | 311 |  
 | 
	
		
			
			| 327 | 312 |  	spotifyClient := spotify.NewClient(credentials.SpotifyClientID, credentials.SpotifyClientSecret)
 | 
	
		
			
			| 328 | 313 |  	go func() {
 | 
	
		
			
			| 329 |  | -
 | 
	
		
			
			| 330 |  | -		webStart(credentials.ListenAddr, modifiedSongChan, spotifyClient)
 | 
	
		
			
			| 331 |  | -	}()
 | 
	
		
			
			| 332 |  | -
 | 
	
		
			
			| 333 |  | -	go func() {
 | 
	
		
			
			| 334 |  | -		for {
 | 
	
		
			
			| 335 |  | -			newSong := <-modifiedSongChan
 | 
	
		
			
			| 336 |  | -			matched := false
 | 
	
		
			
			| 337 |  | -			for _, song := range songs {
 | 
	
		
			
			| 338 |  | -				if song.week == newSong.Week {
 | 
	
		
			
			| 339 |  | -					song.song = songEntryWikiText(newSong)
 | 
	
		
			
			| 340 |  | -					song.sync = newSong.Sync
 | 
	
		
			
			| 341 |  | -					matched = true
 | 
	
		
			
			| 342 |  | -					log.Printf("Updated song for week %d, artist: %s, title: %s, URL: %s, time: %v",
 | 
	
		
			
			| 343 |  | -						newSong.Week, newSong.Artist, newSong.Title, newSong.URL, song.time)
 | 
	
		
			
			| 344 |  | -				}
 | 
	
		
			
			| 345 |  | -			}
 | 
	
		
			
			| 346 |  | -			if !matched {
 | 
	
		
			
			| 347 |  | -				song := &Song{
 | 
	
		
			
			| 348 |  | -					time:  targetTime(newSong),
 | 
	
		
			
			| 349 |  | -					song:  songEntryWikiText(newSong),
 | 
	
		
			
			| 350 |  | -					week:  newSong.Week,
 | 
	
		
			
			| 351 |  | -					sync:  newSong.Sync,
 | 
	
		
			
			| 352 |  | -					index: len(songs),
 | 
	
		
			
			| 353 |  | -				}
 | 
	
		
			
			| 354 |  | -				heap.Push(&songs, song)
 | 
	
		
			
			| 355 |  | -				log.Printf("Added song for week %d, artist: %s, title: %s, URL: %s, time: %v",
 | 
	
		
			
			| 356 |  | -					newSong.Week, newSong.Artist, newSong.Title, newSong.URL, song.time)
 | 
	
		
			
			| 357 |  | -			}
 | 
	
		
			
			| 358 |  | -		}
 | 
	
		
			
			|  | 314 | +		webStart(credentials.ListenAddr, spotifyClient)
 | 
	
		
			
			| 359 | 315 |  	}()
 | 
	
		
			
			| 360 | 316 |  
 | 
	
		
			
			| 361 | 317 |  	gocron.Every(1).Hour().Do(fixAveragesTask)
 |