First step for a config file

This commit is contained in:
Roncero Blanco, Edgar
2025-05-26 15:33:07 +02:00
parent dfe237d3ea
commit 63953f45e8
3 changed files with 110 additions and 66 deletions

2
.gitignore vendored
View File

@@ -180,3 +180,5 @@ cython_debug/
.cursorignore
.cursorindexingignore
# ed1337x
config.ini

View File

@@ -4,26 +4,38 @@ from pathlib import Path
from mutagen.id3 import ID3
from datetime import datetime
from collections import defaultdict
import configparser
import sys
CD_SIZE = 695 * 1024 * 1024 # 695 MB
GROUP_SIZE = 5
# Store the current date
run_date = datetime.now().strftime("%Y-%m-%d_%H%M%S")
def load_config():
config_path = Path("config.ini")
default_config_path = Path("def_config.ini")
# Ask for source path, strip quotes if pasted
source_input = input("Drag and drop your music folder here, then press Enter: ").strip().strip('"')
source_media_path = Path(source_input)
# If config.ini missing, copy def_config.ini
if not config_path.exists():
if default_config_path.exists():
shutil.copy(default_config_path, config_path)
print("config.ini created from def_config.ini with default settings.")
else:
print("Error: def_config.ini not found! Please create it and rerun.")
sys.exit(1)
if not source_media_path.exists() or not source_media_path.is_dir():
print(f"Error: {source_media_path} is not a valid directory.")
exit(1)
# Read default config
default_config = configparser.ConfigParser()
default_config.read(default_config_path)
# Build destination path
parent = source_media_path.parent
folder_name = source_media_path.name
dest_media_path = parent / f"[CDs-{run_date}]{folder_name}"
dest_media_path.mkdir(parents=True, exist_ok=True)
# Read user config (overrides default)
user_config = configparser.ConfigParser()
user_config.read(config_path)
# Merge configs: start with defaults, update with user settings
merged_config = configparser.ConfigParser()
merged_config.read_dict(default_config)
merged_config.read_dict(user_config)
return merged_config
def get_bpm(file_path):
try:
@@ -35,9 +47,36 @@ def get_bpm(file_path):
print(f"Skipping {file_path.name} (no BPM): {e}")
return None
# Collect all tracks recursively, grouping unknown BPM separately
all_tracks = []
for file in source_media_path.rglob("*.mp3"): # <-- recursive glob
def split_evenly(lst, n):
k, m = divmod(len(lst), n)
return [lst[i*k + min(i, m):(i+1)*k + min(i+1, m)] for i in range(n)]
def main():
config = load_config()
# Use SplitFolderMB from config, convert MB to bytes
CD_SIZE = config.getint("Settings", "SplitFolderMB") * 1024 * 1024
# Store the current date for folder naming
run_date = datetime.now().strftime("%Y-%m-%d_%H%M%S")
# Ask for source path, strip quotes if pasted
source_input = input("Drag and drop your music folder here, then press Enter: ").strip().strip('"')
source_media_path = Path(source_input)
if not source_media_path.exists() or not source_media_path.is_dir():
print(f"Error: {source_media_path} is not a valid directory.")
sys.exit(1)
# Build destination path
parent = source_media_path.parent
folder_name = source_media_path.name
dest_media_path = parent / f"[CDs-{run_date}]{folder_name}"
dest_media_path.mkdir(parents=True, exist_ok=True)
# Collect all tracks recursively, group unknown BPM separately
all_tracks = []
for file in source_media_path.rglob("*.mp3"):
bpm = get_bpm(file)
size = file.stat().st_size
if bpm is None:
@@ -46,44 +85,40 @@ for file in source_media_path.rglob("*.mp3"): # <-- recursive glob
bpm_range = f"{(bpm // GROUP_SIZE) * GROUP_SIZE}-to-{((bpm // GROUP_SIZE) * GROUP_SIZE) + GROUP_SIZE - 1}"
all_tracks.append({"file": file, "size": size, "bpm_range": bpm_range})
if not all_tracks:
if not all_tracks:
print("No MP3 files found.")
exit(0)
sys.exit(0)
# Calculate total size and number of CDs needed
total_size = sum(t["size"] for t in all_tracks)
num_cds = max(1, (total_size + CD_SIZE - 1) // CD_SIZE)
# Calculate total size and number of CDs needed
total_size = sum(t["size"] for t in all_tracks)
num_cds = max(1, (total_size + CD_SIZE - 1) // CD_SIZE)
print(f"Total size: {total_size / 1024**2:.2f} MB, splitting into {num_cds} CDs")
print(f"Total size: {total_size / 1024**2:.2f} MB, splitting into {num_cds} CDs")
# Group tracks by BPM range
bpm_groups = defaultdict(list)
for track in all_tracks:
# Group tracks by BPM range
bpm_groups = defaultdict(list)
for track in all_tracks:
bpm_groups[track["bpm_range"]].append(track)
# Sort each bpm group
for bpm_range in bpm_groups:
# Sort each bpm group
for bpm_range in bpm_groups:
bpm_groups[bpm_range].sort(key=lambda x: x["file"].name)
# Split each BPM group evenly into num_cds parts
def split_evenly(lst, n):
k, m = divmod(len(lst), n)
return [lst[i*k + min(i, m):(i+1)*k + min(i+1, m)] for i in range(n)]
bpm_chunks = {}
for bpm_range, tracks in bpm_groups.items():
# Split each BPM group evenly into num_cds parts
bpm_chunks = {}
for bpm_range, tracks in bpm_groups.items():
bpm_chunks[bpm_range] = split_evenly(tracks, num_cds)
# Prepare CDs
cd_contents = [[] for _ in range(num_cds)]
# Prepare CDs
cd_contents = [[] for _ in range(num_cds)]
# Fill CDs with balanced BPM chunks
for bpm_range in bpm_chunks:
# Fill CDs with balanced BPM chunks
for bpm_range in bpm_chunks:
for i, chunk in enumerate(bpm_chunks[bpm_range]):
cd_contents[i].extend(chunk)
# Write CDs with BPM subfolders
for i, tracks in enumerate(cd_contents, start=1):
# Write CDs with BPM subfolders
for i, tracks in enumerate(cd_contents, start=1):
cd_folder = dest_media_path / f"CD-{i:02}"
cd_folder.mkdir(parents=True, exist_ok=True)
size_accum = 0
@@ -94,5 +129,8 @@ for i, tracks in enumerate(cd_contents, start=1):
size_accum += track["size"]
print(f"[WRITE] CD-{i:02}: {len(tracks)} tracks, approx {size_accum/1024**2:.2f} MB")
print("\n✅ Done!")
print("\n✅ Done!")
if __name__ == "__main__":
main()

4
src/def_config.ini Normal file
View File

@@ -0,0 +1,4 @@
[Settings]
bCheckNonPresentBPM = False
bReCheckPresentBPM = False
SplitFolderMB = 695