diff --git a/.gitignore b/.gitignore index 66fd13c..f359ec9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +huso \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..53aa2db --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module github.com/ultrasn0w/huso + +go 1.18 + +require ( + github.com/allegro/bigcache/v3 v3.0.2 + github.com/fasthttp/router v1.4.8 + github.com/gookit/color v1.5.0 + github.com/valyala/fasthttp v1.35.0 + github.com/valyala/quicktemplate v1.7.0 + github.com/xujiajun/nutsdb v0.8.0 +) + +require ( + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/bwmarrin/snowflake v0.3.0 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/savsgio/gotils v0.0.0-20220401102855-e56b59f40436 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + 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-20220412211240-33da011f77ad // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1861a96 --- /dev/null +++ b/go.sum @@ -0,0 +1,72 @@ +github.com/allegro/bigcache/v3 v3.0.2 h1:AKZCw+5eAaVyNTBmI2fgyPVJhHkdWder3O9IrprcQfI= +github.com/allegro/bigcache/v3 v3.0.2/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= +github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fasthttp/router v1.4.8 h1:4zj4sAzXibjA6ZW19MdMe3GaYD1SM+TXrMLzHcVMBOI= +github.com/fasthttp/router v1.4.8/go.mod h1:UUtJdXFYlqYRQ32EAtWOvNYIZ1XfyC5JJIknWai6foI= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/savsgio/gotils v0.0.0-20220401102855-e56b59f40436 h1:sfTahD3f2BSjx9U3R4K09PkNuZZWthT7g6vzTIXNWkM= +github.com/savsgio/gotils v0.0.0-20220401102855-e56b59f40436/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/fasthttp v1.35.0 h1:wwkR8mZn2NbigFsaw2Zj5r+xkmzjbrA/lyTmiSlal/Y= +github.com/valyala/fasthttp v1.35.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= +github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xujiajun/gorouter v1.2.0/go.mod h1:yJrIta+bTNpBM/2UT8hLOaEAFckO+m/qmR3luMIQygM= +github.com/xujiajun/mmap-go v1.0.1 h1:7Se7ss1fLPPRW+ePgqGpCkfGIZzJV6JPq9Wq9iv/WHc= +github.com/xujiajun/mmap-go v1.0.1/go.mod h1:CNN6Sw4SL69Sui00p0zEzcZKbt+5HtEnYUsc6BKKRMg= +github.com/xujiajun/nutsdb v0.8.0 h1:BkXjifwlF3akHVoTQ8B3gdF183oq4QI0JQywazEZXkM= +github.com/xujiajun/nutsdb v0.8.0/go.mod h1:KOdR/RLPELQ6611VTMsSOUBSO2s7kXPINOiA/+1dlgc= +github.com/xujiajun/utils v0.0.0-20190123093513-8bf096c4f53b h1:jKG9OiL4T4xQN3IUrhUpc1tG+HfDXppkgVcrAiiaI/0= +github.com/xujiajun/utils v0.0.0-20190123093513-8bf096c4f53b/go.mod h1:AZd87GYJlUzl82Yab2kTjx1EyXSQCAfZDhpTo1SQC4k= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= +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= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/huso.go b/huso.go new file mode 100644 index 0000000..0c86d87 --- /dev/null +++ b/huso.go @@ -0,0 +1,67 @@ +package main + +import ( + "flag" + "log" + "os" + "os/signal" + "runtime" + "syscall" + "time" + + "github.com/allegro/bigcache/v3" + "github.com/gookit/color" +) + +const ( + husoVersion = "1.0" + seasonApiJikan = "seasons/now" + seasonApiMal = "anime/season/" +) + +var ( + webServerPort = flag.Int("port", 4876, "Port used by internal webserver") + malApiBaseUri = flag.String("malApiBaseUri", "https://api.myanimelist.net/v2/", "MyAnimeList API base URL") + 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 +) + +func main() { + // lese Flaggen + flag.Parse() + // bleib bei uns + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + + color.Notice.Printf("huso %s %s\n", husoVersion, runtime.Version()) + + // cache init + var err error + cache, err = bigcache.NewBigCache(bigcache.DefaultConfig(2 * time.Hour)) + if err != nil { + log.Fatal(err) + } + defer cache.Close() + + initSeason() + + go Arbeiten() + + go RunWebserv() + + //fmt.Printf("%+v\n", jik) + + <-sc +} + +func initSeason() { + _, bytes, err := GetSeasonDataAll() + if err != nil { + color.Errorln(err.Error()) + } + err = cache.Set(seasonApiJikan, bytes) + if err != nil { + color.Errorln(err.Error()) + } +} diff --git a/klotz.go b/klotz.go new file mode 100644 index 0000000..fd9fe94 --- /dev/null +++ b/klotz.go @@ -0,0 +1,135 @@ +package main + +import "time" + +type SeasonMal 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"` + Season struct { + Year int `json:"year"` + Season string `json:"season"` + } `json:"season"` +} + +type SeasonJikan struct { + Pagination struct { + LastVisiblePage int `json:"last_visible_page"` + HasNextPage bool `json:"has_next_page"` + CurrentPage int `json:"current_page"` + Items struct { + Count int `json:"count"` + Total int `json:"total"` + PerPage int `json:"per_page"` + } `json:"items"` + } `json:"pagination"` + Data []struct { + MalID int `json:"mal_id"` + URL string `json:"url"` + Images struct { + Jpg struct { + ImageURL string `json:"image_url"` + SmallImageURL string `json:"small_image_url"` + LargeImageURL string `json:"large_image_url"` + } `json:"jpg"` + Webp struct { + ImageURL string `json:"image_url"` + SmallImageURL string `json:"small_image_url"` + LargeImageURL string `json:"large_image_url"` + } `json:"webp"` + } `json:"images"` + Trailer struct { + YoutubeID string `json:"youtube_id"` + URL string `json:"url"` + EmbedURL string `json:"embed_url"` + Images struct { + ImageURL string `json:"image_url"` + SmallImageURL string `json:"small_image_url"` + MediumImageURL string `json:"medium_image_url"` + LargeImageURL string `json:"large_image_url"` + MaximumImageURL string `json:"maximum_image_url"` + } `json:"images"` + } `json:"trailer"` + Title string `json:"title"` + TitleEnglish string `json:"title_english"` + TitleJapanese string `json:"title_japanese"` + TitleSynonyms []string `json:"title_synonyms"` + Type string `json:"type"` + Source string `json:"source"` + Episodes int `json:"episodes"` + Status string `json:"status"` + Airing bool `json:"airing"` + Aired struct { + From time.Time `json:"from"` + To interface{} `json:"to"` + Prop struct { + From struct { + Day int `json:"day"` + Month int `json:"month"` + Year int `json:"year"` + } `json:"from"` + To struct { + Day interface{} `json:"day"` + Month interface{} `json:"month"` + Year interface{} `json:"year"` + } `json:"to"` + } `json:"prop"` + String string `json:"string"` + } `json:"aired"` + Duration string `json:"duration"` + Rating string `json:"rating"` + Score float64 `json:"score"` + ScoredBy int `json:"scored_by"` + Rank int `json:"rank"` + Popularity int `json:"popularity"` + Members int `json:"members"` + Favorites int `json:"favorites"` + Synopsis string `json:"synopsis"` + Background interface{} `json:"background"` + Season string `json:"season"` + Year int `json:"year"` + Broadcast struct { + Day string `json:"day"` + Time string `json:"time"` + Timezone string `json:"timezone"` + String string `json:"string"` + } `json:"broadcast"` + Producers []struct { + MalID int `json:"mal_id"` + Type string `json:"type"` + Name string `json:"name"` + URL string `json:"url"` + } `json:"producers"` + Licensors []interface{} `json:"licensors"` + Studios []struct { + MalID int `json:"mal_id"` + Type string `json:"type"` + Name string `json:"name"` + URL string `json:"url"` + } `json:"studios"` + Genres []struct { + MalID int `json:"mal_id"` + Type string `json:"type"` + Name string `json:"name"` + URL string `json:"url"` + } `json:"genres"` + ExplicitGenres []interface{} `json:"explicit_genres"` + Themes []struct { + MalID int `json:"mal_id"` + Type string `json:"type"` + Name string `json:"name"` + URL string `json:"url"` + } `json:"themes"` + Demographics []interface{} `json:"demographics"` + } `json:"data"` +} diff --git a/knecht.go b/knecht.go new file mode 100644 index 0000000..9352803 --- /dev/null +++ b/knecht.go @@ -0,0 +1,102 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "time" + + "github.com/gookit/color" + "github.com/valyala/fasthttp" +) + +func GetSeasonDataAll() (*SeasonJikan, []byte, error) { + color.Infoln("Aktuelle Season abfragen...") + data, bytes, err := GetSeasonDataJikan(1) + if err != nil { + return data, bytes, err + } + color.Infof("%d Anime auf %d Seiten\n", data.Pagination.Items.Total, data.Pagination.LastVisiblePage) + for i := 2; data.Pagination.HasNextPage; i++ { + color.Infof("Seite %d abfragen...\n", i) + time.Sleep(time.Second) + newData, _, err := GetSeasonDataJikan(i) + if err != nil { + return data, nil, err + } + data.Pagination.CurrentPage = newData.Pagination.CurrentPage + data.Pagination.HasNextPage = newData.Pagination.HasNextPage + data.Data = append(data.Data, newData.Data...) + data.Pagination.Items.Count += newData.Pagination.Items.Count + } + color.Infof("%d Anime bekommen\n", len(data.Data)) + bytes, err = json.Marshal(data) + return data, bytes, err +} + +func GetSeasonBytesJikan(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() + resp := fasthttp.AcquireResponse() + defer fasthttp.ReleaseRequest(req) + defer fasthttp.ReleaseResponse(resp) + + req.SetRequestURI(*malApiBaseUri + apiAddr) + req.Header.SetMethod(fasthttp.MethodGet) + req.Header.Add("X-MAL-CLIENT-ID", *malApiId) + err := fasthttp.Do(req, resp) + contentEncoding := resp.Header.Peek(fasthttp.HeaderContentEncoding) + if bytes.EqualFold(contentEncoding, []byte("gzip")) { + body, _ = resp.BodyGunzip() + } else { + body = resp.Body() + } + + if resp.StatusCode() != fasthttp.StatusOK { + return body, fmt.Errorf("unexpected response code: %s %d", *malApiBaseUri+apiAddr, resp.StatusCode()) + } + return body, err +} + +func GetDataJikan(apiAddr string) ([]byte, error) { + var body []byte + statusCode, body, err := fasthttp.Get(body, *jikanApiBaseUri+apiAddr) + if statusCode != fasthttp.StatusOK { + return body, fmt.Errorf("unexpected response code: %s %d", *jikanApiBaseUri+apiAddr, statusCode) + } + return body, err +} + +func GetCurrentSeasonString() string { + var now = time.Now() + switch now.Month() { + case time.January, time.February, time.March: + return fmt.Sprintf("%04d/winter", now.Year()) + case time.April, time.May, time.June: + return fmt.Sprintf("%04d/spring", now.Year()) + case time.July, time.August, time.September: + return fmt.Sprintf("%04d/summer", now.Year()) + case time.October, time.November, time.December: + return fmt.Sprintf("%04d/fall", now.Year()) + default: + return fmt.Sprintf("%04d", now.Year()) + } +} diff --git a/nuss.go b/nuss.go new file mode 100644 index 0000000..9149d7a --- /dev/null +++ b/nuss.go @@ -0,0 +1,16 @@ +package main + +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 +} diff --git a/ober.go b/ober.go new file mode 100644 index 0000000..d3298c6 --- /dev/null +++ b/ober.go @@ -0,0 +1,76 @@ +package main + +import ( + "encoding/json" + "log" + "strconv" + + "github.com/fasthttp/router" + "github.com/valyala/fasthttp" +) + +func RunWebserv() { + r := router.New() + r.GET("/", Start) + r.GET("/api/season", Season) + r.POST("api/register", Register) + log.Fatal(fasthttp.ListenAndServe(":"+strconv.Itoa(*webServerPort), r.Handler)) +} + +func Start(ctx *fasthttp.RequestCtx) { + data, err := cache.Get(seasonApiJikan) + if err != nil { + addErrorToCtx(ctx, err) + return + } + var seasonData SeasonJikan + err = json.Unmarshal(data, &seasonData) + if err != nil { + addErrorToCtx(ctx, err) + return + } + + WriteIndex(ctx, &seasonData) + + ctx.SetContentType("text/html; charset=utf-8") + ctx.SetStatusCode(fasthttp.StatusOK) +} + +func Season(ctx *fasthttp.RequestCtx) { + data, err := cache.Get(seasonApiJikan) + if err != nil { + addErrorToCtx(ctx, err) + return + } + var seasonData SeasonJikan + err = json.Unmarshal(data, &seasonData) + if err != nil { + addErrorToCtx(ctx, err) + return + } + + _, err = ctx.Write(data) + if err != nil { + addErrorToCtx(ctx, err) + return + } + + ctx.SetContentType("application/json; charset=utf-8") + ctx.SetStatusCode(fasthttp.StatusOK) +} + +func Register(ctx *fasthttp.RequestCtx) { + _, err := ctx.WriteString("AAA") + if err != nil { + addErrorToCtx(ctx, err) + return + } + + ctx.SetContentType("application/json; charset=utf-8") + ctx.SetStatusCode(fasthttp.StatusOK) +} + +func addErrorToCtx(ctx *fasthttp.RequestCtx, err error) { + ctx.WriteString(err.Error()) + ctx.SetStatusCode(fasthttp.StatusInternalServerError) +} diff --git a/praktikant.go b/praktikant.go new file mode 100644 index 0000000..0d622f7 --- /dev/null +++ b/praktikant.go @@ -0,0 +1,22 @@ +package main + +import ( + "time" + + "github.com/gookit/color" +) + +func Arbeiten() { + for range time.Tick(time.Hour) { + // Alle Daten + _, bytes, err := GetSeasonDataAll() + if err != nil { + color.Errorln(err.Error()) + } else { + err = cache.Set(seasonApiJikan, bytes) + if err != nil { + color.Errorln(err.Error()) + } + } + } +} diff --git a/season.qtpl b/season.qtpl new file mode 100644 index 0000000..a5f7def --- /dev/null +++ b/season.qtpl @@ -0,0 +1,42 @@ +{% package main %} +{% func Index(season *SeasonJikan) %} +{% collapsespace %} + + + + + + + + HUSO - Hanami universeller Serien Organizer + + +

HUSO - Hanami universeller Serien Organizer

+

Anime

+ + + + + +
Airing 📺{%d season.Pagination.Items.Total %}
+
+ + {% for _, anime := range season.Data %} + + + + + + {% endfor %} +
{%s anime.Title %}{%d anime.MalID %}{%s anime.Aired.String %}
+ + +{% endcollapsespace %} +{% endfunc %} \ No newline at end of file diff --git a/season.qtpl.go b/season.qtpl.go new file mode 100644 index 0000000..3fe6dae --- /dev/null +++ b/season.qtpl.go @@ -0,0 +1,81 @@ +// Code generated by qtc from "season.qtpl". DO NOT EDIT. +// See https://github.com/valyala/quicktemplate for details. + +//line season.qtpl:1 +package main + +//line season.qtpl:2 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line season.qtpl:2 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line season.qtpl:2 +func StreamIndex(qw422016 *qt422016.Writer, season *SeasonJikan) { +//line season.qtpl:2 + qw422016.N().S(` +`) +//line season.qtpl:3 + qw422016.N().S(` HUSO - Hanami universeller Serien Organizer

HUSO - Hanami universeller Serien Organizer

Anime

Airing 📺 `) +//line season.qtpl:26 + qw422016.N().D(season.Pagination.Items.Total) +//line season.qtpl:26 + qw422016.N().S(`

`) +//line season.qtpl:31 + for _, anime := range season.Data { +//line season.qtpl:31 + qw422016.N().S(` `) +//line season.qtpl:37 + } +//line season.qtpl:37 + qw422016.N().S(`
`) +//line season.qtpl:33 + qw422016.E().S(anime.Title) +//line season.qtpl:33 + qw422016.N().S(` `) +//line season.qtpl:34 + qw422016.N().D(anime.MalID) +//line season.qtpl:34 + qw422016.N().S(` `) +//line season.qtpl:35 + qw422016.E().S(anime.Aired.String) +//line season.qtpl:35 + qw422016.N().S(`
`) +//line season.qtpl:41 + qw422016.N().S(` +`) +//line season.qtpl:42 +} + +//line season.qtpl:42 +func WriteIndex(qq422016 qtio422016.Writer, season *SeasonJikan) { +//line season.qtpl:42 + qw422016 := qt422016.AcquireWriter(qq422016) +//line season.qtpl:42 + StreamIndex(qw422016, season) +//line season.qtpl:42 + qt422016.ReleaseWriter(qw422016) +//line season.qtpl:42 +} + +//line season.qtpl:42 +func Index(season *SeasonJikan) string { +//line season.qtpl:42 + qb422016 := qt422016.AcquireByteBuffer() +//line season.qtpl:42 + WriteIndex(qb422016, season) +//line season.qtpl:42 + qs422016 := string(qb422016.B) +//line season.qtpl:42 + qt422016.ReleaseByteBuffer(qb422016) +//line season.qtpl:42 + return qs422016 +//line season.qtpl:42 +}