diff --git a/src/app/jobs/process_scrobbles.zig b/src/app/jobs/process_scrobbles.zig index 06d7365..4262fe5 100644 --- a/src/app/jobs/process_scrobbles.zig +++ b/src/app/jobs/process_scrobbles.zig @@ -18,17 +18,11 @@ const rules = @import("../../apply_rule.zig"); // - environment: Enum of `{ production, development }`. pub fn run(allocator: std.mem.Allocator, params: *jetzig.data.Value, env: jetzig.jobs.JobEnv) !void { //_ = env; - const file = try std.fs.cwd().openFile("rules.json", .{ .mode = .read_only }); - const file_content = try file.readToEndAlloc(allocator, 16_000_000); - - const rule_list = try std.json.parseFromSliceLeaky(Data.Rules, allocator, file_content, .{}); - + _ = allocator; if (params.getT(.array, "scrobbles")) |scrobbles| { for (scrobbles.items()) |item| { //const fixed_date: u32 = @as(u32, item.getT(.integer, "date").?); - const pre_scrobble: Scrobble = .{ .track = item.getT(.string, "track").?, .artist = item.getT(.string, "artist").?, .album = item.getT(.string, "album") orelse "", .date = @as(u64, @bitCast(@as(i64, @truncate(item.getT(.integer, "date").? * 1000)))) }; - - const scrobble = rules.applyScrobbleRule(pre_scrobble, rule_list); + const scrobble: Scrobble = .{ .track = item.getT(.string, "track").?, .artist = item.getT(.string, "artist").?, .album = item.getT(.string, "album") orelse "", .date = @as(u64, @bitCast(@as(i64, @truncate(item.getT(.integer, "date").? * 1000)))) }; // Make hashes //const album_hash = @as(i32, @bitCast(std.hash.Fnv1a_32.hash(scrobble.album))); diff --git a/src/app/views/rules/index.zmpl b/src/app/views/rules/index.zmpl index b9a1b17..ab55c96 100644 --- a/src/app/views/rules/index.zmpl +++ b/src/app/views/rules/index.zmpl @@ -16,7 +16,7 @@ If + + + + @@ -87,7 +91,7 @@ then with diff --git a/src/app/views/upload.zig b/src/app/views/upload.zig index 53f3b27..032da9d 100644 --- a/src/app/views/upload.zig +++ b/src/app/views/upload.zig @@ -3,6 +3,8 @@ const jetzig = @import("jetzig"); const jetquery = @import("jetzig").jetquery; const ScrobbleTypes = @import("../../types.zig"); const zeit = @import("zeit"); +const rules = @import("../../apply_rule.zig"); +const Data = @import("../../types.zig"); pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View { _ = data; @@ -31,6 +33,11 @@ pub fn post(request: *jetzig.Request) !jetzig.View { var skipped_tracks: u64 = 0; var limited_tracks: u64 = 0; + const rule_file = try std.fs.cwd().openFile("rules.json", .{ .mode = .read_only }); + defer rule_file.close(); + const file_content = try rule_file.readToEndAlloc(request.allocator, 16_000_000); + const rule_list = try std.json.parseFromSliceLeaky(Data.Rules, request.allocator, file_content, .{}); + // The only difference between a LastFM scrobble and a Spotify scrobble is the format. // I've made a branches for each, because doing it all in one made the readability terrible, // and formatting the date in particular was challenging. I could probably pull out the @@ -46,12 +53,14 @@ pub fn post(request: *jetzig.Request) !jetzig.View { if ((before_limiter or after_limiter) and (scrobble.date > before_limiting_date or scrobble.date < after_limiting_date)) continue :appends; var value = try scrobbles_data.append(.object); + const formatted_scrobble = rules.applyScrobbleRule(scrobble, rule_list); + // This is so unnecessary, probably useful once I start doing Spotify integration though inline for (std.meta.fields(ScrobbleTypes.LastFMScrobble)) |f| { - try value.put(f.name, @as(f.type, @field(scrobble, f.name))); + try value.put(f.name, @as(f.type, @field(formatted_scrobble, f.name))); } // Note sure why this works for ZMPL, but not for jobs. - try scrobbles_view.append(scrobble); + try scrobbles_view.append(formatted_scrobble); } }, 1 => { @@ -88,7 +97,9 @@ pub fn post(request: *jetzig.Request) !jetzig.View { } // Turn SpotifyScrobble into a LastFM scrobble - const formatted_scrobble: ScrobbleTypes.LastFMScrobble = .{ .track = scrobble.master_metadata_track_name.?, .album = scrobble.master_metadata_album_album_name.?, .artist = scrobble.master_metadata_album_artist_name.?, .date = (try zeit.instant(.{ .source = .{ .iso8601 = scrobble.ts } })).unixTimestamp() * 1000 }; + const pre_formatted_scrobble: ScrobbleTypes.LastFMScrobble = .{ .track = scrobble.master_metadata_track_name.?, .album = scrobble.master_metadata_album_album_name.?, .artist = scrobble.master_metadata_album_artist_name.?, .date = (try zeit.instant(.{ .source = .{ .iso8601 = scrobble.ts } })).unixTimestamp() * 1000 }; + + const formatted_scrobble = rules.applyScrobbleRule(pre_formatted_scrobble, rule_list); var value = try scrobbles_data.append(.object); diff --git a/src/apply_rule.zig b/src/apply_rule.zig index 769d062..92d7598 100644 --- a/src/apply_rule.zig +++ b/src/apply_rule.zig @@ -12,7 +12,7 @@ pub fn applyScrobbleRule(scrobble: Scrobble, rules: Rules) Scrobble { inline else => |on| match_found = match_found and std.mem.eql(u8, @field(scrobble, @tagName(on)), cond.match_txt), }, .contains => switch (cond.match_on) { - inline else => |on| match_found = match_found and (std.mem.count(u8, @field(scrobble, @tagName(on)), cond.match_txt) > 0), + inline else => |on| match_found = match_found and std.mem.containsAtLeast(u8, @field(scrobble, @tagName(on)), 1, cond.match_txt), }, } }