Skip to content

Commit 00ab295

Browse files
authored
feat: add some new methods and types.
- not remembered everything.
1 parent 707d3d6 commit 00ab295

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+18216
-433
lines changed

.github/workflows/tag_and_publish.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ jobs:
3030
echo "RELEASE_EXISTS=false" >> $GITHUB_ENV
3131
fi
3232
33+
- name: Get Commit Messages
34+
id: get_commits
35+
run: |
36+
COMMITS=$(git log -1 --pretty=format:"%s" HEAD)
37+
echo "COMMITS=$COMMITS" >> $GITHUB_ENV
38+
3339
- name: Create New Release
3440
if: env.RELEASE_EXISTS == 'false'
3541
uses: actions/create-release@v1
@@ -38,7 +44,11 @@ jobs:
3844
with:
3945
tag_name: ${{ env.VERSION }}
4046
release_name: Release ${{ env.VERSION }}
41-
body: Release ${{ env.VERSION }}
47+
body: |
48+
Release ${{ env.VERSION }}
49+
50+
## Commit Description:
51+
${{ env.COMMITS }}
4252
4353
- name: Build and Publish Python Package
4454
if: env.RELEASE_EXISTS == 'false'
@@ -49,4 +59,4 @@ jobs:
4959
hatch publish
5060
env:
5161
HATCH_INDEX_USER: __token__
52-
HATCH_INDEX_AUTH: ${{ secrets.PYPI_API_TOKEN }}
62+
HATCH_INDEX_AUTH: ${{ secrets.PYPI_API_TOKEN }}

build-docs.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/bash
22

3+
set -e
4+
35
export GITHUB_TOKEN
46
VENV="$(pwd)/venv"
57
export VENV
@@ -16,19 +18,23 @@ cd ../..
1618

1719
"$VENV/bin/sphinx-build" -b html "docs/source" "docs/build/html" -j auto
1820

19-
git clone https://5hojib:"$GITHUB_TOKEN"@github.com/5hojib/Electrogram-docs.git
20-
cd Electrogram-docs
21+
REPO_URL="https://5hojib:$GITHUB_TOKEN@github.com/5hojib/Electrogram-docs.git"
22+
CLONE_DIR="Electrogram-docs"
23+
24+
git clone "$REPO_URL"
25+
cd "$CLONE_DIR"
2126

2227
rm -rf _includes api genindex.html intro py-modindex.html sitemap.xml \
2328
support.html topics _static faq index.html objects.inv \
2429
searchindex.js start telegram
2530

