diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/bin/activate.sh b/bin/activate.sh new file mode 100755 index 0000000..8624131 --- /dev/null +++ b/bin/activate.sh @@ -0,0 +1 @@ +source .venv/bin/activate diff --git a/bin/run.sh b/bin/run.sh new file mode 100755 index 0000000..0e287fe --- /dev/null +++ b/bin/run.sh @@ -0,0 +1,2 @@ +source bin/activate.sh +python -m tagger.run $* diff --git a/bin/setup.sh b/bin/setup.sh new file mode 100755 index 0000000..03ec6d9 --- /dev/null +++ b/bin/setup.sh @@ -0,0 +1,5 @@ +[[ -d .venv ]] && rm -rf .venv +python -m venv .venv +source .venv/bin/activate +pip install --upgrade pip +pip install -r requirements.txt diff --git a/bin/test.sh b/bin/test.sh new file mode 100755 index 0000000..30dd01e --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,2 @@ +source bin/activate.sh +pytest tagger -vv $* diff --git a/bin/watch_test.sh b/bin/watch_test.sh new file mode 100755 index 0000000..16cd96b --- /dev/null +++ b/bin/watch_test.sh @@ -0,0 +1,2 @@ +source bin/activate.sh +watch -c "pytest -q --color=yes --tb=short tagger" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f6e1626 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +mutagen==1.47.0 diff --git a/sample/stardust.mp3 b/sample/stardust.mp3 new file mode 100644 index 0000000..c9e62e3 Binary files /dev/null and b/sample/stardust.mp3 differ diff --git a/tagger/__init__.py b/tagger/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tagger/run.py b/tagger/run.py new file mode 100644 index 0000000..a84e9ca --- /dev/null +++ b/tagger/run.py @@ -0,0 +1,69 @@ +from mutagen import File +from pathlib import Path + +import json +import sys + +# Constants ######################################################################################## + +KEYS = { + "GRID": "group-identification", + "GRP1": "itunes-group", + "MVIN": "itunes-movement-number-count", + "MVNM": "itunes-movement-name", + "OWNE": "ownership", + "PCNT": "play-count", + "PRIV": "private", + "TALB": "album", + "TBPM": "beats-per-minute", + "TCMP": "itunes-compilation-flag", + "TCOM": "composer", + "TCON": "content-type-genre", + "TCOP": "copyright", + "TDAT": "recording-date", # DDMM format + "TEXT": "lyricist", + "TIME": "recording-time", # HHMM format + "TIPL": "involved-people-list", + "TIT1": "content-group-description", + "TIT2": "title", + "TIT3": "subtitle", + "TMCL": "musicians-list", + "TMOO": "mood", + "TOWN": "owner", + "TPE1": "lead-artist-performer-soloist", + "TPE2": "band-orchestra-accompanist", + "TPE3": "conductor", + "TPE4": "iterpreter-remixer", + "TPOS": "part-of-set", + "TRCK": "track-number", # n/m format + "TSO2": "itunes-album-artist-sort-key", + "TSOA": "album-sort-key", + "TSOC": "itunes-composer-sort-key", + "TSOP": "performer-sort-key", + "TSOT": "title-sort-key", + "TXXX": "user-data", + "TYER": "recording-year", +} + +# Script ########################################################################################### + +if __name__ == "__main__": + results:dict[str, dict[str,str|None]] = {} + + sourcePath = Path(sys.argv[1]) + for path in sorted(sourcePath.iterdir()): + file = File(path) + if not file: continue + + pathText = str(path) + results[pathText] = {} + + for code, key in KEYS.items(): + if code in file: + results[pathText][key] = file[code].text + else: + results[pathText][key] = None + + targetFile = sourcePath / "tags.json" + with targetFile.open("w") as file: + file.write(json.dumps(results, indent=" "))