zuletzt/src/app/views/albums.zig
mitteneer 0b7efc3420 Begin album reviews
Album reviews would ideally allow you to rate tracks at the same time, so we'll have to work on that next. Also, disambiguation pages are becoming more and more necessary (Little Talks in inaccessible atm) Preferably, we start working on the `INDEX` for `/ratings` as well, and maybe use a unified language for these things (is it review, rating, rating_text, score,...?)
2025-06-24 00:05:25 -04:00

62 lines
2.6 KiB
Zig

const std = @import("std");
const jetzig = @import("jetzig");
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);
const albums = try queries.entityQueryResult(request, queries.loadQuery(.album, .entities), .{});
try root.put("albums", albums);
return request.render(.ok);
}
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_int});
try root.put("album", album);
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_int});
try root.put("firstlast", firstlast);
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);
}