diff --git a/.gitignore b/.gitignore index 1b3afe7..9f6d7b4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ zig-cache/ *.core static/ .jetzig -src/app/database/ \ No newline at end of file +src/app/database/data.db-journal \ No newline at end of file diff --git a/build.zig b/build.zig index e488390..88fed1c 100644 --- a/build.zig +++ b/build.zig @@ -15,7 +15,7 @@ pub fn build(b: *std.Build) !void { // Example dependency: const iguanas_dep = b.dependency("iguanas", .{ .optimize = optimize, .target = target }); exe.root_module.addImport("iguanas", iguanas_dep.module("iguanas")); - + const sqlite = b.dependency("sqlite", .{ .target = target, .optimize = optimize, @@ -28,7 +28,7 @@ pub fn build(b: *std.Build) !void { // All dependencies **must** be added to imports above this line. - try jetzig.jetzigInit(b, exe, .{.zmpl_version = .v2}); + try jetzig.jetzigInit(b, exe, .{ .zmpl_version = .v2 }); b.installArtifact(exe); diff --git a/build.zig.zon b/build.zig.zon index 578092d..ff7ee12 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -14,20 +14,16 @@ // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. // Once all dependencies are fetched, `zig build` no longer requires // internet connectivity. - .dependencies = .{ - .jetzig = .{ - .url = "https://github.com/jetzig-framework/jetzig/archive/68ca4d3bbad05880e6e38fc6d10e7a24e772081e.tar.gz", - .hash = "122047ebabab1dfe1bb7f96ffdac98410ffb4850b06dc6b1670ce74aaeaa49bdc08e", - }, - .iguanas = .{ - .url = "https://github.com/jetzig-framework/iguanas/archive/89c2abf29de0bc31054a9a6feac5a6a83bab0459.tar.gz", - .hash = "12202fd319a5ab4e124b00e8ddea474d07c19c4e005d77b6c29fc44860904ea01a5c", - }, - .sqlite = .{ - .url = "https://github.com/vrischmann/zig-sqlite/archive/6af21bb.tar.gz", - .hash = "12202799861d92c7880d1a74f95be099752d7f0420a0c9628dc923ca2b1a22b7bda8", - } - }, + .dependencies = .{ .jetzig = .{ + .url = "https://github.com/jetzig-framework/jetzig/archive/88abe2243d87b28ad110c5fe9fe90b716a6c6583.tar.gz", + .hash = "12200d15cef72d4c37a01c930db53c3ffafdc05142462afddeab818701a0291327d1", + }, .iguanas = .{ + .url = "https://github.com/jetzig-framework/iguanas/archive/89c2abf29de0bc31054a9a6feac5a6a83bab0459.tar.gz", + .hash = "12202fd319a5ab4e124b00e8ddea474d07c19c4e005d77b6c29fc44860904ea01a5c", + }, .sqlite = .{ + .url = "https://github.com/vrischmann/zig-sqlite/archive/6af21bb.tar.gz", + .hash = "12202799861d92c7880d1a74f95be099752d7f0420a0c9628dc923ca2b1a22b7bda8", + } }, .paths = .{ // This makes *all* files, recursively, included in this package. It is generally // better to explicitly list the files and directories instead, to insure that diff --git a/public/styles.css b/public/styles.css index 1755d47..afdbce9 100644 --- a/public/styles.css +++ b/public/styles.css @@ -3,8 +3,23 @@ * * */ + @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); -.message { - font-weight: bold; +.title { + font-family: 'Roboto'; font-size: 3rem; + font-weight: 500; + margin-left: 20px; + margin-right: 40px; + margin-top: 20px; +} + +.header-link{ + font-family: 'Roboto'; + font-size: 1.5rem; + margin-right: 20px; +} + +#replaceMe{ + font-family:'Courier New'; } diff --git a/src/app/database/data.db b/src/app/database/data.db new file mode 100644 index 0000000..fa37ab7 Binary files /dev/null and b/src/app/database/data.db differ diff --git a/src/app/lib/db.zig b/src/app/lib/db.zig new file mode 100644 index 0000000..dd6f7bf --- /dev/null +++ b/src/app/lib/db.zig @@ -0,0 +1,22 @@ +pub const addArtist = \\INSERT INTO artists ('artist', 'plays', 'url') VALUES (?,?) +; + +pub const addTrack = \\INSERT INTO tracks ('artist', 'track', 'album', 'plays', 'url') VALUES (?,?,?,?) +; + +pub const getArtist = \\SELECT artist, plays FROM artists WHERE artist == ? +; + +pub const getTrack = \\SELECT artist, track, album, plays FROM tracks WHERE track == ? +; + +pub const getTrackSearch = \\SELECT track, url, form FROM tracks WHERE track LIKE '%' || ? || '%' +; + +pub const getArtistSearch = \\SELECT artist, url, form FROM artists WHERE artist LIKE '%' || ? || '%' +; + +pub const getAlbumSearch = \\SELECT album, url, form FROM albums WHERE album LIKE '%' || ? || '%' +; + +pub const total_search = getArtistSearch ++ " UNION " ++ getAlbumSearch ++ " UNION " ++ getTrackSearch; \ No newline at end of file diff --git a/src/app/views/root.zig b/src/app/views/root.zig index 0fa146c..d567fc5 100644 --- a/src/app/views/root.zig +++ b/src/app/views/root.zig @@ -1,3 +1,4 @@ +const std = @import("std"); const jetzig = @import("jetzig"); /// `src/app/views/root.zig` represents the root URL `/` @@ -18,7 +19,7 @@ pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { var root = try data.object(); // Add a string to the root object. - try root.put("message", data.string("Welcome to Jetzig!")); + try root.put("welcome_message", data.string("Welcome to Jetzig!")); // Request params have the same type as a `data.object()` so they can be inserted them // directly into the response data. Fetch `http://localhost:8080/?message=hello` to set the @@ -26,9 +27,7 @@ pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { // present. const params = try request.params(); - if (params.get("message")) |value| { - try root.put("message_param", value); - } + try root.put("message_param", params.get("message")); // Set arbitrary response headers as required. `content-type` is automatically assigned for // HTML, JSON responses. diff --git a/src/app/views/root/_content.zmpl b/src/app/views/root/_content.zmpl deleted file mode 100644 index 088ab6b..0000000 --- a/src/app/views/root/_content.zmpl +++ /dev/null @@ -1,20 +0,0 @@ - -

{.message}

- -
- -
- - - - -
- -
Visit jetzig.dev to get started. -
Join our Discord server and introduce yourself:
-
- Search for an artist, album, or song: - - -
-
diff --git a/src/db.zig b/src/app/views/root/_graph.zmpl similarity index 100% rename from src/db.zig rename to src/app/views/root/_graph.zmpl diff --git a/src/app/views/root/_header.zmpl b/src/app/views/root/_header.zmpl new file mode 100644 index 0000000..3362c8f --- /dev/null +++ b/src/app/views/root/_header.zmpl @@ -0,0 +1,6 @@ +Zuletzt +Artists +Albums +Tracks +Stats +
\ No newline at end of file diff --git a/src/app/views/root/_history.zmpl b/src/app/views/root/_history.zmpl new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/root/_random.zmpl b/src/app/views/root/_random.zmpl new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/root/_recent.zmpl b/src/app/views/root/_recent.zmpl new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/root/_top.zmpl b/src/app/views/root/_top.zmpl new file mode 100644 index 0000000..3440698 --- /dev/null +++ b/src/app/views/root/_top.zmpl @@ -0,0 +1,26 @@ +
+
+Top: +Artist +Album +Track +
+ +
+of: +Day +Week +Month +3 Months +6 Months +Current Year +365 days +All Time +
+ + + +hyello + + +
diff --git a/src/app/views/root/index.zmpl b/src/app/views/root/index.zmpl index 9473e7a..ea52da6 100644 --- a/src/app/views/root/index.zmpl +++ b/src/app/views/root/index.zmpl @@ -8,15 +8,7 @@ -
- -

{.message_param}

- - -
- @partial root/content -
-
+ @partial root/header + @partial root/top diff --git a/src/app/views/search.zig b/src/app/views/search.zig new file mode 100644 index 0000000..46d1592 --- /dev/null +++ b/src/app/views/search.zig @@ -0,0 +1,52 @@ +const std = @import("std"); +const jetzig = @import("jetzig"); +const queries = @import("../lib/db.zig"); +const sqlite = @import("sqlite"); + +pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + var root = try data.array(); + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + var arena = std.heap.ArenaAllocator.init(allocator); + defer arena.deinit(); + var db = try sqlite.Db.init(.{ + .mode = sqlite.Db.Mode{ .File = "/home/swebb/Source/zuletzt/src/app/database/data.db" }, + .open_flags = .{ + .write = true, + .create = true, + }, + .threading_mode = .MultiThread, + }); + const params = try request.params(); + const queryOrNull: ?[]const u8 = if (params.get("q")) |param| param.string.value else null; + if (queryOrNull) |query| { + // sql.search(query, db); + var artistSearch = try db.prepare(queries.total_search); + defer artistSearch.deinit(); + + const artistResults = try artistSearch.all( + struct { + artist: []u8, + url: []u8, + form: []u8, + }, + arena.allocator(), + .{}, + .{ .artist = query, .album = query, .track = query }, + ); + + for (artistResults) |r| { + std.log.debug("artist: {s}, url: {s}", .{ r.artist, r.url }); + try root.append(data.string(r.artist)); + try root.append(data.string(r.url)); + try root.append(data.string(r.form)); + //std.log.debug("{s}", .{r}); + } + } else { + return request.render(.bad_request); + } + //const query = params.get("q"); + //try root.put("q",query); + //try root.put("q", data.string("Welcome")); + return request.render(.ok); +} diff --git a/src/app/views/search/index.zmpl b/src/app/views/search/index.zmpl new file mode 100644 index 0000000..4101944 --- /dev/null +++ b/src/app/views/search/index.zmpl @@ -0,0 +1,16 @@ + + + + + + + @zig { + for (zmpl.items(.array), 0..) |u,i| { + if(@mod(i,3)==0){ + + + + } + } + } +
ArtistAlbumTrack
{{u}}
\ No newline at end of file diff --git a/src/app/views/stats.zig b/src/app/views/stats.zig new file mode 100644 index 0000000..4fac587 --- /dev/null +++ b/src/app/views/stats.zig @@ -0,0 +1,7 @@ +const std = @import("std"); +const jetzig = @import("jetzig"); + +pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { + _ = data; + return request.render(.ok); +} diff --git a/src/app/views/stats/index.zmpl b/src/app/views/stats/index.zmpl new file mode 100644 index 0000000..76457d0 --- /dev/null +++ b/src/app/views/stats/index.zmpl @@ -0,0 +1,3 @@ +
+ Content goes here +
diff --git a/src/main.zig b/src/main.zig index 9d5b43a..fea50c2 100644 --- a/src/main.zig +++ b/src/main.zig @@ -87,35 +87,35 @@ pub const jetzig_options = struct { }; pub fn main() !void { - var db = try sqlite.Db.init(.{ - .mode = sqlite.Db.Mode{ .File = "/home/swebb/Source/zuletzt/src/app/database/data.db" }, - .open_flags = .{ - .write = true, - .create = true, - }, - .threading_mode = .MultiThread, - }); + //var db = try sqlite.Db.init(.{ + // .mode = sqlite.Db.Mode{ .File = "/home/swebb/Source/zuletzt/src/app/database/data.db" }, + // .open_flags = .{ + // .write = true, + // .create = true, + // }, + // .threading_mode = .MultiThread, + //}); //const create = // \\CREATE TABLE artists ('artist', 'plays') //; - const query = - \\INSERT INTO artists ('artist', 'plays') VALUES (?,?) - ; + //const query = + // \\INSERT INTO artists ('artist', 'plays') VALUES (?,?) + //; //var build = try db.prepare(create); //defer build.deinit(); //try build.exec(.{},.{}); - var stmt = try db.prepare(query); - defer stmt.deinit(); + //var stmt = try db.prepare(query); + //defer stmt.deinit(); - try stmt.exec(.{}, .{ - .artist = "Wilco", - .plays = 2500, - }); + //try stmt.exec(.{}, .{ + // .artist = "Wilco", + // .plays = 2500, + //}); var gpa = std.heap.GeneralPurposeAllocator(.{}){};