Remove --read-tags and --write-tags. Always read tags, so --tags just

controls writing.
Issue #29
This commit is contained in:
CDrummond committed 2025-05-20 12:08:20 +01:00
1 parent b623c1939b
commit 4794a9b747
4 files changed
+38 -52

No files matched your search

+5 -4
View File
@@ -1,13 +1,14 @@
0.4.0 0.4.0
----- -----
1. Add action to export results from database to files. 1. Add action to export results from DB to files.
2. Add option to preserve file modification time when writing tags. 2. Add option to preserve file modification time when writing tags.
3. Store analysis in BLISS_ANALYSIS tag, not in a COMMENT tag. 3. Store analysis in BLISS_ANALYSIS tag, not in a COMMENT tag.
4. Fix reading of tags during analysis phase. 4. Fix reading of tags during analysis phase.
5. Check for multiple genre tags, and if found add as semi-colon separated 5. Check for multiple genre tags, and if found add as semi-colon separated
list to DB. list to DB.
6. Add --read-tags and --write-tags commandline options. 6. When analysing files, always read tags (if present), but only write tags
7. Use max of 16 significant digits (traling zeros stripped) when writing if '--tags' is specified on commandline.
7. Use max of 16 significant digits (trailing zeros stripped) when writing
analysis results to file tags. analysis results to file tags.
0.3.0 0.3.0
@@ -44,7 +45,7 @@
----- -----
1. Tidy up code, thanks to Serial-ATA 1. Tidy up code, thanks to Serial-ATA
2. Update version of tag reader library, should now support ID3v2 in FLAC. 2. Update version of tag reader library, should now support ID3v2 in FLAC.
3. Show error message if can't open, or create, database file. 3. Show error message if can't open, or create, DB file.
4. Update version of bliss-rs, this now handles CUE processing internally. 4. Update version of bliss-rs, this now handles CUE processing internally.
0.1.0 0.1.0
+17 -12
View File
@@ -147,13 +147,7 @@ password protected then use `user:pass@server` - e.g. `lms=pi:abc123@127.0.0.1`
to `9000`. to `9000`.
* `ignore` specifies the name and location of a file containing items to ignore * `ignore` specifies the name and location of a file containing items to ignore
in mixes. See the `Ignore` section later on for more details. in mixes. See the `Ignore` section later on for more details.
* `read_tags` specifies whether analysis results should be read from files. Set * `tags` specifies whether analysis results should be written to files when anlysed.
to `true` or `false`. If enabled, then results are read from a tag named `BLISS_ANALYSIS`.
* `write_tags` specifies whether analysis results should be written to files. Set
to `true` or `false`. If enabled, then results are stored in a tag named `BLISS_ANALYSIS`
* `tags` specifies whether analysis results should be written to, and read from,
files. Set to `true` or `false`. This is the same as setting both `read_tags`
and `write_tags` to `true`
* `preserve` specifies whether file modification time should be preserved when * `preserve` specifies whether file modification time should be preserved when
writing tags. Set to `true` or `false`. writing tags. Set to `true` or `false`.
@@ -178,14 +172,12 @@ tracks are to be analysed and how many old tracks are left in the database.
* `-L` / `--lms` Hostname, or IP address, of your LMS server. * `-L` / `--lms` Hostname, or IP address, of your LMS server.
* `-J` / `--json` JSONRPC port number of your LMS server. * `-J` / `--json` JSONRPC port number of your LMS server.
* `-n` / `--numtracks` Specify maximum number of tracks to analyse. * `-n` / `--numtracks` Specify maximum number of tracks to analyse.
* `-R` / `--read-tags` Read analysis results from file tags. * `-T` / `--tags` When using the `analyse` task, write analysis results to files
* `-W` / `--write-tags` Write analysis results to file tags. within a `BLISS_ANALYSIS` tag.
* `-T` / `--tags` Read tags if present, and write tags if not present - this
option is the same as supplying both --read-tags and --write-tags.
* `-p' / '--preserve` Attempt to preserve file modification time when writing tags. * `-p' / '--preserve` Attempt to preserve file modification time when writing tags.
Equivalent items specified in the INI config file (detailed above) will override Equivalent items specified in the INI config file (detailed above) will override
any specified on the commandline. any specified on the command-line.
`bliss-analyser` requires one extra parameter, which is used to determine the `bliss-analyser` requires one extra parameter, which is used to determine the
required task. This takes the following values: required task. This takes the following values:
@@ -226,6 +218,19 @@ is shown.
As a rough guide, a 2015-era i7 8-core laptop with SSD analyses around 14000 As a rough guide, a 2015-era i7 8-core laptop with SSD analyses around 14000
tracks/hour. tracks/hour.
Tags
----
When analysing tracks, the analyser will first check for a `BLISS_ANALYSIS` tag
within the file, and if found this will be used instead of re-analysing the file.
If `--tags` is passed, the analysis results will be stored within a `BLISS_ANALYSIS`
tag in the file itself. Note, however, that only tracks that are not currently in
the database will be analysed - therefore any such tracks would not have the
`BLISS_ANALYSIS` tag updated. To export analysis results from the database to
files themselves use the `export` task.
*NOTE* USe of the `BLISS_ANALYSIS` tag is not supported for CUE files.
CUE files CUE files
--------- ---------
+14 -22
View File
@@ -44,7 +44,7 @@ const MAX_ERRORS_TO_SHOW: usize = 100;
const MAX_TAG_ERRORS_TO_SHOW: usize = 50; const MAX_TAG_ERRORS_TO_SHOW: usize = 50;
const VALID_EXTENSIONS: [&str; 7] = ["m4a", "mp3", "ogg", "flac", "opus", "wv", "dsf"]; const VALID_EXTENSIONS: [&str; 7] = ["m4a", "mp3", "ogg", "flac", "opus", "wv", "dsf"];
fn get_file_list(db: &mut db::Db, mpath: &Path, path: &Path, track_paths: &mut Vec<String>, cue_tracks:&mut Vec<cue::CueTrack>, file_count:&mut usize, max_num_files: usize, read_tags: bool, tagged_file_count:&mut usize, dry_run: bool) { fn get_file_list(db: &mut db::Db, mpath: &Path, path: &Path, track_paths: &mut Vec<String>, cue_tracks:&mut Vec<cue::CueTrack>, file_count:&mut usize, max_num_files: usize, tagged_file_count:&mut usize, dry_run: bool) {
if !path.is_dir() { if !path.is_dir() {
return; return;
} }
@@ -53,21 +53,21 @@ fn get_file_list(db: &mut db::Db, mpath: &Path, path: &Path, track_paths: &mut V
items.sort_by_key(|dir| dir.path()); items.sort_by_key(|dir| dir.path());
for item in items { for item in items {
check_dir_entry(db, mpath, item, track_paths, cue_tracks, file_count, max_num_files, read_tags, tagged_file_count, dry_run); check_dir_entry(db, mpath, item, track_paths, cue_tracks, file_count, max_num_files, tagged_file_count, dry_run);
if max_num_files>0 && *file_count>=max_num_files { if max_num_files>0 && *file_count>=max_num_files {
break; break;
} }
} }
} }
fn check_dir_entry(db: &mut db::Db, mpath: &Path, entry: DirEntry, track_paths: &mut Vec<String>, cue_tracks:&mut Vec<cue::CueTrack>, file_count:&mut usize, max_num_files: usize, read_tags: bool, tagged_file_count:&mut usize, dry_run: bool) { fn check_dir_entry(db: &mut db::Db, mpath: &Path, entry: DirEntry, track_paths: &mut Vec<String>, cue_tracks:&mut Vec<cue::CueTrack>, file_count:&mut usize, max_num_files: usize, tagged_file_count:&mut usize, dry_run: bool) {
let pb = entry.path(); let pb = entry.path();
if pb.is_dir() { if pb.is_dir() {
let check = pb.join(DONT_ANALYSE); let check = pb.join(DONT_ANALYSE);
if check.exists() { if check.exists() {
log::info!("Skipping '{}', found '{}'", pb.to_string_lossy(), DONT_ANALYSE); log::info!("Skipping '{}', found '{}'", pb.to_string_lossy(), DONT_ANALYSE);
} else if max_num_files<=0 || *file_count<max_num_files { } else if max_num_files<=0 || *file_count<max_num_files {
get_file_list(db, mpath, &pb, track_paths, cue_tracks, file_count, max_num_files, read_tags, tagged_file_count, dry_run); get_file_list(db, mpath, &pb, track_paths, cue_tracks, file_count, max_num_files, tagged_file_count, dry_run);
} }
} else if pb.is_file() && (max_num_files<=0 || *file_count<max_num_files) { } else if pb.is_file() && (max_num_files<=0 || *file_count<max_num_files) {
if_chain! { if_chain! {
@@ -109,15 +109,13 @@ fn check_dir_entry(db: &mut db::Db, mpath: &Path, entry: DirEntry, track_paths:
if let Ok(id) = db.get_rowid(&sname) { if let Ok(id) = db.get_rowid(&sname) {
if id<=0 { if id<=0 {
let mut tags_used = false; let mut tags_used = false;
if read_tags { let meta = tags::read(&String::from(pb.to_string_lossy()), true);
let meta = tags::read(&String::from(pb.to_string_lossy()), true); if !meta.is_empty() && !meta.analysis.is_none() {
if !meta.is_empty() && !meta.analysis.is_none() { if !dry_run {
if !dry_run { db.add_track(&sname, &meta, &meta.analysis.unwrap());
db.add_track(&sname, &meta, &meta.analysis.unwrap());
}
*tagged_file_count+=1;
tags_used = true;
} }
*tagged_file_count+=1;
tags_used = true;
} }
if !tags_used { if !tags_used {
@@ -404,7 +402,7 @@ fn analyse_new_cue_tracks(db:&db::Db, mpath: &PathBuf, cue_tracks:Vec<cue::CueTr
Ok(()) Ok(())
} }
pub fn analyse_files(db_path: &str, mpaths: &Vec<PathBuf>, dry_run: bool, keep_old: bool, max_num_files: usize, max_threads: usize, ignore_path: &PathBuf, read_tags: bool, write_tags: bool, preserve_mod_times: bool) { pub fn analyse_files(db_path: &str, mpaths: &Vec<PathBuf>, dry_run: bool, keep_old: bool, max_num_files: usize, max_threads: usize, ignore_path: &PathBuf, write_tags: bool, preserve_mod_times: bool) {
let mut db = db::Db::new(&String::from(db_path)); let mut db = db::Db::new(&String::from(db_path));
db.init(); db.init();
@@ -427,19 +425,13 @@ pub fn analyse_files(db_path: &str, mpaths: &Vec<PathBuf>, dry_run: bool, keep_o
} else { } else {
log::info!("Looking for new files"); log::info!("Looking for new files");
} }
get_file_list(&mut db, &mpath, &cur, &mut track_paths, &mut cue_tracks, &mut file_count, max_num_files, read_tags, &mut tagged_file_count, dry_run); get_file_list(&mut db, &mpath, &cur, &mut track_paths, &mut cue_tracks, &mut file_count, max_num_files, &mut tagged_file_count, dry_run);
track_paths.sort(); track_paths.sort();
if read_tags { log::info!("New untagged files: {}", track_paths.len());
log::info!("New untagged files: {}", track_paths.len());
} else {
log::info!("New files: {}", track_paths.len());
}
if !cue_tracks.is_empty() { if !cue_tracks.is_empty() {
log::info!("New cue tracks: {}", cue_tracks.len()); log::info!("New cue tracks: {}", cue_tracks.len());
} }
if read_tags { log::info!("New tagged files: {}", tagged_file_count);
log::info!("New tagged files: {}", tagged_file_count);
}
if dry_run { if dry_run {
if !track_paths.is_empty() || !cue_tracks.is_empty() { if !track_paths.is_empty() || !cue_tracks.is_empty() {
+2 -14
View File
@@ -41,8 +41,6 @@ fn main() {
let mut max_num_files: usize = 0; let mut max_num_files: usize = 0;
let mut music_paths: Vec<PathBuf> = Vec::new(); let mut music_paths: Vec<PathBuf> = Vec::new();
let mut max_threads: usize = 0; let mut max_threads: usize = 0;
let mut use_tags = false;
let mut read_tags = false;
let mut write_tags = false; let mut write_tags = false;
let mut preserve_mod_times = false; let mut preserve_mod_times = false;
@@ -78,9 +76,7 @@ fn main() {
arg_parse.refer(&mut lms_json_port).add_option(&["-J", "--json"], Store, &lms_json_port_help); arg_parse.refer(&mut lms_json_port).add_option(&["-J", "--json"], Store, &lms_json_port_help);
arg_parse.refer(&mut max_num_files).add_option(&["-n", "--numfiles"], Store, "Maximum number of files to analyse"); arg_parse.refer(&mut max_num_files).add_option(&["-n", "--numfiles"], Store, "Maximum number of files to analyse");
arg_parse.refer(&mut max_threads).add_option(&["-t", "--threads"], Store, "Maximum number of threads to use for analysis"); arg_parse.refer(&mut max_threads).add_option(&["-t", "--threads"], Store, "Maximum number of threads to use for analysis");
arg_parse.refer(&mut read_tags).add_option(&["-R", "--read-tags"], StoreTrue, "Read analysis results from file tags"); arg_parse.refer(&mut write_tags).add_option(&["-T", "--tags"], StoreTrue, "When analysing files, also store resutls within fiules themselves");
arg_parse.refer(&mut write_tags).add_option(&["-W", "--write-tags"], StoreTrue, "Write analysis results to file tags");
arg_parse.refer(&mut use_tags).add_option(&["-T", "--tags"], StoreTrue, "Read tags if present, and write tags if not present - this option is the same as supplying both --read-tags and --write-tags");
arg_parse.refer(&mut preserve_mod_times).add_option(&["-p", "--preserve"], StoreTrue, "Preserve modification time when writing tags to files"); arg_parse.refer(&mut preserve_mod_times).add_option(&["-p", "--preserve"], StoreTrue, "Preserve modification time when writing tags to files");
arg_parse.refer(&mut task).add_argument("task", Store, "Task to perform; analyse, tags, ignore, upload, export, stopmixer."); arg_parse.refer(&mut task).add_argument("task", Store, "Task to perform; analyse, tags, ignore, upload, export, stopmixer.");
arg_parse.parse_args_or_exit(); arg_parse.parse_args_or_exit();
@@ -150,14 +146,6 @@ fn main() {
None => { } None => { }
} }
match config.get(TOP_LEVEL_INI_TAG, "tags") { match config.get(TOP_LEVEL_INI_TAG, "tags") {
Some(val) => { use_tags = val.eq("true"); }
None => { }
}
match config.get(TOP_LEVEL_INI_TAG, "read_tags") {
Some(val) => { read_tags = val.eq("true"); }
None => { }
}
match config.get(TOP_LEVEL_INI_TAG, "write_tags") {
Some(val) => { write_tags = val.eq("true"); } Some(val) => { write_tags = val.eq("true"); }
None => { } None => { }
} }
@@ -228,7 +216,7 @@ fn main() {
db::export(&db_path, &music_paths, max_threads, preserve_mod_times); db::export(&db_path, &music_paths, max_threads, preserve_mod_times);
} else { } else {
let ignore_path = PathBuf::from(&ignore_file); let ignore_path = PathBuf::from(&ignore_file);
analyse::analyse_files(&db_path, &music_paths, dry_run, keep_old, max_num_files, max_threads, &ignore_path, use_tags||read_tags, use_tags||write_tags, preserve_mod_times); analyse::analyse_files(&db_path, &music_paths, dry_run, keep_old, max_num_files, max_threads, &ignore_path, write_tags, preserve_mod_times);
} }
} }
} }