Skip to content

Vorstellung Restic UI Flask

Restic UI Flask
  • Ich habe ja damals mit PyWebIO ein Restic UI gebaut. Das gibt es auch auf gitlab.com

    Dieses PyWebIO ist schon ein tolles Tool, weil man den Python Code nicht verlässt. Aber, es hat zu viele Einschränkungen, die man dann nicht, oder nur sehr mühsam umgehen kann. Also war ich auf der Suche nach neuen Herausforderungen 🙂

    Zwei Frameworks die ich kannte, waren Django und Flask. Meine Wahl fiel auf Flask. Und nun fand ich mich wieder in Dingen, die ich vor langer Zeit zuletzt benutzt hatte. HTML, CSS und Javascript. Ich musste mich also wieder durch viele Themengebiete wühlen. Dank der Hilfe von ChatGPT, der mir einiges wieder erklären musste, habe ich dann aber mein Tool wieder so hinbekommen, wie ich es gerne haben wollte.

    Ich wollte es heute mal anhand einiger Screenshots vorstellen. Die Funktionalität ist wie beim alten Tool. Habe es aber ein wenig angepasst und viel mehr Funktionen ins Dashboard gepackt. Somit ist von dort aus, fast alles zu erreichen.

    Dashboard

    dashboard.png

    Dashboard mit Hamburger Menü

    hamburger_menue.png

    Add Backup

    add_backup.png

    Add Backup with REST

    add_backup_with_REST.png

    Edit Backup

    edit_backup.png

    About

    about.png

    Allgemeines

    Das Tool ist unter

    https://127.0.0.1:5050/dashboard
    

    mit selbstsignierten Zertifikaten erreichbar.

    Restic UI Flask nutzt als Backend zur Datenspeicherung eine Redis Datenbank. Ja, ist etwas auf mich zugeschnitten, ich habe hier immer eine Redis DB laufen, noch für andere Sachen.

    ToDo

    Den Code sauber machen, da liegt noch zu viel Müll rum. Danch werde ich den, wenn ich alles nochmal auf Fehler geprüft habe, auf Gitlab veröffentlichen. Vielleicht hilft es dem ein oder anderen 😉

    Ich mach mal mit OBS ein Video davon.

  • Python - Interessante Packages

    Python3
    1
    0 Stimmen
    1 Beiträge
    117 Aufrufe
    Niemand hat geantwortet
  • Rest-Server v0.13.0 released

    Restic
    2
    0 Stimmen
    2 Beiträge
    337 Aufrufe
    FrankMF
    Download Rest-Server und installieren Im Github Repository den aktuellen Release suchen. Hier am Beispiel der aktuellen Version 0.13.0 (27.07.2024) Datei herunterladen wget https://github.com/restic/rest-server/releases/download/v0.13.0/rest-server_0.13.0_linux_amd64.tar.gz Die Datei entpacken tar -xf rest-server_0.13.0_linux_amd64.tar.gz Ins Verzeichnis wechseln cd rest-server_0.13.0_linux_amd64 Wenn der Rest-Server läuft, dann muss man diesen erst mal stoppen. systemctl stop rest-server Danach kopiert man das File nach bin. Wer mag sichert vorher das alte File. cp rest-server /usr/local/bin Danach kann man den Rest-Server wieder starten. systemctl start rest-server Versionskontrolle root@rest-server:~# rest-server -v rest-server version rest-server 0.13.0 compiled with go1.22.5 on linux/amd64 Die Hilfe vom Rest-Server root@rest-server:~# rest-server -h Run a REST server for use with restic Usage: rest-server [flags] Flags: --append-only enable append only mode --cpu-profile string write CPU profile to file --debug output debug messages -h, --help help for rest-server --htpasswd-file string location of .htpasswd file (default: "<data directory>/.htpasswd)" --listen string listen address (default ":8000") --log filename write HTTP requests in the combined log format to the specified filename (use "-" for logging to stdout) --max-size int the maximum size of the repository in bytes --no-auth disable .htpasswd authentication --no-verify-upload do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device --path string data directory (default "/tmp/restic") --private-repos users can only access their private repo --prometheus enable Prometheus metrics --prometheus-no-auth disable auth for Prometheus /metrics endpoint --tls turn on TLS support --tls-cert string TLS certificate path --tls-key string TLS key path -v, --version version for rest-server Systemd Wer noch ein passendes systemd File benötigt. [Unit] Description=Rest Server After=syslog.target After=network.target [Service] Type=simple User=rest-server Group=rest-server ExecStart=/usr/local/bin/rest-server --private-repos --tls --tls-cert /mnt/rest-server/<DOMAIN>/fullchain.pem --tls-key /mnt/rest-server/<DOMAIN>/key.pem --path /mnt/rest-server Restart=always RestartSec=5 # Optional security enhancements NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=/mnt/rest-server [Install] WantedBy=multi-user.target
  • Redis - Datenbank Zugriff mit Python

    Redis
    3
    1
    0 Stimmen
    3 Beiträge
    189 Aufrufe
    FrankMF
    Ich bin mit der Lernkurve noch nicht so richtig zufrieden. Eine Frage die sich mir stellte, geht das einfacher? Der Ursprung meiner Datenbank Struktur liegt in einem anderen Projekt, wo ich versucht habe Daten permanent in einem File zu speichern. Dazu hatte ich damals JSON genommen. Deswegen auch diese Zeilen self.project = str(db_client.json().get('settings', '$..project')[0]) or self.project Gut, ich hatte dann mal ChatGPT gefragt, wie macht man das so 'normalerweise'? es kam eine Klasse heraus, die ich dann intensiv ausprobiert habe, ein wenig umgebaut usw. So lange, bis ich der Meinung war, ok ich habe es verstanden. Jetzt nutzte der Code auch mehr Redis Funktionen, wie self.client.hset('settings', name, json.dumps(data)) Es waren jetzt folgende Funktionen drin hset hexists hdel hget Dokumentation -> https://redis.io/commands/hset/ Beim Durchlesen des Codes hatte ich jetzt mehr das Gefühl, so muss das sein In RedisInsight sieht das dann jetzt so aus. [image: 1695479582374-393195f7-1017-4285-8fca-734ee6b4bff7-grafik.png] Klasse class PortfolioSettings: def __init__(self, host='172.17.0.2', port=6379, db=0): if args.test_mode == 1: self.client = redis.StrictRedis(host=SERVER_IP, port=port, db=TEST[0]) else: self.client = redis.StrictRedis(host=SERVER_IP, port=port, db=LIVE[0]) def set_settings(self, name, data): """Init settings if db don't exist""" if not self.client.hexists('settings', name): self.client.hset('settings', name, json.dumps(data)) return True return False def edit_setting(self, name, data): """Edit an entry in settings""" if self.client.hexists('settings', name): self.client.hset('settings', name, json.dumps(data)) return True return False def delete_setting(self, name): """Delete an entry in settings""" return self.client.hdel('settings', name) def get_setting(self, name): """Get an entry in settings""" setting = self.client.hget('settings', name) return json.loads(setting) if setting else None def get_all_settings(self): """Get all entries in settings""" settings = self.client.hgetall('settings') return {k.decode(): json.loads(v) for k, v in settings.items()} Und hier die Initialisierung settings_data = PortfolioSettings() ##################### # Will only be executed if DB is not available! ##################### if not settings_data.get_all_settings(): # Settings initialisieren print("INIT") settings_data.set_settings("project", "Portfolio") settings_data.set_settings("version", "0.0.3") settings_data.set_settings("theme", "dark") settings_data.set_settings("url_list", ["https://www.onvista.de/aktien/Deutsche-Telekom-Aktie-DE0005557508"]) settings_data.set_settings("exchange_list", ['DKB','Smartbroker','BUX']) Teile der Klasse sind [KI-generiert] Ich war zufrieden und habe die Klasse dann in mein Projekt übernommen und den Code überall entsprechend angepasst.
  • Debian Bookworm 12 - Restic

    Linux
    1
    0 Stimmen
    1 Beiträge
    154 Aufrufe
    Niemand hat geantwortet
  • Python - Dict -> JSON und umgekehrt

    Python3
    1
    0 Stimmen
    1 Beiträge
    316 Aufrufe
    Niemand hat geantwortet
  • PyWebIO - put_buttons

    PyWebIO
    2
    1
    0 Stimmen
    2 Beiträge
    194 Aufrufe
    FrankMF
    Und noch eine kleine Übung, wie man den Buttton abhängig von einem Value enabled/disabled # we build header and tdata for table tab_mount = [] for count, value in enumerate(backups): if count == 0: tab_mount.append(['No.', 'Backup name of the restic data backup', 'Actions']) if backups[value].init == "0": tab_mount.append([count + 1, backups[count].name, put_buttons([ dict(label='Mount', value='Mount', color='primary', disabled=True), dict(label='UMount', value='UMount', color='primary', disabled=True), dict(label='Restore', value='Restore', color='primary', disabled=True), ] , onclick=partial(actions, count + 1)) ]) else: tab_mount.append([count + 1, backups[count].name, put_buttons([ dict(label='Mount', value='Mount', color='primary'), dict(label='UMount', value='UMount', color='primary'), dict(label='Restore', value='Restore', color='primary'), ], onclick=partial(actions, count + 1)) ])
  • Restic UI - QThread

    Restic UI
    1
    0 Stimmen
    1 Beiträge
    130 Aufrufe
    Niemand hat geantwortet
  • Restic - Update

    Restic
    1
    0 Stimmen
    1 Beiträge
    436 Aufrufe
    Niemand hat geantwortet