is this wrong, feels so wrong
This commit is contained in:
parent
b4eeededf8
commit
f7ac8f0704
1 changed files with 31 additions and 56 deletions
87
unsync.py
87
unsync.py
|
@ -13,6 +13,10 @@ import mutagen
|
||||||
import mutaext
|
import mutaext
|
||||||
import convert
|
import convert
|
||||||
|
|
||||||
|
# BUG: doesn't work with my .m4a files?
|
||||||
|
goodexts = ('.mp3', '.m4a', '.flac', '.ogg')
|
||||||
|
|
||||||
|
matchtags = ['artist', 'album', 'title']
|
||||||
updatabletags = [\
|
updatabletags = [\
|
||||||
'albumartist', 'composer', 'comment' \
|
'albumartist', 'composer', 'comment' \
|
||||||
'tracknumber', 'discnumber', \
|
'tracknumber', 'discnumber', \
|
||||||
|
@ -20,99 +24,71 @@ updatabletags = [\
|
||||||
]
|
]
|
||||||
updatabletags.extend(mutaext.replaygain_tags)
|
updatabletags.extend(mutaext.replaygain_tags)
|
||||||
updatabletags.extend(mutaext.extra_tags)
|
updatabletags.extend(mutaext.extra_tags)
|
||||||
|
|
||||||
alltags = list(updatabletags)
|
alltags = list(updatabletags)
|
||||||
alltags.extend(['artist', 'album', 'title'])
|
alltags.extend(matchtags)
|
||||||
|
|
||||||
def walkfiles(walker):
|
lament = lambda *args, **kwargs: print(*args, file=sys.stderr, **kwargs)
|
||||||
for root, _, files in walker:
|
walkfiles = lambda w: (os.path.join(r, f) for r, _, fs in w for f in fs)
|
||||||
for f in files:
|
extof = lambda p: os.path.splitext(p)[1].lower()
|
||||||
yield os.path.join(root, f)
|
filterext = lambda ps, es: (p for p in ps if extof(p) in es)
|
||||||
|
|
||||||
def filterext(paths, exts):
|
|
||||||
for p in paths:
|
|
||||||
ext = os.path.splitext(p)[1].lower()
|
|
||||||
if ext in exts:
|
|
||||||
yield p
|
|
||||||
|
|
||||||
def shouldsync(md):
|
def shouldsync(md):
|
||||||
rating = md.get('rating')
|
rating = md.get('rating')
|
||||||
sync = md.get('sync', u'')
|
sync = md.get('sync', u'')
|
||||||
try:
|
try:
|
||||||
rating = int(rating[0])
|
rating = int(rating[0])
|
||||||
except:
|
except (IndexError, ValueError):
|
||||||
pass
|
pass
|
||||||
if sync:
|
if sync:
|
||||||
sync = sync[0].lower()
|
sync = sync[0].lower()
|
||||||
|
|
||||||
if sync == u'no' or sync == u'space':
|
return sync == 'yes' or type(rating) == int and rating >= 3 and not sync is 'no' and not sync is 'space'
|
||||||
return False
|
|
||||||
if sync == u'yes' or sync == u'share':
|
|
||||||
return True
|
|
||||||
if type(rating) == int and rating >= 3:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def fixmetadata(md):
|
def fixmetadata(md):
|
||||||
md['artist'] = md.get('artist', "Unknown Artist")
|
md['artist'] = md.get('artist', u"Unknown Artist")
|
||||||
md['album'] = md.get('album', "Unknown Album")
|
md['album'] = md.get('album', u"Unknown Album")
|
||||||
if 'title' not in md:
|
if 'title' not in md:
|
||||||
fn = os.path.basename(md.path)
|
fn = os.path.basename(md.path)
|
||||||
fn = os.path.splitext(fn)[0]
|
fn = os.path.splitext(fn)[0]
|
||||||
# TODO: attempt to infer trackNum/discNum from fn
|
# TODO: attempt to infer trackNum/discNum from fn
|
||||||
md['title'] = fn
|
md['title'] = unicode(fn)
|
||||||
|
|
||||||
def findmatching(haystack, needle):
|
def findmatching(haystack, needle):
|
||||||
# TODO: don't match mismatched lengths (Xing?)
|
matchme = [needle[t] for t in matchtags]
|
||||||
artist = needle.get('artist')
|
ismatch = lambda hay: [hay[t] for t in matchtags] == matchme
|
||||||
album = needle.get('album')
|
for match in (hay for hay in haystack if ismatch(hay)):
|
||||||
title = needle.get('title')
|
if match.seen:
|
||||||
match = None
|
# TODO: check other tags and filename and such?
|
||||||
for hay in haystack:
|
lament("Warning: duplicate match found:")
|
||||||
if artist == hay.get('artist') \
|
lament(u"%(title)s by %(artist)s from %(album)s" % locals())
|
||||||
and album == hay.get('album') \
|
match.seen = True
|
||||||
and title == hay.get('title'):
|
return match
|
||||||
match = hay
|
|
||||||
if match.seen:
|
|
||||||
# TODO: check other tags and filename and such?
|
|
||||||
print("Warning: duplicate match found:", file=sys.stderr)
|
|
||||||
print("{0} by {1} from {2}".format(artist,album,title), file=sys.stderr)
|
|
||||||
else:
|
|
||||||
match.seen = True
|
|
||||||
break
|
|
||||||
return match
|
|
||||||
|
|
||||||
def updatemetadata(mdold, mdnew):
|
def updatemetadata(mdold, mdnew):
|
||||||
modified = False
|
modified = False
|
||||||
for tag in updatabletags:
|
for tag in updatabletags:
|
||||||
|
# checking for length b/c sometimes (ID3 genre) exists but empty
|
||||||
if tag in mdnew and len(mdnew[tag]):
|
if tag in mdnew and len(mdnew[tag]):
|
||||||
if not tag in mdold or mdnew[tag][0] != mdold[tag][0]:
|
if not tag in mdold or mdnew[tag][0] != mdold[tag][0]:
|
||||||
mdold[tag] = mdnew[tag]
|
mdold[tag] = mdnew[tag]
|
||||||
modified = True
|
modified = True
|
||||||
elif tag in mdold:
|
elif tag in mdold:
|
||||||
del mdold[tag]
|
del mdold[tag]
|
||||||
print('del', tag)
|
|
||||||
modified = True
|
modified = True
|
||||||
return modified
|
return modified
|
||||||
|
|
||||||
def makefilename(md):
|
def makefilename(md):
|
||||||
fn = ""
|
|
||||||
title = md['title'][0]
|
title = md['title'][0]
|
||||||
artist = md['artist'][0]
|
artist = md['artist'][0]
|
||||||
album = md['album'][0]
|
album = md['album'][0]
|
||||||
fn = u"{1} - {2} - {0}".format(title,artist,album)
|
return u"%(artist)s - %(album)s - %(title)s.ogg" % locals()
|
||||||
fn += ".ogg"
|
|
||||||
return fn
|
|
||||||
|
|
||||||
def run(args):
|
def run(args):
|
||||||
if not len(args) in (2, 3):
|
if not len(args) in (2, 3):
|
||||||
print("I need a path or two!", file=sys.stderr)
|
lament("I need a path or two!")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
inonly = len(args) == 2
|
inonly = len(args) == 2
|
||||||
|
|
||||||
# BUG: doesn't work with my .m4a files?
|
|
||||||
goodexts = ('.mp3', '.m4a', '.flac', '.ogg')
|
|
||||||
tosync = []
|
tosync = []
|
||||||
indir = args[1]
|
indir = args[1]
|
||||||
paths = lambda dir: filterext(walkfiles(os.walk(dir)), goodexts)
|
paths = lambda dir: filterext(walkfiles(os.walk(dir)), goodexts)
|
||||||
|
@ -132,19 +108,18 @@ def run(args):
|
||||||
if inonly:
|
if inonly:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
print("Matching...", file=sys.stderr)
|
lament("Matching...")
|
||||||
|
|
||||||
outdir = args[2]
|
outdir = args[2]
|
||||||
for p in paths(outdir):
|
for p in paths(outdir):
|
||||||
md = mutagen.File(p, easy=True)
|
md = mutagen.File(p, easy=True)
|
||||||
match = findmatching(tosync, md)
|
match = findmatching(tosync, md)
|
||||||
if match:
|
if not match:
|
||||||
if updatemetadata(md, match):
|
|
||||||
print("UPD", p)
|
|
||||||
md.save()
|
|
||||||
else:
|
|
||||||
print("DEL", p)
|
print("DEL", p)
|
||||||
os.remove(p)
|
os.remove(p)
|
||||||
|
elif updatemetadata(md, match):
|
||||||
|
print("UPD", p)
|
||||||
|
md.save()
|
||||||
|
|
||||||
for md in tosync:
|
for md in tosync:
|
||||||
if md.seen:
|
if md.seen:
|
||||||
|
|
Loading…
Reference in a new issue