Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 0.8.5 #44

Merged
merged 2 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"seaplayer/objects/Notification.py": "seaplayer/objects/",
"seaplayer/objects/ProgressBar.py": "seaplayer/objects/",
"seaplayer/objects/Radio.py": "seaplayer/objects/",
"seaplayer/objects/PopUp.py": "seaplayer/objects/",
# * 1.2) Types
"seaplayer/types": "seaplayer/types/",
"seaplayer/types/__init__.py": "seaplayer/types/",
Expand Down
3 changes: 2 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

| Version | Date | Tag | Changelog |
| ------- | ---- | --- | --------- |
| [v0.8.4](https://github.com/romanin-rf/SeaPlayer/releases/tag/v0.8.4) | 11.12.2023 | **STABLE** | - Added widgets: `Rheostat`, `ClickableLabel`<br>- Added widget: Rheostat<br>- Added a new widget: `PopUp`<br>- Fixed all language<br>- More attempts to make `Confiturate` screen clearer<br>- Moved all `CSS` from `objects.tcss` to `DEFAULT_CSS` separately for each widget |
| [v0.8.5](https://github.com/romanin-rf/SeaPlayer/releases/tag/v0.8.5) | 16.12.2023 | **STABLE** | - Added support for **python3.8**<br>- Added `on_ready` abstract methods for plugins<br>- Added new widgets: `PopUpWindow`, `WaitButton`<br>- Fixed method `add_sounds_to_list`<br>- Fixed `seaplayer.plug.cli`<br>- Fixed `build.py`<br>- Updated all child custom modules |
| [v0.8.4](https://github.com/romanin-rf/SeaPlayer/releases/tag/v0.8.4) | 11.12.2023 | **DEPRECATED** | - Added widgets: `Rheostat`, `ClickableLabel`<br>- Added widget: Rheostat<br>- Added a new widget: `PopUp`<br>- Fixed all language<br>- More attempts to make `Confiturate` screen clearer<br>- Moved all `CSS` from `objects.tcss` to `DEFAULT_CSS` separately for each widget |
| [v0.8.3](https://github.com/romanin-rf/SeaPlayer/releases/tag/v0.8.3) | 10.12.2023 | **STABLE** | - Added plugin `VKMusic`<br>- Added priority system for codecs<br>- Added system handhers of value<br>- Fixed `build.py`<br>- Moved method `load_plugin_info` in `seaplayer.plug.pluginloader` |
| [v0.8.2](https://github.com/romanin-rf/SeaPlayer/releases/tag/v0.8.2) | 08.12.2023 | **STABLE** | - Added language merge (for translating plugins)<br>- Fixed in translation files (`Log Menu Enable` -> `Logging` )<br>- Changed `object.css` (classes will no longer be used to specify standard properties)<br>- Improved widget `FillLabel` |
| [v0.8.1](https://github.com/romanin-rf/SeaPlayer/releases/tag/v0.8.1) | 07.12.2023 | **STABLE** | - Revisioned of the LanguageLoader<br>- Added new language: `Українська` |
Expand Down
76 changes: 65 additions & 11 deletions plugins/VKMusic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import logging
from rich.console import Console
from rich.prompt import Prompt
from textual.widgets import Input, Label
from seaplayer.plug import PluginBase
from vkpymusic import Service, TokenReceiver
from seaplayer.objects import PopUpWindow, WaitButton
from .vkpymusic import Service, TokenReceiverAsync
# > Typing
from typing import Tuple
# > Local Imports
from .vkmcodec import VKMCodec
from .units import (
pcheck,
VKM_MAIN_PATTERN,
VKM_RANGE_PATTERN
)

Expand Down Expand Up @@ -37,24 +39,76 @@ def exist_token(self) -> bool:
def on_init(self) -> None:
self.configurated = self.exist_token()

def on_run(self) -> None:
async def __req_login_password(self) -> Tuple[str, str]:
lppw = PopUpWindow(
ilogin:=Input(placeholder="Login"),
ipassword:=Input(placeholder="Password", password=True),
elpb:=WaitButton("Log In"),
title="VKMusic Authentication"
)
await self.app.mount(lppw)
await elpb.wait_click()
login, password = ilogin.value, ipassword.value
await lppw.remove()
return login, password

async def __req_2fa(self) -> str:
cpw = PopUpWindow(
icode:=Input(placeholder="Code"),
ecb:=WaitButton("Enter"),
title="VKMusic Authentication"
)
await self.app.mount(cpw)
await ecb.wait_click()
code = icode.value
await cpw.remove()
return code

async def __req_capcha(self, url: str) -> str:
cpw = PopUpWindow(
Label(f"[link={url}]{url}[/link]"),
icapcha:=Input(placeholder="Capcha"),
ecb:=WaitButton("Enter"),
title="VKMusic Authentication"
)
await self.app.mount(cpw)
await ecb.wait_click()
code = icapcha
await cpw.remove()
return code

async def __req_invalid_client(self) -> None:
pass

async def __req_critical_error(self) -> None:
pass

async def __init_service__(self) -> None:
if self.configurated:
self.service = Service.parse_config()
else:
login, password = Prompt.ask("Login"), Prompt.ask("Password", password=True)
while not self.configurated:
tr = TokenReceiver(login, password)
if tr.auth(on_2fa=lambda: Prompt.ask("Code 2FA")):
login, password = await self.__req_login_password()
tr = TokenReceiverAsync(login, password)
if await tr.auth(
self.__req_capcha,
self.__req_2fa,
self.__req_invalid_client,
self.__req_critical_error
):
tr.save_to_config()
self.configurated = True
else:
console.print("[red]Failed to get a token, repeat...[/red]")
self.app.error("Failed to get a token, repeat...")
self.service = Service.parse_config()
self.app.info(f"Service is worked: {repr(self.service)}")
# ! Registration
self.app.CODECS_KWARGS["vkm_service"] = self.service
# ? Registration
self.app.CODECS_KWARGS.update({"vkm_service": self.service})
self.add_value_handlers(vkm_value_handler)
self.add_codecs(VKMCodec)

async def on_ready(self):
self.app.run_worker(self.__init_service__, group=self.info.name_id)

# ! Registeration
__plugin__ = VKMusic
__plugin__ = VKMusic
2 changes: 1 addition & 1 deletion plugins/VKMusic/info.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "VK Music",
"name_id": "seaplayer.plugins.vk.music",
"version": "0.2.0",
"version": "0.3.0.dev1",
"author": "Romanin",
"description": "Music downloader from VK.",
"url": "https://github.com/romanin-rf/SeaPlayer"
Expand Down
2 changes: 1 addition & 1 deletion plugins/VKMusic/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
vkpymusic>=2.2.4
vbml>=1.1
vbml>=1.1
2 changes: 1 addition & 1 deletion plugins/VKMusic/vkmcodec.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import asyncio
from vkpymusic import Service
from .vkpymusic import Service
from seaplayer.codecs.URLS import URLSoundCodec
from seaplayer.codecs.AnySound import AnySound
# > Typing
Expand Down
14 changes: 14 additions & 0 deletions plugins/VKMusic/vkpymusic/Client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Client:
def __init__(self, user_agent, client_id, client_secret):
self.user_agent = user_agent
self.client_id = client_id
self.client_secret = client_secret


KateMobile = Client(
user_agent='KateMobileAndroid/56 lite-460 (Android 4.4.2; SDK 19; x86; unknown Android SDK built for x86; en)',
client_id='2685278',
client_secret='lxhD8OD7dMsqtXIm5IUY'
)

clients = {'Kate': KateMobile}
39 changes: 39 additions & 0 deletions plugins/VKMusic/vkpymusic/Logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import os, datetime, logging


class bcolors:
CRITICAL = "\033[95m"
OKBLUE = "\033[94m"
OKCYAN = "\033[96m"
OKGREEN = "\033[92m"
WARNING = "\033[93m"
ERROR = "\033[91m"
ENDC = "\033[0m"


_log_format = "%(asctime)s | [%(name)s | (%(filename)s) .%(funcName)s(%(lineno)d)] [%(levelname)s] %(message)s"


def get_file_handler():
file_path = f"logs/vkpymusic_{datetime.date.today()}.log"
os.makedirs(os.path.dirname(file_path), exist_ok=True)

file_handler = logging.FileHandler(file_path)
file_handler.setLevel(logging.WARNING)
file_handler.setFormatter(logging.Formatter(_log_format))
return file_handler


def get_stream_handler():
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(logging.Formatter(_log_format))
return stream_handler


def get_logger(name):
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
logger.addHandler(get_file_handler())
logger.addHandler(get_stream_handler())
return logger
32 changes: 32 additions & 0 deletions plugins/VKMusic/vkpymusic/Playlist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Playlist:
def __init__(
self, title, description, photo, count, owner_id, playlist_id, access_key
):
self.title = title
self.description = description
self.photo = photo
self.count = count
self.owner_id = owner_id
self.playlist_id = playlist_id
self.access_key = access_key

def __str__(self):
return f"{self.title} ({self.count} tracks)"

def to_dict(self) -> dict:
return self.__dict__

@classmethod
def from_json(cls, item):
title = str(item["title"])
description = str(item["description"])
photo = str(item["photo"]["photo_1200"])
count = int(item["count"])
owner_id = int(item["owner_id"])
playlist_id = int(item["id"])
access_key = str(item["access_key"])

playlist = cls(
title, description, photo, count, owner_id, playlist_id, access_key
)
return playlist
Loading
Loading