4
1
Fork 1

Compare commits

...

2 Commits

Author SHA1 Message Date
trueold89 c2ab00680f
Add InitBuilder 2024-08-06 14:59:50 +03:00
trueold89 697dac6922
Rewrite CacheDB && Implements UserStates 2024-08-06 13:59:44 +03:00
7 changed files with 215 additions and 107 deletions

View File

@ -7,7 +7,7 @@
# Imports # Imports
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from tubot.static.abc import IValidatable from tubot.static.abc import IValidatable
from tubot.db.types import CacheDBTypes, UserStates from tubot.db.types import CacheDBTypes, User
class CacheDB(IValidatable, ABC): class CacheDB(IValidatable, ABC):
@ -24,50 +24,22 @@ class CacheDB(IValidatable, ABC):
# Users # Users
@abstractmethod @abstractmethod
async def add_user(self, tg_id: int, name: str) -> None: async def write_user(self, tg_id: int, user: User) -> None:
""" """
Add user to cache db Writes user to cache db
:param tg_id: User telegram id :param tg_id: User telegram id
:param name: User telegram name :param user: User object
""" """
raise NotImplementedError raise NotImplementedError
@abstractmethod @abstractmethod
async def user_state(self, tg_id: int) -> UserStates: async def read_user(self, tg_id: int) -> User:
""" """
Get user state Writes user to cache db
:param tg_id: User telegram id
:return: Status of user
"""
raise NotImplementedError
@abstractmethod
async def change_user_state(self, tg_id: int, status: UserStates) -> None:
"""
Change user state
:param tg_id: User telegram id
:param status: New user status
"""
raise NotImplementedError
@abstractmethod
async def auth_user(self, tg_id: int) -> None:
"""
Auth user
:param tg_id: User telegram id
"""
raise NotImplementedError
@abstractmethod
async def is_user_auth(self, tg_id: int) -> bool:
"""
Check if user is already auth
:param tg_id: User telegram id :param tg_id: User telegram id
:return: User object
""" """
raise NotImplementedError raise NotImplementedError

View File

@ -60,38 +60,13 @@ class PythonCache(CacheDB):
# Users # Users
async def add_user(self, tg_id: int, name: str) -> None: async def write_user(self, tg_id: int, user: User) -> None:
if tg_id in tuple(self.users.keys()): self.users[tg_id] = user.to_dict
raise ValueError("User already exists")
user = User(tg_id, name)
self.users[tg_id] = user.dict
await self._save_pkl() await self._save_pkl()
async def user_state(self, tg_id: int) -> UserStates: async def read_user(self, tg_id: int) -> User:
if tg_id not in tuple(self.users.keys()): user_data = self.users[tg_id]
raise ValueError("User doesn't exists") return User.from_dict(user_data)
user = self.users[tg_id]
return user["state"]
async def change_user_state(self, tg_id: int, status: UserStates) -> None:
if tg_id not in tuple(self.users.keys()):
raise ValueError("User doesn't exists")
user = self.users[tg_id]
user["state"] = status
await self._save_pkl()
async def auth_user(self, tg_id: int) -> None:
if tg_id not in tuple(self.users.keys()):
raise ValueError("User doesn't exists")
user = self.users[tg_id]
user["auth"] = True
await self._save_pkl()
async def is_user_auth(self, tg_id: int) -> bool:
if tg_id not in tuple(self.users.keys()):
raise ValueError("User doesn't exists")
user = self.users[tg_id]
return user["auth"]
# Dirs # Dirs
@ -125,49 +100,21 @@ class RedisCache(CacheDB):
# Users # Users
async def add_user(self, tg_id: int, name: str) -> None: async def write_user(self, tg_id: int, user: User) -> None:
async with aioredis.from_url( async with aioredis.from_url(
f"redis://{self.host}", encoding="utf-8", decode_responses=True f"redis://{self.host}", encoding="utf-8", decode_responses=True
) as redis: ) as redis:
user = User(tg_id, name) json = json_dumps(user.to_dict)
json = json_dumps(user.dict)
await redis.set(str(tg_id), json) await redis.set(str(tg_id), json)
async def user_state(self, tg_id: int) -> UserStates: async def read_user(self, tg_id: int) -> User:
async with aioredis.from_url( async with aioredis.from_url(
f"redis://{self.host}", encoding="utf-8", decode_responses=True f"redis://{self.host}", encoding="utf-8", decode_responses=True
) as redis: ) as redis:
json = await redis.get(str(tg_id)) json = await redis.get(str(tg_id))
user = json_loads(json) user_data = json_loads(json)
return user["state"] user_data["state"] = UserStates(user_data["state"])
return User.from_dict(user_data)
async def change_user_state(self, tg_id: int, status: UserStates) -> None:
async with aioredis.from_url(
f"redis://{self.host}", encoding="utf-8", decode_responses=True
) as redis:
json = await redis.get(str(tg_id))
user = json_loads(json)
user["state"] = status
json = json_dumps(user)
await redis.set(str(tg_id), json)
async def auth_user(self, tg_id: int) -> None:
async with aioredis.from_url(
f"redis://{self.host}", encoding="utf-8", decode_responses=True
) as redis:
json = await redis.get(str(tg_id))
user = json_loads(json)
user["auth"] = True
json = json_dumps(user)
await redis.set(str(tg_id), json)
async def is_user_auth(self, tg_id: int) -> bool:
async with aioredis.from_url(
f"redis://{self.host}", encoding="utf-8", decode_responses=True
) as redis:
json = await redis.get(str(tg_id))
user = json_loads(json)
return bool(user["auth"])
# Dirs # Dirs

