Skip to content

Instantly share code, notes, and snippets.

@rozap
Last active August 29, 2015 13:57
Show Gist options
  • Save rozap/9847622 to your computer and use it in GitHub Desktop.
Save rozap/9847622 to your computer and use it in GitHub Desktop.
music organizer
import os
from os import path as ospath
import sys
from mutagen.easyid3 import EasyID3
from mutagen.flac import FLAC
from mutagen._id3util import ID3NoHeaderError
import re
from shutil import copyfile
import subprocess
def is_image(ext):
return ext == 'jpg' or ext == 'jpeg' or ext == 'png'
def sanitize(s):
s = "".join(filter(lambda x: ord(x)<128, s))
s = re.sub('\s', '_', s)
s = re.sub('!', 'chk', s)
s = re.sub('[\."&,\/,\(\)\[\]]', '', s)
s = s.lower()
return s
def move_song(path, filename, to_dir, album_folder):
try:
id = None
to = None
ext = path.split('.')[-1].lower()
if ext == 'txt' or ext == 'm4p':
return
if filename[0] == '.':
return
if is_image(ext) and album_folder:
to = album_folder + '/art.' + ext
else:
if ext == 'm4a':
og_path = path
old_fname = path.split('/')[-1].split('.')[0]
new_fname = '%s.flac' % old_fname
new_path = "/".join(path.split('/')[:-1]) + '/' + new_fname
try:
FNULL = open(os.devnull, 'w')
out = subprocess.call(['ffmpeg', '-y', '-i', path ,'-f', 'flac', new_path], stdout=FNULL, stderr=subprocess.STDOUT)
path = new_path
ext = 'flac'
except:
#Conversion failed, so just copy the OG file...hopefully to the correct album folder
copyfile(og_path, album_folder + '/' + filename)
return
if ext == 'flac':
id = FLAC(path)
else:
id = EasyID3(path)
artist = sanitize(id.get('artist', ['unknown'])[0])
album = sanitize(id.get('album', ['unknown'])[0])
title = sanitize(id.get('title', ['unknown'])[0])
album_folder = to_dir + artist + '/' + album
to = album_folder + '/' + title + '.' + ext
if not os.path.exists(album_folder):
os.makedirs(album_folder)
if to and not ospath.exists(to):
print "c from %s ---> %s" % (sanitize(path)[-30:], to[-30:])
copyfile(path, to)
else:
print "skip %s" % to
if id:
return album_folder
except ID3NoHeaderError as e:
pass
except:
print "FAIL"
print path
def main(rootdir, to_dir):
for folder, subs, files in os.walk(rootdir):
album_folder = ''
art = [file for file in files if is_image(file.split('.')[-1])]
not_art = [file for file in files if not is_image(file.split('.')[-1])]
files = not_art + art
for filename in files:
album_folder = move_song(os.path.join(folder, filename), filename, to_dir, album_folder)
if __name__ == '__main__':
rootdir = sys.argv[1]
to_dir = sys.argv[2]
main(rootdir, to_dir)
@rozap
Copy link
Author

rozap commented Mar 29, 2014

  • takes music in an unspecified folder hierarchy and copies it to <to_dir>///songs_name
  • copies cover art
  • converts m4a to flac

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment