The birthday paradox is a real problem with the size of our datasets. i64 is the largest numerical value we can use, and there's a 0.1% chance of collision with ~2,000,000 values, so I feel pretty comfortable with this
137 lines
3.4 KiB
Zig
137 lines
3.4 KiB
Zig
pub const ImportedScrobbles = union(ScrobbleSources) {
|
|
LastFMStats: []IgnorantScrobble,
|
|
LastFMWeb: []LastFMWebScrobble,
|
|
Spotify: []SpotifyScrobble,
|
|
};
|
|
|
|
const ScrobbleSources = enum {
|
|
LastFMStats,
|
|
LastFMWeb,
|
|
Spotify,
|
|
};
|
|
|
|
pub const IgnorantScrobble = struct {
|
|
track: []const u8,
|
|
artist: []const u8,
|
|
album: []const u8 = "Not Provided",
|
|
//albumId: []const u8,
|
|
date: i64,
|
|
};
|
|
|
|
pub const Scrobble = struct {
|
|
track: []const u8,
|
|
artists_track: []const []const u8,
|
|
album: []const u8 = "",
|
|
artists_album: []const []const u8,
|
|
date: i64,
|
|
};
|
|
|
|
// From lastfmstats.com
|
|
pub const LastFMStats = struct { username: []const u8, scrobbles: []IgnorantScrobble };
|
|
|
|
// I derived whether or not these values were optional from searching
|
|
// the respective fields for null in Vim, so there may be some fields
|
|
// that can be optional that I haven't run into yet
|
|
pub const SpotifyScrobble = struct {
|
|
ts: []const u8,
|
|
//username: []const u8,
|
|
//platform: []const u8,
|
|
ms_played: u64,
|
|
//conn_country: []const u8,
|
|
//ip_addr_decrypted: ?[]const u8,
|
|
//user_agent_decrypted: ?[]const u8,
|
|
master_metadata_track_name: ?[]const u8,
|
|
master_metadata_album_artist_name: ?[]const u8,
|
|
master_metadata_album_album_name: ?[]const u8,
|
|
//spotify_track_uri: ?[]const u8,
|
|
//episode_name: ?[]const u8,
|
|
//episode_show_name: ?[]const u8,
|
|
//spotify_episode_uri: ?[]const u8,
|
|
reason_start: []const u8,
|
|
reason_end: ?[]const u8,
|
|
//shuffle: bool,
|
|
skipped: ?bool,
|
|
//offline: bool,
|
|
offline_timestamp: u64,
|
|
//incognito_mode: ?bool,
|
|
};
|
|
|
|
pub const LastFMWeb = struct {
|
|
recenttracks: struct {
|
|
track: []LastFMWebScrobble,
|
|
@"@attr": LastFMWebQueryInfo,
|
|
},
|
|
};
|
|
|
|
pub const LastFMWebHyperlinkData = struct {
|
|
mbid: []const u8,
|
|
@"#text": []const u8,
|
|
};
|
|
|
|
pub const LastFMWebScrobble = struct {
|
|
artist: LastFMWebHyperlinkData,
|
|
album: ?LastFMWebHyperlinkData = null,
|
|
name: []const u8,
|
|
mbid: ?[]const u8 = null,
|
|
image: []struct {
|
|
size: []const u8,
|
|
@"#text": []const u8,
|
|
},
|
|
date: ?struct {
|
|
uts: []const u8,
|
|
@"#text": []const u8,
|
|
} = null,
|
|
@"@attr": ?struct {
|
|
nowplaying: []const u8,
|
|
} = null,
|
|
url: []const u8,
|
|
};
|
|
|
|
pub const LastFMWebQueryInfo = struct {
|
|
perPage: []const u8,
|
|
totalPages: []const u8,
|
|
page: []const u8,
|
|
user: []const u8,
|
|
total: []const u8,
|
|
};
|
|
|
|
pub const Rule = struct {
|
|
name: []const u8,
|
|
cond_req: enum { any, all },
|
|
conditionals: []struct {
|
|
match_on: enum { artists_album, artists_track, album, track },
|
|
match_cond: enum { is, contains },
|
|
match_txt: []const u8,
|
|
},
|
|
actions: []struct {
|
|
action: enum { replace, add },
|
|
action_on: enum { artists_album, album, artists_track, track },
|
|
action_txt: []const u8,
|
|
},
|
|
};
|
|
|
|
// 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,
|
|
//};
|
|
//
|
|
|
|
pub const TableRow = struct {
|
|
song: ?HyperlinkData = null,
|
|
album: ?HyperlinkData = null,
|
|
artist: ?HyperlinkData = null,
|
|
artistlist: ?[]HyperlinkData = null,
|
|
scrobbles: ?i64 = null,
|
|
date: ?[]const u8 = null,
|
|
};
|
|
|
|
pub const HyperlinkData = struct {
|
|
name: []const u8,
|
|
id: i64,
|
|
};
|