HtmlDownloader 1.0.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.
- htmldownloader-1.0.0/LICENSE.md +21 -0
- htmldownloader-1.0.0/PKG-INFO +379 -0
- htmldownloader-1.0.0/README.md +363 -0
- htmldownloader-1.0.0/pyproject.toml +29 -0
- htmldownloader-1.0.0/setup.cfg +4 -0
- htmldownloader-1.0.0/src/HtmlDownloader/__init__.py +8 -0
- htmldownloader-1.0.0/src/HtmlDownloader/__main__.py +6 -0
- htmldownloader-1.0.0/src/HtmlDownloader/about_page.py +200 -0
- htmldownloader-1.0.0/src/HtmlDownloader/check_system.py +521 -0
- htmldownloader-1.0.0/src/HtmlDownloader/cli.py +388 -0
- htmldownloader-1.0.0/src/HtmlDownloader/menu_language.py +754 -0
- htmldownloader-1.0.0/src/HtmlDownloader/menu_model.py +278 -0
- htmldownloader-1.0.0/src/HtmlDownloader/menu_painter.py +468 -0
- htmldownloader-1.0.0/src/HtmlDownloader/menu_session.py +120 -0
- htmldownloader-1.0.0/src/HtmlDownloader/page_download.py +1305 -0
- htmldownloader-1.0.0/src/HtmlDownloader/page_open.py +393 -0
- htmldownloader-1.0.0/src/HtmlDownloader/page_serve.py +131 -0
- htmldownloader-1.0.0/src/HtmlDownloader/self_management.py +79 -0
- htmldownloader-1.0.0/src/HtmlDownloader/system_log.py +92 -0
- htmldownloader-1.0.0/src/HtmlDownloader/tui.py +729 -0
- htmldownloader-1.0.0/src/HtmlDownloader.egg-info/PKG-INFO +379 -0
- htmldownloader-1.0.0/src/HtmlDownloader.egg-info/SOURCES.txt +30 -0
- htmldownloader-1.0.0/src/HtmlDownloader.egg-info/dependency_links.txt +1 -0
- htmldownloader-1.0.0/src/HtmlDownloader.egg-info/entry_points.txt +2 -0
- htmldownloader-1.0.0/src/HtmlDownloader.egg-info/requires.txt +1 -0
- htmldownloader-1.0.0/src/HtmlDownloader.egg-info/top_level.txt +1 -0
- htmldownloader-1.0.0/tests/test_about.py +1074 -0
- htmldownloader-1.0.0/tests/test_docs.py +72 -0
- htmldownloader-1.0.0/tests/test_download.py +789 -0
- htmldownloader-1.0.0/tests/test_language.py +196 -0
- htmldownloader-1.0.0/tests/test_serve.py +298 -0
- htmldownloader-1.0.0/tests/test_tui.py +307 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wilgat Wong <wilgat.wong@gmail.com>
|
|
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.
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: HtmlDownloader
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: HtmlDownloader downloads one HTML page and its stylesheets, scripts, and images.
|
|
5
|
+
Author-email: Wilgat Wong <wilgat.wong@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cloudgen/HtmlDownloader
|
|
8
|
+
Project-URL: Repository, https://github.com/cloudgen/HtmlDownloader
|
|
9
|
+
Project-URL: Issues, https://github.com/cloudgen/HtmlDownloader/issues
|
|
10
|
+
Keywords: CLI,TUI,download,HTML
|
|
11
|
+
Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE.md
|
|
14
|
+
Requires-Dist: ChronicleLogger>=1.3.1
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# HtmlDownloader - Download a page from the command line and from the text menu
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+

