Handle bans when getting difference

This commit is contained in:
Lonami Exo 2022-05-23 11:41:59 +02:00
parent dfce1f53a8
commit f50b2f5d61
3 changed files with 43 additions and 6 deletions

View File

@ -1,3 +1,3 @@
from .entitycache import EntityCache from .entitycache import EntityCache
from .messagebox import MessageBox, GapError from .messagebox import MessageBox, GapError, PrematureEndReason
from .session import SessionState, ChannelState, Entity, EntityType from .session import SessionState, ChannelState, Entity, EntityType

View File

@ -19,6 +19,7 @@ to get the difference.
import asyncio import asyncio
import datetime import datetime
import time import time
from enum import Enum
from .session import SessionState, ChannelState from .session import SessionState, ChannelState
from ..tl import types as tl, functions as fn from ..tl import types as tl, functions as fn
@ -60,6 +61,11 @@ class GapError(ValueError):
return 'GapError()' return 'GapError()'
class PrematureEndReason(Enum):
TEMPORARY_SERVER_ISSUES = 'tmp'
BANNED = 'ban'
# Represents the information needed to correctly handle a specific `tl::enums::Update`. # Represents the information needed to correctly handle a specific `tl::enums::Update`.
class PtsInfo: class PtsInfo:
__slots__ = ('pts', 'pts_count', 'entry') __slots__ = ('pts', 'pts_count', 'entry')
@ -635,4 +641,19 @@ class MessageBox:
return diff.other_updates, diff.users, diff.chats return diff.other_updates, diff.users, diff.chats
def end_channel_difference(self, request, reason: PrematureEndReason, chat_hashes):
entry = request.channel.channel_id
if reason == PrematureEndReason.TEMPORARY_SERVER_ISSUES:
# Temporary issues. End getting difference without updating the pts so we can retry later.
self.possible_gaps.pop(entry, None)
self.end_get_diff(entry)
elif reason == PrematureEndReason.BANNED:
# Banned in the channel. Forget its state since we can no longer fetch updates from it.
self.possible_gaps.pop(entry, None)
self.end_get_diff(entry)
del self.map[entry]
else:
raise RuntimeError('Unknown reason to end channel difference')
# endregion Getting and applying channel difference. # endregion Getting and applying channel difference.

View File

@ -12,7 +12,7 @@ from collections import deque
from .. import events, utils, errors from .. import events, utils, errors
from ..events.common import EventBuilder, EventCommon from ..events.common import EventBuilder, EventCommon
from ..tl import types, functions from ..tl import types, functions
from .._updates import GapError from .._updates import GapError, PrematureEndReason
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from .telegramclient import TelegramClient from .telegramclient import TelegramClient
@ -290,11 +290,27 @@ class UpdateMethods:
'Getting difference for channel updates caused PersistentTimestampOutdated;' 'Getting difference for channel updates caused PersistentTimestampOutdated;'
' ending getting difference prematurely until server issues are resolved' ' ending getting difference prematurely until server issues are resolved'
) )
diff = types.updates.ChannelDifferenceEmpty( self._message_box.end_channel_difference(
pts=self._message_box.map[get_diff.channel.channel_id].pts, get_diff,
final=True, PrematureEndReason.TEMPORARY_SERVER_ISSUES,
timeout=30 self._mb_entity_cache
) )
continue
except errors.ChannelPrivateError:
# Timeout triggered a get difference, but we have been banned in the channel since then.
# Because we can no longer fetch updates from this channel, we should stop keeping track
# of it entirely.
self._log[__name__].info(
'Account is now banned in %d so we can no longer fetch updates from it',
get_diff.channel.channel_id
)
self._message_box.end_channel_difference(
get_diff,
PrematureEndReason.BANNED,
self._mb_entity_cache
)
continue
updates, users, chats = self._message_box.apply_channel_difference(get_diff, diff, self._mb_entity_cache) updates, users, chats = self._message_box.apply_channel_difference(get_diff, diff, self._mb_entity_cache)
updates_to_dispatch.extend(self._preprocess_updates(updates, users, chats)) updates_to_dispatch.extend(self._preprocess_updates(updates, users, chats))
continue continue