Skip to content

Commit

Permalink
Include deck user application files in the list (#7)
Browse files Browse the repository at this point in the history
* Include deck user application files in the list

* Fix parsing of desktop files that are indented

* Small optimization to the dedup process of the apps' names.

* Use env var provided by decky to dynamically search the user's desktop files
  • Loading branch information
JoaoCostaIFG authored Apr 5, 2023
1 parent 0b2eb18 commit 8ca4213
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 46 deletions.
82 changes: 57 additions & 25 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import os, json, base64, ssl, certifi
from pathlib import Path
from json import dumps as jsonDumps
from itertools import chain

import decky_plugin

Expand All @@ -8,70 +11,99 @@
from urllib.request import urlopen, Request


confdir = os.environ['DECKY_PLUGIN_SETTINGS_DIR']
confdir = os.environ["DECKY_PLUGIN_SETTINGS_DIR"]

send_buffer = []


def split_string(string):
return [string[i:i+1024*60] for i in range(0, len(string), 1024*60)] # every 60KB
return [
string[i : i + 1024 * 60] for i in range(0, len(string), 1024 * 60)
] # every 60KB


class Plugin:
async def get_flatpaks(self):
proc = Popen('flatpak list -d --app | awk \'BEGIN {FS="\\t"} {print "{\\"name\\":\\""$1"\\",\\"exec\\":\\"/usr/bin/flatpak run "$3"\\"},"}\\\'', stdout=PIPE, stderr=None, shell=True)
proc = Popen(
'flatpak list --app --columns="name,application" | awk \'BEGIN {FS="\\t"} {print "{\\"name\\":\\""$1"\\",\\"exec\\":\\"/usr/bin/flatpak run "$2"\\"},"}\\\'',
stdout=PIPE,
stderr=None,
shell=True,
)
packages = proc.communicate()[0]
packages = packages.decode("utf-8")
packages = packages[:-2]
return "["+packages+"]"
return "[" + packages + "]"

async def get_desktops(self):
#Really REALLY scuffed way of reading desktop files...
proc = Popen('ls -l /usr/share/applications | gawk \'{path="/usr/share/applications/"$9; while(( getline line<path) > 0) {if(line ~ /^Exec=/ && exec=="") { exec=substr(line,6);}; if(line ~ /^Name=/ && name=="") { name=substr(line,6); }; if(exec!="" && name!="") { break }};gsub(/"/,"\\\\\\"",exec);print("{\\"name\\":\\""name"\\",\\"exec\\":\\""exec"\\"},");exec="";name=""}\'', stdout=PIPE, stderr=None, shell=True)

packages = proc.communicate()[0]
packages = packages.decode("utf-8")
packages = packages[:-2]
return "["+packages+"]"
packages = []
for desktopFile in chain(
Path("/usr/share/applications").glob("*.desktop"),
Path(f"{decky_plugin.DECKY_USER_HOME}/.local/share/applications/").glob("*.desktop"),
):
if not desktopFile.is_file():
continue
with open(desktopFile) as f:
package = {}
foundName = foundExec = False
for line in f:
line = line.strip()
if line.startswith("Name="):
foundName = True
package["name"] = line[5:]
elif line.startswith("Exec="):
foundExec = True
package["exec"] = line[5:]
if foundName and foundExec:
packages.append(package)
break

return jsonDumps(packages)

async def get_config(self):
with open(os.path.join(confdir,"config.json"), "r") as f:
with open(os.path.join(confdir, "config.json"), "r") as f:
return json.load(f)

async def set_config_value(self, key, value):
config = json.load(open(os.path.join(confdir,"config.json")))
config = json.load(open(os.path.join(confdir, "config.json")))
config[key] = value
with open(os.path.join(confdir,"config.json"), "w") as f:
with open(os.path.join(confdir, "config.json"), "w") as f:
json.dump(config, f)

return config

async def get_id(self):
with open(os.path.join(confdir,"scid.txt"), "r") as sc:
with open(os.path.join(confdir, "scid.txt"), "r") as sc:
id = sc.read()
try:
id = int(id)
return id
except ValueError:
return -1

async def set_id(self, id):
with open(os.path.join(confdir,"scid.txt"), "w") as sc:
with open(os.path.join(confdir, "scid.txt"), "w") as sc:
sc.write(str(id))

async def get_req_imgb64(self, url):
global send_buffer
if(len(send_buffer) != 0):
if len(send_buffer) != 0:
return

req = Request(url)

req.add_header("User-Agent", "SDH-QuickLaunch")

try:
content = urlopen(req, context=ssl.create_default_context(cafile=certifi.where())).read()
img = base64.b64encode(content).decode('ascii')
content = urlopen(
req, context=ssl.create_default_context(cafile=certifi.where())
).read()
img = base64.b64encode(content).decode("ascii")
send_buffer = split_string(img)
new_chunk = send_buffer.pop(0)
return {"data": new_chunk, "is_last": len(send_buffer) == 0}
return {"data": new_chunk, "is_last": len(send_buffer) == 0}
except HTTPError:
decky_plugin.logger.error("HTTPError while requesting "+url)
decky_plugin.logger.error("HTTPError while requesting " + url)
pass

async def receive_next_chunk(self):
Expand All @@ -81,19 +113,19 @@ async def receive_next_chunk(self):

async def _main(self):
decky_plugin.logger.info("Loading plugin")

try:
os.mkdir(confdir)
except FileExistsError:
pass

try:
sc = open(os.path.join(confdir,"scid.txt"), "x")
sc = open(os.path.join(confdir, "scid.txt"), "x")
sc.close()
except FileExistsError:
pass
try:
sc = open(os.path.join(confdir,"config.json"), "x")
sc = open(os.path.join(confdir, "config.json"), "x")
sc.write("{}")
sc.close()
except FileExistsError:
Expand Down
30 changes: 9 additions & 21 deletions src/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,18 @@ export const gameIDFromAppID = (appid: number) => {
}

export async function fetchApps(sAPI: ServerAPI, type: string): Promise<App[]> {
const result = await sAPI.callPluginMethod<any, string>(`get_${type}`, {});
const result = await sAPI.callPluginMethod<any, string>(`get_${type}`, {});
let apps: App[] = []
if(result.success) {
//...i guess it works
let apps_withDuplicates: App[] = JSON.parse(result.result);

let names: String[] = []
for(let app of apps_withDuplicates) {
if(!names.includes(app.name) && app.name !== "") {
names.push(app.name)
}
}
for(let name of names) {
let app = apps_withDuplicates.find(app => app.name === name);
if(app !== undefined) {
apps.push(app);
if (result.success) {
let appsDict = new Map<string, App>();
for (let app of JSON.parse(result.result)) {
if (app.name !== "" && !appsDict.has(app.name)) {
appsDict.set(app.name, app);
}
}

apps.sort((a, b) => {
if(a.name < b.name) { return -1; }
if(a.name > b.name) { return 1; }
return 0;
})
// map values to list
apps = Array.from(appsDict.values()).sort((a, b) => a.name.localeCompare(b.name));
}

return apps
Expand Down Expand Up @@ -78,4 +66,4 @@ export const getShortcutID = async (sAPI: ServerAPI) => {
}

return -1
}
}

0 comments on commit 8ca4213

Please sign in to comment.