From 6e4f03aef8885c611264516ccc4043ad50da0bfc Mon Sep 17 00:00:00 2001 From: JuLi0n21 Date: Wed, 21 May 2025 11:20:00 +0200 Subject: [PATCH] remove outdated backends --- backend/.gitignore | 7 - backend/HttpClient.cs | 85 --- backend/Program.cs | 298 ----------- backend/Properties/launchSettings.json | 21 - backend/SqliteDB.cs | 384 -------------- backend/appsettings.Development.json | 8 - backend/appsettings.json | 9 - backend/default-bg.png | Bin 3787 -> 0 bytes backend/example-cookies.json | 4 - backend/osudb.cs | 158 ------ backend/shitweb.csproj | 21 - backend/shitweb.sln | 25 - backend/types.cs | 102 ---- go-backend/.gitignore | 3 - go-backend/database.go | 599 --------------------- go-backend/docs/docs.go | 685 ------------------------- go-backend/docs/swagger.json | 661 ------------------------ go-backend/docs/swagger.yaml | 446 ---------------- go-backend/go.mod | 34 -- go-backend/go.sum | 115 ----- go-backend/handlers.go | 443 ---------------- go-backend/main.go | 163 ------ go-backend/models.go | 46 -- 23 files changed, 4317 deletions(-) delete mode 100644 backend/.gitignore delete mode 100644 backend/HttpClient.cs delete mode 100644 backend/Program.cs delete mode 100644 backend/Properties/launchSettings.json delete mode 100644 backend/SqliteDB.cs delete mode 100644 backend/appsettings.Development.json delete mode 100644 backend/appsettings.json delete mode 100644 backend/default-bg.png delete mode 100644 backend/example-cookies.json delete mode 100644 backend/osudb.cs delete mode 100644 backend/shitweb.csproj delete mode 100644 backend/shitweb.sln delete mode 100644 backend/types.cs delete mode 100644 go-backend/.gitignore delete mode 100644 go-backend/database.go delete mode 100644 go-backend/docs/docs.go delete mode 100644 go-backend/docs/swagger.json delete mode 100644 go-backend/docs/swagger.yaml delete mode 100644 go-backend/go.mod delete mode 100644 go-backend/go.sum delete mode 100644 go-backend/handlers.go delete mode 100644 go-backend/main.go delete mode 100644 go-backend/models.go diff --git a/backend/.gitignore b/backend/.gitignore deleted file mode 100644 index c84143b..0000000 --- a/backend/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.vs/ -bin/ -obj/ - -*.db -*.env -cookies.json diff --git a/backend/HttpClient.cs b/backend/HttpClient.cs deleted file mode 100644 index 6d2f11b..0000000 --- a/backend/HttpClient.cs +++ /dev/null @@ -1,85 +0,0 @@ -using OsuParsers.Enums.Replays; -using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; - -namespace shitweb -{ - public class ApiClient - { - private const string CookiesFilePath = "cookies.json"; - private HttpClient _client; - private HttpClientHandler _handler; - - public ApiClient() - { - _handler = new HttpClientHandler(); - _client = new HttpClient(_handler); - } - - public async Task InitializeAsync() - { - LoadCookies(); - - } - - public void SaveCookies(String cookie) - { - var cookies = _handler.CookieContainer.GetCookies(new Uri("https://proxy.illegalesachen.download")); - var Cookie = new CookieInfo(); - - Cookie.Name = "session_cookie"; - Cookie.Value = cookie; - var json = JsonSerializer.Serialize(Cookie, new JsonSerializerOptions { WriteIndented = true }); - File.WriteAllText(CookiesFilePath, json); - LoadCookies(); - } - - public Boolean LoadCookies() - { - if (File.Exists(CookiesFilePath)) - { - var json = File.ReadAllText(CookiesFilePath); - var cookieInfo = JsonSerializer.Deserialize(json); - - var cookie = new Cookie(cookieInfo.Name, cookieInfo.Value); - _handler.CookieContainer.Add(new Uri("https://proxy.illegalesachen.download"), cookie); - return true; - } - - return false; - } - - - public async Task UpdateSettingsAsync(string endpoint) - { - var requestContent = new JsonContent(new { endpoint = endpoint }); - var response = await _client.PostAsync("https://proxy.illegalesachen.download/settings", requestContent); - try - { - response.EnsureSuccessStatusCode(); - } - catch (Exception ex) { - System.Console.WriteLine(ex.Message); - } - } - } - - public class CookieInfo - { - public string Name { get; set; } - public string Value { get; set; } - } - - public class JsonContent : StringContent - { - public JsonContent(object obj) - : base(JsonSerializer.Serialize(obj), System.Text.Encoding.UTF8, "application/json") - { - } - } -} \ No newline at end of file diff --git a/backend/Program.cs b/backend/Program.cs deleted file mode 100644 index e220c4e..0000000 --- a/backend/Program.cs +++ /dev/null @@ -1,298 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Hosting; -using shitweb; -using System; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Text; -using System.Net.Http; -using System.Text.RegularExpressions; - -var builder = WebApplication.CreateBuilder(args); - -builder.Services.AddMemoryCache(); - -builder.Services.AddCors(options => -{ - options.AddPolicy("AllowAll", - policy => - { - policy.AllowAnyOrigin() - .AllowAnyHeader() - .AllowAnyMethod(); - }); -}); - -var app = builder.Build(); -app.UseCors("AllowAll"); - -var apiClient = new ApiClient(); - - -app.MapGet("/ping", () => "pong"); - - -app.MapGet("/login", () => { - return Results.Redirect("https://proxy.illegalesachen.download/login"); -}); - -app.MapGet("/api/v1/songs/{hash}", (string hash) => -{ - return Results.Ok(new { hash }); -}); - -app.MapGet("/api/v1/songs/recent", (HttpContext httpContext, int? limit, int? offset) => -{ - var limitValue = limit ?? 100; // default to 10 if not provided - var offsetValue = offset ?? 0; // default to 0 if not provided - - return Results.Json(SqliteDB.GetByRecent(limitValue, offsetValue)); - }); - -app.MapGet("/api/v1/songs/favorite", (int? limit, int? offset) => - { - var limitValue = limit ?? 100; // default to 10 if not provided - var offsetValue = offset ?? 0; // default to 0 if not provided - - return Results.Ok(new { Limit = limitValue, Offset = offsetValue, Message = "List of favorite songs" }); - }); - -app.MapGet("/api/v1/songs/{hash}", (string hash) => - { - return Results.Ok($"Details for song with hash {hash}"); - }); - -app.MapGet("/api/v1/collections/", async (int? limit, int? offset, [FromServices] IMemoryCache cache) => - { - - var limitValue = limit ?? 100; // default to 10 if not provided - var offsetValue = offset ?? 0; - - string cacheKey = $"collections_{offsetValue}_{limitValue}"; - - if (!cache.TryGetValue(cacheKey, out var collections)) - { - - collections = Osudb.Instance.GetCollections(limit: limitValue, offset: offsetValue); - - var cacheEntryOptions = new MemoryCacheEntryOptions() - .SetSlidingExpiration(TimeSpan.FromDays(1)) - .SetAbsoluteExpiration(TimeSpan.FromDays(3)); - - cache.Set(cacheKey, collections, cacheEntryOptions); - } - - return Results.Json(collections); - - }); - -app.MapGet("/api/v1/collection/{index}", (int index) => - { - return Results.Json(Osudb.Instance.GetCollection(index)); - }); - -app.MapGet("/api/v1/audio/{*fileName}", async (string fileName, HttpContext context) => -{ - var decodedFileName = Uri.UnescapeDataString(fileName); - var filePath = Path.Combine(Osudb.osufolder, "Songs", decodedFileName); - - if (!File.Exists(filePath)) - { - return Results.NotFound(); - } - - var fileExtension = Path.GetExtension(filePath).ToLowerInvariant(); - var contentType = fileExtension switch - { - ".mp3" => "audio/mpeg", - ".wav" => "audio/wav", - ".ogg" => "audio/ogg", - _ => "application/octet-stream", - }; - - var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); - - return Results.Stream(fileStream, contentType, enableRangeProcessing: true); -}); - -app.MapGet("/api/v1/search/active", async (string? q) => -{ - return Results.Ok(SqliteDB.activeSearch(q)); -}); - -app.MapGet("/api/v1/search/artist", async (string? q, int? limit, int? offset) => -{ - var limitv = limit ?? 100; - var offsetv = offset ?? 0; - - return Results.Ok(SqliteDB.GetArtistSearch(q, limitv, offsetv)); -}); - -app.MapGet("/api/v1/search/songs", async (string? q, int? limit, int? offset) => -{ - var limitv = limit ?? 100; - var offsetv = offset ?? 0; - return Results.Ok(); -}); - -app.MapGet("/api/v1/search/collections", async (string? q, int? limit, int? offset) => -{ - var limitv = limit ?? 100; - var offsetv = offset ?? 0; - return Results.Ok(); -}); - -app.MapGet("/api/v1/images/{*filename}", async (string filename, int? h, int? w) => -{ - var decodedFileName = Uri.UnescapeDataString(filename); - var filePath = Path.Combine(Osudb.osufolder, "Songs", decodedFileName); - - if (!File.Exists(filePath)) - { - filePath = "default-bg.png"; - } - - var fileExtension = Path.GetExtension(filePath).ToLowerInvariant(); - var contentType = fileExtension switch - { - ".jpg" or ".jpeg" => "image/jpeg", - ".png" => "image/png", - ".gif" => "image/gif", - ".bmp" => "image/bmp", - ".webp" => "image/webp", - _ => "application/octet-stream", - }; - - if (w == null || h == null) - { - var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true); - return Results.Stream(fileStream, contentType, filename); - } - using var originalImage = new Bitmap(filePath); - - - // If resizing is requested, resize the image - Bitmap resizedImage; - if (w.HasValue || h.HasValue) - { - resizedImage = ResizeImage(originalImage, w, h); - } - else - { - resizedImage = new Bitmap(originalImage); // Keep original size - } - - // Convert the resized image to a memory stream - var memoryStream = new MemoryStream(); - resizedImage.Save(memoryStream, GetImageFormat(fileExtension)); - memoryStream.Position = 0; // Reset stream position - - return Results.File(memoryStream, contentType); - -}); - -static Bitmap ResizeImage(Image originalImage, int? width, int? height) -{ - int newWidth = width ?? originalImage.Width; - int newHeight = height ?? originalImage.Height; - - if (width == null) - { - newWidth = originalImage.Width * newHeight / originalImage.Height; - } - else if (height == null) - { - newHeight = originalImage.Height * newWidth / originalImage.Width; - } - - var resizedImage = new Bitmap(newWidth, newHeight); - using (var graphics = Graphics.FromImage(resizedImage)) - { - graphics.CompositingQuality = CompositingQuality.HighQuality; - graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - graphics.SmoothingMode = SmoothingMode.HighQuality; - graphics.DrawImage(originalImage, 0, 0, newWidth, newHeight); - } - - return resizedImage; -} - -static ImageFormat GetImageFormat(string extension) -{ - return extension switch - { - ".jpg" or ".jpeg" => ImageFormat.Jpeg, - ".png" => ImageFormat.Png, - ".gif" => ImageFormat.Gif, - ".bmp" => ImageFormat.Bmp, - ".webp" => ImageFormat.Webp, - _ => ImageFormat.Png, - }; -} - -Osudb.Instance.ToString(); -startCloudflared(); - -Task.Run(() => -{ - Thread.Sleep(500); - if (!apiClient.LoadCookies()) - { - Console.WriteLine("Please visit this link and paste the Value back into here: "); - - var cookie = Console.ReadLine(); - - apiClient.SaveCookies(cookie); - } - - Console.WriteLine("Ur Osu songs should now be available, please delete the cookies.json if it doesnt show up and try again."); -}); - -await apiClient.InitializeAsync(); -app.Run(); - -async Task startCloudflared() { - - var process = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = "cloudflared", - Arguments = "tunnel --url http://localhost:5153", - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - CreateNoWindow = true - } - }; - - process.ErrorDataReceived += (sender, e) => { - if (!string.IsNullOrEmpty(e.Data)) - { - ParseForUrls(e.Data); - } - }; - - process.Start(); - - process.BeginErrorReadLine(); - - await Task.Run(() => process.WaitForExit()); -} - -void ParseForUrls(string data) -{ - var urlRegex = new Regex(@"https?://[^\s]*\.trycloudflare\.com"); - var matches = urlRegex.Matches(data); - - foreach (Match match in matches) - { - Console.WriteLine($"Login here if not done already: {match.Value}/login"); - apiClient.UpdateSettingsAsync(match.Value); - } -} diff --git a/backend/Properties/launchSettings.json b/backend/Properties/launchSettings.json deleted file mode 100644 index e81a762..0000000 --- a/backend/Properties/launchSettings.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:45205", - "sslPort": 44305 - } - }, - "profiles": { - "shitweb": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "http://localhost:5153", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/backend/SqliteDB.cs b/backend/SqliteDB.cs deleted file mode 100644 index c30dedd..0000000 --- a/backend/SqliteDB.cs +++ /dev/null @@ -1,384 +0,0 @@ -using OsuParsers.Beatmaps; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.Data.SQLite; -using System.Reflection.PortableExecutable; - -namespace shitweb -{ - public class SqliteDB - { - private static SqliteDB instance; - private const string filename = "Beatmaps.db"; - private const string dburl = $"Data Source={filename};Version=3;"; - - static SqliteDB() { } - - public static SqliteDB Instance() - { - if (instance == null) - { - - instance = new SqliteDB(); - } - return instance; - } - - public void setup(OsuParsers.Database.OsuDatabase osuDatabase) - { - - int count = 0; - - using (var connection = new SQLiteConnection(dburl)) - { - connection.Open(); - - string createBeatmaps = @" - CREATE TABLE IF NOT EXISTS Beatmap ( - BeatmapId INTEGER DEFAULT 0, - Artist TEXT DEFAULT '?????', - ArtistUnicode TEXT DEFAULT '?????', - Title TEXT DEFAULT '???????', - TitleUnicode TEXT DEFAULT '???????', - Creator TEXT DEFAULT '?????', - Difficulty TEXT DEFAULT '1', - AudioFileName TEXT DEFAULT 'unknown.mp3', - MD5Hash TEXT DEFAULT '00000000000000000000000000000000', - FileName TEXT DEFAULT 'unknown.osu', - RankedStatus TEXT DEFAULT Unknown, - LastModifiedTime DATETIME DEFAULT '0001-01-01 00:00:00', - TotalTime INTEGER DEFAULT 0, - AudioPreviewTime INTEGER DEFAULT 0, - BeatmapSetId INTEGER DEFAULT -1, - Source TEXT DEFAULT '', - Tags TEXT DEFAULT '', - LastPlayed DATETIME DEFAULT '0001-01-01 00:00:00', - FolderName TEXT DEFAULT 'Unknown Folder', - UNIQUE (Artist, Title, MD5Hash) - );"; - - using (var command = new SQLiteCommand(createBeatmaps, connection)) - { - command.ExecuteNonQuery(); - } - - string activeSearch = @"CREATE VIRTUAL TABLE IF NOT EXISTS BeatmapFTS USING fts4( - Title, - Artist, - );"; - - using (var command = new SQLiteCommand(activeSearch, connection)) - { - command.ExecuteNonQuery(); - } - - string triggerSearchupdate = @"CREATE TRIGGER IF NOT EXISTS Beatmap_Insert_Trigger - AFTER INSERT ON Beatmap - BEGIN - INSERT INTO BeatmapFTS (Title, Artist) - VALUES (NEW.Title, NEW.Artist); - END;"; - - using (var command = new SQLiteCommand(triggerSearchupdate, connection)) - { - command.ExecuteNonQuery(); - } - - string query = @"SELECT COUNT(rowid) as count FROM Beatmap"; - - using (var command = new SQLiteCommand(query, connection)) - { - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - count = reader.GetInt32(reader.GetOrdinal("count")); - } - } - } - } - - if (count < osuDatabase.BeatmapCount) - { - DateTime? LastMapInsert = null; - - using (var connection = new SQLiteConnection(dburl)) - { - connection.Open(); - - string query = @"SELECT MAX(LastModifiedTime) as Time FROM Beatmap"; ; - using (var command = new SQLiteCommand(query, connection)) - { - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - try - { - LastMapInsert = reader.GetDateTime(reader.GetOrdinal("Time")); - } - - catch (Exception e) - { - LastMapInsert = null; - } - } - } - } - - int i = 0; - int size = osuDatabase.BeatmapCount; - Console.CursorVisible = false; - foreach (var item in osuDatabase.Beatmaps) - { - if (LastMapInsert == null || item.LastModifiedTime > LastMapInsert) - { - insertBeatmap(item); - i++; - Console.CursorTop -= 1; - Console.Write($"Inserted {i}/{size}"); - } - } - - } - } - - - - } - - public static List GetByRecent(int limit, int offset) - { - var songs = new List(); - - using (var connection = new SQLiteConnection(dburl)) - { - connection.Open(); - - string query = @" - SELECT - MD5Hash, - Title, - Artist, - TotalTime, - Creator, - FileName, - FolderName, - AudioFileName - FROM - Beatmap - GROUP BY - BeatmapSetId - ORDER BY - LastModifiedTime DESC - LIMIT @Limit - OFFSET @Offset - "; - - using (var command = new SQLiteCommand(query, connection)) - { - command.Parameters.AddWithValue("@Limit", limit); - command.Parameters.AddWithValue("@Offset", offset); - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - songs.Add(new Song(reader)); - } - } - } - } - return songs; - } - - public void insertBeatmap(OsuParsers.Database.Objects.DbBeatmap beatmap) - { - - using (var connection = new SQLiteConnection(dburl)) - { - - connection.Open(); - - string insertBeatmap = @" - INSERT INTO Beatmap ( - BeatmapId, Artist, ArtistUnicode, Title, TitleUnicode, Creator, Difficulty, - AudioFileName, MD5Hash, FileName, RankedStatus, LastModifiedTime, TotalTime, - AudioPreviewTime, BeatmapSetId, Source, Tags, LastPlayed, FolderName - ) VALUES ( - @BeatmapId, @Artist, @ArtistUnicode, @Title, @TitleUnicode, @Creator, @Difficulty, - @AudioFileName, @MD5Hash, @FileName, @RankedStatus, @LastModifiedTime, @TotalTime, - @AudioPreviewTime, @BeatmapSetId, @Source, @Tags, @LastPlayed, @FolderName - );"; - using (var command = new SQLiteCommand(insertBeatmap, connection)) - { - command.Parameters.AddWithValue("@BeatmapSetId", beatmap.BeatmapSetId); - command.Parameters.AddWithValue("@BeatmapId", beatmap.BeatmapId); - command.Parameters.AddWithValue("@Artist", beatmap.Artist); - command.Parameters.AddWithValue("@ArtistUnicode", beatmap.ArtistUnicode); - command.Parameters.AddWithValue("@Title", beatmap.Title); - command.Parameters.AddWithValue("@TitleUnicode", beatmap.TitleUnicode); - command.Parameters.AddWithValue("@Creator", beatmap.Creator); - command.Parameters.AddWithValue("@Difficulty", beatmap.Difficulty); - command.Parameters.AddWithValue("@AudioFileName", beatmap.AudioFileName); - command.Parameters.AddWithValue("@MD5Hash", beatmap.MD5Hash); - command.Parameters.AddWithValue("@FileName", beatmap.FileName); - command.Parameters.AddWithValue("@RankedStatus", beatmap.RankedStatus); - command.Parameters.AddWithValue("@LastModifiedTime", beatmap.LastModifiedTime); - command.Parameters.AddWithValue("@TotalTime", beatmap.TotalTime); - command.Parameters.AddWithValue("@AudioPreviewTime", beatmap.AudioPreviewTime); - command.Parameters.AddWithValue("@Source", beatmap.Source); - command.Parameters.AddWithValue("@Tags", beatmap.Tags); - command.Parameters.AddWithValue("@LastPlayed", beatmap.LastPlayed); - command.Parameters.AddWithValue("@FolderName", beatmap.FolderName); - - int rows = command.ExecuteNonQuery(); - Console.WriteLine(rows); - } - } - } - - public static Song GetSongByHash(string hash) - { - - using (var connection = new SQLiteConnection(dburl)) - { - connection.Open(); - - string query = @" - SELECT - MD5Hash, - Title, - Artist, - TotalTime, - Creator, - FileName, - FolderName, - AudioFileName - FROM Beatmap - WHERE MD5Hash = @Hash; - "; - - using (var command = new SQLiteCommand(query, connection)) - { - command.Parameters.AddWithValue("@Hash", hash); - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - return new Song(reader); - } - } - } - } - return null; - } - - public static ActiveSearch activeSearch(string query) { - ActiveSearch search = new ActiveSearch(); - - using (var connection = new SQLiteConnection(dburl)) - { - string q = @"SELECT - MD5Hash, - Title, - Artist, - TotalTime, - Creator, - FileName, - FolderName, - AudioFileName - FROM Beatmap - WHERE Title LIKE @query - OR Artist LIKE @query - OR Tags LIKE @query - Group By Title - LIMIT 15"; - - connection.Open(); - - using (var command = new SQLiteCommand(q, connection)) - { - command.Parameters.AddWithValue("@query", "%" + query + "%"); - - using (var reader = command.ExecuteReader()) { - - while (reader.Read()) { - - search.Songs.Add(new Song(reader)); - } - } - } - - string q2 = @"SELECT - Artist - FROM Beatmap - WHERE Artist LIKE @query - OR Title LIKE @query - Group By Artist - LIMIT 5"; - - using (var command = new SQLiteCommand(q2, connection)) - { - command.Parameters.AddWithValue("@query", query + "%"); - - using (var reader = command.ExecuteReader()) - { - - while (reader.Read()) - { - - search.Artist.Add(reader.GetString(reader.GetOrdinal("Artist"))); - - } - } - } - } - - return search; - } - - public static List GetArtistSearch(string query, int limit, int offset) { - List songs = new List(); - - query = $"%{query}%"; - using (var connection = new SQLiteConnection(dburl)) - { - string q = @"SELECT - MD5Hash, - Title, - Artist, - TotalTime, - Creator, - FileName, - FolderName, - AudioFileName - FROM Beatmap - WHERE Artist LIKE @query - Group By Title - LIMIT @Limit - OFFSET @Offset"; - - connection.Open(); - - using (var command = new SQLiteCommand(q, connection)) - { - command.Parameters.AddWithValue("@query", query); - command.Parameters.AddWithValue("@Limit", limit); - command.Parameters.AddWithValue("@Offset", offset); - - using (var reader = command.ExecuteReader()) - { - - while (reader.Read()) - { - songs.Add(new Song(reader)); - } - } - } - } - - return songs; - } - } -} diff --git a/backend/appsettings.Development.json b/backend/appsettings.Development.json deleted file mode 100644 index 0c208ae..0000000 --- a/backend/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/backend/appsettings.json b/backend/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/backend/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/backend/default-bg.png b/backend/default-bg.png deleted file mode 100644 index 2c31f5a67c026cf01a1e7d11043ffaadb393823f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3787 zcmeHKYdni=+AmI(jG!(OegS#*)Zz zw4s5Ki9Xf{LohpLfYX5^(Z;4IBN75<3`1g&h6ET2i!>x6@kA`q97{6S!{AYPl0Meh z(9{A=Fh$@9Xo8s@8gF21YG7<~423<4KNWhtpo7*8!;N**xla|g=p7TS!*P(W=?u;e1A@~C^*5B@}{4j_daMD^I z>n_PD>bJPnVRb^0N>;GYX|%nOZ?C1LMPV1tzN!wZDd{eA%bap_@_TOUQsj}|kn@Nk zrZ_PbROVOtn(h2duX|x#wRPh%+OsgH-fQA`raQKN^%UclO@&5PZjtk|0W0IlHBp#r zY(;p@oxRbxNP?}xx=h4pp||nbv@e~<8i$|yMCYxxrLGnlsG4EB<_q*(p5ORj9#p`! zR^GEwo0|rr0q{Dn{v&<@+GKf@I+c?T!l=`QLl@q zU5d`m+oDEI8!|=GppEo@k3uF_-fx$*s92mD@d14*)*NpSN^DAmpAPW6WN>uIn=IQ8 z37-6=3WNZqnfu2?q^jXulg_0dO>v{Ofk-f1iVf`@A3LYi^vhUT?pmi`=S9$y@lmzV zIM<1Pzs((X+>EC82#wP%Qm3|1za{meYscpbx5Y{a?7$=W7-cMGDfMAll*Wy3aTT3$ zTFa3!Aap}_;b)eMF;tqb`4cUO{VKC5?g0NFByi1Ln9BJQ-3+lG-4gHWBg$*d)m|)o zV>nL}190G}>MlujCFG8a@p8k5my+YioHG3@#C!O$N7v3(vYb-LI)Q~Y> z53@@BY!9C0<|KrxcU!4|AvLOg;a3_b%3QZE%aiBuO$zbZ0sMh4J#(~ES68(!PjW@s zymoK&^hHO|u0W4+BSLs?6sC;gl01965Wbe21Jj^N2zx*+jIX;k7?Ux6d@#le`}>j^ zWv9yt#Od*)1c|uwqlpD684}&WbFYPfaGc&07uM9!D?cADodBR;9dSJQKOU-4ivIZ! zQe@4;E3xyfXzHPzufT=~;^Nk!n+sTNyB`>8oB~JZv|zMUiF9^t%yn9a z6%b@#8Y=%}-1HF9E&tW6YW_?JHaa=}>cdgm6~ZGD7{Sc7rDclOahS+`7|zuAR=U)i zc~@=Cm&$#b0%Tp~lYnvCQC3Ocr^Ct9=4=GE2;dxnn)t7UKyoC@IItPq|E#@EN{jcU zZOOl^1NN-`!~KYF)t{SL3GS@nolgcBVL2;#tbNTPGm{N}275~}UIBC6#dn1HVNR%{ zmcm0%^UGZqwf3K_11ry4cURx=k80dR7JJ^StQymEhy>c_YXxt^7~L?Ipn)7?t|&HW zx`jX(rDp*@t;mVi+0^aMueaXEg^ii436l4tXHWn-LxWfu=*Ov?G3oQ4%WglzQ(9dm z7;<3fne_VDR`UWUPRw#a{LpJH7K4;|_0(mnDLL_A~+w~yy-PbLdZu1ZwdvKQInavehwCpm#i9_gyk zZ7pr+>WoKMepAOGpHeJ5#)A% zvLv;N13I;*u(C(GYkXwb%s07ff|in93f4+cZun4M$)E0Z+^oH{OSO;h^JbRnWL4I@ zA7FO;$vJgvLU6f<1L6)s6;6Af6|Azh3D^Jw5G4J6hF~i|+%!~-J*%nKG8@vzOD++i z*Iy%pt8tUxv%T)Xr9-7vc^HVXUh1Z0C#`I7k%Lsa=zr`o zs&7(!wqKseJ31gz#Lf3{)V7!1!aDZ*Wkak0bu$&ING7(aRInI#ch&8Nu#(RU%S3AY zL)tW)5s%A1v?{XRq>06_%})&70NN}-F*;OrZ1QU=LJg$}o2YGas*sd%od?J725-NP z#)!nkY7cwejA|2R$9!q5{-r5-&idzHz~wqk-h!VzYARYjN`Yr0q|}0m$1H3+j+GKx z=XsG+Y57M45aK%@2HXMu@@cMlY;Y>;C~7+L)ki@Dd+P%@JJUJSt=Do!u{SO^v%N(b zrJyb3NO7H;d7T{nLX#YY@~Pp?wEyWQud&D+po*w-*tk$aaJ#k}>B2SBT4eB{FY7YO zG9*yF&V`0R!!q&zB82xmNeD?G>qgSW86Ux+RwqgfUQvn~@iL()5*U>6{+*tATc+eL zty(pUoQcU9G_pA5*{JoUo!=RrU2C%D-2sZp#pS~-dKJ>F+mn)gSf-_A&opHT=b*cO zb(eKj()Si54C+R%pkT#&TFnBRI*@kIHi}#@Crpyz07l01UkMGbeR z;Q8b9>Cw#;4-i7h92h##QKRE^pj4$XY z-Y2JaTQ&1RcgRegH(4ko7+e>f&+8x(ts7&MQh&AH!YdEo<#qP%I*g_5M|ITk^3v#u zFTOngD51|{T)yc=y0zT4s{$k+nMwLh^-OkTKxO=Ff{ z*W{-Sx1cTQn>MqNayvU6%77-afpiPzM6pSY^s=HLjgK7YS?!p|E>3h#-~kyzbb2{)g8v{02`NK?-QCqoU1LC_!LCz@COR}I)(E6 z+wuT=MRsn~)8>5I<^BfP6J7KS0YEfDpy{Y?E%#Xd&B*extH$VAbHKRmLB99SRSGqm zuY7N+`GC=oaBBXt(f@1w`!4+VUHJd{F1&CX6sg1MJEBwYc~djZh%n&aDTHF>aI*9` GE%85oCk|%- diff --git a/backend/example-cookies.json b/backend/example-cookies.json deleted file mode 100644 index 56e05e5..0000000 --- a/backend/example-cookies.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Name": "cookie_name", - "Value": "random cookie value here" -} diff --git a/backend/osudb.cs b/backend/osudb.cs deleted file mode 100644 index e88d7b7..0000000 --- a/backend/osudb.cs +++ /dev/null @@ -1,158 +0,0 @@ -using Microsoft.Win32; -using OsuParsers.Database; -using shitweb; -using System.Text.RegularExpressions; - -public class Osudb -{ - private static Osudb instance = null; - private static readonly object padlock = new object(); - public static string osufolder { get; private set; } - public static CollectionDatabase CollectionDb { get; private set; } - - static Osudb() - { - var key = Registry.GetValue( - @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\osu\shell\open\command", - "", - null - ); - - if (key != null) - { - string[] keyparts = key.ToString().Split('"'); - - osufolder = Path.GetDirectoryName(keyparts[1]); - - Parse(osufolder); - } - else throw new Exception("Osu not Installed... "); - } - - static void Parse(string filepath) - { - OsuDatabase osuDatabase = null; - string file = "/osu!.db"; - if (File.Exists(filepath + file)) - { - using (FileStream fileStream = new FileStream(filepath + file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: 4096, useAsync: true)) - { - Console.WriteLine($"Parsing {file}"); - osuDatabase = OsuParsers.Decoders.DatabaseDecoder.DecodeOsu($"{filepath}{file}"); - Console.WriteLine($"Parsed {file}"); - - fileStream.Close(); - } - } - - file = "/collection.db"; - if (File.Exists(filepath + file)) - { - using (FileStream fileStream = new FileStream(filepath + file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: 4096, useAsync: true)) - { - Console.WriteLine($"Parsing {file}"); - CollectionDb = OsuParsers.Decoders.DatabaseDecoder.DecodeCollection($"{filepath}{file}"); - Console.WriteLine($"Parsed {file}"); - } - } - - SqliteDB.Instance().setup(osuDatabase); - osuDatabase = null; - GC.Collect(); - } - - public static Osudb Instance - { - get - { - lock (padlock) - { - if (instance == null) - { - instance = new Osudb(); - } - return instance; - } - } - } - - public static OsuParsers.Database.Objects.Collection GetCollectionbyName(string name) { - - return CollectionDb.Collections.FirstOrDefault(collection => collection.Name == name); - } - - public static OsuParsers.Database.Objects.Collection GetCollectionbyIndex(int index) - { - - return CollectionDb.Collections.ElementAtOrDefault(index); - } - - public Collection GetCollection(int index) { - - var collection = GetCollectionbyIndex(index); - if (collection == null) { return null; } - - List songs = new List(); - var activeId = ""; - - collection.MD5Hashes.ForEach(hash => - { - var beatmap = SqliteDB.GetSongByHash(hash); - if (beatmap == null) { return; } - - songs.Add(beatmap); - - }); - - return new Collection(collection.Name, songs.Count, songs); - } - - public List GetCollections(int limit, int offset) - { - - List collections = new List(); - - for (int i = offset; i < CollectionDb.Collections.Count - 1 && i < offset + limit; i++) { - var collection = CollectionDb.Collections[i]; - - var beatmap = SqliteDB.GetSongByHash(collection.MD5Hashes.FirstOrDefault()); - - collections.Add(new CollectionPreview(index: i, name: collection.Name, previewimage: beatmap.previewimage, length: collection.Count)); - }; - - return collections; - } - - public static string getBG(string songfolder, string diff) - { - string folderpath = Path.Combine(songfolder, diff); - string filepath = Path.Combine(osufolder, "Songs", folderpath); - - if (File.Exists(filepath)) - { - string fileContents = File.ReadAllText($@"{filepath}"); // Read the contents of the file - - string pattern = @"\d+,\d+,""(?[^""]+\.[a-zA-Z]+)"",\d+,\d+"; - - Match match = Regex.Match(fileContents, pattern); - - if (match.Success) - { - string background = Uri.EscapeDataString(match.Groups["image_filename"].Value); - - return Path.Combine(Uri.EscapeDataString(songfolder), background); - } - - pattern = @"\d+,\d+,""(?[^""]+\.[a-zA-Z]+)"""; - - match = Regex.Match(fileContents, pattern); - - if (match.Success) - { - string background = Uri.EscapeDataString(match.Groups["image_filename"].Value); - return Path.Combine(Uri.EscapeDataString(songfolder), background); - } - } - return "default-bg.png"; - } -} diff --git a/backend/shitweb.csproj b/backend/shitweb.csproj deleted file mode 100644 index 9026d11..0000000 --- a/backend/shitweb.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - PreserveNewest - - - - diff --git a/backend/shitweb.sln b/backend/shitweb.sln deleted file mode 100644 index 2d3e2f2..0000000 --- a/backend/shitweb.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.8.34322.80 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "shitweb", "shitweb.csproj", "{A81ACB49-5C0C-42D5-88DA-3BC7E256F859}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A81ACB49-5C0C-42D5-88DA-3BC7E256F859}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A81ACB49-5C0C-42D5-88DA-3BC7E256F859}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A81ACB49-5C0C-42D5-88DA-3BC7E256F859}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A81ACB49-5C0C-42D5-88DA-3BC7E256F859}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A5EA63AB-B1DD-4171-922C-D01C758AD544} - EndGlobalSection -EndGlobal diff --git a/backend/types.cs b/backend/types.cs deleted file mode 100644 index 424cdb0..0000000 --- a/backend/types.cs +++ /dev/null @@ -1,102 +0,0 @@ -using OsuParsers.Database.Objects; -using OsuParsers.Enums.Database; -using OsuParsers.Enums; -using System.Data.SQLite; -using System.CodeDom; - -public class Song{ - public string hash {get; set;} - public string name {get; set;} - public string artist {get; set;} - public int length {get; set;} - public string url { get; set; } - public string previewimage {get; set;} - public string mapper {get; set;} - - public Song(string hash, string name, string artist, int length, string url, string previewimage, string mapper) { - this.hash = hash; this.name = name; this.artist = artist; this.length = length; this.url = url; this.previewimage = previewimage; this.mapper = mapper; - } - - public Song(SQLiteDataReader reader) { - string folder = reader.GetString(reader.GetOrdinal("FolderName")); - string file = reader.GetString(reader.GetOrdinal("FileName")); - string audio = reader.GetString(reader.GetOrdinal("AudioFileName")); - - this.hash = reader.GetString(reader.GetOrdinal("MD5Hash")); - this.name = reader.GetString(reader.GetOrdinal("Title")); - this.artist = reader.GetString(reader.GetOrdinal("Artist")); - this.length = reader.GetInt32(reader.GetOrdinal("TotalTime")); - this.url = Uri.EscapeDataString($"{folder}/{audio}"); - this.previewimage = Osudb.getBG(folder, file); - this.mapper = reader.GetString(reader.GetOrdinal("Creator")); - - } -} - -public class CollectionPreview{ - public int index { get; set;} - public string? name {get; set;} - public int length {get; set;} - public string? previewimage {get; set;} - - private CollectionPreview() { } - - public CollectionPreview(int index, string name, string previewimage, int length) { - this.index = index; this.name = name; this.previewimage = previewimage; this.length = length; - } - -} -public class Collection{ - public string? name {get; set;} - public int length {get; set;} - public List songs { get; set;} = new List(); - - private Collection() { } - - public Collection(string name, int length, List songs) { - this.name = name; this.length = length; this.songs = songs; - } - -} - -public class ActiveSearch{ - public List Artist { get; set; } = new List(); - public List Songs { get; set; } = new List(); -} - -public class Beatmap -{ - public string? Artist { get; set; } - public string? ArtistUnicode { get; set; } - public string? Title { get; set; } - public string? TitleUnicode { get; set; } - public string? Creator { get; set; } - public string? Difficulty { get; set; } - public string? AudioFileName { get; set; } - public string? MD5Hash { get; set; } - public string? FileName { get; set; } - public RankedStatus RankedStatus { get; set; } - public DateTime LastModifiedTime { get; set; } - public int TotalTime { get; set; } - public int AudioPreviewTime { get; set; } - public int BeatmapId { get; set; } - public int BeatmapSetId { get; set; } - public string? Source { get; set; } - public string? Tags { get; set; } - public DateTime LastPlayed { get; set; } - public string? FolderName { get; set; } -} - -public class BeatmapSet { - public int BeatmapSetId { get; set; } - public string? FolderName { get; set; } - public string? Creator { get; set; } - public DateTime LastModifiedTime { get; set; } - public List Beatmaps { get; private set; } = new List(); - - public void AddBeatmap(Beatmap beatmap) - { - beatmap.BeatmapSetId = this.BeatmapSetId; - Beatmaps.Add(beatmap); - } -} \ No newline at end of file diff --git a/go-backend/.gitignore b/go-backend/.gitignore deleted file mode 100644 index 4bdc63d..0000000 --- a/go-backend/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -data/* -.vscode/ -.env \ No newline at end of file diff --git a/go-backend/database.go b/go-backend/database.go deleted file mode 100644 index 49a075a..0000000 --- a/go-backend/database.go +++ /dev/null @@ -1,599 +0,0 @@ -package main - -import ( - "database/sql" - "errors" - "fmt" - "log" - "os" - "path" - "path/filepath" - "strconv" - "strings" - - "github.com/juli0n21/go-osu-parser/parser" - _ "modernc.org/sqlite" -) - -var ErrBeatmapCountNotMatch = errors.New("beatmap count not matching") - -var osuDB *parser.OsuDB -var osuRoot string - -func initDB(connectionString string, osuDb *parser.OsuDB, osuroot string) (*sql.DB, error) { - - osuDB = osuDb - osuRoot = osuroot - - dir := filepath.Dir(connectionString) - - if _, err := os.Stat(dir); os.IsNotExist(err) { - err = os.MkdirAll(dir, 0755) - if err != nil { - return nil, fmt.Errorf("failed to create directory %s: %v", dir, err) - } - } - - db, err := sql.Open("sqlite", connectionString) - if err != nil { - return nil, fmt.Errorf("failed to open SQLite database %s: %v", connectionString, err) - } - - _, err = db.Exec("PRAGMA temp_store = MEMORY;") - if err != nil { - log.Fatal(err) - } - - if err = createDB(db); err != nil { - return nil, err - } - - if err = checkhealth(db, osuDB); err != nil { - if err = rebuildBeatmapDb(db, osuDB); err != nil { - return nil, err - } - } - - if err = createCollectionDB(db); err != nil { - return nil, err - } - - collectionDB, err := parser.ParseCollectionsDB(path.Join(osuRoot, "collection.db")) - if err != nil { - return nil, err - } - - if err = checkCollectionHealth(db, collectionDB); err != nil { - if err = rebuildCollectionDb(db, collectionDB); err != nil { - return nil, err - } - } - - return db, nil -} - -func createDB(db *sql.DB) error { - - _, err := db.Exec(` - CREATE TABLE IF NOT EXISTS Beatmap ( - BeatmapId INTEGER DEFAULT 0, - Artist TEXT DEFAULT '?????', - ArtistUnicode TEXT DEFAULT '?????', - Title TEXT DEFAULT '???????', - TitleUnicode TEXT DEFAULT '???????', - Creator TEXT DEFAULT '?????', - Difficulty TEXT DEFAULT '1', - Audio TEXT DEFAULT 'unknown.mp3', - MD5Hash TEXT DEFAULT '00000000000000000000000000000000', - File TEXT DEFAULT 'unknown.osu', - RankedStatus TEXT DEFAULT Unknown, - LastModifiedTime DATETIME DEFAULT '0001-01-01 00:00:00', - TotalTime INTEGER DEFAULT 0, - AudioPreviewTime INTEGER DEFAULT 0, - BeatmapSetId INTEGER DEFAULT -1, - Source TEXT DEFAULT '', - Tags TEXT DEFAULT '', - LastPlayed DATETIME DEFAULT '0001-01-01 00:00:00', - Folder TEXT DEFAULT 'Unknown Folder', - UNIQUE (Artist, Title, MD5Hash, Difficulty) - ); - `) - if err != nil { - return err - } - - _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_beatmap_md5hash ON Beatmap(MD5Hash);") - if err != nil { - return err - } - - _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_beatmap_lastModifiedTime ON Beatmap(LastModifiedTime);") - if err != nil { - return err - } - - _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_beatmap_title_artist ON Beatmap(Title, Artist);") - if err != nil { - return err - } - - return nil -} - -func createCollectionDB(db *sql.DB) error { - _, err := db.Exec(`CREATE TABLE IF NOT EXISTS Collection ( - Name TEXT DEFAULT '', - MD5Hash TEXT DEFAULT '00000000000000000000000000000000' - ); - `) - if err != nil { - return err - } - - _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_collection_name ON Collection(Name);") - if err != nil { - return err - } - - _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_collection_md5hash ON Collection(MD5Hash);") - if err != nil { - return err - } - - return nil -} - -func checkhealth(db *sql.DB, osuDb *parser.OsuDB) error { - - rows, err := db.Query(`SELECT COUNT(*) FROM Beatmap GROUP BY BeatmapSetId;`) - if err != nil { - return err - } - defer rows.Close() - - var count int - if err = rows.Scan(&count); err != nil { - return err - } - - if count != int(osuDb.FolderCount) { - log.Println("Folder count missmatch rebuilding db...") - return ErrBeatmapCountNotMatch - } - - rows, err = db.Query(`SELECT COUNT(*) FROM Beatmap;`) - if err != nil { - return err - } - - if err = rows.Scan(&count); err != nil { - return err - } - - if count != int(osuDb.NumberOfBeatmaps) { - log.Println("Beatmap count missmatch rebuilding db...") - return ErrBeatmapCountNotMatch - } - - return nil -} - -func rebuildBeatmapDb(db *sql.DB, osuDb *parser.OsuDB) error { - - if _, err := db.Exec("DROP TABLE Beatmap"); err != nil { - return err - } - - if err := createDB(db); err != nil { - return err - } - stmt, err := db.Prepare(` - INSERT INTO Beatmap ( - BeatmapId, Artist, ArtistUnicode, Title, TitleUnicode, Creator, - Difficulty, Audio, MD5Hash, File, RankedStatus, - LastModifiedTime, TotalTime, AudioPreviewTime, BeatmapSetId, - Source, Tags, LastPlayed, Folder - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - `) - // ON CONFLICT (Artist, Title, MD5Hash) DO NOTHING - - if err != nil { - return err - } - defer stmt.Close() - - tx, err := db.Begin() - if err != nil { - return err - } - - stmt = tx.Stmt(stmt) - - for i, beatmap := range osuDb.Beatmaps { - //fmt.Println(i, beatmap.Artist, beatmap.SongTitle, beatmap.MD5Hash) - _, err := stmt.Exec( - beatmap.DifficultyID, beatmap.Artist, beatmap.ArtistUnicode, - beatmap.SongTitle, beatmap.SongTitleUnicode, beatmap.Creator, - beatmap.Difficulty, beatmap.AudioFileName, beatmap.MD5Hash, - beatmap.FileName, beatmap.RankedStatus, beatmap.LastModificationTime, - beatmap.TotalTime, beatmap.AudioPreviewStartTime, beatmap.BeatmapID, - beatmap.SongSource, beatmap.SongTags, beatmap.LastPlayed, beatmap.FolderName, - ) - if err != nil { - fmt.Println(i, "hash: ", beatmap.MD5Hash, "artist:", beatmap.Artist, "title:", beatmap.SongTitle, err) - } - } - - if err := tx.Commit(); err != nil { - return err - } - - return nil -} - -func checkCollectionHealth(db *sql.DB, collectionDB *parser.Collections) error { - rows, err := db.Query(`SELECT COUNT(*) FROM Collection GROUP BY Name;`) - if err != nil { - return err - } - defer rows.Close() - - var count int - if err = rows.Scan(&count); err != nil { - return err - } - - if count != int(collectionDB.NumberOfCollections) { - return errors.New("Collection Count Not Matching") - } - - rows, err = db.Query(`SELECT COUNT(*) FROM Collection;`) - if err != nil { - return err - } - - if err = rows.Scan(&count); err != nil { - return err - } - - sum := 0 - for _, col := range collectionDB.Collections { - sum += len(col.Beatmaps) - } - - if count != int(sum) { - return errors.New("Beatmap count missmatch rebuilding collections") - } - - return nil -} - -func rebuildCollectionDb(db *sql.DB, collectionDb *parser.Collections) error { - if _, err := db.Exec("DROP TABLE Collection"); err != nil { - return err - } - - if err := createCollectionDB(db); err != nil { - return err - } - - stmt, err := db.Prepare(` - INSERT INTO Collection ( - Name, - MD5Hash - ) VALUES (?, ?) - `) - if err != nil { - return err - } - defer stmt.Close() - - tx, err := db.Begin() - if err != nil { - return err - } - - stmt = tx.Stmt(stmt) - - for _, col := range collectionDb.Collections { - for _, hash := range col.Beatmaps { - _, err := stmt.Exec(col.Name, hash) - if err != nil { - fmt.Println(err) - } - } - } - - return tx.Commit() -} - -func getBeatmapCount(db *sql.DB) int { - rows, err := db.Query("SELECT COUNT(*) FROM Beatmap") - if err != nil { - log.Println(err) - return 0 - } - defer rows.Close() - - var count int - if rows.Next() { - err = rows.Scan(&count) - if err != nil { - log.Println(err) - return 0 - } - } else { - return 0 - } - - return count -} - -func getRecent(db *sql.DB, limit, offset int) ([]Song, error) { - rows, err := db.Query("SELECT BeatmapId, MD5Hash, Title, Artist, Creator, Folder, File, Audio, TotalTime FROM Beatmap ORDER BY LastModifiedTime DESC LIMIT ? OFFSET ?", limit, offset) - if err != nil { - return []Song{}, err - } - defer rows.Close() - - return scanSongs(rows) -} - -func getSearch(db *sql.DB, q string, limit, offset int) (ActiveSearch, error) { - rows, err := db.Query("SELECT BeatmapId, MD5Hash, Title, Artist, Creator, Folder, File, Audio, TotalTime FROM Beatmap WHERE MD5Hash FROM Songs WHERE Title LIKE ? OR Artist LIKE ? LIMIT ? OFFSET ?", "%"+q+"%", "%"+q+"%", limit, offset) - if err != nil { - return ActiveSearch{}, err - } - defer rows.Close() - _, err = scanSongs(rows) - if err != nil { - return ActiveSearch{}, err - } - return ActiveSearch{}, nil -} - -func getArtists(db *sql.DB, q string, limit, offset int) ([]Artist, error) { - rows, err := db.Query("SELECT Artist, COUNT(Artist) FROM Beatmap WHERE Artist LIKE ? OR Title LIKE ? GROUP BY Artist LIMIT ? OFFSET ?", "%"+q+"%", "%"+q+"%", limit, offset) - if err != nil { - return []Artist{}, err - } - defer rows.Close() - - artist := []Artist{} - for rows.Next() { - var a string - var c int - err := rows.Scan(&a, &c) - if err != nil { - return []Artist{}, err - } - artist = append(artist, Artist{Artist: a, Count: c}) - } - - return artist, nil -} - -func getFavorites(db *sql.DB, q string, limit, offset int) ([]Song, error) { - rows, err := db.Query("SELECT * FROM Songs WHERE IsFavorite = 1 LIMIT ? OFFSET ?", limit, offset) - if err != nil { - return nil, err - } - defer rows.Close() - return scanSongs(rows) -} - -func getCollection(db *sql.DB, limit, offset, index int) (Collection, error) { - rows, err := db.Query(` - WITH cols AS ( - SELECT - c.Name, - ROW_NUMBER() OVER (ORDER BY c.Name) AS RowNumber - FROM Collection c - GROUP BY c.Name - ) - - SELECT - c.Name, b.BeatmapId, b.MD5Hash, b.Title, b.Artist, - b.Creator, b.Folder, b.File, b.Audio, b.TotalTime - FROM Collection c - Join Beatmap b ON c.MD5Hash = b.MD5Hash - WHERE c.Name = (SELECT Name FROM cols WHERE RowNumber = ?) - LIMIT ? - OFFSET ?;`, index, limit, offset) - if err != nil { - return Collection{}, err - } - defer rows.Close() - - var c Collection - for rows.Next() { - s := Song{} - if err := rows.Scan(&c.Name, &s.BeatmapID, &s.MD5Hash, &s.Title, &s.Artist, &s.Creator, &s.Folder, &s.File, &s.Audio, &s.TotalTime); err != nil { - return Collection{}, err - } - - s.Image = extractImageFromFile(osuRoot, s.Folder, s.File) - - c.Songs = append(c.Songs, s) - } - - row := db.QueryRow(`SELECT COUNT(*) FROM Collection WHERE Name = ?`, c.Name) - var count string - row.Scan(&count) - - if i, err := strconv.Atoi(count); err == nil { - c.Items = i - } - - return c, nil -} - -func getCollectionByName(db *sql.DB, limit, offset int, name string) (Collection, error) { - rows, err := db.Query(` - SELECT - c.Name, b.BeatmapId, b.MD5Hash, b.Title, b.Artist, - b.Creator, b.Folder, b.File, b.Audio, b.TotalTime - FROM Collection c - Join Beatmap b ON c.MD5Hash = b.MD5Hash - WHERE c.Name = ? - LIMIT ? - OFFSET ?;`, name, limit, offset) - if err != nil { - return Collection{}, err - } - defer rows.Close() - - var c Collection - for rows.Next() { - s := Song{} - if err := rows.Scan(&c.Name, &s.BeatmapID, &s.MD5Hash, &s.Title, &s.Artist, &s.Creator, &s.Folder, &s.File, &s.Audio, &s.TotalTime); err != nil { - return Collection{}, err - } - - s.Image = extractImageFromFile(osuRoot, s.Folder, s.File) - - c.Songs = append(c.Songs, s) - } - - row := db.QueryRow(`SELECT COUNT(*) FROM Collection WHERE Name = ?`, c.Name) - var count string - row.Scan(&count) - - if i, err := strconv.Atoi(count); err == nil { - c.Items = i - } else { - return Collection{}, err - } - - return c, nil -} - -func getCollections(db *sql.DB, q string, limit, offset int) ([]CollectionPreview, error) { - rows, err := db.Query(` - SELECT - c.Name, COUNT(b.MD5Hash), b.Folder, b.File - FROM Collection c - Join Beatmap b ON c.MD5Hash = b.MD5Hash - WHERE c.Name LIKE ? - GROUP BY c.NAME - LIMIT ? - OFFSET ?;`, "%"+q+"%", limit, offset) - if err != nil { - return []CollectionPreview{}, err - } - defer rows.Close() - - var collections []CollectionPreview - for rows.Next() { - var c CollectionPreview - var folder, file, count string - if err := rows.Scan(&c.Name, &count, &folder, &file); err != nil { - return []CollectionPreview{}, err - } - - if i, err := strconv.Atoi(count); err == nil { - c.Items = i - } - c.Image = extractImageFromFile(osuRoot, folder, file) - - collections = append(collections, c) - } - - return collections, nil -} - -func getSong(db *sql.DB, hash string) (Song, error) { - - row := db.QueryRow("SELECT BeatmapId, MD5Hash, Title, Artist, Creator, Folder, File, Audio, TotalTime FROM Beatmap WHERE MD5Hash = ?", hash) - s, err := scanSong(row) - return s, err - -} - -func scanSongs(rows *sql.Rows) ([]Song, error) { - songs := []Song{} - for rows.Next() { - var s Song - if err := rows.Scan(&s.BeatmapID, &s.MD5Hash, &s.Title, &s.Artist, &s.Creator, &s.Folder, &s.File, &s.Audio, &s.TotalTime); err != nil { - return []Song{}, err - } - - 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") - } else { - if len(bm.Events) > 1 && len(bm.Events[0].EventParams) > 1 { - s.Image = fmt.Sprintf("%s/%s", s.Folder, strings.Trim(bm.Events[0].EventParams[0], "\"")) - } - } - - songs = append(songs, s) - } - return songs, nil -} - -func scanSong(row *sql.Row) (Song, error) { - - s := Song{} - if err := row.Scan(&s.BeatmapID, &s.MD5Hash, &s.Title, &s.Artist, &s.Creator, &s.Folder, &s.File, &s.Audio, &s.TotalTime); err != nil { - return Song{}, err - } - - s.Image = extractImageFromFile(osuRoot, s.Folder, s.File) - - return s, nil -} - -func extractImageFromFile(osuRoot, folder, file string) string { - bm, err := parser.ParseOsuFile(filepath.Join(osuRoot, "Songs", folder, file)) - if err != nil { - fmt.Println(err) - return "404.png" - } - - if bm.Version > 3 { - if len(bm.Events) > 0 && len(bm.Events[0].EventParams) > 0 { - return fmt.Sprintf(`%s/%s`, folder, strings.Trim(bm.Events[0].EventParams[0], "\"")) - } - } else { - fmt.Println(bm.Events) - } - - return "404.png" -} - -func scanCollections(rows *sql.Rows) ([]Collection, error) { - - var collection []Collection - for rows.Next() { - var c Collection - if err := rows.Scan(&c); err != nil { - return []Collection{}, err - } - collection = append(collection, c) - } - return collection, nil -} - -func scanCollectionPreviews(rows *sql.Rows) ([]CollectionPreview, error) { - - var collection []CollectionPreview - for rows.Next() { - var c CollectionPreview - if err := rows.Scan(&c); err != nil { - return []CollectionPreview{}, err - } - collection = append(collection, c) - } - return collection, nil -} - -func scanCollectionPreview(row *sql.Row) (CollectionPreview, error) { - - var c CollectionPreview - if err := row.Scan(&c); err != nil { - return CollectionPreview{}, err - } - return c, nil -} diff --git a/go-backend/docs/docs.go b/go-backend/docs/docs.go deleted file mode 100644 index 073c744..0000000 --- a/go-backend/docs/docs.go +++ /dev/null @@ -1,685 +0,0 @@ -// Package docs Code generated by swaggo/swag. DO NOT EDIT -package docs - -import "github.com/swaggo/swag" - -const docTemplate = `{ - "schemes": {{ marshal .Schemes }}, - "swagger": "2.0", - "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", - "contact": {}, - "version": "{{.Version}}" - }, - "host": "{{.Host}}", - "basePath": "{{.BasePath}}", - "paths": { - "/audio/{filepath}": { - "get": { - "description": "Retrieves a song file from the server based on the provided encoded filepath", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "files" - ], - "summary": "Retrieves a song file by its encoded path", - "parameters": [ - { - "type": "string", - "description": "Base64 encoded file path", - "name": "filepath", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "The requested song file", - "schema": { - "type": "file" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "404": { - "description": "File Not Found", - "schema": { - "type": "string" - } - } - } - } - }, - "/collection": { - "get": { - "description": "Retrieves a collection of songs using the provided index.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a collection of songs by index", - "parameters": [ - { - "type": "integer", - "description": "Index", - "name": "index", - "in": "query" - }, - { - "type": "string", - "description": "Index", - "name": "name", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "400": { - "description": "Invalid parameter", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "type": "string" - } - } - } - } - }, - "/image/{filepath}": { - "get": { - "description": "Retrieves an image file from the server based on the provided encoded filepath", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "files" - ], - "summary": "Retrieves an image file by its encoded path", - "parameters": [ - { - "type": "string", - "description": "Base64 encoded file path", - "name": "filepath", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "The requested image file", - "schema": { - "type": "file" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "404": { - "description": "File Not Found", - "schema": { - "type": "string" - } - } - } - } - }, - "/login": { - "get": { - "description": "Redirects users to an external authentication page", - "tags": [ - "auth" - ], - "summary": "Redirect to login page", - "responses": { - "307": { - "description": "Temporary Redirect", - "schema": { - "type": "string" - } - } - } - } - }, - "/ping": { - "get": { - "description": "Returns a pong response if the server is running", - "tags": [ - "health" - ], - "summary": "Check server health", - "responses": { - "200": { - "description": "pong", - "schema": { - "type": "string" - } - } - } - } - }, - "/search/active": { - "get": { - "description": "Searches active records in the database based on the query parameter", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "search" - ], - "summary": "Searches active records based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit the number of results", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset for pagination", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Active search result", - "schema": { - "$ref": "#/definitions/main.ActiveSearch" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/search/artist": { - "get": { - "description": "Searches for artists in the database based on the query parameter", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "search" - ], - "summary": "Searches for artists based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit the number of results", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset for pagination", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "List of artists", - "schema": { - "$ref": "#/definitions/main.Artist" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/search/collections": { - "get": { - "description": "Searches collections in the database based on the query parameter", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "search" - ], - "summary": "Searches collections based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit the number of results", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset for pagination", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "List of collections", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Collection" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/song/{hash}": { - "get": { - "description": "Retrieves a song using its unique hash identifier.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a song by its hash", - "parameters": [ - { - "type": "string", - "description": "Song hash", - "name": "hash", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/main.Song" - } - }, - "400": { - "description": "Invalid parameter", - "schema": { - "type": "string" - } - }, - "404": { - "description": "Song not found", - "schema": { - "type": "string" - } - } - } - } - }, - "/songs/artist": { - "get": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Returns all the Songs of a specific Artist", - "parameters": [ - { - "type": "string", - "description": "Artist Name", - "name": "artist", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/songs/favorites": { - "get": { - "description": "Retrieves favorite songs filtered by a query with pagination support.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a list of favorite songs based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "400": { - "description": "Invalid parameter", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "type": "string" - } - } - } - } - }, - "/songs/recents": { - "get": { - "description": "Retrieves recent songs with pagination support.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a list of recent songs", - "parameters": [ - { - "type": "integer", - "default": 10, - "description": "Limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "500": { - "description": "Internal server error", - "schema": { - "type": "string" - } - } - } - } - } - }, - "definitions": { - "main.ActiveSearch": { - "description": "ActiveSearch holds search results for a given artist", - "type": "object", - "properties": { - "artist": { - "type": "string", - "example": "Ed Sheeran" - }, - "songs": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - } - }, - "main.Artist": { - "description": "Artist holds search results for a given artist", - "type": "object", - "properties": { - "artist": { - "type": "string", - "example": "Miku" - }, - "count": { - "type": "integer", - "example": 21 - } - } - }, - "main.Collection": { - "description": "Collection holds a list of songs", - "type": "object", - "properties": { - "items": { - "type": "integer", - "example": 15 - }, - "name": { - "type": "string", - "example": "Best of 2023" - }, - "songs": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - } - }, - "main.Song": { - "description": "Song represents a song with metadata", - "type": "object", - "properties": { - "artist": { - "type": "string", - "example": "Ed Sheeran" - }, - "audio": { - "type": "string", - "example": "audio.mp3" - }, - "beatmap_id": { - "type": "integer", - "example": 123456 - }, - "creator": { - "type": "string", - "example": "JohnDoe" - }, - "file": { - "type": "string", - "example": "beatmap.osu" - }, - "folder": { - "type": "string", - "example": "osu/Songs/123456" - }, - "image": { - "type": "string", - "example": "cover.jpg" - }, - "md5_hash": { - "type": "string", - "example": "abcd1234efgh5678" - }, - "title": { - "type": "string", - "example": "Shape of You" - }, - "total_time": { - "type": "integer", - "example": 240 - } - } - } - } -}` - -// SwaggerInfo holds exported Swagger Info so clients can modify it -var SwaggerInfo = &swag.Spec{ - Version: "1.0", - Host: "", - BasePath: "api/v1/", - Schemes: []string{}, - Title: "go-osu-music-hoster", - Description: "Server Hosting ur own osu files over a simple Api", - InfoInstanceName: "swagger", - SwaggerTemplate: docTemplate, - LeftDelim: "{{", - RightDelim: "}}", -} - -func init() { - swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) -} diff --git a/go-backend/docs/swagger.json b/go-backend/docs/swagger.json deleted file mode 100644 index 0421b35..0000000 --- a/go-backend/docs/swagger.json +++ /dev/null @@ -1,661 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "description": "Server Hosting ur own osu files over a simple Api", - "title": "go-osu-music-hoster", - "contact": {}, - "version": "1.0" - }, - "host": "/", - "basePath": "/api/v1/", - "paths": { - "/audio/{filepath}": { - "get": { - "description": "Retrieves a song file from the server based on the provided encoded filepath", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "files" - ], - "summary": "Retrieves a song file by its encoded path", - "parameters": [ - { - "type": "string", - "description": "Base64 encoded file path", - "name": "filepath", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "The requested song file", - "schema": { - "type": "file" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "404": { - "description": "File Not Found", - "schema": { - "type": "string" - } - } - } - } - }, - "/collection": { - "get": { - "description": "Retrieves a collection of songs using the provided index.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a collection of songs by index", - "parameters": [ - { - "type": "integer", - "description": "Index", - "name": "index", - "in": "query" - }, - { - "type": "string", - "description": "Index", - "name": "name", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "400": { - "description": "Invalid parameter", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "type": "string" - } - } - } - } - }, - "/image/{filepath}": { - "get": { - "description": "Retrieves an image file from the server based on the provided encoded filepath", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "files" - ], - "summary": "Retrieves an image file by its encoded path", - "parameters": [ - { - "type": "string", - "description": "Base64 encoded file path", - "name": "filepath", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "The requested image file", - "schema": { - "type": "file" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "404": { - "description": "File Not Found", - "schema": { - "type": "string" - } - } - } - } - }, - "/login": { - "get": { - "description": "Redirects users to an external authentication page", - "tags": [ - "auth" - ], - "summary": "Redirect to login page", - "responses": { - "307": { - "description": "Temporary Redirect", - "schema": { - "type": "string" - } - } - } - } - }, - "/ping": { - "get": { - "description": "Returns a pong response if the server is running", - "tags": [ - "health" - ], - "summary": "Check server health", - "responses": { - "200": { - "description": "pong", - "schema": { - "type": "string" - } - } - } - } - }, - "/search/active": { - "get": { - "description": "Searches active records in the database based on the query parameter", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "search" - ], - "summary": "Searches active records based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit the number of results", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset for pagination", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Active search result", - "schema": { - "$ref": "#/definitions/main.ActiveSearch" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/search/artist": { - "get": { - "description": "Searches for artists in the database based on the query parameter", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "search" - ], - "summary": "Searches for artists based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit the number of results", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset for pagination", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "List of artists", - "schema": { - "$ref": "#/definitions/main.Artist" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/search/collections": { - "get": { - "description": "Searches collections in the database based on the query parameter", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "search" - ], - "summary": "Searches collections based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit the number of results", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset for pagination", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "List of collections", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Collection" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/song/{hash}": { - "get": { - "description": "Retrieves a song using its unique hash identifier.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a song by its hash", - "parameters": [ - { - "type": "string", - "description": "Song hash", - "name": "hash", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/main.Song" - } - }, - "400": { - "description": "Invalid parameter", - "schema": { - "type": "string" - } - }, - "404": { - "description": "Song not found", - "schema": { - "type": "string" - } - } - } - } - }, - "/songs/artist": { - "get": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Returns all the Songs of a specific Artist", - "parameters": [ - { - "type": "string", - "description": "Artist Name", - "name": "artist", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "type": "string" - } - } - } - } - }, - "/songs/favorites": { - "get": { - "description": "Retrieves favorite songs filtered by a query with pagination support.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a list of favorite songs based on a query", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "query", - "in": "query", - "required": true - }, - { - "type": "integer", - "default": 10, - "description": "Limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "400": { - "description": "Invalid parameter", - "schema": { - "type": "string" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "type": "string" - } - } - } - } - }, - "/songs/recents": { - "get": { - "description": "Retrieves recent songs with pagination support.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "songs" - ], - "summary": "Get a list of recent songs", - "parameters": [ - { - "type": "integer", - "default": 10, - "description": "Limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "default": 0, - "description": "Offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - }, - "500": { - "description": "Internal server error", - "schema": { - "type": "string" - } - } - } - } - } - }, - "definitions": { - "main.ActiveSearch": { - "description": "ActiveSearch holds search results for a given artist", - "type": "object", - "properties": { - "artist": { - "type": "string", - "example": "Ed Sheeran" - }, - "songs": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - } - }, - "main.Artist": { - "description": "Artist holds search results for a given artist", - "type": "object", - "properties": { - "artist": { - "type": "string", - "example": "Miku" - }, - "count": { - "type": "integer", - "example": 21 - } - } - }, - "main.Collection": { - "description": "Collection holds a list of songs", - "type": "object", - "properties": { - "items": { - "type": "integer", - "example": 15 - }, - "name": { - "type": "string", - "example": "Best of 2023" - }, - "songs": { - "type": "array", - "items": { - "$ref": "#/definitions/main.Song" - } - } - } - }, - "main.Song": { - "description": "Song represents a song with metadata", - "type": "object", - "properties": { - "artist": { - "type": "string", - "example": "Ed Sheeran" - }, - "audio": { - "type": "string", - "example": "audio.mp3" - }, - "beatmap_id": { - "type": "integer", - "example": 123456 - }, - "creator": { - "type": "string", - "example": "JohnDoe" - }, - "file": { - "type": "string", - "example": "beatmap.osu" - }, - "folder": { - "type": "string", - "example": "osu/Songs/123456" - }, - "image": { - "type": "string", - "example": "cover.jpg" - }, - "md5_hash": { - "type": "string", - "example": "abcd1234efgh5678" - }, - "title": { - "type": "string", - "example": "Shape of You" - }, - "total_time": { - "type": "integer", - "example": 240 - } - } - } - } -} \ No newline at end of file diff --git a/go-backend/docs/swagger.yaml b/go-backend/docs/swagger.yaml deleted file mode 100644 index f3bb86c..0000000 --- a/go-backend/docs/swagger.yaml +++ /dev/null @@ -1,446 +0,0 @@ -basePath: /api/v1/ -definitions: - main.ActiveSearch: - description: ActiveSearch holds search results for a given artist - properties: - artist: - example: Ed Sheeran - type: string - songs: - items: - $ref: '#/definitions/main.Song' - type: array - type: object - main.Artist: - description: Artist holds search results for a given artist - properties: - artist: - example: Miku - type: string - count: - example: 21 - type: integer - type: object - main.Collection: - description: Collection holds a list of songs - properties: - items: - example: 15 - type: integer - name: - example: Best of 2023 - type: string - songs: - items: - $ref: '#/definitions/main.Song' - type: array - type: object - main.Song: - description: Song represents a song with metadata - properties: - artist: - example: Ed Sheeran - type: string - audio: - example: audio.mp3 - type: string - beatmap_id: - example: 123456 - type: integer - creator: - example: JohnDoe - type: string - file: - example: beatmap.osu - type: string - folder: - example: osu/Songs/123456 - type: string - image: - example: cover.jpg - type: string - md5_hash: - example: abcd1234efgh5678 - type: string - title: - example: Shape of You - type: string - total_time: - example: 240 - type: integer - type: object -host: / -info: - contact: {} - description: Server Hosting ur own osu files over a simple Api - title: go-osu-music-hoster - version: "1.0" -paths: - /audio/{filepath}: - get: - consumes: - - application/json - description: Retrieves a song file from the server based on the provided encoded - filepath - parameters: - - description: Base64 encoded file path - in: path - name: filepath - required: true - type: string - produces: - - application/json - responses: - "200": - description: The requested song file - schema: - type: file - "400": - description: Bad Request - schema: - type: string - "404": - description: File Not Found - schema: - type: string - summary: Retrieves a song file by its encoded path - tags: - - files - /collection: - get: - consumes: - - application/json - description: Retrieves a collection of songs using the provided index. - parameters: - - description: Index - in: query - name: index - type: integer - - description: Index - in: query - name: name - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/main.Song' - type: array - "400": - description: Invalid parameter - schema: - type: string - "500": - description: Internal server error - schema: - type: string - summary: Get a collection of songs by index - tags: - - songs - /image/{filepath}: - get: - consumes: - - application/json - description: Retrieves an image file from the server based on the provided encoded - filepath - parameters: - - description: Base64 encoded file path - in: path - name: filepath - required: true - type: string - produces: - - application/json - responses: - "200": - description: The requested image file - schema: - type: file - "400": - description: Bad Request - schema: - type: string - "404": - description: File Not Found - schema: - type: string - summary: Retrieves an image file by its encoded path - tags: - - files - /login: - get: - description: Redirects users to an external authentication page - responses: - "307": - description: Temporary Redirect - schema: - type: string - summary: Redirect to login page - tags: - - auth - /ping: - get: - description: Returns a pong response if the server is running - responses: - "200": - description: pong - schema: - type: string - summary: Check server health - tags: - - health - /search/active: - get: - consumes: - - application/json - description: Searches active records in the database based on the query parameter - parameters: - - description: Search query - in: query - name: query - required: true - type: string - - default: 10 - description: Limit the number of results - in: query - name: limit - type: integer - - default: 0 - description: Offset for pagination - in: query - name: offset - type: integer - produces: - - application/json - responses: - "200": - description: Active search result - schema: - $ref: '#/definitions/main.ActiveSearch' - "400": - description: Bad Request - schema: - type: string - "500": - description: Internal Server Error - schema: - type: string - summary: Searches active records based on a query - tags: - - search - /search/artist: - get: - consumes: - - application/json - description: Searches for artists in the database based on the query parameter - parameters: - - description: Search query - in: query - name: query - required: true - type: string - - default: 10 - description: Limit the number of results - in: query - name: limit - type: integer - - default: 0 - description: Offset for pagination - in: query - name: offset - type: integer - produces: - - application/json - responses: - "200": - description: List of artists - schema: - $ref: '#/definitions/main.Artist' - "400": - description: Bad Request - schema: - type: string - "500": - description: Internal Server Error - schema: - type: string - summary: Searches for artists based on a query - tags: - - search - /search/collections: - get: - consumes: - - application/json - description: Searches collections in the database based on the query parameter - parameters: - - description: Search query - in: query - name: query - required: true - type: string - - default: 10 - description: Limit the number of results - in: query - name: limit - type: integer - - default: 0 - description: Offset for pagination - in: query - name: offset - type: integer - produces: - - application/json - responses: - "200": - description: List of collections - schema: - items: - $ref: '#/definitions/main.Collection' - type: array - "400": - description: Bad Request - schema: - type: string - "500": - description: Internal Server Error - schema: - type: string - summary: Searches collections based on a query - tags: - - search - /song/{hash}: - get: - consumes: - - application/json - description: Retrieves a song using its unique hash identifier. - parameters: - - description: Song hash - in: path - name: hash - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/main.Song' - "400": - description: Invalid parameter - schema: - type: string - "404": - description: Song not found - schema: - type: string - summary: Get a song by its hash - tags: - - songs - /songs/artist: - get: - consumes: - - application/json - parameters: - - description: Artist Name - in: query - name: artist - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/main.Song' - type: array - "400": - description: Bad Request - schema: - type: string - "500": - description: Internal Server Error - schema: - type: string - summary: Returns all the Songs of a specific Artist - tags: - - songs - /songs/favorites: - get: - consumes: - - application/json - description: Retrieves favorite songs filtered by a query with pagination support. - parameters: - - description: Search query - in: query - name: query - required: true - type: string - - default: 10 - description: Limit - in: query - name: limit - type: integer - - default: 0 - description: Offset - in: query - name: offset - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/main.Song' - type: array - "400": - description: Invalid parameter - schema: - type: string - "500": - description: Internal server error - schema: - type: string - summary: Get a list of favorite songs based on a query - tags: - - songs - /songs/recents: - get: - consumes: - - application/json - description: Retrieves recent songs with pagination support. - parameters: - - default: 10 - description: Limit - in: query - name: limit - type: integer - - default: 0 - description: Offset - in: query - name: offset - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/main.Song' - type: array - "500": - description: Internal server error - schema: - type: string - summary: Get a list of recent songs - tags: - - songs -swagger: "2.0" diff --git a/go-backend/go.mod b/go-backend/go.mod deleted file mode 100644 index 9495f0a..0000000 --- a/go-backend/go.mod +++ /dev/null @@ -1,34 +0,0 @@ -module backend - -go 1.24.3 - -require ( - github.com/joho/godotenv v1.5.1 - github.com/juli0n21/go-osu-parser v0.0.8 - github.com/swaggo/http-swagger v1.3.4 - github.com/swaggo/swag v1.16.4 - modernc.org/sqlite v1.34.5 -) - -require ( - github.com/KyleBanks/depth v1.2.1 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/swaggo/files v1.0.1 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/tools v0.29.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.55.3 // indirect - modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.8.0 // indirect -) diff --git a/go-backend/go.sum b/go-backend/go.sum deleted file mode 100644 index 9e4b7e3..0000000 --- a/go-backend/go.sum +++ /dev/null @@ -1,115 +0,0 @@ -github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= -github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/juli0n21/go-osu-parser v0.0.8 h1:aQtuhAniGvpUw446arhq/3aUOK9YvZEkL7aYUGlViAo= -github.com/juli0n21/go-osu-parser v0.0.8/go.mod h1:oLLWnZReOMW4i5aNva/zvXsFqzdQigrbjyxOSs0cx+0= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= -github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -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/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= -github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= -github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww= -github.com/swaggo/http-swagger v1.3.4/go.mod h1:9dAh0unqMBAlbp1uE2Uc2mQTxNMU/ha4UbucIg1MFkQ= -github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A= -github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= -golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= -modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= -modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= -modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= -modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= -modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= -modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= -modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= -modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.34.5 h1:Bb6SR13/fjp15jt70CL4f18JIN7p7dnMExd+UFnF15g= -modernc.org/sqlite v1.34.5/go.mod h1:YLuNmX9NKs8wRNK2ko1LW1NGYcc9FkBO69JOt1AR9JE= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/go-backend/handlers.go b/go-backend/handlers.go deleted file mode 100644 index 795261e..0000000 --- a/go-backend/handlers.go +++ /dev/null @@ -1,443 +0,0 @@ -package main - -import ( - "database/sql" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "log" - "net/http" - "os" - "strconv" - - _ "backend/docs" - - "github.com/joho/godotenv" - httpSwagger "github.com/swaggo/http-swagger" - - "github.com/juli0n21/go-osu-parser/parser" -) - -var ErrRequiredParameterNotPresent = errors.New("required parameter missing") -var ErrFailedToParseEncoded = errors.New("invalid encoded value") -var ErrFileNotFound = errors.New("file not found") - -type Server struct { - Port string - OsuDir string - Db *sql.DB - OsuDb *parser.OsuDB - Env map[string]string -} - -func (s *Server) registerRoutes() http.Handler { - mux := http.NewServeMux() - - mux.HandleFunc("/api/v1/ping", s.ping) - mux.HandleFunc("/api/v1/login", s.login) - - mux.HandleFunc("/api/v1/song/{hash}/", s.song) - mux.HandleFunc("/api/v1/songs/recent", s.recents) - mux.HandleFunc("/api/v1/songs/favorites", s.favorites) - mux.HandleFunc("/api/v1/songs/artist", s.aristsSongs) - - mux.HandleFunc("/api/v1/collection", s.collection) - mux.HandleFunc("/api/v1/search/collections", s.collectionSearch) - - mux.HandleFunc("/api/v1/search/active", s.activeSearch) - mux.HandleFunc("/api/v1/search/artist", s.artistSearch) - - mux.HandleFunc("/api/v1/audio/{filepath}", s.songFile) - mux.HandleFunc("/api/v1/image/{filepath}", s.imageFile) - - mux.HandleFunc("/api/v1/callback", s.callback) - mux.Handle("/swagger/", httpSwagger.WrapHandler) - - return corsMiddleware(logRequests(mux)) -} - -func run(s *Server) { - mux := s.registerRoutes() - fmt.Println("starting server on http://localhost" + s.Port) - log.Fatal(http.ListenAndServe(s.Port, mux)) -} - -func logRequests(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL.Path) - next.ServeHTTP(w, r) - }) -} - -func corsMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") - w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") - - if r.Method == http.MethodOptions { - w.WriteHeader(http.StatusNoContent) - return - } - - next.ServeHTTP(w, r) - }) -} - -// ping godoc -// -// @Summary Check server health -// @Description Returns a pong response if the server is running -// @Tags health -// @Success 200 {string} string "pong" -// @Router /ping [get] -func (s *Server) ping(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "pong") -} - -// login godoc -// -// @Summary Redirect to login page -// @Description Redirects users to an external authentication page -// @Tags auth -// @Success 307 {string} string "Temporary Redirect" -// @Router /login [get] -func (s *Server) login(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "https://proxy.illegalesachen.download/login", http.StatusTemporaryRedirect) -} - -// song godoc -// -// @Summary Get a song by its hash -// @Description Retrieves a song using its unique hash identifier. -// @Tags songs -// @Accept json -// @Produce json -// @Param hash path string true "Song hash" -// @Success 200 {object} Song -// @Failure 400 {string} string "Invalid parameter" -// @Failure 404 {string} string "Song not found" -// @Router /song/{hash} [get] -func (s *Server) song(w http.ResponseWriter, r *http.Request) { - - hash := r.PathValue("hash") - if hash == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - song, err := getSong(s.Db, hash) - if err != nil { - fmt.Println(err) - http.Error(w, "beatmap not found by hash", http.StatusNotFound) - return - } - - writeJSON(w, song, http.StatusOK) -} - -// recents godoc -// -// @Summary Get a list of recent songs -// @Description Retrieves recent songs with pagination support. -// @Tags songs -// @Accept json -// @Produce json -// @Param limit query int false "Limit" default(10) -// @Param offset query int false "Offset" default(0) -// @Success 200 {array} Song -// @Failure 500 {string} string "Internal server error" -// @Router /songs/recents [get] -func (s *Server) recents(w http.ResponseWriter, r *http.Request) { - - limit, offset := pagination(r) - recent, err := getRecent(s.Db, limit, offset) - if err != nil { - fmt.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - writeJSON(w, recent, http.StatusOK) -} - -// favorites godoc -// -// @Summary Get a list of favorite songs based on a query -// @Description Retrieves favorite songs filtered by a query with pagination support. -// @Tags songs -// @Accept json -// @Produce json -// @Param query query string true "Search query" -// @Param limit query int false "Limit" default(10) -// @Param offset query int false "Offset" default(0) -// @Success 200 {array} Song -// @Failure 400 {string} string "Invalid parameter" -// @Failure 500 {string} string "Internal server error" -// @Router /songs/favorites [get] -func (s *Server) favorites(w http.ResponseWriter, r *http.Request) { - query := r.URL.Query().Get("query") - if query == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - limit, offset := pagination(r) - - favorites, err := getFavorites(s.Db, query, limit, offset) - if err != nil { - fmt.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - writeJSON(w, favorites, http.StatusOK) -} - -// collection godoc -// -// @Summary Get a collection of songs by index -// @Description Retrieves a collection of songs using the provided index. -// @Tags songs -// @Accept json -// @Produce json -// @Param index query int false "Index" -// @Param name query string false "Index" -// @Success 200 {array} Song -// @Failure 400 {string} string "Invalid parameter" -// @Failure 500 {string} string "Internal server error" -// @Router /collection [get] -func (s *Server) collection(w http.ResponseWriter, r *http.Request) { - limit, offset := pagination(r) - name := r.URL.Query().Get("name") - if name != "" { - c, err := getCollectionByName(s.Db, limit, offset, name) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - writeJSON(w, c, http.StatusOK) - return - } - - index, err := strconv.Atoi(r.URL.Query().Get("index")) - if err != nil { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } else { - c, err := getCollection(s.Db, limit, offset, index) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - writeJSON(w, c, http.StatusOK) - return - } - -} - -// @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") - - limit, offset := pagination(r) - - preview, err := getCollections(s.Db, q, limit, offset) - if err != nil { - fmt.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - 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] -func (s *Server) aristsSongs(w http.ResponseWriter, r *http.Request) { - artist := r.URL.Query().Get("artist") - if artist == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - 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] -func (s *Server) activeSearch(w http.ResponseWriter, r *http.Request) { - q := r.URL.Query().Get("query") - if q == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - //TODO - limit, offset := pagination(r) - - recent, err := getSearch(s.Db, q, limit, offset) - if err != nil { - fmt.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - 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] -func (s *Server) artistSearch(w http.ResponseWriter, r *http.Request) { - q := r.URL.Query().Get("query") - if q == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - //TODO - limit, offset := pagination(r) - - a, err := getArtists(s.Db, q, limit, offset) - if err != nil { - fmt.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - 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] -func (s *Server) songFile(w http.ResponseWriter, r *http.Request) { - f := r.PathValue("filepath") - if f == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - filename, err := base64.RawStdEncoding.DecodeString(f) - if err != nil { - fmt.Println(err) - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - file, err := os.Open(s.OsuDir + "Songs/" + string(filename)) - if err != nil { - fmt.Println(err) - http.Error(w, ErrFileNotFound.Error(), http.StatusNotFound) - return - } - defer file.Close() - - stat, err := file.Stat() - if err != nil { - fmt.Println(err) - http.Error(w, ErrFileNotFound.Error(), http.StatusNotFound) - return - } - - 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] -func (s *Server) imageFile(w http.ResponseWriter, r *http.Request) { - f := r.PathValue("filepath") - if f == "" { - http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest) - return - } - - filename, err := base64.RawStdEncoding.DecodeString(f) - if err != nil { - fmt.Println(err) - http.Error(w, ErrFailedToParseEncoded.Error(), http.StatusBadRequest) - return - } - - 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) - if err := json.NewEncoder(w).Encode(v); err != nil { - fmt.Println(err) - http.Error(w, "Failed to encode JSON response", http.StatusInternalServerError) - } -} - -func pagination(r *http.Request) (int, int) { - limit, err := strconv.Atoi(r.URL.Query().Get("limit")) - if err != nil || limit <= 0 || limit > 100 { - limit = 100 - } - offset, err := strconv.Atoi(r.URL.Query().Get("offset")) - if err != nil || offset < 0 { - offset = 0 - } - - return limit, offset -} diff --git a/go-backend/main.go b/go-backend/main.go deleted file mode 100644 index a5f329c..0000000 --- a/go-backend/main.go +++ /dev/null @@ -1,163 +0,0 @@ -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" -) - -// @title go-osu-music-hoster -// @version 1.0 -// @description Server Hosting ur own osu files over a simple Api - -// @host / -// @BasePath /api/v1/ -func main() { - 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: 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 := GetEnv("PROXY_URL", "https://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("failed to create request: %v", err) - } - req.Header.Add("Content-Type", "application/json") - - req.AddCookie(&http.Cookie{ - Name: "session_cookie", - Value: cookie, - }) - - 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) - } - return nil -} diff --git a/go-backend/models.go b/go-backend/models.go deleted file mode 100644 index 41fb4a9..0000000 --- a/go-backend/models.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -// Song represents a song entity -// @Description Song represents a song with metadata -type Song struct { - BeatmapID int `json:"beatmap_id" example:"123456"` - MD5Hash string `json:"md5_hash" example:"abcd1234efgh5678"` - Title string `json:"title" example:"Shape of You"` - Artist string `json:"artist" example:"Ed Sheeran"` - Creator string `json:"creator" example:"JohnDoe"` - Folder string `json:"folder" example:"osu/Songs/123456"` - File string `json:"file" example:"beatmap.osu"` - Audio string `json:"audio" example:"audio.mp3"` - TotalTime int64 `json:"total_time" example:"240"` - Image string `json:"image" example:"cover.jpg"` -} - -// CollectionPreview represents a preview of a song collection -// @Description CollectionPreview contains summary data of a song collection -type CollectionPreview struct { - Name string `json:"name" example:"Collection Name"` - Image string `json:"image" example:"cover.jpg"` - Items int `json:"items" example:"10"` -} - -// Collection represents a full song collection -// @Description Collection holds a list of songs -type Collection struct { - Name string `json:"name" example:"Best of 2023"` - Items int `json:"items" example:"15"` - Songs []Song `json:"songs"` -} - -// ActiveSearch represents an active song search query -// @Description ActiveSearch holds search results for a given artist -type ActiveSearch struct { - Artist string `json:"artist" example:"Ed Sheeran"` - Songs []Song `json:"songs"` -} - -// Artist represents an active song search query -// @Description Artist holds search results for a given artist -type Artist struct { - Artist string `json:"artist" example:"Miku"` - Count int `json:"count" example:"21"` -}