Deleted files to start from the ground up

This commit is contained in:
Kepoor Hampond 2017-03-04 00:23:42 -08:00
parent 651d647767
commit abb60534d9
4 changed files with 1 additions and 645 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@
/dist/
/*.egg-info/
/build/
__pycache__/
# For easy updating of stuff.
update_pypi_and_github.py

View file

@ -1,130 +0,0 @@
#!/usr/bin python
HELP = \
"""
usage:
irs (-h | -v | -C)
irs [-l] [-sa]
irs -p PLAYLIST [-c COMMAND] [-l] [-sa]
irs -A ALBUM [-c COMMAND] [-l] [-sa]
irs -a ARTIST -s SONG [-c COMMAND] [-l]
Options:
-h, --help show this help message and exit
-v, --version Display the version and exit.
-C, --config Return location of configuration file.
-A ALBUM, --album ALBUM
Search spotify for an album.
-p PLAYLIST, --playlist PLAYLIST
Search spotify for a playlist.
-u USER, --user USER Download a user playlist.
-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. Only needed for -s/--song
-s SONG, --song SONG Specify song name of the artist. Must be used with
-a/--artist
-l, --choose-link If supplied, will bring up a console choice for what
link you want to download based off a list of titles.
-sa, --start-at A song index to start at if something goes wrong while
downloading and you have to restart.
-of, --one-folder To place all songs downloaded from a playlist into one
folder.
"""
# For exiting
from sys import exit
# Parsing args
import argparse
# Import the manager
from .manager import Manager
from .utils import *
from .config import CONFIG
def main():
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', '--config', dest="config", action='store_true', help="Return config file location.")
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('-u', '--user', dest="user", help="Specify user to download playlists from.")
parser.add_argument('-l', '--choose-link', action='store_true', dest="link", \
help="Whether or not to choose the link from a list of titles.")
parser.add_argument('-sa', '--start-at', dest="start_at", help="An index to start at if downloading a list.")
parser.add_argument('-p', '--playlist', dest="playlist", \
help="Specify playlist filename. Each line should be formatted like so: SONGNAME - ARTIST")
parser.add_argument('-of', '--one-folder', action="store_true", dest="one_folder", \
help="Place all downloaded playlist songs into one folder")
media = parser.add_mutually_exclusive_group()
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.")
args = parser.parse_args(sys.argv[1:] + CONFIG["default_flags"].split(" ")[:-1])
manager = Manager(args)
if args.help:
global HELP
print (HELP)
exit(1)
elif args.version:
import pkg_resources
print ("\n\n" + color("Ironic Redistribution System", ["HEADER", "BOLD"]))
print ("Homepage: " + color("https://github.com/kepoorhampond/irs", ["OKGREEN"]))
print ("License: " + color("GNU", ["YELLOW"]) + " (http://www.gnu.org/licenses/gpl.html)")
print ("Version: " + pkg_resources.get_distribution("irs").version)
print ("\n")
exit(0)
elif args.config:
print (get_config_file_path())
#elif args.artist and not (args.album or args.song):
# parser.error("error: must supply -A/--album or -s/--song if specifying -a/--artist")
# exit(1)
elif args.playlist:
manager.rip_spotify_list("playlist")
elif args.user:
manager.rip_spotify_list("user")
elif args.album:
manager.rip_spotify_list("album")
elif args.song and not args.artist:
parser.error("error: must supply -a/--artist if specifying -s/--song")
exit(1)
elif args.song:
manager.rip_mp3()
else:
manager.console()
if __name__ == "__main__":
main()

View file

@ -1,352 +0,0 @@
# Powered by:
import youtube_dl
from spotipy.oauth2 import SpotifyClientCredentials
import spotipy
# Info getting
from urllib.request import urlopen
from urllib.parse import urlencode
# Info parsing
from re import findall
import os, json
from bs4 import BeautifulSoup
# Local utils
from .utils import *
from .metadata import *
from .config import CONFIG
class Manager:
def __init__(self, args):
self.args = args
def console(self):
args = self.args
os.system("clear")
media = None
while type(media) is not int:
print (bc.HEADER)
print ("What type of media would you like to download?")
print ("\t1) Song")
print ("\t2) Album")
print ("\t3) Playlist")
try:
media = int(input(bc.YELLOW + bc.BOLD + ":: " + bc.ENDC))
if media not in (1, 2, 3):
raise ValueError
except ValueError:
print (bc.FAIL + "\nPlease enter a valid number." + bc.ENDC)
if media == 1:
self.args.song = color_input("Song you would like to download")
self.args.artist = color_input("Name of artist")
self.rip_mp3()
elif media == 2:
self.args.album = color_input("Album you would like to download")
self.rip_spotify_list("album")
elif media == 3:
self.args.playlist = color_input("Playlist name to search for")
self.rip_spotify_list("playlist")
def find_mp3(self, song=None, artist=None):
if not song:
song = self.args.song
if not artist:
artist = self.args.artist
print (color(song, ["BOLD", "UNDERLINE"]) + ' by ' + color(artist, ["BOLD", "UNDERLINE"]))
search_terms = song + " " + artist + " " + CONFIG["additional_search_terms"]
query_string = urlencode({"search_query" : (search_terms)})
html_content = urlopen("http://www.youtube.com/results?" + query_string)
search_results = findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
in_title = False
i = -1
given_up_score = 0
if not self.args.link:
print (bc.YELLOW + "\nFinding youtube link ...", end="\r")
while in_title == False:
i += 1
given_up_score += 1
if given_up_score >= 10:
in_title = True
try:
audio_url = ("http://www.youtube.com/watch?v=" + search_results[i])
except Exception:
print (bc.FAIL + "Could not find song." + bc.ENDC)
return False
title = strip_special_chars((BeautifulSoup(urlopen(audio_url), 'html.parser')).title.string.lower())
song_title = song.lower().split("/")
for song in song_title:
song = strip_special_chars(song)
if song in title and "full album" not in title:
in_title = True
print (bc.OKGREEN + "Found youtube link! \n" + bc.ENDC)
else:
results = []
print (bc.YELLOW + "\nFinding links ... " + bc.ENDC, end="\r")
for key in search_results[:10]:
results.append(BeautifulSoup(urlopen(("http://www.youtube.com/watch?v="\
+ key)), 'html.parser').title.string.replace(" - YouTube" , ""))
valid_choice = False
while valid_choice == False:
print (bc.HEADER + "What song would you like to download?")
index = 0
for result in results:
index += 1
print (" %s) %s" % (index, result))
i = int(input(bc.YELLOW + bc.BOLD + ":: " + bc.ENDC))
if i in tuple(range(1, 11)):
i -= 1
valid_choice = True
return search_results[i]
def get_album_art(self, artist, album, id=None):
spotify = spotipy.Spotify()
if id:
album = spotify.album(id)
return album["images"][0]["url"]
results = spotify.search(q=artist + " " + album, type='album')
items = results['albums']['items']
if len(items) > 0:
album = items[0]['images'][0]['url']
return album
def rip_spotify_list(self, type):
if type == "playlist":
search = self.args.playlist
elif type == "album":
search = self.args.album
if self.args.artist:
search += self.args.artist
try:
client_credentials_manager = SpotifyClientCredentials(CONFIG["client_id"], CONFIG["client_secret"])
spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
except spotipy.oauth2.SpotifyOauthError:
spotify = spotipy.Spotify()
if type == "user":
items = spotify.user_playlists(self.args.user)["items"]
length = None
else:
results = spotify.search(q=search, type=type)
items = results[type + "s"]['items']
length = 10
songs = []
if len(items) > 0:
spotify_list = choose_from_spotify_list(items, length=length)
list_type = spotify_list["type"]
name = spotify_list["name"]
if list_type != "playlist":
spotify_list = eval("spotify.%s" % list_type)(spotify_list["uri"])
else:
try:
spotify_list = spotify.user_playlist(spotify_list["owner"]["id"], \
playlist_id=spotify_list["uri"], fields="tracks,next")
except spotipy.client.SpotifyException:
fail_oauth()
print (bc.YELLOW + "\nFetching tracks and their metadata: " + bc.ENDC)
increment = 0
for song in spotify_list["tracks"]["items"]:
increment += 1
list_size = increment / len(spotify_list["tracks"]["items"])
drawProgressBar(list_size)
if list_type == "playlist":
song = song["track"]
artist = spotify.artist(song["artists"][0]["id"])
if list_type == "playlist":
album = (spotify.track(song["uri"])["album"])
else:
album = spotify_list
songs.append({
"name": song["name"].split(" - ")[0],
"artist": artist["name"],
"album": album["name"],
"tracknum": increment,
"album_cover": album["images"][0]["url"]
})
print (bc.OKGREEN + "\nFound tracks:" + bc.ENDC)
print (bc.HEADER)
for song in songs:
print ("\t" + song["name"] + " - " + song["artist"])
print (bc.ENDC + "\n")
if self.args.start_at:
start_at = int(self.args.start_at) - 1
if start_at < 0:
start_at = 0
else:
start_at = 0
for song in songs[start_at:]:
already_there = False
if os.path.isdir(CONFIG["directory"] + "/" + song["artist"]):
already_there = True
song_loc = self.rip_mp3(song["name"], song["artist"], album=song["album"], \
tracknum=song["tracknum"], album_art_url=song["album_cover"], \
out_of="%s/%s - " % (song["tracknum"], len(songs)))
if song_loc == False:
continue
if self.args.one_folder:
one_folder = CONFIG["directory"] + "/" + strip_special_chars(name[:30])
if not os.path.isdir(one_folder):
os.makedirs(one_folder)
new_loc = one_folder + "/" + song_loc.split("/")[-1]
os.rename(song_loc, new_loc)
if not already_there:
import shutil
shutil.rmtree(CONFIG["directory"] + "/" + song["artist"])
if self.args.command:
os.system((self.args.command.replace("%(loc)s", '"%s"' % new_loc) + " &"))
else:
print (bc.FAIL + "No results were found. Make sure to use proper spelling and capitalization." + bc.ENDC)
exit(1)
def rip_mp3(self, song=None, artist=None,
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.
out_of="", # For a string to put before the song title.
):
if not song:
song = self.args.song
if not artist:
artist = self.args.artist
print (color(out_of, ["UNDERLINE"]), end="")
audio_code = self.find_mp3(song=song, artist=artist)
if audio_code == False:
return False
if CONFIG["numbered_file_names"] and tracknum:
track = str(tracknum) + " - "
else:
track = ""
filename = track + strip_special_chars(song) + ".mp3"
if CONFIG["download_file_names"]:
filename = track + strip_special_chars((BeautifulSoup(\
urlopen("http://www.youtube.com/watch?v=" + audio_code), 'html.parser'))\
.title.string.lower()).strip("youtube") + ".mp3"
ydl_opts = {
'format': 'bestaudio/best',
#'quiet': True,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(["http://www.youtube.com/watch?v=" + audio_code])
artist_folder = CONFIG["directory"] + "/" + artist
if not os.path.isdir(artist_folder):
os.makedirs(artist_folder)
if album:
album_folder = CONFIG["directory"] + "/" + artist + "/" + album
if not os.path.isdir(album_folder):
os.makedirs(album_folder)
location = album_folder
elif not album:
location = artist_folder
for file in os.listdir("."):
if audio_code in file:
os.rename(file, location + "/" + filename)
# Metadata
mp3 = Metadata(location + "/" + filename, song, artist)
mp3.add_title()
exclaim_good("Title added: ", song)
mp3.add_artist()
exclaim_good("Artist added: ", artist)
test_goodness(mp3.add_album(album), "Album", "album", mp3)
test_goodness(mp3.add_release_date(), "Release Date", "date", mp3)
if tracknum:
mp3.add_track_number(tracknum)
try:
image_url = mp3.add_album_art(self.get_album_art(artist, mp3.get_attr('album')))
exclaim_good("Album art: ", image_url)
except Exception:
print (bc.FAIL + "Album art not added." + bc.ENDC)
print (color(song, ["BOLD", "UNDERLINE"]) + bc.OKGREEN + ' downloaded successfully!'+ bc.ENDC)
print ("")
if self.args.command:
loc = location + "/" + filename
os.system((self.args.command.replace("%(loc)s", '"%s"' % loc) + " &"))
return (location + "/" + filename)

View file

@ -1,163 +0,0 @@
import sys, os, spotipy, irs
def get_config_file_path():
return os.path.dirname(irs.__file__) + "/config.py"
def strip_special_chars(string):
special_chars = "\ / : * ? \" < > | - ( )".split(" ")
for char in special_chars:
string = string.replace(char, "")
return string
def supports_color():
"""
Returns True if the running system's terminal supports color, and False
otherwise.
"""
plat = sys.platform
supported_platform = plat != 'Pocket PC' and (plat != 'win32' or
'ANSICON' in os.environ)
# isatty is not always implemented, #6223.
is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
if not supported_platform or not is_a_tty:
return False
return True
if supports_color():
class bc:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[32m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
GRAY = '\033[30m'
YELLOW = '\033[33m'
else:
class bc:
HEADER = ''
OKBLUE = ''
OKGREEN = ''
WARNING = ''
FAIL = ''
ENDC = ''
BOLD = ''
UNDERLINE = ''
GRAY = ''
YELLOW = ''
def color(text, colors=[]):
if colors == []:
raise "Must have definitions when calling color(text, colors=[])"
color_string = ""
for color in colors:
color_string += "bc.%s + " % color
color_string = color_string[:-2]
return (bc.ENDC + eval(color_string) + str(text) + bc.ENDC)
def color_input(text):
print (bc.HEADER + text, end=" ")
return input(bc.BOLD + bc.YELLOW + ": " + bc.ENDC)
def exclaim_good(text, item):
print (bc.OKGREEN + text + bc.ENDC + item)
def test_goodness(test, word, metadata_id, mp3):
if test:
exclaim_good(word + " added: ", mp3.get_attr(metadata_id))
else:
print (bc.FAIL + word + " not added." + bc.ENDC)
def search_google(self, search_terms=""):
def visible(element):
if element.parent.name in ['style', 'script', '[document]', 'head', 'title']:
return False
elif match('<!--.*-->', str(element)):
return False
return True
search_terms = "%s %s %s" % (self.song, self.artist, search_terms)
url = 'http://www.google.com/search?q=' + quote_plus(search_terms)
hdr = {
'User-Agent':'Mozilla/5.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
}
texts = BeautifulSoup(urlopen(Request(url, \
headers=hdr)).read(), 'html.parser').findAll(text=True)
return list(filter(visible, texts))
def unorganize(file_name, location, song_number, artist):
locations = location.split("/")
folder_name = ("playlist - " + file_name)[:40]
if not os.path.isdir(folder_name):
os.makedirs(folder_name)
os.rename(location, "%s/%s - %s" % (folder_name, song_number, locations[-1]))
if remove:
import shutil # Only import this if I have to.
shutil.rmtree(locations[0])
def finish_unorganize(file_name):
folder_name = ("playlist - " + file_name)[:40]
os.rename(file_name, folder_name + "/" + file_name)
os.rename(folder_name, folder_name.replace("playlist - ", ""))
def fail_oauth():
print (bc.FAIL + "To download Spotify playlists, you need to supply client_ids." + bc.ENDC)
print ("To do this, you'll want to create an application here:")
print ("https://developer.spotify.com/my-applications/#!/applications/create")
print ("Once you've done that, you'll want to copy your 'client id' and your 'client secret'")
print ("into the config file and their corresponding locations:")
print (get_config_file_path())
exit(1)
def choose_from_spotify_list(thelist, length=100000):
spotify = spotipy.Spotify()
thelist = list(thelist)
print ("Results:")
choice = ""
while choice not in tuple(range(0, len(thelist[:length]))):
for index, result in enumerate(thelist[:length]):
type = result["type"]
if type == "playlist":
info = spotify.user(result["owner"]["id"])
try:
display_info = " (" + str(info["followers"]["total"]) + " followers)"
display_info += " - " + info["display_name"]
except Exception:
display_info = " - info couldn't be found"
elif type == "album":
info = spotify.album(result["id"])
display_info = " - " + info["artists"][0]["name"]
print ("\t" + str(index) + ") " + bc.HEADER + result["name"] + display_info + bc.ENDC)
choice = int(input(bc.YELLOW + "\nEnter result number: " + bc.ENDC))
return thelist[choice]
def drawProgressBar(percent, barLen = 40):
import sys
sys.stdout.write("\r")
progress = ""
for i in range(barLen):
if i < int(barLen * percent):
progress += "#"
else:
progress += "-"
sys.stdout.write("[%s] %.2f%%" % (progress, percent * 100))
sys.stdout.flush()