From 663beea9d2a2c0042cf2681d80c4867544091238 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 13:19:44 +0200 Subject: [PATCH 01/30] Added support for sorting albums --- python2.7/music-organizer.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 1bed95e..eb87bc0 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -179,18 +179,25 @@ def song(filename): audio = EasyID3(filename) artist = audio['artist'][0].encode('ascii', 'ignore') title = audio['title'][0].encode('ascii', 'ignore') + album = audio['album'][0].encode('ascii', 'ignore') print(" artist: " + artist) print(" title: " + title) + print(" album: " + album) except: artist = None title = None + album = None neatArtist = toNeat(artist) neatTitle = toNeat(title) + neatAlbum = toNeat(album) print(" neatArtist: " + neatArtist) print(" neatTitle: " + neatTitle) + print(" neatAlbum: " + neatAlbum) if not os.path.isdir(neatArtist): os.mkdir(neatArtist) - newFullPath = os.path.join(neatArtist, neatTitle + ext) + if not os.path.isdir(neatArtist + "/" + neatAlbum): + os.mkdir(neatArtist + "/" + neatAlbum) + newFullPath = os.path.join(neatArtist, neatAlbum, neatTitle + ext) os.rename(filename, newFullPath) From 97cb4aaeb76f533e884be793674a5fa34f6c4ae4 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 13:39:37 +0200 Subject: [PATCH 02/30] Added --album flag for album sorting option --- python2.7/music-organizer.py | 43 ++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index eb87bc0..1eeb3e2 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -23,34 +23,38 @@ from mutagen.easyid3 import EasyID3 parser = argparse.ArgumentParser( - description='''Organizes a music collection using tag information. + description='''Organizes a music collection using tag information. The directory format is that the music collection consists of artist subdirectories, and there are 2 modes to operate on the entire collection or a single artist. All names are made lowercase and separated by dashes for easier navigation in a Linux filesystem.''' -) + ) parser.add_argument('--delete-conflicts', action='store_true', - dest='delete_conflicts', - help='''If an artist has duplicate tracks with the same name, + dest='delete_conflicts', + help='''If an artist has duplicate tracks with the same name, delete them. Note this might always be best in case an artist has multiple versions. To keep multiple versions, fix the tag information.''') parser.add_argument('--ignore-multiple-artists', action='store_true', - dest='ignore_multiple_artists', - help='''This script will prompt for confirmation if an artist + dest='ignore_multiple_artists', + help='''This script will prompt for confirmation if an artist directory has songs with more than 2 different tags. This flag disables the confirmation and won't perform this check.''') parser.add_argument('--collection', action='store_true', - help='''Operate in 'collection' mode and run 'artist' mode + help='''Operate in 'collection' mode and run 'artist' mode on every subdirectory.''') parser.add_argument('--artist', action='store_true', - help='''Operate in 'artist' mode and copy all songs to the + help='''Operate in 'artist' mode and copy all songs to the root of the directory and cleanly format the names to be easily typed and navigated in a shell.''') parser.add_argument('--delete-unrecognized-extensions', action='store_true', - dest='delete_unrecognized') + dest='delete_unrecognized') +parser.add_argument('--album', action='store_true', + dest='album', + help='''Adds album folder inside the artist folder to sort out + albums''') args = parser.parse_args() if args.collection and args.artist: @@ -182,22 +186,29 @@ def song(filename): album = audio['album'][0].encode('ascii', 'ignore') print(" artist: " + artist) print(" title: " + title) - print(" album: " + album) + if args.album: + print(" album: " + album) except: artist = None title = None - album = None + if args.album: + album = None neatArtist = toNeat(artist) neatTitle = toNeat(title) - neatAlbum = toNeat(album) + if args.album: + neatAlbum = toNeat(album) print(" neatArtist: " + neatArtist) print(" neatTitle: " + neatTitle) - print(" neatAlbum: " + neatAlbum) + if args.album: + print(" neatAlbum: " + neatAlbum) if not os.path.isdir(neatArtist): os.mkdir(neatArtist) - if not os.path.isdir(neatArtist + "/" + neatAlbum): - os.mkdir(neatArtist + "/" + neatAlbum) - newFullPath = os.path.join(neatArtist, neatAlbum, neatTitle + ext) + if args.album: + if not os.path.isdir(neatArtist + "/" + neatAlbum): + os.mkdir(neatArtist + "/" + neatAlbum) + newFullPath = os.path.join(neatArtist, neatAlbum, neatTitle + ext) + else: + newFullPath = os.path.join(neatArtist, neatTitle + ext) os.rename(filename, newFullPath) From 48ad83ec43ed6980ea5e13577f214dd0fde3552d Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 14:55:30 +0200 Subject: [PATCH 03/30] Added flag for adding tracklist songs --- python2.7/music-organizer.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 1eeb3e2..325994a 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -55,6 +55,9 @@ dest='album', help='''Adds album folder inside the artist folder to sort out albums''') +parser.add_argument('--numbering', action='store_true', + dest='numbering', + help='''Adds numbering in front of sorted songs''') args = parser.parse_args() if args.collection and args.artist: @@ -184,6 +187,8 @@ def song(filename): artist = audio['artist'][0].encode('ascii', 'ignore') title = audio['title'][0].encode('ascii', 'ignore') album = audio['album'][0].encode('ascii', 'ignore') + if args.numbering: + tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') print(" artist: " + artist) print(" title: " + title) if args.album: @@ -193,8 +198,13 @@ def song(filename): title = None if args.album: album = None + if args.numbering: + tracknumber = None neatArtist = toNeat(artist) - neatTitle = toNeat(title) + if args.numbering: + neatTitle = tracknumber + ".-" + toNeat(title) + else: + neatTitle = toNeat(title) if args.album: neatAlbum = toNeat(album) print(" neatArtist: " + neatArtist) From 1d7747087b52e43ead7d5ad6697f88534c72ee93 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 14:55:30 +0200 Subject: [PATCH 04/30] Added flag for adding tracknumber songs --- python2.7/music-organizer.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 1eeb3e2..325994a 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -55,6 +55,9 @@ dest='album', help='''Adds album folder inside the artist folder to sort out albums''') +parser.add_argument('--numbering', action='store_true', + dest='numbering', + help='''Adds numbering in front of sorted songs''') args = parser.parse_args() if args.collection and args.artist: @@ -184,6 +187,8 @@ def song(filename): artist = audio['artist'][0].encode('ascii', 'ignore') title = audio['title'][0].encode('ascii', 'ignore') album = audio['album'][0].encode('ascii', 'ignore') + if args.numbering: + tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') print(" artist: " + artist) print(" title: " + title) if args.album: @@ -193,8 +198,13 @@ def song(filename): title = None if args.album: album = None + if args.numbering: + tracknumber = None neatArtist = toNeat(artist) - neatTitle = toNeat(title) + if args.numbering: + neatTitle = tracknumber + ".-" + toNeat(title) + else: + neatTitle = toNeat(title) if args.album: neatAlbum = toNeat(album) print(" neatArtist: " + neatArtist) From 71f980cf7371724d8b5aad4a0bfe4e603a4a971c Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 15:48:29 +0200 Subject: [PATCH 05/30] Added support for capital filenames and --capital flag --- python2.7/music-organizer.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 325994a..296ff6c 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -58,6 +58,9 @@ parser.add_argument('--numbering', action='store_true', dest='numbering', help='''Adds numbering in front of sorted songs''') +parser.add_argument('--capital', action='store_true', + dest='capital', + help='''Makes the first letter of a song capital''') args = parser.parse_args() if args.collection and args.artist: @@ -70,7 +73,10 @@ # Maps a string such as 'The Beatles' to 'the-beatles'. def toNeat(s): - s = s.lower().replace("&", "and") + if args.capital: + s = s.title().replace("&", "and") + else: + s = s.lower().replace("&", "and") # Put spaces between and remove blank characters. blankCharsPad = r"()\[\],.\\\?\#/\!\$\:\;" @@ -85,7 +91,10 @@ def toNeat(s): s = re.sub("-*$", "", s) # Ensure the string is only alphanumeric with '-', '+', and '='. - search = re.search("[^0-9a-z\-\+\=]", s) + if args.capital: + search = re.search("[^0-9a-zA-Z\-\+\=]", s) + else: + search = re.search("[^0-9a-z\-\+\=]", s) if search: print("Error: Unrecognized character in '" + s + "'") sys.exit(-42) From 71905983d6d32cf82b6068cc8c6cad693e0094c4 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 16:19:05 +0200 Subject: [PATCH 06/30] Flags now have abbreviations --- python2.7/music-organizer.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 296ff6c..19d440a 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -30,35 +30,35 @@ All names are made lowercase and separated by dashes for easier navigation in a Linux filesystem.''' ) -parser.add_argument('--delete-conflicts', action='store_true', +parser.add_argument('-d','--delete-conflicts', action='store_true', dest='delete_conflicts', help='''If an artist has duplicate tracks with the same name, delete them. Note this might always be best in case an artist has multiple versions. To keep multiple versions, fix the tag information.''') -parser.add_argument('--ignore-multiple-artists', action='store_true', +parser.add_argument('-m','--ignore-multiple-artists', action='store_true', dest='ignore_multiple_artists', help='''This script will prompt for confirmation if an artist directory has songs with more than 2 different tags. This flag disables the confirmation and won't perform this check.''') -parser.add_argument('--collection', action='store_true', +parser.add_argument('-c','--collection', action='store_true', help='''Operate in 'collection' mode and run 'artist' mode on every subdirectory.''') -parser.add_argument('--artist', action='store_true', +parser.add_argument('-a', '--artist', action='store_true', help='''Operate in 'artist' mode and copy all songs to the root of the directory and cleanly format the names to be easily typed and navigated in a shell.''') -parser.add_argument('--delete-unrecognized-extensions', action='store_true', +parser.add_argument('-e','--delete-unrecognized-extensions', action='store_true', dest='delete_unrecognized') -parser.add_argument('--album', action='store_true', +parser.add_argument('-A','--album', action='store_true', dest='album', help='''Adds album folder inside the artist folder to sort out albums''') -parser.add_argument('--numbering', action='store_true', +parser.add_argument('-n','--numbering', action='store_true', dest='numbering', help='''Adds numbering in front of sorted songs''') -parser.add_argument('--capital', action='store_true', +parser.add_argument('-C','--capital', action='store_true', dest='capital', help='''Makes the first letter of a song capital''') args = parser.parse_args() From 64ba09cad0d8f55bd1602ae87930dbd6741de235 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 20:19:53 +0200 Subject: [PATCH 07/30] added Ogg Vorbis suport --- python2.7/music-organizer.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 19d440a..3a43457 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -21,6 +21,7 @@ import shutil import sys from mutagen.easyid3 import EasyID3 +from mutagen.oggvorbis import OggVorbis parser = argparse.ArgumentParser( description='''Organizes a music collection using tag information. @@ -137,12 +138,16 @@ def artist(artistDir): # Move all the files to the root directory. for filename in filenames: ext = os.path.splitext(filename)[1] - if ext == ".mp3": + #if ext == ".mp3": + if ext in (".mp3" , ".ogg"): fullPath = os.path.join(dirname, filename) print("file: " + str(fullPath)) try: - audio = EasyID3(fullPath) + if ext == ".mp3": + audio = EasyID3(fullPath) + elif ext == ".ogg": + audio = OggVorbis(fullPath) title = audio['title'][0].encode('ascii', 'ignore') print(" title: " + title) except: @@ -192,7 +197,10 @@ def song(filename): print("Organizing song '" + filename + "'.") ext = os.path.splitext(filename)[1] try: - audio = EasyID3(filename) + if ext == ".mp3": + audio = EasyID3(filename) + elif ext == ".ogg": + audio = OggVorbis(filename) artist = audio['artist'][0].encode('ascii', 'ignore') title = audio['title'][0].encode('ascii', 'ignore') album = audio['album'][0].encode('ascii', 'ignore') From 0845073d4dceb906d09af2887df30f73048f32d9 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 20:32:24 +0200 Subject: [PATCH 08/30] Album flag workin in artist mode --- python2.7/music-organizer.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 3a43457..e0bba33 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -149,9 +149,13 @@ def artist(artistDir): elif ext == ".ogg": audio = OggVorbis(fullPath) title = audio['title'][0].encode('ascii', 'ignore') + if args.album: + album = audio['album'][0].encode('ascii', 'ignore') print(" title: " + title) except: title = None + if args.album: + album = None if not title: print("Error: title not found for '" + filename + "'") @@ -160,7 +164,13 @@ def artist(artistDir): neatTitle = toNeat(title) print(" neatTitle: " + neatTitle) - newFullPath = os.path.join(artistDir, neatTitle + ext) + if args.album: + neatAlbum = toNeat(album) + print(" neatAlbum: " + neatAlbum) + newFullPath = os.path.join(artistDir, neatAlbum, neatTitle + ext) + + else: + newFullPath = os.path.join(artistDir, neatTitle + ext) print(" newFullPath: " + newFullPath) if newFullPath != fullPath: From 129b99ec395ff6db4e5ce559d0421665f5ab4406 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Fri, 1 Jul 2016 20:32:24 +0200 Subject: [PATCH 09/30] Album flag workin in artist mode --- python2.7/music-organizer.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 3a43457..93fed32 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -149,9 +149,13 @@ def artist(artistDir): elif ext == ".ogg": audio = OggVorbis(fullPath) title = audio['title'][0].encode('ascii', 'ignore') + if args.album: + album = audio['album'][0].encode('ascii', 'ignore') print(" title: " + title) except: title = None + if args.album: + album = None if not title: print("Error: title not found for '" + filename + "'") @@ -160,7 +164,13 @@ def artist(artistDir): neatTitle = toNeat(title) print(" neatTitle: " + neatTitle) - newFullPath = os.path.join(artistDir, neatTitle + ext) + if args.album: + neatAlbum = toNeat(album) + print(" neatAlbum: " + neatAlbum) + newFullPath = os.path.join(artistDir, neatAlbum, neatTitle + ext) + + else: + newFullPath = os.path.join(artistDir, neatTitle + ext) print(" newFullPath: " + newFullPath) if newFullPath != fullPath: @@ -205,7 +215,10 @@ def song(filename): title = audio['title'][0].encode('ascii', 'ignore') album = audio['album'][0].encode('ascii', 'ignore') if args.numbering: - tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') + try: + tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') + except: + tracknumber = "error" print(" artist: " + artist) print(" title: " + title) if args.album: @@ -218,7 +231,7 @@ def song(filename): if args.numbering: tracknumber = None neatArtist = toNeat(artist) - if args.numbering: + if args.numbering and tracknumber is not "error": neatTitle = tracknumber + ".-" + toNeat(title) else: neatTitle = toNeat(title) From a13df2142d368e707d70f635e9ba88af8a7db911 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 11:20:21 +0200 Subject: [PATCH 10/30] Now checks for numbering in the filename and uses it to name files --- python2.7/music-organizer.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 93fed32..4c602fb 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -151,6 +151,20 @@ def artist(artistDir): title = audio['title'][0].encode('ascii', 'ignore') if args.album: album = audio['album'][0].encode('ascii', 'ignore') + if args.numbering: + try: + tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') + except: + try: + numb = os.path.basename(filename).split(' ')[0] + print "numb: " + numb + newnumb = re.findall(r'\d+', numb)[0] + print "newnumb: " + newnumb + tracknumber = newnumb + print "tracknumber: " + tracknumber + except: + tracknumber = "error" + print "tracknumber except: " + tracknumber print(" title: " + title) except: title = None @@ -161,7 +175,11 @@ def artist(artistDir): print("Error: title not found for '" + filename + "'") sys.exit(-42) - neatTitle = toNeat(title) + if args.numbering and tracknumber is not "error": + neatTitle = tracknumber + ".-" + toNeat(title) + else: + neatTitle = toNeat(title) + print(" neatTitle: " + neatTitle) if args.album: @@ -218,7 +236,17 @@ def song(filename): try: tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') except: - tracknumber = "error" + try: + numb = os.path.basename(filename).split(' ')[0] + print "numb: " + numb + newnumb = re.findall(r'\d+', numb)[0] + print "newnumb: " + newnumb + tracknumber = newnumb + print "tracknumber: " + tracknumber + except: + tracknumber = "error" + print "tracknumber except: " + tracknumber + print(" artist: " + artist) print(" title: " + title) if args.album: From c29166fa3f7880ba90ffb26a15eb7105be029eaf Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 11:32:29 +0200 Subject: [PATCH 11/30] cleanup debug statement from last commit --- python2.7/music-organizer.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 4c602fb..26b6c8a 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -156,15 +156,9 @@ def artist(artistDir): tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') except: try: - numb = os.path.basename(filename).split(' ')[0] - print "numb: " + numb - newnumb = re.findall(r'\d+', numb)[0] - print "newnumb: " + newnumb - tracknumber = newnumb - print "tracknumber: " + tracknumber + tracknumber = re.findall(r'\d+', os.path.basename(filename).split(' ')[0])[0] except: - tracknumber = "error" - print "tracknumber except: " + tracknumber + tracknumber = "error" print(" title: " + title) except: title = None @@ -237,16 +231,9 @@ def song(filename): tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') except: try: - numb = os.path.basename(filename).split(' ')[0] - print "numb: " + numb - newnumb = re.findall(r'\d+', numb)[0] - print "newnumb: " + newnumb - tracknumber = newnumb - print "tracknumber: " + tracknumber + tracknumber = re.findall(r'\d+', os.path.basename(filename).split(' ')[0])[0] except: tracknumber = "error" - print "tracknumber except: " + tracknumber - print(" artist: " + artist) print(" title: " + title) if args.album: From d2baac0af2c922657707041c13e669857e8c1d92 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 12:51:40 +0200 Subject: [PATCH 12/30] moved operations from artist method to song --- python2.7/music-organizer.py | 125 ++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index e0bba33..1fd8c5b 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -102,11 +102,12 @@ def toNeat(s): return s -def artist(artistDir): - print("Organizing artist '" + artistDir + "'.") +def artist(): + print("Organizing artist") if not args.ignore_multiple_artists: artists = set() - for dirname, dirnames, filenames in os.walk(artistDir): + for dirname, dirnames, filenames in os.walk("."): + print "Random test" # Make sure there aren't a lot of different artists # in case this was called from the wrong directory. for filename in filenames: @@ -119,10 +120,8 @@ def artist(artistDir): if len(artists) > 2: while True: - print("Warning: More than 2 artists found in '{}'.".format( - artistDir)) - print("This will move all songs to the '{}' directory.".format( - artistDir)) + print("Warning: More than 2 artists found in '{}'.".format(".")) + print("This will move all songs to the '{}' directory.".format(".")) print("Continue? yes/no") choice = raw_input().lower() valid = {"yes": True, "y": True, "no": False, "n": False} @@ -134,13 +133,14 @@ def artist(artistDir): sys.exit(-1) delete_dirs = [] - for dirname, dirnames, filenames in os.walk(artistDir): + for dirname, dirnames, filenames in os.walk("."): # Move all the files to the root directory. for filename in filenames: + fullPath = os.path.join(dirname, filename) + song(fullPath) ext = os.path.splitext(filename)[1] - #if ext == ".mp3": + ''' if ext in (".mp3" , ".ogg"): - fullPath = os.path.join(dirname, filename) print("file: " + str(fullPath)) try: @@ -191,63 +191,14 @@ def artist(artistDir): print("Error: Unrecognized file extension in '{}'.".format( filename)) sys.exit(-42) + ''' # Delete all subdirectories. for subdirname in dirnames: delete_dirs.append(subdirname) for d in delete_dirs: - shutil.rmtree(os.path.join(artistDir, d), ignore_errors=True) - - -def song(filename): - if filename[0] == '.': - print("Ignoring dotfile: '{}'".format(filename)) - return - print("Organizing song '" + filename + "'.") - ext = os.path.splitext(filename)[1] - try: - if ext == ".mp3": - audio = EasyID3(filename) - elif ext == ".ogg": - audio = OggVorbis(filename) - artist = audio['artist'][0].encode('ascii', 'ignore') - title = audio['title'][0].encode('ascii', 'ignore') - album = audio['album'][0].encode('ascii', 'ignore') - if args.numbering: - tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') - print(" artist: " + artist) - print(" title: " + title) - if args.album: - print(" album: " + album) - except: - artist = None - title = None - if args.album: - album = None - if args.numbering: - tracknumber = None - neatArtist = toNeat(artist) - if args.numbering: - neatTitle = tracknumber + ".-" + toNeat(title) - else: - neatTitle = toNeat(title) - if args.album: - neatAlbum = toNeat(album) - print(" neatArtist: " + neatArtist) - print(" neatTitle: " + neatTitle) - if args.album: - print(" neatAlbum: " + neatAlbum) - if not os.path.isdir(neatArtist): - os.mkdir(neatArtist) - if args.album: - if not os.path.isdir(neatArtist + "/" + neatAlbum): - os.mkdir(neatArtist + "/" + neatAlbum) - newFullPath = os.path.join(neatArtist, neatAlbum, neatTitle + ext) - else: - newFullPath = os.path.join(neatArtist, neatTitle + ext) - os.rename(filename, newFullPath) - + shutil.rmtree(os.path.join(".", d), ignore_errors=True) def collection(): for f in glob.glob('*'): @@ -257,8 +208,58 @@ def collection(): elif os.path.isfile(f): song(f) +def song(filename): +# if filename[0] == '.': +# print("Ignoring dotfile: '{}'".format(filename)) +# return + print("Organizing song '" + filename + "'.") + ext = os.path.splitext(filename)[1] + if ext in (".mp3" , ".ogg"): + try: + if ext == ".mp3": + audio = EasyID3(filename) + elif ext == ".ogg": + audio = OggVorbis(filename) + print audio + artist = audio['artist'][0].encode('ascii', 'ignore') + title = audio['title'][0].encode('ascii', 'ignore') + album = audio['album'][0].encode('ascii', 'ignore') + if args.numbering: + tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') + print(" artist: " + artist) + print(" title: " + title) + if args.album: + print(" album: " + album) + except: + artist = None + title = None + if args.album: + album = None + if args.numbering: + tracknumber = None + neatArtist = toNeat(artist) + if args.numbering: + neatTitle = tracknumber + ".-" + toNeat(title) + else: + neatTitle = toNeat(title) + if args.album: + neatAlbum = toNeat(album) + print(" neatArtist: " + neatArtist) + print(" neatTitle: " + neatTitle) + if args.album: + print(" neatAlbum: " + neatAlbum) + if not os.path.isdir(neatArtist): + os.mkdir(neatArtist) + if args.album: + if not os.path.isdir(neatArtist + "/" + neatAlbum): + os.mkdir(neatArtist + "/" + neatAlbum) + newFullPath = os.path.join(neatArtist, neatAlbum, neatTitle + ext) + else: + newFullPath = os.path.join(neatArtist, neatTitle + ext) + os.rename(filename, newFullPath) + if args.artist: - artist('.') + artist() else: collection() print("\nComplete!") From a7d3d5cdf87e90e1009ba9b05a75a300fceabb1f Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 14:09:24 +0200 Subject: [PATCH 13/30] Adding method for detecting unrecognized extensions and fixig the delete unrecognized extensions flag --- python2.7/music-organizer.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 4b0f8b8..5b2ff1d 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -196,12 +196,7 @@ def artist(): os.rename(fullPath, newFullPath) elif ext == ".pdf": pass - else: - if not args.delete_unrecognized: - print("Error: Unrecognized file extension in '{}'.".format( - filename)) - sys.exit(-42) - ''' + ''' # Delete all subdirectories. for subdirname in dirnames: @@ -264,6 +259,11 @@ def song(filename): else: newFullPath = os.path.join(neatArtist, neatTitle + ext) os.rename(filename, newFullPath) + else: + if not args.delete_unrecognized: + print("Error: Unrecognized file extension in '{}'.".format(filename)) + sys.exit(-42) + def collection(): for f in glob.glob('*'): From 2a631e51469d20b6a7611a94ae6c74fee75fd758 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 14:24:19 +0200 Subject: [PATCH 14/30] fixes the album flag --- python2.7/music-organizer.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 5b2ff1d..71b9653 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -219,7 +219,8 @@ def song(filename): audio = OggVorbis(filename) artist = audio['artist'][0].encode('ascii', 'ignore') title = audio['title'][0].encode('ascii', 'ignore') - album = audio['album'][0].encode('ascii', 'ignore') + if args.album: + album = audio['album'][0].encode('ascii', 'ignore') if args.numbering: try: tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') @@ -269,7 +270,7 @@ def collection(): for f in glob.glob('*'): if os.path.isdir(f): if f != 'iTunes' and f != 'playlists': - artist(f) + artist() elif os.path.isfile(f): song(f) From 210ac6a4e5b586e80ba3787baad5f7ef5e06fa2f Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 14:27:35 +0200 Subject: [PATCH 15/30] moving the notification after the extension check --- python2.7/music-organizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 71b9653..8da48cf 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -209,9 +209,9 @@ def song(filename): # if filename[0] == '.': # print("Ignoring dotfile: '{}'".format(filename)) # return - print("Organizing song '" + filename + "'.") ext = os.path.splitext(filename)[1] if ext in (".mp3" , ".ogg"): + print("Organizing song '" + filename + "'.") try: if ext == ".mp3": audio = EasyID3(filename) From 17eb15363d078ef0f50f9762d57d703d9833eb03 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 14:51:32 +0200 Subject: [PATCH 16/30] Songs now have leading zero --- python2.7/music-organizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 8da48cf..39df746 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -242,7 +242,7 @@ def song(filename): tracknumber = None neatArtist = toNeat(artist) if args.numbering: - neatTitle = tracknumber + "." + toNeat(title) + neatTitle = tracknumber.zfill(2) + "." + toNeat(title) else: neatTitle = toNeat(title) if args.album: From 883cb4b2afa3403033ee7a37adfa7bd0cf00aa72 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 14:53:37 +0200 Subject: [PATCH 17/30] Removing obsolate flags --- python2.7/music-organizer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 39df746..804f42a 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -37,6 +37,7 @@ delete them. Note this might always be best in case an artist has multiple versions. To keep multiple versions, fix the tag information.''') +''' parser.add_argument('-m','--ignore-multiple-artists', action='store_true', dest='ignore_multiple_artists', help='''This script will prompt for confirmation if an artist @@ -50,6 +51,7 @@ help='''Operate in 'artist' mode and copy all songs to the root of the directory and cleanly format the names to be easily typed and navigated in a shell.''') +''' parser.add_argument('-e','--delete-unrecognized-extensions', action='store_true', dest='delete_unrecognized') parser.add_argument('-A','--album', action='store_true', From c54d5741355d13a66eaef45f4a798ec1558cbcfc Mon Sep 17 00:00:00 2001 From: joostsijm Date: Mon, 4 Jul 2016 16:28:04 +0200 Subject: [PATCH 18/30] updating music tag fixer and adding music number fixer --- python2.7/fix-music-tags.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index 8e07eb2..b614c43 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -8,8 +8,10 @@ """ from mutagen.easyid3 import EasyID3 +import os import argparse import glob +import re def fixTags(fname, keep): @@ -24,14 +26,32 @@ def fixTags(fname, keep): del audio[k] audio.save() +def fixNumber(fname): + audio = EasyID3(fname) + + if `'tracknumber'` in audio: + return + + else: + try: + tracknumber = re.findall(r'\d+', os.path.basename(fname).split(' ')[0])[0] + audio['tracknumber'] = tracknumber.zfill(2) + audio.save() + except: + return + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('directory', help='Directory with mp3 files to fix.') parser.add_argument('--keep', default=['title', 'artist', 'album', 'genre'], - type=str, nargs='+', metavar='TAG', - help="Tags to keep. Default: title, artist, album, genre") + type=str, nargs='+', metavar='TAG', + help="Tags to keep. Default: title, artist, album, genre") + parser.add_argument('--fixnumber', action='store_true', + help="Trying to fix song number.") args = parser.parse_args() for fname in glob.glob("{}/*.mp3".format(args.directory)): print("Fixing tags for {}".format(fname)) fixTags(fname, args.keep) + if args.fixnumber: + fixNumber(fname) From d79c6aad7233c3a89b334d6cf9ba28e1ccbf9794 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Tue, 5 Jul 2016 09:57:11 +0200 Subject: [PATCH 19/30] fix-music-tags now supports Ogg files in a hacky way --- python2.7/fix-music-tags.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index b614c43..5a90e38 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -8,6 +8,7 @@ """ from mutagen.easyid3 import EasyID3 +from mutagen.oggvorbis import OggVorbis import os import argparse import glob @@ -15,7 +16,11 @@ def fixTags(fname, keep): - audio = EasyID3(fname) + ext = os.path.splitext(fname)[1] + if ext == ".mp3": + audio = EasyID3(fname) + elif ext == ".ogg": + audio = OggVorbis(fname) delKeys = [] for k, v in audio.items(): @@ -27,7 +32,11 @@ def fixTags(fname, keep): audio.save() def fixNumber(fname): - audio = EasyID3(fname) + ext = os.path.splitext(fname)[1] + if ext == ".mp3": + audio = EasyID3(fname) + elif ext == ".ogg": + audio = OggVorbis(fname) if `'tracknumber'` in audio: return @@ -55,3 +64,9 @@ def fixNumber(fname): fixTags(fname, args.keep) if args.fixnumber: fixNumber(fname) + + for fname in glob.glob("{}/*.ogg".format(args.directory)): + print("Fixing tags for {}".format(fname)) + fixTags(fname, args.keep) + if args.fixnumber: + fixNumber(fname) From 82fbcdbea2b54afe870fd62fe2dde1b46a125ca0 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Tue, 5 Jul 2016 10:15:23 +0200 Subject: [PATCH 20/30] File extension are now handeled in a more appropriate fashion --- python2.7/fix-music-tags.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index 5a90e38..61f4d41 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -59,13 +59,14 @@ def fixNumber(fname): help="Trying to fix song number.") args = parser.parse_args() - for fname in glob.glob("{}/*.mp3".format(args.directory)): - print("Fixing tags for {}".format(fname)) - fixTags(fname, args.keep) - if args.fixnumber: - fixNumber(fname) + types = ('*.mp3', '*.ogg') + files_grabbed = [] + for files in types: + files_grabbed.extend( + glob.glob("{}/*{}".format(args.directory, files)) + ) - for fname in glob.glob("{}/*.ogg".format(args.directory)): + for fname in files_grabbed: print("Fixing tags for {}".format(fname)) fixTags(fname, args.keep) if args.fixnumber: From 0b7adb53f589d051bc94870ebe52c7054d8a4ceb Mon Sep 17 00:00:00 2001 From: joostsijm Date: Tue, 5 Jul 2016 10:22:30 +0200 Subject: [PATCH 21/30] Made own method for extracting audio --- python2.7/fix-music-tags.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index 61f4d41..e8919b2 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -14,14 +14,16 @@ import glob import re - -def fixTags(fname, keep): - ext = os.path.splitext(fname)[1] +def returnAudio(path): + ext = os.path.splitext(path)[1] if ext == ".mp3": - audio = EasyID3(fname) + audio = EasyID3(path) elif ext == ".ogg": - audio = OggVorbis(fname) + audio = OggVorbis(path) + return audio +def fixTags(fname, keep): + audio = returnAudio(fname) delKeys = [] for k, v in audio.items(): if k not in keep: @@ -32,12 +34,7 @@ def fixTags(fname, keep): audio.save() def fixNumber(fname): - ext = os.path.splitext(fname)[1] - if ext == ".mp3": - audio = EasyID3(fname) - elif ext == ".ogg": - audio = OggVorbis(fname) - + audio = returnAudio(fname) if `'tracknumber'` in audio: return From 11b15bcc14a082f8791e539e1b83c50978fdc79a Mon Sep 17 00:00:00 2001 From: joostsijm Date: Tue, 5 Jul 2016 10:27:46 +0200 Subject: [PATCH 22/30] Fixes problem with checking if a song already has a tracknumber --- python2.7/fix-music-tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index e8919b2..e06bb4e 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -35,7 +35,7 @@ def fixTags(fname, keep): def fixNumber(fname): audio = returnAudio(fname) - if `'tracknumber'` in audio: + if 'tracknumber' in audio: return else: From 79715651b25837c4ce7bf494c4ee6d5da953573e Mon Sep 17 00:00:00 2001 From: joostsijm Date: Tue, 5 Jul 2016 12:49:51 +0200 Subject: [PATCH 23/30] fixing broken flag which are removed --- python2.7/music-organizer.py | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 804f42a..5ea3572 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -37,21 +37,6 @@ delete them. Note this might always be best in case an artist has multiple versions. To keep multiple versions, fix the tag information.''') -''' -parser.add_argument('-m','--ignore-multiple-artists', action='store_true', - dest='ignore_multiple_artists', - help='''This script will prompt for confirmation if an artist - directory has songs with more than 2 different tags. - This flag disables the confirmation and won't perform - this check.''') -parser.add_argument('-c','--collection', action='store_true', - help='''Operate in 'collection' mode and run 'artist' mode - on every subdirectory.''') -parser.add_argument('-a', '--artist', action='store_true', - help='''Operate in 'artist' mode and copy all songs to the - root of the directory and cleanly format the names to - be easily typed and navigated in a shell.''') -''' parser.add_argument('-e','--delete-unrecognized-extensions', action='store_true', dest='delete_unrecognized') parser.add_argument('-A','--album', action='store_true', @@ -66,14 +51,6 @@ help='''Makes the first letter of a song capital''') args = parser.parse_args() -if args.collection and args.artist: - print("Error: Only provide 1 of '--collection' or '--artist'.") - sys.exit(-1) -elif not (args.collection or args.artist): - print("Error: Mode '--collection' or '--artist' not provided.") - sys.exit(-1) - - # Maps a string such as 'The Beatles' to 'the-beatles'. def toNeat(s): if args.capital: @@ -106,7 +83,7 @@ def toNeat(s): def artist(): print("Organizing artist") - if not args.ignore_multiple_artists: + if not True: artists = set() for dirname, dirnames, filenames in os.walk("."): # Make sure there aren't a lot of different artists @@ -276,8 +253,5 @@ def collection(): elif os.path.isfile(f): song(f) -if args.artist: - artist() -else: - collection() +collection() print("\nComplete!") From cf0fdcb8b20b6756afb4ccf6384c50bec71771a4 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Tue, 5 Jul 2016 16:39:15 +0200 Subject: [PATCH 24/30] problems with removing files that are already formated fixed --- python2.7/music-organizer.py | 126 +++++++++-------------------------- 1 file changed, 33 insertions(+), 93 deletions(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 5ea3572..52d6ea9 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -83,111 +83,35 @@ def toNeat(s): def artist(): print("Organizing artist") - if not True: - artists = set() - for dirname, dirnames, filenames in os.walk("."): - # Make sure there aren't a lot of different artists - # in case this was called from the wrong directory. - for filename in filenames: - try: - audio = EasyID3(os.path.join(dirname, filename)) - artist = audio['artist'][0].decode() - artists.add(artist) - except: - pass - - if len(artists) > 2: - while True: - print("Warning: More than 2 artists found in '{}'.".format(".")) - print("This will move all songs to the '{}' directory.".format(".")) - print("Continue? yes/no") - choice = raw_input().lower() - valid = {"yes": True, "y": True, "no": False, "n": False} - if choice in valid: - if valid[choice]: - break - else: - print("Exiting.") - sys.exit(-1) - delete_dirs = [] for dirname, dirnames, filenames in os.walk("."): # Move all the files to the root directory. for filename in filenames: fullPath = os.path.join(dirname, filename) - song(fullPath) - ''' - if ext in (".mp3" , ".ogg"): - print("file: " + str(fullPath)) - - try: - if ext == ".mp3": - audio = EasyID3(fullPath) - elif ext == ".ogg": - audio = OggVorbis(fullPath) - title = audio['title'][0].encode('ascii', 'ignore') - if args.album: - album = audio['album'][0].encode('ascii', 'ignore') - if args.numbering: - try: - tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') - except: - try: - tracknumber = re.findall(r'\d+', os.path.basename(filename).split(' ')[0])[0] - except: - tracknumber = "error" - print(" title: " + title) - except: - title = None - if args.album: - album = None - - if not title: - print("Error: title not found for '" + filename + "'") - sys.exit(-42) - - if args.numbering and tracknumber is not "error": - neatTitle = tracknumber + ".-" + toNeat(title) - else: - neatTitle = toNeat(title) - - print(" neatTitle: " + neatTitle) - - if args.album: - neatAlbum = toNeat(album) - print(" neatAlbum: " + neatAlbum) - newFullPath = os.path.join(artistDir, neatAlbum, neatTitle + ext) - - else: - newFullPath = os.path.join(artistDir, neatTitle + ext) - print(" newFullPath: " + newFullPath) - - if newFullPath != fullPath: - if os.path.isfile(newFullPath): - if args.delete_conflicts: - os.remove(fullPath) - print("File exists: '" + newFullPath + "'") - print("Deleted: '" + fullPath + "'") - else: - print("Error: File exists: '" + newFullPath + "'") - sys.exit(-42) - else: - os.rename(fullPath, newFullPath) - elif ext == ".pdf": - pass - ''' - - # Delete all subdirectories. + # formating song + returned = song(fullPath) + if returned is "succes": + print("succesful formated") + elif returned is "delete": + print"deleted remaining files in folder" + else: + returnedlist = returned.split('/') + for extdir in returnedlist: + if extdir in delete_dirs: + delete_dirs.remove(extdir) + + # Add subdirectories to a list for subdirname in dirnames: delete_dirs.append(subdirname) + # deletes subdirectories for d in delete_dirs: shutil.rmtree(os.path.join(".", d), ignore_errors=True) def song(filename): # if filename[0] == '.': - # print("Ignoring dotfile: '{}'".format(filename)) - # return +# print("Ignoring dotfile: '{}'".format(filename)) +# return ext = os.path.splitext(filename)[1] if ext in (".mp3" , ".ogg"): print("Organizing song '" + filename + "'.") @@ -219,6 +143,7 @@ def song(filename): album = None if args.numbering: tracknumber = None + neatArtist = toNeat(artist) if args.numbering: neatTitle = tracknumber.zfill(2) + "." + toNeat(title) @@ -238,11 +163,26 @@ def song(filename): newFullPath = os.path.join(neatArtist, neatAlbum, neatTitle + ext) else: newFullPath = os.path.join(neatArtist, neatTitle + ext) - os.rename(filename, newFullPath) + + if newFullPath != filename: + if os.path.isfile(newFullPath): + if args.delete_conflicts: + os.remove(filename) + print("File exists: '" + newFullPath + "'") + print("Deleted: '" + filename + "'") + else: + print("Error: File exists: '" + newFullPath + "'") + return os.path.split(newFullPath)[0] + else: + os.rename(filename, newFullPath) + return "succes" + else: if not args.delete_unrecognized: print("Error: Unrecognized file extension in '{}'.".format(filename)) sys.exit(-42) + else: + return "delete" def collection(): From b5026d1e6f35308bda3ebd7189a9ce49c70e1b48 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Wed, 6 Jul 2016 09:41:26 +0200 Subject: [PATCH 25/30] adding support for files with a slash in their trackname --- python2.7/music-organizer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 52d6ea9..399cf45 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -132,6 +132,7 @@ def song(filename): tracknumber = re.findall(r'\d+', os.path.basename(filename).split(' ')[0])[0] except: tracknumber = "error" + neatTracknumber = tracknumber.split('/')[0].zfill(2) print(" artist: " + artist) print(" title: " + title) if args.album: @@ -146,7 +147,7 @@ def song(filename): neatArtist = toNeat(artist) if args.numbering: - neatTitle = tracknumber.zfill(2) + "." + toNeat(title) + neatTitle = neatTracknumber + "." + toNeat(title) else: neatTitle = toNeat(title) if args.album: From 78ec31e3e805e4761cb1a04e6420b892714bffc6 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Wed, 6 Jul 2016 10:09:30 +0200 Subject: [PATCH 26/30] Now able to fix tracknumbers with slash in them --- python2.7/fix-music-tags.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index e06bb4e..2fdf4eb 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -36,6 +36,9 @@ def fixTags(fname, keep): def fixNumber(fname): audio = returnAudio(fname) if 'tracknumber' in audio: + if '/' in audio['tracknumber'][0]: + audio['tracknumber'] = audio['tracknumber'][0].split('/')[0].zfill(2) + audio.save() return else: From 31b0e6b02d10637e95852e562438862289805d1c Mon Sep 17 00:00:00 2001 From: joostsijm Date: Wed, 6 Jul 2016 11:41:09 +0200 Subject: [PATCH 27/30] Made toNeat its own file --- python2.7/music-autoplaylists.py | 9 +++++--- python2.7/music-organizer.py | 39 ++++---------------------------- python2.7/toNeat.py | 33 +++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 37 deletions(-) create mode 100755 python2.7/toNeat.py diff --git a/python2.7/music-autoplaylists.py b/python2.7/music-autoplaylists.py index 15759bf..0ae7aa7 100755 --- a/python2.7/music-autoplaylists.py +++ b/python2.7/music-autoplaylists.py @@ -15,12 +15,13 @@ import sys from mutagen.easyid3 import EasyID3 from collections import defaultdict - +import toNeat def main(): parser = argparse.ArgumentParser() parser.add_argument('--musicDir', type=str, default='.') parser.add_argument('--playlistDir', type=str, default='./playlists/auto') + parser.add_argument('-C','--capital', action='store_true', help='''Changes names to capital''') args = parser.parse_args() genres = defaultdict(list) @@ -34,7 +35,8 @@ def main(): audio = EasyID3(p) if 'genre' in audio: assert(len(audio['genre']) == 1) - genre = toNeat(str(audio['genre'][0])) + #genre = toNeat(str(audio['genre'][0])) + genre = toNeat.toNeat(str(audio['genre'][0]), args) else: genre = 'Unknown' genres[genre].append(p) @@ -52,7 +54,7 @@ def main(): # Maps a string such as 'The Beatles' to 'the-beatles'. - +''' def toNeat(s): s = s.lower().replace("&", "and") @@ -74,6 +76,7 @@ def toNeat(s): print("Error: Unrecognized character in '" + s + "'") sys.exit(-42) return s +''' if __name__ == '__main__': main() diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 399cf45..34513bb 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -20,6 +20,7 @@ import re import shutil import sys +import toNeat from mutagen.easyid3 import EasyID3 from mutagen.oggvorbis import OggVorbis @@ -51,36 +52,6 @@ help='''Makes the first letter of a song capital''') args = parser.parse_args() -# Maps a string such as 'The Beatles' to 'the-beatles'. -def toNeat(s): - if args.capital: - s = s.title().replace("&", "and") - else: - 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 '='. - if args.capital: - search = re.search("[^0-9a-zA-Z\-\+\=]", s) - else: - search = re.search("[^0-9a-z\-\+\=]", s) - if search: - print("Error: Unrecognized character in '" + s + "'") - sys.exit(-42) - return s - - def artist(): print("Organizing artist") delete_dirs = [] @@ -145,13 +116,13 @@ def song(filename): if args.numbering: tracknumber = None - neatArtist = toNeat(artist) + neatArtist = toNeat.toNeat(artist, args) if args.numbering: - neatTitle = neatTracknumber + "." + toNeat(title) + neatTitle = neatTracknumber + "." + toNeat.toNeat(title, args) else: - neatTitle = toNeat(title) + neatTitle = toNeat.toNeat(title, args) if args.album: - neatAlbum = toNeat(album) + neatAlbum = toNeat.toNeat(album, args) print(" neatArtist: " + neatArtist) print(" neatTitle: " + neatTitle) if args.album: diff --git a/python2.7/toNeat.py b/python2.7/toNeat.py new file mode 100755 index 0000000..34211cd --- /dev/null +++ b/python2.7/toNeat.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python2.7 + +import re +import sys + +# Maps a string such as 'The Beatles' to 'the-beatles'. +def toNeat(s, args): + if args.capital: + s = s.title().replace("&", "and") + else: + 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 '='. + if args.capital: + search = re.search("[^0-9a-zA-Z\-\+\=]", s) + else: + search = re.search("[^0-9a-z\-\+\=]", s) + if search: + print("Error: Unrecognized character in '" + s + "'") + sys.exit(-42) + return s From 0f223be19b4a6e39a85ddd6f29ddae343617954a Mon Sep 17 00:00:00 2001 From: joostsijm Date: Wed, 6 Jul 2016 11:46:16 +0200 Subject: [PATCH 28/30] updated the pitignore to ignore compiled python bitcode --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bee8a64..8d35cb3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__ +*.pyc From 483f06a2d1d84ac35a315fd609b91c7fb84da42f Mon Sep 17 00:00:00 2001 From: joostsijm Date: Wed, 6 Jul 2016 13:46:24 +0200 Subject: [PATCH 29/30] album support for auto-playlist --- python2.7/music-autoplaylists.py | 56 ++++++++++++-------------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/python2.7/music-autoplaylists.py b/python2.7/music-autoplaylists.py index 0ae7aa7..85a0943 100755 --- a/python2.7/music-autoplaylists.py +++ b/python2.7/music-autoplaylists.py @@ -21,10 +21,13 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('--musicDir', type=str, default='.') parser.add_argument('--playlistDir', type=str, default='./playlists/auto') + parser.add_argument('-a','--album', action='store_true', help='''Album mode''') + parser.add_argument('-g','--genre', action='store_true', help='''Genre mode''') parser.add_argument('-C','--capital', action='store_true', help='''Changes names to capital''') args = parser.parse_args() - genres = defaultdict(list) + titleList = defaultdict(list) + for dpath, dnames, fnames in os.walk(args.musicDir): if '.git' in dpath: continue @@ -33,50 +36,31 @@ def main(): 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])) - genre = toNeat.toNeat(str(audio['genre'][0]), args) - else: - genre = 'Unknown' - genres[genre].append(p) + if args.genre: + if 'genre' in audio: + assert(len(audio['genre']) == 1) + title = toNeat.toNeat(str(audio['genre'][0]), args) + else: + title = 'Unknown' + titleList[title].append(p) + elif args.album: + if 'album' in audio: + assert(len(audio['album']) == 1) + title = toNeat.toNeat(str(audio['album'][0]), args) + else: + title = 'Unknown' + titleList[title].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') + for titleList, songs in titleList.items(): + p = os.path.join(args.playlistDir, title + '.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 de9e0dfac7fcf3aa3ac51c3e92832add528ec352 Mon Sep 17 00:00:00 2001 From: joostsijm Date: Wed, 6 Jul 2016 13:46:24 +0200 Subject: [PATCH 30/30] album support for auto-playlist --- python2.7/audioFunction.py | 13 ++++++++ python2.7/fix-music-tags.py | 30 +++-------------- python2.7/music-autoplaylists.py | 56 ++++++++++++-------------------- python2.7/music-organizer.py | 18 +++------- python2.7/tracknumber.py | 31 ++++++++++++++++++ 5 files changed, 73 insertions(+), 75 deletions(-) create mode 100755 python2.7/audioFunction.py create mode 100755 python2.7/tracknumber.py diff --git a/python2.7/audioFunction.py b/python2.7/audioFunction.py new file mode 100755 index 0000000..95effbc --- /dev/null +++ b/python2.7/audioFunction.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python2.7 + +from mutagen.easyid3 import EasyID3 +from mutagen.oggvorbis import OggVorbis +import os + +def returnAudio(path): + ext = os.path.splitext(path)[1] + if ext == ".mp3": + audio = EasyID3(path) + elif ext == ".ogg": + audio = OggVorbis(path) + return audio diff --git a/python2.7/fix-music-tags.py b/python2.7/fix-music-tags.py index 2fdf4eb..8872499 100755 --- a/python2.7/fix-music-tags.py +++ b/python2.7/fix-music-tags.py @@ -13,17 +13,11 @@ import argparse import glob import re - -def returnAudio(path): - ext = os.path.splitext(path)[1] - if ext == ".mp3": - audio = EasyID3(path) - elif ext == ".ogg": - audio = OggVorbis(path) - return audio +import tracknumber +import audioFunction def fixTags(fname, keep): - audio = returnAudio(fname) + audio = audioFunction.returnAudio(fname) delKeys = [] for k, v in audio.items(): if k not in keep: @@ -33,22 +27,6 @@ def fixTags(fname, keep): del audio[k] audio.save() -def fixNumber(fname): - audio = returnAudio(fname) - if 'tracknumber' in audio: - if '/' in audio['tracknumber'][0]: - audio['tracknumber'] = audio['tracknumber'][0].split('/')[0].zfill(2) - audio.save() - return - - else: - try: - tracknumber = re.findall(r'\d+', os.path.basename(fname).split(' ')[0])[0] - audio['tracknumber'] = tracknumber.zfill(2) - audio.save() - except: - return - if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('directory', help='Directory with mp3 files to fix.') @@ -70,4 +48,4 @@ def fixNumber(fname): print("Fixing tags for {}".format(fname)) fixTags(fname, args.keep) if args.fixnumber: - fixNumber(fname) + tracknumber.formatNumber(fname) diff --git a/python2.7/music-autoplaylists.py b/python2.7/music-autoplaylists.py index 0ae7aa7..85a0943 100755 --- a/python2.7/music-autoplaylists.py +++ b/python2.7/music-autoplaylists.py @@ -21,10 +21,13 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('--musicDir', type=str, default='.') parser.add_argument('--playlistDir', type=str, default='./playlists/auto') + parser.add_argument('-a','--album', action='store_true', help='''Album mode''') + parser.add_argument('-g','--genre', action='store_true', help='''Genre mode''') parser.add_argument('-C','--capital', action='store_true', help='''Changes names to capital''') args = parser.parse_args() - genres = defaultdict(list) + titleList = defaultdict(list) + for dpath, dnames, fnames in os.walk(args.musicDir): if '.git' in dpath: continue @@ -33,50 +36,31 @@ def main(): 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])) - genre = toNeat.toNeat(str(audio['genre'][0]), args) - else: - genre = 'Unknown' - genres[genre].append(p) + if args.genre: + if 'genre' in audio: + assert(len(audio['genre']) == 1) + title = toNeat.toNeat(str(audio['genre'][0]), args) + else: + title = 'Unknown' + titleList[title].append(p) + elif args.album: + if 'album' in audio: + assert(len(audio['album']) == 1) + title = toNeat.toNeat(str(audio['album'][0]), args) + else: + title = 'Unknown' + titleList[title].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') + for titleList, songs in titleList.items(): + p = os.path.join(args.playlistDir, title + '.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() diff --git a/python2.7/music-organizer.py b/python2.7/music-organizer.py index 34513bb..ce4c933 100755 --- a/python2.7/music-organizer.py +++ b/python2.7/music-organizer.py @@ -23,6 +23,8 @@ import toNeat from mutagen.easyid3 import EasyID3 from mutagen.oggvorbis import OggVorbis +import tracknumber +import audioFunction parser = argparse.ArgumentParser( description='''Organizes a music collection using tag information. @@ -87,23 +89,13 @@ def song(filename): if ext in (".mp3" , ".ogg"): print("Organizing song '" + filename + "'.") try: - if ext == ".mp3": - audio = EasyID3(filename) - elif ext == ".ogg": - audio = OggVorbis(filename) + audio = audioFunction.returnAudio(filename) artist = audio['artist'][0].encode('ascii', 'ignore') title = audio['title'][0].encode('ascii', 'ignore') if args.album: album = audio['album'][0].encode('ascii', 'ignore') if args.numbering: - try: - tracknumber = audio['tracknumber'][0].encode('ascii', 'ignore') - except: - try: - tracknumber = re.findall(r'\d+', os.path.basename(filename).split(' ')[0])[0] - except: - tracknumber = "error" - neatTracknumber = tracknumber.split('/')[0].zfill(2) + neatTracknumber = tracknumber.getTracknumber(filename) print(" artist: " + artist) print(" title: " + title) if args.album: @@ -114,7 +106,7 @@ def song(filename): if args.album: album = None if args.numbering: - tracknumber = None + neatTracknumber = None neatArtist = toNeat.toNeat(artist, args) if args.numbering: diff --git a/python2.7/tracknumber.py b/python2.7/tracknumber.py new file mode 100755 index 0000000..c541628 --- /dev/null +++ b/python2.7/tracknumber.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python2.7 + +from mutagen.easyid3 import EasyID3 +from mutagen.oggvorbis import OggVorbis +import audioFunction +import os +import re + +def fixTracknumber(fname): + print("fixTracknumber") + audio = audioFunction.returnAudio(fname) + try: + tracknumber = re.findall(r'\d+', os.path.basename(fname).split(' ')[0])[0] + except: + tracknumber = "0" + audio['tracknumber'] = tracknumber.zfill(2) + return formatNumber(audio) + +def formatNumber(fname): + audio = audioFunction.returnAudio(fname) + if 'tracknumber' not in audio: + fixTracknumber(fname) + if '/' in audio['tracknumber'][0]: + audio['tracknumber'] = audio['tracknumber'][0].split('/')[0] + audio['tracknumber'][0] + audio.save() + return audio + +def getTracknumber(fname): + audio = formatNumber(fname) + return audio['tracknumber'][0].encode('ascii', 'ignore')