From abb60534d92b41aa8c983463f02d8a5e68fd437f Mon Sep 17 00:00:00 2001 From: Kepoor Hampond Date: Sat, 4 Mar 2017 00:23:42 -0800 Subject: [PATCH] Deleted files to start from the ground up --- .gitignore | 1 + irs/__main__.py | 130 ------------------ irs/manager.py | 352 ------------------------------------------------ irs/utils.py | 163 ---------------------- 4 files changed, 1 insertion(+), 645 deletions(-) delete mode 100644 irs/__main__.py delete mode 100644 irs/manager.py delete mode 100644 irs/utils.py diff --git a/.gitignore b/.gitignore index 22d4ee4..9f22816 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /dist/ /*.egg-info/ /build/ +__pycache__/ # For easy updating of stuff. update_pypi_and_github.py diff --git a/irs/__main__.py b/irs/__main__.py deleted file mode 100644 index 52f8e4a..0000000 --- a/irs/__main__.py +++ /dev/null @@ -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() diff --git a/irs/manager.py b/irs/manager.py deleted file mode 100644 index 0a013c0..0000000 --- a/irs/manager.py +++ /dev/null @@ -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) diff --git a/irs/utils.py b/irs/utils.py deleted file mode 100644 index 2f8f7af..0000000 --- a/irs/utils.py +++ /dev/null @@ -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()