chgksuite 0.27.2__tar.gz → 0.28.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chgksuite-0.27.2 → chgksuite-0.28.0}/PKG-INFO +1 -1
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/cli.py +14 -1
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/telegram.py +130 -84
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/parser.py +0 -1
- chgksuite-0.28.0/chgksuite/version.py +1 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/pyproject.toml +5 -1
- chgksuite-0.27.2/.claude/settings.local.json +0 -10
- chgksuite-0.27.2/.github/workflows/build.yml +0 -283
- chgksuite-0.27.2/.gitlab-ci.yml +0 -17
- chgksuite-0.27.2/MANIFEST.in +0 -7
- chgksuite-0.27.2/adhoc/regexes_fixer.py +0 -66
- chgksuite-0.27.2/author_counter.py +0 -24
- chgksuite-0.27.2/chgksuite/version.py +0 -1
- chgksuite-0.27.2/dev_readme.md +0 -25
- chgksuite-0.27.2/docs/.cache/.gitignore +0 -1
- chgksuite-0.27.2/docs/.cache/12897346880794287463 +0 -43
- chgksuite-0.27.2/docs/.cache/13071136909783630831 +0 -27
- chgksuite-0.27.2/docs/.cache/13307108790744403429 +0 -58
- chgksuite-0.27.2/docs/.cache/13333983167045209281 +0 -27
- chgksuite-0.27.2/docs/.cache/14085495286103177657 +0 -4
- chgksuite-0.27.2/docs/.cache/15213489598760314030 +0 -149
- chgksuite-0.27.2/docs/.cache/15319492834190874243 +0 -4
- chgksuite-0.27.2/docs/.cache/17387058097034297385 +0 -4
- chgksuite-0.27.2/docs/.cache/17722115158263369208 +0 -4
- chgksuite-0.27.2/docs/.cache/18247088324849079572 +0 -4
- chgksuite-0.27.2/docs/.cache/1840587404175770520 +0 -43
- chgksuite-0.27.2/docs/.cache/2517734129797249711 +0 -4
- chgksuite-0.27.2/docs/.cache/273431981325847810 +0 -164
- chgksuite-0.27.2/docs/.cache/2872065536916780406 +0 -27
- chgksuite-0.27.2/docs/.cache/3476900567878811119 +0 -4
- chgksuite-0.27.2/docs/.cache/4757258273854424423 +0 -58
- chgksuite-0.27.2/docs/.cache/5728722062471071239 +0 -58
- chgksuite-0.27.2/docs/.cache/6061198691539556612 +0 -4
- chgksuite-0.27.2/docs/.cache/6079179394456200124 +0 -4
- chgksuite-0.27.2/docs/.cache/735877668610100612 +0 -73
- chgksuite-0.27.2/docs/.cache/9345880734637750342 +0 -4
- chgksuite-0.27.2/docs/.cache/9490951945832949972 +0 -4
- chgksuite-0.27.2/docs/docs/4s.md +0 -229
- chgksuite-0.27.2/docs/docs/add_stats.md +0 -9
- chgksuite-0.27.2/docs/docs/base.md +0 -43
- chgksuite-0.27.2/docs/docs/i14n.md +0 -31
- chgksuite-0.27.2/docs/docs/images/base.png +0 -0
- chgksuite-0.27.2/docs/docs/images/douplet_problem.png +0 -0
- chgksuite-0.27.2/docs/docs/images/i14n.png +0 -0
- chgksuite-0.27.2/docs/docs/images/i14n_parse.png +0 -0
- chgksuite-0.27.2/docs/docs/images/lj.png +0 -0
- chgksuite-0.27.2/docs/docs/images/main.png +0 -0
- chgksuite-0.27.2/docs/docs/images/openquiz.png +0 -0
- chgksuite-0.27.2/docs/docs/images/openquiz2.png +0 -0
- chgksuite-0.27.2/docs/docs/images/parse.png +0 -0
- chgksuite-0.27.2/docs/docs/images/pptx.png +0 -0
- chgksuite-0.27.2/docs/docs/images/pptx_additional_conf.png +0 -0
- chgksuite-0.27.2/docs/docs/images/pptx_slide_a.png +0 -0
- chgksuite-0.27.2/docs/docs/images/pptx_slide_q.png +0 -0
- chgksuite-0.27.2/docs/docs/images/roenko.png +0 -0
- chgksuite-0.27.2/docs/docs/images/rozhdsushkov.png +0 -0
- chgksuite-0.27.2/docs/docs/images/stats.png +0 -0
- chgksuite-0.27.2/docs/docs/images/telegram.png +0 -0
- chgksuite-0.27.2/docs/docs/images/trello_download.png +0 -0
- chgksuite-0.27.2/docs/docs/images/trello_token.png +0 -0
- chgksuite-0.27.2/docs/docs/images/trello_upload.png +0 -0
- chgksuite-0.27.2/docs/docs/images/word.png +0 -0
- chgksuite-0.27.2/docs/docs/index.md +0 -59
- chgksuite-0.27.2/docs/docs/lj.md +0 -9
- chgksuite-0.27.2/docs/docs/openquiz.md +0 -7
- chgksuite-0.27.2/docs/docs/pptx.md +0 -66
- chgksuite-0.27.2/docs/docs/stylesheets/extra.css +0 -29
- chgksuite-0.27.2/docs/docs/telegram.md +0 -46
- chgksuite-0.27.2/docs/docs/trello.md +0 -31
- chgksuite-0.27.2/docs/docs/word.md +0 -24
- chgksuite-0.27.2/docs/mkdocs.yml +0 -35
- chgksuite-0.27.2/history.md +0 -407
- chgksuite-0.27.2/hook-dateparser.py +0 -12
- chgksuite-0.27.2/packer.py +0 -172
- chgksuite-0.27.2/pytest.ini +0 -5
- chgksuite-0.27.2/pytest.sh +0 -7
- chgksuite-0.27.2/re_helper.py +0 -24
- chgksuite-0.27.2/requirements_dev.txt +0 -2
- chgksuite-0.27.2/ruff.toml +0 -2
- chgksuite-0.27.2/tests/2019-07-23_beln19_u.docx +0 -0
- chgksuite-0.27.2/tests/2019-07-23_beln19_u.docx.canon +0 -690
- chgksuite-0.27.2/tests/Kubok_knyagini_Olgi-2015.docx +0 -0
- chgksuite-0.27.2/tests/Kubok_knyagini_Olgi-2015.docx.canon +0 -644
- chgksuite-0.27.2/tests/Shkolny_Chemp_Estonii-2014_(48v).docx +0 -0
- chgksuite-0.27.2/tests/Shkolny_Chemp_Estonii-2014_(48v).docx.canon +0 -361
- chgksuite-0.27.2/tests/__init__.py +0 -0
- chgksuite-0.27.2/tests/balt09-1.txt +0 -783
- chgksuite-0.27.2/tests/balt09-1.txt.canon +0 -286
- chgksuite-0.27.2/tests/borromeo.txt +0 -11
- chgksuite-0.27.2/tests/borromeo.txt.canon +0 -16
- chgksuite-0.27.2/tests/canonize.py +0 -69
- chgksuite-0.27.2/tests/chgksuite_test.py +0 -364
- chgksuite-0.27.2/tests/conftest.py +0 -21
- chgksuite-0.27.2/tests/encrypt_test_files.py +0 -147
- chgksuite-0.27.2/tests/haifa2025.docx.encrypted +0 -0
- chgksuite-0.27.2/tests/haifa2025.docx.encrypted.canon +0 -0
- chgksuite-0.27.2/tests/handouter_layout_test.py +0 -310
- chgksuite-0.27.2/tests/link_unwrap.docx +0 -0
- chgksuite-0.27.2/tests/link_unwrap.docx.canon +0 -10
- chgksuite-0.27.2/tests/ljcredentials +0 -1
- chgksuite-0.27.2/tests/long_handout.png +0 -0
- chgksuite-0.27.2/tests/malkin_papkov_synchr.docx +0 -0
- chgksuite-0.27.2/tests/malkin_papkov_synchr.docx.canon +0 -99
- chgksuite-0.27.2/tests/octo2021_khmelkov.docx +0 -0
- chgksuite-0.27.2/tests/octo2021_khmelkov.docx.canon +0 -102
- chgksuite-0.27.2/tests/ovsch_boronenko_3.docx +0 -0
- chgksuite-0.27.2/tests/ovsch_boronenko_3.docx.canon +0 -334
- chgksuite-0.27.2/tests/pass1.docx +0 -0
- chgksuite-0.27.2/tests/pass1.docx.canon +0 -183
- chgksuite-0.27.2/tests/settings.json +0 -3
- chgksuite-0.27.2/tests/single_number_line_test.docx +0 -0
- chgksuite-0.27.2/tests/single_number_line_test.docx.canon +0 -46
- chgksuite-0.27.2/tests/smalltest.4s +0 -6
- chgksuite-0.27.2/tests/test.jpg +0 -0
- chgksuite-0.27.2/tests/test_blitz.txt +0 -8
- chgksuite-0.27.2/tests/test_blitz.txt.canon +0 -9
- chgksuite-0.27.2/tests/tourrev_with_razmin.docx +0 -0
- chgksuite-0.27.2/tests/tourrev_with_razmin.docx.canon +0 -34
- chgksuite-0.27.2/tests//320/241/320/247/320/240_/320/250/320/265/321/200/320/265/320/264/320/265/320/263/320/260_/320/225/321/200/320/274/320/270/321/210/320/272/320/270/320/275.docx +0 -0
- chgksuite-0.27.2/tests//320/241/320/247/320/240_/320/250/320/265/321/200/320/265/320/264/320/265/320/263/320/260_/320/225/321/200/320/274/320/270/321/210/320/272/320/270/320/275.docx.canon +0 -13
- chgksuite-0.27.2/uv.lock +0 -1454
- {chgksuite-0.27.2 → chgksuite-0.28.0}/.gitignore +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/.hgignore +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/LICENSE +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/README.md +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/__init__.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/__main__.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/_html2md.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/common.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/__init__.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/chgksuite_parser.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/composer_common.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/db.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/docx.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/latex.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/lj.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/markdown.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/openquiz.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/pptx.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/stats.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/composer/telegram_bot.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/__init__.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/gen.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/installer.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/pack.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/runner.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/tex_internals.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/handouter/utils.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/lastdir +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/parser_db.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/cheader.tex +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/fix-unnumbered-sections.sty +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_az.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_by.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_by_tar.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_en.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_kz_cyr.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_ru.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_sr.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_ua.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_uz.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/labels_uz_cyr.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/pptx_config.toml +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_az.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_by.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_by_tar.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_en.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_kz_cyr.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_ru.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_sr.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_ua.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_uz.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/regexes_uz_cyr.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/template.docx +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/template.pptx +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/resources/trello.json +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/trello.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/typotools.py +0 -0
- {chgksuite-0.27.2 → chgksuite-0.28.0}/chgksuite/vulture_whitelist.py +0 -0
|
@@ -12,6 +12,7 @@ from chgksuite.common import (
|
|
|
12
12
|
load_settings,
|
|
13
13
|
)
|
|
14
14
|
from chgksuite.composer import gui_compose
|
|
15
|
+
from chgksuite.composer.telegram import get_saved_telegram_targets
|
|
15
16
|
from chgksuite.handouter.runner import gui_handouter
|
|
16
17
|
from chgksuite.parser import gui_parse
|
|
17
18
|
from chgksuite.trello import gui_trello
|
|
@@ -34,7 +35,14 @@ class ArgparseBuilder:
|
|
|
34
35
|
if self.use_wrapper:
|
|
35
36
|
return getattr(parser, func)(*args, **kwargs)
|
|
36
37
|
else:
|
|
37
|
-
for k in (
|
|
38
|
+
for k in (
|
|
39
|
+
"caption",
|
|
40
|
+
"advanced",
|
|
41
|
+
"argtype",
|
|
42
|
+
"hide",
|
|
43
|
+
"filetypes",
|
|
44
|
+
"combobox_values",
|
|
45
|
+
):
|
|
38
46
|
try:
|
|
39
47
|
kwargs.pop(k)
|
|
40
48
|
except KeyError:
|
|
@@ -654,12 +662,15 @@ class ArgparseBuilder:
|
|
|
654
662
|
help="a made-up string designating account to use.",
|
|
655
663
|
caption="Аккаунт для постинга",
|
|
656
664
|
)
|
|
665
|
+
saved_targets = get_saved_telegram_targets()
|
|
657
666
|
self.add_argument(
|
|
658
667
|
cmdcompose_telegram,
|
|
659
668
|
"--tgchannel",
|
|
660
669
|
required=True,
|
|
661
670
|
help="a channel to post questions to.",
|
|
662
671
|
caption="Название канала, в который постим",
|
|
672
|
+
argtype="combobox",
|
|
673
|
+
combobox_values=saved_targets,
|
|
663
674
|
)
|
|
664
675
|
self.add_argument(
|
|
665
676
|
cmdcompose_telegram,
|
|
@@ -667,6 +678,8 @@ class ArgparseBuilder:
|
|
|
667
678
|
required=True,
|
|
668
679
|
help="a chat connected to the channel.",
|
|
669
680
|
caption="Название чата, привязанного к каналу",
|
|
681
|
+
argtype="combobox",
|
|
682
|
+
combobox_values=saved_targets,
|
|
670
683
|
)
|
|
671
684
|
self.add_argument(
|
|
672
685
|
cmdcompose_telegram,
|
|
@@ -17,6 +17,28 @@ from chgksuite.composer.composer_common import BaseExporter, parseimg
|
|
|
17
17
|
from chgksuite.composer.telegram_bot import run_bot_in_thread
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
def get_saved_telegram_targets():
|
|
21
|
+
"""
|
|
22
|
+
Load all saved channel/chat usernames from resolve.db.
|
|
23
|
+
Returns a list of usernames that have been previously used.
|
|
24
|
+
"""
|
|
25
|
+
chgksuite_dir = get_chgksuite_dir()
|
|
26
|
+
resolve_db_path = os.path.join(chgksuite_dir, "resolve.db")
|
|
27
|
+
|
|
28
|
+
if not os.path.exists(resolve_db_path):
|
|
29
|
+
return []
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
conn = sqlite3.connect(resolve_db_path)
|
|
33
|
+
cursor = conn.cursor()
|
|
34
|
+
cursor.execute("SELECT username FROM resolve ORDER BY username")
|
|
35
|
+
results = cursor.fetchall()
|
|
36
|
+
conn.close()
|
|
37
|
+
return [row[0] for row in results]
|
|
38
|
+
except Exception:
|
|
39
|
+
return []
|
|
40
|
+
|
|
41
|
+
|
|
20
42
|
def get_text(msg_data):
|
|
21
43
|
if "message" in msg_data and "text" in msg_data["message"]:
|
|
22
44
|
return msg_data["message"]["text"]
|
|
@@ -44,19 +66,14 @@ class TelegramExporter(BaseExporter):
|
|
|
44
66
|
self.chat_id = None # Discussion group ID linked to the channel
|
|
45
67
|
self.auth_uuid = uuid.uuid4().hex[:8]
|
|
46
68
|
self.chat_auth_uuid = uuid.uuid4().hex[:8]
|
|
69
|
+
self.session = requests.Session()
|
|
47
70
|
self.init_telegram()
|
|
48
71
|
|
|
49
72
|
def check_connectivity(self):
|
|
50
|
-
|
|
51
|
-
if req_me.status_code != 200:
|
|
52
|
-
raise Exception(
|
|
53
|
-
f"getMe request wasn't successful: {req_me.status_code} {req_me.text}"
|
|
54
|
-
)
|
|
55
|
-
obj = req_me.json()
|
|
56
|
-
assert obj["ok"]
|
|
73
|
+
result = self.send_api_request("getMe")
|
|
57
74
|
if self.args.debug:
|
|
58
|
-
print(f"connection successful! {
|
|
59
|
-
self.bot_id =
|
|
75
|
+
print(f"connection successful! {result}")
|
|
76
|
+
self.bot_id = result["id"]
|
|
60
77
|
|
|
61
78
|
def init_temp_db(self):
|
|
62
79
|
self.db_conn = sqlite3.connect(self.temp_db_path)
|
|
@@ -102,8 +119,6 @@ class TelegramExporter(BaseExporter):
|
|
|
102
119
|
).fetchall()
|
|
103
120
|
if messages and json.loads(messages[0][0])["status"] == "ok":
|
|
104
121
|
break
|
|
105
|
-
# Request user authentication
|
|
106
|
-
self.authenticate_user()
|
|
107
122
|
|
|
108
123
|
def authenticate_user(self):
|
|
109
124
|
print("\n" + "=" * 50)
|
|
@@ -208,32 +223,46 @@ class TelegramExporter(BaseExporter):
|
|
|
208
223
|
def send_api_request(self, method, data=None, files=None):
|
|
209
224
|
"""Send a request to the Telegram Bot API."""
|
|
210
225
|
url = f"https://api.telegram.org/bot{self.bot_token}/{method}"
|
|
226
|
+
retry_delay = 10 # Start with 10 seconds
|
|
227
|
+
max_retry_delay = 120 # Cap at 2 minutes
|
|
211
228
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
229
|
+
while True:
|
|
230
|
+
try:
|
|
231
|
+
if files:
|
|
232
|
+
response = self.session.post(
|
|
233
|
+
url, data=data, files=files, timeout=60
|
|
234
|
+
)
|
|
235
|
+
else:
|
|
236
|
+
response = self.session.post(url, json=data, timeout=30)
|
|
217
237
|
|
|
218
|
-
|
|
238
|
+
response_data = response.json()
|
|
219
239
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
240
|
+
if not response_data.get("ok"):
|
|
241
|
+
error_message = response_data.get("description", "Unknown error")
|
|
242
|
+
self.logger.error(f"Telegram API error: {error_message}")
|
|
223
243
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
244
|
+
# Handle rate limiting
|
|
245
|
+
if "retry_after" in response_data:
|
|
246
|
+
retry_after = response_data["retry_after"]
|
|
247
|
+
self.logger.info(
|
|
248
|
+
f"Rate limited. Waiting for {retry_after} seconds"
|
|
249
|
+
)
|
|
250
|
+
time.sleep(retry_after + 1)
|
|
251
|
+
return self.send_api_request(method, data, files)
|
|
230
252
|
|
|
231
|
-
|
|
253
|
+
raise Exception(f"Telegram API error: {error_message}")
|
|
232
254
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
255
|
+
return response_data["result"]
|
|
256
|
+
except requests.exceptions.RequestException as e:
|
|
257
|
+
if "Connection reset by peer" in str(e):
|
|
258
|
+
self.logger.warning(
|
|
259
|
+
f"Connection reset by peer. Retrying in {retry_delay} seconds..."
|
|
260
|
+
)
|
|
261
|
+
time.sleep(retry_delay)
|
|
262
|
+
retry_delay = min(retry_delay * 2, max_retry_delay)
|
|
263
|
+
continue
|
|
264
|
+
self.logger.error(f"Request error: {e}")
|
|
265
|
+
raise
|
|
237
266
|
|
|
238
267
|
def get_message_link(self, chat_id, message_id, username=None):
|
|
239
268
|
"""Generate a link to a Telegram message."""
|
|
@@ -851,66 +880,82 @@ class TelegramExporter(BaseExporter):
|
|
|
851
880
|
channel_result = self.extract_id_from_link(self.args.tgchannel)
|
|
852
881
|
chat_result = self.extract_id_from_link(self.args.tgchat)
|
|
853
882
|
|
|
854
|
-
#
|
|
883
|
+
# First, try to resolve both IDs without user interaction
|
|
884
|
+
channel_id = None
|
|
885
|
+
chat_id = None
|
|
886
|
+
needs_channel_interaction = False
|
|
887
|
+
needs_chat_interaction = False
|
|
888
|
+
|
|
855
889
|
if isinstance(channel_result, int):
|
|
856
890
|
channel_id = channel_result
|
|
857
891
|
elif isinstance(channel_result, str):
|
|
858
892
|
channel_id = self.resolve_username_to_id(channel_result)
|
|
859
893
|
if not channel_id:
|
|
860
|
-
|
|
861
|
-
print("Please forward any message from the target channel to the bot.")
|
|
862
|
-
print("This will allow me to extract the channel ID automatically.")
|
|
863
|
-
print("=" * 50 + "\n")
|
|
864
|
-
|
|
865
|
-
# Wait for a forwarded message with channel information
|
|
866
|
-
channel_id = self.wait_for_forwarded_message(
|
|
867
|
-
entity_type="channel", check_type=True
|
|
868
|
-
)
|
|
869
|
-
if channel_id:
|
|
870
|
-
self.save_username(channel_result, channel_id)
|
|
871
|
-
else:
|
|
872
|
-
raise Exception("Failed to get channel ID from forwarded message")
|
|
894
|
+
needs_channel_interaction = True
|
|
873
895
|
else:
|
|
874
896
|
raise Exception("Channel ID is undefined")
|
|
875
897
|
|
|
876
|
-
# Handle chat resolution
|
|
877
898
|
if isinstance(chat_result, int):
|
|
878
899
|
chat_id = chat_result
|
|
879
900
|
elif isinstance(chat_result, str):
|
|
880
901
|
chat_id = self.resolve_username_to_id(chat_result)
|
|
881
902
|
if not chat_id:
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
)
|
|
886
|
-
print("This will allow me to extract the group ID automatically.")
|
|
887
|
-
print(
|
|
888
|
-
"The bot MUST be added do the group and made admin, else it won't work!"
|
|
889
|
-
)
|
|
890
|
-
print("=" * 50 + "\n")
|
|
903
|
+
needs_chat_interaction = True
|
|
904
|
+
else:
|
|
905
|
+
raise Exception("Chat ID is undefined")
|
|
891
906
|
|
|
892
|
-
|
|
907
|
+
# Only authenticate if we need user interaction
|
|
908
|
+
if needs_channel_interaction or needs_chat_interaction:
|
|
909
|
+
self.authenticate_user()
|
|
910
|
+
|
|
911
|
+
# Handle channel resolution with user interaction if needed
|
|
912
|
+
if needs_channel_interaction:
|
|
913
|
+
print("\n" + "=" * 50)
|
|
914
|
+
print("Please forward any message from the target channel to the bot.")
|
|
915
|
+
print("This will allow me to extract the channel ID automatically.")
|
|
916
|
+
print("=" * 50 + "\n")
|
|
917
|
+
|
|
918
|
+
# Wait for a forwarded message with channel information
|
|
919
|
+
channel_id = self.wait_for_forwarded_message(
|
|
920
|
+
entity_type="channel", check_type=True
|
|
921
|
+
)
|
|
922
|
+
if channel_id:
|
|
923
|
+
self.save_username(channel_result, channel_id)
|
|
924
|
+
else:
|
|
925
|
+
raise Exception("Failed to get channel ID from forwarded message")
|
|
926
|
+
|
|
927
|
+
# Handle chat resolution with user interaction if needed
|
|
928
|
+
if needs_chat_interaction:
|
|
929
|
+
print("\n" + "=" * 50)
|
|
930
|
+
print(
|
|
931
|
+
f"Please write a message in the discussion group with text: {self.chat_auth_uuid}"
|
|
932
|
+
)
|
|
933
|
+
print("This will allow me to extract the group ID automatically.")
|
|
934
|
+
print(
|
|
935
|
+
"The bot MUST be added do the group and made admin, else it won't work!"
|
|
936
|
+
)
|
|
937
|
+
print("=" * 50 + "\n")
|
|
938
|
+
|
|
939
|
+
# Wait for a forwarded message with chat information
|
|
940
|
+
chat_id = self.wait_for_forwarded_message(
|
|
941
|
+
entity_type="chat", check_type=False
|
|
942
|
+
)
|
|
943
|
+
if not chat_id:
|
|
944
|
+
self.logger.error("Failed to get chat ID from forwarded message")
|
|
945
|
+
return False
|
|
946
|
+
while chat_id == channel_id:
|
|
947
|
+
error_msg = (
|
|
948
|
+
"Chat ID and channel ID are the same. The problem may be that "
|
|
949
|
+
"you posted a message in the channel, not in the discussion group."
|
|
950
|
+
)
|
|
951
|
+
self.logger.error(error_msg)
|
|
893
952
|
chat_id = self.wait_for_forwarded_message(
|
|
894
|
-
entity_type="chat",
|
|
953
|
+
entity_type="chat",
|
|
954
|
+
check_type=False,
|
|
955
|
+
add_msg=error_msg,
|
|
895
956
|
)
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
return False
|
|
899
|
-
while chat_id == channel_id:
|
|
900
|
-
error_msg = (
|
|
901
|
-
"Chat ID and channel ID are the same. The problem may be that "
|
|
902
|
-
"you posted a message in the channel, not in the discussion group."
|
|
903
|
-
)
|
|
904
|
-
self.logger.error(error_msg)
|
|
905
|
-
chat_id = self.wait_for_forwarded_message(
|
|
906
|
-
entity_type="chat",
|
|
907
|
-
check_type=False,
|
|
908
|
-
add_msg=error_msg,
|
|
909
|
-
)
|
|
910
|
-
if chat_id:
|
|
911
|
-
self.save_username(chat_result, chat_id)
|
|
912
|
-
else:
|
|
913
|
-
raise Exception("Chat ID is undefined")
|
|
957
|
+
if chat_id:
|
|
958
|
+
self.save_username(chat_result, chat_id)
|
|
914
959
|
|
|
915
960
|
if not channel_id:
|
|
916
961
|
raise Exception("Channel ID is undefined")
|
|
@@ -1234,14 +1279,15 @@ class TelegramExporter(BaseExporter):
|
|
|
1234
1279
|
return None
|
|
1235
1280
|
|
|
1236
1281
|
def verify_access(self, telegram_id, hr_type=None):
|
|
1237
|
-
url = f"https://api.telegram.org/bot{self.bot_token}/getChatAdministrators"
|
|
1238
1282
|
if not str(telegram_id).startswith("-100"):
|
|
1239
1283
|
telegram_id = f"-100{telegram_id}"
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1284
|
+
try:
|
|
1285
|
+
result = self.send_api_request(
|
|
1286
|
+
"getChatAdministrators", {"chat_id": telegram_id}
|
|
1287
|
+
)
|
|
1288
|
+
if self.args.debug:
|
|
1289
|
+
print(f"getChatAdministrators result: {result}")
|
|
1290
|
+
admin_ids = {x["user"]["id"] for x in result}
|
|
1291
|
+
return self.bot_id in admin_ids
|
|
1292
|
+
except Exception as e:
|
|
1293
|
+
raise Exception(f"Bot isn't added to {hr_type}: {e}")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.28.0"
|
|
@@ -54,7 +54,11 @@ chgksuite = "chgksuite.__main__:main"
|
|
|
54
54
|
path = "chgksuite/version.py"
|
|
55
55
|
|
|
56
56
|
[tool.hatch.build.targets.sdist]
|
|
57
|
-
|
|
57
|
+
include = [
|
|
58
|
+
"chgksuite/**/*",
|
|
59
|
+
"/LICENSE",
|
|
60
|
+
"/README.md",
|
|
61
|
+
]
|
|
58
62
|
|
|
59
63
|
[tool.hatch.build.targets.wheel]
|
|
60
64
|
packages = ["chgksuite"]
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
name: Build Standalone Executables
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*'
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
inputs:
|
|
9
|
-
tag:
|
|
10
|
-
description: 'Tag to build and release (e.g., v0.26.1). Leave empty for build-only.'
|
|
11
|
-
required: false
|
|
12
|
-
default: ''
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
build:
|
|
16
|
-
strategy:
|
|
17
|
-
fail-fast: false
|
|
18
|
-
matrix:
|
|
19
|
-
include:
|
|
20
|
-
- os: ubuntu-24.04
|
|
21
|
-
platform: linux-x64
|
|
22
|
-
rust_target: x86_64-unknown-linux-gnu
|
|
23
|
-
- os: ubuntu-24.04-arm
|
|
24
|
-
platform: linux-arm64
|
|
25
|
-
rust_target: aarch64-unknown-linux-gnu
|
|
26
|
-
- os: macos-15-intel
|
|
27
|
-
platform: macos-x64
|
|
28
|
-
rust_target: x86_64-apple-darwin
|
|
29
|
-
- os: macos-latest
|
|
30
|
-
platform: macos-arm64
|
|
31
|
-
rust_target: aarch64-apple-darwin
|
|
32
|
-
- os: windows-latest
|
|
33
|
-
platform: windows-x64
|
|
34
|
-
rust_target: x86_64-pc-windows-msvc
|
|
35
|
-
|
|
36
|
-
runs-on: ${{ matrix.os }}
|
|
37
|
-
|
|
38
|
-
steps:
|
|
39
|
-
- name: Checkout chgksuite
|
|
40
|
-
uses: actions/checkout@v4
|
|
41
|
-
|
|
42
|
-
- name: Checkout pyapp
|
|
43
|
-
uses: actions/checkout@v4
|
|
44
|
-
with:
|
|
45
|
-
repository: ofek/pyapp
|
|
46
|
-
path: pyapp
|
|
47
|
-
ref: v0.29.0
|
|
48
|
-
|
|
49
|
-
- name: Install Rust
|
|
50
|
-
uses: dtolnay/rust-toolchain@stable
|
|
51
|
-
with:
|
|
52
|
-
targets: ${{ matrix.rust_target }}
|
|
53
|
-
|
|
54
|
-
- name: Create build directory
|
|
55
|
-
shell: bash
|
|
56
|
-
run: mkdir -p artifacts
|
|
57
|
-
|
|
58
|
-
# Determine versions and create requirements files
|
|
59
|
-
- name: Setup build configuration
|
|
60
|
-
id: config
|
|
61
|
-
shell: bash
|
|
62
|
-
run: |
|
|
63
|
-
TAG="${{ inputs.tag || github.ref_name }}"
|
|
64
|
-
|
|
65
|
-
# Check if this is a release build (tag) or dev build (branch)
|
|
66
|
-
IS_RELEASE="false"
|
|
67
|
-
if [[ "${{ github.ref }}" == refs/tags/* ]] || [[ -n "${{ inputs.tag }}" ]]; then
|
|
68
|
-
IS_RELEASE="true"
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
# Extract version from tag (remove 'v' prefix if present)
|
|
72
|
-
if [[ "$TAG" =~ ^v ]]; then
|
|
73
|
-
VERSION="${TAG:1}"
|
|
74
|
-
else
|
|
75
|
-
VERSION="$TAG"
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
# Fallback to reading from version.py if no tag
|
|
79
|
-
if [ -z "$VERSION" ] || [[ ! "$VERSION" =~ ^[0-9] ]]; then
|
|
80
|
-
VERSION=$(grep -oP '__version__\s*=\s*"\K[^"]+' chgksuite/version.py 2>/dev/null || \
|
|
81
|
-
grep -o '__version__\s*=\s*"[^"]*"' chgksuite/version.py | cut -d'"' -f2 || \
|
|
82
|
-
echo "0.0.0")
|
|
83
|
-
fi
|
|
84
|
-
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
85
|
-
echo "is_release=$IS_RELEASE" >> $GITHUB_OUTPUT
|
|
86
|
-
|
|
87
|
-
# For non-release builds, always use --pre to get latest beta versions
|
|
88
|
-
if [ "$IS_RELEASE" = "false" ]; then
|
|
89
|
-
PIP_PRE="--pre"
|
|
90
|
-
elif [[ "$VERSION" =~ (a|b|rc)[0-9]+ ]]; then
|
|
91
|
-
PIP_PRE="--pre"
|
|
92
|
-
else
|
|
93
|
-
PIP_PRE=""
|
|
94
|
-
fi
|
|
95
|
-
echo "pip_pre=$PIP_PRE" >> $GITHUB_OUTPUT
|
|
96
|
-
|
|
97
|
-
echo "Build configuration:"
|
|
98
|
-
echo " Version: $VERSION"
|
|
99
|
-
echo " Is release: $IS_RELEASE"
|
|
100
|
-
echo " Pip pre flag: $PIP_PRE"
|
|
101
|
-
|
|
102
|
-
# Create requirements files in pyapp directory to avoid Windows path issues
|
|
103
|
-
- name: Create requirements files
|
|
104
|
-
shell: bash
|
|
105
|
-
run: |
|
|
106
|
-
# Qt requirements
|
|
107
|
-
echo "chgksuite" > pyapp/requirements-qt.txt
|
|
108
|
-
echo "chgksuite-qt" >> pyapp/requirements-qt.txt
|
|
109
|
-
|
|
110
|
-
# Tk requirements
|
|
111
|
-
echo "chgksuite" > pyapp/requirements-tk.txt
|
|
112
|
-
echo "chgksuite-tk" >> pyapp/requirements-tk.txt
|
|
113
|
-
|
|
114
|
-
echo "=== Qt requirements ==="
|
|
115
|
-
cat pyapp/requirements-qt.txt
|
|
116
|
-
echo "=== Tk requirements ==="
|
|
117
|
-
cat pyapp/requirements-tk.txt
|
|
118
|
-
|
|
119
|
-
# Build Qt GUI (skip on linux-arm64 - no PyQt6 wheel)
|
|
120
|
-
- name: Build Qt GUI
|
|
121
|
-
if: matrix.platform != 'linux-arm64'
|
|
122
|
-
shell: bash
|
|
123
|
-
working-directory: pyapp
|
|
124
|
-
run: |
|
|
125
|
-
export PYAPP_PROJECT_NAME="chgksuite-qt"
|
|
126
|
-
export PYAPP_PROJECT_VERSION="${{ steps.config.outputs.version }}"
|
|
127
|
-
export PYAPP_PROJECT_DEPENDENCY_FILE="$(pwd)/requirements-qt.txt"
|
|
128
|
-
export PYAPP_EXEC_SPEC="chgksuite_qt.__main__:main"
|
|
129
|
-
export PYAPP_PYTHON_VERSION="3.12"
|
|
130
|
-
export PYAPP_IS_GUI="1"
|
|
131
|
-
export PYAPP_UV_ENABLED="1"
|
|
132
|
-
export PYAPP_PIP_EXTRA_ARGS="${{ steps.config.outputs.pip_pre }}"
|
|
133
|
-
export PYAPP_PASS_LOCATION="1"
|
|
134
|
-
|
|
135
|
-
echo "Building Qt GUI with:"
|
|
136
|
-
echo " PYAPP_PROJECT_DEPENDENCY_FILE=$PYAPP_PROJECT_DEPENDENCY_FILE"
|
|
137
|
-
echo " PYAPP_PIP_EXTRA_ARGS=$PYAPP_PIP_EXTRA_ARGS"
|
|
138
|
-
|
|
139
|
-
cargo build --release --target ${{ matrix.rust_target }}
|
|
140
|
-
|
|
141
|
-
# Copy binary with platform-specific naming
|
|
142
|
-
if [ "${{ runner.os }}" = "Windows" ]; then
|
|
143
|
-
cp target/${{ matrix.rust_target }}/release/pyapp.exe ../artifacts/chgkq-${{ matrix.platform }}.exe
|
|
144
|
-
else
|
|
145
|
-
cp target/${{ matrix.rust_target }}/release/pyapp ../artifacts/chgkq-${{ matrix.platform }}
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
# Build Tk GUI
|
|
149
|
-
- name: Build Tk GUI
|
|
150
|
-
shell: bash
|
|
151
|
-
working-directory: pyapp
|
|
152
|
-
run: |
|
|
153
|
-
export PYAPP_PROJECT_NAME="chgksuite-tk"
|
|
154
|
-
export PYAPP_PROJECT_VERSION="${{ steps.config.outputs.version }}"
|
|
155
|
-
export PYAPP_PROJECT_DEPENDENCY_FILE="$(pwd)/requirements-tk.txt"
|
|
156
|
-
export PYAPP_EXEC_SPEC="chgksuite_tk.__main__:main"
|
|
157
|
-
export PYAPP_PYTHON_VERSION="3.12"
|
|
158
|
-
export PYAPP_IS_GUI="1"
|
|
159
|
-
export PYAPP_UV_ENABLED="1"
|
|
160
|
-
export PYAPP_PIP_EXTRA_ARGS="${{ steps.config.outputs.pip_pre }}"
|
|
161
|
-
export PYAPP_PASS_LOCATION="1"
|
|
162
|
-
|
|
163
|
-
echo "Building Tk GUI with:"
|
|
164
|
-
echo " PYAPP_PROJECT_DEPENDENCY_FILE=$PYAPP_PROJECT_DEPENDENCY_FILE"
|
|
165
|
-
echo " PYAPP_PIP_EXTRA_ARGS=$PYAPP_PIP_EXTRA_ARGS"
|
|
166
|
-
|
|
167
|
-
cargo build --release --target ${{ matrix.rust_target }}
|
|
168
|
-
|
|
169
|
-
# Copy binary with platform-specific naming
|
|
170
|
-
if [ "${{ runner.os }}" = "Windows" ]; then
|
|
171
|
-
cp target/${{ matrix.rust_target }}/release/pyapp.exe ../artifacts/chgkt-${{ matrix.platform }}.exe
|
|
172
|
-
else
|
|
173
|
-
cp target/${{ matrix.rust_target }}/release/pyapp ../artifacts/chgkt-${{ matrix.platform }}
|
|
174
|
-
fi
|
|
175
|
-
|
|
176
|
-
# Create macOS .app bundles (required for Finder launch)
|
|
177
|
-
- name: Create macOS app bundles
|
|
178
|
-
if: runner.os == 'macOS'
|
|
179
|
-
shell: bash
|
|
180
|
-
run: |
|
|
181
|
-
# Create Qt .app bundle
|
|
182
|
-
if [ -f "artifacts/chgkq-${{ matrix.platform }}" ]; then
|
|
183
|
-
mkdir -p "artifacts/chgkq.app/Contents/MacOS"
|
|
184
|
-
mv "artifacts/chgkq-${{ matrix.platform }}" "artifacts/chgkq.app/Contents/MacOS/chgkq"
|
|
185
|
-
cat > "artifacts/chgkq.app/Contents/Info.plist" << 'EOF'
|
|
186
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
187
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
188
|
-
<plist version="1.0">
|
|
189
|
-
<dict>
|
|
190
|
-
<key>CFBundleExecutable</key>
|
|
191
|
-
<string>chgkq</string>
|
|
192
|
-
<key>CFBundleIdentifier</key>
|
|
193
|
-
<string>me.pecheny.chgkq</string>
|
|
194
|
-
<key>CFBundleName</key>
|
|
195
|
-
<string>chgksuite-qt</string>
|
|
196
|
-
<key>CFBundlePackageType</key>
|
|
197
|
-
<string>APPL</string>
|
|
198
|
-
<key>CFBundleVersion</key>
|
|
199
|
-
<string>${{ steps.config.outputs.version }}</string>
|
|
200
|
-
<key>CFBundleShortVersionString</key>
|
|
201
|
-
<string>${{ steps.config.outputs.version }}</string>
|
|
202
|
-
<key>LSMinimumSystemVersion</key>
|
|
203
|
-
<string>10.15</string>
|
|
204
|
-
<key>NSHighResolutionCapable</key>
|
|
205
|
-
<true/>
|
|
206
|
-
</dict>
|
|
207
|
-
</plist>
|
|
208
|
-
EOF
|
|
209
|
-
# Ad-hoc sign the app bundle to prevent "damaged" error
|
|
210
|
-
codesign --force --deep --sign - "artifacts/chgkq.app"
|
|
211
|
-
# Zip the .app bundle
|
|
212
|
-
cd artifacts && zip -r "chgkq-${{ matrix.platform }}.zip" chgkq.app && rm -rf chgkq.app && cd ..
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
# Create Tk .app bundle
|
|
216
|
-
if [ -f "artifacts/chgkt-${{ matrix.platform }}" ]; then
|
|
217
|
-
mkdir -p "artifacts/chgkt.app/Contents/MacOS"
|
|
218
|
-
mv "artifacts/chgkt-${{ matrix.platform }}" "artifacts/chgkt.app/Contents/MacOS/chgkt"
|
|
219
|
-
cat > "artifacts/chgkt.app/Contents/Info.plist" << 'EOF'
|
|
220
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
221
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
222
|
-
<plist version="1.0">
|
|
223
|
-
<dict>
|
|
224
|
-
<key>CFBundleExecutable</key>
|
|
225
|
-
<string>chgkt</string>
|
|
226
|
-
<key>CFBundleIdentifier</key>
|
|
227
|
-
<string>me.pecheny.chgkt</string>
|
|
228
|
-
<key>CFBundleName</key>
|
|
229
|
-
<string>chgksuite-tk</string>
|
|
230
|
-
<key>CFBundlePackageType</key>
|
|
231
|
-
<string>APPL</string>
|
|
232
|
-
<key>CFBundleVersion</key>
|
|
233
|
-
<string>${{ steps.config.outputs.version }}</string>
|
|
234
|
-
<key>CFBundleShortVersionString</key>
|
|
235
|
-
<string>${{ steps.config.outputs.version }}</string>
|
|
236
|
-
<key>LSMinimumSystemVersion</key>
|
|
237
|
-
<string>10.15</string>
|
|
238
|
-
<key>NSHighResolutionCapable</key>
|
|
239
|
-
<true/>
|
|
240
|
-
</dict>
|
|
241
|
-
</plist>
|
|
242
|
-
EOF
|
|
243
|
-
# Ad-hoc sign the app bundle to prevent "damaged" error
|
|
244
|
-
codesign --force --deep --sign - "artifacts/chgkt.app"
|
|
245
|
-
# Zip the .app bundle
|
|
246
|
-
cd artifacts && zip -r "chgkt-${{ matrix.platform }}.zip" chgkt.app && rm -rf chgkt.app && cd ..
|
|
247
|
-
fi
|
|
248
|
-
|
|
249
|
-
- name: List artifacts
|
|
250
|
-
shell: bash
|
|
251
|
-
run: ls -lh artifacts/
|
|
252
|
-
|
|
253
|
-
- name: Upload artifacts
|
|
254
|
-
uses: actions/upload-artifact@v4
|
|
255
|
-
with:
|
|
256
|
-
name: builds-${{ matrix.platform }}
|
|
257
|
-
path: artifacts/*
|
|
258
|
-
|
|
259
|
-
release:
|
|
260
|
-
needs: build
|
|
261
|
-
runs-on: ubuntu-latest
|
|
262
|
-
if: startsWith(github.ref, 'refs/tags/') || inputs.tag != ''
|
|
263
|
-
permissions:
|
|
264
|
-
contents: write
|
|
265
|
-
|
|
266
|
-
steps:
|
|
267
|
-
- name: Download all artifacts
|
|
268
|
-
uses: actions/download-artifact@v4
|
|
269
|
-
with:
|
|
270
|
-
path: artifacts
|
|
271
|
-
merge-multiple: true
|
|
272
|
-
|
|
273
|
-
- name: List artifacts
|
|
274
|
-
run: ls -la artifacts/
|
|
275
|
-
|
|
276
|
-
- name: Create Release
|
|
277
|
-
uses: softprops/action-gh-release@v1
|
|
278
|
-
with:
|
|
279
|
-
tag_name: ${{ inputs.tag || github.ref_name }}
|
|
280
|
-
files: artifacts/*
|
|
281
|
-
generate_release_notes: true
|
|
282
|
-
env:
|
|
283
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
chgksuite-0.27.2/.gitlab-ci.yml
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
image: python:3.14-trixie
|
|
2
|
-
|
|
3
|
-
before_script:
|
|
4
|
-
- pip install zensical
|
|
5
|
-
|
|
6
|
-
pages:
|
|
7
|
-
stage: deploy
|
|
8
|
-
script:
|
|
9
|
-
- cd docs
|
|
10
|
-
- zensical build
|
|
11
|
-
- mv public ../public
|
|
12
|
-
- cd ..
|
|
13
|
-
artifacts:
|
|
14
|
-
paths:
|
|
15
|
-
- public
|
|
16
|
-
rules:
|
|
17
|
-
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
|