2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 21:38:04 +00:00

Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/__init__.py
#	pyrogram/client/methods/chats/export_chat_invite_link.py
#	pyrogram/client/parser/html.py
This commit is contained in:
Dan 2019-07-01 14:49:47 +02:00
commit b20e0ef2d2
11 changed files with 33 additions and 28 deletions

View File

@ -4,7 +4,7 @@ recursive-include compiler *.py *.tl *.tsv *.txt
recursive-include pyrogram mime.types schema.sql recursive-include pyrogram mime.types schema.sql
## Exclude ## Exclude
prune pyrogram/api/errors/exceptions prune pyrogram/errors/exceptions
prune pyrogram/api/functions prune pyrogram/api/functions
prune pyrogram/api/types prune pyrogram/api/types
exclude pyrogram/api/all.py exclude pyrogram/api/all.py

View File

@ -28,7 +28,7 @@ app = Client("my_account")
@app.on_message(Filters.private) @app.on_message(Filters.private)
def hello(client, message): def hello(client, message):
message.reply("Hello {}".format(message.from_user.first_name)) message.reply_text("Hello {}".format(message.from_user.first_name))
app.run() app.run()

View File

@ -2,7 +2,7 @@ User-agent: *
Allow: / Allow: /
Disallow: /dev/* Disallow: /dev*
Disallow: /old/* Disallow: /v0*
Sitemap: https://docs.pyrogram.org/sitemap.xml Sitemap: https://docs.pyrogram.org/sitemap.xml

View File

@ -142,7 +142,7 @@ Details
.. automethod:: Chat.archive() .. automethod:: Chat.archive()
.. automethod:: Chat.unarchive() .. automethod:: Chat.unarchive()
.. automethod:: Chat.set_title() .. automethod:: Chat.set_title()
.. automethod:: Chat.set_description) .. automethod:: Chat.set_description()
.. automethod:: Chat.set_photo() .. automethod:: Chat.set_photo()
.. automethod:: Chat.kick_member() .. automethod:: Chat.kick_member()
.. automethod:: Chat.unban_member() .. automethod:: Chat.unban_member()

View File

@ -106,7 +106,7 @@ Welcome to Pyrogram
@app.on_message(Filters.private) @app.on_message(Filters.private)
def hello(client, message): def hello(client, message):
message.reply("Hello {}".format(message.from_user.first_name)) message.reply_text("Hello {}".format(message.from_user.first_name))
app.run() app.run()

View File

@ -78,7 +78,7 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
"**bold**, " "**bold**, "
"__italic__, " "__italic__, "
"--underline--, " "--underline--, "
"~~strikethrough~~, " "~~strike~~, "
"[mention](tg://user?id=23122162), " "[mention](tg://user?id=23122162), "
"[URL](https://pyrogram.org), " "[URL](https://pyrogram.org), "
"`code`, " "`code`, "
@ -128,7 +128,7 @@ The following tags are currently supported:
"<b>bold</b>, " "<b>bold</b>, "
"<i>italic</i>, " "<i>italic</i>, "
"<u>underline</u>, " "<u>underline</u>, "
"<s>strikethrough</s>, " "<s>strike</s>, "
"<a href=\"tg://user?id=23122162\">mention</a>, " "<a href=\"tg://user?id=23122162\">mention</a>, "
"<a href=\"https://pyrogram.org/\">URL</a>, " "<a href=\"https://pyrogram.org/\">URL</a>, "
"<code>code</code>\n\n" "<code>code</code>\n\n"
@ -202,7 +202,7 @@ Nested and Overlapping Entities
------------------------------- -------------------------------
You can also style texts with more than one decoration at once by nesting entities together. For example, you can send You can also style texts with more than one decoration at once by nesting entities together. For example, you can send
a text message with both :bold-underline:`bold and underline` styles, or a text that has both :italic-strike:`italic and a text message with both :bold-underline:`bold and underline` styles, or a text that has both :strike-italic:`italic and
strike` styles, and you can still combine both Markdown and HTML together. strike` styles, and you can still combine both Markdown and HTML together.
Here there are some example texts you can try sending: Here there are some example texts you can try sending:
@ -210,13 +210,13 @@ Here there are some example texts you can try sending:
**Markdown**: **Markdown**:
- ``**bold, --underline--**`` - ``**bold, --underline--**``
- ``**bold __italic --underline ~~striked~~--__**`` - ``**bold __italic --underline ~~strike~~--__**``
- ``**bold __and** italic__`` - ``**bold __and** italic__``
**HTML**: **HTML**:
- ``<b>bold, <u>underline</u></b>`` - ``<b>bold, <u>underline</u></b>``
- ``<b>bold <i>italic <u>underline <s>striked</s></u></i></b>`` - ``<b>bold <i>italic <u>underline <s>strike</s></u></i></b>``
- ``<b>bold <i>and</b> italic</i>`` - ``<b>bold <i>and</b> italic</i>``
**Combined**: **Combined**:

View File

@ -48,18 +48,15 @@ class ExportChatInviteLink(BaseClient):
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
ValueError: In case the chat_id belongs to a user.
""" """
peer = await self.resolve_peer(chat_id) peer = await self.resolve_peer(chat_id)
if isinstance(peer, types.InputPeerChat): if isinstance(peer, (types.InputPeerChannel, types.InputPeerChat)):
return await self.send( return await self.send(
functions.messages.ExportChatInvite( functions.messages.ExportChatInvite(
peer=peer peer=peer
) )
).link ).link
elif isinstance(peer, types.InputPeerChannel): else:
return await self.send( raise ValueError('The chat_id "{}" belongs to a user'.format(chat_id))
functions.channels.ExportInvite(
channel=peer
)
).link

View File

@ -108,7 +108,7 @@ class HTML:
self.client = client self.client = client
async def parse(self, text: str): async def parse(self, text: str):
text = utils.add_surrogates(str(text or "").strip()) text = utils.add_surrogates(text)
parser = Parser(self.client) parser = Parser(self.client)
parser.feed(text) parser.feed(text)

View File

@ -31,6 +31,8 @@ class Parser:
self.markdown = Markdown(client) self.markdown = Markdown(client)
def parse(self, text: str, mode: str = ""): def parse(self, text: str, mode: str = ""):
text = str(text or "").strip()
if mode is None: if mode is None:
return OrderedDict([ return OrderedDict([
("message", text), ("message", text),

View File

@ -59,8 +59,8 @@ class MemoryStorage(Storage):
(1, None, None, 0, None, None) (1, None, None, 0, None, None)
) )
def _import_session_string(self, string_session: str): def _import_session_string(self, session_string: str):
decoded = base64.urlsafe_b64decode(string_session + "=" * (-len(string_session) % 4)) decoded = base64.urlsafe_b64decode(session_string + "=" * (-len(session_string) % 4))
return struct.unpack(self.SESSION_STRING_FMT, decoded) return struct.unpack(self.SESSION_STRING_FMT, decoded)
def export_session_string(self): def export_session_string(self):
@ -86,8 +86,6 @@ class MemoryStorage(Storage):
self.dc_id, self.test_mode, self.auth_key, self.user_id, self.is_bot = imported_session_string self.dc_id, self.test_mode, self.auth_key, self.user_id, self.is_bot = imported_session_string
self.date = 0 self.date = 0
self.name = ":memory:" + str(self.user_id or "<unknown>")
# noinspection PyAttributeOutsideInit # noinspection PyAttributeOutsideInit
def save(self): def save(self):
self.date = int(time.time()) self.date = int(time.time())
@ -132,7 +130,7 @@ class MemoryStorage(Storage):
access_hash=access_hash access_hash=access_hash
) )
raise ValueError("Invalid peer type") raise ValueError("Invalid peer type: {}".format(peer_type))
def get_peer_by_id(self, peer_id: int): def get_peer_by_id(self, peer_id: int):
r = self.conn.execute( r = self.conn.execute(
@ -141,7 +139,7 @@ class MemoryStorage(Storage):
).fetchone() ).fetchone()
if r is None: if r is None:
raise KeyError("ID not found") raise KeyError("ID not found: {}".format(peer_id))
return self._get_input_peer(*r) return self._get_input_peer(*r)
@ -152,10 +150,10 @@ class MemoryStorage(Storage):
).fetchone() ).fetchone()
if r is None: if r is None:
raise KeyError("Username not found") raise KeyError("Username not found: {}".format(username))
if abs(time.time() - r[3]) > self.USERNAME_TTL: if abs(time.time() - r[3]) > self.USERNAME_TTL:
raise KeyError("Username expired") raise KeyError("Username expired: {}".format(username))
return self._get_input_peer(*r[:3]) return self._get_input_peer(*r[:3])
@ -166,7 +164,7 @@ class MemoryStorage(Storage):
).fetchone() ).fetchone()
if r is None: if r is None:
raise KeyError("Phone number not found") raise KeyError("Phone number not found: {}".format(phone_number))
return self._get_input_peer(*r) return self._get_input_peer(*r)

View File

@ -16,6 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import html
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
@ -135,6 +137,12 @@ class User(Object):
self.photo = photo self.photo = photo
self.restriction_reason = restriction_reason self.restriction_reason = restriction_reason
def __format__(self, format_spec):
if format_spec == "mention":
return '<a href="tg://user?id={0}">{1}</a>'.format(self.id, html.escape(self.first_name))
return html.escape(str(self))
@staticmethod @staticmethod
def _parse(client, user: types.User) -> "User" or None: def _parse(client, user: types.User) -> "User" or None:
if user is None: if user is None: