From cf70db1f9630b97e92ca4ed193b4aa980e83ed67 Mon Sep 17 00:00:00 2001 From: daru Date: Thu, 14 Apr 2022 00:33:38 +0200 Subject: [PATCH] Users + Nuts + Sauce --- .gitignore | 3 ++- README.md | 2 ++ go.sum | 1 - huso.go | 22 ++++++++++++++++-- klotz.go | 43 ++++++++++++++++++++++++++++++++++ knecht.go | 64 ++++++++++++++++++++++++++++++++++++++++----------- nuss.go | 49 +++++++++++++++++++++++++++++++-------- ober.go | 33 +++++++++++++++++++++----- praktikant.go | 5 ++++ 9 files changed, 190 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index f359ec9..092a929 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ # Dependency directories (remove the comment below to include it) # vendor/ -huso \ No newline at end of file +huso +nuts/* diff --git a/README.md b/README.md index b7afb60..70f0a93 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,5 @@ Hanami's universeller Serien Organizer **This is the backend code** + +## API diff --git a/go.sum b/go.sum index 1861a96..064c018 100644 --- a/go.sum +++ b/go.sum @@ -57,7 +57,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/huso.go b/huso.go index 0c86d87..5f9a582 100644 --- a/huso.go +++ b/huso.go @@ -11,12 +11,20 @@ import ( "github.com/allegro/bigcache/v3" "github.com/gookit/color" + "github.com/xujiajun/nutsdb" ) const ( husoVersion = "1.0" + registerSecret = "綾波レイ" seasonApiJikan = "seasons/now" - seasonApiMal = "anime/season/" + userApiJikan = "users/" + userApiMal = "users/" + malApiStatusP = "plan_to_watch" + malApiStatusW = "watching" + malApiStatusC = "completed" + malApiStatusH = "on_hold" + malApiStatusD = "dropped" ) var ( @@ -25,6 +33,7 @@ var ( jikanApiBaseUri = flag.String("jikanApiBaseUri", "https://api.jikan.moe/v4/", "Jikan API base URL") malApiId = flag.String("malApiId", "cc17dcf40581b9dfc8a5a12dba458153", "MyAnimeList API Client ID") cache *bigcache.BigCache + db *nutsdb.DB ) func main() { @@ -44,13 +53,22 @@ func main() { } defer cache.Close() + nutsOpt := nutsdb.DefaultOptions + nutsOpt.Dir = "nuts" + db, err = nutsdb.Open(nutsOpt) + if err != nil { + log.Fatal(err) + } + defer db.Close() + initSeason() go Arbeiten() go RunWebserv() - //fmt.Printf("%+v\n", jik) + //list, _, _ := GetUserAnimeListData("ultrasn0w", malApiStatusW) + //fmt.Printf("%+v\n", list) <-sc } diff --git a/klotz.go b/klotz.go index fd9fe94..7122866 100644 --- a/klotz.go +++ b/klotz.go @@ -2,6 +2,49 @@ package main import "time" +type RegisterData struct { + Username string `json:"username"` + MalId int `json:"malId"` + Sauce string `json:"sauce"` +} + +type AnimeListMal struct { + Data []struct { + Node struct { + ID int `json:"id"` + Title string `json:"title"` + MainPicture struct { + Medium string `json:"medium"` + Large string `json:"large"` + } `json:"main_picture"` + } `json:"node"` + } `json:"data"` + Paging struct { + Next string `json:"next"` + } `json:"paging"` +} + +type UserJikan struct { + Data struct { + MalID int `json:"mal_id"` + Username string `json:"username"` + URL string `json:"url"` + Images struct { + Jpg struct { + ImageURL string `json:"image_url"` + } `json:"jpg"` + Webp struct { + ImageURL string `json:"image_url"` + } `json:"webp"` + } `json:"images"` + LastOnline time.Time `json:"last_online"` + Gender interface{} `json:"gender"` + Birthday interface{} `json:"birthday"` + Location string `json:"location"` + Joined time.Time `json:"joined"` + } `json:"data"` +} + type SeasonMal struct { Data []struct { Node struct { diff --git a/knecht.go b/knecht.go index 9352803..20d3bde 100644 --- a/knecht.go +++ b/knecht.go @@ -11,9 +11,47 @@ import ( "github.com/valyala/fasthttp" ) +func GetUserAnimeListData(username, status string) (*AnimeListMal, []byte, error) { + var list AnimeListMal + body, err := GetUserAnimeListBytes(username, status) + if err != nil { + return nil, body, err + } + 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) +} + +func GetUserData(username string) (*UserJikan, []byte, error) { + var user UserJikan + body, err := GetUserBytesCached(username) + if err != nil { + return nil, body, err + } + err = json.Unmarshal(body, &user) + return &user, body, err +} + +func GetUserBytesCached(username string) ([]byte, error) { + key := userApiJikan + username + data, err := cache.Get(key) + if err != nil { + data, err = GetDataJikan(key) + if err != nil { + return data, err + } + cache.Set(key, data) + return data, err + } + return data, err +} + func GetSeasonDataAll() (*SeasonJikan, []byte, error) { color.Infoln("Aktuelle Season abfragen...") - data, bytes, err := GetSeasonDataJikan(1) + data, bytes, err := GetSeasonData(1) if err != nil { return data, bytes, err } @@ -21,7 +59,7 @@ func GetSeasonDataAll() (*SeasonJikan, []byte, error) { for i := 2; data.Pagination.HasNextPage; i++ { color.Infof("Seite %d abfragen...\n", i) time.Sleep(time.Second) - newData, _, err := GetSeasonDataJikan(i) + newData, _, err := GetSeasonData(i) if err != nil { return data, nil, err } @@ -35,23 +73,23 @@ func GetSeasonDataAll() (*SeasonJikan, []byte, error) { return data, bytes, err } -func GetSeasonBytesJikan(page int) ([]byte, error) { +func GetSeasonData(page int) (*SeasonJikan, []byte, error) { + var data SeasonJikan + body, err := GetSeasonBytes(page) + if err != nil { + return nil, body, err + } + err = json.Unmarshal(body, &data) + return &data, body, err +} + +func GetSeasonBytes(page int) ([]byte, error) { if page != 0 { return GetDataJikan(seasonApiJikan + "?page=" + strconv.Itoa(page)) } return GetDataJikan(seasonApiJikan) } -func GetSeasonDataJikan(page int) (*SeasonJikan, []byte, error) { - var data SeasonJikan - body, err := GetSeasonBytesJikan(page) - if err != nil { - return nil, nil, err - } - err = json.Unmarshal(body, &data) - return &data, body, err -} - func GetDataMal(apiAddr string) ([]byte, error) { var body []byte req := fasthttp.AcquireRequest() diff --git a/nuss.go b/nuss.go index 9149d7a..e9ecb06 100644 --- a/nuss.go +++ b/nuss.go @@ -4,13 +4,44 @@ import ( "github.com/xujiajun/nutsdb" ) -func Nuss() (*nutsdb.DB, error) { - opt := nutsdb.DefaultOptions - // TODO change - opt.Dir = "/tmp/yagoodb" - db, err := nutsdb.Open(opt) - if err != nil { - return nil, err - } - return db, err +func DbClean() error { + err := db.Update( + func(tx *nutsdb.Tx) error { + return db.Merge() + }) + return err +} + +func DbSave(bucket, key string, val []byte) error { + err := db.Update( + func(tx *nutsdb.Tx) error { + keyBytes := []byte(key) + return tx.Put(bucket, keyBytes, val, 0) + }) + return err +} + +func DbRead(bucket, key string) ([]byte, error) { + var val []byte + err := db.View( + func(tx *nutsdb.Tx) error { + key := []byte("name1") + e, err := tx.Get(bucket, key) + if err != nil { + return err + } + val = make([]byte, e.Size()) + copy(val, e.Value) + return err + }) + return val, err +} + +func DbDelete(bucket, key string, val []byte) error { + err := db.Update( + func(tx *nutsdb.Tx) error { + keyBytes := []byte(key) + return tx.Delete(bucket, keyBytes) + }) + return err } diff --git a/ober.go b/ober.go index d3298c6..52e253f 100644 --- a/ober.go +++ b/ober.go @@ -1,9 +1,12 @@ package main import ( + "crypto/sha512" "encoding/json" + "fmt" "log" "strconv" + "strings" "github.com/fasthttp/router" "github.com/valyala/fasthttp" @@ -13,7 +16,7 @@ func RunWebserv() { r := router.New() r.GET("/", Start) r.GET("/api/season", Season) - r.POST("api/register", Register) + r.POST("/api/register", Register) log.Fatal(fasthttp.ListenAndServe(":"+strconv.Itoa(*webServerPort), r.Handler)) } @@ -60,13 +63,31 @@ func Season(ctx *fasthttp.RequestCtx) { } func Register(ctx *fasthttp.RequestCtx) { - _, err := ctx.WriteString("AAA") - if err != nil { - addErrorToCtx(ctx, err) + if string(ctx.Request.Header.ContentType()) != "application/json" { + ctx.SetStatusCode(fasthttp.StatusBadRequest) return } - - ctx.SetContentType("application/json; charset=utf-8") + body := ctx.PostBody() + var register RegisterData + err := json.Unmarshal(body, ®ister) + if err != nil { + ctx.WriteString(err.Error()) + ctx.SetStatusCode(fasthttp.StatusBadRequest) + return + } + if register.MalId == 0 || register.Username == "" || register.Sauce == "" { + ctx.WriteString("Sprich JSON du Hurensohn") + ctx.SetStatusCode(fasthttp.StatusBadRequest) + return + } + calcSauce := fmt.Sprintf("%x", sha512.Sum512([]byte(registerSecret+strconv.Itoa(register.MalId)+register.Username))) + if calcSauce != strings.ToLower(register.Sauce) { + ctx.WriteString("Möge die Sauce mit dir sein") + ctx.SetStatusCode(fasthttp.StatusBadRequest) + return + } + // TODO REGISTER + ctx.SetBody(body) ctx.SetStatusCode(fasthttp.StatusOK) } diff --git a/praktikant.go b/praktikant.go index 0d622f7..d123296 100644 --- a/praktikant.go +++ b/praktikant.go @@ -18,5 +18,10 @@ func Arbeiten() { color.Errorln(err.Error()) } } + + err = DbClean() + if err != nil { + color.Errorln(err.Error()) + } } }