mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-29 12:53:44 +03:00
Remove PackedChat
In favour of using the session entity type consistently.
This commit is contained in:
parent
07faa53c5a
commit
9b4808a558
|
@ -241,11 +241,11 @@ async def get_input_entity(
|
|||
entity = await self._session.get_entity(None, peer_id)
|
||||
if entity:
|
||||
if entity.ty in (Entity.USER, Entity.BOT):
|
||||
return _tl.InputPeerUser(entity.id, entity.access_hash)
|
||||
return _tl.InputPeerUser(entity.id, entity.hash)
|
||||
elif entity.ty in (Entity.GROUP):
|
||||
return _tl.InputPeerChat(peer.chat_id)
|
||||
elif entity.ty in (Entity.CHANNEL, Entity.MEGAGROUP, Entity.GIGAGROUP):
|
||||
return _tl.InputPeerChannel(entity.id, entity.access_hash)
|
||||
return _tl.InputPeerChannel(entity.id, entity.hash)
|
||||
|
||||
# Only network left to try
|
||||
if isinstance(peer, str):
|
||||
|
|
|
@ -64,15 +64,15 @@ class Session(ABC):
|
|||
Get the `Entity` with matching ``ty`` and ``id``.
|
||||
|
||||
The following groups of ``ty`` should be treated to be equivalent, that is, for a given
|
||||
``ty`` and ``id``, if the ``ty`` is in a given group, a matching ``access_hash`` with
|
||||
that ``id`` from within any ``ty`` in that group should be returned.
|
||||
``ty`` and ``id``, if the ``ty`` is in a given group, a matching ``hash`` with that ``id``
|
||||
from within any ``ty`` in that group should be returned.
|
||||
|
||||
* `EntityType.USER` and `EntityType.BOT`.
|
||||
* `EntityType.GROUP`.
|
||||
* `EntityType.CHANNEL`, `EntityType.MEGAGROUP` and `EntityType.GIGAGROUP`.
|
||||
|
||||
For example, if a ``ty`` representing a bot is stored but the asking ``ty`` is a user,
|
||||
the corresponding ``access_hash`` should still be returned.
|
||||
the corresponding ``hash`` should still be returned.
|
||||
|
||||
You may use ``EntityType.canonical`` to find out the canonical type.
|
||||
|
||||
|
|
|
@ -34,12 +34,12 @@ class MemorySession(Session):
|
|||
return list(self.channel_states.values())
|
||||
|
||||
async def insert_entities(self, entities: List[Entity]):
|
||||
self.entities.update((e.id, (e.ty, e.access_hash)) for e in entities)
|
||||
self.entities.update((e.id, (e.ty, e.hash)) for e in entities)
|
||||
|
||||
async def get_entity(self, ty: Optional[int], id: int) -> Optional[Entity]:
|
||||
try:
|
||||
ty, access_hash = self.entities[id]
|
||||
return Entity(ty, id, access_hash)
|
||||
ty, hash = self.entities[id]
|
||||
return Entity(ty, id, hash)
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ class SQLiteSession(Session):
|
|||
limit 1
|
||||
''')
|
||||
c.execute('''
|
||||
insert into entity (id, access_hash, ty)
|
||||
insert into entity (id, hash, ty)
|
||||
select
|
||||
case
|
||||
when id < -1000000000000 then -(id + 1000000000000)
|
||||
|
@ -173,7 +173,7 @@ class SQLiteSession(Session):
|
|||
)''',
|
||||
'''entity (
|
||||
id integer primary key,
|
||||
access_hash integer not null,
|
||||
hash integer not null,
|
||||
ty integer not null
|
||||
)''',
|
||||
)
|
||||
|
@ -245,13 +245,13 @@ class SQLiteSession(Session):
|
|||
try:
|
||||
c.executemany(
|
||||
'insert or replace into entity values (?,?,?)',
|
||||
[(e.id, e.access_hash, e.ty) for e in entities]
|
||||
[(e.id, e.hash, e.ty) for e in entities]
|
||||
)
|
||||
finally:
|
||||
c.close()
|
||||
|
||||
async def get_entity(self, ty: Optional[int], id: int) -> Optional[Entity]:
|
||||
row = self._execute('select ty, id, access_hash from entity where id = ?', id)
|
||||
row = self._execute('select ty, id, hash from entity where id = ?', id)
|
||||
return Entity(*row) if row else None
|
||||
|
||||
async def save(self):
|
||||
|
|
|
@ -105,12 +105,74 @@ class Entity:
|
|||
"""
|
||||
Stores the information needed to use a certain user, chat or channel with the API.
|
||||
|
||||
* ty: 8-bit number indicating the type of the entity.
|
||||
* ty: 8-bit number indicating the type of the entity (of type `EntityType`).
|
||||
* id: 64-bit number uniquely identifying the entity among those of the same type.
|
||||
* access_hash: 64-bit number needed to use this entity with the API.
|
||||
* hash: 64-bit signed number needed to use this entity with the API.
|
||||
|
||||
The string representation of this class is considered to be stable, for as long as
|
||||
Telegram doesn't need to add more fields to the entities. It can also be converted
|
||||
to bytes with ``bytes(entity)``, for a more compact representation.
|
||||
"""
|
||||
__slots__ = ('ty', 'id', 'access_hash')
|
||||
__slots__ = ('ty', 'id', 'hash')
|
||||
|
||||
ty: EntityType
|
||||
id: int
|
||||
access_hash: int
|
||||
hash: int
|
||||
|
||||
@property
|
||||
def is_user(self):
|
||||
"""
|
||||
``True`` if the entity is either a user or a bot.
|
||||
"""
|
||||
return self.ty in (EntityType.USER, EntityType.BOT)
|
||||
|
||||
@property
|
||||
def is_group(self):
|
||||
"""
|
||||
``True`` if the entity is a small group chat or `megagroup`_.
|
||||
|
||||
.. _megagroup: https://telegram.org/blog/supergroups5k
|
||||
"""
|
||||
return self.ty in (EntityType.GROUP, EntityType.MEGAGROUP)
|
||||
|
||||
@property
|
||||
def is_channel(self):
|
||||
"""
|
||||
``True`` if the entity is a broadcast channel or `broadcast group`_.
|
||||
|
||||
.. _broadcast group: https://telegram.org/blog/autodelete-inv2#groups-with-unlimited-members
|
||||
"""
|
||||
return self.ty in (EntityType.CHANNEL, EntityType.GIGAGROUP)
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, string: str):
|
||||
"""
|
||||
Convert the string into an `Entity`.
|
||||
"""
|
||||
try:
|
||||
ty, id, hash = string.split('.')
|
||||
ty, id, hash = ord(ty), int(id), int(hash)
|
||||
except AttributeError:
|
||||
raise TypeError(f'expected str, got {string!r}') from None
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError(f'malformed entity str (must be T.id.hash), got {string!r}') from None
|
||||
|
||||
return cls(EntityType(ty), id, hash)
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, blob):
|
||||
"""
|
||||
Convert the bytes into an `Entity`.
|
||||
"""
|
||||
try:
|
||||
ty, id, hash = struct.unpack('<Bqq', blob)
|
||||
except struct.error:
|
||||
raise ValueError(f'malformed entity data, got {string!r}') from None
|
||||
|
||||
return cls(EntityType(ty), id, hash)
|
||||
|
||||
def __str__(self):
|
||||
return f'{chr(self.ty)}.{self.id}.{self.hash}'
|
||||
|
||||
def __bytes__(self):
|
||||
return struct.pack('<Bqq', self.ty, self.id, self.hash)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
from .entitycache import EntityCache, PackedChat
|
||||
from .entitycache import EntityCache
|
||||
from .messagebox import MessageBox
|
||||
|
|
|
@ -8,59 +8,6 @@ from .. import _tl
|
|||
from .._sessions.types import EntityType, Entity
|
||||
|
||||
|
||||
class PackedChat(namedtuple('PackedChat', 'ty id hash')):
|
||||
__slots__ = ()
|
||||
|
||||
@property
|
||||
def is_user(self):
|
||||
return self.ty in (EntityType.USER, EntityType.BOT)
|
||||
|
||||
@property
|
||||
def is_chat(self):
|
||||
return self.ty in (EntityType.GROUP,)
|
||||
|
||||
@property
|
||||
def is_channel(self):
|
||||
return self.ty in (EntityType.CHANNEL, EntityType.MEGAGROUP, EntityType.GIGAGROUP)
|
||||
|
||||
def to_peer(self):
|
||||
if self.is_user:
|
||||
return _tl.PeerUser(user_id=self.id)
|
||||
elif self.is_chat:
|
||||
return _tl.PeerChat(chat_id=self.id)
|
||||
elif self.is_channel:
|
||||
return _tl.PeerChannel(channel_id=self.id)
|
||||
|
||||
def to_input_peer(self):
|
||||
if self.is_user:
|
||||
return _tl.InputPeerUser(user_id=self.id, access_hash=self.hash)
|
||||
elif self.is_chat:
|
||||
return _tl.InputPeerChat(chat_id=self.id)
|
||||
elif self.is_channel:
|
||||
return _tl.InputPeerChannel(channel_id=self.id, access_hash=self.hash)
|
||||
|
||||
def try_to_input_user(self):
|
||||
if self.is_user:
|
||||
return _tl.InputUser(user_id=self.id, access_hash=self.hash)
|
||||
else:
|
||||
return None
|
||||
|
||||
def try_to_chat_id(self):
|
||||
if self.is_chat:
|
||||
return self.id
|
||||
else:
|
||||
return None
|
||||
|
||||
def try_to_input_channel(self):
|
||||
if self.is_channel:
|
||||
return _tl.InputChannel(channel_id=self.id, access_hash=self.hash)
|
||||
else:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return f'{chr(self.ty.value)}.{self.id}.{self.hash}'
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntityCache:
|
||||
hash_map: dict = field(default_factory=dict) # id -> (hash, ty)
|
||||
|
@ -72,8 +19,11 @@ class EntityCache:
|
|||
self.self_bot = bot
|
||||
|
||||
def get(self, id):
|
||||
value = self.hash_map.get(id)
|
||||
return PackedChat(ty=value[1], id=id, hash=value[0]) if value else None
|
||||
try:
|
||||
hash, ty = self.hash_map[id]
|
||||
return Entity(ty, id, hash)
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def extend(self, users, chats):
|
||||
# See https://core.telegram.org/api/min for "issues" with "min constructors".
|
||||
|
@ -100,4 +50,4 @@ class EntityCache:
|
|||
return [Entity(ty, id, hash) for id, (hash, ty) in self.hash_map.items()]
|
||||
|
||||
def put(self, entity):
|
||||
self.hash_map[entity.id] = (entity.access_hash, entity.ty)
|
||||
self.hash_map[entity.id] = (entity.hash, entity.ty)
|
||||
|
|
|
@ -530,7 +530,7 @@ class MessageBox:
|
|||
|
||||
return _tl.fn.updates.GetChannelDifference(
|
||||
force=False,
|
||||
channel=packed.try_to_input_channel(),
|
||||
channel=_tl.InputChannel(packed.id, packed.hash),
|
||||
filter=_tl.ChannelMessagesFilterEmpty(),
|
||||
pts=state.pts,
|
||||
limit=BOT_CHANNEL_DIFF_LIMIT if chat_hashes.self_bot else USER_CHANNEL_DIFF_LIMIT
|
||||
|
|
Loading…
Reference in New Issue
Block a user