mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-12-01 22:03:46 +03:00
Add friendly method to get admin log (#952)
This commit is contained in:
parent
95cf873bad
commit
4ccabaf422
|
@ -1,8 +1,11 @@
|
||||||
|
import itertools
|
||||||
|
import sys
|
||||||
|
|
||||||
from async_generator import async_generator, yield_
|
from async_generator import async_generator, yield_
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import utils, helpers
|
from .. import utils, helpers
|
||||||
from ..tl import types, functions
|
from ..tl import types, functions, custom
|
||||||
|
|
||||||
|
|
||||||
class ChatMethods(UserMethods):
|
class ChatMethods(UserMethods):
|
||||||
|
@ -188,4 +191,150 @@ class ChatMethods(UserMethods):
|
||||||
participants.total = total[0]
|
participants.total = total[0]
|
||||||
return participants
|
return participants
|
||||||
|
|
||||||
|
@async_generator
|
||||||
|
async def iter_admin_log(
|
||||||
|
self, entity, limit=None, *, max_id=0, min_id=0, search=None,
|
||||||
|
admins=None, join=None, leave=None, invite=None, restrict=None,
|
||||||
|
unrestrict=None, ban=None, unban=None, promote=None, demote=None,
|
||||||
|
info=None, settings=None, pinned=None, edit=None, delete=None):
|
||||||
|
"""
|
||||||
|
Iterator over the admin log for the specified channel.
|
||||||
|
|
||||||
|
Note that you must be an administrator of it to use this method.
|
||||||
|
|
||||||
|
If none of the filters are present (i.e. they all are ``None``),
|
||||||
|
*all* event types will be returned. If at least one of them is
|
||||||
|
``True``, only those that are true will be returned.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entity (`entity`):
|
||||||
|
The channel entity from which to get its admin log.
|
||||||
|
|
||||||
|
limit (`int` | `None`, optional):
|
||||||
|
Number of events to be retrieved.
|
||||||
|
|
||||||
|
The limit may also be ``None``, which would eventually return
|
||||||
|
the whole history.
|
||||||
|
|
||||||
|
max_id (`int`):
|
||||||
|
All the events with a higher (newer) ID or equal to this will
|
||||||
|
be excluded.
|
||||||
|
|
||||||
|
min_id (`int`):
|
||||||
|
All the events with a lower (older) ID or equal to this will
|
||||||
|
be excluded.
|
||||||
|
|
||||||
|
search (`str`):
|
||||||
|
The string to be used as a search query.
|
||||||
|
|
||||||
|
admins (`entity` | `list`):
|
||||||
|
If present, the events will be filtered by these admins
|
||||||
|
(or single admin) and only those caused by them will be
|
||||||
|
returned.
|
||||||
|
|
||||||
|
join (`bool`):
|
||||||
|
If ``True``, events for when a user joined will be returned.
|
||||||
|
|
||||||
|
leave (`bool`):
|
||||||
|
If ``True``, events for when a user leaves will be returned.
|
||||||
|
|
||||||
|
invite (`bool`):
|
||||||
|
If ``True``, events for when a user joins through an invite
|
||||||
|
link will be returned.
|
||||||
|
|
||||||
|
restrict (`bool`):
|
||||||
|
If ``True``, events with partial restrictions will be
|
||||||
|
returned. This is what the API calls "ban".
|
||||||
|
|
||||||
|
unrestrict (`bool`):
|
||||||
|
If ``True``, events removing restrictions will be returned.
|
||||||
|
This is what the API calls "unban".
|
||||||
|
|
||||||
|
ban (`bool`):
|
||||||
|
If ``True``, events applying or removing all restrictions will
|
||||||
|
be returned. This is what the API calls "kick" (restricting
|
||||||
|
all permissions removed is a ban, which kicks the user).
|
||||||
|
|
||||||
|
unban (`bool`):
|
||||||
|
If ``True``, events removing all restrictions will be
|
||||||
|
returned. This is what the API calls "unkick".
|
||||||
|
|
||||||
|
promote (`bool`):
|
||||||
|
If ``True``, events with admin promotions will be returned.
|
||||||
|
|
||||||
|
demote (`bool`):
|
||||||
|
If ``True``, events with admin demotions will be returned.
|
||||||
|
|
||||||
|
info (`bool`):
|
||||||
|
If ``True``, events changing the group info will be returned.
|
||||||
|
|
||||||
|
settings (`bool`):
|
||||||
|
If ``True``, events changing the group settings will be
|
||||||
|
returned.
|
||||||
|
|
||||||
|
pinned (`bool`):
|
||||||
|
If ``True``, events of new pinned messages will be returned.
|
||||||
|
|
||||||
|
edit (`bool`):
|
||||||
|
If ``True``, events of message edits will be returned.
|
||||||
|
|
||||||
|
delete (`bool`):
|
||||||
|
If ``True``, events of message deletions will be returned.
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
Instances of `telethon.tl.custom.adminlogevent.AdminLogEvent`.
|
||||||
|
"""
|
||||||
|
if limit is None:
|
||||||
|
limit = sys.maxsize
|
||||||
|
elif limit <= 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
if any((join, leave, invite, restrict, unrestrict, ban, unban,
|
||||||
|
promote, demote, info, settings, pinned, edit, delete)):
|
||||||
|
events_filter = types.ChannelAdminLogEventsFilter(
|
||||||
|
join=join, leave=leave, invite=invite, ban=restrict,
|
||||||
|
unban=unrestrict, kick=ban, unkick=unban, promote=promote,
|
||||||
|
demote=demote, info=info, settings=settings, pinned=pinned,
|
||||||
|
edit=edit, delete=delete
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
events_filter = None
|
||||||
|
|
||||||
|
entity = await self.get_input_entity(entity)
|
||||||
|
|
||||||
|
admin_list = []
|
||||||
|
if admins:
|
||||||
|
if not utils.is_list_like(admins):
|
||||||
|
admins = (admins,)
|
||||||
|
|
||||||
|
for admin in admins:
|
||||||
|
admin_list.append(await self.get_input_entity(admin))
|
||||||
|
|
||||||
|
request = functions.channels.GetAdminLogRequest(
|
||||||
|
entity, q=search or '', min_id=min_id, max_id=max_id,
|
||||||
|
limit=0, events_filter=events_filter, admins=admin_list or None
|
||||||
|
)
|
||||||
|
while limit > 0:
|
||||||
|
request.limit = min(limit, 100)
|
||||||
|
result = await self(request)
|
||||||
|
limit -= len(result.events)
|
||||||
|
entities = {utils.get_peer_id(x): x
|
||||||
|
for x in itertools.chain(result.users, result.chats)}
|
||||||
|
|
||||||
|
request.max_id = min((e.id for e in result.events), default=0)
|
||||||
|
for event in result.events:
|
||||||
|
await yield_(custom.AdminLogEvent(event, entities))
|
||||||
|
|
||||||
|
if len(result.events) < request.limit:
|
||||||
|
break
|
||||||
|
|
||||||
|
async def get_admin_log(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Same as `iter_admin_log`, but returns a ``list`` instead.
|
||||||
|
"""
|
||||||
|
admin_log = []
|
||||||
|
async for x in self.iter_admin_log(*args, **kwargs):
|
||||||
|
admin_log.append(x)
|
||||||
|
return admin_log
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from .adminlogevent import AdminLogEvent
|
||||||
from .draft import Draft
|
from .draft import Draft
|
||||||
from .dialog import Dialog
|
from .dialog import Dialog
|
||||||
from .inputsizedfile import InputSizedFile
|
from .inputsizedfile import InputSizedFile
|
||||||
|
|
294
telethon/tl/custom/adminlogevent.py
Normal file
294
telethon/tl/custom/adminlogevent.py
Normal file
|
@ -0,0 +1,294 @@
|
||||||
|
from ...tl import types
|
||||||
|
from ...utils import get_input_peer
|
||||||
|
|
||||||
|
|
||||||
|
class AdminLogEvent:
|
||||||
|
"""
|
||||||
|
Represents a more friendly interface for admin log events.
|
||||||
|
|
||||||
|
Members:
|
||||||
|
original (:tl:`ChannelAdminLogEvent`):
|
||||||
|
The original :tl:`ChannelAdminLogEvent`.
|
||||||
|
|
||||||
|
entities (`dict`):
|
||||||
|
A dictionary mapping user IDs to :tl:`User`.
|
||||||
|
|
||||||
|
When `old` and `new` are :tl:`ChannelParticipant`, you can
|
||||||
|
use this dictionary to map the ``user_id``, ``kicked_by``,
|
||||||
|
``inviter_id`` and ``promoted_by`` IDs to their :tl:`User`.
|
||||||
|
|
||||||
|
user (:tl:`User`):
|
||||||
|
The user that caused this action (``entities[original.user_id]``).
|
||||||
|
|
||||||
|
input_user (:tl:`InputPeerUser`):
|
||||||
|
Input variant of `user`.
|
||||||
|
"""
|
||||||
|
def __init__(self, original, entities):
|
||||||
|
self.original = original
|
||||||
|
self.entities = entities
|
||||||
|
self.user = entities[original.user_id]
|
||||||
|
self.input_user = get_input_peer(self.user)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
"""
|
||||||
|
The ID of this event.
|
||||||
|
"""
|
||||||
|
return self.original.id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def date(self):
|
||||||
|
"""
|
||||||
|
The date when this event occured.
|
||||||
|
"""
|
||||||
|
return self.original.date
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_id(self):
|
||||||
|
"""
|
||||||
|
The ID of the user that triggered this event.
|
||||||
|
"""
|
||||||
|
return self.original.user_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def action(self):
|
||||||
|
"""
|
||||||
|
The original :tl:`ChannelAdminLogEventAction`.
|
||||||
|
"""
|
||||||
|
return self.original.action
|
||||||
|
|
||||||
|
@property
|
||||||
|
def old(self):
|
||||||
|
"""
|
||||||
|
The old value from the event.
|
||||||
|
"""
|
||||||
|
ori = self.original
|
||||||
|
if isinstance(ori, (
|
||||||
|
types.ChannelAdminLogEventActionChangeAbout,
|
||||||
|
types.ChannelAdminLogEventActionChangeTitle,
|
||||||
|
types.ChannelAdminLogEventActionChangeUsername
|
||||||
|
)):
|
||||||
|
return ori.prev_value
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionChangePhoto):
|
||||||
|
return ori.prev_photo
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionChangeStickerSet):
|
||||||
|
return ori.prev_stickerset
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionEditMessage):
|
||||||
|
return ori.prev_message
|
||||||
|
elif isinstance(ori, (
|
||||||
|
types.ChannelAdminLogEventActionParticipantToggleAdmin,
|
||||||
|
types.ChannelAdminLogEventActionParticipantToggleBan
|
||||||
|
)):
|
||||||
|
return ori.prev_participant
|
||||||
|
elif isinstance(ori, (
|
||||||
|
types.ChannelAdminLogEventActionToggleInvites,
|
||||||
|
types.ChannelAdminLogEventActionTogglePreHistoryHidden,
|
||||||
|
types.ChannelAdminLogEventActionToggleSignatures
|
||||||
|
)):
|
||||||
|
return not ori.new_value
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionDeleteMessage):
|
||||||
|
return ori.message
|
||||||
|
|
||||||
|
@property
|
||||||
|
def new(self):
|
||||||
|
"""
|
||||||
|
The new value present in the event.
|
||||||
|
"""
|
||||||
|
ori = self.original
|
||||||
|
if isinstance(ori, (
|
||||||
|
types.ChannelAdminLogEventActionChangeAbout,
|
||||||
|
types.ChannelAdminLogEventActionChangeTitle,
|
||||||
|
types.ChannelAdminLogEventActionChangeUsername,
|
||||||
|
types.ChannelAdminLogEventActionToggleInvites,
|
||||||
|
types.ChannelAdminLogEventActionTogglePreHistoryHidden,
|
||||||
|
types.ChannelAdminLogEventActionToggleSignatures
|
||||||
|
)):
|
||||||
|
return ori.new_value
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionChangePhoto):
|
||||||
|
return ori.new_photo
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionChangeStickerSet):
|
||||||
|
return ori.new_stickerset
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionEditMessage):
|
||||||
|
return ori.new_message
|
||||||
|
elif isinstance(ori, (
|
||||||
|
types.ChannelAdminLogEventActionParticipantToggleAdmin,
|
||||||
|
types.ChannelAdminLogEventActionParticipantToggleBan
|
||||||
|
)):
|
||||||
|
return ori.new_participant
|
||||||
|
elif isinstance(ori, types.ChannelAdminLogEventActionParticipantInvite):
|
||||||
|
return ori.participant
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_about(self):
|
||||||
|
"""
|
||||||
|
Whether the channel's about was changed in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as ``str``.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionChangeAbout)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_title(self):
|
||||||
|
"""
|
||||||
|
Whether the channel's title was changed in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as ``str``.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionChangeTitle)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_username(self):
|
||||||
|
"""
|
||||||
|
Whether the channel's username was changed in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as ``str``.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionChangeUsername)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_photo(self):
|
||||||
|
"""
|
||||||
|
Whether the channel's photo was changed in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as :tl:`ChatPhoto`.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionChangePhoto)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_sticker_set(self):
|
||||||
|
"""
|
||||||
|
Whether the channel's sticker set was changed in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as :tl:`InputStickerSet`.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionChangeStickerSet)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_message(self):
|
||||||
|
"""
|
||||||
|
Whether a message in this channel was edited in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as
|
||||||
|
`Message <telethon.tl.custom.message.Message>`.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionEditMessage)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deleted_message(self):
|
||||||
|
"""
|
||||||
|
Whether a message in this channel was deleted in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` will be present as
|
||||||
|
`Message <telethon.tl.custom.message.Message>`.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionDeleteMessage)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_admin(self):
|
||||||
|
"""
|
||||||
|
Whether the permissions for an admin in this channel
|
||||||
|
changed in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as
|
||||||
|
:tl:`ChannelParticipant`.
|
||||||
|
"""
|
||||||
|
return isinstance(
|
||||||
|
self.original,
|
||||||
|
types.ChannelAdminLogEventActionParticipantToggleAdmin)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_restrictions(self):
|
||||||
|
"""
|
||||||
|
Whether a message in this channel was edited in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as
|
||||||
|
:tl:`ChannelParticipant`.
|
||||||
|
"""
|
||||||
|
return isinstance(
|
||||||
|
self.original,
|
||||||
|
types.ChannelAdminLogEventActionParticipantToggleBan)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_invites(self):
|
||||||
|
"""
|
||||||
|
Whether the invites in the channel were toggled in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as ``bool``.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionToggleInvites)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def joined(self):
|
||||||
|
"""
|
||||||
|
Whether `user` joined through the channel's
|
||||||
|
public username in this event or not.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionParticipantJoin)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def joined_invite(self):
|
||||||
|
"""
|
||||||
|
Whether a new user joined through an invite
|
||||||
|
link to the channel in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `new` will be present as
|
||||||
|
:tl:`ChannelParticipant`.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionParticipantInvite)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def left(self):
|
||||||
|
"""
|
||||||
|
Whether `user` left the channel in this event or not.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionParticipantLeave)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_hide_history(self):
|
||||||
|
"""
|
||||||
|
Whether hiding the previous message history for new members
|
||||||
|
in the channel were toggled in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as ``bool``.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionTogglePreHistoryHidden)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_signatures(self):
|
||||||
|
"""
|
||||||
|
Whether the message signatures in the channel were toggled
|
||||||
|
in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `old` and `new` will be present as ``bool``.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionToggleSignatures)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_pin(self):
|
||||||
|
"""
|
||||||
|
Whether a new message in this channel was pinned in this event or not.
|
||||||
|
|
||||||
|
If ``True``, `new` will be present as
|
||||||
|
`Message <telethon.tl.custom.message.Message>`.
|
||||||
|
"""
|
||||||
|
return isinstance(self.original,
|
||||||
|
types.ChannelAdminLogEventActionUpdatePinned)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.original)
|
||||||
|
|
||||||
|
def stringify(self):
|
||||||
|
return self.original.stringify()
|
Loading…
Reference in New Issue
Block a user