Files
mirrors-mautrix-telegram/mautrix_telegram/db/puppet.py

145 lines
5.0 KiB
Python
Raw Normal View History

2019-02-12 15:05:36 +02:00
# mautrix-telegram - A Matrix-Telegram puppeting bridge
# Copyright (C) 2022 Tulir Asokan
2019-02-12 15:05:36 +02:00
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations
2021-12-21 01:36:24 +02:00
from typing import TYPE_CHECKING, ClassVar
from asyncpg import Record
from attr import dataclass
from yarl import URL
2022-02-01 20:51:54 +02:00
from mautrix.types import ContentURI, SyncToken, UserID
from mautrix.util.async_db import Database
2019-02-12 15:05:36 +02:00
from ..types import TelegramID
2019-02-12 15:05:36 +02:00
fake_db = Database.create("") if TYPE_CHECKING else None
@dataclass
class Puppet:
db: ClassVar[Database] = fake_db
id: TelegramID
is_registered: bool
displayname: str | None
displayname_source: TelegramID | None
displayname_contact: bool
displayname_quality: int
disable_updates: bool
username: str | None
2022-04-06 12:47:35 +03:00
phone: str | None
photo_id: str | None
2022-02-01 20:51:54 +02:00
avatar_url: ContentURI | None
name_set: bool
avatar_set: bool
contact_info_set: bool
is_bot: bool | None
is_channel: bool
is_premium: bool
2019-02-12 15:05:36 +02:00
custom_mxid: UserID | None
access_token: str | None
next_batch: SyncToken | None
base_url: URL | None
2019-02-12 15:05:36 +02:00
@classmethod
def _from_row(cls, row: Record | None) -> Puppet | None:
if row is None:
return None
data = {**row}
base_url = data.pop("base_url", None)
return cls(**data, base_url=URL(base_url) if base_url else None)
columns: ClassVar[str] = (
"id, is_registered, displayname, displayname_source, displayname_contact, "
2022-04-06 12:47:35 +03:00
"displayname_quality, disable_updates, username, phone, photo_id, avatar_url, "
"name_set, avatar_set, contact_info_set, is_bot, is_channel, is_premium, "
"custom_mxid, access_token, next_batch, base_url"
)
@classmethod
async def all_with_custom_mxid(cls) -> list[Puppet]:
q = f"SELECT {cls.columns} FROM puppet WHERE custom_mxid<>''"
return [cls._from_row(row) for row in await cls.db.fetch(q)]
2019-02-12 15:05:36 +02:00
@classmethod
async def get_by_tgid(cls, tgid: TelegramID) -> Puppet | None:
q = f"SELECT {cls.columns} FROM puppet WHERE id=$1"
return cls._from_row(await cls.db.fetchrow(q, tgid))
2019-02-12 15:05:36 +02:00
@classmethod
async def get_by_custom_mxid(cls, mxid: UserID) -> Puppet | None:
q = f"SELECT {cls.columns} FROM puppet WHERE custom_mxid=$1"
return cls._from_row(await cls.db.fetchrow(q, mxid))
2019-02-12 15:05:36 +02:00
@classmethod
async def find_by_username(cls, username: str) -> Puppet | None:
q = f"SELECT {cls.columns} FROM puppet WHERE lower(username)=$1"
return cls._from_row(await cls.db.fetchrow(q, username.lower()))
2019-02-12 15:05:36 +02:00
@property
def _values(self):
2021-12-21 01:36:24 +02:00
return (
self.id,
self.is_registered,
self.displayname,
self.displayname_source,
self.displayname_contact,
self.displayname_quality,
self.disable_updates,
self.username,
2022-04-06 12:47:35 +03:00
self.phone,
2021-12-21 01:36:24 +02:00
self.photo_id,
2022-02-01 20:51:54 +02:00
self.avatar_url,
self.name_set,
self.avatar_set,
self.contact_info_set,
2021-12-21 01:36:24 +02:00
self.is_bot,
self.is_channel,
self.is_premium,
2021-12-21 01:36:24 +02:00
self.custom_mxid,
self.access_token,
self.next_batch,
str(self.base_url) if self.base_url else None,
)
async def save(self) -> None:
2022-02-01 20:51:54 +02:00
q = """
UPDATE puppet
SET is_registered=$2, displayname=$3, displayname_source=$4, displayname_contact=$5,
2022-04-06 12:47:35 +03:00
displayname_quality=$6, disable_updates=$7, username=$8, phone=$9, photo_id=$10,
avatar_url=$11, name_set=$12, avatar_set=$13, contact_info_set=$14, is_bot=$15,
is_channel=$16, is_premium=$17, custom_mxid=$18, access_token=$19, next_batch=$20,
base_url=$21
2022-02-01 20:51:54 +02:00
WHERE id=$1
"""
await self.db.execute(q, *self._values)
async def insert(self) -> None:
2022-02-01 20:51:54 +02:00
q = """
INSERT INTO puppet (
id, is_registered, displayname, displayname_source, displayname_contact,
2022-04-06 12:47:35 +03:00
displayname_quality, disable_updates, username, phone, photo_id, avatar_url, name_set,
avatar_set, contact_info_set, is_bot, is_channel, is_premium, custom_mxid,
access_token, next_batch, base_url
2022-04-06 12:47:35 +03:00
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18,
$19, $20, $21)
2022-02-01 20:51:54 +02:00
"""
await self.db.execute(q, *self._values)