mariadb -> postgres
This commit is contained in:
1 parent
21964fa986
commit
e51bb86dc0
36 files changed
+650
-464
No files matched your search
+12
-14
@@ -1,6 +1,6 @@
|
||||
|
||||
from app.core.models.base import AlchemyBase
|
||||
from sqlalchemy import Column, BigInteger, Integer, String, ForeignKey, DateTime, JSON, Boolean
|
||||
from sqlalchemy import Column, Integer, String, JSON, select
|
||||
|
||||
|
||||
class ServiceConfigValue(AlchemyBase):
|
||||
@@ -19,20 +19,18 @@ class ServiceConfig:
|
||||
def __init__(self, session):
|
||||
self.session = session
|
||||
|
||||
def get(self, key, default=None):
|
||||
result = self.session.query(ServiceConfigValue).filter(ServiceConfigValue.key == key).first()
|
||||
async def get(self, key, default=None):
|
||||
result = (await self.session.execute(select(ServiceConfigValue).where(ServiceConfigValue.key == key))).scalars().first()
|
||||
return (result.value if result else None) or default
|
||||
|
||||
def set(self, key, value):
|
||||
config_value = self.session.query(ServiceConfigValue).filter(
|
||||
ServiceConfigValue.key == key
|
||||
).first()
|
||||
if not config_value:
|
||||
config_value = ServiceConfigValue(key=key)
|
||||
self.session.add(config_value)
|
||||
self.session.commit()
|
||||
return self.set(key, value)
|
||||
async def set(self, key, value):
|
||||
result = (await self.session.execute(select(ServiceConfigValue).where(ServiceConfigValue.key == key))).scalars().first()
|
||||
if not result:
|
||||
result = ServiceConfigValue(key=key)
|
||||
self.session.add(result)
|
||||
await self.session.commit()
|
||||
return await self.set(key, value)
|
||||
|
||||
config_value.packed_value = {'value': value}
|
||||
self.session.commit()
|
||||
result.packed_value = {'value': value}
|
||||
await self.session.commit()
|
||||
return
|
||||
@@ -1,4 +1,4 @@
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import and_, select
|
||||
from app.core.models.node_storage import StoredContent
|
||||
from app.core.models.content.user_content import UserContent, UserAction
|
||||
from app.core.logger import make_log
|
||||
@@ -27,17 +27,17 @@ class PlayerTemplates:
|
||||
if not content.encrypted:
|
||||
local_content = content
|
||||
else:
|
||||
local_content = db_session.query(StoredContent).filter_by(
|
||||
id=content.decrypted_content_id
|
||||
).first()
|
||||
local_content = (await db_session.execute(select(StoredContent).where(StoredContent.id == content.decrypted_content_id))).scalars().first()
|
||||
# TODO: add check decrypted_content by .format_json()['content_cid']
|
||||
if local_content:
|
||||
cd_log += f"Decrypted: {local_content.hash}. "
|
||||
else:
|
||||
cd_log += "Can't decrypt content. "
|
||||
|
||||
user_wallet_address = self.user.wallet_address(self.db_session)
|
||||
user_existing_license = self.db_session.query(UserContent).filter_by(user_id=self.user.id, content_id=content.id).first()
|
||||
user_wallet_address = await self.user.wallet_address_async(self.db_session)
|
||||
user_existing_license = (await self.db_session.execute(select(UserContent).where(
|
||||
and_(UserContent.user_id == self.user.id, UserContent.content_id == content.id)
|
||||
))).scalars().first()
|
||||
|
||||
if local_content:
|
||||
content_meta = content.json_format()
|
||||
@@ -48,12 +48,12 @@ class PlayerTemplates:
|
||||
except:
|
||||
content_type, content_encoding = 'application', 'x-binary'
|
||||
|
||||
content_metadata = StoredContent.from_cid(db_session, content_meta.get('metadata_cid') or None)
|
||||
content_metadata = await StoredContent.from_cid_async(db_session, content_meta.get('metadata_cid') or None)
|
||||
with open(content_metadata.filepath, 'r') as f:
|
||||
content_metadata_json = json.loads(f.read())
|
||||
|
||||
try:
|
||||
cover_content = StoredContent.from_cid(self.db_session, content_meta.get('cover_cid') or None)
|
||||
cover_content = await StoredContent.from_cid_async(self.db_session, content_meta.get('cover_cid') or None)
|
||||
cd_log += f"Cover content: {cover_content.cid.serialize_v2()}. "
|
||||
except BaseException as e:
|
||||
cd_log += f"Can't get cover content: {e}. "
|
||||
@@ -88,12 +88,15 @@ class PlayerTemplates:
|
||||
<blockquote><a href="{content_share_link['url']}">🔴 «открыть в MY»</a></blockquote>"""
|
||||
|
||||
make_log("TG-Player", f"Send content {content_type} ({content_encoding}) to chat {self._chat_id}. {cd_log}")
|
||||
for kmsg in self.db_session.query(KnownTelegramMessage).filter_by(
|
||||
content_id=content.id,
|
||||
chat_id=self._chat_id,
|
||||
type=f'content/{content_type}',
|
||||
deleted=False
|
||||
).all():
|
||||
kmsgs = (await self.db_session.execute(select(KnownTelegramMessage).where(
|
||||
and_(
|
||||
KnownTelegramMessage.content_id == content.id,
|
||||
KnownTelegramMessage.chat_id == self._chat_id,
|
||||
KnownTelegramMessage.type == f'content/{content_type}',
|
||||
KnownTelegramMessage.deleted == False
|
||||
)
|
||||
))).scalars().all()
|
||||
for kmsg in kmsgs:
|
||||
await self.delete_message(kmsg.message_id)
|
||||
|
||||
r = await tg_process_template(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from aiogram import Bot, types
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import and_, select
|
||||
|
||||
from app.core.logger import make_log
|
||||
from app.core.models.messages import KnownTelegramMessage
|
||||
@@ -46,14 +46,15 @@ class Wrapped_CBotChat(T, PlayerTemplates):
|
||||
if self.db_session:
|
||||
if message_type == 'common':
|
||||
ci = 0
|
||||
for oc_msg in self.db_session.query(KnownTelegramMessage).filter(
|
||||
result = await self.db_session.execute(select(KnownTelegramMessage).where(
|
||||
and_(
|
||||
KnownTelegramMessage.type == 'common',
|
||||
KnownTelegramMessage.bot_id == self.bot_id,
|
||||
KnownTelegramMessage.chat_id == self._chat_id,
|
||||
KnownTelegramMessage.deleted == False
|
||||
)
|
||||
).all():
|
||||
))
|
||||
for oc_msg in result.scalars().all():
|
||||
make_log(self, f"Delete old message {oc_msg.message_id} {oc_msg.type} {oc_msg.bot_id} {oc_msg.chat_id}")
|
||||
await self.delete_message(oc_msg.message_id)
|
||||
ci += 1
|
||||
@@ -75,7 +76,7 @@ class Wrapped_CBotChat(T, PlayerTemplates):
|
||||
content_id=content_id
|
||||
)
|
||||
)
|
||||
self.db_session.commit()
|
||||
await self.db_session.commit()
|
||||
else:
|
||||
make_log(self, f"Unknown result type: {type(result)}", level='warning')
|
||||
|
||||
@@ -127,14 +128,16 @@ class Wrapped_CBotChat(T, PlayerTemplates):
|
||||
message_id
|
||||
)):
|
||||
if self.db_session:
|
||||
known_message = self.db_session.query(KnownTelegramMessage).filter(
|
||||
KnownTelegramMessage.bot_id == self.bot_id,
|
||||
KnownTelegramMessage.chat_id == self._chat_id,
|
||||
KnownTelegramMessage.message_id == message_id
|
||||
).first()
|
||||
known_message = (await self.db_session.execute(select(KnownTelegramMessage).where(
|
||||
and_(
|
||||
KnownTelegramMessage.bot_id == self.bot_id,
|
||||
KnownTelegramMessage.chat_id == self._chat_id,
|
||||
KnownTelegramMessage.message_id == message_id
|
||||
)
|
||||
))).scalars().first()
|
||||
if known_message:
|
||||
known_message.deleted = True
|
||||
self.db_session.commit()
|
||||
await self.db_session.commit()
|
||||
except Exception as e:
|
||||
make_log(self, f"Error deleting message {self._chat_id}/{message_id}. Error: {e}", level='warning')
|
||||
return None
|
||||
|
||||
+14
-15
@@ -29,22 +29,21 @@ class Asset(AlchemyBase):
|
||||
AlchemyBase.metadata.create_all(engine)
|
||||
|
||||
@classmethod
|
||||
def find(cls, session, **kwargs):
|
||||
async def find_async(cls, session, **kwargs):
|
||||
from sqlalchemy import select, func
|
||||
if 'symbol' in kwargs:
|
||||
kwargs['symbol'] = kwargs['symbol'].upper()
|
||||
|
||||
result = session.query(cls).filter_by(**kwargs)
|
||||
results_count = result.count()
|
||||
if results_count == 0:
|
||||
any_count = session.query(cls).count()
|
||||
if any_count == 0:
|
||||
init_asset = cls(**DEFAULT_ASSET_INITOBJ)
|
||||
session.add(init_asset)
|
||||
session.commit()
|
||||
return cls.find(session, **kwargs)
|
||||
result = await session.execute(select(cls).filter_by(**kwargs))
|
||||
row = result.scalars().first()
|
||||
if row:
|
||||
return row
|
||||
|
||||
raise Exception(f"Asset not found: {kwargs}")
|
||||
elif results_count == 1:
|
||||
return result.first()
|
||||
else:
|
||||
raise Exception(f"Multiple assets found: {results_count}")
|
||||
any_count = (await session.execute(select(func.count()).select_from(cls))).scalar() or 0
|
||||
if any_count == 0:
|
||||
init_asset = cls(**DEFAULT_ASSET_INITOBJ)
|
||||
session.add(init_asset)
|
||||
await session.commit()
|
||||
return await cls.find_async(session, **kwargs)
|
||||
|
||||
raise Exception(f"Asset not found: {kwargs}")
|
||||
@@ -1,7 +1,7 @@
|
||||
import traceback
|
||||
|
||||
import base58
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import and_, select
|
||||
|
||||
from app.core.logger import make_log
|
||||
from app.core.models import StoredContent
|
||||
@@ -57,13 +57,9 @@ class UserContentIndexationMixin:
|
||||
values_slice = cc_indexator_data['values'].begin_parse()
|
||||
content_hash_b58 = base58.b58encode(bytes.fromhex(hex(values_slice.read_uint(256))[2:])).decode()
|
||||
make_log("UserContent", f"License ({self.onchain_address}) content hash: {content_hash_b58}", level="info")
|
||||
stored_content = db_session.query(StoredContent).filter(
|
||||
and_(
|
||||
StoredContent.type == 'onchain/content',
|
||||
StoredContent.hash == content_hash_b58,
|
||||
|
||||
)
|
||||
).first()
|
||||
stored_content = (await db_session.execute(select(StoredContent).where(
|
||||
and_(StoredContent.type == 'onchain/content', StoredContent.hash == content_hash_b58)
|
||||
))).scalars().first()
|
||||
trusted_cop_address_result = await toncenter.run_get_method(stored_content.meta['item_address'], 'get_nft_address_by_index', [['num', cc_indexator_data['index']]])
|
||||
assert trusted_cop_address_result.get('exit_code', -1) == 0, "Trusted cop address error"
|
||||
trusted_cop_address = Cell.one_from_boc(b64decode(trusted_cop_address_result['stack'][0][1]['bytes'])).begin_parse().read_msg_addr().to_string(1, 1, 1)
|
||||
@@ -72,7 +68,7 @@ class UserContentIndexationMixin:
|
||||
self.owner_address = cc_indexator_data['owner_address']
|
||||
self.type = 'nft/listen'
|
||||
self.content_id = stored_content.id
|
||||
db_session.commit()
|
||||
await db_session.commit()
|
||||
except BaseException as e:
|
||||
errored = True
|
||||
make_log("UserContent", f"Error: {e}" + '\n' + traceback.format_exc(), level="error")
|
||||
@@ -80,7 +76,6 @@ class UserContentIndexationMixin:
|
||||
if errored is True:
|
||||
self.type = 'nft/unknown'
|
||||
self.content_id = None
|
||||
db_session.commit()
|
||||
|
||||
await db_session.commit()
|
||||
|
||||
|
||||
@@ -96,6 +96,30 @@ class StoredContent(AlchemyBase, AudioContentMixin):
|
||||
make_log("NodeStorage.open_content", f"Can't open content: {self.id} {e}", level='warning')
|
||||
raise e
|
||||
|
||||
async def open_content_async(self, db_session, content_type=None):
|
||||
from sqlalchemy import select
|
||||
try:
|
||||
decrypted_content = self if not self.encrypted else None
|
||||
encrypted_content = self if self.encrypted else None
|
||||
if not decrypted_content:
|
||||
decrypted_content = (await db_session.execute(select(StoredContent).where(StoredContent.id == self.decrypted_content_id))).scalars().first()
|
||||
else:
|
||||
encrypted_content = (await db_session.execute(select(StoredContent).where(StoredContent.decrypted_content_id == self.id))).scalars().first()
|
||||
|
||||
assert decrypted_content, "Can't get decrypted content"
|
||||
assert encrypted_content, "Can't get encrypted content"
|
||||
_ct = content_type or decrypted_content.json_format()['content_type']
|
||||
content_type = _ct.split('/')[0] if _ct else 'application'
|
||||
|
||||
return {
|
||||
'encrypted_content': encrypted_content,
|
||||
'decrypted_content': decrypted_content,
|
||||
'content_type': content_type or 'application/x-binary'
|
||||
}
|
||||
except BaseException as e:
|
||||
make_log("NodeStorage.open_content_async", f"Can't open content: {self.id} {e}", level='warning')
|
||||
raise e
|
||||
|
||||
def json_format(self):
|
||||
extra_fields = {}
|
||||
if self.type.startswith('local'):
|
||||
@@ -155,3 +179,15 @@ class StoredContent(AlchemyBase, AudioContentMixin):
|
||||
assert content, "Content not found"
|
||||
return content
|
||||
|
||||
@classmethod
|
||||
async def from_cid_async(cls, db_session, content_id):
|
||||
from sqlalchemy import select
|
||||
if isinstance(content_id, str):
|
||||
cid = ContentId.deserialize(content_id)
|
||||
else:
|
||||
cid = content_id
|
||||
|
||||
result = await db_session.execute(select(StoredContent).where(StoredContent.hash == cid.content_hash_b58))
|
||||
content = result.scalars().first()
|
||||
assert content, "Content not found"
|
||||
return content
|
||||
@@ -10,18 +10,21 @@ from httpx import AsyncClient
|
||||
|
||||
|
||||
class WalletMixin:
|
||||
def wallet_connection(self, db_session):
|
||||
return db_session.query(WalletConnection).filter(
|
||||
WalletConnection.user_id == self.id,
|
||||
WalletConnection.invalidated == False
|
||||
).order_by(WalletConnection.created.desc()).first()
|
||||
async def wallet_connection_async(self, db_session):
|
||||
from sqlalchemy import select, and_, desc
|
||||
result = await db_session.execute(
|
||||
select(WalletConnection)
|
||||
.where(and_(WalletConnection.user_id == self.id, WalletConnection.invalidated == False))
|
||||
.order_by(WalletConnection.created.desc())
|
||||
)
|
||||
return result.scalars().first()
|
||||
|
||||
def wallet_address(self, db_session):
|
||||
wallet_connection = self.wallet_connection(db_session)
|
||||
return wallet_connection.wallet_address if wallet_connection else None
|
||||
async def wallet_address_async(self, db_session):
|
||||
wc = await self.wallet_connection_async(db_session)
|
||||
return wc.wallet_address if wc else None
|
||||
|
||||
async def scan_owned_user_content(self, db_session):
|
||||
user_wallet_address = self.wallet_address(db_session)
|
||||
user_wallet_address = await self.wallet_address_async(db_session)
|
||||
|
||||
async def get_nft_items_list():
|
||||
try:
|
||||
@@ -40,9 +43,8 @@ class WalletMixin:
|
||||
item_address = Address(nft_item['address']).to_string(1, 1, 1)
|
||||
owner_address = Address(nft_item['owner']['address']).to_string(1, 1, 1)
|
||||
|
||||
user_content = db_session.query(UserContent).filter(
|
||||
UserContent.onchain_address == item_address
|
||||
).first()
|
||||
from sqlalchemy import select
|
||||
user_content = (await db_session.execute(select(UserContent).where(UserContent.onchain_address == item_address))).scalars().first()
|
||||
if user_content:
|
||||
continue
|
||||
|
||||
@@ -57,18 +59,18 @@ class WalletMixin:
|
||||
created=datetime.now(),
|
||||
meta={},
|
||||
user_id=self.id,
|
||||
wallet_connection_id=self.wallet_connection(db_session).id,
|
||||
wallet_connection_id=(await self.wallet_connection_async(db_session)).id,
|
||||
status="active"
|
||||
)
|
||||
db_session.add(user_content)
|
||||
db_session.commit()
|
||||
await db_session.commit()
|
||||
make_log(self, f"New onchain NFT found: {item_address}", level='info')
|
||||
|
||||
async def ____scan_owned_user_content(self, db_session):
|
||||
page_id = -1
|
||||
page_size = 100
|
||||
have_next_page = True
|
||||
user_wallet_address = self.wallet_address(db_session)
|
||||
user_wallet_address = await self.wallet_address_async(db_session)
|
||||
while have_next_page:
|
||||
page_id += 1
|
||||
nfts_list = await toncenter.get_nft_items(limit=100, offset=page_id * page_size, owner_address=user_wallet_address)
|
||||
@@ -81,9 +83,8 @@ class WalletMixin:
|
||||
item_address = Address(nft_item['address']).to_string(1, 1, 1)
|
||||
owner_address = Address(nft_item['owner_address']).to_string(1, 1, 1)
|
||||
|
||||
user_content = db_session.query(UserContent).filter(
|
||||
UserContent.onchain_address == item_address
|
||||
).first()
|
||||
from sqlalchemy import select
|
||||
user_content = (await db_session.execute(select(UserContent).where(UserContent.onchain_address == item_address))).scalars().first()
|
||||
if user_content:
|
||||
continue
|
||||
|
||||
@@ -105,11 +106,11 @@ class WalletMixin:
|
||||
'metadata_uri': nft_content,
|
||||
},
|
||||
user_id=self.id,
|
||||
wallet_connection_id=self.wallet_connection(db_session).id,
|
||||
wallet_connection_id=(await self.wallet_connection_async(db_session)).id,
|
||||
status="active"
|
||||
)
|
||||
db_session.add(user_content)
|
||||
db_session.commit()
|
||||
await db_session.commit()
|
||||
|
||||
make_log(self, f"New onchain NFT found: {item_address}", level='info')
|
||||
except BaseException as e:
|
||||
@@ -122,6 +123,6 @@ class WalletMixin:
|
||||
except BaseException as e:
|
||||
make_log(self, f"Error while scanning user content: {e}", level='error')
|
||||
|
||||
return self.db_session.query(UserContent).filter(
|
||||
UserContent.user_id == self.id
|
||||
).offset(offset).limit(limit).all()
|
||||
from sqlalchemy import select
|
||||
result = await db_session.execute(select(UserContent).where(UserContent.user_id == self.id).offset(offset).limit(limit))
|
||||
return result.scalars().all()
|
||||
Reference in new issue
Block a user