Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ init: ## Initialize project
@echo -e "3. Build your code with \`\033[0;36mmake build\033[0m\` or \`\033[0;36mmake docker-build\033[0m\` to build inside a docker container"
@echo -e "4. Deploy your plugin code to steamdeck with \`\033[0;36mmake deploy\033[0m\`"

update-frontend-lib: ## Update decky-frontend-lib
update-decky-ui: ## Update @decky/ui @decky/api
@echo "+ $@"
@pnpm update decky-frontend-lib --latest
@pnpm update @decky/ui --latest
@pnpm update @decky/api --latest
@pnpm update @decky/rollup --latest

download:
@echo "+ $@"
Expand Down
184 changes: 184 additions & 0 deletions decky.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
"""
This module exposes various constants and helpers useful for decky plugins.

* Plugin's settings and configurations should be stored under `DECKY_PLUGIN_SETTINGS_DIR`.
* Plugin's runtime data should be stored under `DECKY_PLUGIN_RUNTIME_DIR`.
* Plugin's persistent log files should be stored under `DECKY_PLUGIN_LOG_DIR`.

Avoid writing outside of `DECKY_HOME`, storing under the suggested paths is strongly recommended.

Some basic migration helpers are available: `migrate_any`, `migrate_settings`, `migrate_runtime`, `migrate_logs`.

A logging facility `logger` is available which writes to the recommended location.
"""

__version__ = '1.0.0'

import logging

from typing import Any

"""
Constants
"""

HOME: str
"""
The home directory of the effective user running the process.
Environment variable: `HOME`.
If `root` was specified in the plugin's flags it will be `/root` otherwise the user whose home decky resides in.
e.g.: `/home/deck`
"""

USER: str
"""
The effective username running the process.
Environment variable: `USER`.
It would be `root` if `root` was specified in the plugin's flags otherwise the user whose home decky resides in.
e.g.: `deck`
"""

DECKY_VERSION: str
"""
The version of the decky loader.
Environment variable: `DECKY_VERSION`.
e.g.: `v2.5.0-pre1`
"""

DECKY_USER: str
"""
The user whose home decky resides in.
Environment variable: `DECKY_USER`.
e.g.: `deck`
"""

DECKY_USER_HOME: str
"""
The home of the user where decky resides in.
Environment variable: `DECKY_USER_HOME`.
e.g.: `/home/deck`
"""

DECKY_HOME: str
"""
The root of the decky folder.
Environment variable: `DECKY_HOME`.
e.g.: `/home/deck/homebrew`
"""

DECKY_PLUGIN_SETTINGS_DIR: str
"""
The recommended path in which to store configuration files (created automatically).
Environment variable: `DECKY_PLUGIN_SETTINGS_DIR`.
e.g.: `/home/deck/homebrew/settings/decky-plugin-template`
"""

DECKY_PLUGIN_RUNTIME_DIR: str
"""
The recommended path in which to store runtime data (created automatically).
Environment variable: `DECKY_PLUGIN_RUNTIME_DIR`.
e.g.: `/home/deck/homebrew/data/decky-plugin-template`
"""

DECKY_PLUGIN_LOG_DIR: str
"""
The recommended path in which to store persistent logs (created automatically).
Environment variable: `DECKY_PLUGIN_LOG_DIR`.
e.g.: `/home/deck/homebrew/logs/decky-plugin-template`
"""

DECKY_PLUGIN_DIR: str
"""
The root of the plugin's directory.
Environment variable: `DECKY_PLUGIN_DIR`.
e.g.: `/home/deck/homebrew/plugins/decky-plugin-template`
"""

DECKY_PLUGIN_NAME: str
"""
The name of the plugin as specified in the 'plugin.json'.
Environment variable: `DECKY_PLUGIN_NAME`.
e.g.: `Example Plugin`
"""

DECKY_PLUGIN_VERSION: str
"""
The version of the plugin as specified in the 'package.json'.
Environment variable: `DECKY_PLUGIN_VERSION`.
e.g.: `0.0.1`
"""

DECKY_PLUGIN_AUTHOR: str
"""
The author of the plugin as specified in the 'plugin.json'.
Environment variable: `DECKY_PLUGIN_AUTHOR`.
e.g.: `John Doe`
"""

DECKY_PLUGIN_LOG: str
"""
The path to the plugin's main logfile.
Environment variable: `DECKY_PLUGIN_LOG`.
e.g.: `/home/deck/homebrew/logs/decky-plugin-template/plugin.log`
"""

"""
Migration helpers
"""


def migrate_any(target_dir: str, *files_or_directories: str) -> dict[str, str]:
"""
Migrate files and directories to a new location and remove old locations.
Specified files will be migrated to `target_dir`.
Specified directories will have their contents recursively migrated to `target_dir`.

Returns the mapping of old -> new location.
"""


def migrate_settings(*files_or_directories: str) -> dict[str, str]:
"""
Migrate files and directories relating to plugin settings to the recommended location and remove old locations.
Specified files will be migrated to `DECKY_PLUGIN_SETTINGS_DIR`.
Specified directories will have their contents recursively migrated to `DECKY_PLUGIN_SETTINGS_DIR`.

Returns the mapping of old -> new location.
"""


def migrate_runtime(*files_or_directories: str) -> dict[str, str]:
"""
Migrate files and directories relating to plugin runtime data to the recommended location and remove old locations
Specified files will be migrated to `DECKY_PLUGIN_RUNTIME_DIR`.
Specified directories will have their contents recursively migrated to `DECKY_PLUGIN_RUNTIME_DIR`.

Returns the mapping of old -> new location.
"""


def migrate_logs(*files_or_directories: str) -> dict[str, str]:
"""
Migrate files and directories relating to plugin logs to the recommended location and remove old locations.
Specified files will be migrated to `DECKY_PLUGIN_LOG_DIR`.
Specified directories will have their contents recursively migrated to `DECKY_PLUGIN_LOG_DIR`.

Returns the mapping of old -> new location.
"""


"""
Logging
"""

logger: logging.Logger
"""The main plugin logger writing to `DECKY_PLUGIN_LOG`."""

"""
Event handling
"""
# TODO better docstring im lazy
async def emit(event: str, *args: Any) -> None:
"""
Send an event to the frontend.
"""
9 changes: 4 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import logging
import subprocess
import asyncio
import os
from config import logger, setup_logger
import update
import decky_plugin
import decky
import utils

class Plugin:
Expand All @@ -16,10 +15,10 @@ async def _main(self):
utils.write_font_config()

logger.info("Start Tomoon.")
os.system('chmod -R a+x ' + decky_plugin.DECKY_PLUGIN_DIR)
os.system('chmod -R a+x ' + decky.DECKY_PLUGIN_DIR)
# 切换到工作目录
os.chdir(decky_plugin.DECKY_PLUGIN_DIR)
self.backend_proc = subprocess.Popen([decky_plugin.DECKY_PLUGIN_DIR + "/bin/tomoon"])
os.chdir(decky.DECKY_PLUGIN_DIR)
self.backend_proc = subprocess.Popen([decky.DECKY_PLUGIN_DIR + "/bin/tomoon"])
while True:
await asyncio.sleep(1)

Expand Down
34 changes: 19 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "tomoon",
"version": "0.2.5",
"description": "SteamOS Network Tools Box.",
"type": "module",
"scripts": {
"preinstall": "cp -r usdpl src/",
"build": "shx rm -rf dist && rollup -c",
Expand All @@ -26,24 +27,27 @@
},
"homepage": "https://github.com/SteamDeckHomebrew/decky-plugin-template#readme",
"devDependencies": {
"@rollup/plugin-commonjs": "^21.1.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.5.0",
"@types/react": "16.14.0",
"@types/webpack": "^5.28.0",
"decky-frontend-lib": "^3.24.5",
"rollup": "^2.79.1",
"rollup-plugin-import-assets": "^1.1.1",
"@decky/rollup": "^1.0.1",
"@decky/ui": "^4.9.1",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-replace": "^6.0.2",
"@rollup/plugin-typescript": "^12.1.2",
"@types/react": "19.0.8",
"@types/react-dom": "^19.0.3",
"@types/webpack": "^5.28.5",
"rollup": "^4.32.1",
"shx": "^0.3.4",
"tslib": "^2.4.0",
"typescript": "^4.8.4"
"tslib": "^2.8.1",
"typescript": "^5.7.3"
},
"dependencies": {
"axios": "^1.2.2",
"qrcode.react": "^3.1.0",
"react-icons": "^4.6.0",
"@decky/api": "^1.1.2",
"axios": "^1.7.9",
"qrcode.react": "^4.2.0",
"react": "^19.0.0",
"react-icons": "^5.4.0",
"usdpl-front": "file:src/usdpl"
},
"pnpm": {
Expand Down
1 change: 1 addition & 0 deletions plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "To Moon",
"author": "Sayo Kurisu",
"flags": ["root"],
"api_version": 1,
"publish": {
"tags": ["root", "network"],
"description": "SteamOS Network Tools Box.",
Expand Down
17 changes: 9 additions & 8 deletions py_modules/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import ssl
import stat
import subprocess

import urllib.request

from config import logger, API_URL
import decky_plugin
import decky
from config import API_URL, logger
from utils import get_env


def recursive_chmod(path, perms):
Expand All @@ -23,7 +23,7 @@ def update_latest():
downloaded_filepath = download_latest_build()

if os.path.exists(downloaded_filepath):
plugin_dir = decky_plugin.DECKY_PLUGIN_DIR
plugin_dir = decky.DECKY_PLUGIN_DIR

try:
logger.info(f"removing old plugin from {plugin_dir}")
Expand All @@ -40,14 +40,14 @@ def update_latest():
# extract files to decky plugins dir
shutil.unpack_archive(
downloaded_filepath,
f"{decky_plugin.DECKY_USER_HOME}/homebrew/plugins",
f"{decky.DECKY_USER_HOME}/homebrew/plugins",
format="zip",
)

# cleanup downloaded files
os.remove(downloaded_filepath)
except Exception as e:
decky_plugin.logger.error(f"error during ota file extraction {e}")
logger.error(f"error during ota file extraction {e}")

logger.info("restarting plugin_loader.service")
cmd = "systemctl restart plugin_loader.service"
Expand All @@ -58,6 +58,7 @@ def update_latest():
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=get_env(),
)
logger.info(result.stdout)
return result
Expand All @@ -76,7 +77,7 @@ def download_latest_build():

logger.info(download_url)

file_path = f"/tmp/{decky_plugin.DECKY_PLUGIN_NAME}.zip"
file_path = f"/tmp/{decky.DECKY_PLUGIN_NAME}.zip"

with urllib.request.urlopen(download_url, context=gcontext) as response, open(
file_path, "wb"
Expand All @@ -88,7 +89,7 @@ def download_latest_build():


def get_version():
return f"{decky_plugin.DECKY_PLUGIN_VERSION}"
return f"{decky.DECKY_PLUGIN_VERSION}"


def get_latest_version():
Expand Down
13 changes: 10 additions & 3 deletions py_modules/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import decky_plugin

import decky
from config import logger

FONT_CONFIG = """<?xml version="1.0"?>
Expand Down Expand Up @@ -32,7 +33,7 @@
</alias>
</fontconfig>
"""
FONT_CONF_DIR = f"{decky_plugin.DECKY_USER_HOME}/.config/fontconfig"
FONT_CONF_DIR = f"{decky.DECKY_USER_HOME}/.config/fontconfig"
FONT_CONF_D_DIR = f"{FONT_CONF_DIR}/conf.d"
FONT_CONF_FILE = f"{FONT_CONF_D_DIR}/76-noto-cjk.conf"

Expand All @@ -59,7 +60,7 @@ def write_font_config():
f.write(FONT_CONFIG)
f.close()

user = decky_plugin.DECKY_USER
user = decky.DECKY_USER
# change fontconfig owner
os.system(f"chown -R {user}:{user} {FONT_CONF_DIR}")

Expand All @@ -73,3 +74,9 @@ def remove_font_config():
if "<!-- ToMoon -->" in content:
logger.info(f"Removing fontconfig file: {FONT_CONF_FILE}")
os.remove(FONT_CONF_FILE)


def get_env():
env = os.environ.copy()
env["LD_LIBRARY_PATH"] = ""
return env
Loading