albumcutter

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit e17792405ebd73383eeafca30e7f63ab028f22e9
parent 67bc285da5e987d723ab0eb9cac7589f21c54bcc
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Thu Nov  5 10:05:22 2015

more bugfix, new option

Diffstat:
 bin/ac             |  5 ++-
 src/albumcutter.py | 82 +++++++++++++++++++++++++++++++++----------------------
 2 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/bin/ac b/bin/ac @@ -10,7 +10,7 @@ def main(): return t = get_tracklist() - AlbumCutter(args[0], t, options.dir) + AlbumCutter(args[0], t, options.dir, resume=options.resume) def parsearg(): parser = OptionParser() @@ -18,6 +18,9 @@ def parsearg(): parser.add_option("-d", dest="dir", default="album", help="Destination album", metavar="<dir>") + parser.add_option("-r", "--resume", dest="resume", action="store_true", + default=False, help="assumes file is already downloaded") + return parser.parse_args() def get_tracklist(): diff --git a/src/albumcutter.py b/src/albumcutter.py @@ -14,12 +14,12 @@ Copyright (c) Paul Longtine <paul@nanner.co> """ -import re, os +import re, os, sys from subprocess import call, Popen, PIPE from pydub import AudioSegment class AlbumCutter: - def __init__( self, url, tracklist, output ): + def __init__( self, url, tracklist, output, resume=False ): self.tracklist = tracklist self.url = url self.output = output @@ -28,31 +28,54 @@ class AlbumCutter: self.tracks = None # Make the directory - if os.path.exists(output): + if os.path.exists(output) and not resume: print("ERROR: Directory exists, aborting") - return + sys.exit(1) try: - os.mkdir(output) + if not resume: + os.mkdir(output) except: print("ERROR: Could not make directory ({})".format(output)) - return + sys.exit(1) - assert(self.get_audio(self.url)) + if not resume: + self.download_audio(self.url) + + self.load_audio(self.url) self.process_tracklist(self.tracklist) self.export(self.output) + # loads the audio + def load_audio( self, url ): + self.fname = self.get_filename(url) + # Loads file into the fancy manipulator thingmajig I found on the web + print("Trying to load file ({})".format(self.fname)) + try: + #TODO actually figure out proper encoding memnonic for this function + # Currently, it just assumes the extension IS the memnonic... + # ...which is bad. We don't want that. + self.audio = AudioSegment.from_file(self.fname, + self.fname.split(".")[1]) + except Exception, e: + print("ERROR: Could not load audio\n{}".format(e)) + sys.exit(1) + + print("Loaded audio") + # fetches audio from URL. - def get_audio( self, url ): + def download_audio( self, url ): print("Downloading audio...") # youtube-dl -q -x -o$(output)/$(VIDEO ID).$(EXTENSION) - if not call(['youtube-dl', '-q', '-x', - '-o{}/%(id)s.%(ext)s'.format(self.output), url]): - return(False) + call(['youtube-dl', '-q', '-x', + '-o{}/%(id)s.%(ext)s'.format(self.output), url]) - # This second call here finds the filename for the audio just downloaded + # gets the filename + def get_filename( self, url ): + # This call here finds the filename for the audio just downloaded # It's not elegant at all, and it was the best solution I could find. # The name of the file ends up in `output` with a newline at the end. + print("Determining filename...") p = Popen(['youtube-dl', '--get-filename', '--skip-download', '-x', '-o{}/%(id)s.%(ext)s'.format(self.output), url], stdin=PIPE, stdout=PIPE, stderr=PIPE) @@ -60,23 +83,7 @@ class AlbumCutter: #removes pesky newline, if it exists output = output[:-1] if output[-1] == "\n" else output - if err != '': - print(err) - return(False) - - # Loads file into the fancy manipulator thingmajig I found on the web - print("Trying to load file ({})".format(output)) - try: - #TODO actually figure out proper encoding memnonic for this function - # Currently, it just assumes the extension IS the memnonic... - # ...which is bad. We don't want that. - self.audio = AudioSegment.from_file(output, output.split(".")[1]) - except Exception, e: - print("ERROR: Could not load audio\n{}".format(e)) - - print("Loaded audio") - - self.fname = output + return output # gives meaning to tracklist using format: # [ { 'start': <starting time>, 'end': <ending time>, 'title': <title> }, ] @@ -84,19 +91,28 @@ class AlbumCutter: tracks = [] # Regex for finding hour, minute, and second. I am proud of this. rt = re.compile(r'((?P<hr>\d+):)?((?P<min>\d+):)(?P<sec>\d+)') + + track_names = [] + track_num = 0 for track in tracklist.split("\n"): # Finds hour, minute and second and converts it into miliseconds times = rt.search(track) + if times == None: + continue ms = self.to_ms(times.group('hr'), times.group('min'), times.group('sec')) - # If time is not a thing, continue. This is not a track listing - if ms == None: - continue # Remove timestamp and prettify the title title = rt.sub('', track) title = re.sub('[^-a-zA-Z0-9_.() ]+', '', title) title = title.strip() + if title == "": + title = "Track {}".format(track_num) + + # Enforces uniqueness + if title in track_names: + title = title + " {}".format(track_num) + # Get prevous track and set the end to this start time if len(tracks) > 0: if type(tracks[-1]) == dict: @@ -104,6 +120,8 @@ class AlbumCutter: tracks.append({"start":ms, "end":-1, "title":title}) + track_num += 1 + self.tracks = tracks # Converts hours, minutes, and seconds into ms and adds them into one number