Get reaction limit from server app config

This commit is contained in:
Tulir Asokan
2022-10-01 17:27:56 +03:00
parent 025b864bd8
commit f5cb8baf99
4 changed files with 71 additions and 10 deletions
+7 -8
View File
@@ -2319,8 +2319,7 @@ class Portal(DBPortal, BasePortal):
existing_reacts = await DBReaction.get_by_sender(msg.mxid, msg.mx_room, user.tgid)
new_tg_reactions: list[TypeReaction] = []
reactions_to_remove: list[DBReaction] = []
# TODO use config https://corefork.telegram.org/api/config#reactions-user-max-default
max_reactions = 3 if user.is_premium else 1
max_reactions = await user.get_max_reactions()
max_reactions -= 1 # Leave one reaction of space for the new reaction
for db_reaction in existing_reacts:
if db_reaction.reaction == emoji_id:
@@ -2862,12 +2861,12 @@ class Portal(DBPortal, BasePortal):
return False
@staticmethod
async def _get_reaction_limit(sender: TelegramID) -> int:
async def _get_reaction_limit(source: au.AbstractUser, sender: TelegramID) -> int:
puppet = await p.Puppet.get_by_tgid(sender, create=False)
# TODO use config https://corefork.telegram.org/api/config#reactions-user-max-default
if puppet and puppet.is_premium:
return 3
return 1
is_premium = puppet and puppet.is_premium
if isinstance(source, u.User) and not source.is_bot:
return await source.get_max_reactions(is_premium)
return 3 if is_premium else 1
async def _handle_telegram_reactions_locked(
self,
@@ -2903,7 +2902,7 @@ class Portal(DBPortal, BasePortal):
else:
if is_full or (
new_reactions is not None
and len(new_reactions) == await self._get_reaction_limit(sender_id)
and len(new_reactions) == await self._get_reaction_limit(source, sender_id)
):
removed.append(existing_reaction)
# else: assume the reaction is still there, too much effort to fetch it
+24 -2
View File
@@ -15,7 +15,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING, AsyncGenerator, AsyncIterable, Awaitable, NamedTuple, cast
from typing import TYPE_CHECKING, Any, AsyncGenerator, AsyncIterable, Awaitable, NamedTuple, cast
from datetime import datetime, timezone
import asyncio
import time
@@ -24,6 +24,7 @@ from telethon.errors import AuthKeyDuplicatedError, RPCError, UnauthorizedError
from telethon.tl.custom import Dialog
from telethon.tl.functions.account import UpdateStatusRequest
from telethon.tl.functions.contacts import GetContactsRequest, SearchRequest
from telethon.tl.functions.help import GetAppConfigRequest
from telethon.tl.functions.messages import GetAvailableReactionsRequest
from telethon.tl.functions.updates import GetStateRequest
from telethon.tl.functions.users import GetUsersRequest
@@ -54,7 +55,7 @@ from mautrix.types import PushActionType, PushRuleKind, PushRuleScope, RoomID, R
from mautrix.util.bridge_state import BridgeState, BridgeStateEvent
from mautrix.util.opt_prometheus import Gauge
from . import portal as po, puppet as pu
from . import portal as po, puppet as pu, util
from .abstract_user import AbstractUser
from .db import Message as DBMessage, PgSession, User as DBUser
from .types import TelegramID
@@ -91,6 +92,7 @@ class User(DBUser, AbstractUser, BaseUser):
_available_emoji_reactions_hash: int | None
_available_emoji_reactions_fetched: float
_available_emoji_reactions_lock: asyncio.Lock
_app_config: dict[str, Any] | None
def __init__(
self,
@@ -121,6 +123,7 @@ class User(DBUser, AbstractUser, BaseUser):
self._available_emoji_reactions_hash = None
self._available_emoji_reactions_fetched = 0
self._available_emoji_reactions_lock = asyncio.Lock()
self._app_config = None
(
self.relaybot_whitelisted,
@@ -734,6 +737,25 @@ class User(DBUser, AbstractUser, BaseUser):
)
return self._available_emoji_reactions
def tl_to_json(self) -> Any:
pass
async def get_app_config(self) -> dict[str, Any]:
if not self._app_config:
cfg = await self.client(GetAppConfigRequest())
self._app_config = util.parse_tl_json(cfg)
return self._app_config
async def get_max_reactions(self, is_premium: bool | None = None) -> int:
if is_premium is None:
is_premium = self.is_premium
cfg = await self.get_app_config()
return (
cfg.get("reactions_user_max_premium", 3)
if is_premium
else cfg.get("reactions_user_max_default", 1)
)
# endregion
# region Class instance lookup
+1
View File
@@ -8,3 +8,4 @@ from .file_transfer import (
)
from .parallel_file_transfer import parallel_transfer_to_telegram
from .recursive_dict import recursive_del, recursive_get, recursive_set
from .tl_json import parse_tl_json
+39
View File
@@ -0,0 +1,39 @@
# mautrix-telegram - A Matrix-Telegram puppeting bridge
# Copyright (C) 2022 Tulir Asokan
#
# 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 telethon.tl.types import (
JsonArray,
JsonBool,
JsonNull,
JsonNumber,
JsonObject,
JsonObjectValue,
JsonString,
TypeJSONValue,
)
from mautrix.types import JSON
def parse_tl_json(val: TypeJSONValue) -> JSON:
if isinstance(val, JsonObject):
return {entry.key: parse_tl_json(entry.value) for entry in val.value}
elif isinstance(val, JsonArray):
return [parse_tl_json(item) for item in val.value]
elif isinstance(val, (JsonBool, JsonNumber, JsonString)):
return val.value
elif isinstance(val, JsonNull):
return None
raise ValueError(f"Unsupported type {type(val)} in TL JSON object")