Begin Spotify uploading
This commit is contained in:
parent
7957345057
commit
e2ff66ea50
4 changed files with 36 additions and 21 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const jetzig = @import("jetzig");
|
const jetzig = @import("jetzig");
|
||||||
const jetquery = @import("jetzig").jetquery;
|
const jetquery = @import("jetzig").jetquery;
|
||||||
const Scrobble = @import("../../types.zig").SafeLastFMScrobble;
|
const Scrobble = @import("../../types.zig").LastFMScrobble;
|
||||||
const lastfm = @import("../../types.zig").LastFM;
|
const lastfm = @import("../../types.zig").LastFM;
|
||||||
|
|
||||||
// The `run` function for a job is invoked every time the job is processed by a queue worker
|
// The `run` function for a job is invoked every time the job is processed by a queue worker
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const jetzig = @import("jetzig");
|
const jetzig = @import("jetzig");
|
||||||
const jetquery = @import("jetzig").jetquery;
|
const jetquery = @import("jetzig").jetquery;
|
||||||
const Scrobble = @import("../../types.zig").LastFMScrobble;
|
//const Scrobble = @import("../../types.zig").LastFMScrobble;
|
||||||
const lastfm = @import("../../types.zig").LastFM;
|
//const lastfm = @import("../../types.zig").LastFM;
|
||||||
|
//const UploadData = @import("../../types").UploadData;
|
||||||
|
const ScrobbleTypes = @import("../../types.zig");
|
||||||
const zeit = @import("zeit");
|
const zeit = @import("zeit");
|
||||||
|
|
||||||
pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
|
||||||
|
|
@ -20,26 +22,36 @@ pub fn post(request: *jetzig.Request) !jetzig.View {
|
||||||
var root = try request.data(.object);
|
var root = try request.data(.object);
|
||||||
|
|
||||||
if (try request.file("upload")) |file| {
|
if (try request.file("upload")) |file| {
|
||||||
//std.debug.print("{s}", .{file.content});
|
const params = try request.params();
|
||||||
const content = try std.json.parseFromSliceLeaky(lastfm, request.allocator, file.content, .{ .ignore_unknown_fields = true });
|
|
||||||
|
var content: ScrobbleTypes.UploadData = undefined;
|
||||||
|
|
||||||
|
const source = std.fmt.parseInt(u8, params.get("t").string.value, 10).?;
|
||||||
|
//if (params.get("t")) |param| {
|
||||||
|
// const source = std.fmt.parseInt(u8, param.string.value, 10);
|
||||||
|
switch (source) {
|
||||||
|
0 => content = try std.json.parseFromSliceLeaky(ScrobbleTypes.LastFM, request.allocator, file.content, .{}),
|
||||||
|
1 => content = try std.json.parseFromSliceLeaky(ScrobbleTypes.Spotify, request.allocator, file.content, .{}),
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
|
||||||
|
//const content = try std.json.parseFromSliceLeaky(lastfm, request.allocator, file.content, .{ .ignore_unknown_fields = true });
|
||||||
|
|
||||||
var scrobbles_view = try root.put("scrobbles", .array);
|
var scrobbles_view = try root.put("scrobbles", .array);
|
||||||
|
|
||||||
var job = try request.job("process_scrobbles");
|
var job = try request.job("process_scrobbles");
|
||||||
var scrobbles_data = try job.params.put("scrobbles", .array);
|
var scrobbles_data = try job.params.put("scrobbles", .array);
|
||||||
|
|
||||||
const params = try request.params();
|
|
||||||
const limiting_date_string: ?[]const u8 = if (params.get("l")) |param| param.string.value else null;
|
|
||||||
const limiting_date_instant: ?zeit.Instant = if (limiting_date_string) |str| try zeit.instant(.{ .source = .{ .iso8601 = str } }) else null;
|
|
||||||
// This is seconds from Unix epoch
|
// This is seconds from Unix epoch
|
||||||
const limiting_date_epoch = if (limiting_date_instant) |time| time.unixTimestamp() else 9_223_372_036_854_775_807;
|
const limiting_date = if (params.get("l")) |param| (try zeit.instant(.{ .source = .{ .iso8601 = param.string.value } })).unixTimestamp() else 9_223_372_036_854_775_807;
|
||||||
|
|
||||||
appends: for (content.scrobbles) |scrobble| {
|
appends: for (content.scrobbles) |scrobble| {
|
||||||
|
if (std.mem.eql(u8, @typeName(scrobble), "SpotifyScrobble")) scrobble = scrobble.scrobblize();
|
||||||
// Scrobble.date is in milliseconds from Unix epoch
|
// Scrobble.date is in milliseconds from Unix epoch
|
||||||
if (scrobble.date < limiting_date_epoch * 1000) continue :appends;
|
if (scrobble.date < limiting_date * 1000) continue :appends;
|
||||||
var value = try scrobbles_data.append(.object);
|
var value = try scrobbles_data.append(.object);
|
||||||
// This is so unnecessary, probably useful once I start doing Spotify integration though
|
// This is so unnecessary, probably useful once I start doing Spotify integration though
|
||||||
inline for (std.meta.fields(Scrobble)) |f| {
|
inline for (std.meta.fields(ScrobbleTypes.Scrobble)) |f| {
|
||||||
try value.put(f.name, @as(f.type, @field(scrobble, f.name)));
|
try value.put(f.name, @as(f.type, @field(scrobble, f.name)));
|
||||||
}
|
}
|
||||||
// Note sure why this works for ZMPL, but not for jobs.
|
// Note sure why this works for ZMPL, but not for jobs.
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
<input type="file" name="upload" />
|
<input type="file" name="upload" />
|
||||||
<input type="submit" value="Submit" />
|
<input type="submit" value="Submit" />
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<input type="radio" name="t" label="Last.fm">Last.fm</input>
|
<input type="radio" name="t" label="Last.fm" value="0">Last.fm</input>
|
||||||
<input type="radio" name="t" label="Spotify">Spotify</input>
|
<input type="radio" name="t" label="Spotify" value="1">Spotify</input>
|
||||||
Upload Scrobbles after: <input type="datetime-local" name="l" label="date"></input>
|
Upload Scrobbles after: <input type="datetime-local" name="l" label="date"></input>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
|
const zeit = @import("zeit");
|
||||||
|
|
||||||
pub const LastFMScrobble = struct {
|
pub const LastFMScrobble = struct {
|
||||||
track: []const u8,
|
track: []const u8,
|
||||||
artist: []const u8,
|
artist: []const u8,
|
||||||
album: ?[]const u8 = "",
|
album: []const u8 = "",
|
||||||
date: i128,
|
date: i128,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SafeLastFMScrobble = struct {
|
|
||||||
track: []const u8,
|
|
||||||
artist: []const u8,
|
|
||||||
album: []const u8,
|
|
||||||
date: u64,
|
|
||||||
};
|
|
||||||
|
|
||||||
// From lastfmstats.com
|
// From lastfmstats.com
|
||||||
pub const LastFM = struct { username: []const u8, scrobbles: []LastFMScrobble };
|
pub const LastFM = struct { username: []const u8, scrobbles: []LastFMScrobble };
|
||||||
|
|
||||||
|
|
@ -35,6 +30,14 @@ pub const SpotifyScrobble = struct {
|
||||||
offline: bool,
|
offline: bool,
|
||||||
offline_timestamp: u64,
|
offline_timestamp: u64,
|
||||||
incognito_mode: bool,
|
incognito_mode: bool,
|
||||||
|
|
||||||
|
pub fn scrobblize(self: *SpotifyScrobble) LastFMScrobble {
|
||||||
|
return LastFMScrobble{ .track = self.master_metadata_track_name, .artist = self.master_metadata_artist_name, .album = self.master_metadata_album_name, .date = try zeit.instant(.{ .source = .{ .iso8601 = self.ts } }).unixTimestamp() };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Spotify = struct { scrobbles: []SpotifyScrobble };
|
pub const Spotify = struct { scrobbles: []SpotifyScrobble };
|
||||||
|
|
||||||
|
const UploadDataTag = enum { spotify, lastfm };
|
||||||
|
|
||||||
|
pub const UploadData = union(UploadDataTag) { spotify: Spotify, lastfm: LastFM };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue