diff --git a/src/app/views/albums/get.zmpl b/src/app/views/albums/get.zmpl index 1024ec5..22f99d8 100644 --- a/src/app/views/albums/get.zmpl +++ b/src/app/views/albums/get.zmpl @@ -9,8 +9,10 @@ @partial partials/header -

{{.album}}

-@partial partials/firstlast_listens(scrobbles: .album.scrobbles, rank: .album.rank, firstlast: .firstlast) +

{{.album.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

diff --git a/src/app/views/artists/get.zmpl b/src/app/views/artists/get.zmpl index 69bd661..14976b5 100644 --- a/src/app/views/artists/get.zmpl +++ b/src/app/views/artists/get.zmpl @@ -10,9 +10,14 @@ @partial partials/header

{{.artist.name}}

-@partial partials/firstlast_listens(scrobbles: .artist.scrobbles, rank: .artist.rank, firstlast: .firstlast) -

Yearly Performance

+
+
{{.artist.scrobbles}} scrobbles ({{.artist.rank}} place)
+
{{.artist.song_num}} songs
+
{{.artist.album_num}} albums
+
@partial partials/timescale(range: .yearly) +
+@partial partials/firstlast_listens(firstlast: .firstlast)

Albums

@partial partials/newtable(T: ColumnChoices, table_data: .albums, columns: columns) diff --git a/src/app/views/partials/_firstlast_listens.zmpl b/src/app/views/partials/_firstlast_listens.zmpl index a21114b..3cf3ac9 100644 --- a/src/app/views/partials/_firstlast_listens.zmpl +++ b/src/app/views/partials/_firstlast_listens.zmpl @@ -1,12 +1,10 @@ -@args scrobbles: i64, rank: []const u8, firstlast: *ZmplValue +@args firstlast: *ZmplValue @zig { const songs = firstlast.items(.array); }
-{{scrobbles}} scrobbles ({{rank}} place) -
First listen: {{songs[0].song.name}} ({{songs[0].date}})
Most recent listen: {{songs[1].song.name}} ({{songs[1].date}}) diff --git a/src/app/views/partials/_timescale.zmpl b/src/app/views/partials/_timescale.zmpl index 9937ec6..24ef925 100644 --- a/src/app/views/partials/_timescale.zmpl +++ b/src/app/views/partials/_timescale.zmpl @@ -1,5 +1,6 @@ @args range: *ZmplValue +
@@ -8,11 +9,12 @@ -@for (range) |itm| { - - - - -} - -
{{itm.date}}:{{itm.scrobbles}}
\ No newline at end of file + @for (range) |itm| { + + {{itm.date}}: + {{itm.scrobbles}} + + } + + +
\ No newline at end of file diff --git a/src/app/views/songs/get.zmpl b/src/app/views/songs/get.zmpl index 0a051a4..5b68145 100644 --- a/src/app/views/songs/get.zmpl +++ b/src/app/views/songs/get.zmpl @@ -9,8 +9,9 @@ @partial partials/header -

{{.song}}

-@partial partials/firstlast_listens(scrobbles: .song.scrobbles, rank: .song.rank, firstlast: .firstlast) +

{{.song.name}}

+
{{.song.scrobbles}} scrobbles ({{.song.rank}} place)
+@partial partials/firstlast_listens(firstlast: .firstlast)

Yearly Performance

@partial partials/timescale(range: .yearly)

Scrobbles

diff --git a/src/queries.zig b/src/queries.zig index 0411022..a22b68e 100644 --- a/src/queries.zig +++ b/src/queries.zig @@ -17,13 +17,18 @@ pub fn entityQueryResult(request: *jetzig.Request, query: GeneratedQuery, args: if (query.query_type == .entity_info) { var out: *jetzig.Data.Value = try Data.object(); - const entity = try (try result.next()).?.to(struct { name: []const u8, id: i32, scrobbles: i64, rank: []const u8 }, .{ .dupe = true, .allocator = request.allocator }); - const entity_struct = .{ .name = entity.name, .id = entity.id, .scrobbles = entity.scrobbles, .rank = entity.rank }; - try out.put("entity_info", entity_struct); + const entity = try (try result.next()).?.to(struct { name: []const u8, id: i32, scrobbles: i64, album_num: ?i64 = null, song_num: ?i64 = null, rank: []const u8 }, .{ .dupe = true, .allocator = request.allocator, .map = .name }); + try out.put("entity_info", entity); try result.drain(); return out.get("entity_info").?; } + //if (query.query_type == .datestreak) { + // var out: *jetzig.Data.Value = try Data.object(); + // const entity = try (try result.next()).?.to(struct { name: []const u8, id: i32, scrobbles: i64, rank: []const u8 }, .{ .dupe = true, .allocator = request.allocator }); + // + //} + var out: *jetzig.Data.Value = try Data.array(); var mapper = result.mapper(UnifiedResult, .{ .dupe = true, .allocator = request.allocator }); @@ -168,14 +173,17 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery { , .artist => - \\SELECT TO_CHAR(date_trunc('year', datetime), 'YYYY') AS date, COUNT(*) as scrobbles + \\SELECT y.year AS date, COALESCE(DT.scrobbles, 0) AS scrobbles + \\FROM (SELECT GENERATE_SERIES(2016,date_part('year',now())::int)::text) AS y(year) + \\LEFT JOIN (SELECT TO_CHAR(date_trunc('year', datetime), 'YYYY') AS date, COUNT(*) as scrobbles \\FROM scrobbles \\INNER JOIN albumsongs ON albumsongs.id = scrobbles.albumsong \\INNER JOIN albumsongsartists ON albumsongsartists.albumsong_id = albumsongs.id \\INNER JOIN artists ON artists.id = albumsongsartists.artist_id \\WHERE artists.id = $1 \\GROUP BY date - \\ORDER BY date ASC; + \\ORDER BY date ASC) AS DT + \\ON DT.date = y.year; , }, @@ -303,21 +311,24 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery { .album => \\SELECT * FROM \\(SELECT *, TO_CHAR(ROW_NUMBER() OVER (ORDER BY scrobbles DESC),'FM9999th') AS rank FROM - \\(SELECT albums.name AS name, albums.id AS id, COUNT(scrobbles) AS scrobbles + \\(SELECT albums.name AS name, albums.id AS id, COUNT(DISTINCT songs.id) AS song_num, COUNT(scrobbles) AS scrobbles \\FROM albumsongs \\INNER JOIN albums ON albumsongs.album_id = albums.id \\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id + \\INNER JOIN songs ON songs.id = albumsongs.song_id \\GROUP BY albums.id)) - \\WHERE id = $1 + \\WHERE id = $1; , .artist => \\SELECT * FROM \\(SELECT *, TO_CHAR(ROW_NUMBER() OVER (ORDER BY scrobbles DESC),'FM9999th') AS rank FROM - \\(SELECT artists.name AS name, artists.id AS id, COUNT(scrobbles) AS scrobbles + \\(SELECT artists.name AS name, artists.id AS id, COUNT(scrobbles) AS scrobbles, COUNT(DISTINCT albums.id) AS album_num, COUNT(DISTINCT songs.id) AS song_num \\FROM albumsongsartists \\INNER JOIN artists ON albumsongsartists.artist_id = artists.id \\INNER JOIN albumsongs ON albumsongsartists.albumsong_id = albumsongs.id \\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id + \\INNER JOIN albums ON albums.id = albumsongs.album_id + \\INNER JOIN songs ON songs.id = albumsongs.song_id \\GROUP BY artists.id)) \\WHERE id = $1 , @@ -325,22 +336,44 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery { .datestreak => switch (entity) { .song => - \\SELECT songs.name AS song_name, albums.name AS album_name, streak.maxseq AS intval, FORMAT('%s - %s, streak.ds, streak.de) AS date FROM (SELECT albumsong, MAX(numdays) AS maxseq, ds, de - \\FROM (SELECT albumsong, grp, MIN(datetime::date) AS ds, MAX(datetime::date) AS de, + \\SELECT maxseq AS streak, FORMAT('%s - %s', ds, de) AS date FROM (SELECT MAX(numdays) AS maxseq, ds, de + \\FROM (SELECT grp, MIN(datetime::date) AS ds, MAX(datetime::date) AS de, \\COUNT(DISTINCT datetime::date) AS numdays - \\FROM (SELECT scrobbles.*, - \\((datetime::date - '1970-01-01'::date) - DENSE_RANK() OVER (PARTITION BY albumsong ORDER BY datetime::date)) AS grp - \\FROM scrobbles + \\FROM (SELECT scrobbles.datetime, + \\((datetime::date - '1970-01-01'::date) - DENSE_RANK() OVER (PARTITION BY songs.id ORDER BY datetime::date)) AS grp + \\FROM scrobbles INNER JOIN albumsongs ON albumsongs.id = albumsong INNER JOIN songs ON songs.id = albumsongs.song_id + \\WHERE songs.id = $1) scrobbles + \\GROUP BY grp \\) scrobbles - \\GROUP BY albumsong, grp - \\) scrobbles - \\GROUP BY albumsong, ds, de) AS streak - \\INNER JOIN albumsongs ON albumsongs.id = streak.albumsong - \\INNER JOIN albums ON albums.id = albumsongs.album_id - \\INNER JOIN songs ON songs.id = albumsongs.song_id - \\ORDER BY streak.maxseq DESC; + \\GROUP BY ds, de) + \\ORDER BY maxseq DESC; , - else => unreachable, + .artist => + \\SELECT maxseq AS streak, FORMAT('%s - %s' ,ds,de) AS date FROM (SELECT MAX(numdays) AS maxseq, ds, de + \\FROM (SELECT grp, MIN(datetime::date) AS ds, MAX(datetime::date) AS de, + \\COUNT(DISTINCT datetime::date) AS numdays + \\FROM (SELECT scrobbles.datetime, + \\((scrobbles.datetime::date - '1970-01-01'::date) - DENSE_RANK() OVER (PARTITION BY artists.id ORDER BY scrobbles.datetime::date)) AS grp + \\FROM scrobbles INNER JOIN albumsongsartists ON albumsongsartists.albumsong_id = scrobbles.albumsong INNER JOIN artists ON artists.id = albumsongsartists.artist_id + \\WHERE artists.id = $1) scrobbles + \\GROUP BY grp + \\) scrobbles + \\GROUP BY ds, de) + \\ORDER BY maxseq DESC; + , + .album => + \\SELECT maxseq AS streak, FORMAT('%s - %s', ds, de) AS date FROM (SELECT MAX(numdays) AS maxseq, ds, de + \\FROM (SELECT grp, MIN(datetime::date) AS ds, MAX(datetime::date) AS de, + \\COUNT(DISTINCT datetime::date) AS numdays + \\FROM (SELECT scrobbles.datetime, + \\((datetime::date - '1970-01-01'::date) - DENSE_RANK() OVER (PARTITION BY albums.id ORDER BY datetime::date)) AS grp FROM scrobbles INNER JOIN albumsongs ON albumsongs.id = albumsong INNER JOIN albums ON albums.id = albumsongs.album_id + \\WHERE albums.id = $1) scrobbles + \\GROUP BY grp + \\) scrobbles + \\GROUP BY ds, de) + \\ORDER BY maxseq DESC; + , + .scrobble => unreachable, }, }, };