add even more shit

This commit is contained in:
Fijxu 2025-01-08 20:16:19 -03:00
parent c3d055b2f1
commit db4c3881d9
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4
7 changed files with 331 additions and 53 deletions

View file

@ -15,18 +15,18 @@ type Redis struct {
DB int `json:"db"`
}
type Gql struct {
type GqlConfig struct {
ClientID string `json:"clientId"`
}
type Config struct {
HTTPServer HTTPServer `json:"http_server"`
Redis Redis `json:"redis"`
Gql Gql `json:"gql"`
Gql GqlConfig `json:"gql"`
DbPath string `json:"dbpath"`
}
func loadConfig(configPath string) Config {
// Default config in case a value is missing in the config file
var config = Config{
HTTPServer: HTTPServer{
@ -37,9 +37,10 @@ func loadConfig(configPath string) Config {
Addr: "127.0.0.1:6379",
DB: 0,
},
Gql: Gql{
Gql: GqlConfig{
ClientID: "ue6666qo983tsx6so1t0vnawi233wa",
},
DbPath: "./database.sqlite3",
}
file, err := os.ReadFile(configPath)

View file

@ -2,15 +2,14 @@ package main
import (
"database/sql"
"log"
)
func createDb(db *sql.DB) {
func createDb(db *sql.DB) error {
var exists bool
// rows := db.QueryRow("SELECT EXISTS (SELECT 1 FROM sqlite_schema WHERE type='table' AND name='seventv_ids') AND EXISTS (SELECT 1 FROM sqlite_schema WHERE type='table' AND name='seventv_ids');")
err := db.QueryRow(`SELECT EXISTS (SELECT 1 FROM sqlite_schema WHERE type='table' AND name='seventv_ids') AND EXISTS (SELECT 1 FROM sqlite_schema WHERE type='table' AND name='seventv_ids');`).Scan(&exists)
if err != nil {
log.Fatal("Query failed: ", err)
return err
}
if !exists {
@ -20,10 +19,11 @@ func createDb(db *sql.DB) {
}
for _, query := range queries {
_, err := db.Exec(query)
_, err = db.Exec(query)
if err != nil {
log.Fatalf("Failed to create table: %s\nError: %v", query, err)
return err
}
}
}
return nil
}

View file

@ -5,6 +5,43 @@ import (
"net/http"
)
func root(w http.ResponseWriter, req *http.Request) {
func root(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "WIP Vanity Tester Backend")
}
func getAllBadges(w http.ResponseWriter, r *http.Request) {
parseAllBadges()
io.WriteString(w, "test")
}
// func sevenTvPaints(w http.ResponseWriter, r *http.Request) {
// svt := &SevenTv{}
// badges, err := svt.getPaints()
// if err != nil {
// http.Error(w, err.Error(), http.StatusInternalServerError)
// return
// }
// io.WriteString(w, badges)
// }
// func sevenTvBadges(w http.ResponseWriter, r *http.Request) {
// svt := &SevenTv{}
// badges, err := svt.getBadges()
// if err != nil {
// http.Error(w, err.Error(), http.StatusInternalServerError)
// return
// }
// io.WriteString(w, badges)
// }
// func sevenTvUserCosmetics(w http.ResponseWriter, r *http.Request) {
// svt := &SevenTv{}
// user := strings.TrimPrefix(r.URL.Path, "/7tv/cosmetics/")
// logger.Trace().Msg("sevenTvUserCosmetics: user: " + user)
// badges, err := svt.getUserCosmetics(user)
// if err != nil {
// http.Error(w, err.Error(), http.StatusInternalServerError)
// return
// }
// io.WriteString(w, badges)
// }

View file

@ -1,35 +1,57 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type GQL struct{}
type Gql struct{}
func getUserID(username string) {
func (s *Gql) getUserID(username string) (string, error) {
headers := map[string]string{
"Content-Type": "application/json",
"Client-Id": config.Gql.ClientID,
// The headers from bellow are not really necessary, but since it's GQL,
// it's better to fake the headers to make it more like a real browser
// and not just an scrapper.
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Access-Control-Request-Method": "POST",
"Access-Control-Request-Headers": "authorization,client-id,client-session-id,client-version,x-device-id",
"Referer": "https://www.twitch.tv/",
"Origin": "https://www.twitch.tv",
"Connection": "keep-alive",
}
// TODO: Send the data!
request, err := http.Post("https://gql.twitch.tv/gql", "application/json", data)
query := map[string]string{"query": fmt.Sprintf(`query { user(login: "%s") { id } }`, username)}
data, err := json.Marshal(query)
if err != nil {
logger.Error().Msg(err.Error())
return "", logger.Error().GetCtx().Err()
}
logger.Trace().Msg(string(data))
for key, value := range headers {
request.Header.Set(key, value)
}
res, err := client.Do(request.Request)
request, err := http.NewRequest("POST", "https://gql.twitch.tv/gql", bytes.NewBuffer(data))
if err != nil {
logger.Error().Msg(err.Error())
return "", err
}
for k, v := range headers {
request.Header.Add(k, v)
}
res, err := client.Do(request)
if err != nil {
return "", err
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
return string(body)
return string(body), nil
}

View file

@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"net/http"
"net/url"
"os"
_ "github.com/mattn/go-sqlite3"
@ -11,34 +12,63 @@ import (
"github.com/rs/zerolog/log"
)
var client *http.Client
var rctx = context.Background()
var config = loadConfig("./config.json")
var logger = log.Logger.Output(zerolog.ConsoleWriter{Out: os.Stderr})
var client = &http.Client{
Transport: &http.Transport{
Proxy: func(r *http.Request) (*url.URL, error) {
if os.Getenv("PROXY") != "" {
return url.Parse(os.Getenv("PROXY"))
}
return nil, nil
},
},
}
// Just a small handler to add headers on all responses
func middleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
next(w, r)
}
}
func main() {
// s := &SevenTv{}
// xd, _ := s.getPaints()
// logger.Trace().Msg(xd)
// redisDb := redis.NewClient(&redis.Options{
// Addr: config.Redis.Addr,
// DB: config.Redis.DB,
// })
db, err := sql.Open("sqlite3", "./database.db")
db, err := sql.Open("sqlite3", config.DbPath)
if err != nil {
logger.Fatal().Msg(err.Error())
}
defer db.Close()
createDb(db)
err = createDb(db)
if err != nil {
logger.Fatal().Msgf("Failed to create DB: '%s'", err.Error())
}
mux := http.NewServeMux()
mux.HandleFunc("/", root)
// mux.HandleFunc("/health", health())
// mux.HandleFunc("/stats", stats())
mux.HandleFunc("/badges", middleware(getAllBadges))
// mux.HandleFunc("/7tv/paints", middleware(sevenTvPaints))
// mux.HandleFunc("/7tv/badges", middleware(sevenTvBadges))
// // CONSIDERATION: github.com/gorilla/mux may be an option to make use of something like this:
// // mux.HandleFunc("/7tv/cosmetics/{user}", middleware(sevenTvUserCosmetics))
// // For now I will just trim the path
// mux.HandleFunc("/7tv/cosmetics/", middleware(sevenTvUserCosmetics))
srv := &http.Server{
Handler: mux,
Addr: config.HTTPServer.Addr + ":" + config.HTTPServer.Port,
Handler: mux,
}
logger.Info().Msgf("Starting server at http://%s:%s", config.HTTPServer.Addr, config.HTTPServer.Port)

View file

@ -0,0 +1,26 @@
package main
import "encoding/json"
type Parser struct {
SevenTV string `json:"SevenTV"`
Bttv string `json:"BTTV"`
Ffz string `json:"FFZ"`
Chatterino string `json:"Chatterino"`
Chatty string `json:"Chatty"`
Homies string `json:"Homies"`
Ptv string `json:"PurpleTV"`
}
func parseAllBadges() {
stv := &SevenTv{}
stv.getBadges()
json, _ := json.Marshal(stv.Badges)
logger.Trace().Msg(string(json))
// bttv := &Bttv{}
// ffz := &FrankerFz{}
// chatterino := &Chatterino{}
// chatty := &Chatty{}
// homies := &Homies{}
// ptv := &PurpleTV{}
}

View file

@ -1,11 +1,40 @@
package main
import (
"bytes"
"encoding/json"
"io"
"net/http"
)
type SevenTv struct{}
type Variables struct {
ID string `json:"id"`
}
type GqlQuery struct {
OperationName string `json:"operationName"`
Variables Variables `json:"variables"`
Query string `json:"query"`
}
type SevenTv struct {
Query GqlQuery `json:"query"`
Badges struct {
Data struct {
Cosmetics struct {
Badges []struct {
ID string `json:"id"`
Kind string `json:"kind"`
Name string `json:"name"`
Tooltip string `json:"tooltip"`
Tag string `json:"tag"`
Typename string `json:"__typename"`
}
Typename string `json:"__typename"`
} `json:"cosmetics"`
} `json:"data"`
} `json:"sevenTvBadges"`
}
type Bttv struct{}
type FrankerFz struct{}
type Chatterino struct{}
@ -14,12 +43,12 @@ type DankChat struct{}
type Homies struct{}
type PurpleTV struct{}
func doGetRequest(url string) string {
request, err := http.Get(url)
func doGetRequest(url string) []byte {
request, err := http.NewRequest("GET", url, nil)
if err != nil {
logger.Error().Msg(err.Error())
}
res, err := client.Do(request.Request)
res, err := client.Do(request)
if err != nil {
logger.Error().Msg(err.Error())
}
@ -27,35 +56,168 @@ func doGetRequest(url string) string {
body, err := io.ReadAll(res.Body)
return string(body)
return body
}
func (s *SevenTv) getUserID(userId string) string {
func doPostRequest(url string, data []byte) []byte {
request, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
logger.Error().Msg(err.Error())
}
res, err := client.Do(request)
if err != nil {
logger.Error().Msg(err.Error())
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
return body
}
func (s *SevenTv) getUserID(userId string) []byte {
req := doGetRequest("https://7tv.io/v3/users/twitch/" + userId)
return req
}
func (s *Bttv) getBadges() string {
req := doGetRequest("https://api.betterttv.net/3/cached/badges/twitch")
return req
func (s *SevenTv) getBadges() *SevenTv {
query := `
query GetCosmestics($list: [ObjectID!]) {
cosmetics(list: $list) {
badges {
id
kind
name
tooltip
tag
__typename
}
__typename
}
}`
s.Query = GqlQuery{
OperationName: "GetCosmestics",
Query: query,
}
data, _ := json.Marshal(s.Query)
// if err != nil {
// return "", err
// }
res := doPostRequest("https://7tv.io/v3/gql", data)
logger.Info().Msg(string(res))
err := json.Unmarshal(res, &s.Badges)
if err != nil {
logger.Error().Msg(err.Error())
}
return s
}
func (s *FrankerFz) getBadges() string {
req := doGetRequest("https://api.frankerfacez.com/v1/badges/ids")
return req
}
// func (s *SevenTv) getPaints() (string, error) {
// query := `
// query GetCosmestics($list: [ObjectID!]) {
// cosmetics(list: $list) {
// paints {
// id
// kind
// name
// function
// color
// angle
// shape
// image_url
// repeat
// stops {
// at
// color
// __typename
// }
// shadows {
// x_offset
// y_offset
// radius
// color
// __typename
// }
// __typename
// }
// }
// }`
func (s *Chatty) getBadges() string {
req := doGetRequest("https://api.betterttv.net/3/cached/badges/twitch")
return req
}
// s.Query = GqlQuery{
// OperationName: "GetCosmestics",
// Query: query,
// }
func (s *DankChat) getBadges() string {
req := doGetRequest("https://flxrs.com/api/badges")
return req
}
// data, err := json.Marshal(s.Query)
// if err != nil {
// return "", err
// }
// logger.Trace().Msg(string(data))
func (s *Chatterino) getBadges() string {
req := doGetRequest("https://api.chatterino.com/badges")
return req
}
// res := doPostRequest("https://7tv.io/v3/gql", data)
// return res, nil
// }
// func (s *SevenTv) getUserCosmetics(userId string) (string, error) {
// query := `
// query GetUserCosmetics($id: ObjectID!) {
// user(id: $id) {
// id
// cosmetics {
// id
// kind
// selected
// __typename
// }
// __typename
// }
// }`
// s.Query = GqlQuery{
// OperationName: "GetUserCosmetics",
// Variables: Variables{
// ID: userId,
// },
// Query: query,
// }
// data, err := json.Marshal(s.Query)
// if err != nil {
// return "", err
// }
// logger.Trace().Msg(string(data))
// res := doPostRequest("https://7tv.io/v3/gql", data)
// return res, nil
// }
// func (s *Bttv) getBadges() string {
// req := doGetRequest("https://api.betterttv.net/3/cached/badges/twitch")
// return req
// }
// func (s *FrankerFz) getBadges() string {
// req := doGetRequest("https://api.frankerfacez.com/v1/badges/ids")
// return req
// }
// func (s *Chatty) getBadges() string {
// req := doGetRequest("https://api.betterttv.net/3/cached/badges/twitch")
// return req
// }
// func (s *DankChat) getBadges() string {
// req := doGetRequest("https://flxrs.com/api/badges")
// return req
// }
// func (s *Chatterino) getBadges() string {
// req := doGetRequest("https://api.chatterino.com/badges")
// return req
// }