tgblocks 0.2.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.
Files changed (63) hide show
  1. tgblocks-0.2.0/.gitignore +17 -0
  2. tgblocks-0.2.0/CHANGELOG.md +96 -0
  3. tgblocks-0.2.0/GITHUB.md +267 -0
  4. tgblocks-0.2.0/LICENSE +21 -0
  5. tgblocks-0.2.0/PKG-INFO +382 -0
  6. tgblocks-0.2.0/README.md +346 -0
  7. tgblocks-0.2.0/examples/features.txt +16 -0
  8. tgblocks-0.2.0/examples/full.tg +107 -0
  9. tgblocks-0.2.0/examples/hello.tg +35 -0
  10. tgblocks-0.2.0/pyproject.toml +56 -0
  11. tgblocks-0.2.0/src/tgblocks/__init__.py +26 -0
  12. tgblocks-0.2.0/src/tgblocks/__main__.py +6 -0
  13. tgblocks-0.2.0/src/tgblocks/cli.py +290 -0
  14. tgblocks-0.2.0/src/tgblocks/convert.py +1023 -0
  15. tgblocks-0.2.0/src/tgblocks/dsl/__init__.py +33 -0
  16. tgblocks-0.2.0/src/tgblocks/dsl/codegen.py +942 -0
  17. tgblocks-0.2.0/src/tgblocks/dsl/parser.py +919 -0
  18. tgblocks-0.2.0/src/tgblocks/model.py +865 -0
  19. tgblocks-0.2.0/src/tgblocks/network.py +174 -0
  20. tgblocks-0.2.0/src/tgblocks/runner.py +86 -0
  21. tgblocks-0.2.0/src/tgblocks/textlang.py +666 -0
  22. tgblocks-0.2.0/src/tgblocks/visual/__init__.py +5 -0
  23. tgblocks-0.2.0/src/tgblocks/visual/server.py +990 -0
  24. tgblocks-0.2.0/src/tgblocks/visual/static/blocks.html +634 -0
  25. tgblocks-0.2.0/src/tgblocks/visual/static/nodes.html +1966 -0
  26. tgblocks-0.2.0/src/tgblocks/visual/static/text.html +551 -0
  27. tgblocks-0.2.0/src/tgblocks/visual/static/tgblocks-project.js +239 -0
  28. tgblocks-0.2.0/src/tgblocks/visual/static/tgblocks-ui.js +327 -0
  29. tgblocks-0.2.0/src/tgblocks/visual/static/vendor/blockly.js +1691 -0
  30. tgblocks-0.2.0/tests/botkit.py +207 -0
  31. tgblocks-0.2.0/tests/corpus.py +250 -0
  32. tgblocks-0.2.0/tests/golden/actions.py +113 -0
  33. tgblocks-0.2.0/tests/golden/conditions.py +97 -0
  34. tgblocks-0.2.0/tests/golden/events.py +153 -0
  35. tgblocks-0.2.0/tests/golden/hello.py +138 -0
  36. tgblocks-0.2.0/tests/golden/long-buttons.py +103 -0
  37. tgblocks-0.2.0/tests/golden/nested.py +113 -0
  38. tgblocks-0.2.0/tests/golden/patterns.py +83 -0
  39. tgblocks-0.2.0/tests/golden/proxy.py +80 -0
  40. tgblocks-0.2.0/tests/golden/text-actions.py +123 -0
  41. tgblocks-0.2.0/tests/golden/text-basic.py +109 -0
  42. tgblocks-0.2.0/tests/golden/text-buttons.py +124 -0
  43. tgblocks-0.2.0/tests/test_blockly.py +93 -0
  44. tgblocks-0.2.0/tests/test_bots.py +224 -0
  45. tgblocks-0.2.0/tests/test_clear.py +109 -0
  46. tgblocks-0.2.0/tests/test_cli.py +198 -0
  47. tgblocks-0.2.0/tests/test_dice.py +77 -0
  48. tgblocks-0.2.0/tests/test_dsl.py +123 -0
  49. tgblocks-0.2.0/tests/test_examples.py +82 -0
  50. tgblocks-0.2.0/tests/test_features.py +364 -0
  51. tgblocks-0.2.0/tests/test_filters.py +94 -0
  52. tgblocks-0.2.0/tests/test_golden.py +84 -0
  53. tgblocks-0.2.0/tests/test_hidden_filters.py +82 -0
  54. tgblocks-0.2.0/tests/test_i18n.py +58 -0
  55. tgblocks-0.2.0/tests/test_proxy.py +214 -0
  56. tgblocks-0.2.0/tests/test_scaffold.py +84 -0
  57. tgblocks-0.2.0/tests/test_security.py +141 -0
  58. tgblocks-0.2.0/tests/test_server_ports.py +146 -0
  59. tgblocks-0.2.0/tests/test_sync.py +350 -0
  60. tgblocks-0.2.0/tests/test_ui.py +181 -0
  61. tgblocks-0.2.0/tests/test_validation.py +117 -0
  62. tgblocks-0.2.0/tests/test_whitespace.py +56 -0
  63. tgblocks-0.2.0//320/230/320/235/320/241/320/242/320/240/320/243/320/232/320/246/320/230/320/257.md +699 -0
