mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-07-30 17:59:55 +03:00
Merge pull request #1 from muhammedfurkan/sourcery/master
Sourcery refactored master branch
This commit is contained in:
commit
ea71213b02
|
@ -22,10 +22,9 @@ def make_link_node(rawtext, app, name, options):
|
|||
base += '/'
|
||||
|
||||
set_classes(options)
|
||||
node = nodes.reference(rawtext, utils.unescape(name),
|
||||
return nodes.reference(rawtext, utils.unescape(name),
|
||||
refuri='{}?q={}'.format(base, name),
|
||||
**options)
|
||||
return node
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
|
|
|
@ -109,11 +109,8 @@ class _DraftsIter(RequestIter):
|
|||
r = await self.client(functions.messages.GetAllDraftsRequest())
|
||||
items = r.updates
|
||||
else:
|
||||
peers = []
|
||||
for entity in entities:
|
||||
peers.append(types.InputDialogPeer(
|
||||
await self.client.get_input_entity(entity)))
|
||||
|
||||
peers = [types.InputDialogPeer(
|
||||
await self.client.get_input_entity(entity)) for entity in entities]
|
||||
r = await self.client(functions.messages.GetPeerDialogsRequest(peers))
|
||||
items = r.dialogs
|
||||
|
||||
|
@ -437,11 +434,7 @@ class DialogMethods:
|
|||
"""
|
||||
# If we have enough information (`Dialog.delete` gives it to us),
|
||||
# then we know we don't have to kick ourselves in deactivated chats.
|
||||
if isinstance(entity, types.Chat):
|
||||
deactivated = entity.deactivated
|
||||
else:
|
||||
deactivated = False
|
||||
|
||||
deactivated = entity.deactivated if isinstance(entity, types.Chat) else False
|
||||
entity = await self.get_input_entity(entity)
|
||||
ty = helpers._entity_type(entity)
|
||||
if ty == helpers._EntityType.CHANNEL:
|
||||
|
|
|
@ -385,9 +385,10 @@ class DownloadMethods:
|
|||
if isinstance(media, str):
|
||||
media = utils.resolve_bot_file_id(media)
|
||||
|
||||
if isinstance(media, types.MessageMediaWebPage):
|
||||
if isinstance(media.webpage, types.WebPage):
|
||||
media = media.webpage.document or media.webpage.photo
|
||||
if isinstance(media, types.MessageMediaWebPage) and isinstance(
|
||||
media.webpage, types.WebPage
|
||||
):
|
||||
media = media.webpage.document or media.webpage.photo
|
||||
|
||||
if isinstance(media, (types.MessageMediaPhoto, types.Photo)):
|
||||
return await self._download_photo(
|
||||
|
|
|
@ -521,11 +521,7 @@ class MessageMethods:
|
|||
message_1337 = await client.get_messages(chat, ids=1337)
|
||||
"""
|
||||
if len(args) == 1 and 'limit' not in kwargs:
|
||||
if 'min_id' in kwargs and 'max_id' in kwargs:
|
||||
kwargs['limit'] = None
|
||||
else:
|
||||
kwargs['limit'] = 1
|
||||
|
||||
kwargs['limit'] = None if 'min_id' in kwargs and 'max_id' in kwargs else 1
|
||||
it = self.iter_messages(*args, **kwargs)
|
||||
|
||||
ids = kwargs.get('ids')
|
||||
|
@ -1045,8 +1041,7 @@ class MessageMethods:
|
|||
reply_markup=self.build_reply_markup(buttons),
|
||||
schedule_date=schedule
|
||||
)
|
||||
msg = self._get_response_message(request, await self(request), entity)
|
||||
return msg
|
||||
return self._get_response_message(request, await self(request), entity)
|
||||
|
||||
async def delete_messages(
|
||||
self: 'TelegramClient',
|
||||
|
|
|
@ -311,18 +311,14 @@ class UploadMethods:
|
|||
# we may want to send as an album if all are photo files.
|
||||
if utils.is_list_like(file):
|
||||
media_captions = []
|
||||
document_captions = []
|
||||
if utils.is_list_like(caption):
|
||||
captions = caption
|
||||
else:
|
||||
captions = [caption]
|
||||
|
||||
captions = caption if utils.is_list_like(caption) else [caption]
|
||||
# TODO Fix progress_callback
|
||||
media = []
|
||||
if force_document:
|
||||
documents = file
|
||||
else:
|
||||
documents = []
|
||||
document_captions = []
|
||||
for doc, cap in itertools.zip_longest(file, captions):
|
||||
if utils.is_image(doc) or utils.is_video(doc):
|
||||
media.append(doc)
|
||||
|
|
|
@ -86,7 +86,9 @@ class UserMethods:
|
|||
last_error = e
|
||||
self._log[__name__].warning(
|
||||
'Telegram is having internal issues %s: %s',
|
||||
e.__class__.__name__, e)
|
||||
last_error.__class__.__name__,
|
||||
last_error,
|
||||
)
|
||||
|
||||
await asyncio.sleep(2)
|
||||
except (errors.FloodWaitError, errors.SlowModeWaitError, errors.FloodTestPhoneWaitError) as e:
|
||||
|
|
|
@ -27,13 +27,13 @@ class Factorization:
|
|||
|
||||
while g == 1:
|
||||
x = y
|
||||
for i in range(r):
|
||||
for _ in range(r):
|
||||
y = (pow(y, 2, pq) + c) % pq
|
||||
|
||||
k = 0
|
||||
while k < r and g == 1:
|
||||
ys = y
|
||||
for i in range(min(m, r - k)):
|
||||
for _ in range(min(m, r - k)):
|
||||
y = (pow(y, 2, pq) + c) % pq
|
||||
q = q * (abs(x - y)) % pq
|
||||
|
||||
|
|
|
@ -67,10 +67,10 @@ class CallbackQuery(EventBuilder):
|
|||
if isinstance(pattern, str):
|
||||
pattern = pattern.encode('utf-8')
|
||||
|
||||
match = data if data else pattern
|
||||
match = data or pattern
|
||||
|
||||
if isinstance(match, bytes):
|
||||
self.match = data if data else re.compile(pattern).match
|
||||
self.match = data or re.compile(pattern).match
|
||||
elif not match or callable(match):
|
||||
self.match = match
|
||||
elif hasattr(match, 'match') and callable(match.match):
|
||||
|
|
|
@ -95,9 +95,8 @@ class EventBuilder(abc.ABC):
|
|||
self._resolve_lock = asyncio.Lock()
|
||||
|
||||
async with self._resolve_lock:
|
||||
if not self.resolved:
|
||||
await self._resolve(client)
|
||||
self.resolved = True
|
||||
await self._resolve(client)
|
||||
self.resolved = True
|
||||
|
||||
async def _resolve(self, client):
|
||||
self.chats = await _into_id_set(client, self.chats)
|
||||
|
|
|
@ -151,13 +151,16 @@ class NewMessage(EventBuilder):
|
|||
return
|
||||
if self.outgoing and not event.message.out:
|
||||
return
|
||||
if self.forwards is not None:
|
||||
if bool(self.forwards) != bool(event.message.fwd_from):
|
||||
return
|
||||
if self.forwards is not None and bool(self.forwards) != bool(
|
||||
event.message.fwd_from
|
||||
):
|
||||
return
|
||||
|
||||
if self.from_users is not None:
|
||||
if event.message.sender_id not in self.from_users:
|
||||
return
|
||||
if (
|
||||
self.from_users is not None
|
||||
and event.message.sender_id not in self.from_users
|
||||
):
|
||||
return
|
||||
|
||||
if self.pattern:
|
||||
match = self.pattern(event.message.message or '')
|
||||
|
|
|
@ -131,19 +131,19 @@ class BinaryReader:
|
|||
return [self.tgread_object() for _ in range(self.read_int())]
|
||||
|
||||
clazz = core_objects.get(constructor_id, None)
|
||||
if clazz is None:
|
||||
# If there was still no luck, give up
|
||||
self.seek(-4) # Go back
|
||||
pos = self.tell_position()
|
||||
error = TypeNotFoundError(constructor_id, self.read())
|
||||
self.set_position(pos)
|
||||
raise error
|
||||
if clazz is None:
|
||||
# If there was still no luck, give up
|
||||
self.seek(-4) # Go back
|
||||
pos = self.tell_position()
|
||||
error = TypeNotFoundError(constructor_id, self.read())
|
||||
self.set_position(pos)
|
||||
raise error
|
||||
|
||||
return clazz.from_reader(self)
|
||||
|
||||
def tgread_vector(self):
|
||||
"""Reads a vector (a list) of Telegram objects."""
|
||||
if 0x1cb5c415 != self.read_int(signed=False):
|
||||
if self.read_int(signed=False) != 0x1CB5C415:
|
||||
raise RuntimeError('Invalid constructor code, vector was expected')
|
||||
|
||||
count = self.read_int()
|
||||
|
|
|
@ -45,13 +45,13 @@ class HTMLToTelegramParser(HTMLParser):
|
|||
attrs = dict(attrs)
|
||||
EntityType = None
|
||||
args = {}
|
||||
if tag == 'strong' or tag == 'b':
|
||||
if tag in ['strong', 'b']:
|
||||
EntityType = MessageEntityBold
|
||||
elif tag == 'em' or tag == 'i':
|
||||
elif tag in ['em', 'i']:
|
||||
EntityType = MessageEntityItalic
|
||||
elif tag == 'u':
|
||||
EntityType = MessageEntityUnderline
|
||||
elif tag == 'del' or tag == 's':
|
||||
elif tag in ['del', 's']:
|
||||
EntityType = MessageEntityStrike
|
||||
elif tag == 'blockquote':
|
||||
EntityType = MessageEntityBlockquote
|
||||
|
|
|
@ -91,11 +91,7 @@ def parse(message, delimiters=None, url_re=None):
|
|||
# If the end is after our start, it is affected
|
||||
if ent.offset + ent.length > i:
|
||||
# If the old start is also before ours, it is fully enclosed
|
||||
if ent.offset <= i:
|
||||
ent.length -= len(delim) * 2
|
||||
else:
|
||||
ent.length -= len(delim)
|
||||
|
||||
ent.length -= len(delim) * 2 if ent.offset <= i else len(delim)
|
||||
# Append the found entity
|
||||
ent = delimiters[delim]
|
||||
if ent == MessageEntityPre:
|
||||
|
|
|
@ -111,7 +111,7 @@ def retry_range(retries, force_retry=True):
|
|||
|
||||
# We need at least one iteration even if the retries are 0
|
||||
# when force_retry is True.
|
||||
if force_retry and not (retries is None or retries < 0):
|
||||
if force_retry and retries is not None and retries >= 0:
|
||||
retries += 1
|
||||
|
||||
attempt = 0
|
||||
|
@ -170,11 +170,7 @@ def _sync_enter(self):
|
|||
Helps to cut boilerplate on async context
|
||||
managers that offer synchronous variants.
|
||||
"""
|
||||
if hasattr(self, 'loop'):
|
||||
loop = self.loop
|
||||
else:
|
||||
loop = self._client.loop
|
||||
|
||||
loop = self.loop if hasattr(self, 'loop') else self._client.loop
|
||||
if loop.is_running():
|
||||
raise RuntimeError(
|
||||
'You must use "async with" if the event loop '
|
||||
|
@ -185,11 +181,7 @@ def _sync_enter(self):
|
|||
|
||||
|
||||
def _sync_exit(self, *args):
|
||||
if hasattr(self, 'loop'):
|
||||
loop = self.loop
|
||||
else:
|
||||
loop = self._client.loop
|
||||
|
||||
loop = self.loop if hasattr(self, 'loop') else self._client.loop
|
||||
return loop.run_until_complete(self.__aexit__(*args))
|
||||
|
||||
|
||||
|
|
|
@ -47,11 +47,7 @@ class Connection(abc.ABC):
|
|||
|
||||
async def _connect(self, timeout=None, ssl=None):
|
||||
if not self._proxy:
|
||||
if self._local_addr is not None:
|
||||
local_addr = (self._local_addr, None)
|
||||
else:
|
||||
local_addr = None
|
||||
|
||||
local_addr = (self._local_addr, None) if self._local_addr is not None else None
|
||||
self._reader, self._writer = await asyncio.wait_for(
|
||||
asyncio.open_connection(self._ip, self._port, ssl=ssl, local_addr=local_addr),
|
||||
timeout=timeout
|
||||
|
@ -89,7 +85,7 @@ class Connection(abc.ABC):
|
|||
ssl_version=ssl_mod.PROTOCOL_SSLv23,
|
||||
ciphers='ADH-AES256-SHA'
|
||||
)
|
||||
|
||||
|
||||
s.setblocking(False)
|
||||
|
||||
self._reader, self._writer = await asyncio.open_connection(sock=s)
|
||||
|
|
|
@ -44,8 +44,8 @@ class MTProxyIO:
|
|||
|
||||
# Obfuscated messages secrets cannot start with any of these
|
||||
keywords = (b'PVrG', b'GET ', b'POST', b'\xee\xee\xee\xee')
|
||||
random = os.urandom(64)
|
||||
while True:
|
||||
random = os.urandom(64)
|
||||
if (random[0] != 0xef and
|
||||
random[:4] not in keywords and
|
||||
random[4:4] != b'\0\0\0\0'):
|
||||
|
|
|
@ -21,8 +21,8 @@ class ObfuscatedIO:
|
|||
def init_header(packet_codec):
|
||||
# Obfuscated messages secrets cannot start with any of these
|
||||
keywords = (b'PVrG', b'GET ', b'POST', b'\xee\xee\xee\xee')
|
||||
random = os.urandom(64)
|
||||
while True:
|
||||
random = os.urandom(64)
|
||||
if (random[0] != 0xef and
|
||||
random[:4] not in keywords and
|
||||
random[4:8] != b'\0\0\0\0'):
|
||||
|
|
|
@ -358,7 +358,7 @@ class MTProtoSender:
|
|||
self._state.reset()
|
||||
|
||||
retries = self._retries if self._auto_reconnect else 0
|
||||
|
||||
|
||||
attempt = 0
|
||||
ok = True
|
||||
# We're already "retrying" to connect, so we don't want to force retries
|
||||
|
@ -367,8 +367,12 @@ class MTProtoSender:
|
|||
await self._connect()
|
||||
except (IOError, asyncio.TimeoutError) as e:
|
||||
last_error = e
|
||||
self._log.info('Failed reconnection attempt %d with %s',
|
||||
attempt, e.__class__.__name__)
|
||||
self._log.info(
|
||||
'Failed reconnection attempt %d with %s',
|
||||
attempt,
|
||||
last_error.__class__.__name__,
|
||||
)
|
||||
|
||||
await asyncio.sleep(self._delay)
|
||||
except BufferError as e:
|
||||
# TODO there should probably only be one place to except all these errors
|
||||
|
@ -546,10 +550,11 @@ class MTProtoSender:
|
|||
if state:
|
||||
return [state]
|
||||
|
||||
to_pop = []
|
||||
for state in self._pending_state.values():
|
||||
if state.container_id == msg_id:
|
||||
to_pop.append(state.msg_id)
|
||||
to_pop = [
|
||||
state.msg_id
|
||||
for state in self._pending_state.values()
|
||||
if state.container_id == msg_id
|
||||
]
|
||||
|
||||
if to_pop:
|
||||
return [self._pending_state.pop(x) for x in to_pop]
|
||||
|
|
|
@ -61,9 +61,8 @@ def check_prime_and_good(prime_bytes: bytes, g: int):
|
|||
0x0D, 0x81, 0x15, 0xF6, 0x35, 0xB1, 0x05, 0xEE, 0x2E, 0x4E, 0x15, 0xD0, 0x4B, 0x24, 0x54, 0xBF,
|
||||
0x6F, 0x4F, 0xAD, 0xF0, 0x34, 0xB1, 0x04, 0x03, 0x11, 0x9C, 0xD8, 0xE3, 0xB9, 0x2F, 0xCC, 0x5B))
|
||||
|
||||
if good_prime == prime_bytes:
|
||||
if g in (3, 4, 5, 7):
|
||||
return # It's good
|
||||
if good_prime == prime_bytes and g in (3, 4, 5, 7):
|
||||
return # It's good
|
||||
|
||||
check_prime_and_good_check(int.from_bytes(prime_bytes, 'big'), g)
|
||||
|
||||
|
@ -94,12 +93,12 @@ def is_good_mod_exp_first(modexp, prime) -> bool:
|
|||
diff = prime - modexp
|
||||
min_diff_bits_count = 2048 - 64
|
||||
max_mod_exp_size = 256
|
||||
if diff < 0 or \
|
||||
diff.bit_length() < min_diff_bits_count or \
|
||||
modexp.bit_length() < min_diff_bits_count or \
|
||||
(modexp.bit_length() + 7) // 8 > max_mod_exp_size:
|
||||
return False
|
||||
return True
|
||||
return (
|
||||
diff >= 0
|
||||
and diff.bit_length() >= min_diff_bits_count
|
||||
and modexp.bit_length() >= min_diff_bits_count
|
||||
and (modexp.bit_length() + 7) // 8 <= max_mod_exp_size
|
||||
)
|
||||
|
||||
|
||||
def xor(a: bytes, b: bytes) -> bytes:
|
||||
|
|
|
@ -169,10 +169,7 @@ class SQLiteSession(MemorySession):
|
|||
|
||||
# Fetch the auth_key corresponding to this data center
|
||||
row = self._execute('select auth_key from sessions')
|
||||
if row and row[0]:
|
||||
self._auth_key = AuthKey(data=row[0])
|
||||
else:
|
||||
self._auth_key = None
|
||||
self._auth_key = AuthKey(data=row[0]) if row and row[0] else None
|
||||
|
||||
@MemorySession.auth_key.setter
|
||||
def auth_key(self, value):
|
||||
|
@ -242,11 +239,10 @@ class SQLiteSession(MemorySession):
|
|||
|
||||
def close(self):
|
||||
"""Closes the connection unless we're working in-memory"""
|
||||
if self.filename != ':memory:':
|
||||
if self._conn is not None:
|
||||
self._conn.commit()
|
||||
self._conn.close()
|
||||
self._conn = None
|
||||
if self.filename != ':memory:' and self._conn is not None:
|
||||
self._conn.commit()
|
||||
self._conn.close()
|
||||
self._conn = None
|
||||
|
||||
def delete(self):
|
||||
"""Deletes the current session file"""
|
||||
|
|
|
@ -35,10 +35,7 @@ class StateCache:
|
|||
# is lightweight and immutable we can easily copy them around to
|
||||
# each update in case they need to fetch missing entities.
|
||||
self._logger = loggers[__name__]
|
||||
if initial:
|
||||
self._pts_date = initial.pts, initial.date
|
||||
else:
|
||||
self._pts_date = None, None
|
||||
self._pts_date = (initial.pts, initial.date) if initial else (None, None)
|
||||
|
||||
def reset(self):
|
||||
self.__dict__.clear()
|
||||
|
|
|
@ -54,9 +54,10 @@ def syncify(*types):
|
|||
# about asyncgenfunction's here.
|
||||
for t in types:
|
||||
for name in dir(t):
|
||||
if not name.startswith('_') or name == '__call__':
|
||||
if inspect.iscoroutinefunction(getattr(t, name)):
|
||||
_syncify_wrap(t, name)
|
||||
if (
|
||||
not name.startswith('_') or name == '__call__'
|
||||
) and inspect.iscoroutinefunction(getattr(t, name)):
|
||||
_syncify_wrap(t, name)
|
||||
|
||||
|
||||
syncify(TelegramClient, _TakeoutClient, Draft, Dialog, MessageButton,
|
||||
|
|
|
@ -71,11 +71,7 @@ class Conversation(ChatGetter):
|
|||
# The user is able to expect two responses for the same message.
|
||||
# {desired message ID: next incoming index}
|
||||
self._response_indices = {}
|
||||
if replies_are_responses:
|
||||
self._reply_indices = self._response_indices
|
||||
else:
|
||||
self._reply_indices = {}
|
||||
|
||||
self._reply_indices = self._response_indices if replies_are_responses else {}
|
||||
self._edit_dates = {}
|
||||
|
||||
@_checks_cancelled
|
||||
|
@ -120,10 +116,7 @@ class Conversation(ChatGetter):
|
|||
<telethon.client.messages.MessageMethods.send_read_acknowledge>`.
|
||||
"""
|
||||
if message is None:
|
||||
if self._incoming:
|
||||
message = self._incoming[-1].id
|
||||
else:
|
||||
message = 0
|
||||
message = self._incoming[-1].id if self._incoming else 0
|
||||
elif not isinstance(message, int):
|
||||
message = message.id
|
||||
|
||||
|
|
|
@ -189,11 +189,7 @@ class InlineBuilder:
|
|||
See "Type of the result" in https://core.telegram.org/bots/api.
|
||||
"""
|
||||
if type is None:
|
||||
if voice_note:
|
||||
type = 'voice'
|
||||
else:
|
||||
type = 'document'
|
||||
|
||||
type = 'voice' if voice_note else 'document'
|
||||
try:
|
||||
fh = utils.get_input_document(file)
|
||||
except TypeError:
|
||||
|
|
|
@ -453,9 +453,10 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
|
|||
"""
|
||||
The :tl:`WebPage` media in this message, if any.
|
||||
"""
|
||||
if isinstance(self.media, types.MessageMediaWebPage):
|
||||
if isinstance(self.media.webpage, types.WebPage):
|
||||
return self.media.webpage
|
||||
if isinstance(self.media, types.MessageMediaWebPage) and isinstance(
|
||||
self.media.webpage, types.WebPage
|
||||
):
|
||||
return self.media.webpage
|
||||
|
||||
@property
|
||||
def audio(self):
|
||||
|
@ -920,14 +921,14 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
|
|||
return [answers[idx].option for idx in i]
|
||||
return [answers[i].option]
|
||||
if text is not None:
|
||||
if callable(text):
|
||||
for answer in answers:
|
||||
if text(answer.text):
|
||||
return [answer.option]
|
||||
else:
|
||||
for answer in answers:
|
||||
if answer.text == text:
|
||||
return [answer.option]
|
||||
for answer in answers:
|
||||
if (
|
||||
callable(text)
|
||||
and text(answer.text)
|
||||
or not callable(text)
|
||||
and answer.text == text
|
||||
):
|
||||
return [answer.option]
|
||||
return
|
||||
|
||||
if filter is not None:
|
||||
|
@ -953,14 +954,14 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
|
|||
def find_button():
|
||||
nonlocal i
|
||||
if text is not None:
|
||||
if callable(text):
|
||||
for button in self._buttons_flat:
|
||||
if text(button.text):
|
||||
return button
|
||||
else:
|
||||
for button in self._buttons_flat:
|
||||
if button.text == text:
|
||||
return button
|
||||
for button in self._buttons_flat:
|
||||
if (
|
||||
callable(text)
|
||||
and text(button.text)
|
||||
or not callable(text)
|
||||
and button.text == text
|
||||
):
|
||||
return button
|
||||
return
|
||||
|
||||
if filter is not None:
|
||||
|
|
|
@ -37,10 +37,10 @@ class TLObject:
|
|||
Pretty formats the given object as a string which is returned.
|
||||
If indent is None, a single line will be returned.
|
||||
"""
|
||||
if indent is None:
|
||||
if isinstance(obj, TLObject):
|
||||
obj = obj.to_dict()
|
||||
if isinstance(obj, TLObject):
|
||||
obj = obj.to_dict()
|
||||
|
||||
if indent is None:
|
||||
if isinstance(obj, dict):
|
||||
return '{}({})'.format(obj.get('_', 'dict'), ', '.join(
|
||||
'{}={}'.format(k, TLObject.pretty_format(v))
|
||||
|
@ -56,9 +56,6 @@ class TLObject:
|
|||
return repr(obj)
|
||||
else:
|
||||
result = []
|
||||
if isinstance(obj, TLObject):
|
||||
obj = obj.to_dict()
|
||||
|
||||
if isinstance(obj, dict):
|
||||
result.append(obj.get('_', 'dict'))
|
||||
result.append('(')
|
||||
|
@ -115,8 +112,6 @@ class TLObject:
|
|||
padding = 4 - padding
|
||||
|
||||
r.append(bytes([len(data)]))
|
||||
r.append(data)
|
||||
|
||||
else:
|
||||
padding = len(data) % 4
|
||||
if padding != 0:
|
||||
|
@ -128,7 +123,7 @@ class TLObject:
|
|||
(len(data) >> 8) % 256,
|
||||
(len(data) >> 16) % 256
|
||||
]))
|
||||
r.append(data)
|
||||
r.append(data)
|
||||
|
||||
r.append(bytes(padding))
|
||||
return b''.join(r)
|
||||
|
|
|
@ -621,11 +621,7 @@ def _get_metadata(file):
|
|||
else:
|
||||
stream = file
|
||||
close_stream = False
|
||||
if getattr(file, 'seekable', None):
|
||||
seekable = file.seekable()
|
||||
else:
|
||||
seekable = False
|
||||
|
||||
seekable = file.seekable() if getattr(file, 'seekable', None) else False
|
||||
if not seekable:
|
||||
return None
|
||||
|
||||
|
@ -645,10 +641,12 @@ def _get_metadata(file):
|
|||
_log.warning('Failed to analyze %s: %s %s', file, e.__class__, e)
|
||||
|
||||
finally:
|
||||
if stream and close_stream:
|
||||
stream.close()
|
||||
elif stream and seekable:
|
||||
stream.seek(pos)
|
||||
if close_stream:
|
||||
if stream:
|
||||
stream.close()
|
||||
elif seekable:
|
||||
if stream:
|
||||
stream.seek(pos)
|
||||
|
||||
|
||||
def get_attributes(file, *, attributes=None, mime_type=None,
|
||||
|
|
|
@ -158,13 +158,13 @@ class InteractiveTelegramClient(TelegramClient):
|
|||
# are much easier to use.
|
||||
self.add_event_handler(self.message_handler, events.NewMessage)
|
||||
|
||||
# Retrieve the top dialogs. You can set the limit to None to
|
||||
# retrieve all of them if you wish, but beware that may take
|
||||
# a long time if you have hundreds of them.
|
||||
dialog_count = 15
|
||||
|
||||
# Enter a while loop to chat as long as the user wants
|
||||
while True:
|
||||
# Retrieve the top dialogs. You can set the limit to None to
|
||||
# retrieve all of them if you wish, but beware that may take
|
||||
# a long time if you have hundreds of them.
|
||||
dialog_count = 15
|
||||
|
||||
# Entities represent the user, chat or channel
|
||||
# corresponding to the dialog on the same index.
|
||||
dialogs = await self.get_dialogs(limit=dialog_count)
|
||||
|
@ -198,7 +198,7 @@ class InteractiveTelegramClient(TelegramClient):
|
|||
return
|
||||
|
||||
try:
|
||||
i = int(i if i else 0) - 1
|
||||
i = int(i or 0) - 1
|
||||
# Ensure it is inside the bounds, otherwise retry
|
||||
if not 0 <= i < dialog_count:
|
||||
i = None
|
||||
|
|
|
@ -67,16 +67,15 @@ async def handler(event):
|
|||
await event.reply('> chrome\nneeds more firefox')
|
||||
|
||||
# Reply always responds as a reply. We can respond without replying too
|
||||
if 'shrug' in event.raw_text:
|
||||
if can_react(event.chat_id):
|
||||
await event.respond(r'¯\_(ツ)_/¯')
|
||||
|
||||
# We can also use client methods from here
|
||||
client = event.client
|
||||
if 'shrug' in event.raw_text and can_react(event.chat_id):
|
||||
await event.respond(r'¯\_(ツ)_/¯')
|
||||
|
||||
# If we sent the message, we are replying to someone,
|
||||
# and we said "save pic" in the message
|
||||
if event.out and event.is_reply and 'save pic' in event.raw_text:
|
||||
# We can also use client methods from here
|
||||
client = event.client
|
||||
|
||||
reply_msg = await event.get_reply_message()
|
||||
replied_to_user = await reply_msg.get_input_sender()
|
||||
|
||||
|
|
|
@ -261,36 +261,42 @@ def _write_class_init(tlobject, kind, type_constructors, builder):
|
|||
|
||||
|
||||
def _write_resolve(tlobject, builder):
|
||||
if tlobject.is_function and any(
|
||||
(arg.type in AUTO_CASTS
|
||||
or ((arg.name, arg.type) in NAMED_AUTO_CASTS
|
||||
and tlobject.fullname not in NAMED_BLACKLIST))
|
||||
for arg in tlobject.real_args
|
||||
if not tlobject.is_function or not any(
|
||||
(
|
||||
arg.type in AUTO_CASTS
|
||||
or (
|
||||
(arg.name, arg.type) in NAMED_AUTO_CASTS
|
||||
and tlobject.fullname not in NAMED_BLACKLIST
|
||||
)
|
||||
)
|
||||
for arg in tlobject.real_args
|
||||
):
|
||||
builder.writeln('async def resolve(self, client, utils):')
|
||||
for arg in tlobject.real_args:
|
||||
ac = AUTO_CASTS.get(arg.type)
|
||||
if not ac:
|
||||
ac = NAMED_AUTO_CASTS.get((arg.name, arg.type))
|
||||
if not ac:
|
||||
continue
|
||||
return
|
||||
|
||||
if arg.is_flag:
|
||||
builder.writeln('if self.{}:', arg.name)
|
||||
builder.writeln('async def resolve(self, client, utils):')
|
||||
for arg in tlobject.real_args:
|
||||
ac = AUTO_CASTS.get(arg.type)
|
||||
if not ac:
|
||||
ac = NAMED_AUTO_CASTS.get((arg.name, arg.type))
|
||||
if not ac:
|
||||
continue
|
||||
|
||||
if arg.is_vector:
|
||||
builder.writeln('_tmp = []')
|
||||
builder.writeln('for _x in self.{0}:', arg.name)
|
||||
builder.writeln('_tmp.append({})', ac.format('_x'))
|
||||
builder.end_block()
|
||||
builder.writeln('self.{} = _tmp', arg.name)
|
||||
else:
|
||||
builder.writeln('self.{} = {}', arg.name,
|
||||
ac.format('self.' + arg.name))
|
||||
if arg.is_flag:
|
||||
builder.writeln('if self.{}:', arg.name)
|
||||
|
||||
if arg.is_flag:
|
||||
builder.end_block()
|
||||
builder.end_block()
|
||||
if arg.is_vector:
|
||||
builder.writeln('_tmp = []')
|
||||
builder.writeln('for _x in self.{0}:', arg.name)
|
||||
builder.writeln('_tmp.append({})', ac.format('_x'))
|
||||
builder.end_block()
|
||||
builder.writeln('self.{} = _tmp', arg.name)
|
||||
else:
|
||||
builder.writeln('self.{} = {}', arg.name,
|
||||
ac.format('self.' + arg.name))
|
||||
|
||||
if arg.is_flag:
|
||||
builder.end_block()
|
||||
builder.end_block()
|
||||
|
||||
|
||||
def _write_to_dict(tlobject, builder):
|
||||
|
|
|
@ -55,8 +55,8 @@ class TLObject:
|
|||
self.class_name = snake_to_camel_case(
|
||||
self.name, suffix='Request' if self.is_function else '')
|
||||
|
||||
self.real_args = list(a for a in self.sorted_args() if not
|
||||
(a.flag_indicator or a.generic_definition))
|
||||
self.real_args = [a for a in self.sorted_args() if not
|
||||
(a.flag_indicator or a.generic_definition)]
|
||||
|
||||
@property
|
||||
def innermost_result(self):
|
||||
|
@ -75,16 +75,8 @@ class TLObject:
|
|||
key=lambda x: x.is_flag or x.can_be_inferred)
|
||||
|
||||
def __repr__(self, ignore_id=False):
|
||||
if self.id is None or ignore_id:
|
||||
hex_id = ''
|
||||
else:
|
||||
hex_id = '#{:08x}'.format(self.id)
|
||||
|
||||
if self.args:
|
||||
args = ' ' + ' '.join([repr(arg) for arg in self.args])
|
||||
else:
|
||||
args = ''
|
||||
|
||||
hex_id = '' if self.id is None or ignore_id else '#{:08x}'.format(self.id)
|
||||
args = ' ' + ' '.join([repr(arg) for arg in self.args]) if self.args else ''
|
||||
return '{}{}{} = {}'.format(self.fullname, hex_id, args, self.result)
|
||||
|
||||
def infer_id(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user