mirror of
https://github.com/cooperhammond/irs.git
synced 2025-02-28 23:26:48 +00:00
You can now download off of playlists and add more search terms when looking for an album. Patch
This commit is contained in:
parent
f562cc0a38
commit
c743fcc51d
23
README.md
23
README.md
|
@ -8,16 +8,29 @@ An ingenious program to download audio from youtube and then parse metadata for
|
||||||
___
|
___
|
||||||
### Usage and Examples
|
### 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
|
-h, --help show this help message and exit
|
||||||
-v, --version Display the version 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
|
-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
|
-A ALBUM, --album ALBUM
|
||||||
Specify album name of the artist
|
Specify album name of the artist.
|
||||||
-s SONG, --song SONG Specify song 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.
|
||||||
```
|
```
|
||||||
[](https://asciinema.org/a/bcs7i0sjmka052wsdyxg5xrug?speed=3&autoplay=true)
|
[](https://asciinema.org/a/bcs7i0sjmka052wsdyxg5xrug?speed=3&autoplay=true)
|
||||||
|
|
||||||
|
|
|
@ -30,18 +30,56 @@ def console():
|
||||||
rip_album(album, artist)
|
rip_album(album, artist)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser(add_help=False)
|
||||||
parser.add_argument('-a', '--artist', dest="artist", help="Specify the artist name")
|
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('-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 = 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()
|
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
|
import pkg_resources
|
||||||
print ("\n\n" + color("Ingenious Redistribution System", ["HEADER", "BOLD"]))
|
print ("\n\n" + color("Ingenious Redistribution System", ["HEADER", "BOLD"]))
|
||||||
print ("Homepage: " + color("https://github.com/kepoorhampond/irs", ["OKGREEN"]))
|
print ("Homepage: " + color("https://github.com/kepoorhampond/irs", ["OKGREEN"]))
|
||||||
|
@ -51,19 +89,31 @@ def main():
|
||||||
print ("\n")
|
print ("\n")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
if args.artist and not (args.album or args.song):
|
elif not args.album and args.search_terms:
|
||||||
print ("usage: __init__.py [-h] [-a ARTIST] [-A ALBUM | -s SONG] \n\
|
parser.error("error: must supply -A/--album if you are going to supply -st/--search-terms")
|
||||||
error: must specify -A/--album or -s/--song if specifying -a/--artist")
|
|
||||||
exit(1)
|
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()
|
console()
|
||||||
|
|
||||||
|
elif args.playlist:
|
||||||
|
rip_playlist(args.playlist, args.command)
|
||||||
|
|
||||||
elif args.artist:
|
elif args.artist:
|
||||||
if args.album:
|
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:
|
elif args.song:
|
||||||
rip_mp3(args.song, args.artist)
|
rip_mp3(args.song, args.artist, command=args.command)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -44,9 +44,37 @@ def find_mp3(song, artist):
|
||||||
|
|
||||||
return search_results[i]
|
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,
|
def rip_album(album, artist,
|
||||||
tried=False, # for if it can't find the album the first time
|
tried=False, # for if it can't find the album the first time
|
||||||
search="album", # ditto
|
search="album", # ditto
|
||||||
|
command=None # For running a command with the song's location
|
||||||
):
|
):
|
||||||
visible_texts = search_google(album, artist, search)
|
visible_texts = search_google(album, artist, search)
|
||||||
errors = []
|
errors = []
|
||||||
|
@ -86,10 +114,12 @@ def rip_album(album, artist,
|
||||||
for i, j in enumerate(songs):
|
for i, j in enumerate(songs):
|
||||||
song = j
|
song = j
|
||||||
print (color("\n%s/%s - " % (i + 1, len(songs)), ["UNDERLINE"]), end="")
|
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:
|
if len(errors) > 0:
|
||||||
for error in errors: print (error)
|
for error in errors: print (error)
|
||||||
|
else:
|
||||||
|
print (bc.BOLD + bc.UNDERLINE + album + bc.ENDC + bc.OKGREEN + " downloaded successfully!\n")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if str(e) == "local variable 'indexed' referenced before assignment" or str(e) == 'list index out of range':
|
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
|
part_of_album=False, # neccessary for creating folders
|
||||||
album=None, # if you want to specify an album and save a bit of time
|
album=None, # if you want to specify an album and save a bit of time
|
||||||
tracknum=None, # to specify the tracknumber in the album
|
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)
|
audio_code = find_mp3(song, artist)
|
||||||
|
@ -129,8 +160,10 @@ def rip_mp3(song, artist,
|
||||||
|
|
||||||
|
|
||||||
artist_folder = artist
|
artist_folder = artist
|
||||||
|
|
||||||
if not os.path.isdir(artist_folder):
|
if not os.path.isdir(artist_folder):
|
||||||
os.makedirs(artist_folder)
|
os.makedirs(artist_folder)
|
||||||
|
|
||||||
if not part_of_album:
|
if not part_of_album:
|
||||||
location = artist_folder
|
location = artist_folder
|
||||||
|
|
||||||
|
@ -152,3 +185,7 @@ def rip_mp3(song, artist,
|
||||||
|
|
||||||
print (color(song, ["BOLD", "UNDERLINE"]) + bc.OKGREEN + ' downloaded successfully!'+ bc.ENDC)
|
print (color(song, ["BOLD", "UNDERLINE"]) + bc.OKGREEN + ' downloaded successfully!'+ bc.ENDC)
|
||||||
print ("")
|
print ("")
|
||||||
|
|
||||||
|
if command:
|
||||||
|
loc = location + "/" + filename
|
||||||
|
os.system((command.replace("%(loc)s", '"%s"' % loc) + " &"))
|
||||||
|
|
|
@ -96,18 +96,17 @@ def parse_metadata(song, artist, location, filename,
|
||||||
# Album art
|
# Album art
|
||||||
try:
|
try:
|
||||||
if not album_art_url:
|
if not album_art_url:
|
||||||
album_art_url = get_albumart_url(album, artist)
|
temp_url = get_albumart_url(album, artist)
|
||||||
embed_mp3(album_art_url, location + "/" + filename)
|
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.
|
else: # If part of an album, it should do this.
|
||||||
embed_mp3(album_art_url, location + "/" + filename)
|
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:
|
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):
|
def embed_mp3(albumart_url, song_location):
|
||||||
image = urlopen(albumart_url)
|
image = urlopen(albumart_url)
|
||||||
|
@ -130,6 +129,14 @@ def embed_mp3(albumart_url, song_location):
|
||||||
audio.save()
|
audio.save()
|
||||||
|
|
||||||
def get_albumart_url(album, artist):
|
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)
|
album = "%s %s Album Art" % (artist, album)
|
||||||
url = ("https://www.google.com/search?q=" + quote(album.encode('utf-8')) + "&source=lnms&tbm=isch")
|
url = ("https://www.google.com/search?q=" + quote(album.encode('utf-8')) + "&source=lnms&tbm=isch")
|
||||||
header = {
|
header = {
|
||||||
|
@ -143,7 +150,11 @@ def get_albumart_url(album, artist):
|
||||||
|
|
||||||
soup = BeautifulSoup(urlopen(Request(url, headers=header)), "html.parser")
|
soup = BeautifulSoup(urlopen(Request(url, headers=header)), "html.parser")
|
||||||
|
|
||||||
albumart_div = soup.find("div", {"class": "rg_meta"})
|
albumart_divs = soup.findAll("div", {"class": "rg_meta"})
|
||||||
albumart = json.loads(albumart_div.text)["ou"]
|
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
|
return albumart
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -2,7 +2,7 @@ from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='irs',
|
name='irs',
|
||||||
version='1.2.8',
|
version='1.4.9',
|
||||||
description='A music downloader that just gets metadata.',
|
description='A music downloader that just gets metadata.',
|
||||||
url='https://github.com/kepoorhampond/irs',
|
url='https://github.com/kepoorhampond/irs',
|
||||||
author='Kepoor Hampond',
|
author='Kepoor Hampond',
|
||||||
|
|
Loading…
Reference in a new issue