Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updater for decky-loader #117

Merged
merged 3 commits into from
Jul 15, 2022
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
2 changes: 2 additions & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from injector import inject_to_tab, tab_has_global_var
from loader import Loader
from utilities import Utilities
from updater import Updater

logger = getLogger("Main")

Expand All @@ -47,6 +48,7 @@ def __init__(self) -> None:
self.plugin_loader = Loader(self.web_app, CONFIG["plugin_path"], self.loop, CONFIG["live_reload"])
self.plugin_browser = PluginBrowser(CONFIG["plugin_path"], self.web_app)
self.utilities = Utilities(self)
self.updater = Updater(self)

jinja_setup(self.web_app)
self.web_app.on_startup.append(self.inject_javascript)
Expand Down
113 changes: 113 additions & 0 deletions backend/updater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import uuid
from logging import getLogger
from json.decoder import JSONDecodeError

from asyncio import sleep

from aiohttp import ClientSession, web

from injector import inject_to_tab, get_tab

from os import getcwd, path

from subprocess import call

import helpers

logger = getLogger("Updater")

class Updater:
def __init__(self, context) -> None:
self.context = context
self.updater_methods = {
"get_version": self.get_version,
"do_update": self.do_update,
"do_restart": self.do_restart
}
self.remoteVer = None
try:
with open(path.join(getcwd(), ".loader.version"), 'r') as version_file:
self.localVer = version_file.readline().replace("\n", "")
except:
self.localVer = False

if context:
context.web_app.add_routes([
web.post("/updater/{method_name}", self._handle_server_method_call)
])
context.loop.create_task(self.version_reloader())

async def _handle_server_method_call(self, request):
method_name = request.match_info["method_name"]
try:
args = await request.json()
except JSONDecodeError:
args = {}
res = {}
try:
r = await self.updater_methods[method_name](**args)
res["result"] = r
res["success"] = True
except Exception as e:
res["result"] = str(e)
res["success"] = False
return web.json_response(res)

async def get_version(self):
if self.localVer:
return {
"current": self.localVer,
"remote": self.remoteVer,
"updatable": self.remoteVer != None
}
else:
return {"current": "unknown", "updatable": False}

async def version_reloader(self):
while True:
try:
async with ClientSession() as web:
async with web.request("GET", "https://api.github.com/repos/SteamDeckHomebrew/decky-loader/releases", ssl=helpers.get_ssl_context()) as res:
remoteVersions = await res.json()
self.remoteVer = next(filter(lambda ver: ver["prerelease"] and ver["tag_name"].startswith("v") and ver["tag_name"].endswith("-pre"), remoteVersions), None)
logger.info("Updated remote version information")
except:
pass
await sleep(60 * 60) # 1 hour

async def do_update(self):
version = self.remoteVer["tag_name"]
#TODO don't hardcode this
download_url = self.remoteVer["assets"][0]["browser_download_url"]

tab = await get_tab("SP")
await tab.open_websocket()
async with ClientSession() as web:
async with web.request("GET", download_url, ssl=helpers.get_ssl_context(), allow_redirects=True) as res:
total = int(res.headers.get('content-length', 0))

with open(path.join(getcwd(), "PluginLoader"), "wb") as out:
progress = 0
raw = 0
async for c in res.content.iter_chunked(512):
out.write(c)
raw += len(c)
new_progress = round((raw / total) * 100)
if progress != new_progress:
if new_progress - progress>= 2:
self.context.loop.create_task(tab.evaluate_js(f"window.DeckyUpdater.updateProgress({progress})", False, False))
progress = new_progress

with open(path.join(getcwd(), ".loader.version"), "w") as out:
out.write(version)

call(['chmod', '+x', path.join(getcwd(), "PluginLoader")])

logger.info("Updated loader installation.")
await tab.evaluate_js("window.DeckyUpdater.finish()", False, False)
await tab.client.close()

async def do_restart(self):
call(["systemctl", "daemon-reload"])
call(["systemctl", "restart", "plugin_loader"])
exit(0)
12 changes: 8 additions & 4 deletions dist/install_prerelease.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ sudo -u deck mkdir -p ${HOMEBREW_FOLDER}/services
sudo -u deck mkdir -p ${HOMEBREW_FOLDER}/plugins

# Download latest release and install it
DOWNLOADURL="$(curl -s 'https://api.github.com/repos/SteamDeckHomebrew/decky-loader/releases' | jq -r "first(.[] | select(.prerelease == "true"))" | jq -r ".assets[].browser_download_url")"
RELEASES="$(curl -s 'https://api.github.com/repos/SteamDeckHomebrew/decky-loader/releases')"
RELEASE="$($RELEASES | jq -r "first(.[] | select(.prerelease == "true"))")"
VERSION="$($RELEASE | jq -r ".tag_name")"
DOWNLOADURL="$($RELEASE | jq -r ".assets[].browser_download_url")"
# printf "DOWNLOADURL=$DOWNLOADURL\n"
curl -L $DOWNLOADURL --output ${HOMEBREW_FOLDER}/services/PluginLoader
chmod +x ${HOMEBREW_FOLDER}/services/PluginLoader
echo $VERSION > ${HOMEBREW_FOLDER}/services/.loader.version

systemctl --user stop plugin_loader 2> /dev/null
systemctl --user disable plugin_loader 2> /dev/null
Expand All @@ -30,9 +34,9 @@ Description=SteamDeck Plugin Loader
Type=simple
User=root
Restart=always
ExecStart=/home/deck/homebrew/services/PluginLoader
WorkingDirectory=/home/deck/homebrew/services
Environment=PLUGIN_PATH=/home/deck/homebrew/plugins
ExecStart=${HOMEBREW_FOLDER}/services/PluginLoader
WorkingDirectory=${HOMEBREW_FOLDER}/services
Environment=PLUGIN_PATH=${HOMEBREW_FOLDER}/plugins
Environment=LOG_LEVEL=DEBUG
[Install]
WantedBy=multi-user.target
Expand Down
4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"prettier-plugin-import-sort": "^0.0.7",
"react": "16.14.0",
"react-dom": "16.14.0",
"rollup": "^2.75.7",
"rollup": "^2.76.0",
"tslib": "^2.4.0",
"typescript": "^4.7.4"
},
Expand All @@ -37,7 +37,7 @@
}
},
"dependencies": {
"decky-frontend-lib": "^1.0.2",
"decky-frontend-lib": "^1.2.1",
"react-icons": "^4.4.0"
}
}
Loading