def scrape_yt(soup) -> BaseProviderInput: """Scrapper function for YouTube videos""" # Check if video page has a "Music in this video" section if len(soup.find_all("li", class_="watch-meta-item yt-uix-expander-body")) > 1: output = scrape_embedded_yt_metadata(soup) if output.song_name is not None and output.artist_name is not None: return output raw_title = soup.find("meta", { "property": "og:title" }).get("content").strip() artist, title = None, None # In case the YouTube Title is in the commonly used format <Artist> - <Song name> if "-" in raw_title: raw_title = get_artist_title(raw_title) artist, title = raw_title.split(" - ") # In case the YouTube Title only contains song name else: title = get_artist_title(raw_title) try: artist = soup.find( "a", class_="yt-uix-sessionlink spf-link" ).text # Scrapes "Artist" from the YouTube Channel name artist = clean_channel(artist) except AttributeError: artist = None return DictInput(title, artist)
def test_func(self): if skip: self.skipTest("Currently unsupported") if "options" in test_params: artist, title = get_artist_title( input, options=test_params["options"]) else: artist, title = get_artist_title(input) self.assertEqual(title, expected[1]) self.assertEqual(artist, expected[0])
def searchForVideo(searchstr): # print("Search for:", searchstr) try: youtube = googleapiclient.discovery.build( youtube_api_service_name, youtube_api_version, developerKey=youtube_DEVELOPER_KEY) request = youtube.search().list( order="viewCount", q=searchstr, part="id,snippet", ) response = request.execute() # pprint(response['items'][0]) youtube_link = "https://youtu.be/" + response['items'][0]['id'][ 'videoId'] youtube_title = html.unescape(response['items'][0]['snippet']['title']) youtube_title = youtube_title.split("feat.")[0].split("ft.")[0] # print("Youtube title:", youtube_title) artist, title = get_artist_title(youtube_title) return { 'link': { "youtube": youtube_link }, 'title': title, 'artist': artist } except: return
def scrape_yt(self) -> Tuple[BaseProviderInput, dict]: """Scraper function for YouTube videos""" if not self.api_data: return None, None # Check if video page has a "Music in this video" section # This section is not provided by the YouTube API directly and needs to be scraped if ( len(self.soup.find_all("li", class_="watch-meta-item yt-uix-expander-body")) > 1 ): output, extras = self.scrape_embedded_yt_metadata() if output.song_name is not None and output.artist_name is not None: return output, extras raw_title = self.api_data["snippet"]["title"] artist, title = get_artist_title(raw_title) or (None, None) # If artist/title is found to be None, use video title as title and channel name as artist if artist is None or title is None: title = raw_title try: artist = self.api_data["snippet"][ "channelTitle" ] # Scrapes "Artist" from the YouTube Channel name artist = clean_channel(artist) except AttributeError: artist = None extra = self.get_extra_attrs() return DictInput(title, artist), extra
def get_metadata(song_link, spotify=False, musixmatch=False): metadata = {} if 'youtube.com' not in song_link and 'youtu.be' not in song_link: metadata['youtube'] = {} metadata['spotify'] = {} metadata['musixmatch'] = {} return metadata yt_data = get_youtube_metadata(song_link) clean_title = get_artist_title(yt_data['title']) metadata['youtube'] = yt_data if 'artist' not in yt_data: if spotify == True: sp_data = search_sp(clean_title) metadata['spotify'] = sp_data if musixmatch == True: mm_data = search_mm(clean_title) metadata['musixmatch'] = mm_data elif 'artist' in yt_data and 'song' not in yt_data: if spotify == True: sp_data = search_sp(yt_data['artist'] + " " + clean_title) metadata['spotify'] = sp_data if musixmatch == True: mm_data = search_mm(yt_data['artist'] + " " + clean_title) metadata['musixmatch'] = mm_data else: if spotify == True: sp_data = search_sp(yt_data['song'] + " - " + yt_data['artist']) metadata['spotify'] = sp_data if musixmatch == True: mm_data = search_mm(yt_data['song'] + " - " + yt_data['artist']) metadata['musixmatch'] = mm_data return metadata
def search_and_add(self, user_info, playlist): for song in user_info[1]: #Parse the song information then search if the song exists try: artist, title = get_artist_title(song) except TypeError: continue artist = artist.replace('& ', ',') title = self.remove_parenthesis(title) result = self.cfg.spotify.search(f'{title} {artist}') if result['tracks']['items']: print( f'{title} - {artist} found adding to playlist: {playlist["name"]}\n' ) #Grab the first item in the tracks track = result['tracks']['items'][0] self.cfg.spotify.playlist_add_items( playlist['id'], [f'spotify:track:{track["id"]}']) else: print( f'{title} - {artist} ***NOT FOUND***. Unable to add to playlist: {playlist["name"]}\n' )
def get_meta_info(url): OPTS = { 'format': 'bestaudio/best', 'forcefilename': True } # Try up to 3 times for _ in range(settings.YOUTUBE_MAX_RETRIES): try: with YoutubeDL(OPTS) as ydl: info = ydl.extract_info(url, download=False) filename = ydl.prepare_filename(info) parsed_artist = '' parsed_title = '' result = get_artist_title(info['title']) if result: parsed_artist, parsed_title = result metadata = { 'title': info['title'], 'uploader': info['uploader'], 'embedded_artist': info['artist'], 'embedded_title': info['track'], 'parsed_artist': parsed_artist, 'parsed_title': parsed_title, 'duration': info['duration'], 'url': info['webpage_url'], 'filename': filename } return metadata except DownloadError: pass raise Exception('get_meta_info failed')
def interpret_picard(picard_string): data = {} for match in re.finditer("(\\w+):\\(((?:[^\\\\)]|\\\\.)*)\\)", picard_string): key = match.group(1) value = unescape_picard(match.group(2)) if key == "track": value = re.sub("-([^\"&?\\/\\s]{11})$", "", value) try: try: artist, title = parse_simple(value) except: print("PARSE FAILED") traceback.print_exc() artist, title = get_artist_title(value) data["artist"] = artist data["name"] = title except: print("BOTH FAILED") traceback.print_exc() data["track"] = value elif key != "tnum": data[key] = value ret = "" for key, value in data.items(): if value is not None: ret += " {}:({})".format(key, escape_picard(value)) return ret[1:]
def get_artist_song(title): try: artist, song = get_artist_title(title) except TypeError as e: artist = None song = None return artist, song
def get_meta_info(url): """ Get metadata info from YouTube video. :param url: YouTube video URL """ opts = { 'format': 'bestaudio/best', 'forcefilename': True, 'noplaylist': True } # Try up to 3 times, as youtubedl tends to be flakey for _ in range(settings.YOUTUBE_MAX_RETRIES): try: with YoutubeDL(opts) as ydl: info = ydl.extract_info(url, download=False) filename = ydl.prepare_filename(info) parsed_artist = '' parsed_title = '' # Use youtube_title_parse library to attempt to parse the YouTube video title into # the track's artist and title. result = get_artist_title(info['title']) if result: parsed_artist, parsed_title = result metadata = { # YT video title 'title': info['title'], # YT video uploader 'uploader': info['uploader'], # YT video's embedded track artist (some official songs) 'embedded_artist': info['artist'] if 'artist' in info else '', # YT video's embedded track title (some official songs) 'embedded_title': info['track'] if 'track' in info else '', # Artist name parsed from the YouTube video title 'parsed_artist': parsed_artist, # Title parsed from the YouTube video title 'parsed_title': parsed_title, # Duration of YouTube video in seconds 'duration': info['duration'], # YouTube video URL 'url': info['webpage_url'], # Filename (including extension) 'filename': filename } return metadata except KeyError: pass except DownloadError: # Allow for retry pass raise DownloadError('Unable to parse YouTube link')
def get_metadata(graph_object): """ Get song metadata from music APIs """ if 'name' in graph_object: song_info = get_artist_title(graph_object['name']) spotify_response = search_sp(song_info) musixmatch_response = search_mm(song_info) response = { "spotify": spotify_response, "musixmatch": musixmatch_response } return response
def get_ytplaylist(self): os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" api_service_name = "youtube" api_version = "v3" client_secrets_file = "client_secret.json" # Get credentials and create an API client flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file( client_secrets_file, scopes) credentials = flow.run_console() youtube = googleapiclient.discovery.build(api_service_name, api_version, credentials=credentials) request = youtube.playlistItems().list( part="snippet,contentDetails", maxResults=25, playlistId="PLQ_99qrIfCg3Mm7SDtxHfIBMt7aUkIDZD") response = request.execute() for item in response["items"]: video_title = item["snippet"]["title"] youtube_url = "https://www.youtube.com/watch?v={}".format( item["id"]) print("\n\n\n") #print(video_title) #print(youtube_url) # use youtube_dl to collect the song name & artist name #video = youtube_dl.YoutubeDL({}).extract_info( #'https://www.youtube.com/watch?v=dPhwbZBvW2o', download=False) artist, title = get_artist_title(video_title) #print(artist) #print(title) if title is not None and artist is not None: # save all important info and skip any missing song and artist self.all_song_info[video_title] = { "youtube_url": youtube_url, "song_name": title, "artist": artist, # add the uri, easy to get song to put into playlist "spotify_uri": self.search_song(title, artist) } #print(response) print("\n\n\n")
def get_songs_info(self, song_titles): for song_title in song_titles: val = get_artist_title(song_title) if val: artist, title = val if '&' in artist: artist = artist.split('&')[0] if '(' in title: title = title.split('(')[0] self.songs_info[title] = artist else: print(f"{song_title} cannot be parsed!") return self.songs_info
def scrape_yt(soup): raw_title = soup.find('meta', { 'property': 'og:title' }).get('content').strip() artist, title = None, None #In case the YouTube Title is in the commonly used format <Artist> - <Song name> if '-' in raw_title: raw_title = get_artist_title(raw_title) artist, title = raw_title.split(' - ') # In case the YouTube Title only contains song name else: title = get_artist_title(raw_title) try: artist = soup.find( 'a', class_="yt-uix-sessionlink spf-link" ).text #Scrapes "Artist" from the YouTube Channel name artist = clean_channel(artist) except AttributeError: artist = None return YouTubeInfo(title, artist)
def get_youtube_playlist(): api_key = os.environ['YOUTUBE_API_KEY'] youtube = build('youtube', 'v3', developerKey=api_key) request = youtube.playlists().list( part='snippet', channelId=os.environ['YOUTUBE_CHANNEL_ID'] ) response = request.execute() playlist = {} for item in response['items']: playlist[item['snippet']['title']] = item['id'] print(item['snippet']['title']) playlist_name = input('Which playlist would you like to import? (type name exactly): ') playlist_id = playlist[playlist_name] request = youtube.playlistItems().list( part='snippet', playlistId=playlist_id, maxResults=100 ) response = request.execute() songs = {} for item in response['items']: video_title = item['snippet']['title'] video_id = item['snippet']['resourceId']['videoId'] request = youtube.videos().list( part='snippet', id=video_id ) response = request.execute() channel_id = response['items'][0]['snippet']['channelId'] request = youtube.channels().list( part='snippet', id=channel_id ) response = request.execute() channel_name = response['items'][0]['snippet']['title'] video_title = video_title.replace('(Official Audio)', '') if '|' in video_title: video_title = video_title[:video_title.index('|')] channel_name = channel_name.replace('- Topic', '').replace(',', '') songs[(video_title, channel_name)] = get_artist_title(video_title) songs = fix_artist_and_song_prediction(songs) print_spreadsheet(songs) return songs.values()
def __fetch_songs(self, youtube, playlist_id, page_token=None): result = youtube.playlistItems().list(part="snippet", playlistId=playlist_id, maxResults="300", pageToken=page_token).execute() for item in result['items']: song = item['snippet']['title'] try: artist, title = get_artist_title(song) self.songs.append(clean_song_info(Song(artist, title))) except: print(f'Error parsing {song}') return result
def get_song_credentials(titles): # Parses titles into artist, track categories # Deprecrated tracks, artists, failed = [], [], [] for title in titles: try: artist, track = get_artist_title(title) artist, track = artist.split("(")[0], track.split("(")[0] if artist or track: artists.append(artist) tracks.append(track) else: raise except: failed.append(title) return artists, tracks, failed
def download_videos_and_convert_to_mp3(vid_ids): """ Downloads an array of youtube video ids and converts to mp3 :param vid_ids: Array of youtube video ids """ count = 1 total = len(vid_ids) dest = cwd + config.TEMP_MP4_FOLDER create_dir_if_not_exist(dest) for video in vid_ids: print("Downloading video ({} / {}) ({}%)".format( count, total, round(count / total * 100, 2))) stream = download_video(video, dest) clean_file_name = youtube_title_parse.get_artist_title( stream.default_filename) + ".mp4" file_path = dest + "/" + stream.default_filename # Sometimes youtube will download with ext already attached clean_file_name = clean_file_name.replace(".mp4.mp4", ".mp4") mp3_path = cwd + config.DEFAULT_OUTPUT_FOLDER + "/" + clean_file_name.replace( ".mp4", ".mp3") # Fix for windows paths file_path = file_path.replace("\\", "/") mp3_path = mp3_path.replace("\\", "/") print("Converting file {} to mp3...".format(stream.default_filename)) convert_mp4_to_mp3(file_path, mp3_path) print("Cleaning up metadata...") add_metadata(mp3_path, clean_file_name.replace(".mp4", ".mp3"), video) print("") count += 1 # Clean up the folders (Get rid of temp files) print("Deleting temp folders...") shutil.rmtree(cwd + config.TEMP_THUMBNAIL_FOLDER) shutil.rmtree(cwd + config.TEMP_MP4_FOLDER)
async def lyrics(self, ctx, *author_song): author_song = ' '.join(author_song) if not self.song: return await ctx.reply('No song playing right now.') if not author_song: video = get_artist_title(self.song[0]) if not video: return await ctx.reply('Video is not a song') else: artist, title = video else: artist, title = author_song.split(" | ") song_lyrics = api.search_song(f'{artist} {title}') if song_lyrics: for line in song_lyrics.lyrics.split('\n'): if line: await ctx.send(line) else: await ctx.reply('Lyrics could not be found.')
async def lyrics_(self, ctx): vc = ctx.voice_client if not vc or not vc.is_connected(): embed = discord.Embed(title="", description="I'm not connected to a voice channel", color=discord.Color.green()) return await ctx.send(embed=embed) if not vc.is_playing(): embed = discord.Embed(title="", description="I am currently not playing anything", color=discord.Color.green()) return await ctx.send(embed=embed) artist = vc.source.artist track = vc.source.track artist = re.sub('[(].*[)]', '', artist) artist = re.sub('[[].*[]]', '', artist) track = re.sub('[(].*[)]', '', track) track = re.sub('[[].*[]]', '', track) title = f"{artist} - {track}" try: title = title.replace('$', 's') except: pass try: print(title) except: pass try: artist, creator = get_artist_title(title) lyric = genius.search_song(creator, artist) lyrics = lyric.lyrics pages = [lyrics[i:i+2000] for i in range(0, len(lyrics), 2000)] pager = Pag( title=f"Lyrics - {vc.source.title}", timeout=100, use_defaults=True, entries=pages, length=1 ) await pager.start(ctx) except: embed = discord.Embed(title="", description="lyrics not found", color=discord.Color.green()) await ctx.send(embed=embed)
def url_button_clicked(): try: USERDATA_.video_id = url_entry.get().split('=')[1] params = { "format": "json", "url": "https://www.youtube.com/watch?v=%s" % USERDATA_.video_id } url = "https://www.youtube.com/oembed" query_string = urllib.parse.urlencode(params) url = url + "?" + query_string with urllib.request.urlopen(url) as response: response_text = response.read() data = json.loads(response_text.decode()) artist, title = get_artist_title(data['title']) youtube_file_name_var.set(youtubeTitleFormatted( title)) #data['title'] is the whole title except: youtube_file_name_var.set('invalid url') file_name_label.configure(text=USERDATA_.text_filename) file_name_label.update()
async def update_music_menu(self, page=0, current_progress=''): if not self.music_menu: return player = self.wavelink_client.get_player(self.guild.id) if not page and not self.music_menu_page: page = 1 elif not page and self.music_menu_page: page = self.music_menu_page self.music_menu_page = page music_menu_str = '**Currently Playing:**\n' if not current_progress: current_progress = self.old_progress_bar if self.current_song: if not self.current_song.custom_title: result = get_artist_title(self.current_song.title) if result: title = f'{result[0]} - {result[1]}' else: title = self.current_song.title else: title = self.current_song.title song_type = self.current_song.type currently_playing_str = f'**{song_type}:** ' if song_type != 'Youtube' else '' currently_playing_str += f'[{title}]({self.current_song.uri})' if song_type != 'Twitch': formatted_duration = format_time.ms(self.current_song.duration, accuracy=3) currently_playing_str += f' | `{formatted_duration}`' user = self.bot.get_user(self.current_song.requester) if not user: try: user = await self.bot.fetch_user(self.current_song.requester) except: pass if user: name = user.display_name if len(user.display_name) <= 13 else f'{user.display_name[:13]}...' currently_playing_str += f' - *{name}*' if song_type != 'Twitch': if not current_progress: if self.progress_bar_task: self.progress_bar_task.cancel() self.progress_bar_task = asyncio.create_task(self.progress_bar(self.current_song.duration)) return else: currently_playing_str += f'\n{current_progress}' music_menu_str += f'{currently_playing_str}\n\n' else: music_menu_str += '\n' music_menu_str += '**Queue:**\n' queue_str = [] for i, song in enumerate(self.queue[10 * (page - 1):10 * page]): if not song.custom_title: result = get_artist_title(song.title) if result: title = f'{result[0]} - {result[1]}' else: title = song.title else: title = song.title value = f'`#{(i + 1) + 10 * (page - 1)}` - ' value += f'**{song.type}:** ' if song.type != 'Youtube' else '' value += f'[{title}]({song.uri})' if song.type != 'Twitch': formatted_duration = format_time.ms(song.duration, accuracy=3) value += f' | `{formatted_duration}`' user = self.bot.get_user(self.current_song.requester) if not user: try: user = await self.bot.fetch_user(self.current_song.requester) except: pass if user: name = user.display_name if len(user.display_name) <= 13 else f'{user.display_name[:13]}...' value += f' - *{name}*' queue_str.append(value) music_menu_str += '\n'.join(queue_str) if queue_str else '\u200b' total_duration = sum([s.duration for s in self.queue]) total_duration_formatted = format_time.ms(total_duration, accuracy=4) if self.current_song and self.current_song.type == 'Twitch': total_duration_formatted = '∞' music_menu_str += f'\n\nSongs in queue: **{len(self)}**\nPlaylist duration: **{total_duration_formatted}**\nLoop: **{self.loop}**' page_count = math.ceil(len(self) / 10) if page_count == 0: page_count = 1 author_name = 'Playlist' + (' - Paused' if player.is_paused or not player.is_connected else '') new_embed = self.music_menu.embeds[0] new_embed.set_author(name=author_name, icon_url=self.guild.icon_url) new_embed.description = music_menu_str new_embed.set_footer(text=f'Page {page}/{page_count}') await self.music_menu.edit(embed=new_embed) return True
def download_song(self, url, albart, sponame, z): """ Download the song by passing the video URL as a parameter """ try: v = pafy.new(url) except Exception as e: print( f"\nSome error occurred while fetching the details of the song : {e}\n" ) return name = v.title audio = v.getbestaudio() check_track_name = '' # ---------- GET THE PROCESSED TRACK NAME FOR CHECKING IF IT ALREADY EXISTS IN THE DIRECTORY ---------- try: if self.spo: artist, title = get_artist_title(sponame) else: artist, title = get_artist_title(name) for i in os.listdir(): if sys.platform == 'win32' or os.name == 'nt': check_track_name = title + " - " + artist check_track_name = check_track_name.replace( "\\", "_").replace("/", "_").replace(":", "_").replace( "*", "_").replace("?", "_").replace("\"", "_").replace( "<", "_").replace(">", "_").replace("|", "_") elif sys.platform == 'linux' or os.name == 'posix': check_track_name = title + " - " + artist check_track_name = check_track_name.replace( "\\", " ").replace("/", " ").replace(":", " ").replace( "*", " ").replace("?", " ").replace("\"", " ").replace( "<", " ").replace(">", " ").replace("|", " ") except TypeError: for i in os.listdir(): if name in i: check_track_name = name[:len(i) - 1 - i[::-1].index('.')] if "_" in check_track_name: check_track_name = check_track_name.replace("_", " ") # ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- # CHECK IF THE TRACK EXISTS OR NOT if any(check_track_name in i for i in os.listdir()): exist_track = [ string for string in os.listdir() if check_track_name in string ][0] if ".part" not in exist_track: Console().print( f"\n[bold cyan]{name} track already exists. Skipping the track[/bold cyan]" ) time.sleep(1) return elif ".part" in exist_track: Console().print( f"\n[bold green]{name} track is partly downloaded.[/bold green]" ) # ---------- ---------- END OF CHECKING ---------- ---------- Console().print(f"\n[bold green]Downloading {name}[/bold green]") audio.download() dirs = os.listdir() # ---------- ---------- CONVERT THE DOWNLOADED TRACKS TO MP3 OR FLAC ---------- ---------- try: if self.spo: artist, title = get_artist_title(sponame) else: artist, title = get_artist_title(name) for i in dirs: if sys.platform == 'win32' or os.name == 'nt': if name.replace("\\", "_").replace("/", "_").replace( ":", "_").replace("*", "_").replace("?", "_").replace( "\"", "_").replace("<", "_").replace( ">", "_").replace("|", "_") in i: if z == "1" or z == "flac" or z == "f": track_name = title + " - " + artist + ".flac" track_name = track_name.replace("\\", "_").replace( "/", "_").replace(":", "_").replace( "*", "_").replace("?", "_").replace( "\"", "_").replace("<", "_").replace( ">", "_").replace("|", "_") print(f"Converting the audio format to flac") self.convert(i, track_name, albart, art=title, artist=artist, flac=True) else: track_name = title + " - " + artist + ".mp3" track_name = track_name.replace("\\", "_").replace( "/", "_").replace(":", "_").replace( "*", "_").replace("?", "_").replace( "\"", "_").replace("<", "_").replace( ">", "_").replace("|", "_") print(f"Converting the audio format to mp3") self.convert(i, track_name, albart, art=title, artist=artist) elif sys.platform == 'linux' or os.name == 'posix': if name in i: if z == "1" or z == "flac" or z == "f": track_name = title + " - " + artist + ".flac" track_name = track_name.replace("\\", " ").replace( "/", " ").replace(":", " ").replace( "*", " ").replace("?", " ").replace( "\"", " ").replace("<", " ").replace( ">", " ").replace("|", " ") print(f"Converting the audio format to flac") self.convert(i, track_name, albart, art=title, artist=artist, flac=True) else: track_name = title + " - " + artist + ".mp3" track_name = track_name.replace("\\", " ").replace( "/", " ").replace(":", " ").replace( "*", " ").replace("?", " ").replace( "\"", " ").replace("<", " ").replace( ">", " ").replace("|", " ") print(f"Converting the audio format to mp3") self.convert(i, track_name, albart, art=title, artist=artist) for i in os.listdir(): if "_" in i: try: os.rename(i, i.replace("_", " ")) except FileExistsError: try: os.rename(i, i.replace("_", " ")) except FileExistsError: pass except TypeError: for i in dirs: if name in i: ind1 = len(i) - 1 - i[::-1].index('.') ext = i[ind1:] if ext in i: if z == "1" or z == "flac" or z == "f": track_name = name[:ind1] + ".flac" print(f"Converting the audio format to flac") self.convert(i, track_name, albart, art='', artist='', flac=True) else: track_name = name[:ind1] + ".mp3" print(f"Converting the audio format to mp3") self.convert(i, track_name, albart, art='', artist='') for i in os.listdir(): if "_" in i: os.rename(i, i.replace("_", " "))
def get_artist_track(song_title): clean_title = magic_parser.clean_songname(song_title) return get_artist_title(clean_title)
def download_singles(self): """ Downloads songs based on youtube search. Takes a string as an input. """ cm = common() try: os.chdir("singles") except: os.mkdir("singles") os.chdir("singles") Console().print( Columns([ Panel( "\ntip:\n [bold white]* give the name of song and the artist for better search results)\n * you could paste the youtube video url itself if you're looking for a specific song.[/bold white]\n" ) ])) s = input("\nEnter the song name: ") print(f"\nLoading search results for {s}...\n") s = s.replace(" ", "+") # Get top 7 video URLs video_url = cm.get_url(s) j = 1 names = [] for i in video_url: if len(video_url) == 0: print( "\nThere were no results :(\nmaybe try checking the spelling of the song\n" ) quit() try: t = pafy.new(i) names.append(f"{j} - {t.title} ({t.duration})") j += 1 except: j += 1 # print(traceback.format_exc()) # time.sleep(2) continue picker = Picker( names, "Select your choice using arrow keys or press q to quit", indicator=" => ") picker.register_custom_handler(ord('q'), lambda picker: exit()) picker.register_custom_handler(ord('Q'), lambda picker: exit()) op, c = picker.start() Console().print( Columns([ Panel( f"\nDownload size: [green]{int((pafy.new(video_url[c]).getbestaudio().get_filesize()/1048576)*100)/100} MB[/green]\n" ) ])) print() print("\nWould you like an mp3 or flac conversion?\n") Console().rule( "[bold]**** Here's a quick comparison on both codec ****[bold]", style="black", align="center") print("\n") table = Table(show_header=True, header_style="bold cyan") table.add_column("Avaliable Codec") table.add_column("Bit-rate") table.add_column("File Size") table.add_column("Remarks") table.add_row("mp3", "320kbps (default)", "~7.3MB for 3min song", "Standard codec with normal experience") table.add_row() table.add_row( "flac", "usually >800kbps (1713kbps while testing, 5x of mp3)", "~39MB for 3min song", "Takes fair amount of disk space but gives amazing experience") Console().print(table) Console().rule( "\n[bold]Note: this step [red]does not use internet[/red] [bold]\n", style="black", align="center") print('\nIf you are confused on what to select, select mp3 (default)') z = input("\tEnter\n\t1/flac/f - flac\n\tany key - mp3 : ") cm.download_song(video_url[c], '', '', z) print("\n\n") Console().print( Columns([ Panel( f"\n Your song is downloaded in \"[bold cyan]/musicDL downloads/singles[/bold cyan]\" folder on desktop \n" ) ])) print("\n\n") time.sleep(3) picker = Picker( ["Open the song directory", "Open the song itself"], "Select your choice using arrow keys or press q to quit", indicator=" => ") picker.register_custom_handler(ord('q'), lambda picker: 'qq') picker.register_custom_handler(ord('Q'), lambda picker: 'QQ') _, op = picker.start() if op == 0: if sys.platform == 'win32' or os.name == 'nt': os.startfile(".") elif sys.platform == 'linux' or os.name == 'posix': subprocess.call(['xdg-open', '.']) elif op == 1: file = pafy.new(video_url[c - 1]).title a, t = get_artist_title(file) if file + ".mp3" in os.listdir(): if sys.platform == 'win32' or os.name == 'nt': os.startfile(file + ".mp3") elif sys.platform == 'linux' or os.name == 'posix': subprocess.call(['xdg-open', file + ".mp3"]) elif t + " - " + a + ".mp3" in os.listdir(): if sys.platform == 'win32' or os.name == 'nt': os.startfile(t + " - " + a + ".mp3") elif sys.platform == 'linux' or os.name == 'posix': subprocess.call(['xdg-open', t + " - " + a + ".mp3"]) else: files = glob.glob("./*") song = max(files, key=os.path.getctime) if sys.platform == 'win32' or os.name == 'nt': os.startfile(song) elif sys.platform == 'linux' or os.name == 'posix': subprocess.call(['xdg-open', song]) else: return
def doit(item): if item == "": return "", ["", ""] # item = input('Enter the song to find its lyricsxx: ') res = None maxTries = 4 mc = 0 lyricsText, song_info = "sorry, lyrics not found, try again soon ", [ "Could not find lyrics", item ] while res is None and mc <= maxTries: # try: target = item print("ITEM:" + target) artist_title = get_artist_title(target) if artist_title is not None: print("@@@@@@@@@@@@@@@@@@@@", artist_title) artist, title = artist_title if mc == 1: target = title + " " + artist item = item.replace("&", " and ") if mc == 2: target = title + " " + artist.split(" ")[0] if mc == 3: target = title else: print("!!!!!!!!!!!!!!!!!!!!!!!!") print("!!!!!!!!!!!!!!!!!!!!!!!!") print("!!!!!!!!!!!!!!!!!!!!!!!!") print("TTTTTTTTTTTTTTTTT") print(target) print("TTTTTTTTTTTTTTTTT") # except: # print("E: could not parse artist and title") res = getLyrics(target) mc += 1 if res is not None and len(res) > 1: lyricsText, song_info = res chars = [["-", " "], ["(", ""], [")", ""]] for c in chars: lyricsText = lyricsText.replace(c[0], c[1]) # .replace().replace("(","").replace(")","") lyrics = [] for l in lyricsText.split("\n"): lyrics.append(l) body = [{'text': lyricsText}] translated = [] debug = False bing = False if bing: request = requests.post(constructed_url, headers=headers, json=body) response = request.json() fullL = [] i = 0 print() print("!!!!!!!!!", response) print() if type(response) == type({}) and "error" in response.keys(): if response["error"]["code"] != "0": print("EEEEEE") print("EEEEEE") print("EEEEEE") song_info.append("" + str(response)) else: print(c) for r in response[0]['translations'][0]['text'][::-1].split( "\n")[::-1]: print("@@@@@@@", r) # fullL = [lyrics[i]+"\n"+r[::-1]] translated.append(r) i += 1 else: n = 0 parts = [] print(lyricsText) print(type(lyricsText), len(lyricsText), len(lyricsText.split("\n"))) maxChunks = 50 for chunk in chunks(lyricsText.split("\n"), maxChunks): match = False joiner = " øxø" joiner = " █" joiner = " ø" finalJoiner = "" joiners = [" øxø", " AAAAA", " øø", " █"] joiners = [" øøø ", " øxø"] joiners = [" 123\n ", " øxø\n"] # joiners = [" 123\n "] res = "" for joiner in joiners: if not match: finalJoiner = joiner # joiner = " █ øxø" # joinerN = joiner+"\n" joinerN = joiner chunkT = joinerN.join(chunk) print("!!!!!!!!!!!!", "\n", chunkT) #XXX # res = translator.translate(str(chunkT),lang_tgt="he").replace("Ø","ø").replace(joinerN,joiner.strip()) res = translator.translate( str(chunkT), lang_tgt="he").replace( "Ø", "ø") #.replace(joinerN,joiner.strip()) if chunkT.count(joiner.strip().strip("\n")) == res.count( joiner.strip().strip("\n")): match = True if debug: res += f"--- " + str( chunkT.count(joiner.strip().strip( "\n"))) + " ======== " + str( res.count(joiner.strip().strip("\n"))) else: print(f"--- " + str(chunkT.count(joiner.strip().strip("\n"))) + " != " + str(res.count(joiner.strip().strip("\n")))) if debug: res += f"--- " + str( chunkT.count(joiner.strip().strip( "\n"))) + " != " + str( res.count(joiner.strip().strip("\n"))) if len(res.split("\n")) > 1: res = res.replace(finalJoiner.strip(), "") else: if debug: res = res.replace(finalJoiner.strip(), "@@\n") else: res = res.replace(finalJoiner.strip(), "\n") if debug: res += f"~~~ line count" + str(len(res.split("\n"))) print("$$$$$$$$$$$$$$$$$$$$$") print(res) parts.append(res.replace("OXO", "").replace("oxo", "")) # time.sleep(1) # n+=1 # res = translator.translate(lyricsText,lang_tgt="he") print("########################@@@") print(parts) # translated = res.__dict__()["text"] translated = ("\n".join(parts)).split("\n") print("############################") print(translated) print("XXXXXXXXXXXXXXXXXXXXXXXXXXX") # replacements = {" ":"%20", ";":"%3B", "\n":"%0A", ",":"%2C","\'":"%27"} # base = "https://translate.google.com/?sl=auto&tl=iw&text=" # ending = "&op=translate" # # print(lyricsText) # # input() # url = base + changes(lyricsText, replacements) + ending # # print(url) # # page = requests.get(url) # soup = BeautifulSoup(page.content, 'html.parser') # # spans = soup.find_all("span") # # # # for pp in P: # # lyrics.append(pp.text.replace("\n","").replace(" ","").replace(" ","")) # # for s in spans: # print(":::: ",s.text) # translated.append(s.text) # response = request.json() # https://translate.google.com/?sl=auto&tl=iw&text=She%27s%20got%20a%20smile%20that%20it%20seems%20to%20me%0AReminds%20me%20of%20childhood%20memories%0AWhere%20everything%20was%20as%20fresh%20as%20the%20bright%20blue%20sky%0ANow%20and%20then%20when%20I%20see%20her%20face%0AShe%20takes%20me%20away%20to%20that%20special%20place%0AAnd%20if%20I%20stare%20too%20long%2C%20I%27d%20probably%20break%20down%20and%20cry%0AWhoa%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AWhoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20love%20of%20mine%0AShe%27s%20got%20eyes%20of%20the%20bluest%20skies%0AAs%20if%20they%20thought%20of%20rain%0AI%27d%20hate%20to%20look%20into%20those%20eyes%20and%20see%20an%20ounce%20of%20pain%0AHer%20hair%20reminds%20me%20of%20a%20warm%20safe%20place%0AWhere%20as%20a%20child%20I%27d%20hide%0AAnd%20pray%20for%20the%20thunder%20and%20the%20rain%20to%20quietly%20pass%20me%20by%0AWhoa%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AWhoa%20whoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20love%20of%20mine%0AWhoa%2C%20yeah%0AWhoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AWhoa%2C%20oh%2C%20whoa%2C%20oh%0ASweet%20love%20of%20mine%0AWhoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AOoh%2C%20yeah%E2%80%A6&op=translate # # https://translate.google.com/?sl=auto&tl=iw&text=She%27s%20got%20a%20smile%20that%20it%20seems%20to%20me%3B%20Reminds%20me%20of%20childhood%20memories%0Where%20everything%20was%20as%20fresh%20as%20the%20bright%20blue%20sky%3B%20Now%20and%20then%20when%20I%20see%20her%20face%0She%20takes%20me%20away%20to%20that%20special%20place%3B%20And%20if%20I%20stare%20too%20long%2C%20I%27d%20probably%20break%20down%20and%20cry%0Whoa%2C%20oh%2C%20oh%3B%20Sweet%20child%20o%27%20mine%0Whoa%2C%20oh%2C%20oh%2C%20oh%3B%20Sweet%20love%20of%20mine%0She%27s%20got%20eyes%20of%20the%20bluest%20skies%3B%20As%20if%20they%20thought%20of%20rain%0I%27d%20hate%20to%20look%20into%20those%20eyes%20and%20see%20an%20ounce%20of%20pain%3B%20Her%20hair%20reminds%20me%20of%20a%20warm%20safe%20place%0Where%20as%20a%20child%20I%27d%20hide%3B%20And%20pray%20for%20the%20thunder%20and%20the%20rain%20to%20quietly%20pass%20me%20by%0Whoa%2C%20oh%2C%20oh%3B%20Sweet%20child%20o%27%20mine%0Whoa%20whoa%2C%20oh%2C%20oh%2C%20oh%3B%20Sweet%20love%20of%20mine%0Whoa%2C%20yeah%3B%20Whoa%2C%20oh%2C%20oh%2C%20oh%0Sweet%20child%20o%27%20mine%3B%20Whoa%2C%20oh%2C%20whoa%2C%20oh%0Sweet%20love%20of%20mine%3B%20Whoa%2C%20oh%2C%20oh%2C%20oh%0Sweet%20child%20o%27%20mine%3B%20Ooh%2C%20yeah%0Whoa%2C%20yeah%3B%20Whoa%2C%20oh%2C%20oh%2C%20oh%0Sweet%20child%20o%27%20mine%3B%20Whoa%2C%20oh%2C%20whoa%2C%20oh%0Sweet%20love%20of%20mine%3B%20Whoa%2C%20oh%2C%20oh%2C%20oh%0Sweet%20child%20o%27%20mine%3B%20Ooh%2C%20yeah%0Ooh%2C%20sweet%20love%20of%20mine%3B%20Where%20do%20we%20go?%0Where%20do%20we%20go%20now?%3B%20Where%20do%20we%20go?%0Ooh%2C%20oh%2C%20where%20do%20we%20go?%3B%20Where%20do%20we%20go%20now?%0Oh%2C%20where%20do%20we%20go%20now?%3B%20Where%20do%20we%20go?%20Sweet%20child%0Where%20do%20we%20go%20now?%3B%20Ay%2C%20ay%2C%20ay%2C%20ay%2C%20ay%2C%20ay%2C%20ay%2C%20ay%0Where%20do%20we%20go%20now?%3B%20Ah%2C%20ah%0Where%20do%20we%20go?%3B%20Oh%2C%20where%20do%20we%20go%20now?%0Oh%2C%20where%20do%20we%20go?%3B%20Oh%2C%20where%20do%20we%20go%20now?%0Where%20do%20we%20go?%3B%20Oh%2C%20where%20do%20we%20go%20now?%0Now%2C%20now%2C%20now%2C%20now%2C%20now%2C%20now%2C%20now%3B%20Sweet%20child%0Sweet%20child%20of%20mine%3B%20&op=translate # print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") # print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") # print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") # print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") # print(response) # # She%27s%20got%20a%20smile%20that%20it%20seems%20to%20me%3B%20Reminds%20me%20of%20childhood%20memories%0AWhere%20everything%20was%20as%20fresh%20as%20the%20bright%20blue%20sky%0ANow%20and%20then%20when%20I%20see%20her%20face%0AShe%20takes%20me%20away%20to%20that%20special%20place%0AAnd%20if%20I%20stare%20too%20long%2C%20I%27d%20probably%20break%20down%20and%20cry%0AWhoa%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AWhoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20love%20of%20mine%0AShe%27s%20got%20eyes%20of%20the%20bluest%20skies%0AAs%20if%20they%20thought%20of%20rain%0AI%27d%20hate%20to%20look%20into%20those%20eyes%20and%20see%20an%20ounce%20of%20pain%0AHer%20hair%20reminds%20me%20of%20a%20warm%20safe%20place%0AWhere%20as%20a%20child%20I%27d%20hide%0AAnd%20pray%20for%20the%20thunder%20and%20the%20rain%20to%20quietly%20pass%20me%20by%0AWhoa%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AWhoa%20whoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20love%20of%20mine%0AWhoa%2C%20yeah%0AWhoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AWhoa%2C%20oh%2C%20whoa%2C%20oh%0ASweet%20love%20of%20mine%0AWhoa%2C%20oh%2C%20oh%2C%20oh%0ASweet%20child%20o%27%20mine%0AOoh%2C%20yeah%E2%80%A6 # return fullL # return f'Todo : {item}' # return translated # print("!!!!!") # return fullL = [] # fullt = "<h1>"+item+"</h1>" while lyrics[0] is "": lyrics = lyrics[1:] while translated[0] is "" or translated[0].strip() == ".": translated = translated[1:] # finalLyrics = [] # finalTranslated = [] # for l in lyrics: # if l.strip() != ".": # finalLyrics.append(l) # for l in translated: # if l.strip() != ".": # finalTranslated.append(l) # lyrics = finalLyrics # translated = finalTranslated toff = 0 for c in range(len(lyrics)): # fullL.append(lyrics[c]+"@") # fullL.append(lyrics[c]) addL = lyrics[c] if addL.strip() == ".": addL = " " if debug: fullL.append("E: " + addL + "@@") else: fullL.append(addL) if c + toff < len(translated): addT = translated[c + toff] if addT.strip() == ".": addT = " " # fullL.append(translated[c]) if addT.strip() == ".": fullL.append(f"-1 {c} {toff}, {addT}") toff += 1 # addT = translated[c+toff] # if addT.strip() == ".": # addT = " " if debug: fullL.append("T: " + addT) else: fullL.append(addT) fullL.append("") fullL.append("") # fullt += "<pre>"+lyrics[c] + "</pre>" # fullt += "<pre>"+translated[c][::-1] + "</pre>" # print(lyrics[c]) # print(translated[c]) print("") print(" @ @ @ @ @ @ @") print(fullL) return fullL, song_info, item.replace(" ", "⠀")
def doit(item): if item == "": return "", ["", ""] # item = input('Enter the song to find its lyricsxx: ') res = None maxTries = 4 mc = 0 lyricsText, song_info = "sorry, lyrics not found, try again soon ", [ "Could not find lyrics", item ] while res is None and mc <= maxTries: # try: target = item print("ITEM:" + target) artist_title = get_artist_title(target) if artist_title is not None: print("@@@@@@@@@@@@@@@@@@@@", artist_title) artist, title = artist_title if mc == 1: target = title + " " + artist item = item.replace("&", " and ") if mc == 2: target = title + " " + artist.split(" ")[0] if mc == 3: target = title else: print("!!!!!!!!!!!!!!!!!!!!!!!!") print("!!!!!!!!!!!!!!!!!!!!!!!!") print("!!!!!!!!!!!!!!!!!!!!!!!!") print("TTTTTTTTTTTTTTTTT") print(target) print("TTTTTTTTTTTTTTTTT") # except: # print("E: could not parse artist and title") res = getLyrics(target) mc += 1 if res is not None and len(res) > 1: lyricsText, song_info = res chars = [["-", " "], ["(", ""], [")", ""]] for c in chars: lyricsText = lyricsText.replace(c[0], c[1]) # .replace().replace("(","").replace(")","") lyrics = [] for l in lyricsText.split("\n"): lyrics.append(l) body = [{'text': lyricsText}] translated = [] n = 0 parts = [] print(lyricsText) print(type(lyricsText), len(lyricsText), len(lyricsText.split("\n"))) maxChunks = 50 for chunk in chunks(lyricsText.split("\n"), maxChunks): chunkT = "\n".join(chunk) print("!!!!!!!!!!!!", "\n", chunkT) res = translator.translate(str(chunkT), lang_tgt="he") print("$$$$$$$$$$$$$$$$$$$$$") print(res) parts.append(res + "\n") # time.sleep(1) # n+=1 # res = translator.translate(lyricsText,lang_tgt="he") print("########################@@@") print(parts) # translated = res.__dict__()["text"] translated = ("".join(parts)).split("\n") print("############################") print(translated) print("XXXXXXXXXXXXXXXXXXXXXXXXXXX") fullL = [] # fullt = "<h1>"+item+"</h1>" for c in range(len(lyrics)): fullL.append(lyrics[c]) if c < len(translated): fullL.append(translated[c]) fullL.append("") fullL.append("") # fullt += "<pre>"+lyrics[c] + "</pre>" # fullt += "<pre>"+translated[c][::-1] + "</pre>" # print(lyrics[c]) # print(translated[c]) print("") print(" @ @ @ @ @ @ @") print(fullL) return fullL, song_info
def perform_search(query: str, page_token=None): """ Executes YouTube search request using YouTube Data API v3 and returns simplified list of video results. :param query: Query string :param page_token: Page token """ api_service_name = "youtube" api_version = "v3" if not settings.YOUTUBE_API_KEY: raise YouTubeSearchError( 'Missing YouTube Data API key. Please set the YOUTUBE_API_KEY env variable or update settings.py.' ) youtube = googleapiclient.discovery.build( api_service_name, api_version, developerKey=settings.YOUTUBE_API_KEY) # Execute search query search_request = youtube.search().list(part="snippet", maxResults=25, q=query, pageToken=page_token) search_result = search_request.execute() search_items = search_result['items'] # Construct list of eligible video IDs ids = [ item['id']['videoId'] for item in search_items if item['id']['kind'] == 'youtube#video' and item['snippet']['liveBroadcastContent'] == 'none' ] # Make request to videos() in order to retrieve the durations duration_request = youtube.videos().list(part='contentDetails', id=','.join(ids)) duration_result = duration_request.execute() duration_items = duration_result['items'] duration_dict = { item['id']: item['contentDetails']['duration'] for item in duration_items } # Merge results into single, simplified list videos = [] for item in search_items: if item['id']['kind'] == 'youtube#video' and item['snippet'][ 'liveBroadcastContent'] == 'none' and item['id'][ 'videoId'] in duration_dict: parsed_artist = None parsed_title = None result = get_artist_title(item['snippet']['title']) if result: parsed_artist, parsed_title = result else: parsed_artist = item['snippet']['channelTitle'] parsed_title = item['snippet']['title'] videos.append({ 'id': item['id']['videoId'], 'title': item['snippet']['title'], 'parsed_artist': parsed_artist, 'parsed_title': parsed_title, 'channel': item['snippet']['channelTitle'], 'thumbnail': item['snippet']['thumbnails']['default']['url'], 'duration': duration_dict[item['id']['videoId']] }) next_page_token = search_result[ 'nextPageToken'] if 'nextPageToken' in search_result else None # Return next page token and video result return next_page_token, videos