Open Steffo99 opened 3 years ago
Hi. Thanks for contributing to LyricsGenius. The if song_id is None
was meant to avoid fetching the song twice in case the user had provided a song ID. But as you mentioned, the song_id
is never None. I had a look and the same thing also happens in search_album
as well.
Although your solution solves the problem, now there will be a redundant request if the user provides a song_id
in the first place. I suggest keeping the if statement as it is, but moving it before song_id
gets overwritten.
As for the second part of your PR concerning the new fields, we were reluctant to add more fields because the value of some fields could be misleading. For example, what does a None value for Song.featured_video
mean? Does it mean the Song had no featured video, or it just wasn't in the request dict? That's why we avoided adding more fields to Song.
For the Song
fields, I can think of two ways:
get_full_info
altogether and update Song
to have all fields.or:
Song
into two types: SearchSong
and FullSong
.What do you think, @johnwmillr?
For example, what does a None value for Song.featured_video mean? Does it mean the Song had no featured video, or it just wasn't in the request dict? That's why we avoided adding more fields to Song.
Another solution might be to use Ellipsis
(...
) for values which weren't retrieved, allowing them to be distinguished from None
/null
values returned from the API.
Your PR is about ready. Just apply the change in the last conversation and remove the changes to song.py
.
@Allerter I've done as you asked.
I checked, and confirm that search_artists
isn't affected by this bug. (I found a few unused statements that I will probably fix in a future pull request.)
Thanks for your time!
@johnwmillr, could you please review and merge this?
@johnwmillr, could you please review and merge this?
Hi Dear @allerter I have the same error!!! If i deploy my telegram bot project to server i get 403 forbidden error but when i run local in PyCharm everything works This my Code:
import numpy as np
from requests.exceptions import HTTPError, Timeout
import lyricsgenius
from aiogram import types
from data.config import GENIUS_ACCESS_TOKEN,GENIUS_CLIENT_ID,GENIUS_CLIENT_SECRET,GENIUS_REDIRECT_URI
from keyboards.inline.SelectButton import SelectSong
from aiogram.types import CallbackQuery
from aiogram.dispatcher.filters import Command
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import FSMContext
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
from loader import dp
class OAuth2Genius(StatesGroup):
waiting_for_code = State()
GENIUS_API_BASE_URL = 'https://api.genius.com'
def create_genius_session(token=None, state=None):
client = BackendApplicationClient(client_id=GENIUS_CLIENT_ID)
genius3 = OAuth2Session(client=client, token=token, redirect_uri=GENIUS_REDIRECT_URI, state=state)
return genius3
@dp.message_handler(Command("start"))
async def start_auth(message: types.Message):
# Start the Genius OAuth2 flow
genius3 = create_genius_session()
authorization_url, state = genius3.authorization_url('https://api.genius.com/oauth/authorize')
await message.answer("To authorize, click on this [link]({})".format(authorization_url), parse_mode='Markdown')
await OAuth2Genius.waiting_for_code.set()
@dp.message_handler(state=OAuth2Genius.waiting_for_code)
async def receive_auth_code(message: types.Message, state: FSMContext):
# Receive the Genius OAuth2 code and exchange it for a token
genius3 = create_genius_session(state=state)
token = genius3.fetch_token('https://api.genius.com/oauth/token', authorization_response=message.text,
client_secret=GENIUS_CLIENT_SECRET)
# Save the token to use later in your requests
await state.finish()
await message.answer("Authorization successful! You can now use Genius API.")
# Store the token somewhere secure for future use (e.g., a database)
global genius2
genius2 = create_genius_session(token=token)
genius = lyricsgenius.Genius(GENIUS_ACCESS_TOKEN)
numbered_songs = []
@dp.message_handler()
async def Send_List(message: types.Message):
def ListOfSongs(search_songs):
try:
song = genius.search_songs(f"{search_songs}")
list_of_artist = []
list_of_song = []
for hit in song['hits']:
list_of_artist.append(hit['result']['primary_artist']['name'])
list_of_song.append(hit['result']['title'])
arr = np.dstack((list_of_artist, list_of_song))
len_arr = len(arr[0])
for res in arr[0][range(0, len_arr)]:
numbered_songs.append(f"{res[0]} - {res[1]}")
except HTTPError as e:
print(e.errno)
print(e.args[0])
print(e.args[1])
except Timeout:
pass
if len(numbered_songs) == 0:
ListOfSongs(search_songs=message.text)
else:
numbered_songs.clear()
ListOfSongs(search_songs=message.text)
result_count = min(len(numbered_songs), 10)
if result_count >= 1:
await message.answer(
f"<b>Результаты 1-{result_count}</b>\n\n"
+ "\n".join(f"{i + 1}. {numbered_songs[i]}" for i in range(result_count)),
reply_markup=SelectSong
)
else:
await message.answer("Такой песен не найдено 🤔")
@dp.callback_query_handler(lambda call: call.data.isdigit())
async def Send_Lyric(call: CallbackQuery):
index = int(call.data)
if 1 <= index <= len(numbered_songs):
await call.message.delete()
await call.message.answer("🔎 Ищу тексты песен...")
full_text = await GetText(numbered_songs[index - 1])
if full_text:
# Telegramning maksimal belgilar soni 4040 ta
if len(full_text) <= 4020:
await call.message.answer(full_text)
else:
short_text = full_text[:4020]
await call.message.answer(short_text + f"...\n\n<i>через @MusixMBot</i>")
else:
await call.message.answer("Извините, такого текста не найдено 🫥")
async def GetText(song_name):
artist_name, song_get_name = map(str.strip, song_name.split("-"))
try:
artist = genius.search_artist(artist_name, max_songs=1)
song_text = artist.song(song_get_name)
text = song_text.lyrics
return f"<code>{artist_name} - {song_get_name}</code>\n\n{text[:-5]}\n\n<i>через @MusixMBot</i>"
except HTTPError as e:
print(e.errno)
print(e.args[0])
print(e.args[1])
except Timeout:
pass
return None
I used the liyricsgenius package. But I don't know how to integrate Genius authentication method into Code. If anyone knows, please help!!!
Previously, the full song info wasn't fetched, as
song_id
never wasNone
, and the checkif song_id is None
stopped the retrieval from executing.I corrected that line, and added the new fields to the
Song
type; some of them should probably have a corresponding type too, but I don't currently have time to implement them right now.