From 4c9306ca41ea445d98da7c7edd336f623c768f0e Mon Sep 17 00:00:00 2001 From: speedie Date: Tue, 15 Aug 2023 20:51:29 +0200 Subject: [PATCH] Add mcopy cpp --- mcopy.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 28 ++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 mcopy.cpp create mode 100644 meson.build diff --git a/mcopy.cpp b/mcopy.cpp new file mode 100644 index 0000000..ae5575d --- /dev/null +++ b/mcopy.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef VERSION +#define VERSION "0.1" +#endif + +void help() { + std::cout << + "mcopy " << VERSION << "\n\n" << + "mcopy -f, --format Specify a format to output files using\n" << + "mcopy -a, --ask Ask the user if metadata cannot be retrieved from file\n" << + "mcopy -na, --no-ask Don't ask if metadata cannot be retrieved from file\n" << + "mcopy -h, --help Display help\n" << + "mcopy -v, --version Display version\n" << + "\n" << + "Example: mcopy --format \"/home/anon/Music/Albums/@A/@a/@n. @A - @t.flac" "~/Downloads/myflac1.flac" "~/Downloads/myflac2.flac\n" << + "\n" << + "Formats:\n" << + "\n" << + "@A Artist\n" << + "@a Album name\n" << + "@t Title\n" << + "@n Track number\n"; +} + +TagLib::FileRef get_file(std::string str) { + const char *cstr = str.c_str(); + TagLib::FileName fn(cstr); + TagLib::FileRef file(fn); + + return file; +} + +void getMetadataFromFile(std::string format, std::string str) { + TagLib::FileRef file = get_file(str); + TagLib::Tag *tag = file.tag(); + + if (file.isNull() || !file.audioProperties()) { + return; + } + + std::string title = tag->title().to8Bit(true); + std::string album = tag->album().to8Bit(true); + std::string artist = tag->artist().to8Bit(true); + std::string track = std::to_string(tag->track()); + + std::string filename = format; + + // TODO: Replace this junk + filename = std::regex_replace(format, std::regex("@t"), title); + filename = std::regex_replace(filename, std::regex("@a"), album); + filename = std::regex_replace(filename, std::regex("@A"), artist); + filename = std::regex_replace(filename, std::regex("@n"), track); + + std::filesystem::path fs; + std::string dir = (fs = filename).remove_filename(); + std::filesystem::create_directories(dir); + + if (!std::filesystem::copy_file(str, filename)) { + std::cout << "mcopy: Failed to copy file " << str << " to " << filename << "\n"; + exit(1); + } else { + std::cout << "mcopy: Copied file " << str << " to " << filename << "\n"; + } +} + +int main(int argc, char **argv) { + int ac = argc; + char **av = argv; + + std::string format = ""; + + for (int i{1}; i < argc; i++) { + std::string arg = argv[i]; + + if (!arg.compare("-h")) { + help(); + exit(0); + } else if (!arg.compare("-v")) { + std::cout << "mcopy " << VERSION << '\n'; + exit(0); + } else if (!arg.compare("-f") && i < argc) { + format = argv[++i]; + continue; + } + } + + if (!format.compare("")) { + std::cout << "You must specify a format.\n"; + exit(1); + } + + for (int i{1}; i < ac; i++) { + std::ifstream f(av[i]); + + if (static_cast(f.good())) { + getMetadataFromFile(format, av[i]); + } + } +} diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..91f50fb --- /dev/null +++ b/meson.build @@ -0,0 +1,28 @@ +project( + 'mcopy', + 'cpp', + version : '"0.1"', +) + +cc = meson.get_compiler('cpp') + +project_source_files = [ + 'mcopy.cpp', +] + +project_dependencies = [ + dependency('taglib'), +] + +build_args = [ + '-DVERSION=' + meson.project_version(), +] + +project_target = executable( + meson.project_name(), + project_source_files, install : true, + dependencies: project_dependencies, + c_args : build_args, +) + +test('mcopy', project_target)