From eedfec09409e385f676b2beeeda03ed0bfb8bb2f Mon Sep 17 00:00:00 2001 From: Brandon Amos Date: Sun, 10 Apr 2016 06:19:38 -0400 Subject: [PATCH 1/2] Initial commit of music-autoplaylists. --- python2.7/music-autoplaylists.py | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 python2.7/music-autoplaylists.py diff --git a/python2.7/music-autoplaylists.py b/python2.7/music-autoplaylists.py new file mode 100755 index 0000000..f764076 --- /dev/null +++ b/python2.7/music-autoplaylists.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python2.7 + +__author__ = ['[Brandon Amos](http://bamos.github.io)'] +__date__ = '2015.04.09' + +""" +This script (music-autoplaylists.py) automatically creates +M3U playlists from the genre ID3 tags of songs in a directory. +""" + +import argparse +import os +import re +import shutil +import sys +from mutagen.easyid3 import EasyID3 +from collections import defaultdict + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--musicDir', type=str, default='.') + parser.add_argument('--playlistDir', type=str, default='./playlists/auto') + args = parser.parse_args() + + genres = defaultdict(list) + for dpath, dnames, fnames in os.walk(args.musicDir): + if '.git' in dpath: continue + for fname in fnames: + if os.path.splitext(fname)[1] != '.mp3': continue + p = os.path.abspath(os.path.join(dpath, fname)) + audio = EasyID3(p) + if 'genre' in audio: + assert(len(audio['genre']) == 1) + genre = toNeat(str(audio['genre'][0])) + else: + genre = 'Unknown' + genres[genre].append(p) + + if os.path.exists(args.playlistDir): + shutil.rmtree(args.playlistDir) + os.makedirs(args.playlistDir) + + for genre, songs in genres.items(): + p = os.path.join(args.playlistDir, genre+'.m3u') + print("Creating playlist: {}".format(p)) + with open(p, 'w') as f: + f.write("#EXTM3U\n") + f.write("\n".join(sorted(songs))+"\n") + +# Maps a string such as 'The Beatles' to 'the-beatles'. +def toNeat(s): + s = s.lower().replace("&", "and") + + # Put spaces between and remove blank characters. + blankCharsPad = r"()\[\],.\\\?\#/\!\$\:\;" + blankCharsNoPad = r"'\"" + s = re.sub(r"([" + blankCharsPad + r"])([^ ])", "\\1 \\2", s) + s = re.sub("[" + blankCharsPad + blankCharsNoPad + "]", "", s) + + # Replace spaces with a single dash. + s = re.sub(r"[ \*\_]+", "-", s) + s = re.sub("-+", "-", s) + s = re.sub("^-*", "", s) + s = re.sub("-*$", "", s) + + # Ensure the string is only alphanumeric with '-', '+', and '='. + search = re.search("[^0-9a-z\-\+\=]", s) + if search: + print("Error: Unrecognized character in '" + s + "'") + sys.exit(-42) + return s + +if __name__ == '__main__': + main() From 284e62e741ba8ac0c65f89cd51e5a7e7c8abe3c1 Mon Sep 17 00:00:00 2001 From: Brandon Amos Date: Fri, 22 Apr 2016 22:17:12 -0400 Subject: [PATCH 2/2] Fix flake warnings. --- python2.7/music-autoplaylists.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/python2.7/music-autoplaylists.py b/python2.7/music-autoplaylists.py index f764076..15759bf 100755 --- a/python2.7/music-autoplaylists.py +++ b/python2.7/music-autoplaylists.py @@ -16,6 +16,7 @@ from mutagen.easyid3 import EasyID3 from collections import defaultdict + def main(): parser = argparse.ArgumentParser() parser.add_argument('--musicDir', type=str, default='.') @@ -24,9 +25,11 @@ def main(): genres = defaultdict(list) for dpath, dnames, fnames in os.walk(args.musicDir): - if '.git' in dpath: continue + if '.git' in dpath: + continue for fname in fnames: - if os.path.splitext(fname)[1] != '.mp3': continue + if os.path.splitext(fname)[1] != '.mp3': + continue p = os.path.abspath(os.path.join(dpath, fname)) audio = EasyID3(p) if 'genre' in audio: @@ -41,13 +44,15 @@ def main(): os.makedirs(args.playlistDir) for genre, songs in genres.items(): - p = os.path.join(args.playlistDir, genre+'.m3u') + p = os.path.join(args.playlistDir, genre + '.m3u') print("Creating playlist: {}".format(p)) with open(p, 'w') as f: f.write("#EXTM3U\n") - f.write("\n".join(sorted(songs))+"\n") + f.write("\n".join(sorted(songs)) + "\n") # Maps a string such as 'The Beatles' to 'the-beatles'. + + def toNeat(s): s = s.lower().replace("&", "and")