diff --git a/jobs/mal-sync/character.go b/jobs/mal-sync/character.go new file mode 100644 index 00000000..916153e0 --- /dev/null +++ b/jobs/mal-sync/character.go @@ -0,0 +1,81 @@ +package main + +import ( + "strings" + + "github.com/animenotifier/arn" +) + +func parseCharacterDescription(input string) (output string, attributes []*arn.CharacterAttribute) { + // Parse attributes like these: + // - Position: Club Manager + // - Height: 162 cm (5' 4") + // - Weight: 48 kg (106 lb) + // - Birthday: November 24 + // - Hair color: Brown + // - Eyes: Blue (anime), Green (manga) + + paragraphs := strings.Split(input, "\n\n") + finalParagraphs := make([]string, 0, len(paragraphs)) + + for _, paragraph := range paragraphs { + // Is paragraph full of attributes? + if strings.Contains(paragraph, "\n") { + continue + } + + // Remove all kinds of starting and ending parantheses. + if strings.HasPrefix(paragraph, "(") { + paragraph = strings.TrimPrefix(paragraph, "(") + paragraph = strings.TrimSuffix(paragraph, ")") + } + + // Replace source paragraph with an attribute + if strings.HasPrefix(paragraph, "Source:") || strings.HasPrefix(paragraph, "source:") { + source := paragraph[len("source:"):] + source = strings.TrimSpace(source) + + attributes = append(attributes, &arn.CharacterAttribute{ + Name: "Source", + Value: source, + }) + continue + } + + finalParagraphs = append(finalParagraphs, paragraph) + + // originalLine := line + + // line = strings.TrimSpace(line) + + // colonPos := strings.Index(line, ":") + + // // If a colon has not been found or the colon is too far, + // // treat it as a normal line. + // if colonPos == -1 || colonPos < 2 || colonPos > 25 { + // finalLines = append(finalLines, originalLine) + // continue + // } + + // key := line[:colonPos] + // value := line[colonPos+1:] + + // value = strings.TrimSpace(value) + + // if key == "source" { + // key = "Source" + // } + + // attributes = append(attributes, &arn.CharacterAttribute{ + // Name: key, + // Value: value, + // }) + + // fmt.Println(color.CyanString(key), color.YellowString(value)) + } + + output = strings.Join(finalParagraphs, "\n\n") + output = strings.TrimSpace(output) + + return output, attributes +} diff --git a/jobs/mal-sync/mal-sync.go b/jobs/mal-sync/mal-sync.go index 40aaca0d..4049d3b6 100644 --- a/jobs/mal-sync/mal-sync.go +++ b/jobs/mal-sync/mal-sync.go @@ -37,11 +37,25 @@ func main() { continue } - sync(anime, malID) + syncAnime(anime, malID) + } + + // Sync the most important ones first + allCharacters := arn.AllCharacters() + arn.SortCharactersByLikes(allCharacters) + + for _, character := range allCharacters { + malID := character.GetMapping("myanimelist/character") + + if malID == "" { + continue + } + + syncCharacter(character, malID) } } -func sync(anime *arn.Anime, malID string) { +func syncAnime(anime *arn.Anime, malID string) { obj, err := malDB.Get("Anime", malID) if err != nil { @@ -72,3 +86,25 @@ func sync(anime *arn.Anime, malID string) { // Save in database anime.Save() } + +func syncCharacter(character *arn.Character, malID string) { + obj, err := malDB.Get("Character", malID) + + if err != nil { + fmt.Println(err) + return + } + + malCharacter := obj.(*mal.Character) + + description, attributes := parseCharacterDescription(malCharacter.Description) + character.Description = description + character.Attributes = attributes + + if character.Name.Japanese == "" && malCharacter.JapaneseName != "" { + character.Name.Japanese = malCharacter.JapaneseName + } + + // Save in database + character.Save() +} diff --git a/jobs/mal-sync/shell.go b/jobs/mal-sync/shell.go index 0300b24e..ec5bcef1 100644 --- a/jobs/mal-sync/shell.go +++ b/jobs/mal-sync/shell.go @@ -28,7 +28,7 @@ func InvokeShellArgs() bool { panic("No MAL ID") } - sync(anime, anime.GetMapping("myanimelist/anime")) + syncAnime(anime, anime.GetMapping("myanimelist/anime")) return true }