broken changes
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import hashlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
root = Path.home() / 'Library/Application Support/KJamsClone/DJ'
|
||||
media = root / 'Media'
|
||||
def digest(path):
|
||||
h = hashlib.sha256()
|
||||
with path.open('rb') as stream:
|
||||
for chunk in iter(lambda: stream.read(1024 * 1024), b''):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
with sqlite3.connect(f'file:{root / "Library.sqlite"}?mode=ro', uri=True) as db:
|
||||
originals = [Path(row[0]) for row in db.execute('select original_path from songs') if row[0]]
|
||||
# Include the failed, unregistered source only within the same explicitly imported folder.
|
||||
folders = {p.parent for p in originals}
|
||||
sources = set(originals)
|
||||
for folder in folders:
|
||||
sources.update(p for p in folder.iterdir() if p.is_file() and p.suffix.lower() == '.mp3')
|
||||
repairs = []
|
||||
for source in sorted(sources):
|
||||
if not source.is_file() or source.stat().st_size == 0:
|
||||
continue
|
||||
expected = digest(source)
|
||||
target = media / (expected + source.suffix.lower())
|
||||
if target.is_file() and target.stat().st_size == 0:
|
||||
repairs.append((source, target, expected))
|
||||
print(f'Verified {len(repairs)} empty DJ copies with matching original audio.')
|
||||
if '--apply' in sys.argv:
|
||||
for source, target, expected in repairs:
|
||||
descriptor, temporary = tempfile.mkstemp(prefix='.kjmix-repair-', dir=media)
|
||||
try:
|
||||
with os.fdopen(descriptor, 'wb') as output, source.open('rb') as input_stream:
|
||||
for chunk in iter(lambda: input_stream.read(1024 * 1024), b''):
|
||||
output.write(chunk)
|
||||
output.flush()
|
||||
os.fsync(output.fileno())
|
||||
assert digest(Path(temporary)) == expected
|
||||
assert target.stat().st_size == 0, 'Destination changed; refusing to replace it'
|
||||
os.chmod(temporary, 0o644)
|
||||
os.replace(temporary, target)
|
||||
print(f'Repaired verified audio: {target.name} ({target.stat().st_size} bytes)')
|
||||
finally:
|
||||
if os.path.exists(temporary):
|
||||
os.unlink(temporary)
|
||||
Reference in New Issue
Block a user