Compare commits

...

4 Commits

Author SHA1 Message Date
cb8939a3e3 Added FLAC Tagging 2024-07-01 16:04:53 +03:00
7c213fe037 Added MP3 tagging 2024-07-01 15:39:42 +03:00
42ab8dbcb1 Added cover resizing 2024-07-01 15:17:40 +03:00
21058e5ac4 Prepare for tagging 2024-07-01 15:10:04 +03:00
6 changed files with 224 additions and 31 deletions

View File

@ -38,7 +38,22 @@ https://github.com/nlohmann/json
# eyeD3
https://eyed3.readthedocs.io/en/latest/
* For MP3 tagging
* TODO: Add info here
```
// Common
--encoding utf8
--preserve-file-times
// First Step - Remove Images
--remove-all-images
// Second Step - Change what is needed
--add-image "...":FRONT_COVER
--artist "..."
--album "..."
--title "..."
--track ...
```
# metaflac
https://xiph.org/flac/download.html
@ -49,17 +64,17 @@ metaflac
--preserve-modtime
--no-utf8-convert
// First Step - Remove Tags
// First Step - Remove Pictures
--remove --block-type=PICTURE
// Second Step - Remove Tags
--remove-tag=TITLE
--remove-tag=ARTIST
--remove-tag=ALBUM
--remove-tag=TRACKNUMBER
// Second Step - Remove Pictures
--remove --block-type=PICTURE
// Third Step - Add
--import-picture-from=3|image/jpeg|||"/path/to/cover"
"--import-picture-from=3|image/jpeg|||/path/to/cover"
"--set-tag=TITLE=..."
"--set-tag=ARTIST=..."
"--set-tag=ALBUM=..."

View File

@ -1,5 +1 @@
* Rate limit
* Use external tools
* Download and resize cover before tracks
* Tag tracks
* Update README with eyeD3
* Add API Rate Limit

View File

@ -3,6 +3,7 @@
#include <fstream>
#include <set>
#include <stdlib.h>
#include <sys/stat.h>
using std::endl;
@ -187,3 +188,16 @@ string clean_filename(const string& s)
return result;
}
bool exec_cmd(const string& cmd)
{
int error;
error = system(cmd.c_str());
if (0 != error)
{
return false;
}
return true;
}

View File

@ -19,5 +19,6 @@ void json_extract(const nlohmann::json& j, const std::string& key, bool& out);
bool ensure_folder(const std::string& main_path, const std::string& folder);
std::string trim_whitespace(const std::string& s);
std::string clean_filename(const std::string& s);
bool exec_cmd(const std::string& cmd);
#endif // COMMON_H_

194
main.cpp
View File

