mirror of
https://github.com/ultrasn0w/huso.git
synced 2025-12-13 10:29:52 +01:00
Compare commits
5 Commits
011103395d
...
89c65c29e8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89c65c29e8 | ||
|
|
95294eb344 | ||
|
|
be1419bfa7 | ||
|
|
1ae85f9110 | ||
|
|
96edfbde61 |
249
README.md
249
README.md
@@ -1,6 +1,253 @@
|
||||
# huso
|
||||
Hanami's universeller Serien Organizer
|
||||
|
||||
**This is the backend code**
|
||||
**Backend code**
|
||||
|
||||
## API
|
||||
|
||||
### General
|
||||
| Method | Route | Response |
|
||||
| - | - | - |
|
||||
| GET | / | Startseite als HTML |
|
||||
| GET | /api/log | Log als plaintext |
|
||||
|
||||
### Auth
|
||||
| Method | Route | Description | Response | Parameter | Header | POST-Body |
|
||||
| - | - | - | - | - | - | - |
|
||||
| GET | /api/auth/{user} | Test für Authentifizierung | (status code) | {user} = MAL username | X-HUSO-AUTH | |
|
||||
| POST | /api/register | Registrieren | RegisterData JSON | | | RegisterData JSON |
|
||||
| DELETE | /api/register | User löschen | RegisterData JSON | | | RegisterData JSON |
|
||||
|
||||
_RegisterData_
|
||||
```json
|
||||
{
|
||||
"username": "TESTUSERNAME",
|
||||
"malId": 42069,
|
||||
"secret": "1ef539ed34435873fc964c2c20da84f8793ae3731a154cffb41039f2f061cabe97dea18cfffa51c58f3f564f8e7f0cd0a98d7ba3dddb7301c0e7549626ea43af",
|
||||
"sauce": "31f3637d8d05ddca7deee89453e3b68a9b74860facd8d5a6768e5ca842571595c8d31e43ce0e996f893578d0bd2b61f3f3820ec03fbb30407e31a2603c887b1"
|
||||
}
|
||||
```
|
||||
_sauce_
|
||||
```
|
||||
SHA512(綾波レイ + malId + username)
|
||||
```
|
||||
_secret_
|
||||
```
|
||||
SHA512(SAUCE + PASSWORD)
|
||||
```
|
||||
|
||||
_X-HUSO-AUTH_ -> _secret_ des users
|
||||
|
||||
### Anime
|
||||
| Method | Route | Description | Response | Parameter | Header | POST-Body |
|
||||
| - | - | - | - | - | - | - |
|
||||
| GET | /api/season | Aktuelle Season holen | []Anime JSON | | | |
|
||||
| GET | /api/anime/{id} | Einzelnen Anime holen | Anime JSON | {id} = MAL Anime id | | |
|
||||
| GET | /api/animesearch | Anime auf MAL suchen | []Anime JSON | Query parameter {q} = Suchtext | | |
|
||||
|
||||
_[]Anime_
|
||||
```json
|
||||
[
|
||||
{
|
||||
"anime": 50265,
|
||||
"title": "Spy x Family",
|
||||
"titleEn": "",
|
||||
"titleJp": "SPY×FAMILY",
|
||||
"imageMedium": "https://cdn.myanimelist.net/images/anime/1441/122795.jpg",
|
||||
"imageLarge": "https://cdn.myanimelist.net/images/anime/1441/122795l.jpg",
|
||||
"imageThumb": "https://cdn.myanimelist.net/images/anime/1441/122795t.jpg",
|
||||
"url": "https://myanimelist.net/anime/50265",
|
||||
"type": "TV",
|
||||
"status": "Currently Airing",
|
||||
"episodes": 12,
|
||||
"synopsis": "ANYA~ [Written by MAL Rewrite]",
|
||||
"genres": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Action"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Comedy"
|
||||
}
|
||||
],
|
||||
"startDate": "2022-04-09T00:00:00Z",
|
||||
"endDate": "0001-01-01T00:00:00Z",
|
||||
"year": 2022,
|
||||
"season": "spring",
|
||||
"score": 9.07,
|
||||
"scoredBy": 191073,
|
||||
"rank": 5,
|
||||
"popularity": 239,
|
||||
"members": 661291,
|
||||
"source": "Manga",
|
||||
"weekday": "Saturdays",
|
||||
"studios": [
|
||||
{
|
||||
"id": 858,
|
||||
"name": "Wit Studio"
|
||||
},
|
||||
{
|
||||
"id": 1835,
|
||||
"name": "CloverWorks"
|
||||
}
|
||||
],
|
||||
"trailerUrl": "https://www.youtube.com/watch?v=ofXigq9aIpo",
|
||||
"trailerEmbedUrl": "https://www.youtube.com/embed/ofXigq9aIpo?enablejsapi=1&wmode=opaque&autoplay=1"
|
||||
},
|
||||
{
|
||||
"anime": 43608,
|
||||
"title": "Kaguya-sama wa Kokurasetai: Ultra Romantic",
|
||||
"titleEn": "Kaguya-sama: Love is War - Ultra Romantic",
|
||||
"titleJp": "かぐや様は告らせたい-ウルトラロマンティック-",
|
||||
"imageMedium": "https://cdn.myanimelist.net/images/anime/1160/122627.jpg",
|
||||
"imageLarge": "https://cdn.myanimelist.net/images/anime/1160/122627l.jpg",
|
||||
"imageThumb": "https://cdn.myanimelist.net/images/anime/1160/122627t.jpg",
|
||||
"url": "https://myanimelist.net/anime/43608",
|
||||
"type": "TV",
|
||||
"status": "Currently Airing",
|
||||
"episodes": 12,
|
||||
"synopsis": "Tsun [Written by MAL Rewrite]",
|
||||
"genres": [
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Comedy"
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"name": "Suspense"
|
||||
}
|
||||
],
|
||||
"startDate": "2022-04-09T00:00:00Z",
|
||||
"endDate": "0001-01-01T00:00:00Z",
|
||||
"year": 2022,
|
||||
"season": "spring",
|
||||
"score": 8.99,
|
||||
"scoredBy": 74937,
|
||||
"rank": 13,
|
||||
"popularity": 396,
|
||||
"members": 454326,
|
||||
"source": "Manga",
|
||||
"weekday": "Saturdays",
|
||||
"studios": [
|
||||
{
|
||||
"id": 56,
|
||||
"name": "A-1 Pictures"
|
||||
}
|
||||
],
|
||||
"trailerUrl": "https://www.youtube.com/watch?v=vFN5K-iAyV0",
|
||||
"trailerEmbedUrl": "https://www.youtube.com/embed/vFN5K-iAyV0?enablejsapi=1&wmode=opaque&autoplay=1"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### User
|
||||
| Method | Route | Description | Response | Parameter | Header | POST-Body |
|
||||
| - | - | - | - | - | - | - |
|
||||
| GET | /api/user/{user?} | MAL user suchen oder alle registrierten user holen | []User JSON | {user?} = optional: MAL username | | |
|
||||
|
||||
_[]User_
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 42069,
|
||||
"username": "TESTUSERNAME",
|
||||
"url": "https://myanimelist.net/profile/TESTUSERNAME",
|
||||
"imageUrl": "https://cdn.myanimelist.net/images/userimages/42069.jpg?t=1652707800",
|
||||
"lastOnline": "2022-01-01T06:26:42Z",
|
||||
"gender": "",
|
||||
"birthday": "0001-01-01T00:00:00Z",
|
||||
"location": "TEST",
|
||||
"joined": "2010-01-01T00:00:00Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Watch
|
||||
| Method | Route | Description | Response | Parameter | Header | POST-Body |
|
||||
| - | - | - | - | - | - | - |
|
||||
| GET | /api/watch/{user?} | Watches von user oder allen | []AnimeUser JSON | {user?} = optional: MAL username | | |
|
||||
| GET | /api/watchext/{user?} | Erweiterte Watches von user oder allen | []AnimeUserExtended JSON | {user?} = optional: MAL username | | |
|
||||
| POST | /api/watch/{user} | Neuen watch schicken | []AnimeUser JSON | {user} = MAL username | X-HUSO-AUTH | []AnimeUser JSON |
|
||||
| DELETE | /api/watch/{user} | Watch löschen | []AnimeUser JSON | {user} = MAL username | X-HUSO-AUTH | []AnimeUser JSON |
|
||||
|
||||
**Verwendung des JSON von GET und POST/DELETE unterscheiden sich. Bei POST/DELETE muss nur der zu verändernde Anime angegeben werden und sonst nichts.**
|
||||
|
||||
_[]AnimeUser_ (GET)
|
||||
```json
|
||||
[
|
||||
{
|
||||
"anime": 50265,
|
||||
"users": [
|
||||
{
|
||||
"username": "TESTUSERNAME",
|
||||
"malId": 42069,
|
||||
"progress": 6,
|
||||
"updated": "2022-05-15T20:44:35Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"anime": 40356,
|
||||
"users": [
|
||||
{
|
||||
"username": "TESTUSERNAME",
|
||||
"malId": 42069,
|
||||
"progress": 3,
|
||||
"updated": "2022-04-25T18:11:27Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
_[]AnimeUserExtended_ (GET)
|
||||
```json
|
||||
[
|
||||
{
|
||||
"anime": 50265,
|
||||
"users": [
|
||||
{
|
||||
"username": "TESTUSERNAME",
|
||||
"malId": 42069,
|
||||
"progress": 6,
|
||||
"updated": "2022-05-15T20:44:35Z"
|
||||
}
|
||||
],
|
||||
"data": { --SEE ANIME GET (Anime object)-- }
|
||||
},
|
||||
{
|
||||
"anime": 40356,
|
||||
"users": [
|
||||
{
|
||||
"username": "TESTUSERNAME",
|
||||
"malId": 42069,
|
||||
"progress": 3,
|
||||
"updated": "2022-04-25T18:11:27Z"
|
||||
}
|
||||
],
|
||||
"data": { --SEE ANIME GET (Anime object)-- }
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
_[]AnimeUser_ (POST/DELETE)
|
||||
```json
|
||||
[
|
||||
{
|
||||
"anime": 40356,
|
||||
"users": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Chat
|
||||
| Method | Route | Description | Response | Parameter | Header | POST-Body |
|
||||
| - | - | - | - | - | - | - |
|
||||
| GET | /api/chat/{id} | Chat für Anime holen | Plaintext chat | {id} = MAL Anime id | | |
|
||||
| POST | /api/chat/{id}/{user} | Chat für Anime senden | Plaintext chat mit neuer Nachricht | {id} = MAL Anime id; {user} = MAL username | X-HUSO-AUTH | Neue Nachricht in plaintext |
|
||||
|
||||
### Appointment [WIP]
|
||||
| Method | Route | Description | Response | Parameter | Header | POST-Body |
|
||||
| - | - | - | - | - | - | - |
|
||||
| GET | /api/appointment | Appointments holen | []Appointment | | | |
|
||||
|
||||
2
go.mod
2
go.mod
@@ -21,5 +21,5 @@ require (
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
github.com/xujiajun/mmap-go v1.0.1 // indirect
|
||||
github.com/xujiajun/utils v0.0.0-20190123093513-8bf096c4f53b // indirect
|
||||
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a // indirect
|
||||
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e // indirect
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@@ -59,8 +59,8 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a h1:N2T1jUrTQE9Re6TFF5PhvEHXHCguynGhKjWVsIUt5cY=
|
||||
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e h1:w36l2Uw3dRan1K3TyXriXvY+6T56GNmlKGcqiQUJDfM=
|
||||
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
||||
5
huso.go
5
huso.go
@@ -76,12 +76,12 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer animeCache.Close()
|
||||
seasoncache, err = bigcache.NewBigCache(bigcache.DefaultConfig(2 * time.Hour))
|
||||
seasoncache, err = bigcache.NewBigCache(bigcache.DefaultConfig(7 * time.Hour))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer seasoncache.Close()
|
||||
userCache, err = bigcache.NewBigCache(bigcache.DefaultConfig(7 * time.Hour))
|
||||
userCache, err = bigcache.NewBigCache(bigcache.DefaultConfig(5 * time.Hour))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -109,6 +109,7 @@ func main() {
|
||||
LangeArbeit()
|
||||
|
||||
go Arbeiten()
|
||||
go BissleArbeiten()
|
||||
go LangeArbeiten()
|
||||
|
||||
go RunWebserv()
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
func SearchAnime(query string) ([]Anime, []byte, error) {
|
||||
func SearchAnimeData(query string) ([]Anime, []byte, error) {
|
||||
var animes []Anime
|
||||
data, err := searchCache.Get(query)
|
||||
if err != nil {
|
||||
|
||||
52
ober.go
52
ober.go
@@ -91,21 +91,16 @@ func AnimeGet(ctx *fasthttp.RequestCtx) {
|
||||
ctx.SetStatusCode(fasthttp.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
// search season first
|
||||
anime, err := SearchSeason(malId)
|
||||
var bytes []byte
|
||||
// search anime
|
||||
anime, err := SearchAnime(malId)
|
||||
if err != nil {
|
||||
_, bytes, err = GetAnimeDetailData(malId)
|
||||
if err != nil {
|
||||
addErrorToCtx(ctx, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
bytes, err = json.Marshal(&anime)
|
||||
if err != nil {
|
||||
addErrorToCtx(ctx, err)
|
||||
return
|
||||
}
|
||||
addErrorToCtx(ctx, err)
|
||||
return
|
||||
}
|
||||
bytes, err := json.Marshal(&anime)
|
||||
if err != nil {
|
||||
addErrorToCtx(ctx, err)
|
||||
return
|
||||
}
|
||||
_, err = ctx.Write(bytes)
|
||||
if err != nil {
|
||||
@@ -123,8 +118,8 @@ func AnimeSearchGet(ctx *fasthttp.RequestCtx) {
|
||||
return
|
||||
}
|
||||
query := string(ctx.QueryArgs().Peek("q"))
|
||||
// Search with query
|
||||
_, bytes, err := SearchAnime(query)
|
||||
// search with query
|
||||
_, bytes, err := SearchAnimeData(query)
|
||||
if err != nil {
|
||||
addErrorToCtx(ctx, err)
|
||||
return
|
||||
@@ -271,7 +266,8 @@ func WatchExtendedGet(ctx *fasthttp.RequestCtx) {
|
||||
animeUsersExtended := make([]AnimeUserExtended, 0)
|
||||
// make list advanced
|
||||
for _, a := range animeUsers {
|
||||
data, _, err := GetAnimeDetailData(a.Anime)
|
||||
// search anime
|
||||
data, err := SearchAnime(a.Anime)
|
||||
if err != nil {
|
||||
addErrorToCtx(ctx, err)
|
||||
return
|
||||
@@ -540,16 +536,12 @@ func processUpdateReq(ctx *fasthttp.RequestCtx, update bool) {
|
||||
|
||||
// iterate sent animes
|
||||
for i, anime := range animes {
|
||||
// check if anime is in season
|
||||
_, err = SearchSeason(anime.Anime)
|
||||
// anime holen sie diese
|
||||
_, err = SearchAnime(anime.Anime)
|
||||
if err != nil {
|
||||
// anime not in season => holen sie diese
|
||||
_, _, err := GetAnimeDetailData(anime.Anime)
|
||||
if err != nil {
|
||||
ctx.WriteString(err.Error())
|
||||
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||
return
|
||||
}
|
||||
ctx.WriteString(err.Error())
|
||||
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
var animeData *AnimeUser
|
||||
@@ -557,7 +549,13 @@ func processUpdateReq(ctx *fasthttp.RequestCtx, update bool) {
|
||||
if update {
|
||||
// anime exitsts => save
|
||||
// get watch progress
|
||||
progress, updated, _ := FetchProgress(anime.Anime, userId, username, 0)
|
||||
progress, updated, listState, _ := FetchProgress(anime.Anime, userId, username, 0)
|
||||
// anime is already completed big baka user
|
||||
if listState == malApiStatusC {
|
||||
ctx.WriteString("Du hast schon fertig geschaut bro")
|
||||
ctx.SetStatusCode(fasthttp.StatusConflict)
|
||||
return
|
||||
}
|
||||
animeData, err = AddUserToAnime(username, userId, anime.Anime, progress, updated)
|
||||
} else {
|
||||
// anime exitsts => delete
|
||||
|
||||
@@ -17,18 +17,6 @@ func Arbeiten() {
|
||||
}
|
||||
|
||||
func Arbeit() {
|
||||
// season data
|
||||
_, bytes, err := GetSeasonDataAll()
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
logOut.WriteError(err)
|
||||
} else {
|
||||
err = seasoncache.Set(seasonApiJikan, bytes)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
logOut.WriteError(err)
|
||||
}
|
||||
}
|
||||
// refresh animelist of users
|
||||
animesUsers, err := ReadAnimeUsers()
|
||||
if err != nil {
|
||||
@@ -42,7 +30,7 @@ func Arbeit() {
|
||||
for _, a := range animesUsers {
|
||||
// iterate users
|
||||
for _, u := range a.Users {
|
||||
newProgress, updated, err := FetchProgress(a.Anime, u.MalID, u.Username, u.Progress)
|
||||
newProgress, updated, listState, err := FetchProgress(a.Anime, u.MalID, u.Username, u.Progress)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
logOut.WriteError(err)
|
||||
@@ -51,9 +39,21 @@ func Arbeit() {
|
||||
if newProgress == u.Progress {
|
||||
continue
|
||||
}
|
||||
// update db
|
||||
color.Infof("%s progress von %d: %d -> %d\n", u.Username, a.Anime, u.Progress, newProgress)
|
||||
logOut.WriteLine(fmt.Sprintf("📜 %s progress von %d: %d -> %d", u.Username, a.Anime, u.Progress, newProgress))
|
||||
// check if user set anime as completed
|
||||
if listState == malApiStatusC {
|
||||
color.Infof("%s finished %d\n", u.Username, a.Anime)
|
||||
logOut.WriteLine(fmt.Sprintf("📜 %s finished %d !", u.Username, a.Anime))
|
||||
// delete user from anime
|
||||
_, err = DeleteUserFromAnime(u.Username, u.MalID, a.Anime)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
logOut.WriteError(err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
// update db
|
||||
err = UpdateUserAnimeProgress(a.Anime, u.MalID, newProgress, updated)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
@@ -63,16 +63,15 @@ func Arbeit() {
|
||||
}
|
||||
}
|
||||
|
||||
func LangeArbeiten() {
|
||||
for range time.Tick(6 * time.Hour) {
|
||||
LangeArbeit()
|
||||
func BissleArbeiten() {
|
||||
for range time.Tick(4 * time.Hour) {
|
||||
BissleArbeit()
|
||||
}
|
||||
}
|
||||
|
||||
func LangeArbeit() {
|
||||
count := 0
|
||||
|
||||
func BissleArbeit() {
|
||||
// refresh user cache
|
||||
count := 0
|
||||
regUsers, err := ReadRegisteredUsers()
|
||||
if err != nil {
|
||||
// check if no users registered
|
||||
@@ -93,9 +92,30 @@ func LangeArbeit() {
|
||||
}
|
||||
color.Infof("%d User aktualisiert\n", count)
|
||||
logOut.WriteLine(fmt.Sprintf("🔃 %d User aktualisiert", count))
|
||||
}
|
||||
|
||||
func LangeArbeiten() {
|
||||
for range time.Tick(6 * time.Hour) {
|
||||
LangeArbeit()
|
||||
}
|
||||
}
|
||||
|
||||
func LangeArbeit() {
|
||||
// season data
|
||||
_, bytes, err := GetSeasonDataAll()
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
logOut.WriteError(err)
|
||||
} else {
|
||||
err = seasoncache.Set(seasonApiJikan, bytes)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
logOut.WriteError(err)
|
||||
}
|
||||
}
|
||||
|
||||
count = 0
|
||||
// refresh anime cache with watched
|
||||
count := 0
|
||||
animesUsers, err := ReadAnimeUsers()
|
||||
if err != nil {
|
||||
if err != nutsdb.ErrBucketEmpty {
|
||||
@@ -106,7 +126,7 @@ func LangeArbeit() {
|
||||
for _, a := range animesUsers {
|
||||
// search season first
|
||||
_, err = SearchSeason(a.Anime)
|
||||
if err != nil {
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
err = refreshAnime(a.Anime)
|
||||
|
||||
63
schaffer.go
63
schaffer.go
@@ -132,24 +132,50 @@ 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)
|
||||
func SearchAnime(animeId int64) (*Anime, error) {
|
||||
// search season first
|
||||
anime, err := SearchSeason(animeId)
|
||||
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
|
||||
// get from MAL
|
||||
anime, _, err = GetAnimeDetailData(animeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return anime, err
|
||||
}
|
||||
|
||||
func FetchProgress(animeId, userId int64, username string, progress int) (int, time.Time, string, error) {
|
||||
// check watching first
|
||||
newProgress, updated, err := fetchProgressOnState(animeId, userId, progress, username, malApiStatusW)
|
||||
if err != nil {
|
||||
return newProgress, updated, "", err
|
||||
}
|
||||
if newProgress != -1 {
|
||||
return newProgress, updated, malApiStatusW, err
|
||||
}
|
||||
// check on hold
|
||||
newProgress, updated, err = fetchProgressOnState(animeId, userId, progress, username, malApiStatusH)
|
||||
if err != nil {
|
||||
return newProgress, updated, "", err
|
||||
}
|
||||
if newProgress != -1 {
|
||||
return newProgress, updated, malApiStatusH, err
|
||||
}
|
||||
// check completed
|
||||
list, _, err = GetUserAnimeListData(username, malApiStatusC)
|
||||
newProgress, updated, err = fetchProgressOnState(animeId, userId, progress, username, malApiStatusC)
|
||||
if err != nil {
|
||||
return newProgress, updated, "", err
|
||||
}
|
||||
if newProgress != -1 {
|
||||
return newProgress, updated, malApiStatusC, err
|
||||
}
|
||||
// has no progress or dropped
|
||||
return 0, updated, "", nil
|
||||
}
|
||||
|
||||
func fetchProgressOnState(animeId, userId int64, progress int, username, malStatus string) (int, time.Time, error) {
|
||||
list, _, err := GetUserAnimeListData(username, malStatus)
|
||||
if err != nil {
|
||||
return 0, time.Time{}, err
|
||||
}
|
||||
@@ -157,14 +183,11 @@ func FetchProgress(animeId, userId int64, username string, progress int) (int, t
|
||||
// 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
|
||||
return a.ListStatus.NumEpisodesWatched, a.ListStatus.UpdatedAt, nil
|
||||
}
|
||||
}
|
||||
// has no progress or dropped/hold
|
||||
return 0, time.Now(), nil
|
||||
// no progess found
|
||||
return -1, time.Now(), nil
|
||||
}
|
||||
|
||||
func AddToChat(old, new, user string) string {
|
||||
|
||||
Reference in New Issue
Block a user