mirror of
https://github.com/ultrasn0w/huso.git
synced 2025-12-13 12:29:53 +01:00
MAL progress fetch
This commit is contained in:
9
huso.go
9
huso.go
@@ -42,6 +42,7 @@ var (
|
||||
seasoncache *bigcache.BigCache
|
||||
userCache *bigcache.BigCache
|
||||
searchCache *bigcache.BigCache
|
||||
animeListCache *bigcache.BigCache
|
||||
db *nutsdb.DB
|
||||
)
|
||||
|
||||
@@ -76,6 +77,11 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer searchCache.Close()
|
||||
animeListCache, err = bigcache.NewBigCache(bigcache.DefaultConfig(42 * time.Minute))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer animeListCache.Close()
|
||||
|
||||
nutsOpt := nutsdb.DefaultOptions
|
||||
nutsOpt.Dir = "nuts"
|
||||
@@ -93,8 +99,5 @@ func main() {
|
||||
|
||||
go RunWebserv()
|
||||
|
||||
//list, _, _ := GetUserAnimeListData("ultrasn0w", malApiStatusW)
|
||||
//fmt.Printf("%+v\n", list)
|
||||
|
||||
<-sc
|
||||
}
|
||||
|
||||
16
klotz.go
16
klotz.go
@@ -53,9 +53,10 @@ type AnimeStudio struct {
|
||||
}
|
||||
|
||||
type WatchUser struct {
|
||||
Username string `json:"username"`
|
||||
MalID int64 `json:"malId"`
|
||||
Progress int `json:"progress"`
|
||||
Username string `json:"username"`
|
||||
MalID int64 `json:"malId"`
|
||||
Progress int `json:"progress"`
|
||||
Updated time.Time `json:"updated"`
|
||||
}
|
||||
|
||||
type UserData struct {
|
||||
@@ -130,7 +131,14 @@ type AnimeDetailMal struct {
|
||||
|
||||
type AnimeListMal struct {
|
||||
Data []struct {
|
||||
Node AnimeDetailMal `json:"node"`
|
||||
Node AnimeDetailMal `json:"node"`
|
||||
ListStatus struct {
|
||||
Status string `json:"status"`
|
||||
Score int `json:"score"`
|
||||
NumEpisodesWatched int `json:"num_episodes_watched"`
|
||||
IsRewatching bool `json:"is_rewatching"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
} `json:"list_status"`
|
||||
} `json:"data"`
|
||||
Paging struct {
|
||||
Next string `json:"next"`
|
||||
|
||||
16
knecht.go
16
knecht.go
@@ -72,16 +72,16 @@ func GetAnimeDetailData(animeId int64) (*Anime, []byte, error) {
|
||||
|
||||
func GetUserAnimeListData(username, status string) (*AnimeListMal, []byte, error) {
|
||||
var list AnimeListMal
|
||||
body, err := GetUserAnimeListBytes(username, status)
|
||||
data, err := animeListCache.Get(username + status)
|
||||
if err != nil {
|
||||
return nil, body, err
|
||||
data, err = GetDataMal(userApiMal + username + "/animelist?limit=1000&status=" + status + "&fields=list_status")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
animeListCache.Set(username+status, data)
|
||||
}
|
||||
err = json.Unmarshal(body, &list)
|
||||
return &list, body, err
|
||||
}
|
||||
|
||||
func GetUserAnimeListBytes(username, status string) ([]byte, error) {
|
||||
return GetDataMal(userApiMal + username + "/animelist?limit=1000&status=" + status)
|
||||
err = json.Unmarshal(data, &list)
|
||||
return &list, data, err
|
||||
}
|
||||
|
||||
func GetUserData(username string) (*User, []byte, error) {
|
||||
|
||||
35
nuss.go
35
nuss.go
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/xujiajun/nutsdb"
|
||||
)
|
||||
@@ -30,7 +31,7 @@ func SaveUser(user *UserData) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func AddUserToAnime(username string, userId, animeId int64) (*AnimeUser, error) {
|
||||
func AddUserToAnime(username string, userId, animeId int64, progress int, updated time.Time) (*AnimeUser, error) {
|
||||
var anime AnimeUser
|
||||
err := db.Update(
|
||||
func(tx *nutsdb.Tx) error {
|
||||
@@ -62,6 +63,8 @@ func AddUserToAnime(username string, userId, animeId int64) (*AnimeUser, error)
|
||||
users = append(users, WatchUser{
|
||||
Username: username,
|
||||
MalID: userId,
|
||||
Progress: progress,
|
||||
Updated: updated,
|
||||
})
|
||||
anime = AnimeUser{
|
||||
Anime: animeId,
|
||||
@@ -164,6 +167,36 @@ func DeleteUserFromAnimes(userId int64) error {
|
||||
})
|
||||
}
|
||||
|
||||
func UpdateUserAnimeProgress(animeId, userId int64, progress int, updated time.Time) error {
|
||||
return db.Update(
|
||||
func(tx *nutsdb.Tx) error {
|
||||
keyBytes := Int64ToByte(animeId)
|
||||
e, err := tx.Get(bucketAnime, keyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// parse user list
|
||||
users, err := parseWatchUserList(e.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// find user
|
||||
for i, u := range users {
|
||||
// early terminate
|
||||
if u.MalID == userId {
|
||||
users[i].Progress = progress
|
||||
users[i].Updated = updated
|
||||
newData, err := json.Marshal(users)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Put(bucketAnime, keyBytes, newData, nutsdb.Persistent)
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("%d schaut nicht %d", userId, animeId)
|
||||
})
|
||||
}
|
||||
|
||||
func ReadRegisteredUsers() ([]UserData, error) {
|
||||
var users []UserData
|
||||
err := db.View(
|
||||
|
||||
4
ober.go
4
ober.go
@@ -432,7 +432,9 @@ func processUpdateReq(ctx *fasthttp.RequestCtx, update bool) {
|
||||
// update or delete request
|
||||
if update {
|
||||
// anime exitsts => save
|
||||
animeData, err = AddUserToAnime(username, userId, anime.Anime)
|
||||
// get watch progress
|
||||
progress, updated, _ := FetchProgress(anime.Anime, userId, username, 0)
|
||||
animeData, err = AddUserToAnime(username, userId, anime.Anime, progress, updated)
|
||||
} else {
|
||||
// anime exitsts => delete
|
||||
animeData, err = DeleteUserFromAnime(username, userId, anime.Anime)
|
||||
|
||||
@@ -27,7 +27,33 @@ func Arbeit() {
|
||||
}
|
||||
}
|
||||
// refresh animelist of users
|
||||
// TODO
|
||||
animesUsers, err := ReadAnimeUsers()
|
||||
if err != nil {
|
||||
if err != nutsdb.ErrBucketEmpty {
|
||||
color.Errorln(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
// iterate anime
|
||||
for _, a := range animesUsers {
|
||||
// iterate users
|
||||
for _, u := range a.Users {
|
||||
newProgress, updated, err := FetchProgress(a.Anime, u.MalID, u.Username, u.Progress)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
continue
|
||||
}
|
||||
if newProgress == u.Progress {
|
||||
continue
|
||||
}
|
||||
// update db
|
||||
color.Infof("%s progress von %d: %d -> %d\n", u.Username, a.Anime, u.Progress, newProgress)
|
||||
err = UpdateUserAnimeProgress(a.Anime, u.MalID, newProgress, updated)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func LangeArbeiten() {
|
||||
|
||||
35
schaffer.go
35
schaffer.go
@@ -128,3 +128,38 @@ func SearchSeason(animeId int64) (*Anime, error) {
|
||||
}
|
||||
return nil, errors.New("anime not found")
|
||||
}
|
||||
|
||||
func FetchProgress(animeId, userId int64, username string, progress int) (int, time.Time, error) {
|
||||
// check watching first
|
||||
list, _, err := GetUserAnimeListData(username, malApiStatusW)
|
||||
if err != nil {
|
||||
return 0, time.Time{}, err
|
||||
}
|
||||
for _, a := range list.Data {
|
||||
// check if found
|
||||
if a.Node.ID == animeId {
|
||||
// check if progress changed
|
||||
if progress != a.ListStatus.NumEpisodesWatched {
|
||||
return a.ListStatus.NumEpisodesWatched, a.ListStatus.UpdatedAt, nil
|
||||
}
|
||||
return progress, a.ListStatus.UpdatedAt, nil
|
||||
}
|
||||
}
|
||||
// check completed
|
||||
list, _, err = GetUserAnimeListData(username, malApiStatusC)
|
||||
if err != nil {
|
||||
return 0, time.Time{}, err
|
||||
}
|
||||
for _, a := range list.Data {
|
||||
// check if found
|
||||
if a.Node.ID == animeId {
|
||||
// check if progress changed
|
||||
if progress != a.ListStatus.NumEpisodesWatched {
|
||||
return a.ListStatus.NumEpisodesWatched, a.ListStatus.UpdatedAt, nil
|
||||
}
|
||||
return progress, a.ListStatus.UpdatedAt, nil
|
||||
}
|
||||
}
|
||||
// has no progress or dropped/hold
|
||||
return 0, time.Now(), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user