Created
February 3, 2018 21:50
-
-
Save rpuntaie/7b4d017848009afebcd1525db1e4272f to your computer and use it in GitHub Desktop.
resort badly organized mp3s with a python script that generates a .bat or .sh that does the actual resorting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
#py.test --doctest-modules resortmp3.py | |
import sys | |
import re | |
import os | |
from collections import defaultdict | |
from numpy import base_repr | |
import subprocess | |
_fnencoding = sys.getfilesystemencoding() | |
tounknown='Downloads,artist,Artist,Interpret,interpret,Kein,kein,Unbekannt,unbekannt,Unknown,unknown'.split(',') | |
def tou(x): | |
uk = 'unknown' | |
for u in tounknown: | |
if x.startswith(u): | |
return uk | |
if re.search('www\.',x): | |
return uk | |
rex=r'(\d+)\s+(.*)' | |
if re.match(rex,x): | |
x=re.sub(rex,r'\2',x) | |
x=x.strip('_') | |
if not x: | |
return uk | |
return x | |
fn=lambda x: '"'+os.path.normpath(x)+'"' | |
sofar=defaultdict(int) | |
def newdf(al,outdir=''): | |
""" | |
>>> al = "downloads/vance joy - first time.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "downloads/vance joy" & move /Y "downloads/vance joy - first time.mp3" "downloads/vance joy/first time.mp3"' | |
>>> al="./Music/iTunes/iTunes Media/Music/Unbekannter Interpret/Unbekanntes Album (02.06.2007 12_23_46)/09 Titel 9.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "unknown/unknown" & move /Y "Music/iTunes/iTunes Media/Music/Unbekannter Interpret/Unbekanntes Album (02.06.2007 12_23_46)/09 Titel 9.mp3" "unknown/unknown/09 Titel 9.mp3"' | |
>>> al= "./Downloads/Our Endless Numbered Days (Full Album) By- Iron and Wine-2.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "unknown/Our Endless Numbered Days (Full Album) By" & move /Y "Downloads/Our Endless Numbered Days (Full Album) By- Iron and Wine-2.mp3" "unknown/Our Endless Numbered Days (Full Album) By/Iron and Wine-2.mp3"' | |
>>> al= "./Music/iTunes/iTunes Media/Music/3 Feet Smaller/3rd Strike/03 Strike back.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "Feet Smaller/3rd Strike" & move /Y "Music/iTunes/iTunes Media/Music/3 Feet Smaller/3rd Strike/03 Strike back.mp3" "Feet Smaller/3rd Strike/03 Strike back.mp3"' | |
>>> al="./Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/01 KC Taylor & Didier Vanelli - ElectroFuck - Remix Attack - Pacha Recordings.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "ElectroFuck/Remix Attack" & move /Y "Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/01 KC Taylor & Didier Vanelli - ElectroFuck - Remix Attack - Pacha Recordings.mp3" "ElectroFuck/Remix Attack/Pacha Recordings.mp3"' | |
>>> al= "Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/11 - Trouble.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "unknown/unknown" & move /Y "Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/11 - Trouble.mp3" "unknown/unknown/Trouble.mp3"' | |
>>> al= "Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/BEE GEES - The Very Best Of - 01 - New York mining disaster.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "BEE GEES/The Very Best Of" & move /Y "Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/BEE GEES - The Very Best Of - 01 - New York mining disaster.mp3" "BEE GEES/The Very Best Of/New York mining disaster.mp3"' | |
>>> al="Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/Andrew_Spencer_Dj_Gollum_-_In_The_Shadows_(DJ_Gollum_Mix)_www[1].technorocker.info.mp3" | |
>>> newdf(al).replace('\\\\','/') | |
'mkdir "unknown/unknown" & move /Y "Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/Andrew_Spencer_Dj_Gollum_-_In_The_Shadows_(DJ_Gollum_Mix)_www[1].technorocker.info.mp3" "unknown/unknown/Andrew_Spencer_Dj_Gollum_-_In_The_Shadows_(DJ_Gollum_Mix).mp3"' | |
""" | |
global sofar | |
ln_s=[xx for xx in [x.strip() for x in re.split(r'/|__| |\s*-\s+',al)[-4:]] if re.sub('\d','',xx).strip()] | |
ln_s=ln_s[-3:] | |
d=[tou(ln_s[0]),tou(ln_s[1]),ln_s[2]] | |
if 'www' in d[-1]: | |
d[-1]=re.sub('(\w+)\s*www.*',r'\1',d[-1]).strip('_')+'.mp3' | |
nd = os.sep.join(d[:2]) | |
nf = os.sep.join(d) | |
sofar[nf]+=1 | |
if sofar[nf]>1: | |
sofar[nd]+=1 | |
nd = os.path.join(nd+base_repr(sofar[nd],36)) | |
nf = os.path.join(nd,d[-1]) | |
nd = os.path.join(outdir,nd) | |
nf = os.path.join(outdir,nf) | |
if sys.platform=='win32': | |
mv = 'mkdir {1} & move /Y {0} {2}'.format( | |
fn(al) | |
,fn(nd) | |
,fn(nf) | |
) | |
else: | |
mv = 'mkdir -p {1} & mv {0} {2}'.format( | |
fn(al) | |
,fn(nd) | |
,fn(nf) | |
) | |
return mv | |
if __name__ == '__main__': | |
assert len(sys.argv)==2, "provide output folder" | |
po=subprocess.Popen(["find",".","-name","*.mp3"],stdout=subprocess.PIPE) | |
lns=po.stdout.read().decode(encoding=_fnencoding).splitlines() | |
if sys.platform=='win32': | |
outfn = 'resortmp3.bat' | |
else: | |
outfn = 'resortmp3.sh' | |
nedf = lambda x: newdf(x,outdir=sys.argv[1]) | |
with open(outfn,'w',encoding=_fnencoding) as f: | |
f.write('\n'.join([nedf(al.strip()) for al in lns])) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment