Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f5b21280c | ||
|
|
485b7bc7bf | ||
|
|
3c3ef62b53 |
No files matched your search
@@ -20,6 +20,48 @@
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
<h2 align="center">⚠️ Official Website Disclaimer ⚠️</h2>
|
||||||
|
|
||||||
|
**The only official source and website for KIAUH is this GitHub repository:
|
||||||
|
[https://github.com/dw-0/kiauh/](https://github.com/dw-0/kiauh/).**
|
||||||
|
|
||||||
|
The website **kiauh[.]com** is **not** an official website of this project and
|
||||||
|
is **not** affiliated with, endorsed by, or connected to KIAUH or its maintainer
|
||||||
|
[dw-0](https://github.com/dw-0) in any way. Its operator neither asked for
|
||||||
|
permission nor informed the maintainer. The maintainer has no control over, and
|
||||||
|
takes no responsibility for, its content, downloads, instructions, or any other
|
||||||
|
material offered there.
|
||||||
|
|
||||||
|
Please be aware of the following:
|
||||||
|
|
||||||
|
* **Do not download, open, or run anything from kiauh[.]com.** Its start page
|
||||||
|
offers a ZIP file for download. Under no circumstances should you download it,
|
||||||
|
open it, or execute any code from it. Its contents are unverified and may be
|
||||||
|
malicious.
|
||||||
|
* **Do not use the contact form on kiauh[.]com.** It does not send your message to
|
||||||
|
any official party of this project. Never submit the form or disclose personal
|
||||||
|
data there. This repository is the only official source and communication channel.
|
||||||
|
* **Do not let its appearance, name, or content mislead you.** It is not the project's website, regardless
|
||||||
|
of how it presents itself.
|
||||||
|
* **Do not trust any of the information.** Any statement on that site about KIAUH, its usage, its support, or its
|
||||||
|
licensing has no connection to the maintainer and may be inaccurate or
|
||||||
|
outdated.
|
||||||
|
|
||||||
|
Please download and install KIAUH from this repository only. Do not run scripts
|
||||||
|
or commands obtained from any other source without verifying them against this
|
||||||
|
repository first.
|
||||||
|
|
||||||
|
The KIAUH name and logo must not be used in a way that suggests an official
|
||||||
|
affiliation with or endorsement by this project.
|
||||||
|
|
||||||
|
If you come across websites or sources that present or suggest themselves as official KIAUH
|
||||||
|
channels, please report them in the
|
||||||
|
[GitHub Discussions](https://github.com/dw-0/kiauh/discussions).
|
||||||
|
|
||||||
|
This statement remains valid until explicitly revoked by the maintainer.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<h2 align="center">
|
<h2 align="center">
|
||||||
📄️ Instructions 📄
|
📄️ Instructions 📄
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -22,6 +22,48 @@
|
|||||||
<a><img src="https://img.shields.io/github/contributors/dw-0/kiauh"></a>
|
<a><img src="https://img.shields.io/github/contributors/dw-0/kiauh"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2 align="center">⚠️ Official Website Disclaimer ⚠️</h2>
|
||||||
|
|
||||||
|
**The only official source and website for KIAUH is this GitHub repository:
|
||||||
|
[https://github.com/dw-0/kiauh/](https://github.com/dw-0/kiauh/).**
|
||||||
|
|
||||||
|
The website **kiauh[.]com** is **not** an official website of this project and
|
||||||
|
is **not** affiliated with, endorsed by, or connected to KIAUH or its maintainer
|
||||||
|
[dw-0](https://github.com/dw-0) in any way. Its operator neither asked for
|
||||||
|
permission nor informed the maintainer. The maintainer has no control over, and
|
||||||
|
takes no responsibility for, its content, downloads, instructions, or any other
|
||||||
|
material offered there.
|
||||||
|
|
||||||
|
Please be aware of the following:
|
||||||
|
|
||||||
|
* **Do not download, open, or run anything from kiauh[.]com.** Its start page
|
||||||
|
offers a ZIP file for download. Under no circumstances should you download it,
|
||||||
|
open it, or execute any code from it. Its contents are unverified and may be
|
||||||
|
malicious.
|
||||||
|
* **Do not use the contact form on kiauh[.]com.** It does not send your message to
|
||||||
|
any official party of this project. Never submit the form or disclose personal
|
||||||
|
data there. This repository is the only official source and communication channel.
|
||||||
|
* **Do not let its appearance, name, or content mislead you.** It is not the project's website, regardless
|
||||||
|
of how it presents itself.
|
||||||
|
* **Do not trust any of the information.** Any statement on that site about KIAUH, its usage, its support, or its
|
||||||
|
licensing has no connection to the maintainer and may be inaccurate or
|
||||||
|
outdated.
|
||||||
|
|
||||||
|
Please download and install KIAUH from this repository only. Do not run scripts
|
||||||
|
or commands obtained from any other source without verifying them against this
|
||||||
|
repository first.
|
||||||
|
|
||||||
|
The KIAUH name and logo must not be used in a way that suggests an official
|
||||||
|
affiliation with or endorsement by this project.
|
||||||
|
|
||||||
|
If you come across websites or sources that present or suggest themselves as official KIAUH
|
||||||
|
channels, please report them in the
|
||||||
|
[GitHub Discussions](https://github.com/dw-0/kiauh/discussions).
|
||||||
|
|
||||||
|
This statement remains valid until explicitly revoked by the maintainer.
|
||||||
|
|
||||||
## 📄 使用说明
|
## 📄 使用说明
|
||||||
|
|
||||||
### 📋 系统要求
|
### 📋 系统要求
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class MainsailThemeInstallerExtension(BaseExtension):
|
|||||||
# noinspection PyMethodMayBeStatic
|
# noinspection PyMethodMayBeStatic
|
||||||
class MainsailThemeInstallMenu(BaseMenu):
|
class MainsailThemeInstallMenu(BaseMenu):
|
||||||
THEMES_URL: str = (
|
THEMES_URL: str = (
|
||||||
"https://raw.githubusercontent.com/mainsail-crew/gb-docs/main/_data/themes.csv"
|
"https://raw.githubusercontent.com/mainsail-crew/docs/zensical/_data/themes.csv"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, instances: List[Klipper]):
|
def __init__(self, instances: List[Klipper]):
|
||||||
@@ -94,8 +94,9 @@ class MainsailThemeInstallMenu(BaseMenu):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def set_options(self) -> None:
|
def set_options(self) -> None:
|
||||||
|
# Menu numbers start at 1 to match the theme IDs on the Mainsail docs page
|
||||||
self.options = {
|
self.options = {
|
||||||
f"{index}": Option(self.install_theme, opt_index=f"{index}")
|
f"{index + 1}": Option(self.install_theme, opt_index=f"{index}")
|
||||||
for index in range(len(self.themes))
|
for index in range(len(self.themes))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,11 +108,12 @@ class MainsailThemeInstallMenu(BaseMenu):
|
|||||||
f"""
|
f"""
|
||||||
╟───────────────────────────────────────────────────────╢
|
╟───────────────────────────────────────────────────────╢
|
||||||
║ {line1:<62} ║
|
║ {line1:<62} ║
|
||||||
║ https://docs.mainsail.xyz/theming/themes ║
|
║ https://docs.mainsail.xyz/features/custom- ║
|
||||||
|
║ themes/community-themes/ ║
|
||||||
╟───────────────────────────────────────────────────────╢
|
╟───────────────────────────────────────────────────────╢
|
||||||
"""
|
"""
|
||||||
)[1:]
|
)[1:]
|
||||||
for i, theme in enumerate(self.themes):
|
for i, theme in enumerate(self.themes, start=1):
|
||||||
j: str = f" {i}" if i < 10 else f"{i}"
|
j: str = f" {i}" if i < 10 else f"{i}"
|
||||||
row: str = f"{j}) [{theme.name}]"
|
row: str = f"{j}) [{theme.name}]"
|
||||||
menu += f"║ {row:<53} ║\n"
|
menu += f"║ {row:<53} ║\n"
|
||||||
@@ -123,12 +125,19 @@ class MainsailThemeInstallMenu(BaseMenu):
|
|||||||
themes: List[ThemeData] = []
|
themes: List[ThemeData] = []
|
||||||
content: str = response.read().decode()
|
content: str = response.read().decode()
|
||||||
csv_data: List[str] = content.splitlines()
|
csv_data: List[str] = content.splitlines()
|
||||||
fieldnames = ["name", "short_note", "author", "repo"]
|
# read columns by the csv header, so extra columns in the list
|
||||||
csv_reader = csv.DictReader(csv_data, fieldnames=fieldnames, delimiter=",")
|
# (e.g. "branch" and "preview", used by the docs page) are ignored
|
||||||
next(csv_reader) # skip the header of the csv file
|
csv_reader = csv.DictReader(csv_data, delimiter=",")
|
||||||
for row in csv_reader:
|
for row in csv_reader:
|
||||||
row: Dict[str, str] # type: ignore
|
row: Dict[str, str] # type: ignore
|
||||||
theme: ThemeData = ThemeData(**row)
|
if not row.get("author") or not row.get("repo"):
|
||||||
|
continue
|
||||||
|
theme: ThemeData = ThemeData(
|
||||||
|
name=row.get("name") or row["repo"],
|
||||||
|
short_note=row.get("short_note") or "",
|
||||||
|
author=row["author"],
|
||||||
|
repo=row["repo"],
|
||||||
|
)
|
||||||
themes.append(theme)
|
themes.append(theme)
|
||||||
|
|
||||||
return themes
|
return themes
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"maintained_by": "dw-0",
|
"maintained_by": "dw-0",
|
||||||
"display_name": "Mainsail Theme Installer",
|
"display_name": "Mainsail Theme Installer",
|
||||||
"description": ["Install Mainsail Themes maintained by the Mainsail community."],
|
"description": ["Install Mainsail Themes maintained by the Mainsail community."],
|
||||||
"website": "https://docs.mainsail.xyz/theming/themes",
|
"website": "https://docs.mainsail.xyz/features/custom-themes/community-themes/",
|
||||||
"updates": false
|
"updates": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,8 @@
|
|||||||
"maintained_by": "PEEKYPAUL",
|
"maintained_by": "PEEKYPAUL",
|
||||||
"display_name": "Moongate for Klipper",
|
"display_name": "Moongate for Klipper",
|
||||||
"description": [
|
"description": [
|
||||||
"Pair this printer with the Moongate Android app for secure remote",
|
"Pair this printer with the Moongate app on Android or iPhone for secure remote access and print monitoring.",
|
||||||
"access and print monitoring. Installs cloudflared, a Cloudflare",
|
"Installs cloudflared, a Cloudflare quick-tunnel and an EdDSA auth gate in front of Moonraker."
|
||||||
"quick-tunnel and an EdDSA auth gate in front of Moonraker."
|
|
||||||
],
|
],
|
||||||
"repo": "https://github.com/PEEKYPAUL/Moongate",
|
"repo": "https://github.com/PEEKYPAUL/Moongate",
|
||||||
"updates": true
|
"updates": true
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ class MoongateExtension(BaseExtension):
|
|||||||
"Moongate installed successfully!",
|
"Moongate installed successfully!",
|
||||||
"\n\n",
|
"\n\n",
|
||||||
"Next steps:",
|
"Next steps:",
|
||||||
"● Install the Moongate app on your Android device.",
|
"● Install the Moongate app on your phone (Google Play for "
|
||||||
|
"Android, the App Store for iPhone).",
|
||||||
(
|
(
|
||||||
"● In the app: Add printer > Direct (LAN/VPN), then run "
|
"● In the app: Add printer > Direct (LAN/VPN), then run "
|
||||||
"MOONGATE_PAIR in the Klipper console and scan the QR (or "
|
"MOONGATE_PAIR in the Klipper console and scan the QR (or "
|
||||||
@@ -224,8 +225,8 @@ class MoongateExtension(BaseExtension):
|
|||||||
Logger.print_dialog(
|
Logger.print_dialog(
|
||||||
DialogType.ATTENTION,
|
DialogType.ATTENTION,
|
||||||
[
|
[
|
||||||
"Moongate pairs this printer with the Moongate Android app for "
|
"Moongate pairs this printer with the Moongate app on Android or "
|
||||||
"secure remote access and print monitoring.",
|
"iPhone for secure remote access and print monitoring.",
|
||||||
"\n\n",
|
"\n\n",
|
||||||
"This is a heavier install than most extensions. It will:",
|
"This is a heavier install than most extensions. It will:",
|
||||||
"● clone the Moongate repo to ~/moongate",
|
"● clone the Moongate repo to ~/moongate",
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
# ======================================================================= #
|
||||||
|
# Copyright (C) 2020 - 2026 Dominik Willner <dev.dw-0@proton.me> #
|
||||||
|
# #
|
||||||
|
# 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 pytest
|
||||||
|
from extensions.mainsail_theme_installer.mainsail_theme_installer_extension import (
|
||||||
|
MainsailThemeInstallMenu,
|
||||||
|
ThemeData,
|
||||||
|
)
|
||||||
|
|
||||||
|
MODULE = "extensions.mainsail_theme_installer.mainsail_theme_installer_extension"
|
||||||
|
|
||||||
|
# current format of the list in mainsail-crew/docs
|
||||||
|
DOCS_CSV = (
|
||||||
|
"name,short_note,author,repo,branch,preview\n"
|
||||||
|
"Dracula,,steadyjaw,dracula-mainsail-theme,master,screenshot.jpg\n"
|
||||||
|
"Printables,(unofficial),8bitmcu,mainsail-printables,main,screenshot.jpg\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
# legacy format of the list in mainsail-crew/gb-docs
|
||||||
|
LEGACY_CSV = (
|
||||||
|
"name,short_note,author,repo\n"
|
||||||
|
"Dracula,,steadyjaw,dracula-mainsail-theme\n"
|
||||||
|
"Printables,(unofficial),8bitmcu,mainsail-printables\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
EXPECTED_THEMES = [
|
||||||
|
ThemeData("Dracula", "", "steadyjaw", "dracula-mainsail-theme"),
|
||||||
|
ThemeData("Printables", "(unofficial)", "8bitmcu", "mainsail-printables"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class _FakeResponse:
|
||||||
|
def __init__(self, body: str) -> None:
|
||||||
|
self._body = body.encode()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def read(self) -> bytes:
|
||||||
|
return self._body
|
||||||
|
|
||||||
|
|
||||||
|
def _patch_themes_csv(monkeypatch: pytest.MonkeyPatch, body: str) -> None:
|
||||||
|
class FakeUrlLib:
|
||||||
|
@staticmethod
|
||||||
|
def urlopen(url: str):
|
||||||
|
return _FakeResponse(body)
|
||||||
|
|
||||||
|
monkeypatch.setattr(f"{MODULE}.urllib.request", FakeUrlLib())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def menu(monkeypatch: pytest.MonkeyPatch) -> MainsailThemeInstallMenu:
|
||||||
|
_patch_themes_csv(monkeypatch, DOCS_CSV)
|
||||||
|
return MainsailThemeInstallMenu([])
|
||||||
|
|
||||||
|
|
||||||
|
class TestLoadThemes:
|
||||||
|
def test_parses_docs_format_and_ignores_extra_columns(
|
||||||
|
self, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
_patch_themes_csv(monkeypatch, DOCS_CSV)
|
||||||
|
assert MainsailThemeInstallMenu([]).themes == EXPECTED_THEMES
|
||||||
|
|
||||||
|
def test_parses_legacy_format(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
|
_patch_themes_csv(monkeypatch, LEGACY_CSV)
|
||||||
|
assert MainsailThemeInstallMenu([]).themes == EXPECTED_THEMES
|
||||||
|
|
||||||
|
def test_skips_blank_and_incomplete_rows(
|
||||||
|
self, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
_patch_themes_csv(monkeypatch, DOCS_CSV + "\n" + "Broken,,,,,\n")
|
||||||
|
assert MainsailThemeInstallMenu([]).themes == EXPECTED_THEMES
|
||||||
|
|
||||||
|
|
||||||
|
class TestThemeMenuNumbering:
|
||||||
|
def test_options_start_at_one_to_match_docs_ids(
|
||||||
|
self, menu: MainsailThemeInstallMenu
|
||||||
|
) -> None:
|
||||||
|
menu.set_options()
|
||||||
|
assert list(menu.options) == ["1", "2"]
|
||||||
|
assert menu.options["1"].opt_index == "0"
|
||||||
|
assert menu.options["2"].opt_index == "1"
|
||||||
|
|
||||||
|
def test_menu_lists_themes_from_one(
|
||||||
|
self, menu: MainsailThemeInstallMenu, capsys
|
||||||
|
) -> None:
|
||||||
|
menu.print_menu()
|
||||||
|
out = capsys.readouterr().out
|
||||||
|
assert " 1) [Dracula]" in out
|
||||||
|
assert " 2) [Printables]" in out
|
||||||
|
assert " 0) [" not in out
|
||||||
|
|
||||||
|
def test_menu_links_to_current_docs(
|
||||||
|
self, menu: MainsailThemeInstallMenu, capsys
|
||||||
|
) -> None:
|
||||||
|
menu.print_menu()
|
||||||
|
out = capsys.readouterr().out
|
||||||
|
# the url is too long for the menu box, so it is wrapped over two lines
|
||||||
|
assert "║ https://docs.mainsail.xyz/features/custom- ║" in out
|
||||||
|
assert "║ themes/community-themes/ ║" in out
|
||||||
|
assert "theming/themes" not in out
|
||||||
Reference in new issue
Block a user