summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorAAGaming <aa@mail.catvibers.me>2022-07-14 22:51:55 -0400
committerGitHub <noreply@github.com>2022-07-14 22:51:55 -0400
commit8c8cf180fad2ad6951ad7ce6b74e6c163fa01d18 (patch)
treedd051aaa7928867657c955cf2cad5143ca72f658 /backend
parent05d11cfff037734f7aa6b6ac8e701eacd9f38d60 (diff)
downloaddecky-loader-8c8cf180fad2ad6951ad7ce6b74e6c163fa01d18.tar.gz
decky-loader-8c8cf180fad2ad6951ad7ce6b74e6c163fa01d18.zip
Updater for decky-loader (#117)
* Add an updater in settings for decky-loader * add chmod * remove junk comments
Diffstat (limited to 'backend')
-rw-r--r--backend/main.py2
-rw-r--r--backend/updater.py113
2 files changed, 115 insertions, 0 deletions
diff --git a/backend/main.py b/backend/main.py
index 99e6c618..52e0ce06 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -27,6 +27,7 @@ from browser import PluginBrowser
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")
@@ -47,6 +48,7 @@ class PluginManager:
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)
diff --git a/backend/updater.py b/backend/updater.py
new file mode 100644
index 00000000..d7aed0d7
--- /dev/null
+++ b/backend/updater.py
@@ -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)