diff --git a/build.zig.zon b/build.zig.zon index 9b7f253..e541ab2 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -16,8 +16,8 @@ // internet connectivity. .dependencies = .{ .jetzig = .{ - .url = "https://github.com/jetzig-framework/jetzig/archive/dda433bb73000614482af10a277d47dc9d89600c.tar.gz", - .hash = "12202ce84b803a8b300c91d98afbc7c326298b55a23bf05cf603182e934b621008ec", + .url = "https://github.com/jetzig-framework/jetzig/archive/d887cd5bd88eef611fc145e8acb12eee05b9aeef.tar.gz", + .hash = "12204458ae2b5cb93339296d7ac0f90fc0a0292711fcd82156b6595131fc0a96c648", }, }, .paths = .{ diff --git a/config/database.zig b/config/database.zig new file mode 100644 index 0000000..56b00ec --- /dev/null +++ b/config/database.zig @@ -0,0 +1,28 @@ +pub const database = .{ + .testing = .{ + .adapter = .postgresql, + .hostname = "localhost", + .port = 5432, + .username = "postgres", + .password = "postgres", + .database = "zuletzt_testing", + }, + + .development = .{ + .adapter = .postgresql, + .hostname = "localhost", + .port = 5432, + .username = "postgres", + .password = "postgres", + .database = "zuletzt_dev", + }, + + .production = .{ + .adapter = .postgresql, + .hostname = "localhost", + .port = 5432, + .username = "postgres", + .password = "postgres", + .database = "zuletzt", + }, +}; diff --git a/src/app/database/Schema.zig b/src/app/database/Schema.zig new file mode 100644 index 0000000..7e30fee --- /dev/null +++ b/src/app/database/Schema.zig @@ -0,0 +1,130 @@ +const jetquery = @import("jetzig").jetquery; + +pub const AlbumSong = jetquery.Model( + @This(), + "album_songs", + struct { + id: i32, + album_id: i32, + song_id: i32, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{}, +); + +pub const Album = jetquery.Model( + @This(), + "albums", + struct { + id: i32, + title: []const u8, + song_num: i32, + length: f64, + play_count: i32, + score: f64, + avg_song_score: f64, + url: []const u8, + holiday: bool, + compilation: bool, + collaboration: bool, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{ + .relations = .{ + .scrobbles = jetquery.hasMany(.Scrobble, .{}), + }, + }, +); + +pub const ArtistAlbum = jetquery.Model( + @This(), + "artist_albums", + struct { + id: i32, + artist_id: i32, + album_id: i32, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{}, +); + +pub const ArtistSong = jetquery.Model( + @This(), + "artist_songs", + struct { + id: i32, + artist_id: i32, + song_id: i32, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{}, +); + +pub const Artist = jetquery.Model( + @This(), + "artists", + struct { + id: i32, + name: []const u8, + album_num: i32, + song_num: i32, + play_count: i32, + avg_album_score: f64, + avg_song_score: f64, + url: []const u8, + aliased: bool, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{ + .relations = .{ + .scrobbles = jetquery.hasMany(.Scrobble, .{}), + }, + }, +); + +pub const Scrobble = jetquery.Model( + @This(), + "scrobbles", + struct { + id: i32, + date: jetquery.DateTime, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{ + .relations = .{ + .song = jetquery.belongsTo(.Song, .{}), + .album = jetquery.belongsTo(.Album, .{}), + .artist = jetquery.belongsTo(.Artist, .{}), + }, + }, +); + +pub const Song = jetquery.Model( + @This(), + "songs", + struct { + id: i32, + name: []const u8, + play_count: i32, + length: f64, + score: f64, + url: []const u8, + aliased: bool, + track_num: i32, + hidden: bool, + holiday: bool, + created_at: jetquery.DateTime, + updated_at: jetquery.DateTime, + }, + .{ + .relations = .{ + .scrobbles = jetquery.hasMany(.Scrobble, .{}), + }, + }, +); diff --git a/src/app/database/data.db b/src/app/database/data.db deleted file mode 100644 index fa37ab7..0000000 Binary files a/src/app/database/data.db and /dev/null differ diff --git a/src/app/database/migrations/2024-11-15_14-46-12_create_artists.zig b/src/app/database/migrations/2024-11-15_14-46-12_create_artists.zig new file mode 100644 index 0000000..224877b --- /dev/null +++ b/src/app/database/migrations/2024-11-15_14-46-12_create_artists.zig @@ -0,0 +1,26 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "artists", + &.{ + t.primaryKey("id", .{}), + t.column("name", .string, .{}), + t.column("album_num", .integer, .{}), + t.column("song_num", .integer, .{}), + t.column("play_count", .integer, .{}), + t.column("avg_album_score", .float, .{}), + t.column("avg_song_score", .float, .{}), + t.column("url", .string, .{}), + t.column("aliased", .boolean, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("artists", .{}); +} diff --git a/src/app/database/migrations/2024-11-15_14-58-47_create_songs.zig b/src/app/database/migrations/2024-11-15_14-58-47_create_songs.zig new file mode 100644 index 0000000..4852b4d --- /dev/null +++ b/src/app/database/migrations/2024-11-15_14-58-47_create_songs.zig @@ -0,0 +1,27 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "songs", + &.{ + t.primaryKey("id", .{}), + t.column("name", .string, .{}), + t.column("play_count", .integer, .{}), + t.column("length", .float, .{}), + t.column("score", .float, .{}), + t.column("url", .string, .{}), + t.column("aliased", .boolean, .{}), + t.column("track_num", .integer, .{}), + t.column("hidden", .boolean, .{}), + t.column("holiday", .boolean, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("songs", .{}); +} diff --git a/src/app/database/migrations/2024-11-15_17-52-04_create_artist_songs.zig b/src/app/database/migrations/2024-11-15_17-52-04_create_artist_songs.zig new file mode 100644 index 0000000..03f6ec4 --- /dev/null +++ b/src/app/database/migrations/2024-11-15_17-52-04_create_artist_songs.zig @@ -0,0 +1,20 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "artist_songs", + &.{ + t.primaryKey("id", .{}), + t.column("artist_id", .integer, .{}), + t.column("song_id", .integer, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("artist_songs", .{}); +} diff --git a/src/app/database/migrations/2024-11-15_17-52-28_create_artist_albums.zig b/src/app/database/migrations/2024-11-15_17-52-28_create_artist_albums.zig new file mode 100644 index 0000000..3e186ad --- /dev/null +++ b/src/app/database/migrations/2024-11-15_17-52-28_create_artist_albums.zig @@ -0,0 +1,20 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "artist_albums", + &.{ + t.primaryKey("id", .{}), + t.column("artist_id", .integer, .{}), + t.column("album_id", .integer, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("artist_albums", .{}); +} diff --git a/src/app/database/migrations/2024-11-15_17-52-54_create_album_songs.zig b/src/app/database/migrations/2024-11-15_17-52-54_create_album_songs.zig new file mode 100644 index 0000000..9462f82 --- /dev/null +++ b/src/app/database/migrations/2024-11-15_17-52-54_create_album_songs.zig @@ -0,0 +1,20 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "album_songs", + &.{ + t.primaryKey("id", .{}), + t.column("album_id", .integer, .{}), + t.column("song_id", .integer, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("album_songs", .{}); +} diff --git a/src/app/database/migrations/2024-11-20_00-19-54_create_scrobble.zig b/src/app/database/migrations/2024-11-20_00-19-54_create_scrobble.zig new file mode 100644 index 0000000..c067423 --- /dev/null +++ b/src/app/database/migrations/2024-11-20_00-19-54_create_scrobble.zig @@ -0,0 +1,19 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "scrobbles", + &.{ + t.primaryKey("id", .{}), + t.column("date", .datetime, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("scrobbles", .{}); +} diff --git a/src/app/database/migrations/2024-11-20_19-08-02_create_albums.zig b/src/app/database/migrations/2024-11-20_19-08-02_create_albums.zig new file mode 100644 index 0000000..292793e --- /dev/null +++ b/src/app/database/migrations/2024-11-20_19-08-02_create_albums.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const jetquery = @import("jetquery"); +const t = jetquery.schema.table; + +pub fn up(repo: anytype) !void { + try repo.createTable( + "albums", + &.{ + t.primaryKey("id", .{}), + t.column("title", .string, .{}), + t.column("song_num", .integer, .{}), + t.column("length", .float, .{}), + t.column("play_count", .integer, .{}), + t.column("score", .float, .{}), + t.column("avg_song_score", .float, .{}), + t.column("url", .string, .{}), + t.column("holiday", .boolean, .{}), + t.column("compilation", .boolean, .{}), + t.column("collaboration", .boolean, .{}), + t.timestamps(.{}), + }, + .{}, + ); +} + +pub fn down(repo: anytype) !void { + try repo.dropTable("albums", .{}); +} diff --git a/src/app/lib/db.zig b/src/app/lib/db.zig deleted file mode 100644 index dd6f7bf..0000000 --- a/src/app/lib/db.zig +++ /dev/null @@ -1,22 +0,0 @@ -pub const addArtist = \\INSERT INTO artists ('artist', 'plays', 'url') VALUES (?,?) -; - -pub const addTrack = \\INSERT INTO tracks ('artist', 'track', 'album', 'plays', 'url') VALUES (?,?,?,?) -; - -pub const getArtist = \\SELECT artist, plays FROM artists WHERE artist == ? -; - -pub const getTrack = \\SELECT artist, track, album, plays FROM tracks WHERE track == ? -; - -pub const getTrackSearch = \\SELECT track, url, form FROM tracks WHERE track LIKE '%' || ? || '%' -; - -pub const getArtistSearch = \\SELECT artist, url, form FROM artists WHERE artist LIKE '%' || ? || '%' -; - -pub const getAlbumSearch = \\SELECT album, url, form FROM albums WHERE album LIKE '%' || ? || '%' -; - -pub const total_search = getArtistSearch ++ " UNION " ++ getAlbumSearch ++ " UNION " ++ getTrackSearch; \ No newline at end of file diff --git a/src/app/views/root/_graph.zmpl b/src/app/middleware/lastfmMiddleware.zig similarity index 100% rename from src/app/views/root/_graph.zmpl rename to src/app/middleware/lastfmMiddleware.zig diff --git a/src/app/views/root/_history.zmpl b/src/app/middleware/spotifyMiddleware.zig similarity index 100% rename from src/app/views/root/_history.zmpl rename to src/app/middleware/spotifyMiddleware.zig diff --git a/src/app/views/collection.zig b/src/app/views/collection.zig new file mode 100644 index 0000000..8125efd --- /dev/null +++ b/src/app/views/collection.zig @@ -0,0 +1,36 @@ +const std = @import("std"); +const jetzig = @import("jetzig"); + +pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + return request.render(.ok); +} + +pub fn get(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + _ = id; + return request.render(.ok); +} + +pub fn post(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + return request.render(.created); +} + +pub fn put(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + _ = id; + return request.render(.ok); +} + +pub fn patch(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + _ = id; + return request.render(.ok); +} + +pub fn delete(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + _ = id; + return request.render(.ok); +} diff --git a/src/app/views/stats/index.zmpl b/src/app/views/collection/delete.zmpl similarity index 100% rename from src/app/views/stats/index.zmpl rename to src/app/views/collection/delete.zmpl diff --git a/src/app/views/collection/get.zmpl b/src/app/views/collection/get.zmpl new file mode 100644 index 0000000..76457d0 --- /dev/null +++ b/src/app/views/collection/get.zmpl @@ -0,0 +1,3 @@ +