Skeleton of project - database loading

This commit is contained in:
BarsTiger
2023-02-13 19:51:25 +02:00
commit f778d3f71c
23 changed files with 348 additions and 0 deletions

2
bot/db/__init__.py Normal file
View File

@@ -0,0 +1,2 @@
from .db import db
from .db_model import DBTables

12
bot/db/db.py Normal file
View File

@@ -0,0 +1,12 @@
import os.path
from bot.config import DB
from .db_model import DBDict
if not os.path.isfile(DB):
open('sync', 'w')
db = {
'config': DBDict(DB, autocommit=True, tablename='config'),
'cooldown': DBDict(DB, autocommit=True, tablename='cooldown')
}

32
bot/db/db_model.py Normal file
View File

@@ -0,0 +1,32 @@
from sqlitedict import SqliteDict
from bot.common import bot
from bot.config import DB_CHAT, DB
from aiogram.types import InputFile, InputMediaDocument
from aiogram.utils.exceptions import MessageToEditNotFound
import time
from .meta import DBMeta
class DBTables:
tables = ['config', 'cooldown']
config = "config"
cooldown = "cooldown"
class DBDict(SqliteDict):
async def write(self):
try:
DBMeta()[DBMeta.update_time] = time.time_ns()
await bot.edit_message_media(media=InputMediaDocument(InputFile(DB)),
chat_id=DB_CHAT, message_id=DBMeta()[DBMeta.message_id])
await bot.edit_message_caption(
caption=DBMeta(), chat_id=DB_CHAT, message_id=DBMeta()[DBMeta.message_id]
)
except MessageToEditNotFound:
DBMeta()[DBMeta.update_time] = time.time_ns()
self['db_message_id'] = (await bot.send_document(chat_id=DB_CHAT, document=InputFile(DB),
disable_notification=True)).message_id
DBMeta()[DBMeta.message_id] = self['db_message_id']
await bot.edit_message_caption(
caption=DBMeta(), chat_id=DB_CHAT, message_id=self.get('db_message_id')
)

72
bot/db/meta.py Normal file
View File

@@ -0,0 +1,72 @@
import os.path
from bot.config import DBMETA, BARS_APP_ID, DB_CHAT
from bot.common import bot
from aiogram.utils.exceptions import MessageToForwardNotFound
class DBMeta:
app_id = "app_id"
message_id = "message_id"
update_time = "update_time"
def __init__(self):
if not os.path.isfile(DBMETA):
open(DBMETA, 'w').write(f'{BARS_APP_ID}|None|0')
def __getitem__(self, item):
try:
return open(DBMETA).read().split('|')[{
"app_id": 0,
"message_id": 1,
"update_time": 2
}.get(item)]
except TypeError:
return None
def __setitem__(self, key, value):
meta = open(DBMETA).read().split('|')
meta[{
"app_id": 0,
"message_id": 1,
"update_time": 2
}[key]] = value
open(DBMETA, 'w').write('|'.join(str(x) for x in meta))
def __str__(self):
return open(DBMETA).read()
class CloudMeta:
app_id = "app_id"
message_id = "message_id"
update_time = "update_time"
@staticmethod
async def get(item):
try:
try:
if not DBMeta()[DBMeta.update_time] or not bot.cloudmeta_message_text:
raise AttributeError
except AttributeError:
try:
message = await bot.forward_message(DB_CHAT, DB_CHAT, DBMeta()[DBMeta.message_id])
bot.cloudmeta_message_text = message.caption
await message.delete()
except MessageToForwardNotFound:
print('Cannot get CloudMeta - writing DBDict')
from .db_model import DBDict
await DBDict().write()
message = await bot.forward_message(DB_CHAT, DB_CHAT, DBMeta()[DBMeta.message_id])
bot.cloudmeta_message_text = message.caption
await message.delete()
cloudmeta = bot.cloudmeta_message_text.split('|')
return cloudmeta[{
"app_id": 0,
"message_id": 1,
"update_time": 2
}.get(item)]
except TypeError:
return None

49
bot/db/pull_db.py Normal file
View File

@@ -0,0 +1,49 @@
import os
from .meta import DBMeta, CloudMeta
from bot.common import bot
from bot.config import DB, DB_CHAT
from .db_model import DBTables
from sqlitedict import SqliteDict
async def pull():
if DBMeta()[DBMeta.message_id] == 'None':
from .db import db
print('No dbmeta file')
if msg_id := db[DBTables.config].get('db_message_id'):
print('Found message id in in-db config')
DBMeta()[DBMeta.message_id] = msg_id
await db[DBTables.config].write()
if not os.path.isfile('sync'):
try:
if not bot.cloudmeta_message_text:
print('No cloudmeta initialized')
raise AttributeError
else:
return
except AttributeError:
if int(DBMeta()[DBMeta.update_time]) >= int(await CloudMeta.get(CloudMeta.update_time)):
print('First database pulling for this instance - DB is up-to-date')
return
else:
print('Database file is new. Trying to download cloud data')
os.remove('sync')
print('DB is not up-to-date')
message = await bot.forward_message(DB_CHAT, DB_CHAT, DBMeta()[DBMeta.message_id])
await message.delete()
await message.document.download(destination_file=DB + 'b')
from .db import db
for table in DBTables.tables:
db[table].clear()
new_table = SqliteDict(DB + 'b', tablename=table)
for key in new_table.keys():
db[table][key] = new_table[key]
new_table.close()
print('Loaded database from cloud')