diff --git a/build.zig.zon b/build.zig.zon
index f2e5778..c06a1ac 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -17,12 +17,12 @@
// 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/1feb18fb74e626fe068ec67532318640a9cb83be.tar.gz",
+ .hash = "jetzig-0.0.0-IpAgLfMzDwDyAqZ05btcLDd9dfE_bxUbfOI_Wx7a19ed",
},
.zeit = .{
- .url = "https://github.com/rockorager/zeit/archive/refs/tags/v0.6.0.tar.gz",
- .hash = "zeit-0.0.0-5I6bk_pZAgB03N1p1GmVOZ--gOFwwQSRKj1UXb5tnaKS",
+ .url = "https://github.com/rockorager/zeit/archive/refs/heads/main.tar.gz",
+ .hash = "zeit-0.6.0-5I6bk5daAgC-P60TjxRqW0bYknfCGxJp-03eS9UjGrO7",
},
},
.paths = .{
diff --git a/common_queries.md b/common_queries.md
new file mode 100644
index 0000000..833d2c0
--- /dev/null
+++ b/common_queries.md
@@ -0,0 +1,164 @@
+Get all albums from specified artist:
+```sql
+SELECT artists.name, albums.name
+FROM "Albumartists"
+INNER JOIN artists
+ON "Albumartists".artist_id = artists.id
+INNER JOIN albums
+ON "Albumartists".album_id = albums.id
+WHERE artists.name = {ARTIST};
+```
+
+Get all songs from specified artist:
+```sql
+SELECT artists.name, songs.name
+FROM "Songartists"
+INNER JOIN artists
+ON "Songartists".artist_id = artists.id
+INNER JOIN songs
+ON "Songartists".song_id = songs.id
+WHERE artists.name = {ARTIST};
+```
+
+Get all songs from any album of the specified name:
+```sql
+SELECT songs.name
+FROM "Albumsongs"
+INNER JOIN albums
+ON "Albumsongs".album_id = albums.id
+INNER JOIN songs
+ON "Albumsongs".song_id = songs.id
+WHERE albums.name = {ALBUM};
+```
+
+Sort all songs by plays (does not list artist or album):
+```sql
+SELECT songs.name, COUNT(scrobbles.song_id) AS scount
+FROM songs, scrobbles
+WHERE songs.id = scrobbles.song_id
+GROUP BY songs.id
+ORDER BY scount DESC;
+```
+
+Sort all songs by plays, and include artist:
+```sql
+SELECT songs.name, artists.name, COUNT(scrobbles.song_id) AS scount
+FROM scrobbles, "Songartists"
+INNER JOIN artists
+ON "Songartists".artist_id = artists.id
+INNER JOIN songs
+ON "Songartists".song_id = songs.id
+WHERE songs.id = scrobbles.song_id
+GROUP BY songs.id, artists.id
+ORDER BY scount DESC;
+```
+
+Sort all songs by plays, and include artist and album:
+```sql
+SELECT songs.name, artists.name, albums.name, COUNT(scrobbles.song_id) AS scount
+FROM scrobbles CROSS JOIN "Songartists" CROSS JOIN "Albumsongs"
+INNER JOIN artists
+ON "Songartists".artist_id = artists.id
+INNER JOIN songs
+ON "Songartists".song_id = songs.id AND "Albumsongs".song_id = songs.id
+INNER JOIN albums
+ON "Albumsongs".album_id = albums.id
+WHERE songs.id = scrobbles.song_id
+GROUP BY songs.id, artists.id, albums.id
+ORDER BY scount DESC;
+```
+
+Sort all albums by plays, and include artist:
+```sql
+SELECT albums.name, artists.name, COUNT(scrobbles.album_id) AS scount
+FROM scrobbles, "Albumartists"
+INNER JOIN albums
+ON "Albumartists".album_id = albums.id
+INNER JOIN artists
+ON "Albumartists".artist_id = artists.id
+WHERE albums.id = scrobbles.album_id
+GROUP BY artists.id, albums.id
+ORDER BY scount DESC;
+```
+
+Sort all artists by plays:
+```sql
+SELECT artists.name, COUNT(scrobbles.id) AS scount
+FROM artists, "Scrobbleartists"
+INNER JOIN scrobbles
+ON scrobbles.id = "Scrobbleartists".scrobble_id
+WHERE "Scrobbleartists".artist_id = artists.id
+GROUP BY artists.id
+ORDER BY scount DESC;
+```
+
+Sort all artists by alphabetical order, and include the first time you listened to that artist:
+```sql
+SELECT artists.name, MIN(scrobbles.date)
+FROM "Scrobbleartists"
+INNER JOIN artists
+ON "Scrobbleartists".artist_id = artists.id
+INNER JOIN scrobbles
+ON "Scrobbleartists".scrobble_id = scrobbles.id
+GROUP BY artists.id
+ORDER BY artists.name ASC;
+```
+
+Sort all songs by alphabetical order, and include the first time you listened to that song:
+```sql
+SELECT songs.name, MIN(scrobbles.date)
+FROM scrobbles
+INNER JOIN songs
+ON scrobbles.song_id = songs.id
+GROUP BY songs.id
+ORDER BY songs.name ASC;
+```
+
+Sort all albums by alphabetical order, and include the first time you listened to that album:
+```sql
+SELECT albums.name, MIN(scrobbles.date)
+FROM scrobbles
+INNER JOIN albums
+ON scrobbles.album_id = albums.id
+GROUP BY albums.id
+ORDER BY albums.name ASC;
+```
+
+Select all songs by specified artists, include the number of plays of each song, and sort by plays:
+```sql
+SELECT songs.name, COUNT(scrobbles.song_id) as count
+FROM songs, "Scrobbleartists"
+INNER JOIN artists
+ON "Scrobbleartists".artist_id = artists.id
+INNER JOIN scrobbles
+ON "Scrobbleartists".scrobble_id = scrobbles.id
+WHERE songs.id = scrobbles.song_id AND artists.name = {ARTIST}
+GROUP BY songs.id
+ORDER BY count DESC;
+```
+
+Select all albums by specified artist, include the number of plays of each album, and sort by plays:
+```sql
+SELECT albums.name, COUNT(scrobbles.song_id) as count
+FROM albums, "Scrobbleartists"
+INNER JOIN artists
+ON "Scrobbleartists".artist_id = artists.id
+INNER JOIN scrobbles
+ON "Scrobbleartists".scrobble_id = scrobbles.id
+WHERE albums.id = scrobbles.album_id AND artists.name = {ARTIST}
+GROUP BY albums.id
+ORDER BY count DESC;
+```
+
+Select all songs from an album specified by an ID, and sort by plays
+```sql
+SELECT songs.name, COUNT(scrobbles.song_id) AS count
+FROM "Albumsongs"
+INNER JOIN songs
+ON songs.id = "Albumsongs".song_id
+INNER JOIN scrobbles
+ON scrobbles.song_id = "Albumsongs".song_id
+WHERE "Albumsongs".album_id = {ALBUM_ID}
+GROUP BY songs.id
+ORDER BY count DESC;
+```
\ No newline at end of file
diff --git a/src/app/middleware/DemoMiddleware.zig b/src/app/middleware/DemoMiddleware.zig
new file mode 100644
index 0000000..a6758d2
--- /dev/null
+++ b/src/app/middleware/DemoMiddleware.zig
@@ -0,0 +1,65 @@
+/// Demo middleware. Assign middleware by declaring `pub const middleware` in the
+/// `jetzig_options` defined in your application's `src/main.zig`.
+///
+/// Middleware is called before and after the request, providing full access to the active
+/// request, allowing you to execute any custom code for logging, tracking, inserting response
+/// headers, etc.
+///
+/// This middleware is configured in the demo app's `src/main.zig`:
+///
+/// ```
+/// pub const jetzig_options = struct {
+/// pub const middleware: []const type = &.{@import("app/middleware/DemoMiddleware.zig")};
+/// };
+/// ```
+const std = @import("std");
+const jetzig = @import("jetzig");
+
+/// Define any custom data fields you want to store here. Assigning to these fields in the `init`
+/// function allows you to access them in various middleware callbacks defined below, where they
+/// can also be modified.
+my_custom_value: []const u8,
+
+const Self = @This();
+
+/// Initialize middleware.
+pub fn init(request: *jetzig.http.Request) !*Self {
+ var middleware = try request.allocator.create(Self);
+ middleware.my_custom_value = "initial value";
+ return middleware;
+}
+
+/// Invoked immediately after the request is received but before it has started processing.
+/// Any calls to `request.render` or `request.redirect` will prevent further processing of the
+/// request, including any other middleware in the chain.
+pub fn afterRequest(self: *Self, request: *jetzig.http.Request) !void {
+ try request.server.logger.DEBUG(
+ "[DemoMiddleware:afterRequest] my_custom_value: {s}",
+ .{self.my_custom_value},
+ );
+ self.my_custom_value = @tagName(request.method);
+}
+
+/// Invoked immediately before the response renders to the client.
+/// The response can be modified here if needed.
+pub fn beforeResponse(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) !void {
+ try request.server.logger.DEBUG(
+ "[DemoMiddleware:beforeResponse] my_custom_value: {s}, response status: {s}",
+ .{ self.my_custom_value, @tagName(response.status_code) },
+ );
+}
+
+/// Invoked immediately after the response has been finalized and sent to the client.
+/// Response data can be accessed for logging, but any modifications will have no impact.
+pub fn afterResponse(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) !void {
+ _ = self;
+ _ = response;
+ try request.server.logger.DEBUG("[DemoMiddleware:afterResponse] response completed", .{});
+}
+
+/// Invoked after `afterResponse` is called. Use this function to do any clean-up.
+/// Note that `request.allocator` is an arena allocator, so any allocations are automatically
+/// freed before the next request starts processing.
+pub fn deinit(self: *Self, request: *jetzig.http.Request) void {
+ request.allocator.destroy(self);
+}
diff --git a/src/app/views/albums.zig b/src/app/views/albums.zig
index 1264dac..cc6d765 100644
--- a/src/app/views/albums.zig
+++ b/src/app/views/albums.zig
@@ -29,19 +29,19 @@ pub fn index(request: *jetzig.Request) !jetzig.View {
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 artist_info.put("url", album.artist_id);
continue :blk;
}
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);
+ try artist_info.put("url", album.artist_id);
+
+ try album_view.put("name", album.name);
+ try album_view.put("url", album.id);
+ try album_view.put("scrobbles", album.scrobbles);
prev_artist_infos = artist_infos;
prev_album_id = album.id;
@@ -74,8 +74,100 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
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("url", song.id);
try song_view.put("scrobbles", song.scrobbles);
}
return request.render(.ok);
}
+
+pub fn new(request: *jetzig.Request) !jetzig.View {
+ return request.render(.ok);
+}
+
+pub fn edit(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn post(request: *jetzig.Request) !jetzig.View {
+ return request.render(.created);
+}
+
+pub fn put(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn patch(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn delete(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+test "index" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/album", .{});
+ try response.expectStatus(.ok);
+}
+
+test "get" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/album/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "new" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/album/new", .{});
+ try response.expectStatus(.ok);
+}
+
+test "edit" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/album/example-id/edit", .{});
+ try response.expectStatus(.ok);
+}
+
+test "post" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.POST, "/album", .{});
+ try response.expectStatus(.created);
+}
+
+test "put" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PUT, "/album/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "patch" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PATCH, "/album/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "delete" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.DELETE, "/album/example-id", .{});
+ try response.expectStatus(.ok);
+}
diff --git a/src/app/views/albums/delete.zmpl b/src/app/views/albums/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/albums/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/albums/edit.zmpl b/src/app/views/albums/edit.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/albums/edit.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/albums/get.zmpl b/src/app/views/albums/get.zmpl
index 3a1641b..8084038 100644
--- a/src/app/views/albums/get.zmpl
+++ b/src/app/views/albums/get.zmpl
@@ -1,8 +1,3 @@
-@zig {
- const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
- const columns: ColumnChoices = &.{.song, .scrobbles};
-}
-
@@ -10,6 +5,15 @@
@partial partials/header
{{.album}}
-@partial partials/newtable(T: ColumnChoices, table_data: .songs, columns: columns)
+
+
+Name
+@for (.songs) |song| {
+
+ {{song.name}}
+ {{song.scrobbles}}
+
+}
+
\ No newline at end of file
diff --git a/src/app/views/albums/index.zmpl b/src/app/views/albums/index.zmpl
index 43ff1de..e5536eb 100644
--- a/src/app/views/albums/index.zmpl
+++ b/src/app/views/albums/index.zmpl
@@ -1,15 +1,40 @@
-@zig {
- const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
- const columns: ColumnChoices = &.{.album, .artistlist, .scrobbles};
-}
-
+
@partial partials/header
Albums
-@partial partials/newtable(T: ColumnChoices, table_data: .albums, columns: columns)
+
+
+
+Name
+Artist(s)
+Scrobbles
+
+
+
+@for (.albums) |album| {
+
+ {{album.name}}
+
+ @for (album.get("artist_info").?) |ai| {
+ {{ai.name}}
+ }
+
+ {{album.scrobbles}}
+
+}
+
+
+
+
\ No newline at end of file
diff --git a/src/app/views/albums/new.zmpl b/src/app/views/albums/new.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/albums/new.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/albums/patch.zmpl b/src/app/views/albums/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/albums/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/albums/post.zmpl b/src/app/views/albums/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/albums/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/albums/put.zmpl b/src/app/views/albums/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/albums/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/artists.zig b/src/app/views/artists.zig
index 34cea3e..728ee2c 100644
--- a/src/app/views/artists.zig
+++ b/src/app/views/artists.zig
@@ -138,25 +138,113 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
defer first_last_songs_jq_result.deinit();
// These look backwards, but it's correct this way
- var last_song_view = try root.put("last", .object);
-
if (try first_last_songs_jq_result.postgresql.result.next()) |last_song_row| {
const last_song = try last_song_row.to(ScrobbleResult, .{ .dupe = true, .allocator = request.allocator });
- try last_song_view.put("name", last_song.name);
- try last_song_view.put("id", last_song.id);
- try last_song_view.put("date", (try dateFmt(request.allocator, last_song.date)));
- } else unreachable;
-
- var first_song_view = try root.put("first", .object);
+ try root.put("last_song_name", last_song.name);
+ try root.put("last_song_id", last_song.id);
+ try root.put("last_song_date", (try dateFmt(request.allocator, last_song.date)));
+ }
if (try first_last_songs_jq_result.postgresql.result.next()) |first_song_row| {
const first_song = try first_song_row.to(ScrobbleResult, .{ .dupe = true, .allocator = request.allocator });
- try first_song_view.put("name", first_song.name);
- try first_song_view.put("id", first_song.id);
- try first_song_view.put("date", (try dateFmt(request.allocator, first_song.date)));
- } else unreachable;
+ try root.put("first_song_name", first_song.name);
+ try root.put("first_song_id", first_song.id);
+ try root.put("first_song_date", (try dateFmt(request.allocator, first_song.date)));
+ }
try first_last_songs_jq_result.drain();
return request.render(.ok);
}
+
+pub fn new(request: *jetzig.Request) !jetzig.View {
+ return request.render(.ok);
+}
+
+pub fn edit(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn post(request: *jetzig.Request) !jetzig.View {
+ return request.render(.created);
+}
+
+pub fn put(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn patch(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn delete(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+test "index" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/artist", .{});
+ try response.expectStatus(.ok);
+}
+
+test "get" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/artist/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "new" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/artist/new", .{});
+ try response.expectStatus(.ok);
+}
+
+test "edit" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/artist/example-id/edit", .{});
+ try response.expectStatus(.ok);
+}
+
+test "post" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.POST, "/artist", .{});
+ try response.expectStatus(.created);
+}
+
+test "put" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PUT, "/artist/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "patch" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PATCH, "/artist/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "delete" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.DELETE, "/artist/example-id", .{});
+ try response.expectStatus(.ok);
+}
diff --git a/src/app/views/artists/delete.zmpl b/src/app/views/artists/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/artists/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/artists/edit.zmpl b/src/app/views/artists/edit.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/artists/edit.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/artists/get.zmpl b/src/app/views/artists/get.zmpl
index 48c1c25..adf6158 100644
--- a/src/app/views/artists/get.zmpl
+++ b/src/app/views/artists/get.zmpl
@@ -1,22 +1,53 @@
-@zig {
- const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
- const columns: ColumnChoices = &.{.album, .scrobbles};
-}
-
+
@partial partials/header
{{.artist.name}}
-@partial partials/firstlast_listens(scrobbles: .artist.scrobbles, rank: .artist.rank, last_song: .last, first_song: .first)
-
+{{.artist.scrobbles}} scrobbles ({{.artist.rank}} place)
+
+First listen: {{.first_song_name}} ({{.first_song_date}})
+
+Most recent listen: {{.last_song_name}} ({{.last_song_date}})
Albums
-@partial partials/newtable(T: ColumnChoices, table_data: .albums, columns: columns)
-
+
+
+
+Name Scrobbles
+
+
+
+@for (.albums) |album| {
+
+ {{album.name}}
+ {{album.scrobbles}}
+
+}
+
+
Albums Featured On
-@partial partials/newtable(T: ColumnChoices, table_data: .appears, columns: columns)
-
+
+
+
+ Name Scrobbles
+
+
+
+ @for (.appears) |album| {
+
+ {{album.name}}
+ {{album.scrobbles}}
+
+ }
+
+
+
+
\ No newline at end of file
diff --git a/src/app/views/artists/new.zmpl b/src/app/views/artists/new.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/artists/new.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/artists/patch.zmpl b/src/app/views/artists/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/artists/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/artists/post.zmpl b/src/app/views/artists/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/artists/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/artists/put.zmpl b/src/app/views/artists/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/artists/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/collection.zig b/src/app/views/collection.zig
index 1b0b502..8125efd 100644
--- a/src/app/views/collection.zig
+++ b/src/app/views/collection.zig
@@ -11,3 +11,26 @@ pub fn get(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig
_ = 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/collection/delete.zmpl b/src/app/views/collection/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/collection/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/collection/patch.zmpl b/src/app/views/collection/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/collection/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/collection/post.zmpl b/src/app/views/collection/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/collection/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/collection/put.zmpl b/src/app/views/collection/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/collection/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/concerts.zig b/src/app/views/concerts.zig
index 1b0b502..8125efd 100644
--- a/src/app/views/concerts.zig
+++ b/src/app/views/concerts.zig
@@ -11,3 +11,26 @@ pub fn get(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig
_ = 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/concerts/delete.zmpl b/src/app/views/concerts/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/concerts/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/concerts/patch.zmpl b/src/app/views/concerts/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/concerts/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/concerts/post.zmpl b/src/app/views/concerts/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/concerts/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/concerts/put.zmpl b/src/app/views/concerts/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/concerts/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/lists.zig b/src/app/views/lists.zig
index aecf0dc..8125efd 100644
--- a/src/app/views/lists.zig
+++ b/src/app/views/lists.zig
@@ -16,3 +16,21 @@ 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/lists/delete.zmpl b/src/app/views/lists/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/lists/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/lists/patch.zmpl b/src/app/views/lists/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/lists/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/lists/put.zmpl b/src/app/views/lists/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/lists/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/partials/_firstlast_listens.zmpl b/src/app/views/partials/_firstlast_listens.zmpl
deleted file mode 100644
index 322a0e8..0000000
--- a/src/app/views/partials/_firstlast_listens.zmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-@args scrobbles: i64, rank: []const u8, last_song: *ZmplValue, first_song: *ZmplValue
-
-
\ No newline at end of file
diff --git a/src/app/views/partials/_history.zmpl b/src/app/views/partials/_history.zmpl
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/views/partials/_newtable.zmpl b/src/app/views/partials/_newtable.zmpl
deleted file mode 100644
index 8960e21..0000000
--- a/src/app/views/partials/_newtable.zmpl
+++ /dev/null
@@ -1,69 +0,0 @@
-@args T: type, table_data: *ZmplValue, columns: T
-
-
-
-
-@zig {
- for (columns) |header| {
- switch (header) {
- .song => {
- Song
- },
- .album => {
- Album
- },
- .artist => {
- Artist
- },
- .artistlist => {
- Artist(s)
- },
- .scrobbles => {
- Scrobbles
- },
- .date => {
- Date
- }
- }
- }
-}
-
-
-
-@zig {
- const array = table_data.items(.array);
- for (array) |ent| {
-
- for (columns) |header| {
- switch (header) {
- .song, .album, .artist => {
- const path = switch (header) {
- .song => "songs",
- .album => "albums",
- .artist => "artists",
- else => unreachable
- };
-
- {{ent.name}}
-
- },
- .artistlist => {
-
- @for (ent.get("artist_info").?) |artist| {
- {{artist.name}}
- }
-
- },
- .scrobbles => {
- {{ent.scrobbles}}
- },
- .date =>{
- {{ent.date}}
- }
- }
- }
-
- }
-}
-
-
\ No newline at end of file
diff --git a/src/app/views/partials/_random.zmpl b/src/app/views/partials/_random.zmpl
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/views/partials/_recent.zmpl b/src/app/views/partials/_recent.zmpl
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/views/ratings.zig b/src/app/views/ratings.zig
index aecf0dc..8125efd 100644
--- a/src/app/views/ratings.zig
+++ b/src/app/views/ratings.zig
@@ -16,3 +16,21 @@ 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/ratings/delete.zmpl b/src/app/views/ratings/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/ratings/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/ratings/patch.zmpl b/src/app/views/ratings/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/ratings/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/ratings/put.zmpl b/src/app/views/ratings/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/ratings/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/rules.zig b/src/app/views/rules.zig
index eb85a72..7a2df91 100644
--- a/src/app/views/rules.zig
+++ b/src/app/views/rules.zig
@@ -4,6 +4,21 @@ const jetzig = @import("jetzig");
pub fn index(request: *jetzig.Request) !jetzig.View {
return request.render(.ok);
}
+
+pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn new(request: *jetzig.Request) !jetzig.View {
+ return request.render(.ok);
+}
+
+pub fn edit(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
pub fn post(request: *jetzig.Request) !jetzig.View {
const params = try request.params();
@@ -39,3 +54,82 @@ pub fn post(request: *jetzig.Request) !jetzig.View {
return request.render(.created);
}
+
+pub fn put(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn patch(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn delete(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+test "index" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/rules", .{});
+ try response.expectStatus(.ok);
+}
+
+test "get" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/rules/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "new" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/rules/new", .{});
+ try response.expectStatus(.ok);
+}
+
+test "edit" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/rules/example-id/edit", .{});
+ try response.expectStatus(.ok);
+}
+
+test "post" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.POST, "/rules", .{});
+ try response.expectStatus(.created);
+}
+
+test "put" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PUT, "/rules/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "patch" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PATCH, "/rules/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "delete" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.DELETE, "/rules/example-id", .{});
+ try response.expectStatus(.ok);
+}
diff --git a/src/app/views/rules/delete.zmpl b/src/app/views/rules/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/rules/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/rules/edit.zmpl b/src/app/views/rules/edit.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/rules/edit.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/rules/get.zmpl b/src/app/views/rules/get.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/rules/get.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/rules/new.zmpl b/src/app/views/rules/new.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/rules/new.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/rules/patch.zmpl b/src/app/views/rules/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/rules/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/rules/put.zmpl b/src/app/views/rules/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/rules/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/scrobbles.zig b/src/app/views/scrobbles.zig
index 1386a83..6ee80d8 100644
--- a/src/app/views/scrobbles.zig
+++ b/src/app/views/scrobbles.zig
@@ -55,3 +55,32 @@ pub fn index(request: *jetzig.Request) !jetzig.View {
return request.render(.ok);
}
+
+pub fn get(id: []const u8, request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
+ _ = id;
+ _ = data;
+ 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/scrobbles/delete.zmpl b/src/app/views/scrobbles/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/scrobbles/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/scrobbles/get.zmpl b/src/app/views/scrobbles/get.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/scrobbles/get.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/scrobbles/patch.zmpl b/src/app/views/scrobbles/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/scrobbles/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/scrobbles/post.zmpl b/src/app/views/scrobbles/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/scrobbles/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/scrobbles/put.zmpl b/src/app/views/scrobbles/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/scrobbles/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search.zig b/src/app/views/search.zig
new file mode 100644
index 0000000..be5f7e0
--- /dev/null
+++ b/src/app/views/search.zig
@@ -0,0 +1,104 @@
+const std = @import("std");
+const jetzig = @import("jetzig");
+
+pub fn index(request: *jetzig.Request) !jetzig.View {
+ return request.render(.ok);
+}
+
+pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn new(request: *jetzig.Request) !jetzig.View {
+ return request.render(.ok);
+}
+
+pub fn edit(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn post(request: *jetzig.Request) !jetzig.View {
+ return request.render(.created);
+}
+
+pub fn put(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn patch(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn delete(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+
+test "index" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/search", .{});
+ try response.expectStatus(.ok);
+}
+
+test "get" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/search/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "new" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/search/new", .{});
+ try response.expectStatus(.ok);
+}
+
+test "edit" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/search/example-id/edit", .{});
+ try response.expectStatus(.ok);
+}
+
+test "post" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.POST, "/search", .{});
+ try response.expectStatus(.created);
+}
+
+test "put" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PUT, "/search/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "patch" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PATCH, "/search/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "delete" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.DELETE, "/search/example-id", .{});
+ try response.expectStatus(.ok);
+}
diff --git a/src/app/views/search/delete.zmpl b/src/app/views/search/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/edit.zmpl b/src/app/views/search/edit.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/edit.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/get.zmpl b/src/app/views/search/get.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/get.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/index.zmpl b/src/app/views/search/index.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/index.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/new.zmpl b/src/app/views/search/new.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/new.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/patch.zmpl b/src/app/views/search/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/post.zmpl b/src/app/views/search/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/search/put.zmpl b/src/app/views/search/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/search/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/songs.zig b/src/app/views/songs.zig
index cd220f8..19711d1 100644
--- a/src/app/views/songs.zig
+++ b/src/app/views/songs.zig
@@ -4,6 +4,12 @@ const jetzig = @import("jetzig");
pub fn index(request: *jetzig.Request) !jetzig.View {
var root = try request.data(.object);
var songs_view = try root.put("songs", .array);
+ //const songs = try jetzig.database.Query(.Song)
+ // .select(.{ .id, .name })
+ // .include(.songartists, .{ .select = .{.artist_id} })
+ // .include(.scrobbles, .{ .select = .{.id} })
+ // .orderBy(.{ .name = .asc })
+ // .all(request.repo);
const query =
\\SELECT songs.name, songs.id, artists.name, artists.id, COUNT(scrobbles) AS scrobbles
@@ -46,6 +52,24 @@ pub fn index(request: *jetzig.Request) !jetzig.View {
prev_artist_infos = artist_infos;
prev_song_id = song.id;
}
+
+ //for (songs) |song| {
+ // var song_view = try songs_view.append(.object);
+
+ // var artist_infos = try song_view.put("artist_info", .array);
+ // for (song.songartists) |artist| {
+ // var artist_info = try artist_infos.append(.object);
+ // const artist_data = try jetzig.database.Query(.Artist)
+ // .find(artist.artist_id)
+ // .select(.{ .id, .name })
+ // .execute(request.repo);
+ // try artist_info.put("name", artist_data.?.name);
+ // try artist_info.put("id", artist_data.?.id);
+ // }
+ // try song_view.put("name", song.name);
+ // try song_view.put("url", song.id);
+ // try song_view.put("scrobbles", (song.scrobbles).len);
+ //}
return request.render(.ok);
}
@@ -53,3 +77,95 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
_ = id;
return request.render(.ok);
}
+
+pub fn new(request: *jetzig.Request) !jetzig.View {
+ return request.render(.ok);
+}
+
+pub fn edit(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn post(request: *jetzig.Request) !jetzig.View {
+ return request.render(.created);
+}
+
+pub fn put(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn patch(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+pub fn delete(id: []const u8, request: *jetzig.Request) !jetzig.View {
+ _ = id;
+ return request.render(.ok);
+}
+
+test "index" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/song", .{});
+ try response.expectStatus(.ok);
+}
+
+test "get" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/song/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "new" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/song/new", .{});
+ try response.expectStatus(.ok);
+}
+
+test "edit" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.GET, "/song/example-id/edit", .{});
+ try response.expectStatus(.ok);
+}
+
+test "post" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.POST, "/song", .{});
+ try response.expectStatus(.created);
+}
+
+test "put" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PUT, "/song/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "patch" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.PATCH, "/song/example-id", .{});
+ try response.expectStatus(.ok);
+}
+
+test "delete" {
+ var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
+ defer app.deinit();
+
+ const response = try app.request(.DELETE, "/song/example-id", .{});
+ try response.expectStatus(.ok);
+}
diff --git a/src/app/views/songs/delete.zmpl b/src/app/views/songs/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/songs/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/songs/edit.zmpl b/src/app/views/songs/edit.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/songs/edit.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/songs/new.zmpl b/src/app/views/songs/new.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/songs/new.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/songs/patch.zmpl b/src/app/views/songs/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/songs/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/songs/post.zmpl b/src/app/views/songs/post.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/songs/post.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/songs/put.zmpl b/src/app/views/songs/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/songs/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/upload.zig b/src/app/views/upload.zig
index 5f47cc4..59442a8 100644
--- a/src/app/views/upload.zig
+++ b/src/app/views/upload.zig
@@ -10,6 +10,12 @@ pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
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) !jetzig.View {
var root = try request.data(.object);
@@ -160,3 +166,21 @@ pub fn post(request: *jetzig.Request) !jetzig.View {
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/upload/delete.zmpl b/src/app/views/upload/delete.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/upload/delete.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/upload/get.zmpl b/src/app/views/upload/get.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/upload/get.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/upload/patch.zmpl b/src/app/views/upload/patch.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/upload/patch.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/app/views/upload/put.zmpl b/src/app/views/upload/put.zmpl
new file mode 100644
index 0000000..76457d0
--- /dev/null
+++ b/src/app/views/upload/put.zmpl
@@ -0,0 +1,3 @@
+
+ Content goes here
+
diff --git a/src/types.zig b/src/types.zig
index 455f282..704adc0 100644
--- a/src/types.zig
+++ b/src/types.zig
@@ -61,14 +61,3 @@ pub const Rule = struct {
pub const Rules = struct {
rules: []const Rule,
};
-
-// Can't import types in .zmpl files, so defining this here
-// doesn't really do much (except maybe in the .zig file for views?)
-//pub const HeaderTypes = []enum {
-// song,
-// album,
-// artist,
-// artistlist,
-// scrobbles,
-// date,
-//};