Merge branch 'master' into tgcrypto

This commit is contained in:
Dan 2018-02-16 18:42:43 +01:00
commit 1bf74a9c25
8 changed files with 7890 additions and 71 deletions

View File

@ -23,10 +23,11 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance
"e" if sys.getfilesystemencoding() == "ascii" else "\xe8" "e" if sys.getfilesystemencoding() == "ascii" else "\xe8"
) )
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
__version__ = "0.5.0" __version__ = "0.6.0"
from .api.errors import Error from .api.errors import Error
from .client import ChatAction from .client import ChatAction
from .client import Client from .client import Client
from .client import ParseMode from .client import ParseMode
from .client.input_media import InputMedia from .client.input_media import InputMedia
from .client import Emoji

View File

@ -19,3 +19,4 @@
from .chat_action import ChatAction from .chat_action import ChatAction
from .client import Client from .client import Client
from .parse_mode import ParseMode from .parse_mode import ParseMode
from .emoji import Emoji

View File

@ -706,7 +706,7 @@ class Client:
def resolve_peer(self, peer_id: int or str): def resolve_peer(self, peer_id: int or str):
"""Use this method to get the *InputPeer* of a known *peer_id*. """Use this method to get the *InputPeer* of a known *peer_id*.
It is intended to be used when working with Raw Functions (i.e: a Telegram API method you wish to use which is It is intended to be used when working with Raw Functions (i.e: a Telegram API method you wish to use which is
not available yet in the Client class as an easy-to-use method). not available yet in the Client class as an easy-to-use method).
Args: Args:
@ -2178,6 +2178,7 @@ class Client:
mime_type=mimetypes.types_map[".mp4"], mime_type=mimetypes.types_map[".mp4"],
attributes=[ attributes=[
types.DocumentAttributeVideo( types.DocumentAttributeVideo(
supports_streaming=i.supports_streaming,
duration=i.duration, duration=i.duration,
w=i.width, w=i.width,
h=i.height h=i.height

7810
pyrogram/client/emoji.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,10 +20,11 @@
class InputMedia: class InputMedia:
class Photo: class Photo:
"""This object represents a photo to be sent inside an album. """This object represents a photo to be sent inside an album.
It is intended to be used with :obj:`pyrogram.Client.send_media_group`.
Args: Args:
media (:obj:`str`): media (:obj:`str`):
File to send. Photo file to send.
Pass a file path as string to send a photo that exists on your local machine. Pass a file path as string to send a photo that exists on your local machine.
caption (:obj:`str`): caption (:obj:`str`):
@ -45,19 +46,32 @@ class InputMedia:
class Video: class Video:
"""This object represents a video to be sent inside an album. """This object represents a video to be sent inside an album.
It is intended to be used with :obj:`pyrogram.Client.send_media_group`.
Args: Args:
media (:obj:`str`): media (:obj:`str`):
File to send. Video file to send.
Pass a file path as string to send a video that exists on your local machine. Pass a file path as string to send a video that exists on your local machine.
caption (:obj:`str`): caption (:obj:`str`, optional):
Caption of the video to be sent, 0-200 characters Caption of the video to be sent, 0-200 characters
parse_mode (:obj:`str`): parse_mode (:obj:`str`, optional):
Use :obj:`pyrogram.ParseMode.MARKDOWN` or :obj:`pyrogram.ParseMode.HTML` if you want Telegram apps Use :obj:`pyrogram.ParseMode.MARKDOWN` or :obj:`pyrogram.ParseMode.HTML` if you want Telegram apps
to show bold, italic, fixed-width text or inline URLs in your caption. to show bold, italic, fixed-width text or inline URLs in your caption.
Defaults to Markdown. Defaults to Markdown.
width (:obj:`int`, optional):
Video width.
height (:obj:`int`, optional):
Video height
duration (:obj:`int`, optional):
Video duration.
supports_streaming (:obj:`bool`, optional):
Pass True, if the uploaded video is suitable for streaming.
""" """
def __init__(self, def __init__(self,
@ -66,10 +80,12 @@ class InputMedia:
parse_mode: str = "", parse_mode: str = "",
width: int = 0, width: int = 0,
height: int = 0, height: int = 0,
duration: int = 0): duration: int = 0,
supports_streaming: bool = None):
self.media = media self.media = media
self.caption = caption self.caption = caption
self.parse_mode = parse_mode self.parse_mode = parse_mode
self.width = width self.width = width
self.height = height self.height = height
self.duration = duration self.duration = duration
self.supports_streaming = supports_streaming

View File

@ -24,95 +24,84 @@ from pyrogram.api.types import (
MessageEntityCode as Code, MessageEntityCode as Code,
MessageEntityTextUrl as Url, MessageEntityTextUrl as Url,
MessageEntityPre as Pre, MessageEntityPre as Pre,
MessageEntityMentionName as MentionInvalid,
InputMessageEntityMentionName as Mention InputMessageEntityMentionName as Mention
) )
from . import utils from . import utils
class Markdown: class Markdown:
INLINE_DELIMITERS = { BOLD_DELIMITER = "**"
"**": Bold, ITALIC_DELIMITER = "__"
"__": Italic, CODE_DELIMITER = "`"
"`": Code PRE_DELIMITER = "```"
}
# ``` python MARKDOWN_RE = re.compile(r"```([\w ]*)\n([\w\W]*)(?:\n|)```|\[([^[(]+)\]\(([^])]+)\)|({d})(.+?)\5".format(
# for i in range(10):
# print(i)
# ```
PRE_RE = r"(?P<pre>```(?P<lang>.*)\n(?P<code>(.|\n)*)\n```)"
# [url](github.com)
URL_RE = r"(?P<url>(\[(?P<url_text>.+?)\]\((?P<url_path>.+?)\)))"
# [name](tg://user?id=123456789)
MENTION_RE = r"(?P<mention>(\[(?P<mention_text>.+?)\]\(tg:\/\/user\?id=(?P<user_id>\d+?)\)))"
# **bold**
# __italic__
# `code`
INLINE_RE = r"(?P<inline>(?P<start_delimiter>{d})(?P<body>.+?)(?P<end_delimiter>{d}))".format(
d="|".join( d="|".join(
["".join(i) for i in [ ["".join(i) for i in [
["\{}".format(j) for j in i] ["\{}".format(j) for j in i]
for i in sorted( # Sort delimiters by length for i in [
INLINE_DELIMITERS.keys(), PRE_DELIMITER,
key=lambda k: len(k), # Or: key=len CODE_DELIMITER,
reverse=True ITALIC_DELIMITER,
) BOLD_DELIMITER
]
]] ]]
) )
) ))
MENTION_RE = re.compile(r"tg://user\?id=(\d+)")
MARKDOWN_RE = re.compile("|".join([PRE_RE, MENTION_RE, URL_RE, INLINE_RE])) def __init__(self, peers_by_id: dict):
def __init__(self, peers_by_id):
self.peers_by_id = peers_by_id self.peers_by_id = peers_by_id
def parse(self, text): def parse(self, message: str):
entities = [] entities = []
text = utils.add_surrogates(text) message = utils.add_surrogates(message).strip()
offset = 0 offset = 0
for match in self.MARKDOWN_RE.finditer(text): for match in self.MARKDOWN_RE.finditer(message):
start = match.start() - offset start = match.start() - offset
lang, pre, text, url, style, body = match.groups()
if match.group("pre"): if pre:
pattern = match.group("pre") body = pre = pre.strip()
lang = match.group("lang") entity = Pre(start, len(pre), lang.strip() or "")
replace = match.group("code") offset += len(lang) + len(self.PRE_DELIMITER) * 2
entity = Pre(start, len(replace), lang.strip()) elif url:
offset += len(lang) + 8 mention = self.MENTION_RE.match(url)
elif match.group("url"):
pattern = match.group("url")
replace = match.group("url_text")
path = match.group("url_path")
entity = Url(start, len(replace), path)
offset += len(path) + 4
elif match.group("mention"):
pattern = match.group("mention")
replace = match.group("mention_text")
user_id = match.group("user_id")
entity = Mention(start, len(replace), self.peers_by_id[int(user_id)])
offset += len(user_id) + 17
elif match.group("inline"):
pattern = match.group("inline")
replace = match.group("body")
start_delimiter = match.group("start_delimiter")
end_delimiter = match.group("end_delimiter")
if start_delimiter != end_delimiter: if mention:
user_id = int(mention.group(1))
input_user = self.peers_by_id.get(user_id, None)
entity = (
Mention(start, len(text), input_user)
if input_user
else MentionInvalid(start, len(text), user_id)
)
else:
entity = Url(start, len(text), url)
body = text
offset += len(url) + 4
else:
if style == self.BOLD_DELIMITER:
entity = Bold(start, len(body))
elif style == self.ITALIC_DELIMITER:
entity = Italic(start, len(body))
elif style == self.CODE_DELIMITER:
entity = Code(start, len(body))
elif style == self.PRE_DELIMITER:
entity = Pre(start, len(body), "")
else:
continue continue
entity = self.INLINE_DELIMITERS[start_delimiter](start, len(replace)) offset += len(style) * 2
offset += len(start_delimiter) * 2
else:
continue
entities.append(entity) entities.append(entity)
text = text.replace(pattern, replace) message = message.replace(match.group(), body)
return dict( return dict(
message=utils.remove_surrogates(text), message=utils.remove_surrogates(message),
entities=entities entities=entities
) )

View File

@ -30,6 +30,7 @@ Proxy = namedtuple("Proxy", ["enabled", "hostname", "port", "username", "passwor
class TCP(socks.socksocket): class TCP(socks.socksocket):
def __init__(self, proxy: Proxy): def __init__(self, proxy: Proxy):
super().__init__() super().__init__()
self.settimeout(10)
self.proxy_enabled = False self.proxy_enabled = False
if proxy and proxy.enabled: if proxy and proxy.enabled:

View File

@ -296,7 +296,7 @@ class Session:
break break
try: try:
self._send(functions.Ping(0), False) self._send(functions.PingDelayDisconnect(0, self.PING_INTERVAL + 15), False)
except (OSError, TimeoutError): except (OSError, TimeoutError):
pass pass