2020-10-12 14:12:09 +00:00
|
|
|
package web
|
|
|
|
|
|
|
|
import (
|
2020-10-14 19:08:38 +00:00
|
|
|
"encoding/json"
|
2020-10-12 14:12:09 +00:00
|
|
|
"fmt"
|
2020-10-14 19:08:38 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"path"
|
2020-10-14 19:46:20 +00:00
|
|
|
"strconv"
|
2020-10-14 19:08:38 +00:00
|
|
|
"strings"
|
2020-10-14 19:56:56 +00:00
|
|
|
"sync"
|
2020-10-14 19:08:38 +00:00
|
|
|
"time"
|
2020-10-12 14:12:09 +00:00
|
|
|
|
2020-10-14 19:08:38 +00:00
|
|
|
"github.com/foolin/goview"
|
|
|
|
"github.com/foolin/goview/supports/ginview"
|
|
|
|
"github.com/gin-contrib/static"
|
|
|
|
"github.com/gin-gonic/contrib/sessions"
|
2020-10-12 14:12:09 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2020-10-14 19:46:20 +00:00
|
|
|
"github.com/kofalt/go-memoize"
|
2020-10-12 14:12:09 +00:00
|
|
|
|
|
|
|
"subscribe-bot/config"
|
2020-10-14 19:46:20 +00:00
|
|
|
"subscribe-bot/osuapi"
|
2020-10-12 14:12:09 +00:00
|
|
|
)
|
|
|
|
|
2020-10-14 19:08:38 +00:00
|
|
|
const (
|
|
|
|
USER_KEY = "user"
|
|
|
|
)
|
|
|
|
|
2020-10-14 19:46:20 +00:00
|
|
|
var (
|
|
|
|
cache = memoize.NewMemoizer(90*time.Second, 10*time.Minute)
|
|
|
|
)
|
|
|
|
|
|
|
|
func RunWeb(config *config.Config, api *osuapi.Osuapi) {
|
2020-10-14 19:08:38 +00:00
|
|
|
hc := http.Client{
|
|
|
|
Timeout: 10 * time.Second,
|
|
|
|
}
|
|
|
|
|
2020-10-14 19:11:07 +00:00
|
|
|
if !config.Debug {
|
|
|
|
gin.SetMode(gin.ReleaseMode)
|
|
|
|
}
|
|
|
|
|
2020-10-12 14:12:09 +00:00
|
|
|
r := gin.Default()
|
2020-10-14 19:08:38 +00:00
|
|
|
r.Use(gin.Recovery())
|
|
|
|
r.Use(static.Serve("/static", static.LocalFile("web/static", false)))
|
|
|
|
r.Use(sessions.Sessions("mysession", sessions.NewCookieStore([]byte(config.Web.SessionSecret))))
|
|
|
|
|
|
|
|
r.HTMLRender = ginview.New(goview.Config{
|
|
|
|
Root: "web/templates",
|
|
|
|
DisableCache: config.Debug,
|
|
|
|
})
|
|
|
|
|
2020-10-14 20:09:03 +00:00
|
|
|
r.GET("/logout", func(c *gin.Context) {
|
|
|
|
session := sessions.Default(c)
|
|
|
|
session.Delete("access_token")
|
|
|
|
session.Save()
|
|
|
|
|
|
|
|
c.Redirect(http.StatusTemporaryRedirect, "/")
|
|
|
|
})
|
|
|
|
|
2020-10-14 19:08:38 +00:00
|
|
|
r.GET("/login", func(c *gin.Context) {
|
|
|
|
url := url.URL{
|
|
|
|
Scheme: "https",
|
|
|
|
Host: "osu.ppy.sh",
|
|
|
|
Path: "/oauth/authorize",
|
|
|
|
}
|
|
|
|
q := url.Query()
|
|
|
|
q.Set("client_id", config.Oauth.ClientId)
|
|
|
|
q.Set("redirect_uri", config.Web.ServedAt+"/login/callback")
|
|
|
|
q.Set("response_type", "code")
|
|
|
|
q.Set("scope", "identify public")
|
|
|
|
q.Set("state", "urmom")
|
|
|
|
url.RawQuery = q.Encode()
|
|
|
|
fmt.Println("redirecting to", url.String())
|
|
|
|
c.Redirect(http.StatusTemporaryRedirect, url.String())
|
|
|
|
})
|
|
|
|
|
|
|
|
r.GET("/login/callback", func(c *gin.Context) {
|
|
|
|
receivedCode := c.Query("code")
|
|
|
|
|
|
|
|
bodyQuery := url.Values{}
|
|
|
|
bodyQuery.Set("client_id", config.Oauth.ClientId)
|
|
|
|
bodyQuery.Set("client_secret", config.Oauth.ClientSecret)
|
|
|
|
bodyQuery.Set("code", receivedCode)
|
|
|
|
bodyQuery.Set("grant_type", "authorization_code")
|
|
|
|
bodyQuery.Set("redirect_uri", config.Web.ServedAt+"/login/callback")
|
|
|
|
body := strings.NewReader(bodyQuery.Encode())
|
|
|
|
resp, _ := hc.Post("https://osu.ppy.sh/oauth/token", "application/x-www-form-urlencoded", body)
|
|
|
|
respBody, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
type OsuToken struct {
|
|
|
|
TokenType string `json:"token_type"`
|
|
|
|
ExpiresIn int `json:"expires_in"`
|
|
|
|
AccessToken string `json:"access_token"`
|
|
|
|
RefreshToken string `json:"refresh_token"`
|
|
|
|
}
|
|
|
|
var token OsuToken
|
|
|
|
_ = json.Unmarshal(respBody, &token)
|
|
|
|
fmt.Println("TOKEN", token)
|
|
|
|
|
|
|
|
session := sessions.Default(c)
|
|
|
|
session.Set("access_token", token.AccessToken)
|
|
|
|
session.Save()
|
|
|
|
|
|
|
|
c.Redirect(http.StatusTemporaryRedirect, "/")
|
|
|
|
})
|
|
|
|
|
|
|
|
r.GET("/", func(c *gin.Context) {
|
|
|
|
session := sessions.Default(c)
|
|
|
|
var accessToken string
|
|
|
|
loggedIn := false
|
|
|
|
accessTokenI := session.Get("access_token")
|
|
|
|
if accessTokenI != nil {
|
|
|
|
accessToken = accessTokenI.(string)
|
|
|
|
if len(accessToken) > 0 {
|
|
|
|
loggedIn = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-14 19:46:20 +00:00
|
|
|
beatmapSets := getRepos(config, api)
|
2020-10-14 19:08:38 +00:00
|
|
|
|
|
|
|
// render with master
|
|
|
|
c.HTML(http.StatusOK, "index.html", gin.H{
|
2020-10-14 19:46:20 +00:00
|
|
|
"LoggedIn": loggedIn,
|
|
|
|
"Beatmapsets": beatmapSets,
|
2020-10-12 14:12:09 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
addr := fmt.Sprintf("%s:%d", config.Web.Host, config.Web.Port)
|
|
|
|
r.Run(addr)
|
|
|
|
}
|
2020-10-14 19:08:38 +00:00
|
|
|
|
2020-10-14 19:46:20 +00:00
|
|
|
func getRepos(config *config.Config, api *osuapi.Osuapi) []osuapi.Beatmapset {
|
|
|
|
expensive := func() (interface{}, error) {
|
2020-10-14 19:56:56 +00:00
|
|
|
repos := make([]int, 0)
|
2020-10-14 19:46:20 +00:00
|
|
|
reposDir := config.Repos
|
|
|
|
users, _ := ioutil.ReadDir(reposDir)
|
2020-10-14 19:08:38 +00:00
|
|
|
|
2020-10-14 19:46:20 +00:00
|
|
|
for _, user := range users {
|
|
|
|
userDir := path.Join(reposDir, user.Name())
|
|
|
|
var maps []os.FileInfo
|
|
|
|
maps, _ = ioutil.ReadDir(userDir)
|
2020-10-14 19:08:38 +00:00
|
|
|
|
2020-10-14 19:46:20 +00:00
|
|
|
for _, mapId := range maps {
|
|
|
|
mapDir := path.Join(userDir, mapId.Name())
|
|
|
|
fmt.Println(mapDir)
|
|
|
|
|
|
|
|
id, _ := strconv.Atoi(mapId.Name())
|
2020-10-14 19:56:56 +00:00
|
|
|
repos = append(repos, id)
|
2020-10-14 19:46:20 +00:00
|
|
|
}
|
2020-10-14 19:08:38 +00:00
|
|
|
}
|
2020-10-14 19:46:20 +00:00
|
|
|
|
2020-10-14 19:56:56 +00:00
|
|
|
beatmapSets := make([]osuapi.Beatmapset, len(repos))
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i, repo := range repos {
|
|
|
|
wg.Add(1)
|
|
|
|
go func(i int, repo int) {
|
|
|
|
bs, _ := api.GetBeatmapSet(repo)
|
|
|
|
beatmapSets[i] = bs
|
|
|
|
wg.Done()
|
|
|
|
}(i, repo)
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
return beatmapSets, nil
|
2020-10-14 19:08:38 +00:00
|
|
|
}
|
|
|
|
|
2020-10-14 19:46:20 +00:00
|
|
|
result, _, _ := cache.Memoize("key1", expensive)
|
|
|
|
return result.([]osuapi.Beatmapset)
|
2020-10-14 19:08:38 +00:00
|
|
|
}
|