diff --git a/app.json b/app.json index 8d96140..defb99b 100644 --- a/app.json +++ b/app.json @@ -13,7 +13,7 @@ }, "addons": [ { - "plan": "heroku-postgresql" + "plan": "heroku-redis" } ], "buildpacks": [ diff --git a/hikka/database.py b/hikka/database.py index be81522..ceac072 100755 --- a/hikka/database.py +++ b/hikka/database.py @@ -15,14 +15,14 @@ import time import asyncio try: - import psycopg2 + import redis except ImportError as e: if "DYNO" in os.environ: raise e - POSTGRE_AVAILABLE = False + REDIS_AVAILABLE = False else: - POSTGRE_AVAILABLE = True + REDIS_AVAILABLE = True from typing import Any, Union @@ -50,7 +50,7 @@ class Database(dict): _revisions = [] _assets = None _me = None - _postgre = None + _redis = None _saving_task = None def __init__(self, client): @@ -60,59 +60,49 @@ class Database(dict): def __repr__(self): return object.__repr__(self) - def _postgre_save_sync(self): - self._postgre.execute( - "DELETE FROM hikka WHERE id = %s; INSERT INTO hikka (id, data) VALUES (%s, %s);", - (self._client._tg_id, self._client._tg_id, json.dumps(self)), - ) - self._postgre.connection.commit() + def _redis_save_sync(self): + self._redis.set(str(self._client._tg_id), json.dumps(self, ensure_ascii=True)) - async def postgre_force_save(self) -> bool: - """Force save database to postgresql without waiting""" - if not self._postgre: + async def redis_force_save(self) -> bool: + """Force save database to redis without waiting""" + if not self._redis: return False - await utils.run_sync(self._postgre_save_sync) - logger.debug("Published db to PostgreSQL") + await utils.run_sync(self._redis_save_sync) + logger.debug("Published db to Redis") return True - async def _postgre_save(self) -> bool: - """Save database to postgresql""" - if not self._postgre: + async def _redis_save(self) -> bool: + """Save database to redis""" + if not self._redis: return False await asyncio.sleep(5) - await utils.run_sync(self._postgre_save_sync) + await utils.run_sync(self._redis_save_sync) - logger.debug("Published db to PostgreSQL") + logger.debug("Published db to Redis") self._saving_task = None return True - async def postgre_init(self) -> bool: - """Init postgresql database""" - if not POSTGRE_AVAILABLE: - logger.critical("Attempted to initialize postgresql database, but psycopg2 is not installed") # fmt: skip + async def redis_init(self) -> bool: + """Init redis database""" + if not REDIS_AVAILABLE: + logger.critical("Attempted to initialize redis database, but it is not installed") # fmt: skip return False - POSTGRE_URI = os.environ.get("DATABASE_URL") or main.get_config_key( - "postgre_uri" - ) + REDIS_URI = os.environ.get("REDIS_URL") or main.get_config_key("redis_uri") - if not POSTGRE_URI: + if not REDIS_URI: return False - conn = psycopg2.connect(POSTGRE_URI, sslmode="require") - - cur = conn.cursor() - cur.execute("CREATE TABLE IF NOT EXISTS hikka (id integer, data text);") - self._postgre = cur + self._redis = redis.from_url(REDIS_URI) async def init(self): """Asynchronous initialization unit""" - if os.environ.get("DATABASE_URL") or main.get_config_key("postgre_uri"): - await self.postgre_init() + if os.environ.get("REDIS_URL") or main.get_config_key("redis_uri"): + await self.redis_init() self._db_path = os.path.join(DATA_DIR, f"config-{self._client._tg_id}.json") self.read() @@ -163,15 +153,11 @@ class Database(dict): def read(self): """Read database and stores it in self""" - if self._postgre: + if self._redis: try: - self._postgre.execute( - "SELECT data FROM hikka WHERE id=%s;", - (self._client._tg_id,), - ) - self.update(**json.loads(self._postgre.fetchall()[0][0])) + self.update(**json.loads(self._redis.get(str(self._client._tg_id)))) except Exception: - logger.exception("Error reading postgresql database") + logger.exception("Error reading redis database") else: return @@ -235,9 +221,9 @@ class Database(dict): while len(self._revisions) > 15: self._revisions.pop() - if self._postgre: + if self._redis: if not self._saving_task: - self._saving_task = asyncio.ensure_future(self._postgre_save()) + self._saving_task = asyncio.ensure_future(self._redis_save()) return True try: diff --git a/hikka/heroku.py b/hikka/heroku.py index 9f65ae1..464c1e3 100644 --- a/hikka/heroku.py +++ b/hikka/heroku.py @@ -43,9 +43,9 @@ def publish( ) if not any( - addon.plan.name.startswith("heroku-postgresql") for addon in app.addons() + addon.plan.name.startswith("heroku-redis") for addon in app.addons() ): - app.install_addon("heroku-postgresql") + app.install_addon("heroku-redis") repo = get_repo() url = app.git_url.replace("https://", f"https://api:{key}@") @@ -115,3 +115,8 @@ def init(): """Will be run on every Heroku start""" # Create repo if not found get_repo() + app = get_app()[0] + if not any( + addon.plan.name.startswith("heroku-redis") for addon in app.addons() + ): + app.install_addon("heroku-redis") diff --git a/hikka/modules/python.py b/hikka/modules/python.py index 50e253d..49cc662 100755 --- a/hikka/modules/python.py +++ b/hikka/modules/python.py @@ -115,10 +115,10 @@ class PythonMod(loader.Module): except Exception: exc = format_exc().replace(self._phone, "📵") - if os.environ.get("DATABASE_URL"): + if os.environ.get("REDIS_URL"): exc = exc.replace( - os.environ.get("DATABASE_URL"), - "postgre://**************************", + os.environ.get("REDIS_URL"), + "redis://**************************", ) if os.environ.get("hikka_session"): @@ -142,10 +142,10 @@ class PythonMod(loader.Module): ) ret = ret.replace(str(self._phone), "📵") - if os.environ.get("DATABASE_URL"): + if os.environ.get("REDIS_URL"): ret = ret.replace( - os.environ.get("DATABASE_URL"), - "postgre://**************************", + os.environ.get("REDIS_URL"), + "redis://**************************", ) if os.environ.get("hikka_session"): diff --git a/hikka/modules/test.py b/hikka/modules/test.py index b27f5e5..a0016ad 100755 --- a/hikka/modules/test.py +++ b/hikka/modules/test.py @@ -340,10 +340,10 @@ class TestMod(loader.Module): f'{hikka_token.split("_")[0]}_********************************', ) - if os.environ.get("DATABASE_URL"): + if os.environ.get("REDIS_URL"): logs = logs.replace( - os.environ.get("DATABASE_URL"), - "postgre://**************************", + os.environ.get("REDIS_URL"), + "redis://**************************", ) if os.environ.get("hikka_session"): diff --git a/hikka/modules/updater.py b/hikka/modules/updater.py index e4325ec..b46f24d 100755 --- a/hikka/modules/updater.py +++ b/hikka/modules/updater.py @@ -180,7 +180,7 @@ class UpdaterMod(loader.Module): return if "DYNO" in os.environ: - await self._db.postgre_force_save() + await self._db.redis_force_save() app = heroku.get_app(api_token=main.hikka.api_token)[0] app.restart() return @@ -294,7 +294,7 @@ class UpdaterMod(loader.Module): if "DYNO" in os.environ: await utils.answer(msg_obj, self.strings("heroku_update")) await self.process_restart_message(msg_obj) - await self._db.postgre_force_save() + await self._db.redis_force_save() heroku.publish(api_token=main.hikka.api_token, create_new=False) return diff --git a/requirements.txt b/requirements.txt index 91b6a5d..5ebf2f0 100755 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,6 @@ requests==2.27.1 aiogram==2.19 grapheme==0.6.0 heroku3==5.1.4 -psycopg2-binary==2.9.3 +redis==3.5.3 # Python 3.8+