func pickRelease(releases []interface{}, existingTag ...editor.Tag) map[string]interface{} { var tag editor.Tag if len(existingTag) > 0 { tag.Title = strings.ToUpper(existingTag[0].Title) tag.Artist = strings.ToUpper(existingTag[0].Artist) tag.Album = strings.ToUpper(existingTag[0].Album) } var best int = 0 for i := 1; i < len(releases); i++ { if isMoreSuitableRelease(releases[i].(map[string]interface{}), releases[best].(map[string]interface{}), tag) { best = i } } return releases[best].(map[string]interface{}) }
func (tagger *Tagger) filterByTag(tag editor.Tag) bool { if tagger.filter == All { return true } if (tagger.filter&NoTag) != 0 && tag.Empty() { return true } if (tagger.filter&NoTitle) != 0 && len(tag.Title) == 0 { return true } if (tagger.filter&NoArtist) != 0 && len(tag.Artist) == 0 { return true } if (tagger.filter&NoAlbum) != 0 && len(tag.Album) == 0 { return true } if (tagger.filter&NoCover) != 0 && tag.Cover.Empty() { return true } return false }
func parseAcousticIdReply(reply string, existingTag ...editor.Tag) (editor.Tag, string) { var fields map[string]interface{} err := json.Unmarshal([]byte(reply), &fields) if err != nil || fields["status"] != "ok" { return editor.Tag{}, "" } if fields["results"] == nil { return editor.Tag{}, "" } results := fields["results"].([]interface{}) if len(results) == 0 { return editor.Tag{}, "" } result := results[0].(map[string]interface{}) if result["releases"] == nil { return editor.Tag{}, "" } releases := result["releases"].([]interface{}) if len(releases) == 0 { return editor.Tag{}, "" } release := pickRelease(releases, existingTag...) var tag editor.Tag tag.Year = getReleaseDate(release) tag.Artist = getReleaseArtist(release) tag.Album = getReleaseAlbum(release) tag.Title = getReleaseTitle(release) tag.Track = getReleaseTrack(release) return tag, release["id"].(string) }
func (tagger *Tagger) processFile(src, dst string) error { utils.Log(utils.INFO, "Start processing file '%v'", src) tagEditor := makeEditor(src) tag, err := tagEditor.ReadTag(src) if err != nil { tagger.counter.addFail() utils.Log(utils.ERROR, "Failed to read tags from file '%v': %v", src, err) return err } if !tagger.filterByTag(tag) { utils.Log(utils.INFO, "Update tag is not required for file '%v'", src) return nil } tagger.counter.addFiltered() if tagger.stop.Load().(bool) { utils.Log(utils.WARNING, "Processing file '%v' interrupted by application stop", src) return fmt.Errorf("Processing file '%v' interrupted by application stop", src) } var newTag editor.Tag if tagger.useExistingTag { newTag, err = recognizer.Recognize(src, tag) } else { newTag, err = recognizer.Recognize(src) } if err != nil { tagger.counter.addFail() utils.Log(utils.ERROR, "Failed to recognize composition from file '%v': %v", src, err) return err } if newTag.Empty() { tagger.counter.addFail() utils.Log(utils.WARNING, "Composition from file '%v' is not recognized", src) return nil } // if we need only cover and there is no cover, return here if tagger.filter == NoCover && newTag.Cover.Empty() { tagger.counter.addFail() utils.Log(utils.WARNING, "Cover for file '%v' is not found", src) return nil } // if we need only cover and already has smth else, take only cover if tagger.filter == NoCover && !tag.Empty() { tag.Cover = newTag.Cover newTag = tag } else { newTag.MergeWith(tag) } err = tagger.preparePath(dst) if err != nil { tagger.counter.addFail() utils.Log(utils.ERROR, "Failed to prepare path '%v': %v", dst, err) return err } err = tagEditor.WriteTag(src, dst, newTag) if err != nil { tagger.counter.addFail() utils.Log(utils.ERROR, "Failed to write tag and save file '%v': %v", dst, err) return err } tagger.counter.addSuccess(!newTag.Cover.Empty()) utils.Log(utils.INFO, "File '%v' successfully processed, cover found: %v", src, newTag.Cover.Empty()) return nil }
func isMoreSuitableRelease(r1, r2 map[string]interface{}, tag editor.Tag) bool { data1 := getReleaseDate(r1) artist1 := strings.ToUpper(getReleaseArtist(r1)) album1 := strings.ToUpper(getReleaseAlbum(r1)) title1 := strings.ToUpper(getReleaseTitle(r1)) data2 := getReleaseDate(r2) artist2 := strings.ToUpper(getReleaseArtist(r2)) album2 := strings.ToUpper(getReleaseAlbum(r2)) title2 := strings.ToUpper(getReleaseTitle(r2)) // either there is no existing tag or both releases have the same RIGHT data - choose by date only if tag.Empty() || len(tag.Artist) > 0 && len(tag.Album) > 0 && len(tag.Title) > 0 && artist1 == tag.Artist && album1 == tag.Album && title1 == tag.Title && artist2 == tag.Artist && album2 == tag.Album && title2 == tag.Title { return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT data (and the 2nd one has not) if len(tag.Artist) > 0 && len(tag.Album) > 0 && len(tag.Title) > 0 && artist1 == tag.Artist && album1 == tag.Album && title1 == tag.Title { return true } // if 2nd release has RIGHT data (and the 1st one has not) if len(tag.Artist) > 0 && len(tag.Album) > 0 && len(tag.Title) > 0 && artist2 == tag.Artist && album2 == tag.Album && title2 == tag.Title { return false } // if both releases have the same RIGHT artist and title if len(tag.Artist) > 0 && len(tag.Title) > 0 && artist1 == tag.Artist && title1 == tag.Title && artist2 == tag.Artist && title2 == tag.Title { if len(album1) > 0 && len(album2) == 0 { return true } if len(album1) == 0 && len(album2) > 0 { return false } return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT title and artist (and the 2nd one has not) if len(tag.Artist) > 0 && len(tag.Title) > 0 && artist1 == tag.Artist && title1 == tag.Title { return true } // if 2nd release has RIGHT title and artist (and the 1st one has not) if len(tag.Artist) > 0 && len(tag.Title) > 0 && artist2 == tag.Artist && title2 == tag.Title { return false } // prefer singles and albums over collections various1 := strings.Contains(artist1, "VARIOUS") various2 := strings.Contains(artist2, "VARIOUS") // if both releases have the same RIGHT album and title if len(tag.Album) > 0 && len(tag.Title) > 0 && album1 == tag.Album && title1 == tag.Title && album2 == tag.Album && title2 == tag.Title { if len(artist1) > 0 && len(artist2) == 0 || !various1 && various2 { return true } if len(artist1) == 0 && len(artist2) > 0 || various1 && !various2 { return false } return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT album and title (and the 2nd one has not) if len(tag.Album) > 0 && len(tag.Title) > 0 && album1 == tag.Album && title1 == tag.Title { return true } // if 2nd release has RIGHT album and title (and the 1st one has not) if len(tag.Album) > 0 && len(tag.Title) > 0 && album2 == tag.Album && title2 == tag.Title { return false } // if both releases have the same RIGHT album and artist if len(tag.Album) > 0 && len(tag.Artist) > 0 && album1 == tag.Album && artist1 == tag.Artist && album2 == tag.Album && artist2 == tag.Artist { return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT album and artist (and the 2nd one has not) if len(tag.Album) > 0 && len(tag.Artist) > 0 && album1 == tag.Album && artist1 == tag.Artist { return true } // if 2nd release has RIGHT album and artist (and the 1st one has not) if len(tag.Album) > 0 && len(tag.Artist) > 0 && album2 == tag.Album && artist2 == tag.Artist { return false } // if both releases have the same RIGHT title if len(tag.Title) > 0 && title1 == tag.Title && title2 == tag.Title { if len(artist1) > 0 && len(artist2) == 0 || !various1 && various2 || len(album1) > 0 && len(album2) == 0 { return true } if len(artist1) == 0 && len(artist2) > 0 || various1 && !various2 || len(album1) == 0 && len(album2) > 0 { return false } return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT title (and the 2nd one has not) if len(tag.Title) > 0 && title1 == tag.Title { return true } // if 2nd release has RIGHT title (and the 1st one has not) if len(tag.Title) > 0 && title2 == tag.Title { return false } // if both releases have the same RIGHT artist if len(tag.Artist) > 0 && artist1 == tag.Artist && artist2 == tag.Artist { if len(title1) > 0 && len(title2) == 0 || len(album1) > 0 && len(album2) == 0 { return true } if len(title1) == 0 && len(title2) > 0 || len(album1) == 0 && len(album2) > 0 { return false } return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT artist (and the 2nd one has not) if len(tag.Artist) > 0 && artist1 == tag.Artist { return true } // if 2nd release has RIGHT artist (and the 1st one has not) if len(tag.Artist) > 0 && artist2 == tag.Artist { return false } // if both releases have the same RIGHT album if len(tag.Album) > 0 && album1 == tag.Album && album2 == tag.Album { if len(artist1) > 0 && len(artist2) == 0 || !various1 && various2 || len(title1) > 0 && len(title2) == 0 { return true } if len(artist1) == 0 && len(artist2) > 0 || various1 && !various2 || len(title1) == 0 && len(title2) > 0 { return false } return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 } // if 1st release has RIGHT album (and the 2nd one has not) if len(tag.Album) > 0 && album1 == tag.Album { return true } // if 2nd release has RIGHT album (and the 1st one has not) if len(tag.Album) > 0 && album2 == tag.Album { return false } if !various1 && various2 { return true } if various1 && !various2 { return false } return data1 != 0 && data1 < data2 || data2 == 0 && data1 != 0 }