|
|
21
|
+
[-purple.svg)](https://github.com/cloudgen/ciao)
|
|
22
|
+
[](https://github.com/cloudgen/HtmlDownloader)
|
|
23
|
+
[-blue?style=flat-square)]()
|
|
24
|
+
[](https://pypi.org/project/HtmlDownloader/)
|
|
25
|
+
|
|
26
|
+
HtmlDownloader downloads one HTML page and the stylesheets, scripts, and images that page links to. The typed verb `download` saves that page. Menu row **1 download** lists pages saved earlier, or accepts a URL. Menu row **2 list downloaded** lists saved page names, then opens the chosen page in Visual Studio Code or the default browser.
|
|
27
|
+
|
|
28
|
+
On a terminal, starting it with no arguments opens a text menu. The menu does not download a page by itself, and it does not call pip. It does not join media, call an external encoder, or list files in the folder.
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- Text menu on a terminal: **download**, **list downloaded**, **serve**, **System Log**, **self-management**, **language**, and **Exit**
|
|
33
|
+
- The first row shows the current folder and a local clock (`HH:MM:SS`) when the row has room
|
|
34
|
+
- Numbered rows line up. A rounded input box sits along the bottom, as wide as the terminal, with the name and version on the status line under the box
|
|
35
|
+
- **download** (1) lists saved `page name: URL` pairs, or accepts a URL and a page name. The typed verb `download --url URL --name PAGENAME` saves the page and does not draw the menu. A later run keeps `index.html` and fills in files that are still missing
|
|
36
|
+
- **list downloaded** (2) lists saved page names by number. After a page is chosen, **21 edit** opens `index.html` in Visual Studio Code when the `code` command or the Visual Studio Code desktop entry is installed, and **22 view** opens it in the default browser when one is set. A missing tool is left off that menu. **0** returns to the page list, then to the main menu
|
|
37
|
+
- **serve** (3) lists saved page names by number, then asks for a port. An empty port uses **5000**. The page folder is served at `http://127.0.0.1:<port>/` until Ctrl+C. The typed verb `serve --page-name PAGENAME` does the same without the menu. `--port` changes the port
|
|
38
|
+
- The page is `~/.app/HtmlDownloader/output/<pagename>/index.html`. Linked stylesheets go in `output/<pagename>/assets/css/`. Linked scripts go in `output/<pagename>/assets/js/`. Linked images go in `output/<pagename>/assets/img/`. Those three folders stay flat, with no subfolders. Font files sit in `assets/css/`. When `index.html` is already there, the page is not downloaded again. Missing stylesheets, scripts, and images are fetched. Files already saved are kept.
|
|
39
|
+
- **System Log** (4) opens view-log, clear-log, and log-folder. **self-management** (6) opens version, about, and the pip lifecycle rows. **language** (7) picks the menu language
|
|
40
|
+
- Console script `html-downloader` and module entry `python -m HtmlDownloader`
|
|
41
|
+
- Typed verbs: `help`, `version`, `about`, `download`, `serve`, `self-install`, `version-check`, `self-update`, `self-uninstall`
|
|
42
|
+
|
|
43
|
+
## Advantages
|
|
44
|
+
|
|
45
|
+
1. **Two ways to download.** `html-downloader download --url URL --name PAGENAME` saves the page in the terminal and does not draw the menu. On the menu, row **1 download** lists saved pages by number, or accepts a URL. With no arguments on a terminal, the text menu opens and waits. With no terminal and no verb, the program prints help and returns 0. There is no `--json`.
|
|
46
|
+
2. **Built-in languages.** Row **7** lists thirteen languages: English, Simplified Chinese, Traditional Chinese, Spanish, Arabic, French, Portuguese, Russian, German, Japanese, Korean, Dutch, and Greek. The choice is saved in `~/.local/HtmlDownloader/language` for the next run. `HTMLDOWNLOADER_LANG` overrides that file for one process and does not write it. The download verb stays English. The note on row 1 follows the menu language.
|
|
47
|
+
3. **Lifecycle and diagnostics.** `version-check`, `self-update`, `self-install`, and `self-uninstall` are menu rows **63**–**66** and typed verbs. `self-uninstall` on the command line needs `--force`. They call pip and do not use root. **System Log** (**4**) views a log, clears a log, and shows the log folder. **about** (**62**) stays in English.
|
|
48
|
+
|
|
49
|
+
## Quick Installation
|
|
50
|
+
|
|
51
|
+
**Python dependency:** `ChronicleLogger>=1.3.1` (required). Pip installs it with HtmlDownloader. No external media tool is required.
|
|
52
|
+
|
|
53
|
+
### PyPI (registry)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install HtmlDownloader
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This installs the console entry **`html-downloader`** and the package **`HtmlDownloader`**. Packaging name SSOT is `pyproject.toml` `[project].name` = `HtmlDownloader`. This tree is **1.0.0**. The PyPI badge above shows the live index.
|
|
60
|
+
|
|
61
|
+
### Local install (checkout)
|
|
62
|
+
|
|
63
|
+
From a checkout (editable / unreleased work):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/cloudgen/HtmlDownloader.git
|
|
67
|
+
cd HtmlDownloader
|
|
68
|
+
python3 -m venv venv
|
|
69
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
70
|
+
pip install -e .
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Main menu
|
|
74
|
+
|
|
75
|
+
After install, on a terminal, `html-downloader` with no arguments prints this screen. The verb is bold and the note after the colon is italic. `9` leaves. `0` on a submenu goes back. After a command finishes, the main menu is shown again. A number that is not on the list prints an error and lets you choose again.
|
|
76
|
+
|
|
77
|
+
Picture of the English menu. Current directory `/tmp/clips`. The rows are the text the menu paints. The frame is the 80-column box.
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
$ html-downloader
|
|
81
|
+
Path: /tmp/clips 12:06:45
|
|
82
|
+
|
|
83
|
+
1. **download** : *download a page and its stylesheets, scripts, and images*
|
|
84
|
+
2. **list downloaded**: *show saved page names*
|
|
85
|
+
3. **serve** : *serve a saved page on this computer*
|
|
86
|
+
4. **System Log** : *view, clear, and the log folder*
|
|
87
|
+
6. **self-management**: *version, about, and pip lifecycle*
|
|
88
|
+
7. **language** : *display language for this menu*
|
|
89
|
+
9. **Exit** : *leave*
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
╭─────────────────────────────────────────────────────────────────────────────╮
|
|
95
|
+
│ > │
|
|
96
|
+
╰─────────────────────────────────────────────────────────────────────────────╯
|
|
97
|
+
HtmlDownloader 1.0.0 │ main menu │ Up/Down • Enter
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**System Log** (4). Numbers 44–49 are not printed.
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
Path: /tmp/clips 12:06:45
|
|
104
|
+
|
|
105
|
+
41. **view-log** : *list a log file and show it*
|
|
106
|
+
42. **clear-log** : *empty one log file*
|
|
107
|
+
43. **log-folder**: *show the log folder*
|
|
108
|
+
0. **Back** : *return to the main menu*
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
╭─────────────────────────────────────────────────────────────────────────────╮
|
|
114
|
+
│ > │
|
|
115
|
+
╰─────────────────────────────────────────────────────────────────────────────╯
|
|
116
|
+
HtmlDownloader 1.0.0 │ System Log │ Up/Down • Enter
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**language** (7). The short on each language row is that language’s own name. Numbers 84–98 are not printed. `0` goes back and does not save.
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
Path: /tmp/clips 12:06:46
|
|
123
|
+
|
|
124
|
+
71. **English** : *use English for this menu*
|
|
125
|
+
72. **简体中文** : *use 简体中文 for this menu*
|
|
126
|
+
73. **繁體中文** : *use 繁體中文 for this menu*
|
|
127
|
+
74. **Español** : *use Español for this menu*
|
|
128
|
+
75. **العربية** : *use العربية for this menu*
|
|
129
|
+
76. **Français** : *use Français for this menu*
|
|
130
|
+
77. **Português** : *use Português for this menu*
|
|
131
|
+
78. **Русский** : *use Русский for this menu*
|
|
132
|
+
79. **Deutsch** : *use Deutsch for this menu*
|
|
133
|
+
80. **日本語** : *use 日本語 for this menu*
|
|
134
|
+
81. **한국어** : *use 한국어 for this menu*
|
|
135
|
+
82. **Nederlands**: *use Nederlands for this menu*
|
|
136
|
+
83. **Ελληνικά** : *use Ελληνικά for this menu*
|
|
137
|
+
0. **Back** : *return to the main menu*
|
|
138
|
+
|
|
139
|
+
╭─────────────────────────────────────────────────────────────────────────────╮
|
|
140
|
+
│ > │
|
|
141
|
+
╰─────────────────────────────────────────────────────────────────────────────╯
|
|
142
|
+
HtmlDownloader 1.0.0 │ language │ Up/Down • Enter
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**self-management** (6). Numbers 67–70 are not printed.
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
Path: /tmp/clips 14:05:09
|
|
149
|
+
|
|
150
|
+
61. **version** : *show the installed version*
|
|
151
|
+
62. **about** : *version and this computer*
|
|
152
|
+
63. **version-check** : *compare this install with pip*
|
|
153
|
+
64. **self-update** : *upgrade this package with pip*
|
|
154
|
+
65. **self-uninstall**: *remove this package with pip*
|
|
155
|
+
66. **self-install** : *install this package with pip*
|
|
156
|
+
0. **Back** : *return to the main menu*
|
|
157
|
+
|
|
158
|
+
╭─────────────────────────────────────────────────────────────────────────────╮
|
|
159
|
+
│ > │
|
|
160
|
+
╰─────────────────────────────────────────────────────────────────────────────╯
|
|
161
|
+
HtmlDownloader 1.0.0 │ self-management │ Up/Down • Enter
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Choose a number, or type the command name in the box. The block caret appears in that box while it is focused.
|
|
165
|
+
|
|
166
|
+
## Usage
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
html-downloader
|
|
170
|
+
# or
|
|
171
|
+
python -m HtmlDownloader
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
On a terminal, that opens the main menu above. It does not download a page yet, and it does not call pip. With no terminal, the same command prints help and returns 0.
|
|
175
|
+
|
|
176
|
+
**download** (1) stays on the menu. It lists saved `page name: URL` rows. Type a number to download that pair again, or type an `http://` or `https://` URL and then a page name. The typed verb does not draw the menu:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
html-downloader download --url https://example.com/ --name example
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
That writes `~/.app/HtmlDownloader/output/example/index.html`, puts linked stylesheets in `output/example/assets/css/`, linked scripts in `output/example/assets/js/`, and linked images in `output/example/assets/img/`. Each of those folders is a single layer. The saved page points at those local files. A `<base>` tag or an `xml:base` attribute is removed so local links stay on the saved page. A canonical link and HTML comments are removed too. The pair is remembered in `~/.app/HtmlDownloader/output/url-map.json`. Running the same command again leaves `index.html` in place and downloads only the stylesheets, scripts, and images that are not already in the page folder.
|
|
183
|
+
|
|
184
|
+
**list downloaded** (2) lists those page names by number. Choose one, then **21 edit** opens `index.html` in Visual Studio Code when `code` is installed, and **22 view** opens it in the default browser when a default browser is set. If either tool is missing, that row is not shown. **0** goes back.
|
|
185
|
+
|
|
186
|
+
**serve** (3) lists those page names by number. Choose one, then type a port. Press Enter with an empty box to use **5000**. The server listens on `127.0.0.1` and stops on Ctrl+C. The menu then shows `Stopped <name>.` The typed verb does not draw the menu:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
html-downloader serve --page-name example
|
|
190
|
+
html-downloader serve --page-name example --port 8080
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
That serves `~/.app/HtmlDownloader/output/example/` so `http://127.0.0.1:5000/` is `index.html` and `assets/` stays beside it.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
html-downloader help
|
|
197
|
+
html-downloader version
|
|
198
|
+
html-downloader about
|
|
199
|
+
html-downloader download --url https://example.com/ --name example
|
|
200
|
+
html-downloader serve --page-name example
|
|
201
|
+
html-downloader version-check
|
|
202
|
+
html-downloader self-update
|
|
203
|
+
html-downloader self-install
|
|
204
|
+
html-downloader self-uninstall --force
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`version` prints `HtmlDownloader 1.0.0` and does not call pip. `about` shows one English page: the product identity, a host check of this computer, and a star box. It does not call pip. `download` saves the page and does not draw the menu. `help` prints usage.
|
|
208
|
+
|
|
209
|
+
`version-check` runs `python -m pip index versions HtmlDownloader`. `self-update` runs `python -m pip install --upgrade HtmlDownloader`. `self-install` runs `python -m pip install HtmlDownloader`. `self-uninstall` runs `python -m pip uninstall -y HtmlDownloader` and needs `--force` on the command line. Those pip verbs do not use sudo. Empty arguments do not install or update.
|
|
210
|
+
|
|
211
|
+
Exit codes: non-zero for an unknown verb, a failed download, a failed serve, a pip failure, or a menu that cannot open. Menu **Exit** (9) returns 0. A saved page returns 0. Ctrl+C on `serve` returns 0.
|
|
212
|
+
|
|
213
|
+
Import for scripts (thin entry):
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from HtmlDownloader import main
|
|
217
|
+
# interactive session; a terminal opens the text menu
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Screenshots
|
|
221
|
+
|
|
222
|
+
Each heading is the file name. The paragraph is what that picture shows: the words on the screen and the characters in the input box. Package **1.0.0**. These pictures were captured from the running text menu in `/tmp/clips`. On each menu picture the input box shows `>` and no typed text, and **1 download** or the first row of that board is highlighted. The package index can fetch a picture only after that file is on the public `main` branch.
|
|
223
|
+
|
|
224
|
+
### `language-menu.png`
|
|
225
|
+
|
|
226
|
+
Row **7** has opened the language list. **71 English** is highlighted, with the note "use English for this menu." The other rows are **72 简体中文**, **73 繁體中文**, **74 Español**, **75 العربية**, **76 Français**, **77 Português**, **78 Русский**, **79 Deutsch**, **80 日本語**, **81 한국어**, **82 Nederlands**, and **83 Ελληνικά**. Each note says to use that language for this menu. **0 Back** says "return to the main menu." The path label is `Path`. The path is `/tmp/clips`. The clock is `19:48:09` on the right of that row. The status line says `HtmlDownloader 1.0.0` and `language`.
|
|
227
|
+
|
|
228
|
+

|
|
229
|
+
|
|
230
|
+
### `main-menu-en.png`
|
|
231
|
+
|
|
232
|
+
English main menu. There is no saved-language line above the box. The path label is `Path`. The path is `/tmp/clips`. The clock is `19:48:12` on the right of that row. **1 download** is highlighted: "download a page and its stylesheets, scripts, and images." Then **2 list downloaded** "show saved page names," **3 serve** "serve a saved page on this computer," **4 System Log** "view, clear, and the log folder," **6 self-management** "version, about, and pip lifecycle," **7 language** "display language for this menu," and **9 Exit** "leave." The status line says `HtmlDownloader 1.0.0` and `main menu`.
|
|
233
|
+
|
|
234
|
+

|
|
235
|
+
|
|
236
|
+
### `main-menu-zh-hans.png`
|
|
237
|
+
|
|
238
|
+
Simplified Chinese main menu. The line above the box says `菜单语言是简体中文`. The path label is `路径`. The path is `/tmp/clips`. The clock is `19:48:14` on the right of that row. **1 download** is highlighted and stays `download`: "下载页面、样式表和脚本." **2** stays `list downloaded`. **3** stays `serve`. **4** is `系统日志`. **6** is `自我管理`. **7** is `语言`. **9** is `离开`. The status line says `HtmlDownloader 1.0.0` and `主菜单`.
|
|
239
|
+
|
|
240
|
+

|
|
241
|
+
|
|
242
|
+
### `main-menu-zh-hant.png`
|
|
243
|
+
|
|
244
|
+
Traditional Chinese main menu. The line above the box says `選單語言是繁體中文`. The path label is `路徑`. The path is `/tmp/clips`. The clock is `19:48:17` on the right of that row. **1 download** is highlighted and stays `download`: "下載頁面、樣式表和指令碼." **2** stays `list downloaded`. **3** stays `serve`. **4** is `系統日誌`. **6** is `自我管理`. **7** is `語言`. **9** is `離開`. The status line says `HtmlDownloader 1.0.0` and `主選單`.
|
|
245
|
+
|
|
246
|
+

|
|
247
|
+
|
|
248
|
+
### `main-menu-es.png`
|
|
249
|
+
|
|
250
|
+
Spanish main menu. The line above the box says `El idioma del menú es español`. The path label is `Ruta`. The path is `/tmp/clips`. The clock is `19:48:19` on the right of that row. **1 download** is highlighted and stays `download`: "descarga una página, sus hojas de estilo y sus scripts." **2** stays `list downloaded`. **3** stays `serve`. **4** is `registro`. **6** is `autogestión`. **7** is `idioma`. **9** is `Salir`. The status line says `HtmlDownloader 1.0.0` and `menú principal`.
|
|
251
|
+
|
|
252
|
+

|
|
253
|
+
|
|
254
|
+
### `main-menu-ar.png`
|
|
255
|
+
|
|
256
|
+
Arabic main menu. The line above the box says `لغة القائمة هي العربية`. The path label is `المسار`. The path is `/tmp/clips`. The clock is `19:48:22` on the right of that row. The numbers stay on the left. Arabic words on each row are shaped and read right to left. **1 download** is highlighted and stays `download`. **2** stays `list downloaded`. **3** stays `serve`. **4** is `سجل النظام`. **6** is `إدارة ذاتية`. **7** is `لغة`. **9** is `خروج`. The status line says `HtmlDownloader 1.0.0` and `القائمة الرئيسية`.
|
|
257
|
+
|
|
258
|
+

|
|
259
|
+
|
|
260
|
+
### `main-menu-fr.png`
|
|
261
|
+
|
|
262
|
+
French main menu. The line above the box says `La langue du menu est le français`. The path label is `Chemin`. The path is `/tmp/clips`. The clock is `19:48:24` on the right of that row. **1 download** is highlighted and stays `download`: "télécharger une page, ses feuilles de style et ses scripts." **2** stays `list downloaded`. **3** stays `serve`. **4** is `journal`. **6** is `autogestion`. **7** is `langue`. **9** is `Quitter`. The status line says `HtmlDownloader 1.0.0` and `menu principal`.
|
|
263
|
+
|
|
264
|
+

|
|
265
|
+
|
|
266
|
+
### `main-menu-pt.png`
|
|
267
|
+
|
|
268
|
+
Portuguese main menu. The line above the box says `O idioma do menu é português`. The path label is `Caminho`. The path is `/tmp/clips`. The clock is `19:48:27` on the right of that row. **1 download** is highlighted and stays `download`: "transferir uma página, as folhas de estilo e os scripts." **2** stays `list downloaded`. **3** stays `serve`. **4** is `registo`. **6** is `autogestão`. **7** is `idioma`. **9** is `Sair`. The status line says `HtmlDownloader 1.0.0` and `menu principal`.
|
|
269
|
+
|
|
270
|
+

|
|
271
|
+
|
|
272
|
+
### `main-menu-ru.png`
|
|
273
|
+
|
|
274
|
+
Russian main menu. The line above the box says `Язык меню — русский`. The path label is `Путь`. The path is `/tmp/clips`. The clock is `19:48:29` on the right of that row. **1 download** is highlighted and stays `download`: "скачать страницу, таблицы стилей и скрипты." **2** stays `list downloaded`. **3** stays `serve`. **4** is `системный журнал`. **6** is `самоуправление`. **7** is `язык`. **9** is `Выход`. The status line says `HtmlDownloader 1.0.0` and `главное меню`.
|
|
275
|
+
|
|
276
|
+

|
|
277
|
+
|
|
278
|
+
### `main-menu-de.png`
|
|
279
|
+
|
|
280
|
+
German main menu. The line above the box says `Die Menüsprache ist Deutsch`. The path label is `Pfad`. The path is `/tmp/clips`. The clock is `19:48:32` on the right of that row. **1 download** is highlighted and stays `download`: "eine Seite, ihre Stylesheets und ihre Skripte herunterladen." **2** stays `list downloaded`. **3** stays `serve`. **4** is `Systemprotokoll`. **6** is `Selbstverwaltung`. **7** is `Sprache`. **9** is `Beenden`. The status line says `HtmlDownloader 1.0.0` and `Hauptmenü`.
|
|
281
|
+
|
|
282
|
+

|
|
283
|
+
|
|
284
|
+
### `main-menu-ja.png`
|
|
285
|
+
|
|
286
|
+
Japanese main menu. The line above the box says `メニューの言語は日本語`. The path label is `パス`. The path is `/tmp/clips`. The clock is `19:48:34` on the right of that row. **1 download** is highlighted and stays `download`: "ページとスタイルシートとスクリプトを取得する." **2** stays `list downloaded`. **3** stays `serve`. **4** is `システムログ`. **6** is `自己管理`. **7** is `言語`. **9** is `終了`. The status line says `HtmlDownloader 1.0.0` and `メインメニュー`.
|
|
287
|
+
|
|
288
|
+

|
|
289
|
+
|
|
290
|
+
### `main-menu-ko.png`
|
|
291
|
+
|
|
292
|
+
Korean main menu. The line above the box says `메뉴 언어는 한국어`. The path label is `경로`. The path is `/tmp/clips`. The clock is `19:48:37` on the right of that row. **1 download** is highlighted and stays `download`: "페이지와 스타일시트와 스크립트를 받습니다." **2** stays `list downloaded`. **3** stays `serve`. **4** is `시스템 로그`. **6** is `자기관리`. **7** is `언어`. **9** is `종료`. The status line says `HtmlDownloader 1.0.0` and `주 메뉴`.
|
|
293
|
+
|
|
294
|
+

|
|
295
|
+
|
|
296
|
+
### `main-menu-nl.png`
|
|
297
|
+
|
|
298
|
+
Dutch main menu. The line above the box says `De menutaal is Nederlands`. The path label is `Pad`. The path is `/tmp/clips`. The clock is `19:48:39` on the right of that row. **1 download** is highlighted and stays `download`: "download een pagina, de stylesheets en de scripts." **2** stays `list downloaded`. **3** stays `serve`. **4** is `systeemlog`. **6** is `zelfbeheer`. **7** is `taal`. **9** is `Afsluiten`. The status line says `HtmlDownloader 1.0.0` and `hoofdmenu`.
|
|
299
|
+
|
|
300
|
+

|
|
301
|
+
|
|
302
|
+
### `main-menu-el.png`
|
|
303
|
+
|
|
304
|
+
Greek main menu. The line above the box says `Η γλώσσα του μενού είναι ελληνικά`. The path label is `Διαδρομή`. The path is `/tmp/clips`. The clock is `19:48:42` on the right of that row. **1 download** is highlighted and stays `download`: "κατέβασε μια σελίδα, τα φύλλα στυλ και τα σκριπτ." **2** stays `list downloaded`. **3** stays `serve`. **4** is `αρχείο καταγραφής`. **6** is `αυτοδιαχείριση`. **7** is `γλώσσα`. **9** is `Έξοδος`. The status line says `HtmlDownloader 1.0.0` and `κύριο μενού`.
|
|
305
|
+
|
|
306
|
+

|
|
307
|
+
|
|
308
|
+
### `self-management.png`
|
|
309
|
+
|
|
310
|
+
Row **6** has opened self-management. **61 version** is highlighted: "show the installed version." Then **62 about** "version and this computer", **63 version-check** "compare this install with pip", **64 self-update** "upgrade this package with pip", **65 self-uninstall** "remove this package with pip", **66 self-install** "install this package with pip", and **0 Back** "return to the main menu." The path label is `Path`. The path is `/tmp/clips`. The clock is `19:48:44` on the right of that row. The status line says `HtmlDownloader 1.0.0` and `self-management`.
|
|
311
|
+
|
|
312
|
+

|
|
313
|
+
|
|
314
|
+
### `tui-about.png`
|
|
315
|
+
|
|
316
|
+
**about** (62) on the result page. The title is `HtmlDownloader (1.0.0) — result`. The page prints `HtmlDownloader 1.0.0`, `Domain: Download a page and its stylesheets, scripts, and images`, `Runtime tools: none`, and `Entry points: html-downloader, python -m HtmlDownloader`. The host check is stamped `2026-10-16 19:48:50.012150` and headed `[CHECK SYSTEM]:`. Visible lines include Python 3.12.11, C Library GCC 13.3.0, Ubuntu 24.04.5 LTS, amd64, the current user, the shell `/bin/bash`, Python Executable `python3`, python2 location, python3 location, a blank conda location, pyenv location, `Inside docker container: False`, and `Cython String: cpython-312-x86_64-linux-gnu`. The footer says `Up/Down scrolls this page.` and `Press a key to return to the main menu.` There is no input box and no clock. The page stays in English.
|
|
317
|
+
|
|
318
|
+

|
|
319
|
+
|
|
320
|
+
### `system-log.png`
|
|
321
|
+
|
|
322
|
+
Row **4** has opened System Log. **41 view-log** is highlighted: "list a log file and show it." Then **42 clear-log** "empty one log file", **43 log-folder** "show the log folder", and **0 Back** "return to the main menu." The path label is `Path`. The path is `/tmp/clips`. The clock is `19:48:47` on the right of that row. The status line says `HtmlDownloader 1.0.0` and `System Log`.
|
|
323
|
+
|
|
324
|
+

|
|
325
|
+
|
|
326
|
+
## Examples
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
html-downloader
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
html-downloader version
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
`version` prints `HtmlDownloader 1.0.0` and does not call pip. A run that is not the text menu can also print ChronicleLogger status lines above that. The text menu keeps those lines off the screen.
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
html-downloader download --url https://example.com/ --name example
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
That saves the page and does not draw the menu. On a terminal, row **1** lists saved pages or accepts a URL.
|
|
343
|
+
|
|
344
|
+
## Platform Compatibility
|
|
345
|
+
|
|
346
|
+
| Platform | Status |
|
|
347
|
+
|----------|--------|
|
|
348
|
+
| Linux | Primary; tested development path |
|
|
349
|
+
| macOS | Supported when CPython is on PATH |
|
|
350
|
+
| Windows | Supported when CPython is on PATH (venv activate differs) |
|
|
351
|
+
| Architectures | Any with CPython |
|
|
352
|
+
|
|
353
|
+
The text menu needs a terminal. With no terminal and no verb, the program prints help and returns 0. It does not wait.
|
|
354
|
+
|
|
355
|
+
## Related Projects
|
|
356
|
+
|
|
357
|
+
- [HtmlDownloader on GitHub](https://github.com/cloudgen/HtmlDownloader) — this program’s source
|
|
358
|
+
- [HtmlDownloader on PyPI](https://pypi.org/project/HtmlDownloader/) — this program on PyPI
|
|
359
|
+
- [AnimeDlp](https://github.com/Wilgat/AnimeDlp) — command-line downloader for anime video sites
|
|
360
|
+
- [ChronicleLogger](https://github.com/Wilgat/ChronicleLogger) — status logger this program depends on (`ChronicleLogger>=1.3.1`)
|
|
361
|
+
- [VideoSpeed](https://github.com/Wilgat/VideoSpeed) — cuts, changes speed, and boomerangs a clip. That program is not this one
|
|
362
|
+
- [CIAO](https://github.com/cloudgen/ciao) — Caution, Intentional, Anti-fragile, Over-engineered
|
|
363
|
+
- [CIAO-Lite](https://github.com/cloudgen/ciao-lite) — short agent contract
|
|
364
|
+
- [safe-rm](https://github.com/cloudgen/safe-rm) — guarded `rm`
|
|
365
|
+
|
|
366
|
+
## Contributing
|
|
367
|
+
|
|
368
|
+
1. Keep product law under `docs/requirements/` in sync when behavior changes.
|
|
369
|
+
2. Prefer small, CIAO-safe changes. Do not put media joining, an external encoder, or a file listing back without an explicit design.
|
|
370
|
+
3. Version dual SSOT: bump **`pyproject.toml`** and **`src/HtmlDownloader/__init__.__version__`** together.
|
|
371
|
+
4. Open issues and pull requests on GitHub.
|
|
372
|
+
|
|
373
|
+
## License
|
|
374
|
+
|
|
375
|
+
MIT — see [`LICENSE.md`](./LICENSE.md). Also declared in `pyproject.toml`.
|
|
376
|
+
|
|
377
|
+
## Last Update
|
|
378
|
+
|
|
379
|
+
2026-10-16 — **1.0.0**. Public source is https://github.com/cloudgen/HtmlDownloader. The console script is `html-downloader`. `download --url URL --name PAGENAME` saves the page under `~/.app/HtmlDownloader/output/`. Menu row 1 **download** lists saved pages or accepts a URL. Menu pictures show this board: language **71**–**83**, one main menu for each language, self-management **61**–**66**, about, and System Log **41**–**43**. Product law under `docs/requirements/` names this version and this menu. Version badge matches `pyproject.toml` and `__version__`. `ChronicleLogger>=1.3.1` is required.
|