2631
cp -r ../docs/build/html/* .
32+
2733
git config --local user.name "5hojib"
2834
git config --local user.email "yesiamshojib@gmail.com"
2935
git add --all
30-
git commit -m "Update docs" --signoff
31-
git checkout --orphan x
36+
37+
git checkout --orphan temp-branch
3238
git commit -m "Update docs" --signoff
3339
git branch -D main
3440
git branch -m main

compiler/api/compiler.py

Lines changed: 141 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import contextlib
4+
import json
45
import re
56
import shutil
67
from functools import partial
@@ -12,7 +13,6 @@
1213

1314
DESTINATION_PATH = REPO_HOME_PATH / "pyrogram" / "raw"
1415

15-
1616
SECTION_RE = re.compile(r"---(\w+)---")
1717
LAYER_RE = re.compile(r"//\sLAYER\s(\d+)")
1818
COMBINATOR_RE = re.compile(
@@ -35,6 +35,15 @@
3535
"Bool",
3636
"true",
3737
]
38+
39+
WARNING = """
40+
# # # # # # # # # # # # # # # # # # # # # # # #
41+
# !!! WARNING !!! #
42+
# This is a generated file! #
43+
# All changes made in this file will be lost! #
44+
# # # # # # # # # # # # # # # # # # # # # # # #
45+
""".strip()
46+
3847
open = partial(open, encoding="utf-8")
3948

4049
types_to_constructors: dict[str, list[str]] = {}
@@ -44,6 +53,12 @@
4453
namespaces_to_constructors: dict[str, list[str]] = {}
4554
namespaces_to_functions: dict[str, list[str]] = {}
4655

56+
try:
57+
with open(API_HOME_PATH / "docs.json") as f:
58+
docs = json.load(f)
59+
except FileNotFoundError:
60+
docs = {"type": {}, "constructor": {}, "method": {}}
61+
4762

4863
class Combinator(NamedTuple):
4964
section: str
@@ -59,6 +74,7 @@ class Combinator(NamedTuple):
5974

6075

6176
def snake(s: str):
77+
# https://stackoverflow.com/q/1175208
6278
s = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", s)
6379
return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s).lower()
6480

@@ -85,7 +101,7 @@ def get_type_hint(type: str) -> str:
85101
type = "str"
86102
elif type in {"Bool", "true"}:
87103
type = "bool"
88-
else:
104+
else: # bytes and object
89105
type = "bytes"
90106

91107
if type in {"Object", "!X"}:
@@ -131,7 +147,43 @@ def remove_whitespaces(source: str) -> str:
131147
return "\n".join(lines)
132148

133149

134-
def start() -> None:
150+
def get_docstring_arg_type(t: str):
151+
if t in CORE_TYPES:
152+
if t == "long":
153+
return "``int`` ``64-bit``"
154+
if "int" in t:
155+
size = INT_RE.match(t)
156+
return (
157+
f"``int`` ``{size.group(1)}-bit``" if size else "``int`` ``32-bit``"
158+
)
159+
if t == "double":
160+
return "``float`` ``64-bit``"
161+
if t == "string":
162+
return "``str``"
163+
if t == "true":
164+
return "``bool``"
165+
return f"``{t.lower()}``"
166+
if t in {"TLObject", "X"}:
167+
return "Any object from :obj:`~pyrogram.raw.types`"
168+
if t == "!X":
169+
return "Any function from :obj:`~pyrogram.raw.functions`"
170+
if t.lower().startswith("vector"):
171+
return "List of " + get_docstring_arg_type(t.split("<", 1)[1][:-1])
172+
return f":obj:`{t} <pyrogram.raw.base.{t}>`"
173+
174+
175+
def get_references(t: str, kind: str):
176+
if kind == "constructors":
177+
items = constructors_to_functions.get(t)
178+
elif kind == "types":
179+
items = types_to_functions.get(t)
180+
else:
181+
raise ValueError("Invalid kind")
182+
183+
return ("\n ".join(items), len(items)) if items else (None, 0)
184+
185+
186+
def start():
135187
shutil.rmtree(DESTINATION_PATH / "types", ignore_errors=True)
136188
shutil.rmtree(DESTINATION_PATH / "functions", ignore_errors=True)
137189
shutil.rmtree(DESTINATION_PATH / "base", ignore_errors=True)
@@ -182,6 +234,7 @@ def start() -> None:
182234

183235
args = ARGS_RE.findall(line)
184236

237+
# Fix arg name being "self" or "from" (reserved python keywords)
185238
for i, item in enumerate(args):
186239
if item[0] == "self":
187240
args[i] = ("is_self", item[1])
@@ -242,12 +295,34 @@ def start() -> None:
242295
dir_path.mkdir(parents=True, exist_ok=True)
243296

244297
constructors = sorted(qualval)
245-
len(constructors)
246-
"\n ".join([f"{c}" for c in constructors])
298+
constr_count = len(constructors)
299+
items = "\n ".join([f"{c}" for c in constructors])
300+
301+
type_docs = docs["type"].get(qualtype, None)
302+
303+
type_docs = type_docs["desc"] if type_docs else "Telegram API base type."
304+
305+
docstring = type_docs
306+
307+
docstring += (
308+
f"\n\n Constructors:\n"
309+
f" This base type has {constr_count} constructor{'s' if constr_count > 1 else ''} available.\n\n"
310+
f" .. currentmodule:: pyrogram.raw.types\n\n"
311+
f" .. autosummary::\n"
312+
f" :nosignatures:\n\n"
313+
f" {items}"
314+
)
315+
316+
references, ref_count = get_references(qualtype, "types")
317+
318+
if references:
319+
docstring += f"\n\n Functions:\n This object can be returned by {ref_count} function{'s' if ref_count > 1 else ''}.\n\n .. currentmodule:: pyrogram.raw.functions\n\n .. autosummary::\n :nosignatures:\n\n {references}"
247320

248321
with open(dir_path / f"{snake(module)}.py", "w") as f:
249322
f.write(
250323
type_tmpl.format(
324+
warning=WARNING,
325+
docstring=docstring,
251326
name=type,
252327
qualname=qualtype,
253328
types=", ".join([f'"raw.types.{c}"' for c in constructors]),
@@ -272,11 +347,60 @@ def start() -> None:
272347
else "pass"
273348
)
274349

350+
docstring = ""
351+
docstring_args = []
352+
353+
combinator_docs = (
354+
docs["method"] if c.section == "functions" else docs["constructor"]
355+
)
356+
275357
for arg in sorted_args:
276358
arg_name, arg_type = arg
277-
FLAGS_RE.match(arg_type)
359+
is_optional = FLAGS_RE.match(arg_type)
278360
arg_type = arg_type.split("?")[-1]
279361

362+
arg_docs = combinator_docs.get(c.qualname, None)
363+
364+
arg_docs = arg_docs["params"].get(arg_name, "N/A") if arg_docs else "N/A"
365+
366+
docstring_args.append(
367+
f'{arg_name} ({get_docstring_arg_type(arg_type)}{", *optional*" if is_optional else ""}):\n {arg_docs}\n'
368+
)
369+
370+
if c.section == "types":
371+
constructor_docs = docs["constructor"].get(c.qualname, None)
372+
373+
constructor_docs = (
374+
constructor_docs["desc"]
375+
if constructor_docs
376+
else "Telegram API type."
377+
)
378+
docstring += constructor_docs + "\n"
379+
docstring += (
380+
f"\n Constructor of :obj:`~pyrogram.raw.base.{c.qualtype}`."
381+
)
382+
elif function_docs := docs["method"].get(c.qualname, None):
383+
docstring += function_docs["desc"] + "\n"
384+
else:
385+
docstring += "Telegram API function."
386+
387+
docstring += f"\n\n Details:\n - Layer: ``{layer}``\n - ID: ``{c.id[2:].upper()}``\n\n"
388+
docstring += " Parameters:\n " + (
389+
"\n ".join(docstring_args)
390+
if docstring_args
391+
else "No parameters required.\n"
392+
)
393+
394+
if c.section == "functions":
395+
docstring += "\n Returns:\n " + get_docstring_arg_type(
396+
c.qualtype
397+
)
398+
else:
399+
references, count = get_references(c.qualname, "constructors")
400+
401+
if references:
402+
docstring += f"\n Functions:\n This object can be returned by {count} function{'s' if count > 1 else ''}.\n\n .. currentmodule:: pyrogram.raw.functions\n\n .. autosummary::\n :nosignatures:\n\n {references}"
403+
280404
write_types = read_types = "" if c.has_flags else "# No flags\n "
281405

282406
for arg_name, arg_type in c.args:
@@ -375,7 +499,9 @@ def start() -> None:
375499
return_arguments = ", ".join([f"{i[0]}={i[0]}" for i in sorted_args])
376500

377501
compiled_combinator = combinator_tmpl.format(
502+
warning=WARNING,
378503
name=c.name,
504+
docstring=docstring,
379505
slots=slots,
380506
id=c.id,
381507
qualname=f"{c.section}.{c.qualname}",
@@ -413,6 +539,8 @@ def start() -> None:
413539

414540
for namespace, types in namespaces_to_types.items():
415541
with open(DESTINATION_PATH / "base" / namespace / "__init__.py", "w") as f:
542+
f.write(f"{WARNING}\n\n")
543+
416544
all = []
417545

418546
for t in types:
@@ -438,10 +566,9 @@ def start() -> None:
438566
f.write("]\n")
439567

440568
for namespace, types in namespaces_to_constructors.items():
441-
with open(
442-
DESTINATION_PATH / "types" / namespace / "__init__.py",
443-
"w",
444-
) as f:
569+
with open(DESTINATION_PATH / "types" / namespace / "__init__.py", "w") as f:
570+
f.write(f"{WARNING}\n\n")
571+
445572
all = []
446573

447574
for t in types:
@@ -468,9 +595,10 @@ def start() -> None:
468595

469596
for namespace, types in namespaces_to_functions.items():
470597
with open(
471-
DESTINATION_PATH / "functions" / namespace / "__init__.py",
472-
"w",
598+
DESTINATION_PATH / "functions" / namespace / "__init__.py", "w"
473599
) as f:
600+
f.write(f"{WARNING}\n\n")
601+
474602
all = []
475603

476604
for t in types:
@@ -496,6 +624,7 @@ def start() -> None:
496624
f.write("]\n")
497625

498626
with open(DESTINATION_PATH / "all.py", "w", encoding="utf-8") as f:
627+
f.write(WARNING + "\n\n")
499628
f.write(f"layer = {layer}\n\n")
500629
f.write("objects = {")
501630

0 commit comments

Comments
 (0)