Added arn to the main repository
This commit is contained in:
112
arn/search/Characters.go
Normal file
112
arn/search/Characters.go
Normal file
@ -0,0 +1,112 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/animenotifier/notify.moe/arn"
|
||||
"github.com/animenotifier/notify.moe/arn/stringutils"
|
||||
)
|
||||
|
||||
// Characters searches all characters.
|
||||
func Characters(originalTerm string, maxLength int) []*arn.Character {
|
||||
if maxLength == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
term := strings.ToLower(stringutils.RemoveSpecialCharacters(originalTerm))
|
||||
termHasUnicode := stringutils.ContainsUnicodeLetters(term)
|
||||
results := make([]*Result, 0, maxLength)
|
||||
|
||||
for character := range arn.StreamCharacters() {
|
||||
if character.ID == originalTerm {
|
||||
return []*arn.Character{character}
|
||||
}
|
||||
|
||||
if character.Image.Extension == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Canonical
|
||||
text := strings.ToLower(stringutils.RemoveSpecialCharacters(character.Name.Canonical))
|
||||
|
||||
if text == term {
|
||||
results = append(results, &Result{
|
||||
obj: character,
|
||||
similarity: float64(20 + len(character.Likes)),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
spaceCount := 0
|
||||
start := 0
|
||||
found := false
|
||||
|
||||
for i := 0; i <= len(text); i++ {
|
||||
if i == len(text) || text[i] == ' ' {
|
||||
part := text[start:i]
|
||||
|
||||
if part == term {
|
||||
results = append(results, &Result{
|
||||
obj: character,
|
||||
similarity: float64(10 - spaceCount*5 + len(character.Likes)),
|
||||
})
|
||||
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
||||
start = i + 1
|
||||
spaceCount++
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
|
||||
// Japanese
|
||||
if termHasUnicode {
|
||||
if strings.Contains(character.Name.Japanese, term) {
|
||||
results = append(results, &Result{
|
||||
obj: character,
|
||||
similarity: float64(len(character.Likes)),
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort
|
||||
sort.Slice(results, func(i, j int) bool {
|
||||
similarityA := results[i].similarity
|
||||
similarityB := results[j].similarity
|
||||
|
||||
if similarityA == similarityB {
|
||||
characterA := results[i].obj.(*arn.Character)
|
||||
characterB := results[j].obj.(*arn.Character)
|
||||
|
||||
if characterA.Name.Canonical == characterB.Name.Canonical {
|
||||
return characterA.ID < characterB.ID
|
||||
}
|
||||
|
||||
return characterA.Name.Canonical < characterB.Name.Canonical
|
||||
}
|
||||
|
||||
return similarityA > similarityB
|
||||
})
|
||||
|
||||
// Limit
|
||||
if len(results) >= maxLength {
|
||||
results = results[:maxLength]
|
||||
}
|
||||
|
||||
// Final list
|
||||
final := make([]*arn.Character, len(results))
|
||||
|
||||
for i, result := range results {
|
||||
final[i] = result.obj.(*arn.Character)
|
||||
}
|
||||
|
||||
return final
|
||||
}
|
Reference in New Issue
Block a user