First step for a config file
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -180,3 +180,5 @@ cython_debug/
|
||||
.cursorignore
|
||||
.cursorindexingignore
|
||||
|
||||
# ed1337x
|
||||
config.ini
|
||||
|
80
src/app.py
80
src/app.py
@@ -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
|
||||
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"): # <-- recursive glob
|
||||
for file in source_media_path.rglob("*.mp3"):
|
||||
bpm = get_bpm(file)
|
||||
size = file.stat().st_size
|
||||
if bpm is None:
|
||||
@@ -48,7 +87,7 @@ for file in source_media_path.rglob("*.mp3"): # <-- recursive glob
|
||||
|
||||
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)
|
||||
@@ -66,10 +105,6 @@ 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():
|
||||
bpm_chunks[bpm_range] = split_evenly(tracks, num_cds)
|
||||
@@ -96,3 +131,6 @@ for i, tracks in enumerate(cd_contents, start=1):
|
||||
|
||||
print("\n✅ Done!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
4
src/def_config.ini
Normal file
4
src/def_config.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
[Settings]
|
||||
bCheckNonPresentBPM = False
|
||||
bReCheckPresentBPM = False
|
||||
SplitFolderMB = 695
|
Reference in New Issue
Block a user