From 365b9dbf11345af987960b92d58148769ccdbe43 Mon Sep 17 00:00:00 2001 From: mitteneer Date: Tue, 13 May 2025 14:24:14 -0400 Subject: [PATCH] Switch to using newtable partial for all tables Will be renamed eventually, don't care right now. Also cleans up a lot of code I wasn't particularly happy about --- build.zig.zon | 4 +-- src/app/views/albums.zig | 42 ++++++++++++++------------- src/app/views/artists.zig | 25 ++++++++++++---- src/app/views/artists/index.zmpl | 31 ++++---------------- src/app/views/partials/_newtable.zmpl | 28 ++++++++++-------- src/app/views/scrobbles.zig | 41 +++++++++++++------------- src/app/views/scrobbles/index.zmpl | 39 ++++--------------------- src/app/views/songs.zig | 32 ++++++++++---------- src/app/views/songs/index.zmpl | 37 ++++------------------- src/types.zig | 15 ++++++++++ 10 files changed, 128 insertions(+), 166 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index f2e5778..d7fb785 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -17,8 +17,8 @@ // internet connectivity. .dependencies = .{ .jetzig = .{ - .url = "https://github.com/jetzig-framework/jetzig/archive/a298192bb0cddf9c45d7d0d976a9852804457de2.tar.gz", - .hash = "jetzig-0.0.0-IpAgLf5aDwB4UOKMhIjtK22zBsPfbWEwCYgHT0hayyT-", + .url = "https://github.com/jetzig-framework/jetzig/archive/7be1d137fcab5c422e05f12092f6e04a02900d6f.tar.gz", + .hash = "jetzig-0.0.0-IpAgLURbDwB1NlywUH7lnQ3zptNvSQWVosaA1k7l1cNz", }, .zeit = .{ .url = "https://github.com/rockorager/zeit/archive/refs/tags/v0.6.0.tar.gz", diff --git a/src/app/views/albums.zig b/src/app/views/albums.zig index 1264dac..95f5b86 100644 --- a/src/app/views/albums.zig +++ b/src/app/views/albums.zig @@ -1,6 +1,8 @@ const std = @import("std"); const jetzig = @import("jetzig"); const jetquery = @import("jetzig").jetquery; +const TableRow = @import("../../types.zig").TableRows; +const HyperlinkData = @import("../../types.zig").HyperlinkData; pub fn index(request: *jetzig.Request) !jetzig.View { var root = try request.data(.object); @@ -22,28 +24,26 @@ pub fn index(request: *jetzig.Request) !jetzig.View { const Album = struct { name: []const u8, id: i32, artist_name: []const u8, artist_id: i32, scrobbles: i64 }; var prev_album_id: ?i32 = null; - var prev_artist_infos: ?*jetzig.zmpl.Data.Value = null; + + var row: ?TableRow = null; + var artistlist = std.ArrayList(HyperlinkData).init(request.allocator); blk: while (try albums_jq_result.postgresql.result.next()) |album_row| { const album = try album_row.to(Album, .{ .dupe = true, .allocator = request.allocator }); if (album.id == prev_album_id) { - var artist_info = try prev_artist_infos.?.append(.object); - try artist_info.put("name", album.artist_name); - try artist_info.put("id", album.artist_id); + try artistlist.append(.{ .name = album.artist_name, .id = album.artist_id }); continue :blk; + } else { + try artistlist.append(.{ .name = album.artist_name, .id = album.artist_id }); + + row = TableRow{ + .album = .{ .name = album.name, .id = album.id }, + .artistlist = try artistlist.toOwnedSlice(), + .scrobbles = album.scrobbles, + }; + + try albums_view.append(row); } - var album_view = try albums_view.append(.object); - - try album_view.put("name", album.name); - try album_view.put("id", album.id); - try album_view.put("scrobbles", album.scrobbles); - - var artist_infos = try album_view.put("artist_info", .array); - var artist_info = try artist_infos.append(.object); - try artist_info.put("name", album.artist_name); - try artist_info.put("id", album.artist_id); - - prev_artist_infos = artist_infos; prev_album_id = album.id; } return request.render(.ok); @@ -72,10 +72,12 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View { while (try songs_js_result.postgresql.result.next()) |song_row| { const song = try song_row.to(Song, .{ .dupe = true, .allocator = request.allocator }); - var song_view = try songs_view.append(.object); - try song_view.put("name", song.name); - try song_view.put("id", song.id); - try song_view.put("scrobbles", song.scrobbles); + const row = TableRow{ + .song = .{ .name = song.name, .id = song.id }, + .scrobbles = song.scrobbles, + }; + + try songs_view.append(row); } return request.render(.ok); } diff --git a/src/app/views/artists.zig b/src/app/views/artists.zig index 34cea3e..461235a 100644 --- a/src/app/views/artists.zig +++ b/src/app/views/artists.zig @@ -1,6 +1,7 @@ const std = @import("std"); const jetzig = @import("jetzig"); const jetquery = @import("jetzig").jetquery; +const TableRow = @import("../../types.zig").TableRows; const dateFmt = @import("../../date_fmt.zig").dateFmt; const ordinalFmt = @import("../../ordinal_fmt.zig").ordinalFmt; @@ -25,10 +26,12 @@ pub fn index(request: *jetzig.Request) !jetzig.View { while (try artists_jq_result.postgresql.result.next()) |artist_row| { const artist = try artist_row.to(Artist, .{ .dupe = true, .allocator = request.allocator }); - var artist_view = try artists_view.append(.object); - try artist_view.put("name", artist.name); - try artist_view.put("url", artist.id); - try artist_view.put("scrobbles", artist.scrobbles); + const row = TableRow{ + .artist = .{ .name = artist.name, .id = artist.id }, + .scrobbles = artist.scrobbles, + }; + + try artists_view.append(row); } return request.render(.ok); @@ -84,7 +87,12 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View { while (try albums_jq_result.postgresql.result.next()) |album_row| { const album = try album_row.to(AlbumsResult, .{ .dupe = true, .allocator = request.allocator }); - try albums_view.append(album); + const album_table_row = TableRow{ + .album = .{ .name = album.name, .id = album.id }, + .scrobbles = album.scrobbles, + }; + + try albums_view.append(album_table_row); } //albums_jq_result.drain(); @@ -107,7 +115,12 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View { while (try appears_jq_result.postgresql.result.next()) |appears_row| { const appears = try appears_row.to(AlbumsResult, .{ .dupe = true, .allocator = request.allocator }); - try appears_view.append(appears); + const appears_table_row = TableRow{ + .album = .{ .name = appears.name, .id = appears.id }, + .scrobbles = appears.scrobbles, + }; + + try appears_view.append(appears_table_row); } //appears_jq_result.drain(); diff --git a/src/app/views/artists/index.zmpl b/src/app/views/artists/index.zmpl index 6854e07..0648c91 100644 --- a/src/app/views/artists/index.zmpl +++ b/src/app/views/artists/index.zmpl @@ -1,34 +1,15 @@ +@zig { + const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date}; + const columns: ColumnChoices = &.{.artist, .scrobbles}; +} + - @partial partials/header