View File

@ -22,7 +22,9 @@ class UserStates(Enum):
Types of User status Types of User status
""" """
... IDLE = "IDLE"
DIRS = "DIRS"
WAIT_FOR_TORRENT = "WAIT_FOR_TORRENT"
class User(object): class User(object):
@ -32,11 +34,15 @@ class User(object):
tg_id: int tg_id: int
name: str name: str
state: UserStates | None = None state: UserStates = UserStates.IDLE
auth: bool = False auth: bool = False
def __init__( def __init__(
self, tg_id: int, name: str, state: UserStates | None = None, auth: bool = False self,
tg_id: int,
name: str,
state: UserStates = UserStates.IDLE,
auth: bool = False,
) -> None: ) -> None:
self.tg_id = tg_id self.tg_id = tg_id
self.name = name self.name = name
@ -44,10 +50,18 @@ class User(object):
self.auth = auth self.auth = auth
@property @property
def dict(self): def to_dict(self):
return { return {
"tg_id": self.tg_id, "tg_id": self.tg_id,
"name": self.name, "name": self.name,
"state": self.state, "state": self.state.value,
"auth": self.auth, "auth": self.auth,
} }
@classmethod
def from_dict(cls, usr: dict) -> "User":
tg = usr["tg_id"]
name = usr["name"]
state = UserStates(usr["state"])
auth = usr["auth"]
return cls(tg, name, state, auth)

View File

@ -13,5 +13,5 @@ class GetterTypes(Enum):
Types of getters Types of getters
""" """
OS = "Python os module" OS = "os"
Jellyfin = "Jelyfin API" Jellyfin = "jellyfin"

View File

@ -24,3 +24,84 @@ class REDIS_HOST(ENV):
_name = "REDIS_HOST" _name = "REDIS_HOST"
DEFAULT = "localhost:6379" DEFAULT = "localhost:6379"
class CACHE_TYPE(ENV):
"""
CacheDB Type
"""
_name = "CACHE_TYPE"
DEFAULT = "python"
class DIR_GETTER(ENV):
"""
DirGetter Type
"""
_name = "DIR_GETTER"
DEFAULT = "os"
class DG_OS_FOLDER(ENV):
"""
Path to parent directory for OS_DirGetter
"""
_name = "DG_OS_FOLDER"
DEFAULT = "/mnt/Media"
class DG_JELLYFIN_HOST(ENV):
"""
Jellyfin Server API host
"""
_name = "DG_JELLYFIN_HOST"
DEFAULT = "http://localhost:8096"
class DG_JELLYFIN_TOKEN(ENV):
"""
Jellyfin API key
"""
_name = "DG_JELLYFIN_TOKEN"
DEFAULT = ""
class TORRENT_SERVER(ENV):
"""
Torrent Server Type
"""
_name = "TORRENT_SERVER"
DEFAULT = "qbit"
class TS_USER(ENV):
"""
Torrent Server auth username
"""
_name = "TS_USER"
DEFAULT = ""
class TS_PASSWORD(ENV):
"""
Torrent Server auth password
"""
_name = "TS_PASSWORD"
DEFAULT = ""
class TS_HOST(ENV):
"""
Torrent Server host
"""
_name = "TS_HOST"
DEFAULT = "http://localhost"

