flood-for-transmission
flood-for-transmission copied to clipboard
Add support for exporting and importing UI configuration
There is quite a bit of config stored in the browser now. And @realivanjx suggested here to add support for exporting and importing that configuration somehow.
what are config (non server config) that are stored in the browser besides the common paths? i believe currently it is everything under the User Interface menu?
just to keep it simple i think it is good to store everything into a .json
file for export/import. when an export button is clicked just merge the localstorage settings into a single json object then convert to json string and then trigger a browser download dialog somehow? importing can simply be a button that open file browser dialog like the ones under Add Torrents by file. this way #427 can be mitigated while waiting for a fix.
if i am not mistaken the download thing can be done with window.URL.createObjectURL
as explained here
what are config (non server config) that are stored in the browser besides the common paths? i believe currently it is everything under the User Interface menu?
Enabled and disabled columns, their width and order are also stored in LocalStorage. So that can also be part of the export.
Hi and thanks for this great UI, I'm using it with transmission-openvpn as a docker container and I'd like to know if the exported json file could be mounted as a volume in docker so it could be easy to store these configs on the server. I'm using Flood on different browsers (mobile and desktop) and it's a PITA to configure all.
@niawag thanks for your input!
I don't think that will be possible since the docker container won't be accessible from the browser, where the data is stored, and the browser won't be accessible from the docker container. However, if you know of some way to write to localStorage from a docker container, I'm all ears! :D
If support should be added for such a case we would have to add a feature into Transmission Daemon to support loading some UI config file from the file system. Otherwise the UI is completely blind to what is present in the OS.
edit: that's actually not entirely true! 🤔 I think Transmission serves all files within a folder, so the UI can make a request to a file on the file system and read from there. Writing could perhaps be done via the FileSystem API.
That would an interesting thing to attempt at least, but I'm not sure if it will work! :D
@johman10 thanks for your detailled answer! I'm not a js connoisseur so I asked! I thought that what is done here https://github.com/vasyl-bhd/flood-for-transmission/commit/aef7e0b24d89f705d9287700dafe032da200331e#diff-4b049ea196f984c5efdff949c671572127f627d6a5addaf069f19f5924b1cc8cL8-R13 could be added from a file instead of hardcoded. Maybe with something like this: https://stackoverflow.com/questions/19706046/how-to-read-an-external-local-json-file-in-javascript (but, as I said, I'm no js expert...)
@niawag you're right something like that could be done as well! An interesting suggestion to also consider while implementing this.
In general I would want to make this quite diverse though, not to force the user to deal with the file system etc, but rather to allow at least some kind of UI to export and import the data. However that doesn't take away the option to also support a file system approach.
I think my mind is docker-oriented now, too much playing with it ! In any case, if you need some testing I'll be glad to help!
I'm using it with transmission-openvpn as a docker container and I'd like to know if the exported json file could be mounted as a volume in docker so it could be easy to store these configs on the server.
@niawag same, this is my workaround
#!/bin/bash
# save user interface settings in flood
# type "localStorage" into console, right click and copy object
# paste object below into "const obj"
# https://haugene.github.io/docker-transmission-openvpn/config-options/#custom_scripts
# volume /path/transmission/scripts:/scripts
# chmod +x scripts/transmission-pre-start.sh
python3 << EOF
PATH = "/opt/transmission-ui/flood-for-transmission/index.html"
SCRIPT = r"""
<script id="inject">
const obj = {
"tableHeaderConfig": "false",
"darkMode": "enabled",
"paths": "[]",
"timeConfig": "true",
"switchSpeedColors": "false",
"ui-columns": "[{\"id\":13,\"enabled\":true,\"width\":369},{\"id\":27,\"enabled\":true,\"width\":64},{\"id\":15,\"enabled\":true,\"width\":263},{\"id\":9,\"enabled\":true,\"width\":84},{\"id\":6,\"enabled\":true,\"width\":85},{\"id\":22,\"enabled\":true,\"width\":89},{\"id\":10,\"enabled\":true,\"width\":91},{\"id\":1,\"enabled\":true,\"width\":135},{\"id\":7,\"enabled\":false,\"width\":100},{\"id\":23,\"enabled\":false,\"width\":100},{\"id\":14,\"enabled\":false,\"width\":100},{\"id\":19,\"enabled\":false,\"width\":100},{\"id\":2,\"enabled\":true,\"width\":234},{\"id\":3,\"enabled\":false,\"width\":100},{\"id\":4,\"enabled\":false,\"width\":100},{\"id\":11,\"enabled\":false,\"width\":100},{\"id\":16,\"enabled\":false,\"width\":100},{\"id\":12,\"enabled\":false,\"width\":100},{\"id\":8,\"enabled\":false,\"width\":100},{\"id\":21,\"enabled\":false,\"width\":100},{\"id\":18,\"enabled\":false,\"width\":100},{\"id\":5,\"enabled\":false,\"width\":100},{\"id\":20,\"enabled\":false,\"width\":100},{\"id\":17,\"enabled\":false,\"width\":100},{\"id\":24,\"enabled\":false,\"width\":100},{\"id\":25,\"enabled\":false,\"width\":100},{\"id\":26,\"enabled\":false,\"width\":100}]",
"torrent-sorting": "{\"id\":15,\"direction\":\"asc\"}"
}
for (const [key, value] of Object.entries(obj)) {
localStorage.setItem(key, value);
}
</script>
"""
with open(PATH, "r", encoding="utf-8") as file:
html = file.read()
# Check if the script with the ID "inject" is already in the file
if '<script id="inject">' in html:
# Replace existing script
html = html.split('<script id="inject">')[0] + SCRIPT + html.split('</script>', 1)[1]
else:
# Inject new script before </head>
html = html.replace("</head>", SCRIPT + "</head>")
with open(PATH, "w", encoding="utf-8") as file:
file.write(html)
EOF
@ivanjx @niawag @matt8707 as you might have noticed I have released a new version with at least some kind of server side configuration. This means you can effectively overwrite the default configuration.
So the order of importance is like this: Client configuration > config.json configuration > original default configuration
PR for reference can be found here: https://github.com/johman10/flood-for-transmission/pull/540.
I hope that resolves the needs which were raised with this issue, so I will close this. Please open another issue if you have more specific needs.
Thanks a lot for this release, I've tried it and I can see that my settings are propagated, great! I'm having an issue with the common paths setting, I can see they are set well in the webui setting but, when I click on the magnifier icon to choose one, the webui get stuck, only a refresh works to get it back. I opened chrome console and here is the error:
Paths.svelte:18 Uncaught (in promise) TypeError: Pl.init is not a function
at ic (Paths.svelte:18:15)
at We (Component.js:148:34)
at new ac (Paths.svelte:14:17)
at ne (dom.js:1198:9)
at Wa (ContextMenu.svelte:120:32)
at Object.p (ContextMenu.svelte:102:20)
at Ee (scheduler.js:119:30)
at Se (scheduler.js:79:5)
Another little problem is that, once the webui is used on a client the following changes in config.json won't be propagated without clearing storage and autorisations (why are both needed ?) but I'm not sure this can be leveraged. Or is it possible to change the order of preference and always use config.json configuration?
Regarding the error, I just pushed a fix for that. I should probably write some tests at some point. 😅
Another little problem is that, once the webui is used on a client the following changes in config.json won't be propagated without clearing storage and autorisations (why are both needed ?) but I'm not sure this can be leveraged. Or is it possible to change the order of preference and always use config.json configuration?
Yeah, that's a limitation of the current setup. Perhaps easiest would be to prevent changes if a config file is present. But I don't really want to force everyone to use a file to configure the UI, hence why it's currently supported. Changing the priority order is another option, but I would have to find another way to store the column width than I'm doing currently for that to work correctly.
Great, thanks for the fix! Would it be possible to store a hash of the file (or another way to check if the file changed) ? If yes, we could reload file and overwrite client config only if the file changed. The column width is a very good example of what should not be in the config file, maybe a part of the settings like this one should be in another file, not affected by the presence of a config file.
How does this work with haugene/transmission-openvpn? Linking config.json has no effect, do i have to install flood manually?
transmission:
image: haugene/transmission-openvpn
environment:
TRANSMISSION_WEB_UI: flood-for-transmission
volumes:
- /volume1/docker/transmission/config.json:/opt/transmission-ui/flood-for-transmission/public/config.json
...
@matt8707 I think that should work. Can you share the output of the next two commands after running it on the Docker host machine:
ls -al /volume1/docker/transmission/config.json
docker exec transmission ls -al /opt/transmission-ui/flood-for-transmission/public/config.json
-rwxrwxrwx+ 1 matte users 349 Nov 24 02:55 /volume1/docker/transmission/config.json
-rwxrwxr-x 1 abc abc 349 Nov 24 02:55 /opt/transmission-ui/flood-for-transmission/public/config.json
I also can't find a config.json.defaults
file, which suggests that I might be on an older version? (haugene/transmission-openvpn is latest)
Right, that's probably it. You will have to wait for haugene/transmission-openvpn to upgrade to the latest version, but after that this mounting solution should work.
How does this work with haugene/transmission-openvpn? Linking config.json has no effect, do i have to install flood manually?
transmission: image: haugene/transmission-openvpn environment: TRANSMISSION_WEB_UI: flood-for-transmission volumes: - /volume1/docker/transmission/config.json:/opt/transmission-ui/flood-for-transmission/public/config.json ...
I think you should install this webui as an alternate webui, not messing with the flood installed by default. You just have to mount a volume with this webui file and change the TRANSMISSION_WEB_HOME to this path. This issue should help you do so: https://github.com/haugene/docker-transmission-openvpn/discussions/2271 (same problem for a different webui) And that would allow you to keep flood up to date (but you'll have to take care of it)
Can confirm that new docker-transmission-openvpn release has the config.json.defaults
Using public folder, linking config file still has no effect. I did clear localStorage, console says
No config.json found, using default values: See https://github.com/johman10/flood-for-transmission#beta-customization
What did fix it was to remove public in the path 👍🏻
volumes:
- /volume1/docker/transmission/config.json:/opt/transmission-ui/flood-for-transmission/config.json