Artists

- - - - - - - - -@for (.artists) |artist| { - - - - -} - -
NameScrobbles
{{artist.name}}{{artist.scrobbles}}
- - +@partial partials/newtable(T: ColumnChoices, table_data: .artists, columns: columns) \ No newline at end of file diff --git a/src/app/views/partials/_newtable.zmpl b/src/app/views/partials/_newtable.zmpl index 8960e21..6746a2a 100644 --- a/src/app/views/partials/_newtable.zmpl +++ b/src/app/views/partials/_newtable.zmpl @@ -32,33 +32,37 @@ @zig { const array = table_data.items(.array); - for (array) |ent| { + for (array) |row| { for (columns) |header| { switch (header) { - .song, .album, .artist => { - const path = switch (header) { - .song => "songs", - .album => "albums", - .artist => "artists", - else => unreachable - }; + .song => { - {{ent.name}} + {{row.song.name}} + + }, + .album => { + + {{row.album.name}} + + }, + .artist => { + + {{row.artist.name}} }, .artistlist => { - @for (ent.get("artist_info").?) |artist| { + @for (row.get("artistlist").?) |artist| { {{artist.name}} } }, .scrobbles => { - {{ent.scrobbles}} + {{row.scrobbles}} }, .date =>{ - {{ent.date}} + {{row.date}} } } } diff --git a/src/app/views/scrobbles.zig b/src/app/views/scrobbles.zig index 1386a83..9403fa9 100644 --- a/src/app/views/scrobbles.zig +++ b/src/app/views/scrobbles.zig @@ -1,6 +1,8 @@ const std = @import("std"); const jetzig = @import("jetzig"); const zeit = @import("zeit"); +const TableRow = @import("../../types.zig").TableRows; +const HyperlinkData = @import("../../types.zig").HyperlinkData; pub fn index(request: *jetzig.Request) !jetzig.View { var root = try request.data(.object); @@ -23,33 +25,30 @@ pub fn index(request: *jetzig.Request) !jetzig.View { const Scrobble = struct { song_name: []const u8, song_id: i32, album_name: []const u8, album_id: i32, artist_name: []const u8, artist_id: i32, s_id: i32, date: i64 }; var prev_s_id: ?i32 = null; - var prev_artist_infos: ?*jetzig.zmpl.Data.Value = null; + + var row: ?TableRow = null; + var artistlist = std.ArrayList(HyperlinkData).init(request.allocator); blk: while (try scrobbles_jq_result.postgresql.result.next()) |scrobble_row| { const scrobble = try scrobble_row.to(Scrobble, .{ .dupe = true, .allocator = request.allocator }); if (scrobble.s_id == prev_s_id) { - var artist_info = try prev_artist_infos.?.append(.object); - try artist_info.put("name", scrobble.artist_name); - try artist_info.put("url", scrobble.artist_id); + try artistlist.append(.{ .name = scrobble.artist_name, .id = scrobble.artist_id }); continue :blk; + } else { + var date = std.ArrayList(u8).init(request.allocator); + try (try zeit.instant(.{ .source = .{ .unix_timestamp = @divFloor(scrobble.date, 1_000) } })).time().strftime(date.writer(), "%d %b %Y, %H:%M"); + + try artistlist.append(.{ .name = scrobble.artist_name, .id = scrobble.artist_id }); + + row = TableRow{ + .song = .{ .name = scrobble.song_name, .id = scrobble.song_id }, + .album = .{ .name = scrobble.album_name, .id = scrobble.album_id }, + .artistlist = try artistlist.toOwnedSlice(), + .date = date.items, + }; + + try scrobbles_view.append(row); } - // Not appending the scrobble directly because we don't want the unix timestamp or scrobble id - var scrobble_view = try scrobbles_view.append(.object); - - var artist_infos = try scrobble_view.put("artist_info", .array); - var artist_info = try artist_infos.append(.object); - try artist_info.put("name", scrobble.artist_name); - try artist_info.put("url", scrobble.artist_id); - - try scrobble_view.put("song_name", scrobble.song_name); - try scrobble_view.put("song_id", scrobble.song_id); - try scrobble_view.put("album_name", scrobble.album_name); - try scrobble_view.put("album_id", scrobble.album_id); - var date = std.ArrayList(u8).init(request.allocator); - try (try zeit.instant(.{ .source = .{ .unix_timestamp = @divFloor(scrobble.date, 1_000) } })).time().strftime(date.writer(), "%d %b %Y, %H:%M"); - try scrobble_view.put("date", date.items); - - prev_artist_infos = artist_infos; prev_s_id = scrobble.s_id; } diff --git a/src/app/views/scrobbles/index.zmpl b/src/app/views/scrobbles/index.zmpl index b298cb6..c3d6759 100644 --- a/src/app/views/scrobbles/index.zmpl +++ b/src/app/views/scrobbles/index.zmpl @@ -1,42 +1,15 @@ +@zig { + const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date}; + const columns: ColumnChoices = &.{.song, .artistlist, .album, .date}; +} + - @partial partials/header

Scrobbles

- - - - - - - - - - -@for (.scrobbles) |scrobble| { - - - - - - -} - -
SongArtist(s)AlbumDate
{{scrobble.song_name}} - @for (scrobble.get("artist_info").?) |ai| { - {{ai.name}} - } - {{scrobble.album_name}}{{scrobble.date}}
- - +@partial partials/newtable(T: ColumnChoices, table_data: .scrobbles, columns: columns) \ No newline at end of file diff --git a/src/app/views/songs.zig b/src/app/views/songs.zig index cd220f8..5302906 100644 --- a/src/app/views/songs.zig +++ b/src/app/views/songs.zig @@ -1,5 +1,7 @@ const std = @import("std"); const jetzig = @import("jetzig"); +const TableRow = @import("../../types.zig").TableRows; +const HyperlinkData = @import("../../types.zig").HyperlinkData; pub fn index(request: *jetzig.Request) !jetzig.View { var root = try request.data(.object); @@ -22,28 +24,26 @@ pub fn index(request: *jetzig.Request) !jetzig.View { const Song = struct { name: []const u8, id: i32, artist_name: []const u8, artist_id: i32, scrobbles: i64 }; var prev_song_id: ?i32 = null; - var prev_artist_infos: ?*jetzig.zmpl.Data.Value = null; + + var row: ?TableRow = null; + var artistlist = std.ArrayList(HyperlinkData).init(request.allocator); blk: while (try songs_js_result.postgresql.result.next()) |song_row| { const song = try song_row.to(Song, .{ .dupe = true, .allocator = request.allocator }); if (song.id == prev_song_id) { - var artist_info = try prev_artist_infos.?.append(.object); - try artist_info.put("name", song.artist_name); - try artist_info.put("url", song.artist_id); + try artistlist.append(.{ .name = song.artist_name, .id = song.artist_id }); continue :blk; + } else { + try artistlist.append(.{ .name = song.artist_name, .id = song.artist_id }); + + row = TableRow{ + .song = .{ .name = song.name, .id = song.id }, + .artistlist = try artistlist.toOwnedSlice(), + .scrobbles = song.scrobbles, + }; + + try songs_view.append(row); } - var song_view = try songs_view.append(.object); - - var artist_infos = try song_view.put("artist_info", .array); - var artist_info = try artist_infos.append(.object); - try artist_info.put("name", song.artist_name); - try artist_info.put("url", song.artist_id); - - try song_view.put("name", song.name); - try song_view.put("url", song.id); - try song_view.put("scrobbles", song.scrobbles); - - prev_artist_infos = artist_infos; prev_song_id = song.id; } return request.render(.ok); diff --git a/src/app/views/songs/index.zmpl b/src/app/views/songs/index.zmpl index 181da87..6964630 100644 --- a/src/app/views/songs/index.zmpl +++ b/src/app/views/songs/index.zmpl @@ -1,40 +1,15 @@ +@zig { + const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date}; + const columns: ColumnChoices = &.{.song, .artistlist, .scrobbles}; +} + - @partial partials/header

Songs

- - - - - - - - - -@for (.songs) |song| { - - - - - -} - -
NameArtist(s)Scrobbles
{{song.name}} - @for (song.get("artist_info").?) |ai| { - {{ai.name}} - } - {{song.scrobbles}}
- - +@partial partials/newtable(T: ColumnChoices, table_data: .songs, columns: columns) \ No newline at end of file diff --git a/src/types.zig b/src/types.zig index 455f282..2a82886 100644 --- a/src/types.zig +++ b/src/types.zig @@ -72,3 +72,18 @@ pub const Rules = struct { // scrobbles, // date, //}; +// + +pub const TableRows = struct { + song: ?HyperlinkData = null, + album: ?HyperlinkData = null, + artist: ?HyperlinkData = null, + artistlist: ?[]HyperlinkData = null, + scrobbles: ?i64 = null, + date: ?[]const u8 = null, +}; + +pub const HyperlinkData = struct { + name: []const u8, + id: i32, +};