@@ -0,0 +1,17 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .venv/
7
+ venv/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .coverage
12
+ # generated bots
13
+ bot.py
14
+ !examples/*.py
15
+ .idea/
16
+ .vscode/
17
+ .DS_Store
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ The release that made the three editors agree with each other.
6
+
7
+ ### Added
8
+
9
+ - **A single feature catalogue** (`src/tgblocks/model.py`): every action and event is
10
+ described once, and the DSL parser, the text parser, the converters, the code
11
+ generator and all three editors read it. `/api/schema` serves it to the pages, so a
12
+ new block appears in `/nodes`, `/blocks` and `/text` without touching their code.
13
+ - **Media**: `send_document`, `send_video`, `send_animation`, `send_audio`,
14
+ `send_voice`, `send_sticker`, `send_location`, `send_contact`, `send_poll`,
15
+ `send_dice`.
16
+ - **Editing and answering**: `edit_text`, `answer_callback [alert]`.
17
+ - **Chat actions**: `pin [silent]`, `unpin`.
18
+ - **Moderation**: `ban_user`, `unban_user`, `mute_user` — without an ID they act on the
19
+ sender of the message.
20
+ - **Dialogues (FSM)**: `state order`, `set_state`, `clear_state`, `on state order:`.
21
+ The generated bot gets `StatesGroup` and a `MemoryStorage` dispatcher.
22
+ - **Events**: `on callback:`, `on callback "/data":`, `on inline_query:` with
23
+ `inline_result`, `on chat_member:`, `on my_chat_member:`, `on poll_answer:`,
24
+ `on channel_post:`, `on dice:`, `on pinned:`, `on web_app_data:`.
25
+ - **Filters** on any event: `chat=`, `from_user=`, `regex=`.
26
+ - **Webhook mode**: `bot webhook`, `bot webhook_path`, `bot webhook_secret`.
27
+ - **Keyboard buttons**: Web App buttons, and reply buttons that request a contact or a
28
+ location.
29
+ - `tgblocks check` reports warnings, and the editors show them.
30
+ - `tools/check_javascript.py`, and tests that parse every page.
31
+
32
+ ### Changed
33
+
34
+ - `tgblocks compile` writes code **without** the token; `--embed-token` restores the old
35
+ behaviour. `tgblocks run` passes the token through the environment.
36
+ - Generated helpers are emitted only when a bot uses them, so a small bot stays small.
37
+ - The node editor no longer has its own JavaScript DSL writer: the board goes to the
38
+ server, and one converter produces the shared text and the code.
39
+ - The block editor sends its Blockly workspace as XML; the server converts it back.
40
+ Blocks are now chained with `<next>`, which fixes only the first handler being shown.
41
+ - `scaffold.py` is generated from the tree by `tools/build_scaffold.py` and checked by
42
+ `tests/test_scaffold.py`.
43
+
44
+ ### Fixed
45
+
46
+ - **Security**: the local server refused nothing from other origins. It now checks
47
+ `Host`, `Origin` and `Sec-Fetch-Site`, requires `application/json` bodies, and needs
48
+ `--allow-remote` before `--host` exposes it. Requests from a foreign page could start
49
+ arbitrary code through `/api/run`.
50
+ - Two handlers with the same filters are refused instead of silently leaving the second
51
+ one dead.
52
+ - A button that calls a command nobody handles produces a warning.
53
+ - `pass` at the top level of the text syntax no longer raises `NameError`.
54
+ - The server no longer reloads the DSL modules on every request (that replaced the
55
+ exception classes under a running `except`).
56
+ - On Windows, a second `tgblocks visual` can no longer bind the same port and leave the
57
+ old code answering.
58
+ - `Tuple` is imported where it is annotated; the long-line wrapper, the entity escaping
59
+ and the `_1`-suffixed handler names are consistent.
60
+ - **Filters and magic filters**: `Command("start") & F.chat.type == "private"` crashed
61
+ with `TypeError: unsupported operand type(s) for &: 'Command' and 'bool'`. Filters are
62
+ now separate decorator arguments, and every combination is run against aiogram in
63
+ `tests/test_filters.py`.
64
+ - **The three views stay in sync when a document is emptied**: clearing a canvas or the
65
+ text sets a new revision with empty text, instead of leaving the old bot in the other
66
+ views. A half-built canvas still keeps the last good text.
67
+ - **Editor pages no longer hang**: a missing page-local helper (`L`) threw at boot and
68
+ left `/blocks` and `/text` on "Loading Blockly…"; `tools/check_javascript.py` now fails
69
+ on a helper that is called but never defined.
70
+ - **The light theme was broken**: colours were hardcoded per rule, so only `--bg`/`--panel`
71
+ changed. Every surface is a variable now (`--chip`, `--field`, `--log`, `--tok-*`), and
72
+ the Blockly canvas follows the theme too.
73
+ - `/blocks?lang=ru` reloaded itself in a loop, because the page compared the language
74
+ before the preference was read.
75
+ - Stray spaces or tabs around a pasted token, proxy or webhook URL are stripped instead of
76
+ silently breaking the connection.
77
+
78
+ ### Editor
79
+
80
+ - **Settings in every view**: ⚙ in the header switches the theme (dark/light) and the
81
+ interface language (English by default, Russian optional). The choice is remembered and
82
+ can be shared as `?theme=light&lang=ru`; the whole catalogue — block names, field
83
+ captions, hints, drop-down values, status lines — is translated.
84
+ - **Typing is one-line everywhere again**, and every field has a caption, so a drop-down
85
+ says what it is.
86
+ - **Two event filters are hidden** from the panel: "only these texts" and "matches a
87
+ pattern". A `when` condition does the same job visibly. Values that come from the text
88
+ view are kept and shown as a removable chip, so nothing is dropped silently.
89
+ - **Blockly ships with the package** (`static/vendor/blockly.js`), so the block editor
90
+ works without internet; the CDN is only a fallback.
91
+ - The palette scrollbar is thin and vertical; a drag handle sets the panel width.
92
+ - The scrollbar, the fields and the node headers are correct in both themes.
93
+
94
+ ## 0.1.0
95
+
96
+ First public shape: DSL, one code generator, three editors, no tests worth the name.
@@ -0,0 +1,267 @@
1
+ # Публикация tgblocks на GitHub и в PyPI
2
+
3
+ Полная инструкция с нуля: от пустого аккаунта до `pip install tgblocks` у любого
4
+ человека. Всё, что нужно сделать тебе, — один раз выполнить команды из разделов 1–4,
5
+ а потом (по желанию) разделы 5–6.
6
+
7
+ ---
8
+
9
+ ## 0. Что понадобится
10
+
11
+ **Аккаунт GitHub** — хранить код: <https://github.com/signup>
12
+
13
+ **git** — отправлять код: <https://git-scm.com/download/win>
14
+ (при установке оставь галочки по умолчанию)
15
+
16
+ **Python 3.9 или новее** — собирать пакет: <https://www.python.org/downloads/>
17
+
18
+ **Аккаунт PyPI** — чтобы работал `pip install`: <https://pypi.org/account/register/>
19
+
20
+ Проверка, что всё стоит:
21
+
22
+ ```powershell
23
+ git --version
24
+ python --version
25
+ ```
26
+
27
+ ---
28
+
29
+ ## 1. Один раз настроить git
30
+
31
+ ```powershell
32
+ git config --global user.name "Твоё Имя"
33
+ git config --global user.email "твоя_почта@example.com"
34
+ ```
35
+
36
+ Почта должна совпадать с той, на которую зарегистрирован GitHub — иначе коммиты не
37
+ будут связаны с профилем.
38
+
39
+ ---
40
+
41
+ ## 2. Создать репозиторий на GitHub
42
+
43
+ 1. Открой <https://github.com/new>.
44
+ 2. **Repository name**: `tgblocks`.
45
+ 3. **Public** (для приватного всё то же, но `pip install` с GitHub не сработает).
46
+ 4. **НЕ** ставь галочки «Add a README», «Add .gitignore», «Choose a license» — они уже
47
+ есть в проекте, иначе будет конфликт при первом `push`.
48
+ 5. **Create repository**.
49
+
50
+ GitHub покажет адрес вида `https://github.com/Pupka228228/tgblocks.git`.
51
+
52
+ ---
53
+
54
+ ## 3. Отправить код (первый push)
55
+
56
+ ```powershell
57
+ cd C:\TGBots\tgblocks
58
+ git status # должно быть "nothing to commit, working tree clean"
59
+ git log --oneline | Select-Object -First 3
60
+
61
+ git remote add origin https://github.com/Pupka228228/tgblocks.git
62
+ git branch -M main
63
+ git push -u origin main
64
+ ```
65
+
66
+ Если `remote origin already exists`:
67
+
68
+ ```powershell
69
+ git remote set-url origin https://github.com/Pupka228228/tgblocks.git
70
+ ```
71
+
72
+ ### Пароль не подойдёт — нужен токен
73
+
74
+ GitHub больше не принимает пароль аккаунта. Один раз:
75
+
76
+ 1. <https://github.com/settings/tokens> → **Generate new token (classic)**.
77
+ 2. Note: `tgblocks push`, Expiration: 90 days, галочка **`repo`**.
78
+ 3. **Generate token**, скопируй строку `ghp_...` (она показывается один раз).
79
+ 4. В окне `git push` на запрос пароля вставь этот токен, логин — обычный.
80
+
81
+ Сохранить токен в менеджере Windows, чтобы не вводить каждый раз:
82
+
83
+ ```powershell
84
+ git config --global credential.helper manager
85
+ ```
86
+
87
+ Альтернатива — GitHub CLI:
88
+
89
+ ```powershell
90
+ winget install --id GitHub.cli
91
+ gh auth login # выбираешь GitHub.com → HTTPS → Login with a web browser
92
+ ```
93
+
94
+ ### Каждый следующий раз
95
+
96
+ ```powershell
97
+ git add -A
98
+ git commit -m "что изменилось"
99
+ git push
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 4. Проверить, что всё в порядке
105
+
106
+ 1. Открой страницу репозитория — файлы на месте, README и `docs/demo.gif` видны.
107
+ 2. Вкладка **Actions**: workflow **CI** должен стать зелёным. Он прогоняет 261 тест на
108
+ Windows и Linux (Python 3.9, 3.11, 3.13), проверяет JS редакторов, собирает пакет и
109
+ ставит его в чистое окружение.
110
+ 3. Бейдж в README (вставь после заголовка):
111
+
112
+ ```markdown
113
+ [![CI](https://github.com/Pupka228228/tgblocks/actions/workflows/ci.yml/badge.svg)](https://github.com/Pupka228228/tgblocks/actions/workflows/ci.yml)
114
+ ```
115
+
116
+ Если Actions красный — открой лог: чаще всего это не установленные зависимости, а не
117
+ код; локально повтори `python -m pytest -q`.
118
+
119
+ ---
120
+
121
+ ## 5. Установка из GitHub (работает сразу после push)
122
+
123
+ Ничего дополнительно публиковать не нужно:
124
+
125
+ ```bash
126
+ pip install "tgblocks[runtime] @ git+https://github.com/Pupka228228/tgblocks.git"
127
+ tgblocks
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 6. PyPI: чтобы работала одна строка `pip install tgblocks`
133
+
134
+ ### 6.1 Аккаунт и токен
135
+
136
+ 1. Регистрация: <https://pypi.org/account/register/>.
137
+ 2. Включи **двухфакторную аутентификацию** (без неё токен не создать):
138
+ Account settings → Two-factor authentication.
139
+ 3. Account settings → **API tokens** → **Add API token** → Name: `tgblocks`,
140
+ Scope: **Entire account** (для первого раза) → **Add token**.
141
+ 4. Скопируй `pypi-AgEIcHlwaS5vcmc...` — это пароль для загрузки.
142
+
143
+ ### 6.2 Собрать и проверить
144
+
145
+ ```powershell
146
+ cd C:\TGBots\tgblocks
147
+ python -m pip install --upgrade build twine
148
+ python -m build # dist\tgblocks-0.2.0-py3-none-any.whl и .tar.gz
149
+ python -m twine check dist/* # "PASSED" для обоих файлов
150
+ ```
151
+
152
+ ### 6.3 Загрузить
153
+
154
+ ```powershell
155
+ python -m twine upload dist/*
156
+ ```
157
+
158
+ Логин: `__token__`, пароль: сам токен `pypi-...`.
159
+
160
+ Проверка (подожди полминуты):
161
+
162
+ ```powershell
163
+ pip install --upgrade "tgblocks[runtime]"
164
+ tgblocks --version
165
+ ```
166
+
167
+ ### 6.4 Тренировка на тестовом индексе (необязательно)
168
+
169
+ ```powershell
170
+ python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
171
+ pip install --index-url https://test.pypi.org/simple tgblocks
172
+ ```
173
+
174
+ Там отдельный аккаунт (<https://test.pypi.org/account/register/>) и отдельный токен.
175
+
176
+ ---
177
+
178
+ ## 7. Как это ставится у любого человека
179
+
180
+ ```bash
181
+ pip install "tgblocks[runtime]" # пакет + aiogram, чтобы запускать ботов
182
+ tgblocks # редактор: http://127.0.0.1:8765/
183
+ tgblocks check mybot.tg
184
+ tgblocks compile mybot.tg -o bot.py
185
+ ```
186
+
187
+ - без `[runtime]` ставится только компилятор и редакторы (генерация кода работает);
188
+ - `tgblocks` появляется в PATH вместе с Python; в виртуальном окружении — после
189
+ активации. Если команда не находится: `python -m tgblocks` работает всегда.
190
+
191
+ ---
192
+
193
+ ## 8. Выпуск новой версии
194
+
195
+ 1. Подними версию в `pyproject.toml` (`version = "0.2.1"`).
196
+ 2. Допиши раздел в `CHANGELOG.md`.
197
+ 3. Прогони проверки:
198
+
199
+ ```powershell
200
+ python -m pytest -q
201
+ python tools/build_scaffold.py --check
202
+ python tools/check_javascript.py
203
+ python -m build
204
+ python -m twine check dist/*
205
+ ```
206
+
207
+ 4. Отправь код и создай релиз:
208
+
209
+ ```powershell
210
+ git add -A
211
+ git commit -m "release 0.2.1"
212
+ git tag v0.2.1
213
+ git push
214
+ git push --tags
215
+ ```
216
+
217
+ На GitHub: **Releases** → **Draft a new release** → выбери тег `v0.2.1` → опиши
218
+ изменения → прикрепи файлы из `dist/` → **Publish release**.
219
+
220
+ 5. Загрузи в PyPI (`python -m twine upload dist/*`). Одно и то же имя версии дважды
221
+ загрузить нельзя — всегда поднимай номер.
222
+
223
+ ---
224
+
225
+ ## 9. Частые проблемы
226
+
227
+ **`Authentication failed` при push** — введён пароль вместо токена.
228
+ Смотри раздел 3, нужен токен с галочкой `repo`.
229
+
230
+ **`remote origin already exists`** — remote уже привязан.
231
+ Выполни `git remote set-url origin <адрес>`.
232
+
233
+ **`Updates were rejected`** — на GitHub уже есть коммиты (например, создавал README
234
+ через сайт). Сделай `git pull --rebase origin main`, потом `git push`.
235
+
236
+ **`403` при `twine upload`** — токен без Scope «Entire account» или не включена 2FA.
237
+ Создай токен заново.
238
+
239
+ **`File already exists` на PyPI** — эта версия уже загружена.
240
+ Подними `version` в `pyproject.toml`.
241
+
242
+ **`tgblocks: command not found`** — папка скриптов Python не в PATH.
243
+ Активируй venv или запускай `python -m tgblocks`.
244
+
245
+ **`ModuleNotFoundError: aiogram`** при запуске бота — пакет поставлен без `[runtime]`.
246
+ Нужен `pip install "tgblocks[runtime]"`.
247
+
248
+ **README не показывает картинки** — файлы не попали в репозиторий.
249
+ Проверь, что `docs/editor-nodes.png`, `docs/editor-blocks.png`, `docs/editor-text.png`
250
+ и `docs/demo.gif` закоммичены, а ветка в ссылках — `main`.
251
+
252
+ ---
253
+
254
+ ## 10. Чек-лист перед публикацией
255
+
256
+ ```powershell
257
+ python -m pytest -q # 261 passed
258
+ python tools/build_scaffold.py --check # scaffold.py не отстал
259
+ python tools/check_javascript.py # JS редакторов и его хелперы
260
+ python tools/qa_smoke.py # эндпоинты + переходы между видами
261
+ python -m build
262
+ python -m twine check dist/*
263
+ ```
264
+
265
+ И глазами: `tgblocks` открывает редактор, `⚙` переключает тему и язык,
266
+ `tgblocks check examples/full.tg` печатает сводку, `tgblocks compile examples/hello.tg
267
+ -o bot.py` даёт файл, который открывается в PyCharm без ошибок.
tgblocks-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tgblocks contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.