From 0a8fe9329754af4267dde292bd14b789e579586f Mon Sep 17 00:00:00 2001 From: Hamcha Date: Sat, 27 Apr 2024 03:35:20 +0200 Subject: [PATCH] it's kinda done --- src/main.zig | 53 +++++++++++++++++++++++++++++++++++++++++++++-- src/trackinfo.zig | 24 ++++++++++----------- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/main.zig b/src/main.zig index 6ce9449..fe2c4f8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -15,6 +15,23 @@ fn parse_musicdef(allocator: mem.Allocator, tracks: *TrackMap, file: []const u8) } } +const forbidden_chars = "<>:\"/\\|?*!"; +fn slugify(allocator: mem.Allocator, name: ?[]const u8, fallback: []const u8) ![]const u8 { + const notNullName = name orelse fallback; + + // Make copy of name + var copiedName = try allocator.alloc(u8, notNullName.len); + + for (0..copiedName.len) |i| { + if (std.mem.indexOfScalar(u8, forbidden_chars, notNullName[i])) |_| { + copiedName[i] = '-'; + } else { + copiedName[i] = notNullName[i]; + } + } + return copiedName; +} + pub fn main() !void { // Get allocator var gpa = std.heap.GeneralPurposeAllocator(.{}){}; @@ -54,7 +71,7 @@ pub fn main() !void { defer iter.deinit(); while (try iter.next()) |entry| { // Skip non-files - if (entry.kind != fs.File.Kind.file) { + if (entry.kind != .file) { continue; } @@ -69,10 +86,15 @@ pub fn main() !void { try parse_musicdef(keyAllocator, &trackInfos, filedata); } else { // Save file to hashmap of resolved files - try trackLocations.put(try keyAllocator.dupe(u8, filename), entry.path); + try trackLocations.put(try keyAllocator.dupe(u8, filename), try keyAllocator.dupe(u8, entry.path)); } } + // Make target dirs + const outputDir = try fs.cwd().makeOpenPath("target", .{}); + const originalsDir = try outputDir.makeOpenPath("original", .{}); + const othersDir = try outputDir.makeOpenPath("others", .{}); + // Print detected songs var tracks = trackInfos.valueIterator(); while (tracks.next()) |trackInfo| { @@ -82,5 +104,32 @@ pub fn main() !void { trackInfo.author, trackInfo.source, }); + // Extract all the qualifying IDs + var ids = mem.splitScalar(u8, trackInfo.id, ','); + while (ids.next()) |id| { + const actualID = mem.trimLeft(u8, id, "\\"); + + // Map to track location + var soundIDBuffer: [10]u8 = undefined; + const soundID = try std.fmt.bufPrint(&soundIDBuffer, "O_{s}", .{actualID}); + const location = trackLocations.get(soundID) orelse { + std.debug.panic("{s} has no track assigned", .{soundID}); + }; + + // Copy file over, dir depending on originality (I-I mean, I'm not trying to be mean) + const sourceDirName = try slugify(allocator, trackInfo.source, "unknown"); + defer allocator.free(sourceDirName); + const targetDir = if (trackInfo.is_original) originalsDir else try othersDir.makeOpenPath(sourceDirName, .{}); + + const author = try slugify(allocator, trackInfo.author, "unknown"); + defer allocator.free(author); + const title = try slugify(allocator, trackInfo.title, trackInfo.id); + defer allocator.free(title); + + const filename = try std.fmt.allocPrint(allocator, "{s} - {s}.ogg", .{ author, title }); + defer allocator.free(filename); + + try dir.copyFile(location, targetDir, filename, .{}); + } } } diff --git a/src/trackinfo.zig b/src/trackinfo.zig index 949744a..c823fa8 100644 --- a/src/trackinfo.zig +++ b/src/trackinfo.zig @@ -21,7 +21,7 @@ is_original: bool, pub fn parseLump(allocator: mem.Allocator, lump: []const u8) !Self { // Get lines - var lines = mem.tokenize(u8, lump, "\n"); + var lines = mem.tokenizeScalar(u8, lump, '\n'); // Next line is the ID, we need that ASAP! const id = mem.trim(u8, lines.next().?, " \r"); @@ -37,18 +37,16 @@ pub fn parseLump(allocator: mem.Allocator, lump: []const u8) !Self { // Read rest of lump and assign to fields in struct while (lines.next()) |line| { - const sep = mem.indexOf(u8, line, "="); - if (sep) |sepIndex| { - const key = mem.trim(u8, line[0..sepIndex], " \r"); - const val = mem.trim(u8, line[sepIndex + 1 ..], " \r"); - const ownedVal = try allocator.dupe(u8, val); - const infoKey = std.meta.stringToEnum(InfoKey, key) orelse continue; - switch (infoKey) { - .Title => info.title = ownedVal, - .Author => info.author = ownedVal, - .Source => info.source = ownedVal, - .OriginalComposers => info.originalComposers = ownedVal, - } + const sep = mem.indexOfScalar(u8, line, '=') orelse continue; + const key = mem.trim(u8, line[0..sep], " \r"); + const val = mem.trim(u8, line[sep + 1 ..], " \r"); + const ownedVal = try allocator.dupe(u8, val); + const infoKey = std.meta.stringToEnum(InfoKey, key) orelse continue; + switch (infoKey) { + .Title => info.title = ownedVal, + .Author => info.author = ownedVal, + .Source => info.source = ownedVal, + .OriginalComposers => info.originalComposers = ownedVal, } }