Skip to content

Commit

Permalink
Support all scoring systems
Browse files Browse the repository at this point in the history
  • Loading branch information
aQaTL committed Apr 7, 2023
1 parent 48c19f1 commit 28a87cb
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 53 deletions.
3 changes: 2 additions & 1 deletion anilist/anilist.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ const ALDomain = "https://anilist.co"
var InvalidToken = errors.New("Invalid token")

// TODO downloading only given list like watching/completed
func QueryUserLists(userId int, token oauth2.OAuthToken) ([]MediaListGroup, error) {
func QueryUserLists(userId int, scoreFormat ScoreFormat, token oauth2.OAuthToken) ([]MediaListGroup, error) {
vars := make(map[string]interface{})
vars["userID"] = userId
vars["scoreFormat"] = scoreFormat

resp := struct {
MediaListCollection `json:"MediaListCollection"`
Expand Down
4 changes: 2 additions & 2 deletions anilist/animation_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"github.com/aqatl/cliwait"
)

func QueryUserListsWaitAnimation(userId int, token oauth2.OAuthToken) ([]MediaListGroup, error) {
func QueryUserListsWaitAnimation(userId int, scoreFormat ScoreFormat, token oauth2.OAuthToken) ([]MediaListGroup, error) {
var mlg []MediaListGroup
var err error
cliwait.DoFuncWithWaitAnimation("Queyring user list", func() {
mlg, err = QueryUserLists(userId, token)
mlg, err = QueryUserLists(userId, scoreFormat, token)
})
return mlg, err
}
Expand Down
7 changes: 5 additions & 2 deletions anilist/gql_queries.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package anilist

var queryUserAnimeList = `
query UserList ($userID: Int) {
query UserList ($userID: Int, $scoreFormat: ScoreFormat) {
MediaListCollection (userId: $userID, type: ANIME) {
lists {
entries {
id
status
score(format: POINT_10)
score(format: $scoreFormat)
progress
repeat
updatedAt
Expand Down Expand Up @@ -81,6 +81,9 @@ query {
donatorTier
moderatorStatus
updatedAt
mediaListOptions {
scoreFormat
}
}
}
`
Expand Down
37 changes: 26 additions & 11 deletions anilist/gql_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,37 @@ import (
)

type User struct {
Id int `json:"id"`
Name string `json:"name"`
About string `json:"about"`
BannerImage string `json:"bannerImage"`
Stats UserStats `json:"stats"`
UnreadNotificationCount int `json:"unreadNotificationCount"`
SiteUrl string `json:"siteUrl"`
DonatorTier int `json:"donatorTier"`
ModeratorStatus string `json:"moderatorStatus"`
UpdatedAt int `json:"updatedAt"`
Id int `json:"id"`
Name string `json:"name"`
About string `json:"about"`
BannerImage string `json:"bannerImage"`
Stats UserStats `json:"stats"`
UnreadNotificationCount int `json:"unreadNotificationCount"`
SiteUrl string `json:"siteUrl"`
DonatorTier int `json:"donatorTier"`
ModeratorStatus string `json:"moderatorStatus"`
UpdatedAt int `json:"updatedAt"`
MediaListOptions MediaListOptions `json:"mediaListOptions"`
}

type UserStats struct {
WatchedTime int `json:"watchedTime"`
}

type MediaListOptions struct {
ScoreFormat ScoreFormat `json:"scoreFormat"`
}

type ScoreFormat string

const (
Point100 ScoreFormat = "POINT_100"
Point10Decimal ScoreFormat = "POINT_10_DECIMAL"
Point10 ScoreFormat = "POINT_10"
Point5 ScoreFormat = "POINT_5"
Point3 ScoreFormat = "POINT_3"
)

type MediaListCollection struct {
Lists []MediaListGroup `json:"lists"`
}
Expand All @@ -36,7 +51,7 @@ type MediaListGroup struct {
type MediaListEntry struct {
ListId int `json:"id"`
Status MediaListStatus `json:"status"`
Score int `json:"score"`
Score float32 `json:"score"`
Progress int `json:"progress"`
Repeat int `json:"repeat"`
UpdatedAt int `json:"updatedAt"`
Expand Down
84 changes: 64 additions & 20 deletions anilist_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,12 @@ func aniListDefaultAction(ctx *cli.Context) error {
fmt.Printf("%*s%*.*s%8s%6s\n",
numberFieldWidth, "No", titleWidth, titleWidth, "Title", "Eps", "Score")
fmt.Println(strings.Repeat("=", cfg.ListWidth))
pattern := "%*d%*.*s%8s%6d\n"
var pattern string
if al.User.MediaListOptions.ScoreFormat == anilist.Point10Decimal {
pattern = "%*d%*.*s%8s%6.1f\n"
} else {
pattern = "%*d%*.*s%8s%6.f\n"
}
var entry *anilist.MediaListEntry
for i := visibleEntries - 1; i >= 0; i-- {
entry = &list[i]
Expand Down Expand Up @@ -393,7 +398,7 @@ func alSetEntryEpisodes(ctx *cli.Context) error {
}

fmt.Println("Updated successfully")
alPrintEntryDetailsAfterUpdatedEpisodes(entry, epsBefore)
alPrintEntryDetailsAfterUpdatedEpisodes(entry, epsBefore, al.User.MediaListOptions.ScoreFormat)
return nil
}

Expand Down Expand Up @@ -437,7 +442,7 @@ func alSetEntryStatus(ctx *cli.Context) error {
}

fmt.Println("Updated successfully")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)
return nil
}

Expand All @@ -451,9 +456,9 @@ func alSetEntryScore(ctx *cli.Context) error {
return err
}

score, err := strconv.Atoi(ctx.Args().First())
if err != nil || score < 0 || score > 10 {
return fmt.Errorf("invalid score; valid range: <0;10>")
score, err := parseScore(ctx.Args().First(), al.User.MediaListOptions.ScoreFormat)
if err != nil {
return err
}

entry.Score = score
Expand All @@ -466,10 +471,49 @@ func alSetEntryScore(ctx *cli.Context) error {
}

fmt.Println("Updated successfully")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)
return nil
}

func parseScore(score string, scoreFormat anilist.ScoreFormat) (float32, error) {
maxScore := 0
switch scoreFormat {
case anilist.Point10Decimal:
maxScore = 10
decimalPartIdx := strings.Index(score, ".")
if decimalPartIdx == -1 {
break
} else if decimalPartIdx == len(score)-1 {
score = score[:decimalPartIdx]
break
}

decimalPart := score[(decimalPartIdx + 1):]
if len(decimalPart) > 1 {
return 0, fmt.Errorf("invalid score; up to 1 decimal place allowed")
}

parsedScore, err := strconv.ParseFloat(score, 32)
if err != nil || parsedScore < 0.0 || parsedScore > 10.0 {
return 0, fmt.Errorf("invalid score; valid range: <0;10>")
}
return float32(parsedScore), err
case anilist.Point100:
maxScore = 100
case anilist.Point10:
maxScore = 10
case anilist.Point5:
maxScore = 5
case anilist.Point3:
maxScore = 3
}
parsedScore, err := strconv.Atoi(score)
if err != nil || parsedScore < 0 || parsedScore > maxScore {
return 0, fmt.Errorf("invalid score; valid range: <0;%d>", maxScore)
}
return float32(parsedScore), err
}

func alDeleteEntry(ctx *cli.Context) error {
al, entry, _, err := loadAniListFull(ctx)
if err != nil {
Expand All @@ -481,7 +525,7 @@ func alDeleteEntry(ctx *cli.Context) error {
}

fmt.Println("Entry deleted successfully")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)

al.List = al.List.DeleteById(entry.ListId)
return saveAniListAnimeLists(al)
Expand Down Expand Up @@ -519,7 +563,7 @@ func alSelectEntry(ctx *cli.Context) error {
}
}
if matchedEntry != nil {
alSaveSelection(cfg, matchedEntry)
alSaveSelection(cfg, matchedEntry, al.User.MediaListOptions.ScoreFormat)
return nil
}

Expand All @@ -534,25 +578,25 @@ func alSelectRandomEntry(ctx *cli.Context) error {

planToWatchList := alGetList(al, anilist.Planning)
idx := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(len(planToWatchList))
alSaveSelection(LoadConfig(), &planToWatchList[idx])
alSaveSelection(LoadConfig(), &planToWatchList[idx], al.User.MediaListOptions.ScoreFormat)

return nil
}

func alSaveSelection(cfg *Config, entry *anilist.MediaListEntry) {
func alSaveSelection(cfg *Config, entry *anilist.MediaListEntry, scoreFormat anilist.ScoreFormat) {
cfg.ALSelectedID = entry.Id
cfg.Save()

fmt.Println("Selected entry:")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, scoreFormat)
}

func alShowSelectedEntry(ctx *cli.Context) error {
_, entry, _, err := loadAniListFull(ctx)
al, entry, _, err := loadAniListFull(ctx)
if err != nil {
return err
}
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)
return nil
}

Expand Down Expand Up @@ -586,7 +630,7 @@ func alNyaaWebsite(ctx *cli.Context) error {
}

fmt.Println("Searched for:")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)
return nil
}

