# meta developer: @SunnexGB
# requires: aiohttp
# meta pic: https://r2.fakecrime.bio/uploads/f49a9294-36ad-4fc4-801f-48cb049111d6.jpg
# meta banner: https://r2.fakecrime.bio/uploads/f49a9294-36ad-4fc4-801f-48cb049111d6.jpg
# meta fhsdesc: Spotify, music, музыка, спотифай,Lyrics, слова, текст, трек, песня
# все же я не знаю трек или сонг, так что пусть будет трек, а не сонг потому что интуитивнее поняттнее,наверное?
# крутой баннер да?
#current version
__version__ = (1, 1, 2)
from herokutl.types import Message
from .. import loader, utils
from ..types import InlineCall
import aiohttp
import asyncio
import re
@loader.tds
class SpotifyLyrics(loader.Module):
"""life lyrics current song"""
strings = {
"name": "SpotifyLyrics",
"no_spotifymod": "{}",
"not_synced": "{}",
"not_synced": "{utils.escape_html(t)}")
return header + "\n".join(rows)
else:
return header + not_synced_str + f"
{utils.escape_html((plain or '')[:4000])}" def _markup(self, song_url): return [ [{"text": "🔗 song.link", "url": song_url}], [{"text": "❌ Close", "callback": self._close_cb}], ] async def _close_cb(self, call): for track_id, task in list(self._active_tasks.items()): task.cancel() self._active_tasks.pop(track_id, None) try: await call.answer() await call.delete() except Exception: pass async def run_loop(self, form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str): last_display = "" try: while True: pb = mod.sp.current_playback() if not pb or not pb.get("item") or pb["item"]["id"] != track_id: try: await form.edit( self.strings("finished"), reply_markup=[[{"text": "❌ Close", "callback": self._close_cb}]], ) except Exception: pass break prog = pb.get("progress_ms", 0) content = self._build_content( artist_name, track_name, lines, plain, prog, not_synced_str ) if content != last_display: try: await form.edit(content, reply_markup=self._markup(song_url)) last_display = content except Exception: break if not lines: break await asyncio.sleep(self.config["lyrics_delay"]) except asyncio.CancelledError: raise except Exception: pass finally: self._active_tasks.pop(track_id, None) @loader.command(ru_doc="- показать синхронизированный текст песни") async def snowlcmd(self, message: Message): """- show synchronized lyrics for current Spotify track""" mod = self.lookup("SpotifyMod") if not mod: form = await self.inline.form("⏳", message=message) await form.edit( self.strings("no_spotifymod"), reply_markup=[[{"text": "Install SpotifyMod", "callback": self.install_spotifymod}]], ) return acs_tkn = mod.get("acs_tkn") if not acs_tkn: await self.invoke("sauth", " ", "me") form = await self.inline.form("⏳", message=message) await form.edit( self.strings("no_auth"), reply_markup=[[{"text": "Хорошо", "callback": self.close}]], ) return playback = mod.sp.current_playback() if not playback or not playback.get("item"): return await utils.answer(message, self.strings("no_spotify")) track = playback["item"] track_id = track["id"] artist_name = track["artists"][0]["name"] track_name = track["name"] song_url = f"https://song.link/s/{track_id}" old = self._active_tasks.pop(track_id, None) if old: old.cancel() data = await self._get_lyrics(artist_name, track_name) if data and data.get("timeout"): return utils.answer( message, self.strings["timeout"] ) if not data or data.get("instrumental"): track_and_artist = f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}" return await utils.answer( message, self.strings("no_lyrics").format(track_and_artist), ) synced_raw = data.get("syncedLyrics") plain = data.get("plainLyrics", "") lines = self._parse_synced(synced_raw) if synced_raw else [] not_synced_str = self.strings("not_synced") prog = playback.get("progress_ms", 0) initial_content = self._build_content( artist_name, track_name, lines, plain, prog, not_synced_str ) form = await self.inline.form( text=initial_content, message=message, reply_markup=self._markup(song_url), ) task = asyncio.ensure_future( self.run_loop( form=form, mod=mod, track_id=track_id, artist_name=artist_name, track_name=track_name, song_url=song_url, lines=lines, plain=plain, not_synced_str=not_synced_str, ) ) self._active_tasks[track_id] = task