Refactor
This commit is contained in:
parent
742c3887c9
commit
319c5aeae8
2 changed files with 93 additions and 110 deletions
|
|
@ -20,43 +20,44 @@ pub const Result = struct {
|
||||||
if (count == 0) return null;
|
if (count == 0) return null;
|
||||||
const sorted_recordings = self.recordings.?;
|
const sorted_recordings = self.recordings.?;
|
||||||
std.mem.sort(Recording, sorted_recordings, {}, Recording.lessThan);
|
std.mem.sort(Recording, sorted_recordings, {}, Recording.lessThan);
|
||||||
rc_loop: for (sorted_recordings) |rc| {
|
for (sorted_recordings) |rc| {
|
||||||
switch (pbo.parse) {
|
switch (pbo.parse) {
|
||||||
.song => {
|
.song => {
|
||||||
var output = searchIDs{ .id = "" };
|
const output = searchIDs{
|
||||||
switch (pbo.specifyBy) {
|
.id = switch (pbo.specifyBy) {
|
||||||
.song => {
|
.song => song_song: {
|
||||||
if (std.mem.eql(u8, rc.title, smd.tn)) {
|
if (std.mem.eql(u8, rc.title, smd.tn)) {
|
||||||
output.id = rc.id;
|
break :song_song rc.id;
|
||||||
break :rc_loop;
|
//break :rc_loop;
|
||||||
}
|
|
||||||
},
|
|
||||||
.album => {
|
|
||||||
if (rc.releases) |rls| {
|
|
||||||
for (rls) |rl| {
|
|
||||||
if (std.mem.eql(u8, rl.title, smd.rgn)) {
|
|
||||||
output.id = rc.id;
|
|
||||||
break :rc_loop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
std.log.err("Could not find any releases", .{});
|
.album => song_album: {
|
||||||
}
|
if (rc.releases) |rls| {
|
||||||
},
|
for (rls) |rl| {
|
||||||
.artist => {
|
if (std.mem.eql(u8, rl.title, smd.rgn)) {
|
||||||
if (rc.@"artist-credit") |acs| {
|
break :song_album rc.id;
|
||||||
for (acs) |ac| {
|
//break :rc_loop;
|
||||||
if (std.mem.eql(u8, ac.name, smd.an)) {
|
}
|
||||||
output.id = rc.id;
|
|
||||||
break :rc_loop;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
std.log.err("Could not find any releases", .{});
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
std.log.err("Could not find any artists", .{});
|
.artist => song_artist: {
|
||||||
}
|
if (rc.@"artist-credit") |acs| {
|
||||||
|
for (acs) |ac| {
|
||||||
|
if (std.mem.eql(u8, ac.name, smd.an)) {
|
||||||
|
break :song_artist rc.id;
|
||||||
|
//break :rc_loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std.log.err("Could not find any artists", .{});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.all => unreachable, // I'll do this later
|
||||||
},
|
},
|
||||||
.all => unreachable, // I'll do this later
|
};
|
||||||
}
|
|
||||||
return output;
|
return output;
|
||||||
},
|
},
|
||||||
.album => {
|
.album => {
|
||||||
|
|
@ -133,59 +134,45 @@ pub const parseOption = union(enum) {
|
||||||
|
|
||||||
pub const parseByOptions = struct { parse: parseOption = .song, specifyBy: parseOption = .song };
|
pub const parseByOptions = struct { parse: parseOption = .song, specifyBy: parseOption = .song };
|
||||||
|
|
||||||
const eunuchMetadata = struct {
|
pub const searchMetadata = struct {
|
||||||
tn: struct { dec: []const u8, enc: []const u8 = undefined },
|
tn: []const u8,
|
||||||
rn: struct { dec: []const u8, enc: []const u8 = undefined },
|
rn: []const u8,
|
||||||
an: struct { dec: []const u8, enc: []const u8 = undefined },
|
an: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Maybe just use a HashMap...
|
// Maybe just use a HashMap...
|
||||||
pub const searchMetadata = struct {
|
pub const searchMetadataEncoded = struct {
|
||||||
alloc: std.mem.Allocator = undefined,
|
tn: []const u8,
|
||||||
tn: struct { dec: []const u8, enc: []const u8 = undefined },
|
rn: []const u8,
|
||||||
rn: struct { dec: []const u8, enc: []const u8 = undefined },
|
an: []const u8,
|
||||||
an: struct { dec: []const u8, enc: []const u8 = undefined },
|
|
||||||
|
|
||||||
pub fn deinit(self: *searchMetadata) void {
|
//pub fn deinit(self: *searchMetadata) void {
|
||||||
self.alloc.free(self.tn.enc);
|
// self.alloc.free(self.tn.enc);
|
||||||
self.alloc.free(self.rn.enc);
|
// self.alloc.free(self.rn.enc);
|
||||||
self.alloc.free(self.an.enc);
|
// self.alloc.free(self.an.enc);
|
||||||
}
|
//}
|
||||||
|
|
||||||
pub fn percentEncode(self: *searchMetadata) !void {
|
|
||||||
inline for (std.meta.fields(eunuchMetadata)) |k| {
|
|
||||||
var encoded = std.ArrayList(u8).init(self.alloc);
|
|
||||||
errdefer encoded.deinit();
|
|
||||||
for (@field(self, k.name).dec) |v| {
|
|
||||||
if ((v >= 'A' and v <= 'Z') or (v >= 'a' and v <= 'z') or (v >= '0' and v <= '9') or v == '-' or v == '_' or v == '.' or v == '~') {
|
|
||||||
try encoded.append(v);
|
|
||||||
} else if (v == ' ') {
|
|
||||||
try encoded.append('+');
|
|
||||||
} else {
|
|
||||||
const hex = try std.fmt.allocPrint(self.alloc, "%{x}", .{v});
|
|
||||||
defer self.alloc.free(hex);
|
|
||||||
try encoded.appendSlice(hex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@field(self, k.name).enc = try encoded.toOwnedSlice();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
pub fn percentEncode(alloc: std.mem.Allocator, smd: searchMetadata) !searchMetadataEncoded {
|
||||||
|
var output: searchMetadataEncoded = undefined;
|
||||||
|
inline for (std.meta.fields(searchMetadata)) |k| {
|
||||||
|
var encoded = std.ArrayList(u8).init(alloc);
|
||||||
|
errdefer encoded.deinit();
|
||||||
|
for (@field(smd, k.name)) |v| {
|
||||||
|
if ((v >= 'A' and v <= 'Z') or (v >= 'a' and v <= 'z') or (v >= '0' and v <= '9') or v == '-' or v == '_' or v == '.' or v == '~') {
|
||||||
|
try encoded.append(v);
|
||||||
|
} else if (v == ' ') {
|
||||||
|
try encoded.append('+');
|
||||||
|
} else {
|
||||||
|
const hex = try std.fmt.allocPrint(alloc, "%{x}", .{v});
|
||||||
|
defer alloc.free(hex);
|
||||||
|
try encoded.appendSlice(hex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@field(output, k.name) = try encoded.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
// I don't think I need a second type, but I'd like to hold on to the original, unencoded metadata as well, so maybe this is fine
|
return output;
|
||||||
// Maybe make fields for encoded data?
|
}
|
||||||
//pub const searchMetadataEncoded = struct {
|
|
||||||
// alloc: std.mem.Allocator,
|
|
||||||
// tn: []const u8,
|
|
||||||
// rgn: []const u8,
|
|
||||||
// an: []const u8,
|
|
||||||
//
|
|
||||||
// pub fn deinit(self: *const searchMetadataEncoded) void {
|
|
||||||
// self.alloc.free(self.an);
|
|
||||||
// self.alloc.free(self.rgn);
|
|
||||||
// self.alloc.free(self.tn);
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
pub const searchIDs = union {
|
pub const searchIDs = union {
|
||||||
id: []const u8,
|
id: []const u8,
|
||||||
|
|
|
||||||
60
src/root.zig
60
src/root.zig
|
|
@ -8,57 +8,53 @@ const Client = std.http.Client;
|
||||||
|
|
||||||
pub const user_agent: []const u8 = "ZuletztMBClient/0.0.1 (swebbguy@gmail.com)";
|
pub const user_agent: []const u8 = "ZuletztMBClient/0.0.1 (swebbguy@gmail.com)";
|
||||||
|
|
||||||
pub fn mbSearch(allocator: std.mem.Allocator, ar: *std.ArrayList(u8), smd: MBQ.searchMetadata) !?[]const u8 {
|
pub fn mbSearch(alloc: std.mem.Allocator, smd: MBQ.searchMetadata) !?MBQ.Result {
|
||||||
const encoded = try MBQ.percentEncode(allocator, smd);
|
const encoded = try MBQ.percentEncode(alloc, smd);
|
||||||
defer encoded.deinit();
|
|
||||||
var client = Client{ .allocator = allocator };
|
// Might consider making just one of these and passing it around
|
||||||
|
var client = Client{ .allocator = alloc };
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
const query: []const u8 = try std.fmt.allocPrint(allocator, "https://musicbrainz.org/ws/2/recording/?query=\"{s}\"%20AND%20artist:\"{s}\"%20AND%20release:\"{s}\"&fmt=json", .{ encoded.tn, encoded.an, encoded.rgn });
|
const query: []const u8 = try std.fmt.allocPrint(alloc, "https://musicbrainz.org/ws/2/recording/?query=\"{s}\"%20AND%20artist:\"{s}\"%20AND%20release:\"{s}\"&fmt=json", .{ encoded.tn, encoded.an, encoded.rn });
|
||||||
defer allocator.free(query);
|
defer alloc.free(query);
|
||||||
|
|
||||||
const response: Client.FetchResult = try client.fetch(.{ .response_storage = .{ .dynamic = ar }, .location = .{ .url = query }, .method = .GET, .headers = .{ .user_agent = .{ .override = user_agent } } });
|
var ar = std.ArrayList(u8).init(alloc);
|
||||||
|
errdefer ar.deinit();
|
||||||
|
|
||||||
|
const response: Client.FetchResult = try client.fetch(.{ .response_storage = .{ .dynamic = &ar }, .location = .{ .url = query }, .method = .GET, .headers = .{ .user_agent = .{ .override = user_agent } } });
|
||||||
|
|
||||||
switch (@intFromEnum(response.status)) {
|
switch (@intFromEnum(response.status)) {
|
||||||
0...299 => std.log.debug("Success\n", .{}),
|
0...299 => std.log.debug("Success", .{}),
|
||||||
300...399 => {
|
300...399 => {
|
||||||
std.log.err("Redirected\n", .{});
|
std.log.err("Redirected", .{});
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
400...511 => {
|
400...511 => {
|
||||||
std.log.err("Get rekt\n{s}", .{ar.items});
|
std.log.err("Get rekt {s}", .{ar.items});
|
||||||
return Client.ConnectError.ConnectionRefused;
|
return Client.ConnectError.ConnectionRefused;
|
||||||
},
|
},
|
||||||
512 => {
|
512 => {
|
||||||
std.log.err("Need to login\n", .{});
|
std.log.err("Need to login", .{});
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ar.items;
|
const json = try std.json.parseFromSlice(MBQ.Result, alloc, ar.items, .{ .ignore_unknown_fields = true });
|
||||||
|
errdefer json.deinit();
|
||||||
|
|
||||||
|
return json.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test is very volatile, but I think
|
|
||||||
// these params are specific enough that
|
|
||||||
// it shouldn't need changing too often
|
|
||||||
test "arid_via_recording" {
|
test "arid_via_recording" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
|
|
||||||
const metadata = MBQ.searchMetadata{ .tn = "Veni veni Emmanuel", .an = "iamthemorning", .rgn = "Counting the Ghosts" };
|
const metadata = MBQ.searchMetadata{ .tn = "Veni veni Emmanuel", .an = "iamthemorning", .rn = "Counting the Ghosts" };
|
||||||
const iatm_id: []const u8 = "5854a6de-af8f-4b99-8710-cb47d6436a19";
|
const iatm_id: []const u8 = "5854a6de-af8f-4b99-8710-cb47d6436a19";
|
||||||
|
|
||||||
var mb_result = std.ArrayList(u8).init(test_alloc);
|
const search_result = try mbSearch(test_alloc, metadata);
|
||||||
defer mb_result.deinit();
|
if (search_result) |rs| {
|
||||||
|
const id = rs.getIDs(metadata, .{ .parse = .artist, .specifyBy = .song });
|
||||||
const search_result = try mbSearch(test_alloc, &mb_result, metadata);
|
|
||||||
|
|
||||||
if (search_result) |sr| {
|
|
||||||
const json = try std.json.parseFromSlice(MBQ.Result, test_alloc, sr, .{ .ignore_unknown_fields = true });
|
|
||||||
defer json.deinit();
|
|
||||||
|
|
||||||
const result: MBQ.Result = json.value;
|
|
||||||
const id = result.getIDs(metadata, .{ .parse = .artist, .specifyBy = .song });
|
|
||||||
|
|
||||||
std.Thread.sleep(1000000000);
|
std.Thread.sleep(1000000000);
|
||||||
|
|
||||||
|
|
@ -71,7 +67,7 @@ test "arid_via_recording" {
|
||||||
test "arid_via_recording_multiple_artists_1" {
|
test "arid_via_recording_multiple_artists_1" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
|
|
||||||
const metadata = MBQ.searchMetadata{ .tn = "Roll Me Up And Smoke Me When I Die", .an = "Lyle Lovett", .rgn = "Willie Nelson American Outlaw" };
|
const metadata = MBQ.searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "Roll Me Up And Smoke Me When I Die" }, .an = .{ .dec = "Lyle Lovett" }, .rn = .{ .dec = "Willie Nelson American Outlaw" } };
|
||||||
const ll_id: []const u8 = "7241e3ed-5ad4-4849-94df-6858ea833472";
|
const ll_id: []const u8 = "7241e3ed-5ad4-4849-94df-6858ea833472";
|
||||||
|
|
||||||
var mb_result = std.ArrayList(u8).init(test_alloc);
|
var mb_result = std.ArrayList(u8).init(test_alloc);
|
||||||
|
|
@ -97,7 +93,7 @@ test "arid_via_recording_multiple_artists_1" {
|
||||||
test "rgid_via_recording" {
|
test "rgid_via_recording" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
|
|
||||||
const metadata = MBQ.searchMetadata{ .tn = "I Of The Storm", .rgn = "Beneath the Skin", .an = "Of Monsters and Men" };
|
const metadata = MBQ.searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "I Of The Storm" }, .rn = .{ .dec = "Beneath the Skin" }, .an = .{ .dec = "Of Monsters and Men" } };
|
||||||
const bts_id: []const u8 = "4f4f5b98-45ac-4b47-addb-66b501473bd8";
|
const bts_id: []const u8 = "4f4f5b98-45ac-4b47-addb-66b501473bd8";
|
||||||
|
|
||||||
var mb_result = std.ArrayList(u8).init(test_alloc);
|
var mb_result = std.ArrayList(u8).init(test_alloc);
|
||||||
|
|
@ -123,7 +119,7 @@ test "rgid_via_recording" {
|
||||||
test "rgid_via_recording_multiple_artists_2" {
|
test "rgid_via_recording_multiple_artists_2" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
|
|
||||||
const metadata = MBQ.searchMetadata{ .tn = "Hesitating Beauty", .rgn = "Mermaid Avenue", .an = "Wilco" };
|
const metadata = MBQ.searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "Hesitating Beauty" }, .rn = .{ .dec = "Mermaid Avenue" }, .an = .{ .dec = "Wilco" } };
|
||||||
const wilco_id: []const u8 = "9ba73bf8-6c15-4bd2-8da1-e2292538f617";
|
const wilco_id: []const u8 = "9ba73bf8-6c15-4bd2-8da1-e2292538f617";
|
||||||
|
|
||||||
var mb_result = std.ArrayList(u8).init(test_alloc);
|
var mb_result = std.ArrayList(u8).init(test_alloc);
|
||||||
|
|
@ -150,7 +146,7 @@ test "rgid_via_recording_multiple_artists_2" {
|
||||||
test "rid_aqualung" {
|
test "rid_aqualung" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
|
|
||||||
const metadata = MBQ.searchMetadata{ .tn = "Aqualung", .rgn = "Aqualung", .an = "Jethro Tull" };
|
const metadata = MBQ.searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "Aqualung" }, .rn = .{ .dec = "Aqualung" }, .an = .{ .dec = "Jethro Tull" } };
|
||||||
const aqualung_id: []const u8 = "2621d113-3a9f-41f9-a0f2-b9459f86e8e9";
|
const aqualung_id: []const u8 = "2621d113-3a9f-41f9-a0f2-b9459f86e8e9";
|
||||||
|
|
||||||
var mb_result = std.ArrayList(u8).init(test_alloc);
|
var mb_result = std.ArrayList(u8).init(test_alloc);
|
||||||
|
|
@ -174,7 +170,7 @@ test "rid_aqualung" {
|
||||||
test "rid_battery" {
|
test "rid_battery" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
|
|
||||||
const metadata = MBQ.searchMetadata{ .tn = "Battery", .rgn = "Master of Puppets", .an = "Metallica" };
|
const metadata = MBQ.searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "Battery" }, .rn = .{ .dec = "Master of Puppets" }, .an = .{ .dec = "Metallica" } };
|
||||||
const battery_id: []const u8 = "3bfda26a-49fa-4bc4-a4d6-8bbfa0767ab7";
|
const battery_id: []const u8 = "3bfda26a-49fa-4bc4-a4d6-8bbfa0767ab7";
|
||||||
|
|
||||||
var mb_result = std.ArrayList(u8).init(test_alloc);
|
var mb_result = std.ArrayList(u8).init(test_alloc);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue