# meta developer: @SunnexGB
# requires: aiohttp
# meta pic: https://r2.fakecrime.bio/uploads/6725e5a0-0c9e-48ed-be85-dfd857c2aa5f.jpg
# meta banner: https://r2.fakecrime.bio/uploads/6725e5a0-0c9e-48ed-be85-dfd857c2aa5f.jpg
# meta fhsdesc: Spotify, YaMusic, music, музыка, Lyrics, слова, текст, трек, песня
__version__ = (1, 0, 0)
from herokutl.types import Message
from .. import loader, utils
from ..types import InlineCall
import aiohttp
import asyncio
import re
@loader.tds
class LiveLyrics(loader.Module):
"""life lyrics current song"""
strings = {
"name": "LiveLyrics",
"no_spotifymod": "{}",
"not_synced": "{}",
"not_synced": "{utils.escape_html(t)}")
return header + "\n".join(rows)
return header + not_synced_str + f"
{utils.escape_html((plain or '')[:4000])}" def build_keyboard(self, song_url): return [ [ {"text": self.strings["song_link"], "url": song_url} ], [ {"text": self.strings["close"], "callback": self.close_cb} ], ] async def close_cb(self, call: InlineCall): 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 za_loop_a(self, form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str, heroku_module: str): buffer_clipboard = "" try: while True: if heroku_module == "SpotifyMod": pb = mod.sp.current_playback() TrackEnded = not pb or not pb.get("item") or pb["item"]["id"] != track_id else: pb = await mod._YaMusicMod__get_now_playing() TrackEnded = not pb or not pb.get("track") or pb["track"]["track_id"] != track_id if TrackEnded: try: await form.edit( self.strings["TrackEnded"], reply_markup=[[{"text": self.strings["close"], "callback": self.close_cb}]], ) except Exception: pass break prog = pb.get("progress_ms", 0) content = self.build_lyrics(artist_name, track_name, lines, plain, prog, not_synced_str) if content != buffer_clipboard: try: await form.edit(content, reply_markup=self.build_keyboard(song_url)) buffer_clipboard = 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 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": self.strings["spotify_installed"], "callback": self.install_mod, "kwargs": {"heroku_module": "SpotifyMod"} } ] ], ) return if not mod.get("acs_tkn"): await self.invoke("sauth", " ", "me") form = await self.inline.form("⏳", message=message) await form.edit( self.strings["no_auth_spotify"], reply_markup=[[{"text": self.strings["ok"], "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 await utils.answer(message, self.strings["timeout"]) if not data or data.get("instrumental"): return await utils.answer( message, self.strings["no_lyrics"].format(f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}"), ) 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"] form = await self.inline.form( text=self.build_lyrics(artist_name, track_name, lines, plain, playback.get("progress_ms", 0), not_synced_str), message=message, reply_markup=self.build_keyboard(song_url), ) self._active_tasks[track_id] = asyncio.ensure_future( self.za_loop_a(form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str, heroku_module="SpotifyMod") ) @loader.command(ru_doc="- показать синхронизированный текст песни") async def ynowlcmd(self, message: Message): """- show synchronized lyrics for current track""" mod = self.lookup("YaMusic") if not mod: form = await self.inline.form("⏳", message=message) await form.edit( self.strings["no_yamusic"], reply_markup=[ [ { "text": "Install YaMusicMod", "callback": self.install_mod, "kwargs": {"heroku_module": "YaMusic"} } ] ], ) return if not mod.get("__config__")["token"]: await self.invoke("yguide", " ", "me") form = await self.inline.form("⏳", message=message) await form.edit( self.strings["no_auth_yamusic"], reply_markup=[[{"text": self.strings["ok"], "callback": self.close}]], ) return playback = await mod._YaMusicMod__get_now_playing() if not playback or not playback.get("track"): return await utils.answer(message, self.strings["no_ym"]) track = playback["track"] track_id = track["track_id"] artist_name = ", ".join(track["artist"]) track_name = track["title"] 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 await utils.answer(message, self.strings["timeout"]) if not data or data.get("instrumental"): return await utils.answer( message, self.strings["no_lyrics"].format(f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}"), ) 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"] form = await self.inline.form( text=self.build_lyrics(artist_name, track_name, lines, plain, playback.get("progress_ms", 0), not_synced_str), message=message, reply_markup=self.build_keyboard(song_url), ) self._active_tasks[track_id] = asyncio.ensure_future( self.za_loop_a(form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str, heroku_module="YaMusic") )