Switch TelegramFile to SQLAlchemy core

This commit is contained in:
Tulir Asokan
2018-12-20 00:07:04 +02:00
parent e548836d38
commit b2e183e363
2 changed files with 43 additions and 19 deletions
+22 -1
View File
@@ -278,7 +278,9 @@ class BotChat(Base):
class TelegramFile(Base): class TelegramFile(Base):
query = None # type: Query db = None # type: Engine
t = None # type: Table
c = None # type: ImmutableColumnCollection
__tablename__ = "telegram_file" __tablename__ = "telegram_file"
id = Column(String, primary_key=True) id = Column(String, primary_key=True)
@@ -292,6 +294,25 @@ class TelegramFile(Base):
thumbnail_id = Column("thumbnail", String, ForeignKey("telegram_file.id"), nullable=True) thumbnail_id = Column("thumbnail", String, ForeignKey("telegram_file.id"), nullable=True)
thumbnail = relationship("TelegramFile", uselist=False) thumbnail = relationship("TelegramFile", uselist=False)
@classmethod
def get(cls, id: str) -> Optional['TelegramFile']:
rows = cls.db.execute(cls.t.select().where(cls.c.id == id))
try:
id, mxc, mime, conv, ts, s, w, h, thumb_id = next(rows)
thumb = None
if thumb_id:
thumb = cls.get(thumb_id)
return TelegramFile(id=id, mxc=mxc, mime_type=mime, was_converted=conv, timestamp=ts,
size=s, width=w, height=h, thumbnail_id=thumb_id, thumbnail=thumb)
except StopIteration:
return None
def insert(self) -> None:
self.db.execute(self.t.insert().values(
id=self.id, mxc=self.mxc, mime_type=self.mime_type, timestamp=self.timestamp,
size=self.size, width=self.width, height=self.height,
thumbnail_id=self.thumbnail.id if self.thumbnail else self.thumbnail_id))
def init(db_session, db_engine) -> None: def init(db_session, db_engine) -> None:
query = db_session.query_property() query = db_session.query_property()
+21 -18
View File
@@ -23,7 +23,6 @@ import asyncio
import magic import magic
from sqlalchemy import orm from sqlalchemy import orm
from sqlalchemy.exc import IntegrityError, InvalidRequestError from sqlalchemy.exc import IntegrityError, InvalidRequestError
from sqlalchemy.orm.exc import FlushError
from telethon.tl.types import (Document, FileLocation, InputFileLocation, from telethon.tl.types import (Document, FileLocation, InputFileLocation,
InputDocumentFileLocation, PhotoSize, PhotoCachedSize) InputDocumentFileLocation, PhotoSize, PhotoCachedSize)
@@ -117,6 +116,10 @@ async def transfer_thumbnail_to_matrix(client: MautrixTelegramClient, intent: In
if not loc_id: if not loc_id:
return None return None
db_file = DBTelegramFile.get(loc_id)
if db_file:
return db_file
video_ext = mimetypes.guess_extension(mime) video_ext = mimetypes.guess_extension(mime)
if VideoFileClip and video_ext: if VideoFileClip and video_ext:
try: try:
@@ -131,22 +134,29 @@ async def transfer_thumbnail_to_matrix(client: MautrixTelegramClient, intent: In
content_uri = await intent.upload_file(file, mime_type) content_uri = await intent.upload_file(file, mime_type)
return DBTelegramFile(id=loc_id, mxc=content_uri, mime_type=mime_type, db_file = DBTelegramFile(id=loc_id, mxc=content_uri, mime_type=mime_type,
was_converted=False, timestamp=int(time.time()), size=len(file), was_converted=False, timestamp=int(time.time()), size=len(file),
width=width, height=height) width=width, height=height)
try:
db_file.insert()
except (IntegrityError, InvalidRequestError) as e:
log.exception(f"{e.__class__.__name__} while saving transferred file thumbnail data. "
"This was probably caused by two simultaneous transfers of the same file, "
"and might (but probably won't) cause problems with thumbnails or something.")
return db_file
transfer_locks = {} # type: Dict[str, asyncio.Lock] transfer_locks = {} # type: Dict[str, asyncio.Lock]
async def transfer_file_to_matrix(db: orm.Session, client: MautrixTelegramClient, intent: IntentAPI, async def transfer_file_to_matrix(client: MautrixTelegramClient, intent: IntentAPI,
location: TypeLocation, thumbnail: Optional[TypeLocation] = None, location: TypeLocation, thumbnail: Optional[TypeLocation] = None,
is_sticker: bool = False) -> Optional[DBTelegramFile]: is_sticker: bool = False) -> Optional[DBTelegramFile]:
location_id = _location_to_id(location) location_id = _location_to_id(location)
if not location_id: if not location_id:
return None return None
db_file = DBTelegramFile.query.get(location_id) db_file = DBTelegramFile.get(location_id)
if db_file: if db_file:
return db_file return db_file
@@ -156,15 +166,15 @@ async def transfer_file_to_matrix(db: orm.Session, client: MautrixTelegramClient
lock = asyncio.Lock() lock = asyncio.Lock()
transfer_locks[location_id] = lock transfer_locks[location_id] = lock
async with lock: async with lock:
return await _unlocked_transfer_file_to_matrix(db, client, intent, location_id, location, return await _unlocked_transfer_file_to_matrix(client, intent, location_id, location,
thumbnail, is_sticker) thumbnail, is_sticker)
async def _unlocked_transfer_file_to_matrix(db: orm.Session, client: MautrixTelegramClient, async def _unlocked_transfer_file_to_matrix(client: MautrixTelegramClient, intent: IntentAPI,
intent: IntentAPI, loc_id: str, location: TypeLocation, loc_id: str, location: TypeLocation,
thumbnail: Optional[TypeLocation], thumbnail: Optional[TypeLocation],
is_sticker: bool) -> Optional[DBTelegramFile]: is_sticker: bool) -> Optional[DBTelegramFile]:
db_file = DBTelegramFile.query.get(loc_id) db_file = DBTelegramFile.get(loc_id)
if db_file: if db_file:
return db_file return db_file
@@ -201,16 +211,9 @@ async def _unlocked_transfer_file_to_matrix(db: orm.Session, client: MautrixTele
mime_type) mime_type)
try: try:
db.add(db_file) db_file.insert()
db.commit()
except FlushError as e:
log.exception(f"{e.__class__.__name__} while saving transferred file data. "
"This was probably caused by two simultaneous transfers of the same file, "
"and should not cause any problems.")
except (IntegrityError, InvalidRequestError) as e: except (IntegrityError, InvalidRequestError) as e:
db.rollback()
log.exception(f"{e.__class__.__name__} while saving transferred file data. " log.exception(f"{e.__class__.__name__} while saving transferred file data. "
"This was probably caused by two simultaneous transfers of the same file, " "This was probably caused by two simultaneous transfers of the same file, "
"and should not cause any problems.") "and should not cause any problems.")
return db_file return db_file