@ -15,6 +15,111 @@ void usage(const char *name)
cout << "Usage: " << name << " [catalog id] ..." << endl;
}
string gen_resize_command(const string& release_folder, const string& convert_exec)
{
string cmd;
cmd = convert_exec;
cmd += " \"";
cmd += build_fname(release_folder, "", "Cover.*");
cmd += "\" -resize 750x750 \"";
cmd += build_fname(release_folder, "", "Cover_small.jpg");
cmd += "\"";
return cmd;
}
string gen_mp3_clear(const string& filepath, const string& eyed3_exec)
{
string cmd;
cmd = eyed3_exec;
cmd += " --preserve-file-times --remove-all-images \"";
cmd += filepath;
cmd += "\" > /dev/null 2>&1";
return cmd;
}
string gen_mp3_set_tags(const string& filepath, const string& artist,
const string& title, const string& album, int track_num,
const string& cover_filepath, string eyed3_exec)
{
string cmd;
cmd = eyed3_exec;
cmd += " --encoding utf8 --preserve-file-times --add-image \"";
cmd += cover_filepath;
cmd += "\":FRONT_COVER --artist \"";
cmd += artist;
// cmd += "\" --album \"";
// cmd += album;
cmd += "\" --title \"";
cmd += title;
cmd += "\" --track ";
cmd += to_string(track_num);
cmd += " \"";
cmd += filepath;
cmd += "\" > /dev/null 2>&1";
return cmd;
}
string gen_flac_clear_images(const string& filepath, const string& metaflac_exec)
{
string cmd;
cmd = metaflac_exec;
cmd += " --preserve-modtime --no-utf8-convert";
cmd += " --remove --block-type=PICTURE \"";
cmd += filepath;
cmd += "\"";
return cmd;
}
string gen_flac_clear_tags(const string& filepath, const string& metaflac_exec)
{
string cmd;
cmd = metaflac_exec;
cmd += " --preserve-modtime --no-utf8-convert";
cmd += " --remove-tag=TITLE";
cmd += " --remove-tag=ARTIST";
// cmd += " --remove-tag=ALBUM";
cmd += " --remove-tag=TRACKNUMBER";
cmd += " \"";
cmd += filepath;
cmd += "\"";
return cmd;
}
string gen_flac_set_tags(const string& filepath, const string& artist,
const string& title, const string& album, int track_num,
const string& cover_filepath, string metaflac_exec)
{
string cmd;
cmd = metaflac_exec;
cmd += " --preserve-modtime --no-utf8-convert";
cmd += " \"--import-picture-from=3|image/jpeg|||";
cmd += cover_filepath;
cmd += "\" \"--set-tag=TITLE=";
cmd += title;
cmd += "\" \"--set-tag=ARTIST=";
cmd += artist;
// cmd += "\" \"--set-tag=ALBUM=";
// cmd += album;
cmd += "\" \"--set-tag=TRACKNUMBER=";
cmd += to_string(track_num);
cmd += "\" --dont-use-padding \"";
cmd += filepath;
cmd += "\"";
return cmd;
}
int main(int argc, char **argv)
{
// Config stuff
@ -51,6 +156,10 @@ int main(int argc, char **argv)
json_extract(config, "Pass", pass);
json_extract(config, "download_path", main_path);
json_extract(config, "convert_exec", convert_exec);
json_extract(config, "eyed3_exec", eyed3_exec);
json_extract(config, "metaflac_exec", metaflac_exec);
ok = mcat.login(email, pass);
if (!ok)
{
@ -96,6 +205,22 @@ int main(int argc, char **argv)
continue;
}
// Download Cover
ok = mcat.download_cover(release.catalog_id, release_folder);
if (!ok)
{
cout << "Could not download cover for release " << release.catalog_id << endl;
continue;
}
// Resize cover
ok = exec_cmd(gen_resize_command(release_folder, convert_exec));
if (!ok)
{
cout << "Could not resize cover for release - " << release.catalog_id << endl;
continue;
}
// Download tracks (1 -- N)
for (Track& track : release.tracks)
{
@ -103,6 +228,7 @@ int main(int argc, char **argv)
// Download MP3
filepath = build_fname(mp3_folder, "", filename);
filepath += ".mp3";
ok = mcat.download_track(release.id, track.id, filepath, FORMAT_MP3);
if (!ok)
{
@ -111,8 +237,34 @@ int main(int argc, char **argv)
continue;
}
// Clear MP3 Images
ok = exec_cmd(gen_mp3_clear(filepath, eyed3_exec));
if (!ok)
{
cout << "Could not clear images for MP3 track " << track.number <<
" from release " << release.catalog_id << endl;
continue;
}
// Set MP3 Tags
ok = exec_cmd(
gen_mp3_set_tags(filepath,
track.artist,
track.title,
release.title,
track.number,
build_fname(release_folder, "", "Cover_small.jpg"),
eyed3_exec));
if (!ok)
{
cout << "Could not tag MP3 track " << track.number <<
" from release " << release.catalog_id << endl;
continue;
}
// Download FLAC
filepath = build_fname(flac_folder, "", filename);
filepath += ".flac";
ok = mcat.download_track(release.id, track.id, filepath, FORMAT_FLAC);
if (!ok)
{
@ -121,6 +273,40 @@ int main(int argc, char **argv)
continue;
}
// Clear FLAC Images
ok = exec_cmd(gen_flac_clear_images(filepath, metaflac_exec));
if (!ok)
{
cout << "Could not clear images for FLAC track " << track.number <<
" from release " << release.catalog_id << endl;
continue;
}
// Clear FLAC Tags
ok = exec_cmd(gen_flac_clear_tags(filepath, metaflac_exec));
if (!ok)
{
cout << "Could not clear tags for FLAC track " << track.number <<
" from release " << release.catalog_id << endl;
continue;
}
// Set FLAC Tags
ok = exec_cmd(
gen_flac_set_tags(filepath,
track.artist,
track.title,
release.title,
track.number,
build_fname(release_folder, "", "Cover_small.jpg"),
metaflac_exec));
if (!ok)
{
cout << "Could not tag FLAC track " << track.number <<
" from release " << release.catalog_id << endl;
continue;
}
// Download Extended Mix
if (!track.extended_mix_file_id.empty())
{
@ -143,14 +329,6 @@ int main(int argc, char **argv)
}
}
}
// Download Cover
ok = mcat.download_cover(release.catalog_id, release_folder);
if (!ok)
{
cout << "Could not download cover for release " << release.catalog_id << endl;
continue;
}
}
ok = mcat.logout();

View File

@ -502,12 +502,11 @@ bool Monstercat_DL::download_cover(const string& catalog_id, const string& path)
}
bool Monstercat_DL::download_track(const string& release_id,
const string& track_id, const string& path, bool is_mp3)
const string& track_id, const string& filepath, bool is_mp3)
{
CURL_DL& curl = CURL_DL::get_handle();
bool ok;
string url;
string filepath;
stringstream out_data;
ofstream out_file;
@ -537,16 +536,6 @@ bool Monstercat_DL::download_track(const string& release_id,
return false;
}
filepath = path;
if (is_mp3)
{
filepath += ".mp3";
}
else
{
filepath += ".flac";
}
out_file.open(filepath, std::ios::binary);
if (!out_file.is_open())
{