Compare commits

..

343 Commits

Author SHA1 Message Date
dw-0
6225ee59d0 fix: add sysd_dir to base_folders
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-31 08:18:22 +02:00
dw-0
535c50a3ac fix: better check for still existing services during removal
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-31 08:17:59 +02:00
dw-0
e26315f469 chore: remove unused menu attribute from Option class
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 20:25:12 +02:00
dw-0
b77f1356bf chore(extension): update print menu to use new style
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 20:07:13 +02:00
dw-0
d201f54cee refactor(extension): fix typing
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 20:03:56 +02:00
dw-0
69dbf68760 refactor: composition > inheritance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 15:37:46 +02:00
dw-0
ffc262a89b chore: sort imports
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-24 23:01:49 +02:00
dw-0
cf35da5ff4 fix(extensions): fix import
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-24 20:15:56 +02:00
Staubgeborener
f34392bfd5 refactor(extension): adjust code in Klipper-Backup (#502)
* refactor(extension): clean up klipper backup extension code

- replace subprocess.run with remove_system_servicefunction,remove_with_sudo and cmd_sysctl_service
- add missing remove_moonraker_entry call
- remove unnecessary Logger commands

* refactor(extension): add  daemon-reload and reset-failed to klipper backup extension

* refactor(extension): remove unnecessary lines in klipper backup extension

* refactor(extension): adjust uninstall_service function in klipper backup extension

and also add some commentary

* refactor(extension): remove unnecessary try except block klipper backup extension

remove_with_sudo() function has it's own try except block, if an error occurs, the remaining code is not executed by raise statement anyway
2024-08-22 19:31:54 +02:00
dw-0
ea991644cd refactor: create moonraker instances based on klipper instances
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-20 20:22:01 +02:00
dw-0
fe0bfc5376 refactor: create a remove base method and use it in all subclasses
replace get_service_file_path with service_file_path and remove get_service_file_name

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-19 21:14:19 +02:00
dw-0
fdfdf18dd2 chore: sort imports
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-19 21:07:06 +02:00
dw-0
bbf64eec9c refactor: improve system service removal
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-19 19:25:02 +02:00
dw-0
a0076698d5 refactor: do not run the requirements installation if the virtualenv already exists
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-18 20:59:49 +02:00
dw-0
547194e950 refactor: move nginx related functions to client_utils
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-18 20:13:31 +02:00
dw-0
14973c4d98 refactor: tweak client setup and removal
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-18 19:35:43 +02:00
dw-0
f49f7b2fee fix: check if stderr is None
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-18 18:01:58 +02:00
dw-0
5d678c4ff2 refactor: rework webclient removal
* also backup fluidds config.json on update

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-18 13:42:27 +02:00
dw-0
184c5ac3ff fix: skip if a symlink is broken
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-18 12:28:58 +02:00
dw-0
27b7651e11 refactor: trim ".git" from repo name
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-17 19:35:38 +02:00
dw-0
660481af5a feat: version select on startup (#499) 2024-08-17 18:50:43 +02:00
Staubgeborener
9b2960594e refactor(extension): add new check to klipper backup extension (#498)
Also started using SYSTEMD variable instead of hardcoded path, reworked the crontab entry remove function and revised the code in general
2024-08-15 18:36:49 +02:00
dw-0
db3a9ca622 refactor: allow to also check for timer unit files
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-13 19:28:37 +02:00
dw-0
3f428df9d6 refactor: move more constants to core.constants
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 16:28:57 +02:00
dw-0
8aec1e437a refactor: move types to core
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 16:21:16 +02:00
dw-0
231e9d134a refactor: move logger to core
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 16:09:30 +02:00
dw-0
ddab9e7c96 refactor: move spinner to core
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 16:06:20 +02:00
dw-0
f60d0b923c feat: add color to spinner
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 16:05:11 +02:00
dw-0
3e6d3d9015 feat: add change hostename procedure
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 12:55:13 +02:00
dw-0
69a0fe2dfb fix: remove redundant print statement
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 12:54:44 +02:00
dw-0
13611ccd52 refactor: check_install_dependencies expects a set now
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 12:54:27 +02:00
dw-0
ea4409ee54 refactor: add default to print_ok if no message is given
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-11 12:53:08 +02:00
dw-0
4f39edd06c fix: change type of deps from list to set
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-10 15:17:49 +02:00
dw-0
77128ac7f8 refactor: move constants and decorators to core package
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-10 14:57:21 +02:00
dw-0
16d4fdbcfe fix: toggle all in remove menu
inverted the selection

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-10 12:02:20 +02:00
dw-0
9e66c8093b feat: add system upgrades
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-10 11:55:39 +02:00
dw-0
88f784348b refactor: refactor Obico for Klipper to dataclass
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-04 19:29:29 +02:00
dw-0
1fc50848b0 refactor: refactor OctoEverywhere to dataclass
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-04 18:44:45 +02:00
dw-0
acde067e68 refactor(extensions): refactor telegram bot extension
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-04 18:36:04 +02:00
dw-0
96daf966ee feat: add mypy to the project
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-04 16:15:59 +02:00
dw-0
0d7a471a03 fix: logical bug in handle_instance_names
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-03 23:55:51 +02:00
dw-0
f00d41b1bf fix: fix logic bug in handle_instance_names
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-27 23:18:32 +02:00
dw-0
f578247b74 fix: fix logic bug in conditional
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-27 23:02:08 +02:00
dw-0
a7c67721b6 refactor: make Moonraker to dataclass
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-27 22:30:53 +02:00
dw-0
32742943a0 refactor: start at index 1 in moonraker setup dialog if multi instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-27 22:23:06 +02:00
dw-0
871bedb76b refactor: overhaul of the klipper setup process
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-27 21:13:56 +02:00
dw-0
fee2dd0bda refactor: use | instead of Union
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-14 14:44:08 +02:00
dw-0
e5bcab5d85 fix: return if instance_list is empty
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-13 13:34:55 +02:00
dw-0
31ea6c2e5a refactor: add moonraker speedup dependencies
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:29:49 +02:00
dw-0
1384f7328a refactor: use global deps list to check for generally required dependencies
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
6bf55b5f69 refactor: use virtualenv instead of venv
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
398705b176 fix: prevent exception when trying to remove log files from non-existing directory
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
ed2e318d0e refactor: add __repr__ to Klipper class
This commit adds a __repr__ method to the Klipper class. This method returns a JSON string representation of the instance, which can be used for debugging purposes.

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
75ac8a22d5 refactor: add regex pattern to assign custom names
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
005e2d3339 refactor: improve robustness of instance sorting
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
bdb2c85e9b fix: fix usage of wrong status code
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
7e251eb31e refactor: more extraction into constant
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-07 22:16:37 +02:00
dw-0
64ea337e7e refactor: create service removal helper function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-02 22:07:52 +02:00
dw-0
1cd9414cae refactor: extract redundant code into shared methods
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-01 21:04:15 +02:00
dw-0
2391f491bb refactor: implement constants for klipper
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-01 20:42:22 +02:00
dw-0
92ed67ddd2 fix(mobileraker): fix typo and add more constants
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-01 20:41:56 +02:00
dw-0
0cb1e35b06 refactor: improve klipper class structure
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-01 20:41:56 +02:00
dw-0
7632c3c980 refactor: implement constants for klipper
use ubuntu 22.04 install script

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-07-01 20:41:54 +02:00
dw-0
c1f600f539 refactor: replace glob with iterdir
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 21:25:55 +02:00
dw-0
01deab7c64 fix: disallow installing client config if another client config is installed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 20:51:04 +02:00
dw-0
e530c75307 fix: f-string in glob caused exception
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 18:32:27 +02:00
dw-0
9655f9ba5c refactor: use 1-based indexing for moonraker instance selection
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 18:29:53 +02:00
dw-0
94e95671ca refactor: delete moonraker logs with their respective instances upon instance removal
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 18:27:00 +02:00
dw-0
9ec12ba0b8 refactor: use 1-based indexing for klipper instance selection
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 18:24:50 +02:00
dw-0
372712ba32 refactor: delete klipper logs with their respective instances upon instance removal
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 18:24:50 +02:00
dw-0
6b7057882b fix: remove rogue 'pass' statement
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 16:07:32 +02:00
dw-0
481394abf9 refactor: use loading spinner in update menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 16:01:25 +02:00
dw-0
7c9dcea359 feat: add loading spinner
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 16:01:11 +02:00
dw-0
956666605c refactor: rework update menu, logic and typing
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-30 13:45:07 +02:00
dw-0
8a620cdbd4 refactor: improve component removal routines
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-29 09:20:26 +02:00
dw-0
6636365cb7 fix: use correct footer in klipper remove menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-29 08:58:34 +02:00
dw-0
61618d064d refactor: go back do remove menu when component was removed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-29 08:58:10 +02:00
dw-0
59e619ea0f refactor: fix padding in dialog
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-29 08:58:10 +02:00
dw-0
2ad11d68de refactor: remove ipv6 check
doesn't seem to be necessary

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-29 08:11:07 +02:00
dw-0
7444ae8cea refactor: client dialog improvements
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-29 00:08:19 +02:00
dw-0
103a7b61b3 feat: OctoEverywhere for KIAUH v6 (#485)
* feat: scaffold OE installer

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: remove redundant steps ocoeverywhere already takes care of

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: add padding option to dialog

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: oe uninstaller

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* fix: add recursive removal of files

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: implement octoeverywhere update

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* chore: cleanup

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* chore: remove unused argument

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* fix: add instance names to blacklist

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: use update.sh script of OctoEverywhere for updating

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* fix: typo

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: add force flag to git_clone_wrapper

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

---------

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-28 23:26:27 +02:00
dw-0
dbe15e3a32 feat: add ipv6 check before installing webclients
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-27 17:55:17 +02:00
dw-0
e421a12daf fix: logical error in list comprehension
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 23:21:34 +02:00
dw-0
3734ef0568 feat(obico): add obico extension (#474)
* feat(obico): add obico extension

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* refactor: add obico to moonraker suffix blacklist

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* fix: correctly recognize the suffix of the instance

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* fix: fix logic of asking for linking

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* Squashed 'kiauh/core/submodules/simple_config_parser/' changes from 2698f60..7aa6586

7aa6586 fix: sections can have hyphens in their second word
44cedf5 fix(tests): fix whitespaces in expected output

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 7aa658654eeb08fd53831effbfba4503a61e0eff

* refactor: use SimpleConfigParser and finalize the code

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* fix: wrong condition in _load_config

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* Squashed 'kiauh/core/submodules/simple_config_parser/' changes from 7aa6586..47c353f

47c353f refactor: improve section regex
dd904bc test: add more test cases

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 47c353f4e91e6be9605394b174834e1f34c9cfdf

* Squashed 'kiauh/core/submodules/simple_config_parser/' changes from 47c353f..3655330

3655330 refactor: use pop() for removing elements from lists and dicts
99733f1 refactor: add empty options dict to _all_options on section parsing

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 3655330d2156e13acffc56fac070ab8716444c85

* refactor: improve config creations and patching

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

---------

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 18:08:00 +02:00
dw-0
08c10fdded refactor: rework some moonraker dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 15:57:13 +02:00
dw-0
cfc45a9746 refactor: rework some klipper dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 15:50:31 +02:00
dw-0
205c84b3c3 refactor: make menus more visually appealing
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 12:30:29 +02:00
dw-0
e63eb47ee9 refactor: extract config filenames into constants
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 10:58:43 +02:00
dw-0
af57b9670d fix: wrong condition in _load_config
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 10:56:02 +02:00
dw-0
b758b3887b refactor: improve error logging on missing kiauh config file
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-22 10:55:11 +02:00
dw-0
5eff560627 Merge remote-tracking branch 'origin/kiauh-v6-dev' into kiauh-v6-dev 2024-06-19 20:21:03 +02:00
Staubgeborener
93ba579232 refactor(klipper_backup): replace is_service_installed with service_instance_exists (#481)
* use service_instance_exists function

* change header in __init__.py

* remove is_service_installed function

* small fix
2024-06-19 20:17:52 +02:00
dw-0
5c090e88c3 refactor(settings): use SimpleConfigParser for KiauhSettings
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-19 20:12:39 +02:00
dw-0
c2dfabb326 Merge commit '08640e5b177595f5e84d4bf9194311282b1a91e2' into kiauh-v6-dev 2024-06-19 20:06:45 +02:00
dw-0
08640e5b17 Squashed 'kiauh/core/submodules/simple_config_parser/' changes from 4d60d30..2698f60
2698f60 refactor: reset state on read method call

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 2698f600e4bef3197d696a798f2c3436dabe836a
2024-06-19 20:06:45 +02:00
dw-0
802eaccf57 refactor(scp): replace old config parser with new one, remove ConfigManager
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-16 21:46:21 +02:00
dw-0
c6cc3fc0f6 Squashed 'kiauh/core/submodules/simple_config_parser/' changes from 188dd1f..4d60d30
4d60d30 refactor: in multiline options we do not replace the option name
0a1fba5 refactor: set default indent to 4 spaces
ab522bf refactor: the value of an option can be a list of strings

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 4d60d30a75e7151be7b38b7cdbb2c133711b0091
2024-06-16 18:57:15 +02:00
dw-0
7b9f9b1a67 Merge commit 'c6cc3fc0f6e6400714c67d316f2abf08527ad24e' into kiauh-v6-dev 2024-06-16 18:57:15 +02:00
dw-0
fbab9a769a feat(scp): add new config parser
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-06-16 18:17:05 +02:00
dw-0
60f8aef69b Squashed 'kiauh/core/submodules/simple_config_parser/' content from commit 188dd1f
git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 188dd1ffd80bf72a2dc6075147ddc9339b059c4b
2024-06-16 18:14:55 +02:00
dw-0
f73ee6e6a0 Merge commit '60f8aef69ba552ce8d31066d2e09829d1cca9df2' as 'kiauh/core/submodules/simple_config_parser' 2024-06-16 18:14:55 +02:00
dw-0
d414be609a feat: add utils function to check for a specific service instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 21:32:59 +02:00
dw-0
df45c5955e refactor: add regex pattern as parameter to get_string_input for validating input
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 21:32:15 +02:00
dw-0
70ad635e3d feat: add util function to check if moonraker is installed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 21:31:26 +02:00
dw-0
6570400f9e fix(moonraker): correctly loading dependencies from system-dependencies.json
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 19:45:05 +02:00
dw-0
aafcba9f40 refactor: replace usage of instance manager method with cmd_sysctl_manage function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 18:42:20 +02:00
dw-0
91162a7070 refactor: remove redundant printing of status messages
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 18:37:42 +02:00
dw-0
74c70189af feat: implement option to center content in dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-25 17:09:41 +02:00
dw-0
017f1d4597 refactor: make format_dialog_content method public, use it in the extensions menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-20 19:27:35 +02:00
dw-0
0dfe7672b8 feat(extension): implement PrettyGCode for Klipper extension
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-20 12:15:33 +02:00
dw-0
b3df3e7b5c refactor: improve nginx config generation
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-20 12:14:56 +02:00
dw-0
01afe1fe77 chore: ruff organize imports
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-20 10:52:18 +02:00
dw-0
ac0478b062 refactor: more robust type hinting
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-19 18:41:29 +02:00
dw-0
6eb06772b4 fix(utils): fix condition
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-19 18:39:31 +02:00
dw-0
d6317ad439 chore: cleanup moonraker telegram bot
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-19 16:05:31 +02:00
dw-0
e28869be1a fix(mobileraker): remove copy paste error
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-18 22:39:17 +02:00
dw-0
51993e367d chore: cleanup settings_menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 23:07:54 +02:00
dw-0
a03e943ebf chore: check import sorting when linting
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 22:52:25 +02:00
dw-0
fc8fedc9f6 refactor(Klipper): change subprocess imports
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 22:49:26 +02:00
dw-0
7f79f68209 refactor(Klipper): use warn dialog
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 22:29:53 +02:00
dw-0
a44508ead5 refactor: update dependency management
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 22:23:51 +02:00
dw-0
9342c94096 chore: cleanup and update toml, create editorconfig
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 20:18:09 +02:00
dw-0
ea78ba25e6 fix(crowsnest): fix multi instance steps
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 19:45:42 +02:00
dw-0
63cae491f3 refactor: update .gitignore
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-11 12:27:54 +02:00
Patrick Gehrsitz
05b5664062 fix: fix crowsnest installer (#470)
* fix: fix crowsnest installer

Signed-off-by: mryel00 <mryel00.github@gmail.com>

* chore: remove unnecessary code

This check is made inside the called tool too. Therefore removing it here.

Signed-off-by: mryel00 <mryel00.github@gmail.com>

---------

Signed-off-by: mryel00 <mryel00.github@gmail.com>
2024-05-10 21:28:15 +02:00
Staubgeborener
a4b149c11a chore: remove test section and add new klipperbackup url in header (#467)
The old test branch will be deleted anyway
2024-05-08 18:44:26 +02:00
dw-0
3b2bc05746 refactor(crowsnest): allow backup before update for crowsnest
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-05 19:23:09 +02:00
dw-0
72663ef71c feat: implement moonraker telegram bot extension
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-05 19:16:03 +02:00
dw-0
8730fc395e refactor: be able to specify last character after printing a dialog
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-05 19:15:25 +02:00
dw-0
3885405366 feat: implement conversion of camel case to kebab case
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-05 16:33:20 +02:00
dw-0
e986dfbf4c fix: fix typo in systemctl command
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-05 14:15:11 +02:00
dw-0
79b4f3eefe refactor(logger): double newline as content allows for a full blank line
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-04 20:41:39 +02:00
dw-0
bf0385e3c9 fix: add missing mobileraker status getter
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-04 00:28:12 +02:00
dw-0
750bf1caaf refactor: rework status fetching to make it more readable
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-04 00:20:53 +02:00
dw-0
27455dfc64 feat: add mobileraker support
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 23:21:23 +02:00
dw-0
940f7cfbf1 refactor(KlipperScreen): improve error message
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 22:45:44 +02:00
dw-0
e5d0e97b82 refactor(KlipperScreen): reload manager config and reset failed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 22:21:38 +02:00
dw-0
799892500a refactor(sys_utils): rename systemctl method and add new one
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 22:20:00 +02:00
dw-0
5f1e42b88b refactor(KlipperScreen): add proper warning message
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 20:03:59 +02:00
dw-0
09dc961646 refactor: allow content to consist of paragraphs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 20:00:48 +02:00
dw-0
40e382c9a1 feat: implement method for printing formatted dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-03 19:24:15 +02:00
dw-0
9864dd0c7f refactor: use check_install_dependencies at more places where appropriate
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 23:26:47 +02:00
dw-0
d84adee7f9 fix: typo
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 23:26:00 +02:00
dw-0
c17c3e9bd4 feat: add KlipperScreen
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:54:49 +02:00
dw-0
074344cf7c refactor: unneccessary use of check_file_exist
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:53:57 +02:00
dw-0
42667ad792 refactor(backups): print info message when file or directory does not exist
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:53:18 +02:00
dw-0
9804411d74 feat: add remove_with_sudo function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:18:29 +02:00
dw-0
067a102b6b feat: add deprecated decorator
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:18:29 +02:00
dw-0
4a5d1a971a refactor: rearrange input parameters for git_clone_wrapper
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:18:28 +02:00
dw-0
6407664e3e refactor: extract check for python version into function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 22:18:28 +02:00
dw-0
65617ca971 refactor: rename filesystem_utils to fs_utils and system_utils to sys_utils
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 15:53:22 +02:00
dw-0
e05a42630e refactor: use utils to handle service masking
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-02 15:51:52 +02:00
dw-0
be228210bd refactor: use utils to handle service actions
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 21:33:12 +02:00
dw-0
b70ac0dfd7 refactor: move config related helper methods into own util module
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 21:12:37 +02:00
dw-0
af48738221 refactor: use util function to handle service controls
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 19:04:50 +02:00
dw-0
9d2cb72aa4 feat: implement crowsnest (#462)
* feat: add crowsnest install/remove


Signed-off-by: Dominik Willner <th33xitus@gmail.com>

* feat: add crowsnest update

Signed-off-by: Dominik Willner <th33xitus@gmail.com>

---------

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 18:46:58 +02:00
dw-0
8c3397ea78 fix: add missing methods to MainsailThemeInstallMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 14:12:20 +02:00
dw-0
7d3d46ac07 refactor: replace RepositoryManager by simple util functions
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 14:05:46 +02:00
dw-0
3da7aedd7f refactor: remove redundant variable assignment
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 13:08:04 +02:00
dw-0
8d343853f1 feat: fall back to .version file if release_info.json not exist
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-05-01 13:02:42 +02:00
dw-0
1f2d724189 feat: use dynamically created client download URL
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-28 19:43:36 +02:00
dw-0
1a29324e6a refactor: handle ports as ints as they are coming as ints from the KiauhSettings
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-28 19:42:40 +02:00
dw-0
5225e70e83 refactor: replace two seperate download url properties by only one
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-28 19:41:38 +02:00
dw-0
51f0713c5a refactor: print traceback of exception
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-28 19:40:30 +02:00
dw-0
d420daca26 fix: options not applied to self.options
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-28 12:49:44 +02:00
dw-0
cb62909f41 feat: implement functions of SettingsMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-28 12:12:45 +02:00
dw-0
02eebff571 feat: implement KiauhSettings and use it where appropriate
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-27 15:03:29 +02:00
dw-0
36b295bd1b refactor: clean up fetch_status code
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-26 17:26:52 +02:00
dw-0
372c9c0b7d refactor: update remove menu ui
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-25 20:57:35 +02:00
dw-0
c67ea2245d fix: return sorted extension dict
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-19 18:29:39 +02:00
dw-0
fda99bb70a chore: format
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-19 18:05:49 +02:00
Staubgeborener
2c1c94c904 feat: Add Klipper-Backup to KIAUH (#457) 2024-04-19 17:58:41 +02:00
dw-0
b020f10967 feat: implement repo rollback feature
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-18 21:54:34 +02:00
dw-0
aa1b435da5 feat: implement build + flash process
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-17 19:58:40 +02:00
dw-0
449317b118 fix: fix sd flash process
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-17 19:48:31 +02:00
dw-0
336414c43c fix: init previous_menu in menus
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-15 22:12:14 +02:00
dw-0
cd63034b74 fix: ignore flash method when checking for firmware files
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-15 21:52:32 +02:00
dw-0
8de7ab7e11 fix: wrong default previous menu for KlipperFlashMethodMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-15 21:37:25 +02:00
dw-0
c2b0ca5b19 fix: typo
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-15 21:31:54 +02:00
dw-0
ecb673a088 feat: implement firmware build
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-15 21:29:13 +02:00
dw-0
da4c5fe109 refactor: rework of menu lifecycle and option handling
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-14 22:11:40 +02:00
dw-0
bb769fdf6d fix: hitting 'b' or 'h' in main menu raises exception
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-10 22:49:52 +02:00
dw-0
409aa3da25 refactor: extend firmware flashing functionalities
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-10 21:10:01 +02:00
dw-0
0b41d63496 feat: implement optional extension update entry point
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-07 19:35:26 +02:00
dw-0
44301c0c87 feat: implement get-id feature
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-07 19:07:42 +02:00
dw-0
ace47e2873 refactor: remove code duplication
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-06 22:07:59 +02:00
dw-0
06801a47eb refactor: full refactor of how webclient data is handled
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-06 21:47:15 +02:00
dw-0
1484ebf445 refactor: use dict instead of list in discover_extensions method
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-01 00:56:14 +02:00
dw-0
4547ac571a fix: use of lambdas breaks the menu refactoring
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-04-01 00:55:25 +02:00
dw-0
b2dd5d8ed7 refactor: using @dataclass actually broke the singleton
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-31 17:57:01 +02:00
dw-0
e50ce1fc71 Merge branch 'master' into kiauh-v6-dev 2024-03-31 17:30:15 +02:00
dw-0
417180f724 refactor: further menu refactoring
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-31 17:30:04 +02:00
dw-0
39f0bd8b0a refactor: menu refactoring
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-31 00:33:00 +01:00
dw-0
dc87d30770 feat: first implementation of firmware flashing via usb and regular flash command
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-30 14:33:11 +01:00
dw-0
aaf5216275 refactor: remove unnecessary call to get_logfile_list
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-29 21:22:27 +01:00
dw-0
ebdfadac07 feat: allow custom input label text in menus
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-29 20:35:00 +01:00
dw-0
cac73cc58d Merge branch 'master' into kiauh-v6-dev 2024-03-27 20:44:31 +01:00
dw-0
78dbf31576 refactor: update advanced menu layout
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-27 20:43:59 +01:00
dw-0
fef8b58510 refactor: help menus need to be an option now
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-27 20:42:59 +01:00
dw-0
72e3a56e4f chore: replace black with ruff
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 01:06:59 +01:00
dw-0
e64aa94df4 chore: format
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 01:06:59 +01:00
dw-0
58719a4ca0 chore: fix lint issues
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 00:32:27 +01:00
dw-0
59a83aee12 feat(Mainsail): implement Mainsail Theme-Installer
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 00:04:29 +01:00
dw-0
7104eb078f refactor(RepoManager): if no branch is given, no checkout is done
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 00:02:10 +01:00
dw-0
341ecb325c refactor(klipper): instance overview dialog can now show printer folder and not only services
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 00:01:36 +01:00
dw-0
e3a6d8a0ab README.md: add contributor section
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-23 21:18:11 +01:00
dw-0
0183988d5d fix(LogUpload): fix bug in menu options
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-23 18:40:35 +01:00
dw-0
03c3ed20f3 refactor: disable header printing in extension menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-23 17:55:25 +01:00
dw-0
5c1c98b6b8 refactor: update advanced menu layout
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-23 12:59:26 +01:00
dw-0
ef13c130e0 chore: remove mypy from project
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-22 22:44:07 +01:00
dw-0
2acd74cbd9 refactor(webclients): make a backup before modification of config files
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-22 22:20:13 +01:00
dw-0
00665109c2 feat: allow sections to be added to the top of a config file
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-22 22:11:56 +01:00
dw-0
a5dce136f3 chore: remove shebang from most files because it is not needed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-21 21:55:35 +01:00
dw-0
4ffa057931 chore: improve type hinting
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-21 21:50:10 +01:00
dw-0
ed35dc9e03 chore: add mypy config to pyproject.toml
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-21 20:38:14 +01:00
dw-0
7ec055f562 refactor(webclients): always remove config sections
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-20 22:10:51 +01:00
dw-0
9eb0531cdf fix(moonraker): patch klippy_uds_address section when converting single to multi instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-20 21:40:03 +01:00
dw-0
84cda99af8 fix(klipper): patch virtual_sdcard section when converting single to multi instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-20 21:39:20 +01:00
dw-0
5f823c2d3a refactor(klipper): use correct virtual_sdcard path after multi-conversion
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-18 22:18:45 +01:00
dw-0
758a783ede refactor(moonraker): allow re-running installer if instance count already matches
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 21:01:30 +01:00
dw-0
682baaa105 refactor(kiauh): remove unused function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 20:56:14 +01:00
dw-0
601ccb2191 fix(webclients): add symlink to added klipper instances
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 20:53:49 +01:00
dw-0
c0caab13b3 fix(kiauh): typo
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 20:34:21 +01:00
dw-0
7c754de08e refactor(utils): re-arrange message printing
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 20:31:30 +01:00
dw-0
9dc556e7e4 fix(webclients): correctly remove symlink
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 20:26:01 +01:00
dw-0
655b781aef refactor(KIAUH): move util functions into util modules
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 11:42:27 +01:00
dw-0
14aafd558a refactor(moonraker): add existing client and client configs to example config upon creation
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 11:33:49 +01:00
dw-0
bd1aa1ae2b refactor(klipper): add existing client configs to example config upon creation
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-03 11:04:06 +01:00
dw-0
8df75dc8d0 fix(webclients): print to screen if symlink does not exist
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-02 21:47:27 +01:00
dw-0
5c37b68463 fix(webclients): default to port 80 if none/invalid configured in kiauh.cfg
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-02 21:25:17 +01:00
dw-0
1620efe56c refactor(KIAUH): full refactor of client and client-config installation
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-02 17:22:37 +01:00
dw-0
7fd91e6cef refactor(KIAUH): allow reading ipv6 configured ports with possible default_server suffixes
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-24 15:46:02 +01:00
dw-0
750cb7b307 refactor(KIAUH): update NGINX config to match mainsails structure
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-24 15:44:19 +01:00
dw-0
384503c4f5 feat(Fluidd): add Fluidd
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-24 15:26:32 +01:00
dw-0
2a4fcf3a3a refactor(KIAUH): add application root to sys path
shortens imports and helps with auto imports from IDE

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-18 22:30:28 +01:00
dw-0
573dc7c3c9 refactor(Mainsail): use urllib.request instead of requests module
requests is actually not part of the python 3.8 standard library, hence we use urllib.request now, which is.

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-18 22:08:21 +01:00
dw-0
05b4ef2d18 refactor(utils): raise exception if pip not found in venv
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-11 20:19:29 +01:00
dw-0
863c62511c fix(klipper): add python3-venv dependency for creating venv
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-11 20:19:29 +01:00
dw-0
be5f345a7c style: reformat code
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-10 16:21:19 +01:00
dw-0
948927cfd3 feat: implement backup menu and backup methods for existing components
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-10 11:47:27 +01:00
dw-0
34ebe5d15e refactor(BackupManager): backup_file method only takes in single files now
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-10 11:40:38 +01:00
dw-0
3bef6ecb85 feat(BackupManager): allow to ignore folders
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-10 00:50:45 +01:00
dw-0
5ace920d3e feat(extensions): implement initial extension feature and first extension
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-09 15:47:13 +01:00
dw-0
2f34253bad refactor(kiauh): handle menus based on if they need instantiation or not
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-08 22:41:52 +01:00
dw-0
0447bc4405 refactor(kiauh): allow menus to link options to letters
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-02-05 21:57:19 +01:00
dw-0
7cb2231584 chore(kiauh): rename "res" to "assets"
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-29 21:28:01 +01:00
dw-0
5a3d21c40b chore(kiauh): rename "modules" to "components"
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-29 21:20:26 +01:00
dw-0
ad56b51e70 feat(LogUpload): implement log upload feature
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-28 22:27:38 +01:00
dw-0
c6999f1990 refactor(kiauh): if self.options is an empty dict, return invalid input error message.
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-28 22:26:54 +01:00
dw-0
bc30cf418b refactor(kiauh): add option index parameter to method calls from menus
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-28 22:25:22 +01:00
dw-0
ee81ee4c0c fix(Mainsail): correctly handle invalid config value for default_port
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-28 15:35:00 +01:00
dw-0
35911604af chore(kiauh): update copyright
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-28 12:54:37 +01:00
dw-0
77f1089041 chore(kiauh): reformat code / rename method
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-28 12:54:35 +01:00
dw-0
7820155094 refactor(Klipper): add some exception handling
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-29 19:47:45 +01:00
dw-0
c28d5c28b9 refactor(KIAUH): use pythons own venv module to create a venv
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-29 19:39:45 +01:00
dw-0
cda6d31a7c fix(RepoManager): check if git dir exists
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-29 18:57:53 +01:00
dw-0
9a657daffd feat(KIAUH): show Mainsail in UpdateMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-28 18:05:43 +01:00
dw-0
85b4b68f16 refactor(Klipper/Moonraker): install new packages during updates
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-28 13:49:28 +01:00
dw-0
dfbce3b489 feat(KIAUH): show commit in UpdateMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-28 13:38:24 +01:00
dw-0
f3b0e45e39 refactor(Klipper): refactor klipper_setup to reduce cognitive complexity
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-27 23:49:34 +01:00
dw-0
83e5d9c0d5 refactor(Klipper/Moonraker): remove obsolete method calls
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-27 15:58:37 +01:00
dw-0
8f44187568 feat(Moonraker): enable Mainsail remote mode after multi instance setup
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-27 15:42:46 +01:00
dw-0
625a808484 fix(InstanceManager): return an updated list when getting the instances property
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-27 14:09:51 +01:00
dw-0
ad0dbf63b8 refactor(Mainsail): enable remote mode if moonraker multi instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-27 00:11:11 +01:00
dw-0
9dedf38079 refactor(KIAUH): big refactor of instance handling
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-26 23:37:35 +01:00
dw-0
1b4c76d080 fix(KIAUH): more file path handling improvements
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 22:31:18 +01:00
dw-0
d20d82aeac fix(Mainsail): proper check if config exists
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 22:06:40 +01:00
dw-0
16a28ffda0 fix(Klipper/Moonraker): config files now always have a Path, are never None anymore
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 22:03:44 +01:00
dw-0
a9367cc064 fix(Klipper): remove obsolete method parameter
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 22:01:18 +01:00
dw-0
b165d88855 fix(Moonraker): missing return statement if all requirements met
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 20:57:22 +01:00
dw-0
6c59d58193 refactor(KIAUH): use red dash instead of "Unknown" if repo info not available
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 20:44:04 +01:00
dw-0
b4f5c3c1ac refactor(Mainsail): remove mainsail.zip after extracting content
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 20:16:38 +01:00
dw-0
b69ecbc9b5 fix(KIAUH): wrong logic in status detection
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 19:56:43 +01:00
dw-0
fc9fa39eee refactor(Mainsail): use same wording in MainsailRemoveMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 19:43:30 +01:00
dw-0
142b4498a3 refactor(Klipper): rework remove process
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 19:39:19 +01:00
dw-0
012b6c4bb7 refactor(Moonraker): rework remove process
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 15:12:08 +01:00
dw-0
8aeb01aca0 refactor(KIAUH): use pathlib instead of os where possible. consistent use of pathlib.
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-25 01:16:16 +01:00
dw-0
da533fdd67 refactor(KIAUH): use util functions for Klipper and Moonraker to get their status
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-24 14:35:25 +01:00
dw-0
8cb0754296 feat(KIAUH): show Mainsail install status
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-24 14:23:57 +01:00
dw-0
7a6590e86a refactor(Mainsail): rework config.json backup
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-24 13:53:55 +01:00
dw-0
2f0feb317e refactor(BackupManager): rework backup structure and implement single file backup method
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-24 12:58:41 +01:00
dw-0
b9479db766 feat(KIAUH): show installation status of Klipper and Moonraker in MainMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-23 19:59:39 +01:00
dw-0
14132fc34b refactor(ConfigManager): automatically read config upon ConfigManager instance init
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-23 19:36:03 +01:00
dw-0
3d5e83d5ab refactor(Mainsail): remove specific methods and replace by generic ones
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-22 22:54:29 +01:00
dw-0
edd5f5c6fd refactor(KIAUH): refactor RemoveMenu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-22 22:43:29 +01:00
dw-0
8ff0b9d81d refactor(Mainsail): refactor methods for removing and checking files
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-22 22:39:43 +01:00
dw-0
22e8e314db fix(Mainsail): implement missing mainsail cfg symlinking
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-22 21:41:15 +01:00
dw-0
12bd8eb799 feat(KIAUH): move filesystem related methods to own module
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-22 21:25:20 +01:00
dw-0
4915896099 feat(Mainsail): remove Mainsail
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-21 22:53:41 +01:00
dw-0
cd38970bbd refactor(Mainsail): move some functions to a mainsail utils module
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-20 22:35:29 +01:00
dw-0
b8640f45a6 refactor(Klipper): refactor example printer.cfg creation
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 23:30:38 +01:00
dw-0
5fb4444f03 refactor(Moonraker): refactor example moonraker.conf creation
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 23:30:15 +01:00
dw-0
926ba1acb4 feat(ConfigManager): implement own ConfigParser write() method
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 21:49:09 +01:00
dw-0
c2e7ee98df feat(Mainsail): implement Mainsail installer
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 18:08:18 +01:00
dw-0
3865266da1 refactor(RepoManager): default to master branch if none is provided
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 18:07:18 +01:00
dw-0
b83f642a13 refactor(ConfigManager): logging can be silenced
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 18:03:42 +01:00
dw-0
30b4414469 feat(Klipper): create example printer.cfg if wanted
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 18:00:16 +01:00
dw-0
1178d3c730 refactor(Moonraker): skip selection dialog if there is only 1 klipper instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 16:18:44 +01:00
dw-0
59d8867c8c fix(kiauh): copy&paste issue in repo url for Moonraker
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 16:12:43 +01:00
dw-0
80a953a587 fix(Moonraker): typo in python version check
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 16:10:20 +01:00
dw-0
a80f0bb0e8 feat(utils): add several util methods
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 14:42:53 +01:00
dw-0
78cefddb2e feat(InstanceManager): add restart service method
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 13:26:22 +01:00
dw-0
b20613819e feat(Logger): add "start" parameter
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 13:00:46 +01:00
dw-0
1836beab42 feat(klipper): add getter for specific properties
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 00:01:25 +01:00
dw-0
545397f598 feat(kiauh): fix typo in check_package_install
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-16 17:38:01 +01:00
dw-0
f709cf84e7 feat(kiauh): add helper methods for downloading files
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-16 15:41:48 +01:00
dw-0
f62c10dc8b feat(kiauh): add helper methods to check for installed packages
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-16 15:38:23 +01:00
dw-0
e121ba8a62 feat(Moonraker): add python version check
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-04 22:35:36 +01:00
dw-0
9a1a66aa64 docs(utils): add docstrings
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-04 21:35:28 +01:00
dw-0
420b193f4b feat(Moonraker): implement Moonraker
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-03 23:13:28 +01:00
dw-0
de20f0c412 refactor(ConfigManager): allow to take in any config file
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-03 23:10:43 +01:00
dw-0
57f34b07c6 refactor(utils): add more util functions
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-03 23:09:43 +01:00
dw-0
e35e44a76a refactor(kiauh): move create_folders to BaseInstance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-03 23:08:41 +01:00
dw-0
bfb10c742b refactor(kiauh): reword print_info to print_status and implement new print_info method
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-03 23:06:30 +01:00
dw-0
458c89a78a fix(InstanceManager): print service name instead of suffix only
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-02 16:52:30 +01:00
dw-0
6128e35d45 refactor(kiauh): rework menu formatting logic
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-15 22:58:54 +01:00
dw-0
279d000bb0 refactor(kiauh): specify python3 in shebang
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-14 21:31:25 +01:00
dw-0
a4a3d5eecb feat(BackupManager): implement simple backup manager
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-14 21:28:13 +01:00
dw-0
1392ca9f82 refactor(klipper): pass the script path as a Path to the parse function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-13 20:07:21 +01:00
dw-0
47121f6875 refactor(utils): clean up, add comments
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-13 20:06:48 +01:00
dw-0
d0d2404132 refactor(kiauh): move core modules to core package
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 23:28:05 +01:00
dw-0
6ed5395f17 feat(klipper): check for brltty-udev too
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 01:26:43 +01:00
dw-0
be805c169b feat(klipper): allow keeping klipper and klipper-env dir during uninstall
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 01:13:39 +01:00
dw-0
eaf12db27e fix(klipper): allow go back when asked for new instances
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 00:39:10 +01:00
dw-0
fe8767113b refactor(klipper): rework dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 00:37:25 +01:00
dw-0
2148d95cf4 fix(InstanceManager): return None for suffix if there is none
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 00:10:52 +01:00
dw-0
682be48e8d fix(InstanceManager): instance_service should be service file name
remove debug prints

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-12 00:01:21 +01:00
dw-0
68369753fd refactor(InstanceManager): rework
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-11 23:56:27 +01:00
dw-0
44ed3b6ddf feat(kiauh): add .iml to gitignore
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-11 23:53:42 +01:00
dw-0
e12e578098 refactor(klipper): rewrite dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-05 23:13:16 +01:00
dw-0
515a42f098 feat(klipper): implement update function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-05 16:15:19 +01:00
dw-0
f9ecad0eca refactor(klipper): use name "klipper" for single instance setup
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-05 16:12:17 +01:00
dw-0
fb09acf660 refactor(utils): reduce complexity
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-02 22:52:34 +01:00
dw-0
093da73dd1 refactor(klipper): use constants for commonly used strings
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-11-02 22:37:17 +01:00
dw-0
c9e8c4807e feat(klipper): convert single to multi instance
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-31 20:54:44 +01:00
dw-0
09e874214b feat(ConfigManager): implement ConfigManager
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-29 17:19:26 +01:00
dw-0
623bd7553b feat(RepoManager): implement RepoManager
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-29 13:25:21 +01:00
dw-0
1e0c74b549 style: rename input functions
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-29 01:29:27 +02:00
dw-0
358c666da9 feat(style): use black code style / formatter
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-29 00:31:34 +02:00
dw-0
84a530be7d fix(klipper): handle disruptive system packages/services
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-28 23:52:51 +02:00
dw-0
bfff3019cb fix(InstanceManager): fix TypeError if instance name is None
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-28 22:10:07 +02:00
dw-0
2a100c2934 feat(klipper): check for required user-groups
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-28 21:31:31 +02:00
dw-0
ce0daa52ae feat(klipper): implement instance manager and klipper installer in python
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-26 13:58:31 +02:00
36 changed files with 257 additions and 520 deletions

View File

@@ -2,54 +2,13 @@
This document covers possible important changes to KIAUH.
### 2024-08-31 (v6.0.0-alpha.1)
Long time no see, but here we are again!
A lot has happened in the background, but now it is time to take it out into the wild.
#### KIAUH has now reached version 6! Well, at least in an alpha state...
The project has seen a complete rewrite of the script from scratch in Python.
It requires Python 3.8 or newer to run. Because this update is still in an alpha state, bugs may or will occur.
During startup, you will be asked if you want to start the new version 6 or the old version 5.
As long as version 6 is in a pre-release state, version 5 will still be available. If there are any critical issues
with the new version that were overlooked, you can always switch back to the old version.
In case you selected not to get asked about which version to start (option 3 or 4 in the startup dialog) and you want to
revert that decision, you will find a line called `version_to_launch=` within the `.kiauh.ini` file in your home directory.
Just delete that line, save the file and restart KIAUH. KIAUH will then ask you again which version you want to start.
Here is a list of the most important changes to KIAUH in regard to version 6:
- The majority of features available in KIAUH v5 are still available; they just got migrated from Bash to Python.
- It is now possible to add new/remove instances to/from existing multi-instance installations of Klipper and Moonraker
- KIAUH now has an Extension-System. This allows contributors to add new installers to KIAUH without having to modify the main script.
- You will now find some of the features that were previously available in the Installer-Menu in the Extensions-Menu.
- The current extensions are:
- G-Code Shell Command (previously found in the Advanced-Menu)
- Mainsail Theme Installer (previously found in the Advanced-Menu)
- Klipper-Backup (new in v6!)
- Moonraker Telegram Bot (previously found in the Installer-Menu)
- PrettyGCode for Klipper (previously found in the Installer-Menu)
- Obico for Klipper (previously found in the Installer-Menu)
- The following additional extensions are planned, but not yet available:
- Spoolman (available in v5 in the Installer-Menu)
- OctoApp (available in v5 in the Installer-Menu)
- KIAUH has its own config file now
- The file has some default values for the currently supported options
- There might be more options in the future
- It is located in KIAUH's root directory and is called `default.kiauh.cfg`
- DO NOT EDIT the default file directly, instead make a copy of it and call it `kiauh.cfg`
- Settings changed via the Advanced-Menu will be written to the `kiauh.cfg`
- Support for OctoPrint was removed
Feel free to give version 6 a try and report any bugs or issues you encounter! Every feedback is appreciated.
### 2023-06-17
KIAUH has now added support for installing Mobileraker's companion!
KIAUH has now added support for installing Mobileraker's companion!
Mobileraker is a free and Open Source Android and iOS App for Klipper, utilizing the Moonraker API, allowing you
to control your printer. Thank you to [Clon1998](https://github.com/Clon1998) for adding this feature!
### 2023-02-03
The installer for MJPG-Streamer got replaced by crowsnest. It is an improved webcam service, utilizing ustreamer.
The installer for MJPG-Streamer got replaced by crowsnest. It is an improved webcam service, utilizing ustreamer.
Please have a look here for additional info about crowsnest and how to configure it: https://github.com/mainsail-crew/crowsnest \
It's unsure if the previous MJPG-Streamer installer will be updated and make its way back into KIAUH.
A big thanks to [KwadFan](https://github.com/KwadFan) for writing the crowsnest implementation.
@@ -156,7 +115,7 @@ membership for example caused issues when installing mjpg-streamer while not usi
Other issues could occur when trying to flash an MCU on Debian or Ubuntu distributions where a user might not be part
of the dialout group by default. A check for the tty group is also done. The tty group is needed for setting
up a linux MCU (currently not yet supported by KIAUH).
* There is an issue when trying to install Mainsail or Fluidd on Ubuntu 21.10. Permissions on that distro seem to have seen a rework
* There is an issue when trying to install Mainsail or Fluidd on Ubuntu 21.10. Permissions on that distro seem to have seen a rework
in comparison to 20.04 and users will be greeted with an "Error 403 - Permission denied" message after installing one of Klippers webinterfaces.
I still have to figure out a viable solution for that.

View File

@@ -164,6 +164,7 @@ function main() {
fi
}
check_if_ratos
check_euid
init_logfile
@@ -172,3 +173,4 @@ kiauh_update_dialog
read_kiauh_ini
init_ini
main

View File

@@ -234,6 +234,8 @@ def display_moonraker_info(moonraker_list: List[Moonraker]) -> bool:
"The following Klipper instances will be installed:",
*[f"● klipper-{m.suffix}" for m in moonraker_list],
],
padding_top=0,
padding_bottom=0,
)
_input: bool = get_confirm("Proceed with installation?")
return _input

View File

@@ -103,6 +103,7 @@ def check_user_groups() -> None:
"INFO:",
"Relog required for group assignments to take effect!",
],
padding_bottom=0,
)
if not get_confirm(f"Add user '{CURRENT_USER}' to group(s) now?"):

View File

@@ -81,7 +81,6 @@ class KlipperBuildFirmwareMenu(BaseMenu):
line = f"{COLOR_RED}Dependencies are missing!{RESET_FORMAT}"
menu += f"{line:<62}\n"
menu += "╟───────────────────────────────────────────────────────╢\n"
print(menu, end="")

View File

@@ -32,7 +32,7 @@ class KlipperNoFirmwareErrorMenu(BaseMenu):
self.previous_menu = previous_menu
def set_options(self) -> None:
self.default_option = Option(method=self.go_back)
self.default_option = Option(self.go_back, False)
def print_menu(self) -> None:
header = "!!! NO FIRMWARE FILE FOUND !!!"
@@ -79,7 +79,7 @@ class KlipperNoBoardTypesErrorMenu(BaseMenu):
self.previous_menu = previous_menu
def set_options(self) -> None:
self.default_option = Option(method=self.go_back)
self.default_option = Option(self.go_back, False)
def print_menu(self) -> None:
header = "!!! ERROR GETTING BOARD LIST !!!"

View File

@@ -249,7 +249,7 @@ class KlipperSelectMcuIdMenu(BaseMenu):
self.flash_options = FlashOptions()
self.mcu_list = self.flash_options.mcu_list
self.input_label_txt = "Select MCU to flash"
self.footer_type = FooterType.BACK
self.footer_type = FooterType.BACK_HELP
def set_previous_menu(self, previous_menu: Type[BaseMenu] | None) -> None:
self.previous_menu = (
@@ -260,12 +260,13 @@ class KlipperSelectMcuIdMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
f"{i}": Option(self.flash_mcu, f"{i}") for i in range(len(self.mcu_list))
f"{i}": Option(self.flash_mcu, False, f"{i}")
for i in range(len(self.mcu_list))
}
def print_menu(self) -> None:
header = "!!! ATTENTION !!!"
header2 = f"[{COLOR_CYAN}List of detected MCUs{RESET_FORMAT}]"
header2 = f"[{COLOR_CYAN}List of available MCUs{RESET_FORMAT}]"
color = COLOR_RED
count = 62 - len(color) - len(RESET_FORMAT)
menu = textwrap.dedent(
@@ -277,21 +278,15 @@ class KlipperSelectMcuIdMenu(BaseMenu):
║ ONLY flash a firmware created for the respective MCU! ║
║ ║
{header2:─^64}
║ ║
"""
)[1:]
for i, mcu in enumerate(self.mcu_list):
mcu = mcu.split("/")[-1]
menu += f" {i}) {COLOR_CYAN}{mcu:<51}{RESET_FORMAT}\n"
menu += f" ● MCU #{i}: {COLOR_CYAN}{mcu}{RESET_FORMAT}\n"
menu += "╟───────────────────────────┬───────────────────────────╢"
menu += textwrap.dedent(
"""
║ ║
╟───────────────────────────────────────────────────────╢
"""
)[1:]
print(menu, end="")
print(menu, end="\n")
def flash_mcu(self, **kwargs):
try:
@@ -328,7 +323,7 @@ class KlipperSelectSDFlashBoardMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
f"{i}": Option(self.board_select, f"{i}")
f"{i}": Option(self.board_select, False, f"{i}")
for i in range(len(self.available_boards))
}
@@ -349,8 +344,8 @@ class KlipperSelectSDFlashBoardMenu(BaseMenu):
for i, board in enumerate(self.available_boards):
line = f" {i}) {board}"
menu += f"{line:<55}\n"
menu += "╟───────────────────────────────────────────────────────╢"
menu += f"|{line:<55}|\n"
print(menu, end="")
def board_select(self, **kwargs):
@@ -398,8 +393,8 @@ class KlipperFlashOverviewMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"y": Option(self.execute_flash),
"n": Option(self.abort_process),
"Y": Option(self.execute_flash),
"N": Option(self.abort_process),
}
self.default_option = Option(self.execute_flash)
@@ -412,7 +407,7 @@ class KlipperFlashOverviewMenu(BaseMenu):
method = self.flash_options.flash_method.value
command = self.flash_options.flash_command.value
conn_type = self.flash_options.connection_type.value
mcu = self.flash_options.selected_mcu.split("/")[-1]
mcu = self.flash_options.selected_mcu
board = self.flash_options.selected_board
baudrate = self.flash_options.selected_baudrate
subheader = f"[{COLOR_CYAN}Overview{RESET_FORMAT}]"
@@ -426,37 +421,26 @@ class KlipperFlashOverviewMenu(BaseMenu):
║ sure everything is correct, start the process. If any ║
║ parameter needs to be changed, you can go back (B) ║
║ step by step or abort and start from the beginning. ║
{subheader:^64}
║ ║
{subheader:-^64}
"""
)[1:]
menu += textwrap.dedent(
f"""
║ MCU: {COLOR_CYAN}{mcu:<48}{RESET_FORMAT}
║ Connection: {COLOR_CYAN}{conn_type:<41}{RESET_FORMAT}
║ Flash method: {COLOR_CYAN}{method:<39}{RESET_FORMAT}
║ Flash command: {COLOR_CYAN}{command:<38}{RESET_FORMAT}
"""
)[1:]
menu += f" ● MCU: {COLOR_CYAN}{mcu}{RESET_FORMAT}\n"
menu += f" ● Connection: {COLOR_CYAN}{conn_type}{RESET_FORMAT}\n"
menu += f" ● Flash method: {COLOR_CYAN}{method}{RESET_FORMAT}\n"
menu += f" ● Flash command: {COLOR_CYAN}{command}{RESET_FORMAT}\n"
if self.flash_options.flash_method is FlashMethod.SD_CARD:
menu += textwrap.dedent(
f"""
║ Board type: {COLOR_CYAN}{board:<41}{RESET_FORMAT}
║ Baudrate: {COLOR_CYAN}{baudrate:<43}{RESET_FORMAT}
"""
)[1:]
menu += f" ● Board type: {COLOR_CYAN}{board}{RESET_FORMAT}\n"
menu += f" ● Baudrate: {COLOR_CYAN}{baudrate}{RESET_FORMAT}\n"
menu += textwrap.dedent(
"""
║ ║
╟───────────────────────────────────────────────────────╢
║ Y) Start flash process ║
║ N) Abort - Return to Advanced Menu ║
╟───────────────────────────────────────────────────────╢
"""
)[1:]
)
print(menu, end="")
def execute_flash(self, **kwargs):

View File

@@ -68,6 +68,8 @@ def install_klipperscreen() -> None:
"KlipperScreens update manager configuration for Moonraker "
"will not be added to any moonraker.conf.",
],
padding_top=0,
padding_bottom=0,
)
if not get_confirm(
"Continue KlipperScreen installation?",
@@ -103,8 +105,8 @@ def patch_klipperscreen_update_manager(instances: List[Moonraker]) -> None:
options=[
("type", "git_repo"),
("path", KLIPPERSCREEN_DIR.as_posix()),
("origin", KLIPPERSCREEN_REPO),
("managed_services", "KlipperScreen"),
("orgin", KLIPPERSCREEN_REPO),
("manages_servcies", "KlipperScreen"),
("env", f"{KLIPPERSCREEN_ENV_DIR}/bin/python"),
("requirements", KLIPPERSCREEN_REQ_FILE.as_posix()),
("install_script", KLIPPERSCREEN_INSTALL_SCRIPT.as_posix()),

View File

@@ -32,7 +32,7 @@ class LogUploadMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
f"{index}": Option(self.upload, opt_index=f"{index}")
f"{index}": Option(self.upload, False, opt_index=f"{index}")
for index in range(len(self.logfile_list))
}

View File

@@ -63,6 +63,8 @@ def install_octoeverywhere() -> None:
"It is safe to run the installer again to link your "
"printer or repair any issues.",
],
padding_top=0,
padding_bottom=0,
)
if not get_confirm("Re-run OctoEverywhere installation?"):
Logger.print_info("Exiting OctoEverywhere for Klipper installation ...")
@@ -83,6 +85,8 @@ def install_octoeverywhere() -> None:
"\n\n",
"The setup will apply the same names to OctoEverywhere!",
],
padding_top=0,
padding_bottom=0,
)
if not get_confirm(

View File

@@ -24,6 +24,8 @@ def print_moonraker_not_found_dialog() -> None:
"another machine in your network. Otherwise Mainsail will NOT work "
"correctly.",
],
padding_top=0,
padding_bottom=0,
)
@@ -34,6 +36,8 @@ def print_client_already_installed_dialog(name: str) -> None:
f"{name} seems to be already installed!",
f"If you continue, your current {name} installation will be overwritten.",
],
padding_top=0,
padding_bottom=0,
)
@@ -53,6 +57,8 @@ def print_client_port_select_dialog(
"The following ports were found to be in use already:",
*[f"{port}" for port in ports_in_use],
],
padding_top=0,
padding_bottom=0,
)
@@ -71,6 +77,8 @@ def print_install_client_config_dialog(client: BaseWebClient) -> None:
"If you already use these macros skip this step. Otherwise you should "
"consider to answer with 'Y' to download the recommended macros.",
],
padding_top=0,
padding_bottom=0,
)

