106 lines
2.0 KiB
Go
106 lines
2.0 KiB
Go
package search
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/animenotifier/notify.moe/arn"
|
|
"github.com/animenotifier/notify.moe/arn/stringutils"
|
|
)
|
|
|
|
// Anime searches all anime.
|
|
func Anime(originalTerm string, maxLength int) []*arn.Anime {
|
|
term := strings.ToLower(stringutils.RemoveSpecialCharacters(originalTerm))
|
|
results := make([]*Result, 0, maxLength)
|
|
|
|
check := func(text string) float64 {
|
|
if text == "" {
|
|
return 0
|
|
}
|
|
|
|
return stringutils.AdvancedStringSimilarity(term, strings.ToLower(stringutils.RemoveSpecialCharacters(text)))
|
|
}
|
|
|
|
add := func(anime *arn.Anime, similarity float64) {
|
|
similarity += float64(anime.Popularity.Total()) * popularityDamping
|
|
|
|
if anime.Type != "tv" && anime.Type != "movie" {
|
|
similarity -= 0.3
|
|
}
|
|
|
|
results = append(results, &Result{
|
|
obj: anime,
|
|
similarity: similarity,
|
|
})
|
|
}
|
|
|
|
for anime := range arn.StreamAnime() {
|
|
if anime.ID == originalTerm {
|
|
return []*arn.Anime{anime}
|
|
}
|
|
|
|
// Canonical title
|
|
similarity := check(anime.Title.Canonical)
|
|
|
|
if similarity >= MinStringSimilarity {
|
|
add(anime, similarity)
|
|
continue
|
|
}
|
|
|
|
// English
|
|
similarity = check(anime.Title.English)
|
|
|
|
if similarity >= MinStringSimilarity {
|
|
add(anime, similarity)
|
|
continue
|
|
}
|
|
|
|
// Romaji
|
|
similarity = check(anime.Title.Romaji)
|
|
|
|
if similarity >= MinStringSimilarity {
|
|
add(anime, similarity)
|
|
continue
|
|
}
|
|
|
|
// Synonyms
|
|
for _, synonym := range anime.Title.Synonyms {
|
|
similarity := check(synonym)
|
|
|
|
if similarity >= MinStringSimilarity {
|
|
add(anime, similarity)
|
|
goto nextAnime
|
|
}
|
|
}
|
|
|
|
// Japanese
|
|
similarity = check(anime.Title.Japanese)
|
|
|
|
if similarity >= MinStringSimilarity {
|
|
add(anime, similarity)
|
|
continue
|
|
}
|
|
|
|
nextAnime:
|
|
}
|
|
|
|
// Sort
|
|
sort.Slice(results, func(i, j int) bool {
|
|
return results[i].similarity > results[j].similarity
|
|
})
|
|
|
|
// Limit
|
|
if len(results) >= maxLength {
|
|
results = results[:maxLength]
|
|
}
|
|
|
|
// Final list
|
|
final := make([]*arn.Anime, len(results))
|
|
|
|
for i, result := range results {
|
|
final[i] = result.obj.(*arn.Anime)
|
|
}
|
|
|
|
return final
|
|
}
|