Get reaction limit from server app config
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
Reference in New Issue
Block a user