View File

@@ -38,7 +38,7 @@ from core.types import ComponentStatus
from utils.common import get_install_status
from utils.fs_utils import create_symlink, remove_file
from utils.git_utils import (
get_latest_remote_tag,
get_latest_tag,
get_latest_unstable_tag,
)
@@ -137,7 +137,7 @@ def get_local_client_version(client: BaseWebClient) -> str | None:
def get_remote_client_version(client: BaseWebClient) -> str | None:
try:
if (tag := get_latest_remote_tag(client.repo_path)) != "":
if (tag := get_latest_tag(client.repo_path)) != "":
return str(tag)
return None
except Exception:

View File

@@ -17,10 +17,6 @@ from core.logger import Logger
from utils.common import get_current_date
class BackupManagerException(Exception):
pass
# noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic
class BackupManager:
@@ -69,7 +65,7 @@ class BackupManager:
def backup_directory(
self, name: str, source: Path, target: Path | None = None
) -> Path | None:
) -> None:
Logger.print_status(f"Creating backup of {name} in {target} ...")
if source is None or not Path(source).exists():
@@ -80,15 +76,15 @@ class BackupManager:
try:
date = get_current_date().get("date")
time = get_current_date().get("time")
backup_target = target.joinpath(f"{name.lower()}-{date}-{time}")
shutil.copytree(source, backup_target, ignore=self.ignore_folders_func)
shutil.copytree(
source,
target.joinpath(f"{name.lower()}-{date}-{time}"),
ignore=self.ignore_folders_func,
)
Logger.print_ok("Backup successful!")
return backup_target
except OSError as e:
Logger.print_error(f"Unable to backup directory '{source}':\n{e}")
raise BackupManagerException(f"Unable to backup directory '{source}':\n{e}")
return
def ignore_folders_func(self, dirpath, filenames) -> List[str]:
return (

View File

@@ -92,8 +92,8 @@ class Logger:
center_content: bool = False,
custom_title: str | None = None,
custom_color: DialogCustomColor | None = None,
margin_top: int = 0,
margin_bottom: int = 0,
padding_top: int = 1,
padding_bottom: int = 1,
) -> None:
"""
Prints a dialog with the given title and content.
@@ -106,8 +106,8 @@ class Logger:
:param center_content: Whether to center the content or not.
:param custom_title: A custom title for the dialog.
:param custom_color: A custom color for the dialog.
:param margin_top: The number of empty lines to print before the dialog.
:param margin_bottom: The number of empty lines to print after the dialog.
:param padding_top: The number of empty lines to print before the dialog.
:param padding_bottom: The number of empty lines to print after the dialog.
"""
dialog_color = Logger._get_dialog_color(title, custom_color)
dialog_title = Logger._get_dialog_title(title, custom_title)
@@ -116,12 +116,12 @@ class Logger:
top = Logger._format_top_border(dialog_color)
bottom = Logger._format_bottom_border()
print("\n" * margin_top)
print("\n" * padding_top)
print(
f"{top}{dialog_title_formatted}{dialog_content}{bottom}",
end="",
)
print("\n" * margin_bottom)
print("\n" * padding_bottom)
@staticmethod
def _get_dialog_title(

View File

@@ -10,7 +10,7 @@ from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from typing import Any, Callable, Type
from typing import Any, Callable
@dataclass
@@ -22,10 +22,7 @@ class Option:
:param opt_data: Can be used to pass any additional data to the menu option
"""
def __repr__(self):
return f"Option(method={self.method.__name__}, opt_index={self.opt_index}, opt_data={self.opt_data})"
method: Type[Callable]
method: Callable | None = None
opt_index: str = ""
opt_data: Any = None

View File

@@ -25,7 +25,6 @@ from core.constants import (
)
from core.logger import Logger
from core.menus import FooterType, Option
from utils.input_utils import get_selection_input
def clear() -> None:
@@ -142,7 +141,7 @@ class BaseMenu(metaclass=PostInitCaller):
def __go_to_help(self, **kwargs) -> None:
if self.help_menu is None:
return
self.help_menu(previous_menu=self.__class__).run()
self.help_menu(previous_menu=self).run()
def __exit(self, **kwargs) -> None:
Logger.print_ok("###### Happy printing!", False)
@@ -178,20 +177,46 @@ class BaseMenu(metaclass=PostInitCaller):
self.print_menu()
self.print_footer()
def validate_user_input(self, usr_input: str) -> Option:
"""
Validate the user input and either return an Option, a string or None
:param usr_input: The user input in form of a string
:return: Option, str or None
"""
usr_input = usr_input.lower()
option = self.options.get(
usr_input,
Option(method=None, opt_index="", opt_data=None),
)
# if option/usr_input is None/empty string, we execute the menus default option if specified
if (option is None or usr_input == "") and self.default_option is not None:
self.default_option.opt_index = usr_input
return self.default_option
# user selected a regular option
option.opt_index = usr_input
return option
def handle_user_input(self) -> Option:
"""Handle the user input, return the validated input or print an error."""
while True:
print(f"{COLOR_CYAN}###### {self.input_label_txt}: {RESET_FORMAT}", end="")
usr_input = input().lower()
validated_input = self.validate_user_input(usr_input)
if validated_input.method is not None:
return validated_input
else:
Logger.print_error("Invalid input!", False)
def run(self) -> None:
"""Start the menu lifecycle. When this function returns, the lifecycle of the menu ends."""
try:
self.display_menu()
option = get_selection_input(self.input_label_txt, self.options)
selected_option: Option = self.options.get(option)
selected_option.method(
opt_index=selected_option.opt_index,
opt_data=selected_option.opt_data,
)
option = self.handle_user_input()
option.method(opt_index=option.opt_index, opt_data=option.opt_data)
self.run()
except Exception as e:
Logger.print_error(
f"An unexpected error occured:\n{e}\n{traceback.format_exc()}"

View File

@@ -44,7 +44,6 @@ from core.menus.settings_menu import SettingsMenu
from core.menus.update_menu import UpdateMenu
from core.types import ComponentStatus, StatusMap, StatusText
from extensions.extensions_menu import ExtensionsMenu
from utils.common import get_kiauh_version
# noinspection PyUnusedLocal
@@ -56,9 +55,7 @@ class MainMenu(BaseMenu):
self.header: bool = True
self.footer_type: FooterType = FooterType.QUIT
self.version = ""
self.kl_status = self.kl_owner = self.kl_repo = ""
self.mr_status = self.mr_owner = self.mr_repo = ""
self.kl_status = self.kl_repo = self.mr_status = self.mr_repo = ""
self.ms_status = self.fl_status = self.ks_status = self.mb_status = ""
self.cn_status = self.cc_status = self.oe_status = ""
self._init_status()
@@ -89,7 +86,6 @@ class MainMenu(BaseMenu):
)
def _fetch_status(self) -> None:
self.version = get_kiauh_version()
self._get_component_status("kl", get_klipper_status)
self._get_component_status("mr", get_moonraker_status)
self._get_component_status("ms", get_client_status, MainsailData())
@@ -104,7 +100,6 @@ class MainMenu(BaseMenu):
status_data: ComponentStatus = status_fn(*args)
code: int = status_data.status
status: StatusText = StatusMap[code]
owner: str = status_data.owner
repo: str = status_data.repo
instance_count: int = status_data.instances
@@ -113,7 +108,6 @@ class MainMenu(BaseMenu):
count_txt = f": {instance_count}"
setattr(self, f"{name}_status", self._format_by_code(code, status, count_txt))
setattr(self, f"{name}_owner", f"{COLOR_CYAN}{owner}{RESET_FORMAT}")
setattr(self, f"{name}_repo", f"{COLOR_CYAN}{repo}{RESET_FORMAT}")
def _format_by_code(self, code: int, status: str, count: str) -> str:
@@ -131,7 +125,7 @@ class MainMenu(BaseMenu):
self._fetch_status()
header = " [ Main Menu ] "
footer1 = f"{COLOR_CYAN}{self.version}{RESET_FORMAT}"
footer1 = f"{COLOR_CYAN}KIAUH v6.0.0{RESET_FORMAT}"
footer2 = f"Changelog: {COLOR_MAGENTA}https://git.io/JnmlX{RESET_FORMAT}"
color = COLOR_CYAN
count = 62 - len(color) - len(RESET_FORMAT)
@@ -143,19 +137,17 @@ class MainMenu(BaseMenu):
{color}{header:~^{count}}{RESET_FORMAT}
╟──────────────────┬────────────────────────────────────╢
║ 0) [Log-Upload] │ Klipper: {self.kl_status:<{pad1}}
║ │ Owner: {self.kl_owner:<{pad1}}
║ 1) [Install] │ Repo: {self.kl_repo:<{pad1}}
║ 2) [Update] ├────────────────────────────────────╢
║ 3) [Remove] │ Moonraker: {self.mr_status:<{pad1}}
║ 4) [Advanced] │ Owner: {self.mr_owner:<{pad1}}
║ 5) [Backup] │ Repo: {self.mr_repo:<{pad1}}
║ ├────────────────────────────────────╢
║ S) [Settings] │ Mainsail: {self.ms_status:<{pad2}}
║ │ Repo: {self.kl_repo:<{pad1}}
║ 1) [Install] ├────────────────────────────────────╢
║ 2) [Update] │ Moonraker: {self.mr_status:<{pad1}}
║ 3) [Remove] │ Repo: {self.mr_repo:<{pad1}}
║ 4) [Advanced] ├────────────────────────────────────╢
║ 5) [Backup] │ Mainsail: {self.ms_status:<{pad2}}
║ │ Fluidd: {self.fl_status:<{pad2}}
Community: │ Client-Config: {self.cc_status:<{pad2}}
E) [Extensions] │ ║
│ KlipperScreen: {self.ks_status:<{pad2}}
│ Mobileraker: {self.mb_status:<{pad2}}
S) [Settings] │ Client-Config: {self.cc_status:<{pad2}}
│ ║
Community: │ KlipperScreen: {self.ks_status:<{pad2}}
E) [Extensions] │ Mobileraker: {self.mb_status:<{pad2}}
║ │ OctoEverywhere: {self.oe_status:<{pad2}}
║ │ Crowsnest: {self.cn_status:<{pad2}}
╟──────────────────┼────────────────────────────────────╢

View File

@@ -8,16 +8,24 @@
# ======================================================================= #
from __future__ import annotations
import shutil
import textwrap
from typing import Literal, Tuple, Type
from pathlib import Path
from typing import Tuple, Type
from components.klipper import KLIPPER_DIR
from components.klipper.klipper import Klipper
from components.moonraker import MOONRAKER_DIR
from components.moonraker.moonraker import Moonraker
from core.constants import COLOR_CYAN, COLOR_GREEN, RESET_FORMAT
from core.instance_manager.instance_manager import InstanceManager
from core.logger import DialogType, Logger
from core.menus import Option
from core.menus.base_menu import BaseMenu
from core.settings.kiauh_settings import KiauhSettings, RepoSettings
from procedures.switch_repo import run_switch_repo_routine
from core.settings.kiauh_settings import KiauhSettings
from utils.git_utils import git_clone_wrapper
from utils.input_utils import get_confirm, get_string_input
from utils.instance_utils import get_instances
# noinspection PyUnusedLocal
@@ -97,28 +105,22 @@ class SettingsMenu(BaseMenu):
self.mainsail_unstable = self.settings.mainsail.unstable_releases
self.fluidd_unstable = self.settings.fluidd.unstable_releases
def _format_repo_str(self, repo_name: Literal["klipper", "moonraker"]) -> None:
repo: RepoSettings = self.settings[repo_name]
repo_str = f"{'/'.join(repo.repo_url.rsplit('/', 2)[-2:])}"
branch_str = f"({COLOR_CYAN}@ {repo.branch}{RESET_FORMAT})"
setattr(
self,
f"{repo_name}_repo",
f"{COLOR_CYAN}{repo_str}{RESET_FORMAT} {branch_str}",
)
def _format_repo_str(self, repo_name: str) -> None:
repo = self.settings.get(repo_name, "repo_url")
repo = f"{'/'.join(repo.rsplit('/', 2)[-2:])}"
branch = self.settings.get(repo_name, "branch")
branch = f"({COLOR_CYAN}@ {branch}{RESET_FORMAT})"
setattr(self, f"{repo_name}_repo", f"{COLOR_CYAN}{repo}{RESET_FORMAT} {branch}")
def _gather_input(self) -> Tuple[str, str]:
Logger.print_dialog(
DialogType.ATTENTION,
[
"There is no input validation in place! Make sure your the input is "
"valid and has no typos or invalid characters! For the change to take "
"effect, the new repository will be cloned. A backup of the old "
"repository will be created.",
"\n\n",
"Make sure you don't have any ongoing prints running, as the services "
"will be restarted during this process! You will loose any ongoing print!",
"There is no input validation in place! Make sure your"
" input is valid and has no typos! For any change to"
" take effect, the repository must be cloned again. "
"Make sure you don't have any ongoing prints running, "
"as the services will be restarted!"
],
)
repo = get_string_input(
@@ -132,7 +134,7 @@ class SettingsMenu(BaseMenu):
return repo, branch
def _set_repo(self, repo_name: Literal["klipper", "moonraker"]) -> None:
def _set_repo(self, repo_name: str) -> None:
repo_url, branch = self._gather_input()
display_name = repo_name.capitalize()
Logger.print_dialog(
@@ -146,13 +148,10 @@ class SettingsMenu(BaseMenu):
)
if get_confirm("Apply changes?", allow_go_back=True):
repo: RepoSettings = self.settings[repo_name]
repo.repo_url = repo_url
repo.branch = branch
self.settings.set(repo_name, "repo_url", repo_url)
self.settings.set(repo_name, "branch", branch)
self.settings.save()
self._load_settings()
Logger.print_ok("Changes saved!")
else:
Logger.print_info(
@@ -162,10 +161,31 @@ class SettingsMenu(BaseMenu):
Logger.print_status(f"Switching to {display_name}'s new source repository ...")
self._switch_repo(repo_name)
Logger.print_ok(f"Switched to {repo_url} at branch {branch}!")
def _switch_repo(self, name: Literal["klipper", "moonraker"]) -> None:
repo: RepoSettings = self.settings[name]
run_switch_repo_routine(name, repo)
def _switch_repo(self, name: str) -> None:
target_dir: Path
if name == "klipper":
target_dir = KLIPPER_DIR
_type = Klipper
elif name == "moonraker":
target_dir = MOONRAKER_DIR
_type = Moonraker
else:
Logger.print_error("Invalid repository name!")
return
if target_dir.exists():
shutil.rmtree(target_dir)
instances = get_instances(_type)
InstanceManager.stop_all(instances)
repo = self.settings.get(name, "repo_url")
branch = self.settings.get(name, "branch")
git_clone_wrapper(repo, target_dir, branch)
InstanceManager.start_all(instances)
def set_klipper_repo(self, **kwargs) -> None:
self._set_repo("klipper")

View File

@@ -281,6 +281,8 @@ class UpdateMenu(BaseMenu):
DialogType.CUSTOM,
["The following packages will be upgraded:", "\n\n", pkgs],
custom_title="UPGRADABLE SYSTEM UPDATES",
padding_top=0,
padding_bottom=0,
)
if not get_confirm("Continue?"):
return

View File

@@ -8,9 +8,6 @@
# ======================================================================= #
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
from core.logger import DialogType, Logger
from core.submodules.simple_config_parser.src.simple_config_parser.simple_config_parser import (
NoOptionError,
@@ -25,21 +22,33 @@ DEFAULT_CFG = PROJECT_ROOT.joinpath("default.kiauh.cfg")
CUSTOM_CFG = PROJECT_ROOT.joinpath("kiauh.cfg")
@dataclass
class AppSettings:
backup_before_update: bool | None = field(default=None)
def __init__(self) -> None:
self.backup_before_update = None
@dataclass
class RepoSettings:
repo_url: str | None = field(default=None)
branch: str | None = field(default=None)
class KlipperSettings:
def __init__(self) -> None:
self.repo_url = None
self.branch = None
@dataclass
class WebUiSettings:
port: str | None = field(default=None)
unstable_releases: bool | None = field(default=None)
class MoonrakerSettings:
def __init__(self) -> None:
self.repo_url = None
self.branch = None
class MainsailSettings:
def __init__(self) -> None:
self.port = None
self.unstable_releases = None
class FluiddSettings:
def __init__(self) -> None:
self.port = None
self.unstable_releases = None
# noinspection PyUnusedLocal
@@ -52,12 +61,6 @@ class KiauhSettings:
cls._instance = super(KiauhSettings, cls).__new__(cls, *args, **kwargs)
return cls._instance
def __repr__(self) -> str:
return f"KiauhSettings(kiauh={self.kiauh}, klipper={self.klipper}, moonraker={self.moonraker}, mainsail={self.mainsail}, fluidd={self.fluidd})"
def __getitem__(self, item: str) -> Any:
return getattr(self, item)
def __init__(self) -> None:
if not hasattr(self, "__initialized"):
self.__initialized = False
@@ -66,10 +69,20 @@ class KiauhSettings:
self.__initialized = True
self.config = SimpleConfigParser()
self.kiauh = AppSettings()
self.klipper = RepoSettings()
self.moonraker = RepoSettings()
self.mainsail = WebUiSettings()
self.fluidd = WebUiSettings()
self.klipper = KlipperSettings()
self.moonraker = MoonrakerSettings()
self.mainsail = MainsailSettings()
self.fluidd = FluiddSettings()
self.kiauh.backup_before_update = None
self.klipper.repo_url = None
self.klipper.branch = None
self.moonraker.repo_url = None
self.moonraker.branch = None
self.mainsail.port = None
self.mainsail.unstable_releases = None
self.fluidd.port = None
self.fluidd.unstable_releases = None
self._load_config()
@@ -89,8 +102,22 @@ class KiauhSettings:
except AttributeError:
raise
def set(self, section: str, option: str, value: str | int | bool) -> None:
"""
Set a value in the settings state by providing the section and option name as strings.
Prefer direct access to the properties, as it is usually safer!
:param section: The section name as string.
:param option: The option name as string.
:param value: The value to set as string, int or bool.
"""
try:
section = getattr(self, section)
section.option = value # type: ignore
except AttributeError:
raise
def save(self) -> None:
self._set_config_options_state()
self._set_config_options()
self.config.write(CUSTOM_CFG)
self._load_config()
@@ -102,7 +129,7 @@ class KiauhSettings:
self.config.read(cfg)
self._validate_cfg()
self._apply_settings_from_file()
self._read_settings()
def _validate_cfg(self) -> None:
try:
@@ -144,7 +171,7 @@ class KiauhSettings:
if v.isdigit() or v.lower() == "true" or v.lower() == "false":
raise ValueError
def _apply_settings_from_file(self) -> None:
def _read_settings(self) -> None:
self.kiauh.backup_before_update = self.config.getboolean(
"kiauh", "backup_before_update"
)
@@ -161,7 +188,7 @@ class KiauhSettings:
"fluidd", "unstable_releases"
)
def _set_config_options_state(self) -> None:
def _set_config_options(self) -> None:
self.config.set(
"kiauh",
"backup_before_update",

View File

@@ -85,46 +85,10 @@ class DuplicateOptionError(Exception):
class SimpleConfigParser:
"""A customized config parser targeted at handling Klipper style config files"""
# definition of section line:
# - then line MUST start with an opening square bracket - it is the first section marker
# - the section marker MUST be followed by at least one character - it is the section name
# - the section name MUST be followed by a closing square bracket - it is the second section marker
# - the second section marker MAY be followed by any amount of whitespace characters
# - the second section marker MAY be followed by a # or ; - it is the comment marker
# - the inline comment MAY be of any length and character
_SECTION_RE = re.compile(r"\[(.+)]\s*([#;].*)?$")
# definition of option line:
# - the line MUST start with a word - it is the option name
# - the option name MUST be followed by a colon or an equal sign - it is the separator
# - the separator MUST be followed by a value
# - the separator MAY have any amount of leading or trailing whitespaces
# - the separator MUST NOT be directly followed by a colon or equal sign
# - the value MAY be of any length and character
# - the value MAY contain any amount of trailing whitespaces
# - the value MAY be followed by a # or ; - it is the comment marker
# - the inline comment MAY be of any length and character
_OPTION_RE = re.compile(r"^([^:=\s]+)\s?[:=]\s*([^=:].*)\s*([#;].*)?$")
# definition of multiline option line:
# - the line MUST start with a word - it is the option name
# - the option name MUST be followed by a colon or an equal sign - it is the separator
# - the separator MUST NOT be followed by a value
# - the separator MAY have any amount of leading or trailing whitespaces
# - the separator MUST NOT be directly followed by a colon or equal sign
# - the separator MAY be followed by a # or ; - it is the comment marker
# - the inline comment MAY be of any length and character
_MLOPTION_RE = re.compile(r"^([^:=\s]+)\s*[:=]\s*([#;].*)?$")
# definition of comment line:
# - the line MAY start with any amount of whitespace characters
# - the line MUST contain a # or ; - it is the comment marker
# - the comment marker MAY be followed by any amount of whitespace characters
# - the comment MAY be of any length and character
_SECTION_RE = re.compile(r"\s*\[(\w+\s?.+)]\s*([#;].*)?$")
_OPTION_RE = re.compile(r"^\s*(\w+)\s*[:=]\s*([^=:].*)\s*([#;].*)?$")
_MLOPTION_RE = re.compile(r"^\s*(\w+)\s*[:=]\s*([#;].*)?$")
_COMMENT_RE = re.compile(r"^\s*([#;].*)?$")
# definition of empty line:
# - the line MUST contain only whitespace characters
_EMPTY_LINE_RE = re.compile(r"^\s*$")
BOOLEAN_STATES = {

View File

@@ -21,8 +21,4 @@ testcases = [
"serial",
"/dev/serial/by-id/<your-mcu-id>",
),
("parameter_temperature_(°C): 155", "parameter_temperature_(°C)", "155"),
("parameter_humidity_(%_RH): 45", "parameter_humidity_(%_RH)", "45"),
("parameter_spool_weight_(%): 10", "parameter_spool_weight_(%)", "10"),
("path: /dev/shm/drying_box.json", "path", "/dev/shm/drying_box.json"),
]

View File

@@ -14,7 +14,7 @@ def parser():
return SimpleConfigParser()
class TestSingleLineParsing:
class TestLineParsing:
@pytest.mark.parametrize("given, expected", [*case_parse_section])
def test_parse_section(self, parser, given, expected):
parser._parse_section(given)

View File

@@ -14,14 +14,4 @@ testcases = [
("", False),
("# that's a comment", False),
("; that's a comment", False),
("parameter_humidity_(%_RH):", True),
("parameter_spool_weight_(%):", True),
("parameter_temperature_(°C):", True),
("parameter_humidity_(%_RH): 18.123", False),
("parameter_spool_weight_(%): 150", False),
("parameter_temperature_(°C): 30,5", False),
("trusted_clients:", True),
("trusted_clients: 192.168.1.0/24", False),
("cors_domains:", True),
("cors_domains: http://*.lan", False),
]

View File

@@ -26,6 +26,5 @@ testcases = [
("description: homing!", True),
("description: inline macro :-)", True),
("path: %GCODES_DIR%", True),
("path: /dev/shm/drying_box.json", True),
("serial = /dev/serial/by-id/<your-mcu-id>", True),
]

View File

@@ -23,7 +23,6 @@ StatusMap: Dict[StatusCode, StatusText] = {
@dataclass
class ComponentStatus:
status: StatusCode
owner: str | None = None
repo: str | None = None
local: str | None = None
remote: str | None = None

View File

@@ -38,7 +38,9 @@ class ExtensionsMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
i: Option(self.extension_submenu, opt_data=self.extensions.get(i))
i: Option(
self.extension_submenu, menu=True, opt_data=self.extensions.get(i)
)
for i in self.extensions
}

View File

@@ -93,7 +93,7 @@ class MainsailThemeInstallMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
f"{index}": Option(self.install_theme, opt_index=f"{index}")
f"{index}": Option(self.install_theme, False, opt_index=f"{index}")
for index in range(len(self.themes))
}

View File

@@ -49,6 +49,8 @@ class TelegramBotExtension(BaseExtension):
"Moonraker Telegram Bot requires Moonraker to be installed. "
"Please install Moonraker first!",
],
padding_top=0,
padding_bottom=0,
)
return
@@ -63,6 +65,8 @@ class TelegramBotExtension(BaseExtension):
"\n\n",
"The setup will apply the same names to Telegram Bot!",
],
padding_top=0,
padding_bottom=0,
)
if not get_confirm(
"Continue Moonraker Telegram Bot installation?",
@@ -84,6 +88,8 @@ class TelegramBotExtension(BaseExtension):
instance = MoonrakerTelegramBot(suffix=name)
instance.create()
print(instance)
cmd_sysctl_service(instance.service_file_path.name, "enable")
if create_example_cfg:
@@ -120,7 +126,6 @@ class TelegramBotExtension(BaseExtension):
"following wiki page for further information:",
"https://github.com/nlef/moonraker-telegram-bot/wiki",
],
margin_bottom=1,
)
Logger.print_ok("Telegram Bot installation complete!")
@@ -175,7 +180,7 @@ class TelegramBotExtension(BaseExtension):
options=[
("type", "git_repo"),
("path", str(TG_BOT_DIR)),
("origin", TG_BOT_REPO),
("orgin", TG_BOT_REPO),
("env", env_py),
("requirements", "scripts/requirements.txt"),
("install_script", "scripts/install.sh"),

View File

@@ -1,154 +0,0 @@
# ======================================================================= #
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/dw-0/kiauh #
# #
# This file may be distributed under the terms of the GNU GPLv3 license #
# ======================================================================= #
from __future__ import annotations
import shutil
from pathlib import Path
from typing import Literal
from components.klipper import (
KLIPPER_BACKUP_DIR,
KLIPPER_DIR,
KLIPPER_ENV_DIR,
KLIPPER_REQ_FILE,
)
from components.klipper.klipper import Klipper
from components.klipper.klipper_setup import install_klipper_packages
from components.moonraker import (
MOONRAKER_BACKUP_DIR,
MOONRAKER_DIR,
MOONRAKER_ENV_DIR,
MOONRAKER_REQ_FILE,
)
from components.moonraker.moonraker import Moonraker
from components.moonraker.moonraker_setup import install_moonraker_packages
from core.backup_manager.backup_manager import BackupManager, BackupManagerException
from core.instance_manager.instance_manager import InstanceManager
from core.logger import Logger
from core.settings.kiauh_settings import RepoSettings
from utils.git_utils import GitException, get_repo_name, git_clone_wrapper
from utils.instance_utils import get_instances
from utils.sys_utils import (
VenvCreationFailedException,
create_python_venv,
install_python_requirements,
)
class RepoSwitchFailedException(Exception):
pass
def run_switch_repo_routine(
name: Literal["klipper", "moonraker"], repo_settings: RepoSettings
) -> None:
repo_dir: Path = KLIPPER_DIR if name == "klipper" else MOONRAKER_DIR
env_dir: Path = KLIPPER_ENV_DIR if name == "klipper" else MOONRAKER_ENV_DIR
req_file = KLIPPER_REQ_FILE if name == "klipper" else MOONRAKER_REQ_FILE
backup_dir: Path = KLIPPER_BACKUP_DIR if name == "klipper" else MOONRAKER_BACKUP_DIR
_type = Klipper if name == "klipper" else Moonraker
# step 1: stop all instances
Logger.print_status(f"Stopping all {_type.__name__} instances ...")
instances = get_instances(_type)
InstanceManager.stop_all(instances)
repo_dir_backup_path: Path | None = None
env_dir_backup_path: Path | None = None
try:
# step 2: backup old repo and env
org, repo = get_repo_name(repo_dir)
backup_dir = backup_dir.joinpath(org)
bm = BackupManager()
repo_dir_backup_path = bm.backup_directory(
repo_dir.name,
repo_dir,
backup_dir,
)
env_dir_backup_path = bm.backup_directory(
env_dir.name,
env_dir,
backup_dir,
)
# step 3: read repo url and branch from settings
repo_url = repo_settings.repo_url
branch = repo_settings.branch
if not (repo_url or branch):
error = f"Invalid repository URL ({repo_url}) or branch ({branch})!"
raise ValueError(error)
# step 4: clone new repo
git_clone_wrapper(repo_url, repo_dir, branch, force=True)
# step 5: install os dependencies
if name == "klipper":
install_klipper_packages()
elif name == "moonraker":
install_moonraker_packages()
# step 6: recreate python virtualenv
Logger.print_status(f"Recreating {_type.__name__} virtualenv ...")
if not create_python_venv(env_dir, force=True):
raise GitException(f"Failed to recreate virtualenv for {_type.__name__}")
else:
install_python_requirements(env_dir, req_file)
Logger.print_ok(f"Switched to {repo_url} at branch {branch}!")
except BackupManagerException as e:
Logger.print_error(f"Error during backup of repository: {e}")
raise RepoSwitchFailedException(e)
except (GitException, VenvCreationFailedException) as e:
# if something goes wrong during cloning or recreating the virtualenv,
# we restore the backup of the repo and env
Logger.print_error(f"Error during repository switch: {e}", start="\n")
Logger.print_status(f"Restoring last backup of {_type.__name__} ...")
_restore_repo_backup(
_type.__name__,
env_dir,
env_dir_backup_path,
repo_dir,
repo_dir_backup_path,
)
except RepoSwitchFailedException as e:
Logger.print_error(f"Something went wrong: {e}")
return
Logger.print_status(f"Restarting all {_type.__name__} instances ...")
InstanceManager.start_all(instances)
def _restore_repo_backup(
name: str,
env_dir: Path,
env_dir_backup_path: Path | None,
repo_dir: Path,
repo_dir_backup_path: Path | None,
) -> None:
# if repo_dir_backup_path is not None and env_dir_backup_path is not None:
if not repo_dir_backup_path or not env_dir_backup_path:
raise RepoSwitchFailedException(
f"Unable to restore backup of {name}! Path of backups directory is None!"
)
try:
if repo_dir.exists():
shutil.rmtree(repo_dir)
shutil.copytree(repo_dir_backup_path, repo_dir)
if env_dir.exists():
shutil.rmtree(env_dir)
shutil.copytree(env_dir_backup_path, env_dir)
Logger.print_warn(f"Restored backup of {name} successfully!")
except Exception as e:
raise RepoSwitchFailedException(f"Error restoring backup: {e}")

View File

@@ -35,6 +35,8 @@ def change_system_hostname() -> None:
"browser.",
],
custom_title="CHANGE SYSTEM HOSTNAME",
padding_top=0,
padding_bottom=0,
)
if not get_confirm("Do you want to change the hostname?", default_choice=False):
return
@@ -48,6 +50,8 @@ def change_system_hostname() -> None:
"● Any special characters",
"● No leading or trailing '-'",
],
padding_top=0,
padding_bottom=0,
)
hostname = get_string_input(
"Enter the new hostname",

View File

@@ -22,12 +22,7 @@ from core.constants import (
)
from core.logger import DialogType, Logger
from core.types import ComponentStatus, StatusCode
from utils.git_utils import (
get_local_commit,
get_local_tags,
get_remote_commit,
get_repo_name,
)
from utils.git_utils import get_local_commit, get_remote_commit, get_repo_name
from utils.instance_utils import get_instances
from utils.sys_utils import (
check_package_install,
@@ -36,14 +31,6 @@ from utils.sys_utils import (
)
def get_kiauh_version() -> str:
"""
Helper method to get the current KIAUH version by reading the latest tag
:return: string of the latest tag
"""
return get_local_tags(Path(__file__).parent.parent)[-1]
def convert_camelcase_to_kebabcase(name: str) -> str:
return re.sub(r"(?<!^)(?=[A-Z])", "-", name).lower()
@@ -124,12 +111,10 @@ def get_install_status(
else:
status = 1 # incomplete
org, repo = get_repo_name(repo_dir)
return ComponentStatus(
status=status,
instances=instances,
owner=org,
repo=repo,
repo=get_repo_name(repo_dir),
local=get_local_commit(repo_dir),
remote=get_remote_commit(repo_dir),
)

View File

@@ -16,10 +16,6 @@ from utils.input_utils import get_confirm, get_number_input
from utils.instance_utils import get_instances
class GitException(Exception):
pass
def git_clone_wrapper(
repo: str, target_dir: Path, branch: str | None = None, force: bool = False
) -> None:
@@ -47,10 +43,10 @@ def git_clone_wrapper(
except CalledProcessError:
log = "An unexpected error occured during cloning of the repository."
Logger.print_error(log)
raise GitException(log)
return
except OSError as e:
Logger.print_error(f"Error removing existing repository: {e.strerror}")
raise GitException(f"Error removing existing repository: {e.strerror}")
return
def git_pull_wrapper(repo: str, target_dir: Path) -> None:
@@ -70,58 +66,25 @@ def git_pull_wrapper(repo: str, target_dir: Path) -> None:
return
def get_repo_name(repo: Path) -> tuple[str, str] | None:
def get_repo_name(repo: Path) -> str | None:
"""
Helper method to extract the organisation and name of a repository |
:param repo: repository to extract the values from
:return: String in form of "<orga>/<name>" or None
"""
if not repo.exists() or not repo.joinpath(".git").exists():
return "-", "-"
return "-"
try:
cmd = ["git", "-C", repo.as_posix(), "config", "--get", "remote.origin.url"]
result: str = check_output(cmd, stderr=DEVNULL).decode(encoding="utf-8")
substrings: List[str] = result.strip().split("/")[-2:]
return substrings[0], substrings[1]
# return "/".join(substrings).replace(".git", "")
return "/".join(substrings).replace(".git", "")
except CalledProcessError:
return None
def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]:
"""
Get all tags of a local Git repository
:param repo_path: Path to the local Git repository
:param _filter: Optional filter to filter the tags by
:return: List of tags
"""
try:
cmd = ["git", "tag", "-l"]
if _filter is not None:
cmd.append(f"'${_filter}'")
result: str = check_output(
cmd,
stderr=DEVNULL,
cwd=repo_path.as_posix(),
).decode(encoding="utf-8")
tags = result.split("\n")
return tags[:-1]
except CalledProcessError:
return []
def get_remote_tags(repo_path: str) -> List[str]:
"""
Gets the tags of a GitHub repostiory
:param repo_path: path of the GitHub repository - e.g. `<owner>/<name>`
:return: List of tags
"""
def get_tags(repo_path: str) -> List[str]:
try:
url = f"https://api.github.com/repos/{repo_path}/tags"
with urllib.request.urlopen(url) as r:
@@ -139,14 +102,14 @@ def get_remote_tags(repo_path: str) -> List[str]:
raise
def get_latest_remote_tag(repo_path: str) -> str:
def get_latest_tag(repo_path: str) -> str:
"""
Gets the latest stable tag of a GitHub repostiory
:param repo_path: path of the GitHub repository - e.g. `<owner>/<name>`
:return: tag or empty string
"""
try:
if len(latest_tag := get_remote_tags(repo_path)) > 0:
if len(latest_tag := get_tags(repo_path)) > 0:
return latest_tag[0]
else:
return ""
@@ -161,10 +124,7 @@ def get_latest_unstable_tag(repo_path: str) -> str:
:return: tag or empty string
"""
try:
if (
len(unstable_tags := [t for t in get_remote_tags(repo_path) if "-" in t])
> 0
):
if len(unstable_tags := [t for t in get_tags(repo_path) if "-" in t]) > 0:
return unstable_tags[0]
else:
return ""
@@ -173,34 +133,6 @@ def get_latest_unstable_tag(repo_path: str) -> str:
raise
def compare_semver_tags(tag1: str, tag2: str) -> bool:
"""
Compare two semver version strings.
Does not support comparing pre-release versions (e.g. 1.0.0-rc.1, 1.0.0-beta.1)
:param tag1: First version string
:param tag2: Second version string
:return: True if tag1 is greater than tag2, False otherwise
"""
if tag1 == tag2:
return False
def parse_version(v):
return list(map(int, v[1:].split(".")))
tag1_parts = parse_version(tag1)
tag2_parts = parse_version(tag2)
max_len = max(len(tag1_parts), len(tag2_parts))
tag1_parts += [0] * (max_len - len(tag1_parts))
tag2_parts += [0] * (max_len - len(tag2_parts))
for part1, part2 in zip(tag1_parts, tag2_parts):
if part1 != part2:
return part1 > part2
return False
def get_local_commit(repo: Path) -> str | None:
if not repo.exists() or not repo.joinpath(".git").exists():
return None

View File

@@ -137,7 +137,7 @@ def get_selection_input(question: str, option_list: List | Dict, default=None) -
else:
raise ValueError("Invalid option_list type")
Logger.print_error("Invalid option! Please select a valid option.", False)
Logger.print_error(INVALID_CHOICE)
def format_question(question: str, default=None) -> str:

View File

@@ -39,10 +39,6 @@ SysCtlServiceAction = Literal[
SysCtlManageAction = Literal["daemon-reload", "reset-failed"]
class VenvCreationFailedException(Exception):
pass
def kill(opt_err_msg: str = "") -> None:
"""
Kills the application |
@@ -91,12 +87,11 @@ def parse_packages_from_file(source_file: Path) -> List[str]:
return packages
def create_python_venv(target: Path, force: bool = False) -> bool:
def create_python_venv(target: Path) -> bool:
"""
Create a python 3 virtualenv at the provided target destination.
Returns True if the virtualenv was created successfully.
Returns False if the virtualenv already exists, recreation was declined or creation failed.
:param force: Force recreation of the virtualenv
:param target: Path where to create the virtualenv at
:return: bool
"""
@@ -111,7 +106,7 @@ def create_python_venv(target: Path, force: bool = False) -> bool:
Logger.print_error(f"Error setting up virtualenv:\n{e}")
return False
else:
if not force and not get_confirm(
if not get_confirm(
"Virtualenv already exists. Re-create?", default_choice=False
):
Logger.print_info("Skipping re-creation of virtualenv ...")
@@ -179,14 +174,14 @@ def install_python_requirements(target: Path, requirements: Path) -> None:
if result.returncode != 0 or result.stderr:
Logger.print_error(f"{result.stderr}", False)
raise VenvCreationFailedException("Installing Python requirements failed!")
Logger.print_error("Installing Python requirements failed!")
return
Logger.print_ok("Installing Python requirements successful!")
except Exception as e:
log = f"Error installing Python requirements: {e}"
except CalledProcessError as e:
log = f"Error installing Python requirements:\n{e.output.decode()}"
Logger.print_error(log)
raise VenvCreationFailedException(log)
raise
def update_system_package_lists(silent: bool, rls_info_change=False) -> None:

View File

@@ -40,7 +40,7 @@ function main_ui() {
function get_kiauh_version() {
local version
cd "${KIAUH_SRCDIR}"
version="$(git tag -l 'v5*' | tail -1)"
version="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)"
echo "${version}"
}