def search_lyrics(call): """Handle searching for a song's lyrics.""" data = call.data artist = data[ATTR_ARTIST_NAME] title = data[ATTR_SONG_TITLE] entity_id = data.get(CONF_ENTITY_ID) state = data.get("state") old_state = hass.states.get(entity_id) if old_state: attrs = old_state.attributes else: attrs = {} # get lyrics from lyricsgenius import Genius genius = Genius(genius_access_token) #_LOGGER.debug("Searching for lyrics with artist '{}' and title '{}'".format(artist, title)) song = genius.search_song(title, artist, get_full_info=False) if song is None: #_LOGGER.debug("Song not found.") attrs = { 'artist': artist.title(), # title case until we have a preformatted name 'title': title, 'lyrics': None } else: #_LOGGER.debug("Song data: \n{}".format(song.to_dict())) attrs = song.to_dict() attrs['artist'] = artist.title( ) # title case until we have a preformatted name if entity_id is not None: hass.states.set(entity_id, state, attrs)
class Lyrics: def __init__(self): self.genius = Genius(data["geniusAPI"]["token"]) def searchLyrics(self, name): try: song, artist = (name.strip()).split(',') except: song, artist = name.strip(), "" self.song = self.genius.search_song(song, artist) song_info = { "title": self.song.title, "artist": self.song.artist, "lyrics": self.song.lyrics, "thumbnail": self.song.song_art_image_thumbnail_url, "linecount": (self.song.lyrics).count('\n') } return song_info def serachSongByLyrics(self, lyr): request = self.genius.search_lyrics(lyr) ans = [] for hit in request['sections'][0]['hits']: ans.append((hit['result']['full_title']).split(' by')) return ans def saveLyrics(self, songName, songLyrics): with open(f'{songName }.txt', 'w') as f: f.write(songLyrics)
class GeniusProvider(LyricsProviderABC): NAME = 'genius.com' API_BASE_URL = 'https://api.genius.com/' LYRICS_BASE_URL = 'https://genius.com/' def __init__(self): super().__init__() self.api = GeniusAPI(constants.Genius.TOKEN, verbose=False) def _requests_lyrics(self, track: 'Track') -> Optional[str]: try: track_genius = self.api.search_song( f'{track.title.replace(" - Bonus Track", "")} by {track.artists[0]}' ) if track_genius is None: self.logger.info( f'GeniusProvider: Track not found: {track_genius}') return self.logger.debug( f'GeniusProvider: Found track: {track_genius.title}') return track_genius.lyrics except requests.exceptions.HTTPError as e: raise HTTPError(self.__class__, e) except requests.exceptions.RequestException as e: raise NetworkError(self.__class__, e)
def get_song_genius(track_name, artist_name): genius = Genius(GENIUS_TOKEN, verbose=False) song = genius.search_song(track_name, artist_name) if not song: return None song = json.loads(song.to_json()) if not valid_song(track_name, song['title'], artist_name, song['primary_artist']['name']): return None try: meaning = song['description']['plain'].split('\n') assert (meaning != ["?"] and meaning != [""]) except: meaning = None response = { 'lyrics': add_line_breaks(song['lyrics'].split('\n')), 'meaning': meaning, 'source': 'Genius', 'source_url': song['url'], } for item in song['media']: if item['provider'] == 'youtube': response['youtube_embed_url'] = 'https://www.youtube.com/embed/' + \ item['url'].split('=')[1] break return response
class OpenSongLyrics: def __init__(self): self.sclient_id = spotify_client_id self.sclient_secret = spotify_client_secret self.redirect_uri = 'http://localhost:8080' self.scope = 'user-read-playback-state' self.username = '******' self.client_credentials_manager = SpotifyOAuth( username=self.username, redirect_uri=self.redirect_uri, scope=self.scope, client_id=self.sclient_id, client_secret=self.sclient_secret, open_browser=False) self.genius_token = genius_token self.lyrics = None self.genius = Genius(client_access_token=self.genius_token, response_format='dom', verbose=True, skip_non_songs=True) def get_song_info(self): sp = spotipy.Spotify( client_credentials_manager=self.client_credentials_manager) playback_read = sp.current_playback() if playback_read is not None: get_title = playback_read['item']['name'] get_artists = playback_read['item']['artists'] artists = [] for artist in get_artists: name = artist['name'] artists.append(name) album = playback_read['item']['album']['name'] song_info = { 'title': get_title, 'artists': artists, 'album': album } print(song_info) else: song_info = {} return song_info def get_current_lyrics(self): song_info = self.get_song_info() print(song_info) song_title = clean_title(artists=song_info['artists'], song_title=song_info['title']) self.lyrics = self.genius.search_song( title=song_title, artist=song_info['artists'][0]).lyrics # artists = " ".join(song_info['artists']) # term = song_title + " " + artists # a = genius.search_all(term, per_page=5, page=1) # aa = genius._get_item_from_search_response(a, term, type_='song', result_type='song_title') # album = genius.search_lyrics() return self.lyrics
def lyrics(message): args = extract_args(message) if r"-" in args: pass else: edit(message, f'`{get_translation("lyricsError")}`') return if not GENIUS_TOKEN: edit(message, f'`{get_translation("geniusToken")}`') else: genius = Genius(GENIUS_TOKEN) try: args = args.split('-') artist = args[0].strip() song = args[1].strip() except BaseException: edit(message, f'`{get_translation("lyricsError2")}`') return if len(args) < 1: edit(message, f'`{get_translation("lyricsError2")}`') return edit(message, get_translation('lyricsSearch', ['`', artist, song])) try: songs = genius.search_song(song, artist) except TypeError: songs = None if not songs: edit(message, get_translation('lyricsNotFound', ['**', artist, song])) return if len(songs.lyrics) > 4096: edit(message, f'`{get_translation("lyricsOutput")}`') with open('lyrics.txt', 'w+') as f: f.write( get_translation('lyricsQuery', ['', '', artist, song, songs.lyrics])) reply_doc(message, 'lyrics.txt', delete_after_send=True) else: edit( message, get_translation('lyricsQuery', ['**', '`', artist, song, songs.lyrics]), ) return
class Genius(Provider): name = 'genius' synchronized = False def __init__(self, config_entry): remove_section_headers = config_entry.getboolean( 'remove_section_headers', False) self.genius = LyrGenius( config_entry['token'], verbose=False, remove_section_headers=remove_section_headers, ) def get_lyrics(self, artist: str, title: str, _: int) -> Lyrics: lyrics = Lyrics() song = self.genius.search_song(title, artist, get_full_info=False) if song: lyrics.unsynchronized = song.lyrics return lyrics
def get_lyrics(artist, song_title): """ Retrieves lyrics from Genius.com using a python """ artist = artist.lower() song_title = song_title.lower() genius = Genius(LYRICS_SECRET_KEY) # genius = lyricsgenius.Genius(LYRICS_SECRET_KEY) try: # import pdb; pdb.set_trace() song = genius.search_song(song_title, artist) # song = genius.song(song_title, artist) if (song): lyrics = song.lyrics.replace('\n', '<br>') return {'status': 'success', 'msg': 'ok', 'lyrics': lyrics} else: # No matching lyrics were found status = 'error' msg = NO_MATCHING_LYRICS lyrics = None return {'status': status, 'msg': msg, 'lyrics': lyrics} except Exception as e: print(f"Exception occurred in retrieving lyrics: {str(e)}") status = 'error' lyrics = None if e.status == 404: msg = f"{NO_MATCHING_LYRICS} (error-code ={e.status})" elif e.status == 403: msg = f"{LYRICS_SERVICE_NOT_RESPONDiNG} (error code={e.status}) " elif e.status == 500: msg = f"Server error occurred (error-code={e.status})" else: # Catch all for all other errors msg = f"{MISC_SERVER_ERROR} (error-code={e.status})" # import pdb; pdb.set_trace() return {'status': status, 'msg': msg, 'lyrics': lyrics}
def get_song_lyrics(genius: lyricsgenius.Genius, song: str, artist: str) -> Union[dict, None]: """Searches Genius for song details based on song name and artist. Args: genius (lyricsgenius.Genius): LyricsGenius object to use for query. song (str): Title of song artist (str): Name of artist Returns: Union[dict,None]: Song details (from JSON) or `None` if no results. """ songdetails = genius.search_song( title=song, artist=artist, get_full_info=True, ) if songdetails: return songdetails.to_dict() else: return None
class GetGenius: def __init__(self): # init Genius GENIUS_ACCESS_TOKEN = os.getenv('GENIUS_ACCESS_TOKEN') self.genius = Genius(GENIUS_ACCESS_TOKEN) def get_lyrics(self, query): lyrics = [] results = self.genius.search_lyrics(query) for hit in results['sections'][0]['hits']: if hit['result']['title'][-4:] != 'list': docid = hit['result']['id'] title = str(hit['result']['title']).replace('/', ' ').replace( '?', ' ') artist = hit['result']['primary_artist']['name'] url_img = hit['result']['song_art_image_url'] lyric = self.genius.search_song(title, artist).lyrics lyrics.append([docid, title, artist, url_img, lyric]) return (lyrics)
def retrieve_song_lyrics(update, context): '''get song lyrics''' text = update.message.text genius = Genius(LYRICS_TOKEN) genius.skip_non_songs = True song = genius.search_song(text, artist='', get_full_info=False) if not song: update.message.reply_text("Unable to find lyrics for the given song.") else: lyrics = song.lyrics song_length = len(lyrics) count = 0 try: while song_length > 4096: update.message.reply_text(lyrics[:4096]) song_length -= 4096 count += 1 update.message.reply_text(lyrics[4096 * count:]) except: update.message.reply_text( "Unable to find lyrics for the given song.") update.message.reply_text("Use /help to list available actions.") return ConversationHandler.END
def cmd_lyrics(arg): token = "47eX0yhBx2cDhrs1n7530NrDmSVJbuCmgCORJRDv9wvIbtbKRAK4BPP2_uoKVaN3" genius = Genius(token) search_phrase = str(arg) try: full_input = search_phrase.lower() full_input = full_input.split(",") artist_input = full_input[0] song_input = full_input[1] result = genius.search_song(song_input, artist_input) text_data = result.lyrics except Exception as E: text_data = ( "Lyric search failed, please check the spelling of the artist and song title. Please note, " "there are millions of songs and artist in the database, your query has to be exactly right to " "retrieve the lyrics.") text_data += "Your body of the message should look like one of the following examples: \r" text_data += "Ariana Grande, Imagine \r" text_data += "Lady Gaga, Shallow \r" text_data += "Mariah Carey, All I want for Christmas is Your \r" text_data += "Chainsmokers, Hope \r" text_data += "Error: " + str(E) return text_data
def main(): genius = Genius(apikeys.genius) genius.excluded_terms = ['(How to pronounce)'] genius.remove_section_headers = True genius.skip_non_songs = True pinyin = Pinyin() song_info = [ input("Enter the song name\n"), input( "Enter the artist name (recommended, leave blank if you don't know)\n" ) ] song = genius.search_song(song_info[0], song_info[1]) lyrics = song.lyrics pinyin_lyrics = pinyin.get_pinyin(lyrics, splitter=' ', tone_marks='marks') pinyin_lyrics = cleanup(pinyin_lyrics) print(pinyin_lyrics) outfile_path = "C:\\Users\\Declan\\Desktop\\" + song.title + ', ' + song.artist + '-Pinyin.txt' outfile = open(outfile_path, 'w', encoding='utf-8') outfile.write(pinyin_lyrics) outfile.close()
class GeniusLyrics: def __init__(self, access_token, genius=None): self.__artist = None self.__title = None self.__lyrics = None self.__genius = None from lyricsgenius import Genius # use or create Genius class if isinstance(genius, Genius): self.__genius = genius else: self.__genius = Genius(access_token, skip_non_songs=True) @property def artist(self): return self.__artist @artist.setter def artist(self, new_artist): self.__artist = new_artist _LOGGER.debug(f"Artist set to: {self.__artist}") @property def title(self): return self.__title @title.setter def title(self, new_title): # filter out terms from title # TODO: move to CONFIG_SCHEMA exclude_terms = [ '(explicit', '(feat', ] _new_title = str(new_title).lower() for term in exclude_terms: if term in _new_title: pos = _new_title.find(term) self.__title = new_title[0:pos].strip() break else: self.__title = new_title _LOGGER.debug(f"Title set to: {self.__title}") @property def lyrics(self): return self.__lyrics def fetch_lyrics(self, artist=None, title=None): if artist: self.__artist = artist if title: self.__title = title if self.__artist is None or self.__title is None: _LOGGER.error("Missing artist and/or title") return _LOGGER.info( f"Search lyrics for artist='{self.__artist}' and title='{self.__title}'" ) song = self.__genius.search_song(self.__title, self.__artist, get_full_info=False) if song: _LOGGER.debug( f"Found song: artist = {song.artist}, title = {song.title}") # FIXME: need to avoid incorrectly found song lyrics # for now..comparing artist names suffices. Titles may differ (e.g. 'feat. John Doe') # if self.__title == song.title: # _LOGGER.debug(f"Found lyrics: {song.lyrics}") # if str(self.__artist).lower() == str(song.artist).lower() \ # or str(song.title).lower() in str(self.__title).lower(): self.__title = song.title self.__lyrics = song.lyrics return True else: self.__lyrics = "Lyrics not found" return False def reset(self): self.__artist = None self.__title = None self.__lyrics = None
def execute(self, context): if self.skip_task == True: return genius = Genius(self.genius_access_token) redshift = PostgresHook(postgres_conn_id=self.redshift_conn_id) self.year = context.get('execution_date').year if (self.delete_before_insert == True): self.log.info("Clearing data from destination Redshift table") redshift.run("DELETE FROM {}".format(self.to_table)) self.log.info("Getting songs to query their lyrics") if self.select_limit is not None: select_limit = "LIMIT {}".format(self.select_limit) else: select_limit = "" select_query = """ SELECT artist_name AS artist, song_name AS song FROM staging_charts WHERE chart_year = '{}' AND chart_title = '{}' {} """.format(self.year, self.chart_name.replace("'", "\\'"), select_limit) song_list = redshift.get_records(select_query) self.log.info("Querying lyrics for {} tracks".format(len(song_list))) sid = SentimentIntensityAnalyzer() song_lyrics = [] for song in song_list: try: genius_song = genius.search_song(song[1], song[0]) except Exception as e: self.log.error(e) if genius_song is not None: self.log.info('Found : {} - {}'.format(genius_song.title, genius_song.artist)) # get the lyrics sentence = genius_song.lyrics # remove words between [] and () sentence = re.sub(r'\[.*\]', '', sentence) sentence = re.sub(r'\(.*\)', '', sentence) # tokenize tokens = nltk.word_tokenize(sentence) # tokenize without punctuation and converting to lowercase lower_alpha_tokens = [ w for w in word_tokenize(sentence.lower()) if w.isalpha() ] # remove stopwords no_stops = [ t for t in lower_alpha_tokens if t not in stopwords.words('english') ] # get stopwords removed only_stops = [ x for x in lower_alpha_tokens if x not in no_stops ] # count count_words = len(lower_alpha_tokens) count_stopwords = len(only_stops) count_no_stopwords = len(no_stops) count_distinct_words = len( collections.Counter(lower_alpha_tokens)) count_distinct_no_stopwords = len( collections.Counter(no_stops)) count_distinct_words_used_once = len([ x[1] for x in collections.Counter(no_stops).most_common() if x[1] == 1 ]) # get most frequent words distinct_most_common = [ '{}:{}'.format(x[0], x[1]) for x in collections.Counter( no_stops).most_common(self.most_common_count) ] count_most_common_usage = sum([ x[1] for x in collections.Counter(no_stops).most_common( self.most_common_count) ]) # analyse sentiment lyrics_sentiment = sid.polarity_scores(sentence) common_words_sentiment = sid.polarity_scores(' '.join([ x[0] for x in collections.Counter(no_stops).most_common( self.most_common_count) ])) common_words_sentiment_with_weights = sid.polarity_scores( ' '.join([ ' '.join([x[0]] * x[1]) for x in collections.Counter( no_stops).most_common(self.most_common_count) ])) song_lyrics.append({ 'artist': genius_song.artist, 'song': genius_song.title, 'lyrics': genius_song.lyrics.replace("'", "\\'"), 'count_words': count_words, 'count_no_stopwords': count_no_stopwords, 'count_distinct_words': count_distinct_words, 'count_distinct_no_stopwords': count_distinct_no_stopwords, 'count_distinct_words_used_once': count_distinct_words_used_once, 'distinct_most_common': ','.join(distinct_most_common), 'count_most_common_usage': count_most_common_usage, 'lyrics_sentiment': lyrics_sentiment['compound'], 'common_words_sentiment': common_words_sentiment['compound'], 'common_words_sentiment_with_weights': common_words_sentiment_with_weights['compound'], }) self.log.info("Copying data to table") data_to_insert = [("(" + ",".join( (len(song)) * ["'{}'"]) + ")").format( song['artist'], song['song'], song['lyrics'][0:65535], song['count_words'], song['count_no_stopwords'], song['count_distinct_words'], song['count_distinct_no_stopwords'], song['count_distinct_words_used_once'], song['distinct_most_common'], song['count_most_common_usage'], song['lyrics_sentiment'], song['common_words_sentiment'], song['common_words_sentiment_with_weights'], ) for song in song_lyrics] formatted_sql = self.sql_query.format(self.to_table, ','.join(data_to_insert)) redshift.run(formatted_sql)
from lyricsgenius import Genius # token goes here # still need to get the token genius = Genius(token) res = genius.search_song("Red Hot Chili Peppers", "Under the Bridge") print(res.lyrics)
# load env file load_dotenv(find_dotenv()) # init twilio things twilio_account_sid = os.getenv('TWILIO_ACCOUNT_SID') twilio_auth_token = os.getenv('TWILIO_AUTH_TOKEN') # init lyrics genius things lyrics_genius_client_id = os.getenv('GENIUS_CLIENT_ID') genius = Genius(lyrics_genius_client_id) # get artist info #song = genius.search_song("Look At Me", "xxxtentacion") #song = genius.search_song("WAP", "cardi b") #song = genius.search_song("f**k love", "xxxtentacion") #song = genius.search_song("lateralus", "tool") #song = genius.search_song("and i told them i invented times new roman", "dance gavin dance") song = genius.search_song("throat babies", "city girls") lyrics = song.lyrics.splitlines() pyautogui.PAUSE = 1 sleep(2) for line in lyrics: pyautogui.write(line + "\n", ) #pyautogui.press("enter",interval=0.025, _pause=0.25) #phone_num_to = "+17867201701" #phone_num_from = "+17866996629" #lyrics_file = "/Users/jasonballadares/repos/imessagespambot/data/lookatme.txt" #lyrics = get_lyrics(lyrics_file) # send_messages(phone_num_to, phone_num_from, lyrics, # Client(account_sid, auth_token))
df = pd.DataFrame({ "track": track, "artist": artist, }) return df spotify_data = get_playlist_tracks(playlist_uri) print(spotify_data) lyrics = [""] * len(spotify_data) for i, (track, artist) in tqdm( enumerate(zip(spotify_data["track"], spotify_data["artist"]))): try: song = genius.search_song(track, artist, get_full_info=False) lyrics[i] = song.lyrics except: print(f'Skipping "{track}" by {artist}') for i, x in tqdm(enumerate(lyrics)): if x == "": track = spotify_data["track"][i] artist = spotify_data["artist"][i] try: song = genius.search_song(track, artist, get_full_info=False) lyrics[i] = song.lyrics except: print(f'Giving up on "{track}" by {artist}') spotify_data.insert(2, "lyrics", lyrics)
def _fetch_lyrics(self, query: str) -> typing.Optional[Song]: genius = Genius(self.GENIUS_TOKEN, verbose=False) return genius.search_song(query, get_full_info=False)
from lyricsgenius import Genius from colorama import init, Fore, Style from mutagen.easyid3 import EasyID3 from genius_tokens import CLIENT_ACCESS_TOKEN import sys args = sys.argv if len(args) == 1: print("Specify path to audio") exit(1) audio_path = args[1] audio = EasyID3(audio_path) genius = Genius(CLIENT_ACCESS_TOKEN) genius.verbose = False genius.remove_section_headers = True song = genius.search_song(audio["title"][0], audio["artist"][0]) print(song.lyrics)
class Scraper: """ Scraper for genius data. Args: genius_auth_path (str): filepath to the authorization text file with genius API client access token. Default is 'data/genius.auth' minsleep (float): minimum time to sleep between requests to the genius API. Default is 0.5 """ def __init__(self, genius_auth_path="data/genius.auth", minsleep=0.5): # gets client access token with open("data/genius.auth", "r") as file: client_access_token = file.read().strip() self.minsleep = minsleep self.api = Genius(client_access_token, remove_section_headers=True) self.lyrics = MongoClient().billboard["lyrics"] self.errlog = MongoClient().billboard["lyrics_errlog"] print("Initialized") def populate_billboard_scrapables(self): """ Identifies billboard tracks to scrape from the spotify collection. Returns: None. sets self.df """ results = MongoClient().billboard.spotify.find() self.df = pd.DataFrame( data=map( lambda r: ( r["metadata"]["id"], r["metadata"]["artists"][0]["name"], r["metadata"]["name"], ), results, ), columns=["track_id", "artist_name", "title"], ) print(f"Tracks identified to scrape lyrics: {self.df.shape[0]}") def populate_nillboard_scrapables(self): """ Populates tracks to scraped that are not on the billboard Returns: None. Sets internal state as self.df """ # initialize db connection db = MongoClient().billboard # get the track_ids that have already been scraped. scraped_ids = [r["_id"] for r in db.lyrics.find() ] + [r["metadata"]["id"] for r in db.spotify.find()] print("scraped ids", len(scraped_ids)) # get the entries that have not yet been scraped tracks_cursor = db.spotify_nillboard.find( {"_id": { "$nin": scraped_ids }}) # unpack the db response cursor data = map( lambda r: [ r["_id"], r["metadata"]["artists"][0]["name"], r["metadata"]["name"], ], tracks_cursor, ) # set internal dataframe to be scraped self.df = pd.DataFrame(data, columns=["track_id", "artist_name", "title"]) print(f"Tracks identified to scrape lyrics: {self.df.shape[0]}") def scrape_df_segment_to_db(self, scraperange, verbose=1): """ Scrapes an index range from self.df to the database. Args: scraperange (iterable): iterable of indices to scrape from self.df to the db verbose (int): verbosity level. Higher verbosity, more prints. Returns: None. Puts genius data in billboard.lyrics and errors in billboard.lyrics_errlog when needed. """ for i in scraperange: row = self.df.iloc[i] try: self.scrape_song_to_db(row["artist_name"], row["title"], row["track_id"]) # record error and continue except TypeError as e: self.record_error(row["track_id"], "TypeError") # track has already been scraped to the db - print and continue except DuplicateKeyError: if verbose: print(f"Duplicate skipped on index {i}") if verbose > 1: print(i) def scrape_song_to_db(self, artist, title, track_id): """ Scrapes a single track to the database. Args: artist (str): the artist name title (str): the title of the track track_id (str): the id of the track to be used as the mongodb _id Returns: None. Adds a track to the lyrics collection, or lyrics_errlog if needed. """ # remove featured artist names artist = stripFeat(artist) try: # record stout from lyricsgenius call because it catches errors and prints with Capturing() as output: songdata = self.api.search_song(title, artist) # for the few errors that have been raised except ReadTimeout: self.api.sleep_time += 3 print(f"sleep time increased to {self.api.sleep_time}") self.record_error(track_id, "ReadTimeout") self.scrape_song_to_db(artist, title, track_id) return # take sleep time slowly back to minimum if self.api.sleep_time > self.minsleep: self.api.sleep_time -= 0.25 print(f"sleep time decreased to {self.api.sleep_time}") # search successful if songdata != None: self.record_lyrics_result(track_id, songdata) # handle (record & retry) Timeout error elif output[1].startswith("Timeout"): self.api.sleep_time += 3 self.record_error(track_id, "Timeout") self.scrape_song_to_db(artist, title, track_id) return # record error: not in genius db elif output[1].startswith("No results"): self.record_error(track_id, "no_results") # record error: song without lyrics elif output[1] == "Specified song does not contain lyrics. Rejecting.": self.record_error(track_id, "lacks_lyrics") # record error: URL issue elif (output[1] == "Specified song does not have a valid URL with lyrics. Rejecting." ): self.record_error(track_id, "invalid_url") def record_lyrics_result(self, track_id, songdata): """ Inserts a track's lyrics to the lyrics collection. Args: track_id (str): spotify track id to be the mongodb _id songdata (dict): contains track data in keys 'artist', 'title', and 'lyrics' Returns: None. A song is inserted into the lyrics collection. """ self.lyrics.insert_one({ "_id": track_id, "response_artist": songdata.artist, "response_title": songdata.title, "lyrics": songdata.lyrics, }) def record_error(self, track_id, errtype): """ Inserts the record of an error into the errlog collection. Args: track_id (str): id of the track this error occurred on errtype (str): type of error that occurred. Returns: None. Inserts 1 record into the errlog collection """ self.errlog.insert_one({"track": track_id, "type": errtype}) def record_error_verbose(self, track_id, errmsg): """ Inserts a verbose error into the errlog collection. Args: track_id (str): id of the track this error occurred on errmsg (str): error message to record Returns: None. An error of type 'verbose' is inserted into the errlog collection. """ self.errlog.insert_one({ "track": track_id, "type": "verbose", "message": errmsg })
class music(commands.Cog): def __init__(self, bot): self.bot = bot self.YTDL_OPTIONS = { 'format': 'bestaudio', 'noplaylist': True, 'default-search': 'auto', 'quiet': True, 'extractaudio': True, 'audioformat': 'mp3', 'rm-cache-dir': True, 'skip_download': True } self.YTDL_OPTIONS_PLAYLIST_FIRSTSONG = { 'format': 'bestaudio', 'extractaudio': True, 'skip_download': True, 'playlistend': 1, 'noplaylist': False, 'quiet': True, '-yes_playlist': True } self.YTDL_OPTIONS_PLAYLIST_RESTOFSONGS = { 'format': 'bestaudio', 'extractaudio': True, 'skip_download': True, 'playliststart': 2, 'playlistend': 20, 'quiet': True, 'noplaylist': False, '-yes_playlist': True } self.FFMPEG_OPTIONS = { 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn' } conn = sqlite.connect("data/internal.db") conn.execute( "CREATE TABLE IF NOT EXISTS music(id INTEGER PRIMARY KEY, guild_id INTEGER NOT NULL, current_song TEXT, queued_songs TEXT, loop INTEGER NOT NULL)" ) conn.commit() conn.close() self.lyrics_finder = Genius(GENIUS_TOKEN) def songs_to_string(self, songs): output = "" for song in songs: output += f"|{song['track']}|{song['title']}|{song['artist']}|{song['duration']}|{song['likes']}|{song['dislikes']}|{song['link']}|{song['author']}|" return output def song_to_string(self, song): return f"|{song['track']}|{song['title']}|{song['artist']}|{song['duration']}|{song['likes']}|{song['dislikes']}|{song['link']}|{song['author']}|" def songs_from_string(self, songs): if songs == "" or songs == None or not songs: return [] songs = songs.split("||") output = [] for song in songs: if song == "": pass else: song = list(filter(None, song.split("|"))) output.append({ 'track': song[0], 'title': song[1], 'artist': song[2], 'duration': song[3], 'likes': song[4], 'dislikes': song[5], 'link': song[6], 'author': song[7] }) return output def song_from_string(self, song): if not song: return {} song = song.split("|") return { 'track': song[1], 'title': song[2], 'artist': song[3], 'duration': song[4], 'likes': song[5], 'dislikes': song[6], 'link': song[7], 'author': song[8] } def write_to_db(self, ctx, song): conn = sqlite.connect("data/internal.db") song_to_store = f"|{song['track']}|{song['title']}|{song['artist']}|{song['duration']}|{song['likes']}|{song['dislikes']}|{song['link']}|{song['author']}|" if len( conn.execute( f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}"). fetchall()) == 0: conn.execute("INSERT INTO music VALUES(NULL, ?, ?, ?, ?)", [ctx.guild.id, "", song_to_store, 0]) else: guild_music = conn.execute( f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0] guild_loop = guild_music[4] guild_music = self.songs_from_string(guild_music[3]) if guild_loop == 1: guild_music.insert(-1, song) else: guild_music.append(song) conn.execute( f"UPDATE music SET queued_songs = ? WHERE guild_id = ?", (self.songs_to_string(guild_music), ctx.guild.id)) conn.commit() conn.close() def write_to_db_multiple(self, ctx, songs): conn = sqlite.connect("data/internal.db") songs_to_store = self.songs_to_string(songs) if len( conn.execute( f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}"). fetchall()) == 0: conn.execute("INSERT INTO music VALUES(NULL, ?, ?, ?, ?)", [ctx.guild.id, "", songs_to_store, 0]) else: guild_music = conn.execute( f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0] guild_loop = guild_music[4] guild_music = self.songs_from_string(guild_music[3]) if guild_loop == 1: for song in songs: guild_music.insert(-1, song) else: guild_music.extend(songs) conn.execute( f"UPDATE music SET queued_songs = ? WHERE guild_id = ?", (self.songs_to_string(guild_music), ctx.guild.id)) conn.commit() conn.close() async def get_audio_info(self, song, author, ytlist=False, first=True): if not ytlist: if song.__contains__( "https://www.youtube.com") or song.__contains__( "https://www.youtu.be"): with YoutubeDL(self.YTDL_OPTIONS) as ydl: info = ydl.extract_info(song, download=False) else: with YoutubeDL(self.YTDL_OPTIONS) as ydl: info = ydl.extract_info(f"ytsearch:{song}", download=False)['entries'][0] try: creator = info['creator'] except KeyError: creator = info['uploader_id'] try: dislikes = info['dislike_count'] except KeyError: dislikes = "Hidden" return { "track": info['url'], "title": info['title'], "artist": creator, "duration": info['duration'], "likes": info['like_count'], "dislikes": dislikes, "link": "https://www.youtube.com/watch?v=" + info['id'], "author": author } else: if first: with YoutubeDL(self.YTDL_OPTIONS_PLAYLIST_FIRSTSONG) as ydl: info = ydl.extract_info(song, download=False)['entries'][0] try: creator = info['creator'] except KeyError: creator = info['uploader_id'] try: dislikes = info['dislike_count'] except KeyError: dislikes = "Hidden" return { "track": info['url'], "title": info['title'], "artist": creator, "duration": info['duration'], "likes": info['like_count'], "dislikes": dislikes, "link": "https://www.youtube.com/watch?v=" + info['id'], "author": author } else: with YoutubeDL(self.YTDL_OPTIONS_PLAYLIST_RESTOFSONGS) as ydl: info = ydl.extract_info(song, download=False)['entries'] output = [] for entry in info: try: creator = entry['creator'] except KeyError: creator = entry['uploader_id'] try: dislikes = entry['dislike_count'] except KeyError: dislikes = "Hidden" output.append({ "track": entry['url'], "title": entry['title'], "artist": creator, "duration": entry['duration'], "likes": entry['like_count'], "dislikes": dislikes, "link": "https://www.youtube.com/watch?v=" + entry['id'], "author": author }) return output def play_audio(self, ctx, inform=True): conn = sqlite.connect("data/internal.db") guild_info = conn.execute( f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}").fetchall( )[0] songs = self.songs_from_string(guild_info[3]) current_song = "" if conn.execute( f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}").fetchall( )[0][2] == "" else self.song_from_string(guild_info[2]) loop = guild_info[4] if len(songs) > 0: if loop == 1 and current_song == songs[0] and len(songs) > 1: songs.append(songs.pop(0)) current_song = songs.pop(0) if inform: self.bot.loop.create_task(self.inform_user(ctx)) if loop == 1: songs.append(current_song) conn.execute( f"UPDATE music SET current_song = ?, queued_songs = ? WHERE guild_id = ?", (self.song_to_string(current_song), self.songs_to_string(songs), ctx.guild.id)) conn.commit() conn.close() ctx.voice_client.play( FFmpegPCMAudio(current_song['track'], **self.FFMPEG_OPTIONS), after=lambda error: print(error) if error is not None else self.play_audio(ctx)) async def inform_user(self, ctx): conn = sqlite.connect("data/internal.db") current_song = self.songs_from_string( conn.execute(f"SELECT * FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][2])[0] conn.close() music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") music_field.title = f"{current_song['title']}" music_field.add_field(name=f"`{current_song['artist']}`", value=f"Artist") music_field.add_field( name= f"`{datetime.timedelta(seconds = int(current_song['duration']))}`", value=f"Duration") music_field.add_field( name=f"`{current_song['likes']}/{current_song['dislikes']}`", value=f"Popularity") author = await ctx.guild.fetch_member(current_song['author']) music_field.add_field(name=f"Playing now!", value=f"Requested by { author.mention}") await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="join") @commands.command() async def join(self, ctx, hello=""): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") if ctx.author.voice: if not ctx.voice_client: await ctx.author.voice.channel.connect() music_field.add_field( name=f"Connected to your channel!", value= f"You can use `{get_prefix(self.bot, ctx.message)}play` to start some music" ) if hello != "": info = self.get_audio_info( "https://www.youtube.com/watch?v=hCiv9wphnME") ctx.voice_client.play( FFmpegPCMAudio(info['track'], **self.FFMPEG_OPTIONS)) else: music_field.add_field( name=f"I'm already connected!", value= f"Use `{get_prefix(self.bot, ctx.message)}play` to play music" ) else: music_field.add_field( name=f"You have to be connected to a voice channel.", value= f"What a dumb rule, right? But I have to know where to connect first." ) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="leave") @commands.command() async def leave(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") if ctx.voice_client: await ctx.voice_client.disconnect() music_field.add_field( name=f"Disconnected from voice channel!", value=f"And until next time, have a great time!") else: music_field.add_field( name=f"I am not connected anywhere!", value= f"You can use `{get_prefix(self.bot, ctx.message)}join` to get me on your channel or `{get_prefix(self.bot, ctx.message)}play` to start some music" ) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="play") @commands.command() async def play(self, ctx, *, song): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") if ctx.author.voice: if ctx.voice_client == None: await ctx.author.voice.channel.connect() if song.lower().__contains__("list="): if song.lower().__contains__("&list="): x = song.index("list=") song = f"https://www.youtube.com/playlist?{song[x:]}" info = await self.get_audio_info(song, ctx.author.id, ytlist=True, first=True) self.write_to_db(ctx, info) if not ctx.voice_client.is_playing( ) and not ctx.voice_client.is_paused(): self.play_audio(ctx, inform=False) await self.inform_user(ctx) infos = await self.get_audio_info(song, ctx.author.id, ytlist=True, first=False) self.write_to_db_multiple(ctx, infos) music_field.title = f"Loaded your list!" music_field.add_field( name= f"I have placed all the songs from the playlist into your queue", value= f"I'm sorry if it took long, sometimes, loading 200 song playlist is not an easy task." ) await ctx.send(embed=music_field) else: info = await self.get_audio_info( song, ctx.author.id, ) if not ctx.voice_client.is_playing( ) and not ctx.voice_client.is_paused(): self.write_to_db(ctx, info) self.play_audio(ctx) else: music_field.title = f"{info['title']}" music_field.add_field(name=f"`{info['artist']}`", value=f"Artist") music_field.add_field( name= f"`{datetime.timedelta(seconds = info['duration'])}`", value=f"Duration") music_field.add_field( name=f"`{info['likes']}/{info['dislikes']}`", value=f"Popularity") music_field.add_field( name=f"Added to queue", value=f"***Sorry, somebody was faster than you.***") self.write_to_db(ctx, info) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="pause") @commands.command() async def pause(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") if ctx.voice_client == None: music_field.add_field( name="Nothing to be paused!", value= f"This commands purpose is to pause currently playing song. To play song use `{get_prefix(self.bot, ctx.message)}play`" ) else: if ctx.voice_client.is_playing(): current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) music_field.add_field( name=f"{current_song['title']} paused!", value= f"Song is now paused if you want to resume it, you can use `{get_prefix(self.bot, ctx.message)}resume`" ) ctx.voice_client.pause() elif ctx.voice_client.is_paused(): current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) music_field.add_field( name=f"{current_song['title']} is already paused!", value= f"To resume it use `{get_prefix(self.bot, ctx.message)}resume`" ) else: music_field.add_field( name="Nothing to be paused!", value= f"This commands purpose is to pause currently playing song. To play song use `{get_prefix(self.bot, ctx.message)}play`" ) await ctx.send(embed=music_field) conn.close() #@cog_ext.cog_slash(name="resume") @commands.command() async def resume(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") if ctx.voice_client == None: music_field.add_field( name="Nothing to be resumed!", value= f"If you want to start some music use `{get_prefix(self.bot, ctx.message)}play`" ) else: if ctx.voice_client.is_paused(): current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) music_field.add_field(name=f"{current_song['title']} resumed!", value=f"Let the show start again!") ctx.voice_client.resume() elif ctx.voice_client.is_playing(): current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) music_field.add_field( name=f"{current_song['title']} is playing already!", value= f"You can pause it using `{get_prefix(self.bot, ctx.message)}pause`" ) else: music_field.add_field( name="Nothing to be resumed!", value= f"If you want to start some music use `{get_prefix(self.bot, ctx.message)}play`" ) await ctx.send(embed=music_field) conn.close() #@cog_ext.cog_slash(name="skip") @commands.command() async def skip(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") if ctx.voice_client == None: music_field.add_field( name="Nothing to be skipped!", value= f"It seems you have no songs playing nor in queue. Don't worry, use `{get_prefix(self.bot, ctx.message)}play` to play something!" ) else: if ctx.voice_client.is_playing() or ctx.voice_client.is_paused(): current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) conn.close() music_field.add_field(name=f"{current_song['title']} skipped!", value=f"You didn't like it, I see") ctx.voice_client.stop() else: music_field.add_field( name="Nothing to be skipped!", value= f"It seems you have no songs playing nor in queue. Don't worry, use `{get_prefix(self.bot, ctx.message)}play` to play something!" ) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="loop") @commands.command() async def loop(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") if len( conn.execute("SELECT * FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()) == 0: conn.execute("INSERT INTO music VALUES(NULL, ?, ?, ?, ?)", ("", "", 1, ctx.guild.id)) music_field.add_field( name="Loop turn on!", value= f"To enjoy the sweet music before you start hatin' it, {ctx.author.mention}?" ) conn.commit() conn.close() else: loop = True if int( conn.execute( "SELECT loop FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) == 1 else False if loop: conn.execute("UPDATE music SET loop = ? WHERE guild_id = ?", (0, ctx.guild.id)) conn.commit() conn.close() music_field.add_field(name="Song looping off!", value=f"You got tired of it, huh?") else: conn.execute("UPDATE music SET loop = ? WHERE guild_id = ?", (1, ctx.guild.id)) conn.commit() music_field.add_field( name="Loop turn on!", value= f"You really like ***this*** song, {ctx.author.mention}?") songs = self.songs_from_string( conn.execute( f"SELECT queued_songs FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][0]) if ctx.voice_client.is_playing( ) or ctx.voice_client.is_paused and songs.empty(): conn.execute( "UPDATE music SET queued_songs = ? WHERE guild_id = ?", (conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0], ctx.guild.id)) conn.commit() conn.close() await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="stop") @commands.command() async def stop(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") if ctx.voice_client == None: music_field.add_field( name="No songs to be stopped!", value= f"You don't have ny songs in your queue or playing. Use `{get_prefix(self.bot, ctx.message)}play` to play something!" ) else: if ctx.voice_client.is_playing() or ctx.voice_client.is_paused(): conn.execute( "UPDATE music SET queued_songs = ?, current_song = ? WHERE guild_id = ?", ("", "", ctx.guild.id)) conn.commit() ctx.voice_client.stop() music_field.add_field( name="All songs from queue were purged!", value= f"To disconnect me use `{get_prefix(self.bot, ctx.message)}leave` or issue `{get_prefix(self.bot, ctx.message)}play` to play new songs!" ) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="queue") @commands.command() async def queue(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") total_duration = 0 if ctx.voice_client: if ctx.voice_client.is_playing() or ctx.voice_client.is_paused(): current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) songs = self.songs_from_string( conn.execute( f"SELECT queued_songs FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][0]) loop = "Yes" if conn.execute( f"SELECT loop FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0] == 1 else "No" if current_song: music_field.title = f"`Now playing` - {current_song['title']}" if songs: for song in songs: author = await ctx.guild.fetch_member( song['author']) music_field.add_field( name= f"`{songs.index(song) + 1}` - {song['title']} by `{song['artist']}`", value= f"Duration: `{datetime.timedelta(seconds = int(song['duration']))}` | Popularity: `{song['likes']}/{song['dislikes']}` | Requested by {author.mention}", inline=False) total_duration += int(song['duration']) music_field.add_field( name=f"Total Duration", value= f"`{datetime.timedelta(seconds = total_duration)}`" ) music_field.add_field(name=f"Number of songs", value=f"`{len(songs)}`") music_field.add_field(name=f"Loop", value=f"`{loop}`") else: author = await ctx.guild.fetch_member( current_song['author']) music_field.add_field( name=f"Author: `{current_song['artist']}`", value= f"Duration: `{datetime.timedelta(seconds = int(current_song['duration']))}` | Popularity: `{current_song['likes']}/{current_song['dislikes']}` | Requested by {author.mention}" ) else: music_field.title = f"I'm not playing anything" music_field.add_field( name=f"You can sit here in silence", value= f"Or you can play a song using `{get_prefix(self.bot, ctx.message)}play link or name of song here`" ) else: music_field.add_field( name=f"They are no songs playing!", value= f"If you want to play a new song simply type `{get_prefix(self.bot, ctx.message)}play`" ) else: music_field.title = f"You want to display a whole queue of nothingness?" music_field.add_field( name= f"Not even connecting me and wanting to display queue.. Rude.", value= f"You can join me into your voice channel using `{get_prefix(self.bot, ctx.message)}join`" ) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="remove") @commands.command() async def remove(self, ctx, index): index = int(index) music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute("SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) songs = self.songs_from_string( conn.execute( f"SELECT queued_songs FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][0]) if not songs and not ctx.voice_client.is_playing( ) and not ctx.voice_client.is_paused(): music_field.add_field( name="There is no existing queue", value= f"But you can use `{get_prefix(self.bot, ctx.message)}play` to play something!" ) elif index - 1 > len(songs): music_field.add_field( name="This song doesn't exist in your queue", value= f"To remove all songs from the queue use `{get_prefix(self.bot, ctx.message)}stop`" ) elif index - 1 <= len(songs) and index - 1 >= 0: removed_song = songs.pop(index - 1) music_field.add_field( name= f"{removed_song['title']} has been removed from your queue!", value=f"I bet nobody will miss it anyway") conn.execute( "UPDATE music SET queued_songs = ? WHERE guild_id = ?", (self.songs_to_string(songs), ctx.guild.id)) conn.commit() conn.close() await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="move") @commands.command() async def move(self, ctx, index_of_song, desired_position): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") index_of_song = int(index_of_song) - 1 desired_position = int(desired_position) - 1 conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute("SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) songs = self.songs_from_string( conn.execute( f"SELECT queued_songs FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][0]) if index_of_song >= 0 and desired_position >= 0: if index_of_song > len(songs): music_field.add_field( name=f"There is no song on position `{index_of_song + 1}`", value= f"Did you want to skip? Use `{get_prefix(bot, ctx.message)}skip` Don't worry, if you have loop enabled the song will stay in queue" ) else: if desired_position > len(songs) - 1: songs.append(songs.pop(index_of_song)) conn.execute( "UPDATE music SET queued_songs = ? WHERE guild_id = ?", (self.songs_to_string(songs), ctx.guild.id)) conn.commit() music_field.add_field( name= f"Song `{songs[-1]['title']}` was moved to the end of queue from position `{index_of_song + 1}`", value= f"This happened because you entered number greater than the index of last song" ) else: songs.insert(desired_position, songs.pop(index_of_song)) conn.execute( "UPDATE music SET queued_songs = ? WHERE guild_id = ?", (self.songs_to_string(songs), ctx.guild.id)) conn.commit() music_field.add_field( name= f"I have moved `{songs[desired_position]['title']}`from position `{index_of_song + 1}` to `{desired_position + 1}`", value=f"I hope I got it right!") conn.close() await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="now") @commands.command() async def now(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") if ctx.voice_client: if ctx.voice_client.is_playing() or ctx.voice_client.is_paused(): conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute( "SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) conn.close() if current_song: author = await ctx.guild.fetch_member( current_song['author']) music_field.title = f"`Now playing` - {current_song['title']}" music_field.add_field( name=f"Author: `{current_song['artist']}`", value= f"Duration: `{datetime.timedelta(seconds = int(current_song['duration']))}` | Popularity: `{current_song['likes']}/{current_song['dislikes']}` | Requested by {author.mention}" ) else: music_field.title = f"I'm not playing anything" music_field.add_field( name= f"But you can play a song using `{get_prefix(self.bot, ctx.message)}play link or name of song here`", value= "Or you can continue sitting here in complete silence, your choice." ) else: music_field.title = f"I'm not playing anything" music_field.add_field( name= f"But you can play a song using `{get_prefix(self.bot, ctx.message)}play link or name of song here`", value= "Or you can continue sitting here in complete silence, your choice." ) else: music_field.title = f"You have to at least connect me first!" music_field.add_field( name= f"I can't display nothing. Well, I can, I'm doing now, right?", value= f"You can play a song using `{get_prefix(self.bot, ctx.message)}play link or name of song here`" ) await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="grab") @commands.command() async def grab(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") dm_field = discord.Embed(colour=discord.Colour(0xFDED32)) dm_field.set_author(name="𝓖𝓛𝓞𝓑") conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute("SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) conn.close() if ctx.voice_client.is_playing() or ctx.voice_client.is_paused(): music_field.title = f"{current_song['title']}" music_field.add_field(name=f"`{current_song['artist']}`", value=f"Artist") music_field.add_field( name= f"`{datetime.timedelta(seconds = int(current_song['duration']))}`", value=f"Total Duration") music_field.add_field( name=f"`{current_song['likes']}/{current_song['dislikes']}`", value=f"Popularity") music_field.add_field(name=f"You really liked it, didn't ya?", value=f"*I sent this song to your DMs*") dm_field.title = f"{current_song['title']}" dm_field.add_field(name=f"`{current_song['artist']}`", value=f"Artist") dm_field.add_field( name= f"`{datetime.timedelta(seconds = int(current_song['duration']))}`", value=f"Total Duration") dm_field.add_field( name=f"`{current_song['likes']}/{current_song['dislikes']}`", value=f"Popularity") dm_field.add_field(name=f"Here you go!", value=f"{current_song['link']}") channel = await ctx.author.create_dm() await channel.send(embed=dm_field) else: music_field.title = f"I'm not playing anything!" music_field.add_field( name= f"If I'm not playing anything what am I supposed to send you?", value=f"*Who's the ape now, huh.*") await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="addToPlaylist") @commands.command() async def addToPlaylist(self, ctx, name, *, song_name=None): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute("SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) songs = self.songs_from_string( conn.execute( f"SELECT queued_songs FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][0]) song_to_save = "" if current_song == {} and song_name is None: music_field.add_field(name=f"You have to specify what song!", value=f"I can't add nothing to playlist..") else: if song_name == None: song_to_save = f"{current_song['link']}|" elif song_name.lower() == "queue": for song in self.songs: song_to_save += f"{song['link']}|" song_to_save += f"{current_song['link']}|" else: info = await self.get_audio_info(song_name, ctx.message.author) song_to_save += f"{info['link']}|" if len( conn.execute( f"SELECT * FROM playlists WHERE name = '{name}' AND user_id = '{ctx.author.id}'" ).fetchall()) == 0: conn.execute("INSERT INTO playlists VALUES(NULL, ?, ?, ?)", (ctx.author.id, name, song_to_save)) conn.commit() if song_name == None: music_field.add_field( name= f"`{name}` playlist created! I added `{current_song['title']}` into it for you.", value= f"You can add songs to your playlist using `{get_prefix(self.bot, ctx.message)}addToPlaylist {name} song`" ) elif song_name.lower() == "queue": music_field.add_field( name= f"New playlist named `{name}` created! And your queue added into it", value= f"You can play your playlist using `{get_prefix(self.bot, ctx.message)}playPlaylist {name}` or you can add songs to your queue, use `{get_prefix(self.bot, ctx.message)}addToPlaylist {name} queue` to update it" ) else: music_field.add_field( name= f"Created new playlist named `{name}` and added `{info['title']}` into it", value= f"You can play your playlist using `{get_prefix(self.bot, ctx.message)}playPlaylist {name}` or you can add songs to your queue, use `{get_prefix(self.bot, ctx.message)}addToPlaylist {name} queue` to update it" ) else: songs_in_playlist = conn.execute( f"SELECT songs FROM playlists WHERE user_id = '{ctx.author.id}' AND name = '{name}'" ).fetchall()[0][0] conn.execute( f"UPDATE playlists SET songs = '{songs_in_playlist + song_to_save}' WHERE user_id = '{ctx.author.id}' AND name = '{name}'" ) conn.commit() if song_name == None: music_field.add_field( name= f"Added your currently playing song named `{current_song['title']}` into your playlist `{name}`", value= f"You can play it using `{get_prefix(self.bot, ctx.message)}playPlaylist`" ) else: music_field.add_field( name= f"Added `{info['title']}` into your playlist named `{name}`", value= f"That's nice song you got there, {ctx.author.mention}!" ) conn.close() await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="updatePlaylist") @commands.command() async def updatePlaylist(self, ctx, name): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute("SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) songs = self.songs_from_string( conn.execute( f"SELECT queued_songs FROM music WHERE guild_id = {ctx.guild.id}" ).fetchall()[0][0]) playlists = conn.execute( f"SELECT * FROM playlists WHERE name = '{name}' AND user_id = '{ctx.author.id}'" ).fetchall() if len(playlists) == 0: music_field.add_field( name=f"Couldn't find any playlists under the name `{name}`", value= f"But you can create it! Using `{get_prefix(self.bot, ctx.message)}addToPlaylist {name} song`" ) else: songs_to_save = f"{current_song['link']}|" for song in songs: songs_to_save += f"{song['link']}|" conn.execute( f"UPDATE playlists SET songs = '{songs_to_save}' WHERE name = '{name}' AND user_id = '{ctx.author.id}'" ) conn.commit() music_field.add_field( name=f"Updated playlist `{name}` according to your queue", value= f"You can now play the updated version using `{get_prefix(self.bot, ctx.message)}playPlaylist {name}`" ) conn.close() await ctx.send(embed=music_field) #@cog_ext.cog_slash(name="playPlaylist") @commands.command() async def playPlaylist(self, ctx, name): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") if len(ctx.message.mentions) == 0: data = conn.execute( f"SELECT * FROM playlists WHERE name = '{name}'").fetchall() else: data = conn.execute( f"SELECT * FROM playlists WHERE name = '{name}' user_id = '{ctx.message.mentions[0].id}'" ).fetchall() if len(data) != 0: songs = list(filter(None, data[0][3].split("|"))) if not ctx.voice_client: await ctx.author.voice.channel.connect() if not ctx.voice_client.is_playing( ) and not ctx.voice_client.is_paused(): self.write_to_db( ctx, await self.get_audio_info(songs.pop(0), ctx.message.author.id)) self.play_audio(ctx, inform=False) await self.inform_user(ctx) songs_to_write = [] if songs: for song in songs: songs_to_write.append(await self.get_audio_info( song, ctx.message.author.id)) self.write_to_db_multiple(ctx, songs_to_write) music_field.add_field( name=f"Replaced your queue with songs from playlist `{name}`", value= f"If you add any songs to your queue, you can update your playlist using `{get_prefix(self.bot, ctx.message)}addToPlaylist {name} update`" ) else: music_field.add_field( name=f"I couldn't find any playlist under name `{name}`", value= f"Don't worry, you can always create a new one with this name using `{get_prefix(self.bot, ctx.message)}addToPlaylist {name} song`" ) conn.close() await ctx.send(embed=music_field) @commands.command() async def lyrics(self, ctx): music_field = discord.Embed(colour=discord.Colour(0xFDED32)) music_field.set_author(name="𝓜𝓾𝓼𝓲𝓬") conn = sqlite.connect("data/internal.db") current_song = self.song_from_string( conn.execute("SELECT current_song FROM music WHERE guild_id = ?", (ctx.guild.id, )).fetchall()[0][0]) conn.close() # 'track': song[1], 'title': song[2], 'artist': song[3], 'duration': song[4], 'likes': song[5], 'dislikes': song[6], 'link': song[7], 'author': song[8] title = current_song['title'] strings_to_erase = re.findall(r"([([].+?[])])", title) for string in strings_to_erase: print(string) title = title.replace(string, '') music_field.title = f"Lyrics for {title}" lyrics = self.lyrics_finder.search_song(title).lyrics words = list(filter(None, re.split(r"[[].+?[]]", lyrics))) titles = list(filter(None, re.findall(r"[[].+?[]]", lyrics))) for i in range(len(titles)): music_field.add_field(name=f"{titles[i]}", value=f"{words[i]}", inline=False) #music_field.remove_field(index=0) await ctx.send(embed=music_field)