mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-01 10:49:58 +03:00
Merge branch 'master' into patch-1
This commit is contained in:
commit
b9ec9c118d
|
@ -3,7 +3,7 @@ String-based Debugging
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Debugging is *really* important. Telegram's API is really big and there
|
Debugging is *really* important. Telegram's API is really big and there
|
||||||
is a lot of things that you should know. Such as, what attributes or fields
|
are a lot of things that you should know. Such as, what attributes or fields
|
||||||
does a result have? Well, the easiest thing to do is printing it:
|
does a result have? Well, the easiest thing to do is printing it:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
@ -32,7 +32,7 @@ Can we get better than the shown string, though? Yes!
|
||||||
|
|
||||||
print(entity.stringify())
|
print(entity.stringify())
|
||||||
|
|
||||||
Will show a much better:
|
Will show a much better representation:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import abc
|
import abc
|
||||||
|
import re
|
||||||
import asyncio
|
import asyncio
|
||||||
import collections
|
import collections
|
||||||
import logging
|
import logging
|
||||||
|
@ -161,11 +162,11 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
device_model (`str`, optional):
|
device_model (`str`, optional):
|
||||||
"Device model" to be sent when creating the initial connection.
|
"Device model" to be sent when creating the initial connection.
|
||||||
Defaults to ``platform.node()``.
|
Defaults to 'PC (n)bit' derived from ``platform.uname().machine``, or its direct value if unknown.
|
||||||
|
|
||||||
system_version (`str`, optional):
|
system_version (`str`, optional):
|
||||||
"System version" to be sent when creating the initial connection.
|
"System version" to be sent when creating the initial connection.
|
||||||
Defaults to ``platform.system()``.
|
Defaults to ``platform.uname().release`` stripped of everything ahead of -.
|
||||||
|
|
||||||
app_version (`str`, optional):
|
app_version (`str`, optional):
|
||||||
"App version" to be sent when creating the initial connection.
|
"App version" to be sent when creating the initial connection.
|
||||||
|
@ -320,11 +321,19 @@ class TelegramBaseClient(abc.ABC):
|
||||||
# Used on connection. Capture the variables in a lambda since
|
# Used on connection. Capture the variables in a lambda since
|
||||||
# exporting clients need to create this InvokeWithLayerRequest.
|
# exporting clients need to create this InvokeWithLayerRequest.
|
||||||
system = platform.uname()
|
system = platform.uname()
|
||||||
|
|
||||||
|
if system.machine in ('x86_64', 'AMD64'):
|
||||||
|
default_device_model = 'PC 64bit'
|
||||||
|
elif system.machine in ('i386','i686','x86'):
|
||||||
|
default_device_model = 'PC 32bit'
|
||||||
|
else:
|
||||||
|
default_device_model = system.machine
|
||||||
|
default_system_version = re.sub(r'-.+','',system.release)
|
||||||
self._init_with = lambda x: functions.InvokeWithLayerRequest(
|
self._init_with = lambda x: functions.InvokeWithLayerRequest(
|
||||||
LAYER, functions.InitConnectionRequest(
|
LAYER, functions.InitConnectionRequest(
|
||||||
api_id=self.api_id,
|
api_id=self.api_id,
|
||||||
device_model=device_model or system.system or 'Unknown',
|
device_model=device_model or default_device_model or 'Unknown',
|
||||||
system_version=system_version or system.release or '1.0',
|
system_version=system_version or default_system_version or '1.0',
|
||||||
app_version=app_version or self.__version__,
|
app_version=app_version or self.__version__,
|
||||||
lang_code=lang_code,
|
lang_code=lang_code,
|
||||||
system_lang_code=system_lang_code,
|
system_lang_code=system_lang_code,
|
||||||
|
|
|
@ -467,6 +467,8 @@ class UpdateMethods:
|
||||||
# the name of speed; we don't want to make it worse for all updates
|
# the name of speed; we don't want to make it worse for all updates
|
||||||
# just because albums may need it.
|
# just because albums may need it.
|
||||||
for builder, callback in self._event_builders:
|
for builder, callback in self._event_builders:
|
||||||
|
if isinstance(builder, events.Raw):
|
||||||
|
continue
|
||||||
if not isinstance(event, builder.Event):
|
if not isinstance(event, builder.Event):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -601,16 +601,52 @@ def get_message_id(message):
|
||||||
|
|
||||||
|
|
||||||
def _get_metadata(file):
|
def _get_metadata(file):
|
||||||
# `hachoir` only deals with paths to in-disk files, while
|
if not hachoir:
|
||||||
# `_get_extension` supports a few other things. The parser
|
return
|
||||||
# may also fail in any case and we don't want to crash if
|
|
||||||
|
stream = None
|
||||||
|
close_stream = True
|
||||||
|
seekable = True
|
||||||
|
|
||||||
|
# The parser may fail and we don't want to crash if
|
||||||
# the extraction process fails.
|
# the extraction process fails.
|
||||||
if hachoir and isinstance(file, str) and os.path.isfile(file):
|
try:
|
||||||
try:
|
# Note: aiofiles are intentionally left out for simplicity
|
||||||
with hachoir.parser.createParser(file) as parser:
|
if isinstance(file, str):
|
||||||
return hachoir.metadata.extractMetadata(parser)
|
stream = open(file, 'rb')
|
||||||
except Exception as e:
|
elif isinstance(file, bytes):
|
||||||
_log.warning('Failed to analyze %s: %s %s', file, e.__class__, e)
|
stream = io.BytesIO(file)
|
||||||
|
else:
|
||||||
|
stream = file
|
||||||
|
close_stream = False
|
||||||
|
if getattr(file, 'seekable', None):
|
||||||
|
seekable = file.seekable()
|
||||||
|
else:
|
||||||
|
seekable = False
|
||||||
|
|
||||||
|
if not seekable:
|
||||||
|
return None
|
||||||
|
|
||||||
|
pos = stream.tell()
|
||||||
|
filename = getattr(file, 'name', '')
|
||||||
|
|
||||||
|
parser = hachoir.parser.guess.guessParser(hachoir.stream.InputIOStream(
|
||||||
|
stream,
|
||||||
|
source='file:' + filename,
|
||||||
|
tags=[],
|
||||||
|
filename=filename
|
||||||
|
))
|
||||||
|
|
||||||
|
return hachoir.metadata.extractMetadata(parser)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_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)
|
||||||
|
|
||||||
|
|
||||||
def get_attributes(file, *, attributes=None, mime_type=None,
|
def get_attributes(file, *, attributes=None, mime_type=None,
|
||||||
|
@ -803,15 +839,31 @@ def is_gif(file):
|
||||||
|
|
||||||
|
|
||||||
def is_audio(file):
|
def is_audio(file):
|
||||||
"""Returns `True` if the file extension looks like an audio file."""
|
"""Returns `True` if the file has an audio mime type."""
|
||||||
file = 'a' + _get_extension(file)
|
ext = _get_extension(file)
|
||||||
return (mimetypes.guess_type(file)[0] or '').startswith('audio/')
|
if not ext:
|
||||||
|
metadata = _get_metadata(file)
|
||||||
|
if metadata and metadata.has('mime_type'):
|
||||||
|
return metadata.get('mime_type').startswith('audio/')
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
file = 'a' + ext
|
||||||
|
return (mimetypes.guess_type(file)[0] or '').startswith('audio/')
|
||||||
|
|
||||||
|
|
||||||
def is_video(file):
|
def is_video(file):
|
||||||
"""Returns `True` if the file extension looks like a video file."""
|
"""Returns `True` if the file has a video mime type."""
|
||||||
file = 'a' + _get_extension(file)
|
ext = _get_extension(file)
|
||||||
return (mimetypes.guess_type(file)[0] or '').startswith('video/')
|
if not ext:
|
||||||
|
metadata = _get_metadata(file)
|
||||||
|
if metadata and metadata.has('mime_type'):
|
||||||
|
return metadata.get('mime_type').startswith('video/')
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
file = 'a' + ext
|
||||||
|
return (mimetypes.guess_type(file)[0] or '').startswith('video/')
|
||||||
|
|
||||||
|
|
||||||
def is_list_like(obj):
|
def is_list_like(obj):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user