mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 05:02:50 +02:00
Dropping a game's .zip, folder or .exe on Send to Frame now adds it to the headset's Steam library through Valve's SteamOS Devkit title path, with the runtime picked from the program's header: Windows PE -> Proton Experimental (steam_play=1), aarch64 ELF -> SteamLinuxRuntime_4-arm64, x86-64 ELF -> SteamLinuxRuntime_4 (through FEX). Other architectures are refused. - frame/devkit-utils: Valve's devkit-utils vendored unmodified (MIT, steamos-devkit v0.20260925.1), synced to ~/devkit-utils by stamp, bundled in the app and compiled in CI. - ui/frame_titles.py: inspect (safe unzip, ELF/PE classification, launch target ranking), install(path, name=None, exe=None, runtime=None, progress=None), list, launch, remove, plus a CLI. - ui/server.py: /api/titles (inspect/install/discard/launch/remove), /api/titles/job progress, and an upload mode 'title'. - ui/index.html: confirm dialog (name, launch target, runtime), install progress, and a Sideloaded titles list with Launch and Remove. The app's preload passes a dropped folder's path. - tests and docs/sideloading.md. Device-side behaviour is inferred from Valve's source; the headset was offline, so none of it has been checked on a Frame yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
49 lines
1.5 KiB
Python
Executable File
49 lines
1.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import os
|
|
import logging
|
|
import argparse
|
|
import tempfile
|
|
import urllib.parse
|
|
import re
|
|
|
|
import devkit_utils
|
|
|
|
logging.basicConfig(format='%(message)s', level=logging.DEBUG)
|
|
logger = logging.getLogger()
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('command')
|
|
parser.add_argument('args', nargs='*')
|
|
conf = parser.parse_args()
|
|
|
|
try:
|
|
devkit_utils.validate_steam_client()
|
|
except devkit_utils.SteamClientNotRunningException as e:
|
|
logger.error(repr(e))
|
|
sys.exit(-1)
|
|
else:
|
|
with tempfile.TemporaryDirectory(prefix='steam-devkit-rpc') as tempdir:
|
|
response = os.path.join(tempdir, 'steam-devkit-rpc')
|
|
parms = {
|
|
'response' : response,
|
|
}
|
|
for arg in conf.args:
|
|
(k, v) = re.split('=', arg)
|
|
parms[k] = v
|
|
cmd = f'{conf.command}/?{urllib.parse.urlencode(parms)}'
|
|
devkit_utils.execute_steam_client_command(cmd)
|
|
try:
|
|
with devkit_utils.wait_on_file_response(response) as success_response:
|
|
logger.info('success')
|
|
sys.stdout.write(success_response)
|
|
sys.exit(0)
|
|
except devkit_utils.SteamResponse_Timeout:
|
|
logger.error('timeout')
|
|
except devkit_utils.SteamResponse_Error as e:
|
|
logger.error('failed')
|
|
sys.stdout.write(e.error_response)
|
|
sys.exit(-1)
|