Expand Down Expand Up @@ -631,7 +675,7 @@ func alOpenWebsite(ctx *cli.Context) error {
}

fmt.Println("Opened website for:")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)
fmt.Fprintf(color.Output, "URL: %v\n", color.CyanString("%v", entryUrl))
} else {
fmt.Println("Nothing to open")
Expand Down Expand Up @@ -848,7 +892,7 @@ func alCopyIntoClipboard(ctx *cli.Context) error {
}

func alOpenEntrySite(ctx *cli.Context) error {
_, entry, cfg, err := loadAniListFull(ctx)
al, entry, cfg, err := loadAniListFull(ctx)
if err != nil {
return err
}
Expand All @@ -860,20 +904,20 @@ func alOpenEntrySite(ctx *cli.Context) error {
open.StartWith(uri, path)
}
fmt.Println("Opened website for:")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)

return nil
}

func alOpenMalSite(ctx *cli.Context) error {
_, entry, cfg, err := loadAniListFull(ctx)
al, entry, cfg, err := loadAniListFull(ctx)
if err != nil {
return err
}

openMalSite(cfg, entry.IdMal)
fmt.Println("Opened website for:")
alPrintEntryDetails(entry)
alPrintEntryDetails(entry, al.User.MediaListOptions.ScoreFormat)

return nil
}
Expand Down
Loading

0 comments on commit 28a87cb

Please sign in to comment.