Skip to content

Commit 2b06872

Browse files
authored
Merge pull request #21 from GedasFX/feature/19
Feature/19
2 parents 6fb1e42 + c29d503 commit 2b06872

File tree

5 files changed

+46
-30
lines changed

5 files changed

+46
-30
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Support: **[SteamDeckHomebrew Discord](https://discord.gg/ZU74G2NJzk)**.
1717
* Ability to back up files automatically after a game is closed.
1818
* File counter, which estimates the number of files a sync path would pick up. Prevents accidental backing up of the entire steam deck.
1919
* Advanced filtering, allowing users to set up custom filtering rules with includes and excludes.
20+
* Ability to customize destination folder name (found in `plugin.properties` config).
2021

2122
**IMPORTANT!** This plugin does not support bidirectional sync. In other words, this plugin is not intended for use cases to sync saves between devices, but rather just to keep your game progress safe in case of data loss.
2223

main.py

+38-23
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def _regenerate_filter_file():
5454
f.write("# If you are editing this file manually, make sure to not use the UI file picker, as the saves done there will overwrite.\n")
5555
f.write("# Examples: https://rclone.org/filtering/#examples\n")
5656
f.write("\n")
57-
57+
5858
for exclude in excludes:
5959
f.write(f"- {exclude}")
6060
f.write("\n")
@@ -63,6 +63,30 @@ def _regenerate_filter_file():
6363
f.write("\n")
6464
f.write("- **\n")
6565

66+
67+
def _get_config():
68+
with open(cfg_property_file) as f:
69+
lines = f.readlines()
70+
lines = list(map(lambda x: x.strip().split('='), lines))
71+
logger.debug("config %s", lines)
72+
return lines
73+
74+
def _set_config(key: str, value: str):
75+
with open(cfg_property_file, "r") as f:
76+
lines = f.readlines()
77+
78+
with open(cfg_property_file, "w") as f:
79+
found = False
80+
for line in lines:
81+
if line.startswith(key + '='):
82+
f.write(f"{key}={value}\n")
83+
found = True
84+
else:
85+
f.write(line)
86+
87+
if not found:
88+
f.write(f"{key}={value}\n")
89+
6690
class Plugin:
6791
current_spawn = None
6892
current_sync = None
@@ -104,8 +128,11 @@ async def get_backend_type(self):
104128

105129
async def sync_now(self):
106130
logger.debug("Executing: sync_now()")
107-
logger.debug("Running command: %s copy --filter-from %s / backend:decky-cloud-save --copy-links", rclone_bin, cfg_syncpath_filter_file)
108-
self.current_sync = await asyncio.subprocess.create_subprocess_exec(rclone_bin, *["copy", "--filter-from", cfg_syncpath_filter_file, "/", "backend:decky-cloud-save", "--copy-links"])
131+
132+
destination_path = next((x[1] for x in _get_config() if x[0] == "destination_directory"), "decky-cloud-save")
133+
logger.debug("Running command: %s copy --filter-from %s / backend:%s --copy-links", rclone_bin, cfg_syncpath_filter_file, destination_path)
134+
135+
self.current_sync = await asyncio.subprocess.create_subprocess_exec(rclone_bin, *["copy", "--filter-from", cfg_syncpath_filter_file, "/", f"backend:{destination_path}", "--copy-links"])
109136

110137
async def sync_now_probe(self):
111138
logger.debug("Executing: sync_now_probe()")
@@ -186,29 +213,11 @@ async def remove_syncpath(self, path: str, file: str):
186213

187214
async def get_config(self):
188215
logger.debug("Executing: get_config()")
189-
with open(cfg_property_file) as f:
190-
lines = f.readlines()
191-
lines = list(map(lambda x: x.strip().split('='), lines))
192-
logger.debug("config %s", lines)
193-
return lines
216+
return _get_config()
194217

195218
async def set_config(self, key: str, value: str):
196219
logger.debug("Executing: set_config(%s, %s)", key, value)
197-
with open(cfg_property_file, "r") as f:
198-
lines = f.readlines()
199-
200-
with open(cfg_property_file, "w") as f:
201-
found = False
202-
for line in lines:
203-
if line.startswith(key + '='):
204-
f.write(f"{key}={value}\n")
205-
found = True
206-
else:
207-
f.write(line)
208-
209-
if not found:
210-
f.write(f"{key}={value}\n")
211-
220+
_set_config(key, value)
212221

213222
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
214223

@@ -228,6 +237,12 @@ async def _main(self):
228237
if not cfg_property_file.is_file():
229238
cfg_property_file.touch()
230239

240+
# Prepopulate config
241+
config = _get_config()
242+
logger.warn(config)
243+
if not any(e[0] == "destination_directory" for e in config):
244+
_set_config("destination_directory", "decky-cloud-save")
245+
231246
# Function called first during the unload process, utilize this to handle your plugin being removed
232247
async def _unload(self):
233248
await _kill_previous_spawn(self.current_spawn) # Kills only if exists

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "decky-cloud-save",
3-
"version": "1.2.2",
3+
"version": "1.3.0",
44
"description": "Manage cloud saves for games that do not support it in [current year].",
55
"scripts": {
66
"build": "shx rm -rf dist && rollup -c",
@@ -42,7 +42,7 @@
4242
"typescript": "^4.9.5"
4343
},
4444
"dependencies": {
45-
"decky-frontend-lib": "^3.20.7",
45+
"decky-frontend-lib": "^3.21.2",
4646
"react-icons": "^4.8.0"
4747
},
4848
"pnpm": {

pnpm-lock.yaml

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/apiClient.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function syncNow(): Promise<void> {
2727
body = `Sync completed in ${(new Date().getTime() - start.getTime()) / 1000}s.`;
2828
break;
2929
default:
30-
body = `Sync failed. Check journalctl for errors.`;
30+
body = `Sync failed. Run journalctl -u plugin_loader.service to see the errors.`;
3131
break;
3232
}
3333

0 commit comments

Comments
 (0)