From c743fcc51d7848e20501c52860d5a014d6c864f2 Mon Sep 17 00:00:00 2001 From: Kepoor Hampond Date: Wed, 14 Dec 2016 22:45:07 -0800 Subject: [PATCH] You can now download off of playlists and add more search terms when looking for an album. Patch --- README.md | 25 ++++++++++++----- irs/__main__.py | 72 +++++++++++++++++++++++++++++++++++++++++-------- irs/manage.py | 41 ++++++++++++++++++++++++++-- irs/metadata.py | 29 +++++++++++++------- setup.py | 2 +- 5 files changed, 140 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index d9ca5df..28377d8 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,30 @@ An ingenious program to download audio from youtube and then parse metadata for ___ ### Usage and Examples ``` -usage: irs [-h] [-v] [-a ARTIST] [-A ALBUM | -s SONG] +usage: + irs + irs (-h | -v) + irs -p PLAYLIST [-c COMMAND] + irs -a ARTIST (-s SONG | -A ALBUM [-st SEARCH_TERMS]) [-c COMMAND] -optional arguments: +Options: -h, --help show this help message and exit -v, --version Display the version and exit. + -c COMMAND, --command COMMAND + Run a background command with each song's location. + Example: `-c "rhythmbox %(loc)s"` -a ARTIST, --artist ARTIST - Specify the artist name + Specify the artist name. + -p PLAYLIST, --playlist PLAYLIST + Specify playlist filename. Each line in the file + should be formatted like so: `SONGNAME - ARTIST` + -s SONG, --song SONG Specify song name of the artist. -A ALBUM, --album ALBUM - Specify album name of the artist - -s SONG, --song SONG Specify song name of the artist - ``` + Specify album name of the artist. + -st SEARCH_TERMS, --search-terms SEARCH_TERMS + Only use if calling -A/--album. Acts as extra search + terms when looking for the album. +``` [![asciicast](https://asciinema.org/a/bcs7i0sjmka052wsdyxg5xrug.png)](https://asciinema.org/a/bcs7i0sjmka052wsdyxg5xrug?speed=3&autoplay=true) [![asciicast](https://asciinema.org/a/8kb9882j4cbtd4hwbsbb7h0ia.png)](https://asciinema.org/a/8kb9882j4cbtd4hwbsbb7h0ia?speed=3) diff --git a/irs/__main__.py b/irs/__main__.py index af740ce..01373da 100644 --- a/irs/__main__.py +++ b/irs/__main__.py @@ -30,18 +30,56 @@ def console(): rip_album(album, artist) def main(): - parser = argparse.ArgumentParser() - parser.add_argument('-a', '--artist', dest="artist", help="Specify the artist name") + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('-h', '--help', action='store_true', dest='help') parser.add_argument('-v', '--version', dest="version", action='store_true', help="Display the version and exit.") + parser.add_argument('-c', '--command', dest="command", help="Run a background command with each song's location.") + parser.add_argument('-a', '--artist', dest="artist", help="Specify the artist name.") + + parser.add_argument('-p', '--playlist', dest="playlist", \ + help="Specify playlist filename. Each line should be formatted like so: SONGNAME - ARTIST") + media = parser.add_mutually_exclusive_group() - media.add_argument('-A', '--album', dest="album", help="Specify album name of the artist") - media.add_argument('-s', '--song', dest="song", help="Specify song name of the artist") + media.add_argument('-s', '--song', dest="song", help="Specify song name of the artist.") + + media.add_argument('-A', '--album', dest="album", help="Specify album name of the artist.") + parser.add_argument('-st', '--search-terms', dest="search_terms", \ + help="Only use if calling -A/--album. Acts as extra search terms for the album.") + args = parser.parse_args() + if args.help: + help = \ +""" +usage: + irs + irs (-h | -v) + irs -p PLAYLIST [-c COMMAND] + irs -a ARTIST (-s SONG | -A ALBUM [-st SEARCH_TERMS]) [-c COMMAND] - if args.version: +Options: + -h, --help show this help message and exit + -v, --version Display the version and exit. + -c COMMAND, --command COMMAND + Run a background command with each song's location. + Example: `-c "rhythmbox %(loc)s"` + -a ARTIST, --artist ARTIST + Specify the artist name. + -p PLAYLIST, --playlist PLAYLIST + Specify playlist filename. Each line in the file + should be formatted like so: `SONGNAME - ARTIST` + -s SONG, --song SONG Specify song name of the artist. + -A ALBUM, --album ALBUM + Specify album name of the artist. + -st SEARCH_TERMS, --search-terms SEARCH_TERMS + Only use if calling -A/--album. Acts as extra search + terms when looking for the album. +""" + print (help) + + elif args.version: import pkg_resources print ("\n\n" + color("Ingenious Redistribution System", ["HEADER", "BOLD"])) print ("Homepage: " + color("https://github.com/kepoorhampond/irs", ["OKGREEN"])) @@ -51,19 +89,31 @@ def main(): print ("\n") exit(0) - if args.artist and not (args.album or args.song): - print ("usage: __init__.py [-h] [-a ARTIST] [-A ALBUM | -s SONG] \n\ - error: must specify -A/--album or -s/--song if specifying -a/--artist") + elif not args.album and args.search_terms: + parser.error("error: must supply -A/--album if you are going to supply -st/--search-terms") exit(1) - elif not args.artist: + elif args.artist and not (args.album or args.song): + print ("error: must specify -A/--album or -s/--song if specifying -a/--artist") + exit(1) + + elif not args.artist and not args.playlist: console() + elif args.playlist: + rip_playlist(args.playlist, args.command) + elif args.artist: if args.album: - rip_album(args.album, args.artist) + if args.search_terms: + rip_album(args.album, args.artist, command=args.command, search=args.search_terms) + else: + rip_album(args.album, args.artist, command=args.command) + elif args.song: - rip_mp3(args.song, args.artist) + rip_mp3(args.song, args.artist, command=args.command) + + if __name__ == "__main__": main() diff --git a/irs/manage.py b/irs/manage.py index 889174e..7b00a9e 100644 --- a/irs/manage.py +++ b/irs/manage.py @@ -44,9 +44,37 @@ def find_mp3(song, artist): return search_results[i] +def rip_playlist(file_name, command=None): + print (command.inspect) + try: + file = open(file_name, 'r') + except Exception: + print (file_name + bc.FAIL + " could not be found." + bc.ENDC) + exit(1) + + errors = [] + + for line in file: + try: + arr = line.strip("\n").split(" - ") + song = arr[0] + artist = arr[1] + rip_mp3(song, artist, command=command) + + except Exception as e: + errors.append("%s" + color(" : ", ["YELLOw"]) + bc.FAIL + str(e) + bc.ENDC) + + if len(errors) > 0: + print (bc.FAIL + "Something was wrong with the formatting of the following lines:" + bc.ENDC) + + for i in errors: + print ("\t%s" % i) + + def rip_album(album, artist, tried=False, # for if it can't find the album the first time search="album", # ditto + command=None # For running a command with the song's location ): visible_texts = search_google(album, artist, search) errors = [] @@ -86,10 +114,12 @@ def rip_album(album, artist, for i, j in enumerate(songs): song = j print (color("\n%s/%s - " % (i + 1, len(songs)), ["UNDERLINE"]), end="") - rip_mp3(j, artist, part_of_album=True, album=album, tracknum=i + 1, album_art_url=album_art_url) + rip_mp3(j, artist, part_of_album=True, album=album, tracknum=i + 1, album_art_url=album_art_url, command=command) if len(errors) > 0: for error in errors: print (error) + else: + print (bc.BOLD + bc.UNDERLINE + album + bc.ENDC + bc.OKGREEN + " downloaded successfully!\n") except Exception as e: if str(e) == "local variable 'indexed' referenced before assignment" or str(e) == 'list index out of range': @@ -108,7 +138,8 @@ def rip_mp3(song, artist, part_of_album=False, # neccessary for creating folders album=None, # if you want to specify an album and save a bit of time tracknum=None, # to specify the tracknumber in the album - album_art_url=None # if you want to save a lot of time trying to find album cover. + album_art_url=None, # if you want to save a lot of time trying to find album cover. + command=None, # For running a command with the song's location ): audio_code = find_mp3(song, artist) @@ -129,8 +160,10 @@ def rip_mp3(song, artist, artist_folder = artist + if not os.path.isdir(artist_folder): os.makedirs(artist_folder) + if not part_of_album: location = artist_folder @@ -152,3 +185,7 @@ def rip_mp3(song, artist, print (color(song, ["BOLD", "UNDERLINE"]) + bc.OKGREEN + ' downloaded successfully!'+ bc.ENDC) print ("") + + if command: + loc = location + "/" + filename + os.system((command.replace("%(loc)s", '"%s"' % loc) + " &")) diff --git a/irs/metadata.py b/irs/metadata.py index 607c444..962c834 100644 --- a/irs/metadata.py +++ b/irs/metadata.py @@ -96,18 +96,17 @@ def parse_metadata(song, artist, location, filename, # Album art try: if not album_art_url: - album_art_url = get_albumart_url(album, artist) - embed_mp3(album_art_url, location + "/" + filename) + temp_url = get_albumart_url(album, artist) + embed_mp3(temp_url, location + "/" + filename) + print (bc.OKGREEN + "Album art parsed: " + bc.ENDC + temp_url) + else: # If part of an album, it should do this. embed_mp3(album_art_url, location + "/" + filename) + print (bc.OKGREEN + "Album art parsed." + bc.ENDC) - if album_art_url: - print (bc.OKGREEN + "Album art parsed!" + bc.ENDC) - else: - print (bc.OKGREEN + "Album art parsed: " + bc.ENDC + album_art_url) except Exception as e: - print (bc.FAIL + "Album art not parsed: " + bc.ENDC + e) + print (bc.FAIL + "Album art not parsed: " + bc.ENDC + str(e)) def embed_mp3(albumart_url, song_location): image = urlopen(albumart_url) @@ -130,6 +129,14 @@ def embed_mp3(albumart_url, song_location): audio.save() def get_albumart_url(album, artist): + def test_404(url): + try: + urlopen(albumart).read() + except Exception: + return False + return True + + tries = 0 album = "%s %s Album Art" % (artist, album) url = ("https://www.google.com/search?q=" + quote(album.encode('utf-8')) + "&source=lnms&tbm=isch") header = { @@ -143,7 +150,11 @@ def get_albumart_url(album, artist): soup = BeautifulSoup(urlopen(Request(url, headers=header)), "html.parser") - albumart_div = soup.find("div", {"class": "rg_meta"}) - albumart = json.loads(albumart_div.text)["ou"] + albumart_divs = soup.findAll("div", {"class": "rg_meta"}) + albumart = json.loads(albumart_divs[tries].text)["ou"] + + while not test_404(albumart): + tries += 1 + albumart = json.loads(albumart_divs[tries].text)["ou"] return albumart diff --git a/setup.py b/setup.py index 604e9f6..bd1b37b 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup setup( name='irs', - version='1.2.8', + version='1.4.9', description='A music downloader that just gets metadata.', url='https://github.com/kepoorhampond/irs', author='Kepoor Hampond',