mirror of
https://github.com/JuLi0n21/pwa-player.git
synced 2026-04-19 15:30:05 +00:00
updating go-backend
This commit is contained in:
3
go-backend/.gitignore
vendored
3
go-backend/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
data/*
|
||||
.vscode/
|
||||
.vscode/
|
||||
.env
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -17,12 +18,12 @@ import (
|
||||
var ErrBeatmapCountNotMatch = errors.New("beatmap count not matching")
|
||||
|
||||
var osuDB *parser.OsuDB
|
||||
var fileName string
|
||||
var osuRoot string
|
||||
|
||||
func initDB(connectionString string, osuDb *parser.OsuDB, osuRoot string) (*sql.DB, error) {
|
||||
func initDB(connectionString string, osuDb *parser.OsuDB, osuroot string) (*sql.DB, error) {
|
||||
|
||||
osuDB = osuDb
|
||||
fileName = osuRoot
|
||||
osuRoot = osuroot
|
||||
|
||||
dir := filepath.Dir(connectionString)
|
||||
|
||||
@@ -57,7 +58,7 @@ func initDB(connectionString string, osuDb *parser.OsuDB, osuRoot string) (*sql.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
collectionDB, err := parser.ParseCollectionsDB(osuRoot + "collection.db")
|
||||
collectionDB, err := parser.ParseCollectionsDB(path.Join(osuRoot, "collection.db"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -411,7 +412,7 @@ func getCollection(db *sql.DB, limit, offset, index int) (Collection, error) {
|
||||
return Collection{}, err
|
||||
}
|
||||
|
||||
s.Image = extractImageFromFile(fileName, s.Folder, s.File)
|
||||
s.Image = extractImageFromFile(osuRoot, s.Folder, s.File)
|
||||
|
||||
c.Songs = append(c.Songs, s)
|
||||
}
|
||||
@@ -449,7 +450,7 @@ func getCollectionByName(db *sql.DB, limit, offset int, name string) (Collection
|
||||
return Collection{}, err
|
||||
}
|
||||
|
||||
s.Image = extractImageFromFile(fileName, s.Folder, s.File)
|
||||
s.Image = extractImageFromFile(osuRoot, s.Folder, s.File)
|
||||
|
||||
c.Songs = append(c.Songs, s)
|
||||
}
|
||||
@@ -493,7 +494,7 @@ func getCollections(db *sql.DB, q string, limit, offset int) ([]CollectionPrevie
|
||||
if i, err := strconv.Atoi(count); err == nil {
|
||||
c.Items = i
|
||||
}
|
||||
c.Image = extractImageFromFile(fileName, folder, file)
|
||||
c.Image = extractImageFromFile(osuRoot, folder, file)
|
||||
|
||||
collections = append(collections, c)
|
||||
}
|
||||
@@ -517,7 +518,7 @@ func scanSongs(rows *sql.Rows) ([]Song, error) {
|
||||
return []Song{}, err
|
||||
}
|
||||
|
||||
bm, err := parser.ParseOsuFile(fmt.Sprintf("%sSongs/%s/%s", fileName, s.Folder, s.File))
|
||||
bm, err := parser.ParseOsuFile(fmt.Sprintf("%sSongs/%s/%s", osuRoot, s.Folder, s.File))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
s.Image = fmt.Sprintf("404.png")
|
||||
@@ -539,7 +540,7 @@ func scanSong(row *sql.Row) (Song, error) {
|
||||
return Song{}, err
|
||||
}
|
||||
|
||||
s.Image = extractImageFromFile(fileName, s.Folder, s.File)
|
||||
s.Image = extractImageFromFile(osuRoot, s.Folder, s.File)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
_ "backend/docs"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
httpSwagger "github.com/swaggo/http-swagger"
|
||||
|
||||
"github.com/juli0n21/go-osu-parser/parser"
|
||||
@@ -27,6 +28,7 @@ type Server struct {
|
||||
OsuDir string
|
||||
Db *sql.DB
|
||||
OsuDb *parser.OsuDB
|
||||
Env map[string]string
|
||||
}
|
||||
|
||||
func (s *Server) registerRoutes() {
|
||||
@@ -46,6 +48,8 @@ func (s *Server) registerRoutes() {
|
||||
|
||||
http.HandleFunc("/api/v1/audio/{filepath}", s.songFile)
|
||||
http.HandleFunc("/api/v1/image/{filepath}", s.imageFile)
|
||||
|
||||
http.HandleFunc("/api/v1/callback", s.callback)
|
||||
http.Handle("/swagger/", httpSwagger.WrapHandler)
|
||||
}
|
||||
|
||||
@@ -205,18 +209,18 @@ func (s *Server) collection(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
|
||||
// @Summary Searches collections based on a query
|
||||
// @Description Searches collections in the database based on the query parameter
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param query query string true "Search query"
|
||||
// @Param limit query int false "Limit the number of results" default(10)
|
||||
// @Param offset query int false "Offset for pagination" default(0)
|
||||
// @Success 200 {array} Collection "List of collections"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /search/collections [get]
|
||||
// @Summary Searches collections based on a query
|
||||
// @Description Searches collections in the database based on the query parameter
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param query query string true "Search query"
|
||||
// @Param limit query int false "Limit the number of results" default(10)
|
||||
// @Param offset query int false "Offset for pagination" default(0)
|
||||
// @Success 200 {array} Collection "List of collections"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /search/collections [get]
|
||||
func (s *Server) collectionSearch(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query().Get("query")
|
||||
|
||||
@@ -231,15 +235,15 @@ func (s *Server) collectionSearch(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, preview, http.StatusOK)
|
||||
}
|
||||
|
||||
// @Summary Returns all the Songs of a specific Artist
|
||||
// @Tags songs
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param artist query string true "Artist Name"
|
||||
// @Success 200 {array} Song
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /songs/artist [get]
|
||||
// @Summary Returns all the Songs of a specific Artist
|
||||
// @Tags songs
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param artist query string true "Artist Name"
|
||||
// @Success 200 {array} Song
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /songs/artist [get]
|
||||
func (s *Server) aristsSongs(w http.ResponseWriter, r *http.Request) {
|
||||
artist := r.URL.Query().Get("artist")
|
||||
if artist == "" {
|
||||
@@ -250,18 +254,18 @@ func (s *Server) aristsSongs(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, []Song{}, http.StatusOK)
|
||||
}
|
||||
|
||||
// @Summary Searches active records based on a query
|
||||
// @Description Searches active records in the database based on the query parameter
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param query query string true "Search query"
|
||||
// @Param limit query int false "Limit the number of results" default(10)
|
||||
// @Param offset query int false "Offset for pagination" default(0)
|
||||
// @Success 200 {object} ActiveSearch "Active search result"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /search/active [get]
|
||||
// @Summary Searches active records based on a query
|
||||
// @Description Searches active records in the database based on the query parameter
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param query query string true "Search query"
|
||||
// @Param limit query int false "Limit the number of results" default(10)
|
||||
// @Param offset query int false "Offset for pagination" default(0)
|
||||
// @Success 200 {object} ActiveSearch "Active search result"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /search/active [get]
|
||||
func (s *Server) activeSearch(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query().Get("query")
|
||||
if q == "" {
|
||||
@@ -281,18 +285,18 @@ func (s *Server) activeSearch(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, recent, http.StatusOK)
|
||||
}
|
||||
|
||||
// @Summary Searches for artists based on a query
|
||||
// @Description Searches for artists in the database based on the query parameter
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param query query string true "Search query"
|
||||
// @Param limit query int false "Limit the number of results" default(10)
|
||||
// @Param offset query int false "Offset for pagination" default(0)
|
||||
// @Success 200 {object} Artist "List of artists"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /search/artist [get]
|
||||
// @Summary Searches for artists based on a query
|
||||
// @Description Searches for artists in the database based on the query parameter
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param query query string true "Search query"
|
||||
// @Param limit query int false "Limit the number of results" default(10)
|
||||
// @Param offset query int false "Offset for pagination" default(0)
|
||||
// @Success 200 {object} Artist "List of artists"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 500 {object} string "Internal Server Error"
|
||||
// @Router /search/artist [get]
|
||||
func (s *Server) artistSearch(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query().Get("query")
|
||||
if q == "" {
|
||||
@@ -312,16 +316,16 @@ func (s *Server) artistSearch(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, a, http.StatusOK)
|
||||
}
|
||||
|
||||
// @Summary Retrieves a song file by its encoded path
|
||||
// @Description Retrieves a song file from the server based on the provided encoded filepath
|
||||
// @Tags files
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param filepath path string true "Base64 encoded file path"
|
||||
// @Success 200 {file} File "The requested song file"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 404 {object} string "File Not Found"
|
||||
// @Router /audio/{filepath} [get]
|
||||
// @Summary Retrieves a song file by its encoded path
|
||||
// @Description Retrieves a song file from the server based on the provided encoded filepath
|
||||
// @Tags files
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param filepath path string true "Base64 encoded file path"
|
||||
// @Success 200 {file} File "The requested song file"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 404 {object} string "File Not Found"
|
||||
// @Router /audio/{filepath} [get]
|
||||
func (s *Server) songFile(w http.ResponseWriter, r *http.Request) {
|
||||
f := r.PathValue("filepath")
|
||||
if f == "" {
|
||||
@@ -354,16 +358,16 @@ func (s *Server) songFile(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeContent(w, r, stat.Name(), stat.ModTime(), file)
|
||||
}
|
||||
|
||||
// @Summary Retrieves an image file by its encoded path
|
||||
// @Description Retrieves an image file from the server based on the provided encoded filepath
|
||||
// @Tags files
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param filepath path string true "Base64 encoded file path"
|
||||
// @Success 200 {file} File "The requested image file"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 404 {object} string "File Not Found"
|
||||
// @Router /image/{filepath} [get]
|
||||
// @Summary Retrieves an image file by its encoded path
|
||||
// @Description Retrieves an image file from the server based on the provided encoded filepath
|
||||
// @Tags files
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param filepath path string true "Base64 encoded file path"
|
||||
// @Success 200 {file} File "The requested image file"
|
||||
// @Failure 400 {object} string "Bad Request"
|
||||
// @Failure 404 {object} string "File Not Found"
|
||||
// @Router /image/{filepath} [get]
|
||||
func (s *Server) imageFile(w http.ResponseWriter, r *http.Request) {
|
||||
f := r.PathValue("filepath")
|
||||
if f == "" {
|
||||
@@ -381,6 +385,15 @@ func (s *Server) imageFile(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, s.OsuDir+"Songs/"+string(filename))
|
||||
}
|
||||
|
||||
func (s *Server) callback(w http.ResponseWriter, r *http.Request) {
|
||||
cookie := r.URL.Query().Get("COOKIE")
|
||||
|
||||
if cookie != "" {
|
||||
s.Env["COOKIE"] = cookie
|
||||
godotenv.Write(s.Env, ".env")
|
||||
}
|
||||
}
|
||||
|
||||
func writeJSON(w http.ResponseWriter, v any, status int) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/juli0n21/go-osu-parser/parser"
|
||||
@@ -12,32 +21,148 @@ import (
|
||||
// @version 1.0
|
||||
// @description Server Hosting ur own osu files over a simple Api
|
||||
|
||||
// @host localhost:8080
|
||||
// @BasePath /api/v1/
|
||||
// @host localhost:8080
|
||||
// @BasePath /api/v1/
|
||||
func main() {
|
||||
|
||||
filename := "/mnt/g/Anwendungen/osu!/osu!.db"
|
||||
osuRoot := "/mnt/g/Anwendungen/osu!/"
|
||||
|
||||
if err := godotenv.Load(); err != nil {
|
||||
fmt.Println("Error loading .env file")
|
||||
envMap, err := godotenv.Read(".env")
|
||||
if err != nil {
|
||||
fmt.Println("Error reading .env file")
|
||||
}
|
||||
|
||||
if envMap["OSU_PATH"] == "" {
|
||||
fmt.Println("Osu Path not found! Please paste the full path to your osu! folder.")
|
||||
fmt.Println("Osu Path not found pls paste the full Path to ur osu! folder \n it should start with 'C://' and can be opened from the Settings menu!)\n path: ")
|
||||
|
||||
fmt.Scanln(&osuRoot)
|
||||
osuRoot = strings.TrimSpace(osuRoot)
|
||||
|
||||
envMap["OSU_PATH"] = osuRoot
|
||||
godotenv.Write(envMap, ".env")
|
||||
}
|
||||
|
||||
osuRoot := envMap["OSU_PATH"]
|
||||
cookie := envMap["COOKIE"]
|
||||
port := GetEnv(envMap["PORT"], ":8080")
|
||||
filename := path.Join(osuRoot, "osu!.db")
|
||||
|
||||
osuDb, err := parser.ParseOsuDB(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if cookie == "" {
|
||||
fmt.Println("No Authentication found please follow the link to log in!\n http://proxy.illegalesachen.download/login")
|
||||
}
|
||||
|
||||
url, err := StartCloudflared(port)
|
||||
if err != nil {
|
||||
log.Fatalf("Cloudflared service couldnt be started: %v", err)
|
||||
}
|
||||
|
||||
if err = sendUrl(url, cookie); err != nil {
|
||||
log.Fatalf("Couldnt Update Endpoint url with Proxy: %v", err)
|
||||
}
|
||||
|
||||
db, err := initDB("./data/music.db", osuDb, osuRoot)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
Port: ":8080",
|
||||
Port: port,
|
||||
Db: db,
|
||||
OsuDir: osuRoot,
|
||||
Env: envMap,
|
||||
}
|
||||
|
||||
run(s)
|
||||
}
|
||||
|
||||
func GetEnv(key, fallback string) string {
|
||||
if value, ok := os.LookupEnv(key); ok && value != "" {
|
||||
return value
|
||||
}
|
||||
|
||||
return fallback
|
||||
}
|
||||
|
||||
func StartCloudflared(port string) (string, error) {
|
||||
cmd := exec.Command("cloudflared", "tunnel", "--url", fmt.Sprintf("http://localhost%s", port))
|
||||
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error creating StderrPipe: %v", err)
|
||||
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", fmt.Errorf("Error starting command: %v", err)
|
||||
|
||||
}
|
||||
|
||||
stderrScanner := bufio.NewScanner(stderr)
|
||||
|
||||
urlRegex := regexp.MustCompile(`https?://[\w.-]+\.trycloudflare\.com`)
|
||||
|
||||
for stderrScanner.Scan() {
|
||||
line := stderrScanner.Text()
|
||||
if url := urlRegex.FindString(line); url != "" {
|
||||
fmt.Println("Found URL:", url)
|
||||
return url, nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return "", fmt.Errorf("Error waiting for command: %v", err)
|
||||
}
|
||||
|
||||
if err := stderrScanner.Err(); err != nil {
|
||||
return "", fmt.Errorf("Error reading stderr: %v", err)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no url found")
|
||||
}
|
||||
|
||||
func sendUrl(endpoint, cookie string) error {
|
||||
url := "http://proxy.illegalesachen.download/settings"
|
||||
|
||||
payload := struct {
|
||||
Sharing *bool `json:"sharing"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
}{
|
||||
Endpoint: endpoint,
|
||||
}
|
||||
|
||||
body, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error marshalling payload: %v", err)
|
||||
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating request: %v", err)
|
||||
}
|
||||
|
||||
req.AddCookie(&http.Cookie{
|
||||
Name: "session_cookie",
|
||||
Value: cookie,
|
||||
})
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
fmt.Println(req)
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error sending request: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("Error in request: %s", resp.Status)
|
||||
}
|
||||
fmt.Println("Response Status:", resp.Status)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user