mirror of
https://github.com/ultrasn0w/huso.git
synced 2025-12-14 19:09:54 +01:00
Implement MovieManager connection
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@
|
|||||||
|
|
||||||
huso
|
huso
|
||||||
nuts/*
|
nuts/*
|
||||||
|
mm.cred
|
||||||
|
|||||||
1
build.sh
1
build.sh
@@ -1,2 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
date=$(date '+%Y-%m-%dT%H:%M:%S')
|
date=$(date '+%Y-%m-%dT%H:%M:%S')
|
||||||
go build -ldflags "-X main.buildTime=$date"
|
go build -ldflags "-X main.buildTime=$date"
|
||||||
1
go.mod
1
go.mod
@@ -5,6 +5,7 @@ go 1.18
|
|||||||
require (
|
require (
|
||||||
github.com/allegro/bigcache/v3 v3.0.2
|
github.com/allegro/bigcache/v3 v3.0.2
|
||||||
github.com/fasthttp/router v1.4.10
|
github.com/fasthttp/router v1.4.10
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0
|
||||||
github.com/gookit/color v1.5.1
|
github.com/gookit/color v1.5.1
|
||||||
github.com/valyala/fasthttp v1.38.0
|
github.com/valyala/fasthttp v1.38.0
|
||||||
github.com/valyala/quicktemplate v1.7.0
|
github.com/valyala/quicktemplate v1.7.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -11,6 +11,8 @@ 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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fasthttp/router v1.4.10 h1:C8z6K1pTqhLjSv97/qCY9tZiiPT8JuFwDoO9E2HJFWQ=
|
github.com/fasthttp/router v1.4.10 h1:C8z6K1pTqhLjSv97/qCY9tZiiPT8JuFwDoO9E2HJFWQ=
|
||||||
github.com/fasthttp/router v1.4.10/go.mod h1:FGSUOg9SQ/tU864SfD23kG/HwfD0akXqOqhTQ27gTFQ=
|
github.com/fasthttp/router v1.4.10/go.mod h1:FGSUOg9SQ/tU864SfD23kG/HwfD0akXqOqhTQ27gTFQ=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
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/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
|
github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
|
||||||
|
|||||||
39
huso.go
39
huso.go
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/allegro/bigcache/v3"
|
"github.com/allegro/bigcache/v3"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
"github.com/xujiajun/nutsdb"
|
"github.com/xujiajun/nutsdb"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
@@ -45,12 +47,16 @@ var (
|
|||||||
jikanApiBaseUri = flag.String("jikanApiBaseUri", "https://api.jikan.moe/v4/", "Jikan 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")
|
malApiId = flag.String("malApiId", "cc17dcf40581b9dfc8a5a12dba458153", "MyAnimeList API Client ID")
|
||||||
localServer = flag.Bool("localServer", false, "Set varius headers for running locally")
|
localServer = flag.Bool("localServer", false, "Set varius headers for running locally")
|
||||||
|
mmDbServer = flag.String("mmDbServer", "hanami.family:3306", "MovieManager db server")
|
||||||
|
mmDbUser = flag.String("mmDbUser", "yui", "MovieManager db user")
|
||||||
animeCache *bigcache.BigCache
|
animeCache *bigcache.BigCache
|
||||||
seasoncache *bigcache.BigCache
|
seasoncache *bigcache.BigCache
|
||||||
userCache *bigcache.BigCache
|
userCache *bigcache.BigCache
|
||||||
searchCache *bigcache.BigCache
|
searchCache *bigcache.BigCache
|
||||||
animeListCache *bigcache.BigCache
|
animeListCache *bigcache.BigCache
|
||||||
|
mmCache *bigcache.BigCache
|
||||||
db *nutsdb.DB
|
db *nutsdb.DB
|
||||||
|
mmDb *sql.DB
|
||||||
jikanLimiter *rate.Limiter
|
jikanLimiter *rate.Limiter
|
||||||
logOut *RingBuf
|
logOut *RingBuf
|
||||||
buildTime string
|
buildTime string
|
||||||
@@ -66,7 +72,7 @@ func main() {
|
|||||||
logOut = NewRingBuf(10101)
|
logOut = NewRingBuf(10101)
|
||||||
|
|
||||||
color.Notice.Printf("huso %s built on %s with %s\n", husoVersion, buildTime, runtime.Version())
|
color.Notice.Printf("huso %s built on %s with %s\n", husoVersion, buildTime, runtime.Version())
|
||||||
logOut.WriteLine(fmt.Sprintf("🎉 huso %s built on %s with %s\n", husoVersion, buildTime, runtime.Version()))
|
logOut.WriteLine(fmt.Sprintf("🎉 huso %s built on %s with %s", husoVersion, buildTime, runtime.Version()))
|
||||||
|
|
||||||
jikanLimiter = rate.NewLimiter(rate.Every(time.Second), 1)
|
jikanLimiter = rate.NewLimiter(rate.Every(time.Second), 1)
|
||||||
|
|
||||||
@@ -97,6 +103,11 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer animeListCache.Close()
|
defer animeListCache.Close()
|
||||||
|
mmCache, err = bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer mmCache.Close()
|
||||||
|
|
||||||
nutsOpt := nutsdb.DefaultOptions
|
nutsOpt := nutsdb.DefaultOptions
|
||||||
nutsOpt.Dir = "nuts"
|
nutsOpt.Dir = "nuts"
|
||||||
@@ -106,6 +117,32 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
|
color.Infoln("NutsDB connected")
|
||||||
|
logOut.WriteLine("🗃️ NutsDB connected")
|
||||||
|
|
||||||
|
conns, err := GetMmConnString()
|
||||||
|
if err != nil {
|
||||||
|
color.Errorln(err.Error())
|
||||||
|
} else {
|
||||||
|
mmDb, err = sql.Open("mysql", conns)
|
||||||
|
if err != nil || mmDb == nil {
|
||||||
|
color.Errorln(err.Error())
|
||||||
|
} else {
|
||||||
|
mmDb.SetConnMaxLifetime(time.Minute * 3)
|
||||||
|
mmDb.SetMaxOpenConns(10)
|
||||||
|
mmDb.SetMaxIdleConns(10)
|
||||||
|
defer mmDb.Close()
|
||||||
|
|
||||||
|
err = mmDb.Ping()
|
||||||
|
if err != nil {
|
||||||
|
color.Errorln(err.Error())
|
||||||
|
} else {
|
||||||
|
color.Infoln("MovieManager DB connected")
|
||||||
|
logOut.WriteLine("🗃️ MovieManager DB connected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Arbeit()
|
Arbeit()
|
||||||
LangeArbeit()
|
LangeArbeit()
|
||||||
|
|
||||||
|
|||||||
7
klotz.go
7
klotz.go
@@ -310,3 +310,10 @@ type SeasonJikan struct {
|
|||||||
} `json:"pagination"`
|
} `json:"pagination"`
|
||||||
Data []SeasonAnimeJikan `json:"data"`
|
Data []SeasonAnimeJikan `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MmOracle struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Anime int64 `json:"anime"`
|
||||||
|
AvgScore int `json:"avgScore"`
|
||||||
|
}
|
||||||
|
|||||||
8
ober.go
8
ober.go
@@ -44,7 +44,13 @@ func Start(ctx *fasthttp.RequestCtx) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteIndex(ctx, season, logOut.String())
|
oracles, err := MmReadOracle()
|
||||||
|
if err != nil {
|
||||||
|
addErrorToCtx(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteIndex(ctx, season, oracles, logOut.String())
|
||||||
|
|
||||||
ctx.SetContentType("text/html; charset=utf-8")
|
ctx.SetContentType("text/html; charset=utf-8")
|
||||||
ctx.SetStatusCode(fasthttp.StatusOK)
|
ctx.SetStatusCode(fasthttp.StatusOK)
|
||||||
|
|||||||
@@ -43,3 +43,7 @@ func BytesToInt64AndDate(bytes []byte) (int64, time.Time, error) {
|
|||||||
func Int64AndDateToBytes(num int64, appoint time.Time) []byte {
|
func Int64AndDateToBytes(num int64, appoint time.Time) []byte {
|
||||||
return []byte(fmt.Sprintf("%d%s%s", num, AppointSplit, appoint.Format(time.RFC3339)))
|
return []byte(fmt.Sprintf("%d%s%s", num, AppointSplit, appoint.Format(time.RFC3339)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PrintDate(t time.Time) string {
|
||||||
|
return t.Format("2006-01-02")
|
||||||
|
}
|
||||||
|
|||||||
22
season.qtpl
22
season.qtpl
@@ -1,5 +1,5 @@
|
|||||||
{% package main %}
|
{% package main %}
|
||||||
{% func Index(animes []Anime, log string) %}
|
{% func Index(animes []Anime, oracles []MmOracle, log string) %}
|
||||||
{% collapsespace %}
|
{% collapsespace %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -19,6 +19,8 @@ body { background-color: #1a1a1a; color: #fff; }
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>HUSO - Hanami universeller Serien Organizer</h1>
|
<h1>HUSO - Hanami universeller Serien Organizer</h1>
|
||||||
|
<h2>Log</h2>
|
||||||
|
<pre>{%s log %}</pre>
|
||||||
<h2>Anime</h2>
|
<h2>Anime</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -30,16 +32,24 @@ body { background-color: #1a1a1a; color: #fff; }
|
|||||||
<table>
|
<table>
|
||||||
{% for _, anime := range animes %}
|
{% for _, anime := range animes %}
|
||||||
<tr>
|
<tr>
|
||||||
|
<td><a href="{%s anime.URL %}" target="_blank" rel="noopener noreferrer">{%dl anime.Anime %}</a></td>
|
||||||
<td><strong>{%s anime.Title %}</strong></td>
|
<td><strong>{%s anime.Title %}</strong></td>
|
||||||
<td>{%dl anime.Anime %}</td>
|
|
||||||
<td>{%d anime.Episodes %}</td>
|
<td>{%d anime.Episodes %}</td>
|
||||||
|
<td>{%f anime.Score %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<h2>MovieManager Oracle</h2>
|
||||||
|
<table>
|
||||||
|
{% for _, oracle := range oracles %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://movies.hanami.family/movie/{%d oracle.Id %}" target="_blank" rel="noopener noreferrer">{%d oracle.Id %}</a></td>
|
||||||
|
<td>{%d oracle.AvgScore %}</td>
|
||||||
|
<td><strong>{%s oracle.Title %}</strong></td>
|
||||||
|
<td>{%dl oracle.Anime %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<h2>Log</h2>
|
|
||||||
<pre>
|
|
||||||
{%s log %}
|
|
||||||
</pre>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{% endcollapsespace %}
|
{% endcollapsespace %}
|
||||||
|
|||||||
130
season.qtpl.go
130
season.qtpl.go
@@ -18,68 +18,104 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//line season.qtpl:2
|
//line season.qtpl:2
|
||||||
func StreamIndex(qw422016 *qt422016.Writer, animes []Anime, log string) {
|
func StreamIndex(qw422016 *qt422016.Writer, animes []Anime, oracles []MmOracle, log string) {
|
||||||
//line season.qtpl:2
|
//line season.qtpl:2
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line season.qtpl:3
|
//line season.qtpl:3
|
||||||
qw422016.N().S(` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { font-family: sans-serif; } table { border-spacing: 0; } td, th { text-align: left; padding: 0 0.5em; } td:first-child, th:first-child { padding-left: 0; } td:last-child, th:first-child { padding-right: 0; } body { background-color: #1a1a1a; color: #fff; } </style> <title>HUSO - Hanami universeller Serien Organizer</title> </head> <body> <h1>HUSO - Hanami universeller Serien Organizer</h1> <h2>Anime</h2> <table> <tr> <td><strong>Airing 📺</strong></td> <td>`)
|
qw422016.N().S(` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { font-family: sans-serif; } table { border-spacing: 0; } td, th { text-align: left; padding: 0 0.5em; } td:first-child, th:first-child { padding-left: 0; } td:last-child, th:first-child { padding-right: 0; } body { background-color: #1a1a1a; color: #fff; } </style> <title>HUSO - Hanami universeller Serien Organizer</title> </head> <body> <h1>HUSO - Hanami universeller Serien Organizer</h1> <h2>Log</h2> <pre>`)
|
||||||
//line season.qtpl:26
|
//line season.qtpl:23
|
||||||
qw422016.N().D(len(animes))
|
|
||||||
//line season.qtpl:26
|
|
||||||
qw422016.N().S(`</td> </tr> </table> </br> <table> `)
|
|
||||||
//line season.qtpl:31
|
|
||||||
for _, anime := range animes {
|
|
||||||
//line season.qtpl:31
|
|
||||||
qw422016.N().S(` <tr> <td><strong>`)
|
|
||||||
//line season.qtpl:33
|
|
||||||
qw422016.E().S(anime.Title)
|
|
||||||
//line season.qtpl:33
|
|
||||||
qw422016.N().S(`</strong></td> <td>`)
|
|
||||||
//line season.qtpl:34
|
|
||||||
qw422016.N().DL(anime.Anime)
|
|
||||||
//line season.qtpl:34
|
|
||||||
qw422016.N().S(`</td> <td>`)
|
|
||||||
//line season.qtpl:35
|
|
||||||
qw422016.N().D(anime.Episodes)
|
|
||||||
//line season.qtpl:35
|
|
||||||
qw422016.N().S(`</td> </tr> `)
|
|
||||||
//line season.qtpl:37
|
|
||||||
}
|
|
||||||
//line season.qtpl:37
|
|
||||||
qw422016.N().S(` </table> <h2>Log</h2> <pre> `)
|
|
||||||
//line season.qtpl:41
|
|
||||||
qw422016.E().S(log)
|
qw422016.E().S(log)
|
||||||
//line season.qtpl:41
|
//line season.qtpl:23
|
||||||
qw422016.N().S(` </pre> </body> </html> `)
|
qw422016.N().S(`</pre> <h2>Anime</h2> <table> <tr> <td><strong>Airing 📺</strong></td> <td>`)
|
||||||
//line season.qtpl:45
|
//line season.qtpl:28
|
||||||
|
qw422016.N().D(len(animes))
|
||||||
|
//line season.qtpl:28
|
||||||
|
qw422016.N().S(`</td> </tr> </table> </br> <table> `)
|
||||||
|
//line season.qtpl:33
|
||||||
|
for _, anime := range animes {
|
||||||
|
//line season.qtpl:33
|
||||||
|
qw422016.N().S(` <tr> <td><a href="`)
|
||||||
|
//line season.qtpl:35
|
||||||
|
qw422016.E().S(anime.URL)
|
||||||
|
//line season.qtpl:35
|
||||||
|
qw422016.N().S(`" target="_blank" rel="noopener noreferrer">`)
|
||||||
|
//line season.qtpl:35
|
||||||
|
qw422016.N().DL(anime.Anime)
|
||||||
|
//line season.qtpl:35
|
||||||
|
qw422016.N().S(`</a></td> <td><strong>`)
|
||||||
|
//line season.qtpl:36
|
||||||
|
qw422016.E().S(anime.Title)
|
||||||
|
//line season.qtpl:36
|
||||||
|
qw422016.N().S(`</strong></td> <td>`)
|
||||||
|
//line season.qtpl:37
|
||||||
|
qw422016.N().D(anime.Episodes)
|
||||||
|
//line season.qtpl:37
|
||||||
|
qw422016.N().S(`</td> <td>`)
|
||||||
|
//line season.qtpl:38
|
||||||
|
qw422016.N().F(anime.Score)
|
||||||
|
//line season.qtpl:38
|
||||||
|
qw422016.N().S(`</td> </tr> `)
|
||||||
|
//line season.qtpl:40
|
||||||
|
}
|
||||||
|
//line season.qtpl:40
|
||||||
|
qw422016.N().S(` </table> <h2>MovieManager Oracle</h2> <table> `)
|
||||||
|
//line season.qtpl:44
|
||||||
|
for _, oracle := range oracles {
|
||||||
|
//line season.qtpl:44
|
||||||
|
qw422016.N().S(` <tr> <td><a href="https://movies.hanami.family/movie/`)
|
||||||
|
//line season.qtpl:46
|
||||||
|
qw422016.N().D(oracle.Id)
|
||||||
|
//line season.qtpl:46
|
||||||
|
qw422016.N().S(`" target="_blank" rel="noopener noreferrer">`)
|
||||||
|
//line season.qtpl:46
|
||||||
|
qw422016.N().D(oracle.Id)
|
||||||
|
//line season.qtpl:46
|
||||||
|
qw422016.N().S(`</a></td> <td>`)
|
||||||
|
//line season.qtpl:47
|
||||||
|
qw422016.N().D(oracle.AvgScore)
|
||||||
|
//line season.qtpl:47
|
||||||
|
qw422016.N().S(`</td> <td><strong>`)
|
||||||
|
//line season.qtpl:48
|
||||||
|
qw422016.E().S(oracle.Title)
|
||||||
|
//line season.qtpl:48
|
||||||
|
qw422016.N().S(`</strong></td> <td>`)
|
||||||
|
//line season.qtpl:49
|
||||||
|
qw422016.N().DL(oracle.Anime)
|
||||||
|
//line season.qtpl:49
|
||||||
|
qw422016.N().S(`</td> </tr> `)
|
||||||
|
//line season.qtpl:51
|
||||||
|
}
|
||||||
|
//line season.qtpl:51
|
||||||
|
qw422016.N().S(` </table> </body> </html> `)
|
||||||
|
//line season.qtpl:55
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
}
|
}
|
||||||
|
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
func WriteIndex(qq422016 qtio422016.Writer, animes []Anime, log string) {
|
func WriteIndex(qq422016 qtio422016.Writer, animes []Anime, oracles []MmOracle, log string) {
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
StreamIndex(qw422016, animes, log)
|
StreamIndex(qw422016, animes, oracles, log)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
}
|
}
|
||||||
|
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
func Index(animes []Anime, log string) string {
|
func Index(animes []Anime, oracles []MmOracle, log string) string {
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
WriteIndex(qb422016, animes, log)
|
WriteIndex(qb422016, animes, oracles, log)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
qs422016 := string(qb422016.B)
|
qs422016 := string(qb422016.B)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
qt422016.ReleaseByteBuffer(qb422016)
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
return qs422016
|
return qs422016
|
||||||
//line season.qtpl:46
|
//line season.qtpl:56
|
||||||
}
|
}
|
||||||
|
|||||||
2
template.sh
Executable file
2
template.sh
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
~/go/bin/qtc
|
||||||
90
zecke.go
Normal file
90
zecke.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
_ "embed"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed mm.cred
|
||||||
|
var mmDbCred string
|
||||||
|
|
||||||
|
func GetMmConnString() (string, error) {
|
||||||
|
pw, err := base64.StdEncoding.DecodeString(mmDbCred)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%s@tcp(%s)/moviemanager?parseTime=true", *mmDbUser, pw, *mmDbServer), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MmReadOracle() ([]MmOracle, error) {
|
||||||
|
key := "oracle"
|
||||||
|
var oracles []MmOracle
|
||||||
|
data, err := mmCache.Get(key)
|
||||||
|
if err == nil {
|
||||||
|
err = json.Unmarshal(data, &oracles)
|
||||||
|
if err == nil {
|
||||||
|
return oracles, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oracleQuery := `SELECT m.id, m.title, m.mal_id, COALESCE(SUM(pv.score), 0) AS avgScore FROM movie m
|
||||||
|
INNER JOIN vote pv ON (m.id = pv.movie_id)
|
||||||
|
INNER JOIN promise pp ON (pp.user_id = pv.user_id)
|
||||||
|
INNER JOIN evening me ON (pp.evening_id = me.id)
|
||||||
|
WHERE m.id NOT IN (
|
||||||
|
SELECT m2.id FROM movie m2
|
||||||
|
INNER JOIN evening_movie em2 ON (m2.id = em2.movie_id)
|
||||||
|
INNER JOIN evening e2 ON (em2.evening_id = e2.id)
|
||||||
|
WHERE e2.date < ?
|
||||||
|
) AND (
|
||||||
|
m.id IN (
|
||||||
|
SELECT mm.movie_source FROM movie m3
|
||||||
|
INNER JOIN movie_movie mm ON (m3.id = mm.movie_target)
|
||||||
|
INNER JOIN evening_movie em3 ON (mm.movie_target = em3.movie_id)
|
||||||
|
INNER JOIN evening e3 ON (em3.evening_id = e3.id)
|
||||||
|
WHERE e3.date < ? GROUP BY m3.id
|
||||||
|
)
|
||||||
|
OR
|
||||||
|
m.id NOT IN (
|
||||||
|
SELECT mm.movie_source FROM movie m4
|
||||||
|
INNER JOIN movie_movie mm ON (m4.id = mm.movie_source)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AND pp.promised = 1 AND m.aired = 1 AND me.date >= ? AND me.date < ? GROUP BY m.id ORDER BY avgScore DESC, m.id ASC;`
|
||||||
|
today := PrintDate(time.Now())
|
||||||
|
nextWeek := PrintDate(time.Now().AddDate(0, 0, 7))
|
||||||
|
rows, err := mmDb.Query(oracleQuery, today, today, today, nextWeek)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
oracles = make([]MmOracle, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
var oracle MmOracle
|
||||||
|
var qMalId sql.NullInt64
|
||||||
|
err = rows.Scan(&oracle.Id, &oracle.Title, &qMalId, &oracle.AvgScore)
|
||||||
|
if err != nil {
|
||||||
|
return oracles, err
|
||||||
|
}
|
||||||
|
if qMalId.Valid {
|
||||||
|
oracle.Anime = qMalId.Int64
|
||||||
|
}
|
||||||
|
oracles = append(oracles, oracle)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = rows.Err()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
bytes, err := json.Marshal(oracles)
|
||||||
|
if err == nil {
|
||||||
|
mmCache.Set(key, bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return oracles, err
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user