94
tubot/static/init.py Normal file
View File

@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
######################
# Init static module #
######################
# Imports
from typing import Iterable
from tubot.static import env
from tubot.static.functions import validate
from tubot.torrent.apis import qBitTorrent
from tubot.torrent.types import ServerTypes
from tubot.torrent.abc import TorrentAPI
from tubot.dirgetter.types import GetterTypes
from tubot.dirgetter.abc import DirGetter
from tubot.dirgetter.getter import OSGetter, Jellyfin
from tubot.db.types import CacheDBTypes
from tubot.db.abc import CacheDB
from tubot.db.cache import PythonCache, RedisCache
from asyncio import create_task, gather
class InitBuilder(object):
"""
Init all bot modules
"""
TORRENT_SERVER: ServerTypes | TorrentAPI
DG: GetterTypes | DirGetter
CACHE: CacheDBTypes | CacheDB
def set_torrent_server(self, server_type: ServerTypes) -> "InitBuilder":
self.TORRENT_SERVER = server_type
return self
def set_directory_getter(self, dg_type: GetterTypes) -> "InitBuilder":
self.DG = dg_type
return self
def set_cache_type(self, cache_type: CacheDBTypes) -> "InitBuilder":
self.CACHE = cache_type
return self
async def init_ts(self) -> None:
host = env.TS_HOST()()
user = env.TS_USER()()
pwd = env.TS_PASSWORD()()
match self.TORRENT_SERVER:
case ServerTypes.qBitTorrent:
self.TORRENT_SERVER = qBitTorrent(host, user, pwd)
case _:
raise TypeError
await validate(self.TORRENT_SERVER)
async def init_dg(self) -> None:
match self.DG:
case GetterTypes.OS:
base_dir = env.DG_OS_FOLDER()()
self.DG = OSGetter(base_dir)
case GetterTypes.Jellyfin:
host = env.DG_JELLYFIN_HOST()()
key = env.DG_JELLYFIN_TOKEN()()
self.DG = Jellyfin(host, key)
case _:
raise TypeError
await validate(self.DG)
async def init_cache(self) -> None:
match self.CACHE:
case CacheDBTypes.PythonPKL:
self.CACHE = PythonCache()
case CacheDBTypes.Redis:
host = env.REDIS_HOST()()
self.CACHE = RedisCache(host)
case _:
raise TypeError
await validate(self.CACHE)
async def init_all_modules(self) -> None:
tasks = (create_task(self.init_ts()), create_task(self.init_dg()), create_task(self.init_cache()))
await gather(*tasks)
@property
def tuple(self) -> Iterable:
return (self.TORRENT_SERVER, self.DG, self.CACHE)
async def init_modules() -> Iterable:
ts = ServerTypes(env.TORRENT_SERVER()())
dg = GetterTypes(env.DIR_GETTER()())
cache = CacheDBTypes(env.CACHE_TYPE()())
builder = InitBuilder().set_torrent_server(ts).set_directory_getter(dg).set_cache_type(cache)
await builder.init_all_modules()
return builder.tuple

View File

@ -24,7 +24,7 @@ class ServerTypes(Enum):
Types of Torrent servers API's Types of Torrent servers API's
""" """
qBitTorrent = "qBitTorrent Remote API" qBitTorrent = "qbit"
class TorrentFromServer(object): class TorrentFromServer(object):