def setData(SONG_INFO, is_quiet, song_path, datatype='mp3', choice=None): """Add the metadata to the song.""" if datatype == 'mp3': option, img_added = set_MP3_data(SONG_INFO, is_quiet, song_path, choice) elif datatype == 'm4a': option, img_added = set_M4A_data(SONG_INFO, is_quiet, song_path, choice) # Show the written stuff in a better format prepend.PREPEND(1) print('================================') print(' || YEAR: ' + SONG_INFO[option].release_date) print(' || TITLE: ' + SONG_INFO[option].track_name) print(' || ARTIST: ' + SONG_INFO[option].artist_name) print(' || ALBUM: ' + SONG_INFO[option].collection_name) print(' || GENRE: ' + SONG_INFO[option].primary_genre_name) print(' || TRACK NO: ' + str(SONG_INFO[option].track_number)) if img_added: print(' || ALBUM COVER ADDED') prepend.PREPEND(1) print('================================') return option
def setData(SONG_INFO, is_quiet, song_path, datatype='mp3', choice=None): """Add the metadata to the song.""" # Some providers need extra daa from other endpoints, # this is where we define which need it and where to get # it from logger.debug(choice) option = _get_option(SONG_INFO, is_quiet, choice) logger.debug(option) if option != '~': song = SONG_INFO[option] get_more_data_dict = preconfig.CONFIG().GET_EXTRA_DATA # Try to check if the song object has an attribute provider # Deezer has it but other objects don't have it. # If the provider is present then fetch extra data accordingly if hasattr(song, 'provider') and song.provider in get_more_data_dict: song = get_more_data_dict.get(song.provider, lambda _: None)(song) if datatype == 'mp3': img_added = set_MP3_data( song, song_path, ) elif datatype == 'm4a': img_added = set_M4A_data( song, song_path, ) elif datatype == 'opus': img_added = set_OPUS_data(song, song_path) # Show the written stuff in a better format prepend.PREPEND(1) print('================================') print(' || YEAR: ' + song.release_date) print(' || TITLE: ' + song.track_name) print(' || ARTIST: ' + song.artist_name) print(' || ALBUM: ' + song.collection_name) print(' || GENRE: ' + song.primary_genre_name) print(' || TRACK NO: ' + str(song.track_number)) if img_added: print(' || ALBUM COVER ADDED') prepend.PREPEND(1) print('================================') # Otherwise, the user has opted to enter metadata manually. else: logger.debug('The user is manually entering metadata ...') return option
def getData(SONG_NAME): """Try to download the metadata using itunespy.""" # Try to get the song data from itunes try: SONG_INFO = itunespy.search_track(SONG_NAME) return SONG_INFO except LookupError: prepend.PREPEND(2) print('Song not found!') return False except TimeoutError: prepend.PREPEND(2) print('Search timed out. Are you connected to internet?\a') return False else: prepend.PREPEND(2) print('Unknown Error!\a') return False
def getChoice(SONG_INFO, type): """If more than 1 result from getData then ask for a choice.""" # Print 5 of the search results # In case less, print all prepend.PREPEND(1) print('Choose One {}'.format( '(One with [M] is verified music)' if type == 'mp3' else '')) results = len(SONG_INFO) if results > 5: results = 5 PRINT_WHOLE = True default_choice = get_default(SONG_INFO, type) beg = 0 while True: # Print the results first if PRINT_WHOLE: print_choice(beg, results, SONG_INFO, type) prepend.PREPEND(1) choice = IntPrompt.ask('Enter Choice', default=default_choice) choice = int(choice) # If the choice is 6 then try to print more results if choice <= results and choice > 0: break elif choice == 0 and results < len(SONG_INFO): PRINT_WHOLE = True beg = results results = beg + 5 else: PRINT_WHOLE = False choice = int(choice) choice -= 1 return choice
def getChoice(SONG_INFO, type): """If more than 1 result from getData then ask for a choice.""" # Print 5 of the search results # In case less, print all logger.info('Choose One {}'.format( '(One with [M] is verified music)' if type == 'mp3' else '')) results = len(SONG_INFO) if results > 5: results = 5 PRINT_WHOLE = True default_choice = get_default(SONG_INFO, type) beg = 0 while True: # Print the results first if PRINT_WHOLE: print_choice(beg, results, SONG_INFO, type) prepend.PREPEND(1) valid_choices = [*range(-1, len(SONG_INFO) + 1)] valid_choices = list(map(str, valid_choices)) valid_choices.append('~') logger.debug(valid_choices) choice = Prompt.ask('Enter Choice', choices=valid_choices, default=default_choice, show_choices=False) logger.debug(choice) if choice != '~': choice = int(choice) # If the choice is 0 then try to print more results # The choice is valid if it is in the range and it is greater than 0 # We also need to break when the user enters -1 which means the exec # will skip the current song if (choice <= len(SONG_INFO) and choice > 0) or choice == -1: break elif choice == 0 and results < len(SONG_INFO): PRINT_WHOLE = True beg = results results = beg + 5 else: PRINT_WHOLE = False # The user has opted to manually enter metadata for this song. else: return '~' return choice - 1
def getChoice(SONG_INFO, type): """If more than 1 result from getData then ask for a choice.""" # Print 5 of the search results # In case less, print all prepend.PREPEND(1) print('Choose One') results = len(SONG_INFO) if results > 5: results = 5 PRINT_WHOLE = True beg = 0 while True: # Print the results first if PRINT_WHOLE: print_choice(beg, results, SONG_INFO, type) prepend.PREPEND(1) choice = input('Enter Choice [default is 1] ') if not choice: choice = 1 choice = int(choice) # If the choice is 6 then try to print more results if choice <= results and choice > 0: break elif choice == 0 and results < len(SONG_INFO): PRINT_WHOLE = True beg = results results = beg + 5 else: PRINT_WHOLE = False choice = int(choice) choice -= 1 return choice
def get_new_meta_search_by(old_search_by): """ Ask the user to enter a new title to search the metadata with. This function will be called when the user explicitly asks for a different title to search the metadata with. """ prepend.PREPEND(1) new_search_by = Prompt.ask("Enter new title to search metadata with", default=old_search_by) if new_search_by == old_search_by: logger.info("You can disable this behaviour by removing the" "`--ask-meta-name` flag.") return new_search_by
def dwCover(song): """Download the song cover img from itunes.""" # Try to download the cover art as cover.jpg in temp logger.info("Preparing the album cover") try: imgURL = song.artwork_url_100 # Check if the passed imgURL is a local file # this is possible if the metadata was entered manually. imgURL = os.path.expanduser(imgURL) if os.path.exists(imgURL): # Probably a file, read it in binary and extract the data # then return. content = open(imgURL, "rb").read() with open(defaults.DEFAULT.COVER_IMG, 'wb') as f: f.write(content) return True # Else might be an URL try: # Try to get 512 cover art imgURL = imgURL.replace('100x100', '2048x2048') except Exception: pass r = requests.get(imgURL) with open(defaults.DEFAULT.COVER_IMG, 'wb') as f: f.write(r.content) return True except TimeoutError: prepend.PREPEND(2) print('Could not get album cover. Are you connected to internet?\a') return False except Exception as e: logger.warning( "Error while trying to download image, skipping!: {}".format(e)) return False else: return False
def dwCover(SONG_INFO, index): """Download the song cover img from itunes.""" # Try to download the cover art as cover.jpg in temp try: imgURL = SONG_INFO[index].artwork_url_100 try: # Try to get 512 cover art imgURL = imgURL.replace('100x100', '2048x2048') except Exception: pass r = requests.get(imgURL) with open(defaults.DEFAULT.COVER_IMG, 'wb') as f: f.write(r.content) return True except TimeoutError: prepend.PREPEND(2) print('Could not get album cover. Are you connected to internet?\a') return False else: return False
def setData(SONG_INFO, is_quiet): """Add the metadata to the song.""" # A variable to see if cover image was added. IS_IMG_ADDED = False try: # If more than one choice then call getChoice if len(SONG_INFO) > 1 and not is_quiet: option = getChoice(SONG_INFO, 'metadata') else: option = 0 SONG_PATH = os.path.join(defaults.DEFAULT.SONG_TEMP_DIR, 'ytmdl_temp.mp3_new.mp3') audio = MP3(SONG_PATH, ID3=ID3) data = ID3(SONG_PATH) # Download the cover image, if failed, pass if dwCover(SONG_INFO, option): imagedata = open(defaults.DEFAULT.COVER_IMG, 'rb').read() data.add(APIC(3, 'image/jpeg', 3, 'Front cover', imagedata)) # REmove the image os.remove(defaults.DEFAULT.COVER_IMG) IS_IMG_ADDED = True # If tags are not present then add them try: audio.add_tags() except Exception: pass audio.save() option = int(option) data.add(TYER(encoding=3, text=SONG_INFO[option].release_date)) data.add(TIT2(encoding=3, text=SONG_INFO[option].track_name)) data.add(TPE1(encoding=3, text=SONG_INFO[option].artist_name)) data.add(TALB(encoding=3, text=SONG_INFO[option].collection_name)) data.add(TCON(encoding=3, text=SONG_INFO[option].primary_genre_name)) data.add(TRCK(encoding=3, text=str(SONG_INFO[option].track_number))) data.save() defaults.DEFAULT.SONG_NAME_TO_SAVE = SONG_INFO[ option].track_name + '.mp3' # Rename the downloaded file os.rename( SONG_PATH, os.path.join(defaults.DEFAULT.SONG_TEMP_DIR, defaults.DEFAULT.SONG_NAME_TO_SAVE)) # Show the written stuff in a better format prepend.PREPEND(1) print('================================') print(' || YEAR: ' + SONG_INFO[option].release_date) print(' || TITLE: ' + SONG_INFO[option].track_name) print(' || ARITST: ' + SONG_INFO[option].artist_name) print(' || ALBUM: ' + SONG_INFO[option].collection_name) print(' || GENRE: ' + SONG_INFO[option].primary_genre_name) print(' || TRACK NO: ' + str(SONG_INFO[option].track_number)) if IS_IMG_ADDED: print(' || ALBUM COVER ADDED') prepend.PREPEND(1) print('================================') return option except Exception: return False
def main(): """Run on program call.""" args = arguments() song_name = args.SONG_NAME # Check if --setup is passed if args.setup: setupConfig.make_config() exit(0) # After this part song name is required if song_name is None: prepend.PREPEND(2) print("Please pass a song name. This is necessary", "to search in itunes.") exit(1) if not args.nolocal: # Search for the song locally if not cache.main(song_name): exit(0) is_quiet = args.quiet url = args.url # If the url is passed then get the data if url is not None: data = [] # Get video data from youtube temp_data = yt.scan_video(yt.get_href(url)) data.append(temp_data) # link to dw the song link = url # In this case choice will be 0 choice = 0 else: if is_quiet: prepend.PREPEND(1) print('Quiet is enabled') prepend.PREPEND(1) print('Searching Youtube for ', end='') print(Fore.LIGHTYELLOW_EX, end='') print(song_name, end='') print(Style.RESET_ALL) data, urls = yt.search(song_name) if len(data) > 1 and not is_quiet: # Ask for a choice choice = song.getChoice(data, 'mp3') else: choice = 0 link = 'https://youtube.com{}'.format(urls[int(choice)]) # Declare a var to store the name of the yt video yt_title = data[choice]['title'] prepend.PREPEND(1) print('Downloading ', end='') print(Fore.LIGHTMAGENTA_EX, end='') print(yt_title, end=' ') print(Style.RESET_ALL, end='') print('in', end=' ') print(Fore.LIGHTYELLOW_EX, end='') print(defaults.DEFAULT.SONG_QUALITY + 'kbps', end='') print(Style.RESET_ALL) path = yt.dw(link, yt_title) if not path: prepend.PREPEND(2) print('Something went wrong while downloading!\a') sys.exit(0) else: prepend.PREPEND(1) print('Downloaded!') prepend.PREPEND(1) print('Converting to mp3...') conv_name = utility.convert_to_mp3(path) if not conv_name: prepend.PREPEND(2) print('Something went wrong while converting!\a') prepend.PREPEND(1) print('Getting song data...') # TRACK_INFO = song.getData(song_name) TRACK_INFO = metadata.SEARCH_SONG(song_name) # declare a variable to store the option option = 0 if TRACK_INFO is False: # prepend.PREPEND(2) # print('Data \a') # exit(0) pass elif len(TRACK_INFO) == 0: prepend.PREPEND(2) print('No data was found!\a') sys.exit(0) else: prepend.PREPEND(1) print('Setting data...') option = song.setData(TRACK_INFO, is_quiet, conv_name) if type(option) is not int: prepend.PREPEND(2) print('Something went wrong while writing data!\a') sys.exit(0) # Get the directory where song is moved DIR = dir.cleanup(TRACK_INFO, option) prepend.PREPEND(1) print('Moving to {}...'.format(DIR)) if not DIR: prepend.PREPEND(2) print('Something went wrong while moving!\a') sys.exit(0) else: prepend.PREPEND(1) print('Done')