func karmaSong() func() (library.Song, error) { log.Println("karmaSong") var impressionsByKey map[int][]string = invertMap(karma.SongKarma) impressionKeys := keys(impressionsByKey) sort.Ints(impressionKeys) log.Println("impressions prepped") songCh := make(chan *library.Song) observer.Observe("library.loaded", func(msg interface{}) { go func() { for i := len(impressionKeys) - 1; i >= 0; i-- { log.Printf("impression key: %v", impressionKeys[i]) for _, hash := range impressionsByKey[impressionKeys[i]] { log.Printf("impression hash: %q", hash) song, err := library.ByHash(hash) if err != nil { continue } log.Printf("karmaSong karma:%d song:%v", impressionKeys[i], song) songCh <- song } } close(songCh) }() }) return func() (library.Song, error) { nextSong, ok := <-songCh if ok { return *nextSong, nil } else { return library.Song{}, fmt.Errorf("NoSong") } } }
// Build up the SongKarma map, and spread impressiosn to library.Song.Rank func Load() error { SongKarma = make(map[string]int) impressionCount := 0 timestampIdx := 0 logTypeIdx := 1 // logType = karma hashIdx := 2 impressionIdx := 3 // logType = env tagIdx := 2 valIdx := 3 impressionLogPath := path.Join(config.DataPath, "impression.log") log.Printf("Reading impressions from: %q", impressionLogPath) f, err := os.Open(impressionLogPath) if err != nil { return err } defer f.Close() r := csv.NewReader(f) r.Comma = '\t' r.Comment = '#' records, err := r.ReadAll() if err != nil { return err } for _, record := range records { if len(record) != 4 { return fmt.Errorf("Malformed impression.log, wrong number of columns %d expected 4", len(record)) } timestampStr := record[timestampIdx] timestamp, _ := time.Parse("2016/02/21 20:18:49.091737", timestampStr) logType := record[logTypeIdx] switch logType { case "karma": hash := record[hashIdx] impression, _ := strconv.Atoi(record[impressionIdx]) SongKarma[hash] += impression song, err := library.ByHash(hash) if err != nil { continue } impressionCount++ historicalEnv.Impress(timestamp, song, impression) go song.PathGraphImpress(impression) case "env": sensor := record[tagIdx] val := record[valIdx] historicalEnv.Update(timestamp, sensor, val) } } //historicalEnv.Print() //log.Printf("%v", SongKarma) sort.Sort(library.Songs) observer.Notify("karma.loaded", struct{}{}) log.Printf("Loading karma: %d impressions loaded", impressionCount) return nil }