diff --git a/src/app/views/albums.zig b/src/app/views/albums.zig index 03046b3..17421e7 100644 --- a/src/app/views/albums.zig +++ b/src/app/views/albums.zig @@ -4,6 +4,7 @@ const jetquery = @import("jetzig").jetquery; const TableRow = @import("../../types.zig").TableRow; const HyperlinkData = @import("../../types.zig").HyperlinkData; const queries = @import("../../queries.zig"); +const decode = @import("../../date_fmt.zig").urlDecode; pub fn index(request: *jetzig.Request) !jetzig.View { var root = try request.data(.object); @@ -15,19 +16,47 @@ pub fn index(request: *jetzig.Request) !jetzig.View { } pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View { + const parse_err = blk: { + const rdr_id = std.fmt.parseInt(i64, id, 10) catch |err| break :blk err; + const album = try jetzig.database.Query(.Album).find(rdr_id).execute(request.repo); + if (album == null) break :blk error.InvalidCharacter; + var name = std.ArrayList(u8).init(request.allocator); + try name.appendSlice("http://127.0.0.1:8080/albums/"); + try name.appendSlice(album.?.name); + return request.redirect(try name.toOwnedSlice(), .found); + }; + + const id_int = switch (parse_err) { + error.Overflow => return request.fail(.not_found), + error.InvalidCharacter => blk: { + const rn = try decode(request.allocator, id); + std.log.debug("{s}", .{rn}); + const songs = try jetzig.database.Query(.Album).where(.{ .name = rn }).all(request.repo); + + if (songs.len == 0) return request.fail(.not_found); + if (songs.len > 1) return request.redirect("http://127.0.0.1:8080", .found); + break :blk songs[0].id; + }, + }; var root = try request.data(.object); - const album = try queries.entityQueryResult(request, queries.loadQuery(.album, .entity_info), .{id}); + const album = try queries.entityQueryResult(request, queries.loadQuery(.album, .entity_info), .{id_int}); try root.put("album", album); - const songs = try queries.entityQueryResult(request, queries.loadQuery(.album, .get_songs), .{id}); + const scrobbles = try queries.entityQueryResult(request, queries.loadQuery(.song, .get_scrobbles), .{id_int}); + try root.put("scrobbles", scrobbles); + + const songs = try queries.entityQueryResult(request, queries.loadQuery(.album, .get_songs), .{id_int}); try root.put("songs", songs); - const firstlast = try queries.entityQueryResult(request, queries.loadQuery(.album, .firstlast), .{id}); + const firstlast = try queries.entityQueryResult(request, queries.loadQuery(.album, .firstlast), .{id_int}); try root.put("firstlast", firstlast); - const timescale = try queries.entityQueryResult(request, queries.loadQuery(.album, .timescale), .{id}); + const timescale = try queries.entityQueryResult(request, queries.loadQuery(.album, .timescale), .{id_int}); try root.put("yearly", timescale); + const ratings = try queries.entityQueryResult(request, queries.loadQuery(.song, .get_ratings), .{id_int}); + try root.put("reviews", ratings); + return request.render(.ok); } diff --git a/src/app/views/albums/get.zmpl b/src/app/views/albums/get.zmpl index 7e089e7..6dfd7f7 100644 --- a/src/app/views/albums/get.zmpl +++ b/src/app/views/albums/get.zmpl @@ -1,22 +1,48 @@ @zig { const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date}; const columns: ColumnChoices = &.{.song, .scrobbles}; + const reviews = try zmpl.coerceArray(".reviews"); } + @partial partials/header +

{{.album.album_name}}

{{.album.artist_name}}

-
{{.album.scrobbles}} scrobbles ({{.album.rank}} place)
-
{{.album.song_num}} songs
-@partial partials/firstlast_listens(firstlast: .firstlast) -

Yearly Performance

-@partial partials/timescale(range: .yearly) -

Songs

-@partial partials/newtable(T: ColumnChoices, table_data: .songs, columns: columns) +
+ +
+
+
{{.album.scrobbles}} scrobbles ({{.album.rank}} place)
+
{{.album.song_num}} songs
+ @partial partials/firstlast_listens(firstlast: .firstlast) +

Yearly Performance

+ @partial partials/timescale(range: .yearly) +

Songs

+ @partial partials/newtable(T: ColumnChoices, table_data: .songs, columns: columns) +
+
+

Rating

+
+ @zig { + if (reviews.len == 0) { +
+ + + +
+ } else { + for (reviews) |review| { + {{review.score}}: {{review.review}} ({{review.date}}) + } + } + } +
+
\ No newline at end of file diff --git a/src/app/views/ratings/albums.zig b/src/app/views/ratings/albums.zig new file mode 100644 index 0000000..a57adfa --- /dev/null +++ b/src/app/views/ratings/albums.zig @@ -0,0 +1,14 @@ +const std = @import("std"); +const jetzig = @import("jetzig"); +pub fn post(request: *jetzig.Request) !jetzig.View { + var root = try request.data(.object); + const params = try request.params(); + const id = params.getT(.integer, "album_id").?; + const score = if (params.getT(.integer, "score")) |score| @as(i16, @truncate(score)) else null; + const review = params.getT(.string, "review"); + try jetzig.database.Query(.Albumrating).insert(.{ .album = id, .rating = score, .rating_text = review, .date = @divFloor(request.start_time, 1_000) }).execute(request.repo); + try root.put("score", score); + try root.put("review", review); + + return request.render(.created); +} diff --git a/src/app/views/ratings/albums/post.zmpl b/src/app/views/ratings/albums/post.zmpl new file mode 100644 index 0000000..ca54fd7 --- /dev/null +++ b/src/app/views/ratings/albums/post.zmpl @@ -0,0 +1 @@ + {{.score}}: {{.review}} (Today) \ No newline at end of file diff --git a/src/app/views/songs/get.zmpl b/src/app/views/songs/get.zmpl index f07b03c..c092ea5 100644 --- a/src/app/views/songs/get.zmpl +++ b/src/app/views/songs/get.zmpl @@ -28,17 +28,17 @@

Rating

@zig { - if (reviews.len == 0) { -
- - - -
- } else { - for (reviews) |review| { - {{review.score}}: {{review.review}} ({{review.date}}) - } -} + if (reviews.len == 0) { +
+ + + +
+ } else { + for (reviews) |review| { + {{review.score}}: {{review.review}} ({{review.date}}) + } + } }
diff --git a/src/queries.zig b/src/queries.zig index 0c9359e..9010942 100644 --- a/src/queries.zig +++ b/src/queries.zig @@ -446,6 +446,12 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery { \\WHERE song = $1 \\ORDER BY date DESC; , + .album => + \\SELECT rating AS score, rating_text AS review, TO_CHAR(date, 'YYY-MM-DD') AS date + \\FROM albumratings + \\WHERE album = $1 + \\ORDER BY date DESC; + , else => unreachable, }, },