From 8c3b7949ea6ff1e9c8cc467e5011587b947aba1a Mon Sep 17 00:00:00 2001 From: Nacho Date: Thu, 27 Aug 2026 19:08:36 +0200 Subject: [PATCH 1/2] docs: rewrite README with a fresh structure and voice Closes #200 --- README.es.md | 164 +++++++++++++++++++++++++++++---------------------- README.md | 162 ++++++++++++++++++++++++++++---------------------- 2 files changed, 185 insertions(+), 141 deletions(-) diff --git a/README.es.md b/README.es.md index 4ae1893..64cadf5 100644 --- a/README.es.md +++ b/README.es.md @@ -1,121 +1,143 @@
+ Icono de NextSync

NextSync

-

Tus ficheros, en local. Cualquier servidor, en sincronización.

-

Un compañero de escritorio para GNOME que mantiene espejos locales completos de tus cuentas. Agnóstico del servidor, construido con Rust, GTK 4 y Libadwaita.

+

Tus archivos, en local.
Cualquier servidor, en sincronía.

+

Un cliente de escritorio para GNOME que mantiene un espejo local completo de tus cuentas Nextcloud y OpenCloud.
Un único binario Rust. Sin telemetría, sin suscripciones.

- Sitio web + Web · - Reportar un problema + Releases + · + Incidencias

-

- Español | +

English + · + Español

- Versión 0.2.16 - Sitio web - Linux - GNOME - GTK 4 - Rust - GNU GPLv3 o posterior + Estado de CI + Versión 0.2.16 + GNU GPL v3 o posterior

-## Un compañero de GNOME al que no le importa qué servidor uses +

+ + + Ventana principal de NextSync: cuentas a la izquierda, filas de estado de carpetas con progreso de sincronización en vivo a la derecha + +

+ +## Qué es + +Tus archivos viven en tu disco. Cuando tu ordenador y tu servidor tienen que ponerse de acuerdo sobre qué ha cambiado, NextSync llama al motor oficial de línea de comandos de tu plataforma y lo envuelve en una experiencia de escritorio de verdad: cuentas, configuración por carpeta, progreso en vivo, resolución de conflictos y un icono de bandeja que refleja lo que de verdad está pasando. + +Es ingeniería aburrida a propósito. La lógica de reconciliación se queda en los motores oficiales, que arrastran años de casos límite. Todo lo que NextSync añade es pegamento de escritorio: cuándo ejecutar, qué mostrar y qué hacer cuando algo falla. + +## Por qué existe + +Empecé con un fork en Python de PyNextCloud-Sync, una pequeña app de GNOME de ehstbr que ya había entendido la idea correcta: no inventar otro algoritmo de sincronización, envolver el motor oficial y hacer que vivir con él sea agradable. Usé esa app, aprendí de ella y compartía la mayoría de sus decisiones. + +La reescritura en Rust llegó por razones prácticas: quería varias cuentas y varios proveedores en una sola app, un único binario sin runtime de Python y un código donde los callbacks asíncronos y los lifetimes de GObject no pudieran morderme en tiempo de ejecución. La filosofía del envoltorio siguió intacta, la capa de escritorio se reconstruyó y el proyecto creció hasta tener vida propia. Gracias, ehstbr, por publicar el original bajo GPL-3.0-or-later y hacer posible todo esto. + +## Qué hace -NextSync es una aplicación de escritorio GNOME que mantiene una o varias cuentas reflejadas en una o varias carpetas locales. Es **agnóstico del servidor por diseño**: no habla el protocolo de ningún proveedor, delega la sincronización en sí misma en una herramienta de sincronización por línea de comandos, y construye la experiencia de escritorio alrededor de esa herramienta. +**Sincronización** -Hoy eso significa dos proveedores: +- Varias cuentas y varias carpetas por cuenta, cada una mapeada a su ruta remota o su espacio de OpenCloud. +- Reconciliación bidireccional con los motores oficiales, con transferencias delta y copias en conflicto. +- Un sondeo remoto que comprueba primero el ETag de la carpeta y se salta el escaneo si el servidor no ha cambiado. El ETag sobrevive a los reinicios. +- Un planificador que agrupa los disparadores en una única cola, nunca lanza dos motores sobre la misma carpeta y nunca re-ejecuta una carpeta por los eventos de su propia sincronización. -- **Nextcloud**, a través del motor oficial `nextcloudcmd`. -- **OpenCloud**, a través del motor oficial `opencloudcmd`. +**Escritorio** -Cualquier plataforma que publique un CLI de sincronización puede añadirse después detrás de la misma abstracción. La capa de escritorio (cuentas, credenciales, programación, monitorización del sistema de ficheros, bandeja, ventanas, registros, resolución de conflictos) permanece igual; solo cambia el constructor del comando. +- Interfaz libadwaita con filas de estado por carpeta y progreso archivo a archivo mientras sincroniza. +- Icono de bandeja que refleja el estado global (sincronizado, sincronizando, en pausa, sin conexión, necesita atención) y un menú para abrir la app o salirla. Cerrar la ventana lo deja todo funcionando. +- Resolución de conflictos desde la app: quedarse con lo local o con lo remoto, archivo por archivo o en bloque. +- Interfaz en español e inglés. -El motor es la parte que hace el trabajo importante. NextSync es la parte que lo hace vivir bien en el escritorio: inicio de sesión seguro, disparadores automáticos, una ventana de estado compacta, integración con GNOME, registros y un menú de bandeja. +**Redes de seguridad** -### Un fork, con agradecimiento +- Antes de propagar un borrado masivo local, la sincronización se detiene y la revisión agrupa lo desaparecido por carpeta de primer nivel, con detalles desplegables. Apruebas una vez, restauras desde el servidor o dejas la carpeta en pausa. +- Si el servidor deja de responder, la cuenta pasa a sin conexión en lugar de encadenar errores, y NextSync la sigue sondeando hasta que vuelve. +- Las credenciales rechazadas ponen la cuenta en pausa para las sincronizaciones automáticas en lugar de machacar el servidor a reintentos. Un llavero bloqueado reintenta solo, con un límite acotado. -NextSync hereda su identidad y gran parte de su diseño de [**PyNextCloud-Sync**](https://github.com/ehstbr/PyNextCloud-Sync), de **ehstbr**. Ese proyecto es una pieza de trabajo preciosa, y todas las buenas decisiones que tomó sobre la experiencia de escritorio se han mantenido aquí. +**Privacidad** -Nosotros tomamos una dirección distinta por debajo. PyNextCloud-Sync envuelve un motor de Nextcloud en Python y GTK 4 vía PyGObject. NextSync es una reescritura en Rust que generaliza la idea: en lugar de un compañero para una cuenta de Nextcloud concreta, es un compañero para **cualquier herramienta de sincronización** que publique tu servidor. +- Sin telemetría, sin analítica, sin informes de errores remotos. Nada sale de tu máquina salvo el tráfico de sincronización con tu propio servidor. +- Las credenciales viven en el Secret Service (llavero de GNOME). Los registros son ficheros locales, uno por día. -Muchas gracias a ehstbr por iniciar algo tan maravilloso, por tomar las decisiones acertadas que hemos heredado, y por publicarlo bajo la licencia GPL-3.0-or-later, que hace posible este proyecto. +## Proveedores + +| Proveedor | Motor | Inicio de sesión | +|---|---|---| +| Nextcloud | `nextcloudcmd` | Login Flow v2 en el navegador, o contraseña de aplicación | +| OpenCloud | `opencloudcmd` | Contraseña de aplicación desde la web del servidor | + +Ambos motores se esconden detrás del mismo trait pequeño, así que un proveedor nuevo es un constructor de comandos, no un cambio de arquitectura. Las notificaciones push del servidor (`notify_push`) aplican a Nextcloud; las cuentas sin push recurren a un intervalo de sondeo. + +## Instalación -## Por qué una reescritura en Rust +### Arch, CachyOS y derivadas -- **Un único binario estático.** Sin runtime de Python, sin estructura de site-packages. La distribución y el autostart son triviales. -- **Huella pequeña en reposo.** Un compañero de bandeja y ventanas se sitúa muy por debajo de la línea base del intérprete de Python, y el arranque es casi inmediato. -- **Seguridad de tipos en toda la app.** Los tiempos de vida de GObject, los callbacks asíncronos y la máquina de estados son exactamente donde más ayuda Rust. -- **Agnóstico del servidor por construcción.** El motor de sincronización está detrás de un trait pequeño, así que añadir un tercer proveedor es un constructor de comando, no un cambio de arquitectura. +Descarga el `.pkg.tar.zst` de la [última release](https://github.com/gnacho/nextsync/releases/latest) e instálalo: -## Características destacadas +```bash +sudo pacman -U nextsync-0.2.16-1-x86_64.pkg.tar.zst +``` -- **Multicuenta.** Cada cuenta mantiene sus propios ajustes de sincronización y de runtime. -- **Multicarpeta.** Cada cuenta puede reflejar varias carpetas locales, cada una con su ruta remota (o espacio de OpenCloud), su propio estado y sus propios disparadores. -- **Multiproveedor.** Nextcloud y OpenCloud hoy, cualquier cosa con un CLI de sincronización mañana, todo en una sola app. -- **Pensado para cuentas grandes.** Sin copias de staging, sin análisis previo a la transferencia. La detección delta del motor descarga solo lo que difiere. -- **Recursos optimizados, no duplicados.** Todos los disparadores desembocan en una única cola de coalescencia por cuenta, y la app nunca lanza dos procesos de sincronización para la misma carpeta. Un cambio remoto y un cambio local que llegan juntos producen una ejecución, no dos. -- **Motor oficial.** La herramienta CLI es dueña de la sincronización, la resolución de conflictos y la seguridad. NextSync añade la experiencia de escritorio y los huecos que el CLI deja abiertos. -- **Interfaz nativa de GNOME.** Rust, GTK 4 y Libadwaita. -- **Credenciales seguras.** Almacenadas a través de Secret Service / GNOME Keyring. -- **Detección local rápida.** Monitorización recursiva de `inotify` en Linux con coalescencia de eventos. -- **Menú de bandeja.** Abrir, Configuración, Registro y Salir directamente desde la bandeja; cerrar la ventana mantiene la app funcionando en segundo plano (el item Salir de la bandeja es la única forma de salir del todo). -- **Guardia de borrado.** Un borrado masivo local bloquea la sincronización antes de que el motor pueda propagarlo, porque los motores CLI no piden confirmación en modo no interactivo. -- **Privado por diseño.** Sin telemetría, sin analítica, sin informes remotos de fallos. +El paquete depende de `gtk4` y `libadwaita`. Para cuentas Nextcloud instala `nextcloud-client` (aporta `nextcloudcmd`); para cuentas OpenCloud, el `opencloudcmd` oficial. -## Cómo funciona la sincronización +### Desde el código fuente -Cada disparador pide al mismo programador una reconciliación bidireccional. Las peticiones que llegan juntas se coalescen en una única cola, y la app nunca inicia dos procesos del motor para la misma cuenta. +Necesitas Rust (cargo) más los paquetes de desarrollo de GTK 4 y libadwaita: -```mermaid -flowchart LR - A["Cambios locales
inotify / intervalo"] --> Q["Cola única
de sincronización"] - B["Avisos remotos
notify_push / intervalo"] --> Q - C["Sync manual
red / resume"] --> Q - Q --> E["CLI de sync
nextcloudcmd / opencloudcmd"] - E <--> F["Espejo local"] - E <--> S["Tu servidor"] +```bash +git clone https://github.com/gnacho/nextsync +cd nextsync +cargo build --release ``` -> [!IMPORTANT] -> La sincronización es bidireccional. Los cambios locales y remotos, incluidos los borrados, pueden propagarse al otro lado. Mantén una copia de seguridad independiente de los datos importantes y no ejecutes otro motor de sincronización contra la misma carpeta local. +El binario queda en `target/release/nextsync`. Se incluye un `PKGBUILD` por si prefieres generar el paquete completo con `makepkg` en una distribución tipo Arch. -## Proveedores +## Primer arranque -| Proveedor | Motor | Autenticación | -|---|---|---| -| Nextcloud | `nextcloudcmd` | Login Flow v2 (navegador) o credenciales vía Secret Service | -| OpenCloud | `opencloudcmd` | Contraseña de aplicación creada en la web del servidor, guardada en Secret Service | +1. Añade una cuenta: dirección del servidor y login con el navegador (Login Flow v2 de Nextcloud) o contraseña de aplicación (OpenCloud). +2. Añade carpetas: elige una carpeta local y su correspondencia en el servidor. En cuentas Nextcloud el selector lista tus carpetas existentes; en OpenCloud se escribe la ruta a mano. +3. Si la carpeta local ya tenía ficheros o una sincronización anterior, NextSync muestra lo que va a pasar antes de tocar nada. +4. A partir de ahí sincroniza con los cambios, por calendario y con los push del servidor. Cierra la ventana; la bandeja sigue trabajando. -Las notificaciones push vía `notify_push` aplican a Nextcloud. OpenCloud no tiene `notify_push`, por lo que esa cuenta se apoya en el disparador de intervalo remoto. +## Los borrados viajan en ambos sentidos -## Estado del proyecto +La sincronización también replica borrados. Si una carpeta desaparece en local, desaparece en el servidor, y al revés. Guarda una copia de seguridad independiente de lo que sea importante y nunca apuntes un segundo motor de sincronización a la misma carpeta local. La revisión de borrados para los desastres evidentes, pero una revisión no es una copia de seguridad. -Esta es una versión de desarrollo temprana. La arquitectura está en su sitio: configuración, credenciales, máquina de estados, programador, motor de sincronización con progreso en vivo, monitorización del sistema de ficheros, guardia de borrado y la abstracción de proveedores. La interfaz GTK es lo siguiente que se está construyendo. +## Ficheros en disco -Pruébalo con datos no críticos antes de confiar en él para la sincronización habitual, y mantén siempre copias de seguridad independientes de los ficheros importantes. +| Qué | Dónde | +|---|---| +| Configuración | `~/.config/nextsync/` | +| Estado, registros, avatares | `~/.local/state/nextsync/` | +| Credenciales | Llavero de GNOME (Secret Service) | -## Desarrollo y tests +## Desarrollo ```bash -cargo check cargo test cargo clippy --all-targets -- -D warnings +cargo fmt --check ``` -La suite cubre configuración, credenciales, la máquina de estados, el programador, los constructores de comando de sincronización para ambos proveedores, el analizador de progreso en vivo, la monitorización del sistema de ficheros, la guardia de borrado y el protocolo notify_push incluyendo un handshake WebSocket tolerante. +La batería cubre configuración, credenciales, planificador, motor de sincronización, protocolo push, revisión de borrados y lógica de interfaz, con tests de humo GTK que toleran entornos sin pantalla. CI ejecuta las mismas comprobaciones más un test de paridad i18n que falla si a alguna cadena de la interfaz le falta su traducción al español, y un job de cobertura. -Los tests con cuenta real requieren un servidor real y una sesión de escritorio, y están marcados con `#[ignore]`. +Más en [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md) y el [CHANGELOG](CHANGELOG.md). -## Documentación +## Créditos -- [Plan de implementación](plans/2026-08-13-rust-rewrite.md) -- [Licencia pública general GNU v3 o posterior](LICENSE) +NextSync empezó siendo un fork de [PyNextCloud-Sync](https://github.com/ehstbr/PyNextCloud-Sync) de ehstbr. El código se ha reescrito en Rust desde entonces y el proyecto ha crecido hasta tener vida propia, pero la idea central y el buen criterio original son herencia. Como el original, se publica bajo [GPL-3.0-or-later](LICENSE). ---

-Nextcloud es una marca registrada de Nextcloud GmbH. OpenCloud es un producto del grupo Heinlein. NextSync es un proyecto independiente y no oficial, y no está afiliado, patrocinado, respaldado ni conectado de ningún otro modo con ninguna de las dos empresas. El uso está sujeto a la Licencia Pública General GNU versión 3 o posterior. +Nextcloud es una marca registrada de Nextcloud GmbH. OpenCloud es un producto del Heinlein Group. NextSync es un proyecto independiente y no oficial, sin afiliación, patrocinio ni respaldo de ninguna de las dos compañías.

diff --git a/README.md b/README.md index 9a45e6d..a9ef86b 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,143 @@
+ NextSync icon

NextSync

-

Your files, local. Any server, in sync.

-

A GNOME-native desktop companion for keeping complete local mirrors of your accounts. Server agnostic, built with Rust, GTK 4, and Libadwaita.

+

Your files, local.
Any server, in sync.

+

A GNOME desktop client that keeps a complete local mirror of your Nextcloud and OpenCloud accounts.
One small Rust binary. No telemetry, no subscriptions.

Website · - Report an issue + Releases + · + Issues

-

- English | +

+ English + · Español

- Version 0.2.16 - Website - Linux - GNOME - GTK 4 - Rust - GNU GPLv3 or later + CI status + Version 0.2.16 + GNU GPL v3 or later

-## A GNOME companion that does not care what server you run +

+ + + NextSync main window: accounts on the left, folder status rows with live sync progress on the right + +

+ +## What it is + +You keep your files on your disk. When your computer and your server need to agree on what changed, NextSync calls the official command line engine for your platform and wraps it in a real desktop experience: accounts, per-folder configuration, live progress, conflict resolution, and a tray icon that reflects what is actually going on. + +It is deliberately boring engineering. The reconciliation logic stays in the official engines, which carry years of edge cases behind them. Everything NextSync adds is desktop glue: when to run, what to show, and what to do when something goes wrong. + +## Why it exists + +I started with a Python fork of PyNextCloud-Sync, a small GNOME app by ehstbr that had already figured out the right idea: do not invent another synchronization algorithm, wrap the official engine and make it pleasant to live with. I used that app, learned from it, and agreed with most of its choices. + +The rewrite in Rust happened for practical reasons: I wanted several accounts and several providers in a single app, one binary without a Python runtime, and a codebase where async callbacks and GObject lifetimes could not bite me at runtime. The wrapper philosophy carried over intact, the desktop layer was rebuilt, and the project grew into something of its own. Thank you, ehstbr, for releasing the original under GPL-3.0-or-later and making all of this possible. + +## What it does -NextSync is a GNOME desktop application that keeps one or more accounts mirrored to one or more local folders. It is **server agnostic by design**: it does not speak a vendor protocol, it delegates the synchronization itself to a command line sync tool, and it builds the desktop experience around that tool. +**Synchronization** -Today that means two providers: +- Multiple accounts, and multiple folders per account, each mapped to its own remote path or OpenCloud space. +- Bidirectional reconciliation through the official engines, with delta transfers and conflicted copies. +- A remote poll that checks the folder ETag first and skips the scan when the server did not change. The ETag survives restarts. +- A scheduler that coalesces triggers into one queue, never runs two engines on the same folder, and never re-runs a folder because of its own sync events. -- **Nextcloud**, through the official `nextcloudcmd` engine. -- **OpenCloud**, through the official `opencloudcmd` engine. +**Desktop** -Any platform that ships a synchronization CLI can be added later behind the same abstraction. The desktop layer (accounts, credentials, scheduling, filesystem monitoring, tray, windows, logs, conflict resolution) stays the same; only the command builder changes. +- A libadwaita interface with per-folder status rows and file-by-file progress while a sync runs. +- A tray icon that reflects the global state (synced, syncing, paused, offline, needs attention) plus a menu to open the app or quit it. Closing the window keeps everything running. +- Conflict resolution from the app: keep local, keep remote, per file or in bulk. +- English and Spanish interface. -The engine is the part that does the real work. NextSync is the part that makes it live nicely on the desktop: secure login, automatic triggers, a compact status window, GNOME integration, logs, and a tray menu. +**Safety rails** -### A fork, with thanks +- Before a mass local deletion is propagated, sync stops and the review groups what disappeared by top-level folder, with expandable details. You approve once, restore from the server, or stay paused. +- If the server stops answering, the account goes offline instead of looping errors, and NextSync keeps probing until it is back. +- Rejected credentials pause automatic syncs for that account instead of hammering the server with retries. A locked keyring retries on its own with a capped backoff. -NextSync inherits its identity and much of its design from [**PyNextCloud-Sync**](https://github.com/ehstbr/PyNextCloud-Sync) by **ehstbr**. That project is a beautiful piece of work, and every good decision it made about the desktop experience carried over here. +**Privacy** -We took a different direction under the hood. PyNextCloud-Sync wraps one Nextcloud engine in Python and GTK 4 via PyGObject. NextSync is a Rust rewrite that generalizes the idea: instead of a companion for one specific Nextcloud account, it is a companion for **any sync tool** your server ships. +- No telemetry, no analytics, no crash reporting. Nothing leaves your machine except sync traffic with your own server. +- Credentials live in the Secret Service (GNOME Keyring). Logs are local files, one per day. -A big thank you to ehstbr for starting something so good, for making the right choices that we inherited, and for releasing it under the GPL-3.0-or-later license, which makes this project possible. +## Providers + +| Provider | Engine | Sign in | +|---|---|---| +| Nextcloud | `nextcloudcmd` | Login Flow v2 in your browser, or app password | +| OpenCloud | `opencloudcmd` | App password from the server web UI | + +Both engines sit behind the same small trait, so a new provider is a command builder, not an architecture change. Server push notifications (`notify_push`) apply to Nextcloud; accounts without push fall back to a polling interval. + +## Install -## Why a Rust rewrite +### Arch, CachyOS and derivatives -- **A single static binary.** No Python runtime, no site-packages layout. Distribution and autostart are trivial. -- **Small idle footprint.** A tray and windows companion sits far below the Python interpreter baseline, and startup is near instant. -- **Type safety across the app.** GObject lifetimes, async callbacks, and the state machine are exactly where Rust helps most. -- **Server agnostic by construction.** The sync engine is behind a small trait, so adding a third provider is a command builder, not an architecture change. +Download the `.pkg.tar.zst` from the [latest release](https://github.com/gnacho/nextsync/releases/latest) and install it: -## Highlights +```bash +sudo pacman -U nextsync-0.2.16-1-x86_64.pkg.tar.zst +``` -- **Multi-account.** Each account keeps its own synchronization and runtime settings. -- **Multi-folder.** Each account can mirror several local folders, each with its own remote path (or OpenCloud space), its own status, and its own triggers. -- **Multi-provider.** Nextcloud and OpenCloud today, anything with a sync CLI tomorrow, all in one app. -- **Built for large accounts.** No staging copies, no pre-transfer analysis. The engine's delta detection downloads only what differs. -- **Resources optimized, not duplicated.** All triggers funnel into a single coalescing queue per account, and the app never starts two sync processes for the same folder. A remote change and a local change arriving together produce one run, not two. -- **Official engine.** The CLI tool owns synchronization, conflict resolution, and safety. NextSync adds the desktop experience and the gaps the CLI leaves open. -- **GNOME-native interface.** Rust, GTK 4, and Libadwaita. -- **Secure credentials.** Stored through Secret Service / GNOME Keyring. -- **Fast local detection.** Recursive Linux `inotify` monitoring with event coalescing. -- **Tray menu.** Open, Settings, Log and Quit straight from the tray; closing the window keeps the app running in the background (the tray Quit item is the only way to fully exit). -- **Deletion guard.** A mass local deletion blocks sync before the engine can propagate it, because the CLI engines do not ask for confirmation in non-interactive mode. -- **Private by design.** No telemetry, no analytics, no remote crash reporting. +The package depends on `gtk4` and `libadwaita`. For Nextcloud accounts install `nextcloud-client` (it provides `nextcloudcmd`); for OpenCloud accounts, the official `opencloudcmd`. -## How synchronization works +### From source -Every trigger asks the same scheduler for a bidirectional reconciliation. Requests that arrive together are coalesced into a single queue, and the app never intentionally starts two engine processes for the same account. +You need Rust (cargo) plus the GTK 4 and libadwaita development packages: -```mermaid -flowchart LR - A["Local changes
inotify / interval"] --> Q["Single
sync queue"] - B["Remote hints
notify_push / interval"] --> Q - C["Manual sync
network / resume"] --> Q - Q --> E["Sync CLI
nextcloudcmd / opencloudcmd"] - E <--> F["Local mirror"] - E <--> S["Your server"] +```bash +git clone https://github.com/gnacho/nextsync +cd nextsync +cargo build --release ``` -> [!IMPORTANT] -> Synchronization is bidirectional. Local and remote changes, including deletions, can be propagated to the other side. Keep an independent backup of important data and do not run another synchronization engine against the same local folder. +The binary lands in `target/release/nextsync`. A `PKGBUILD` is included if you prefer to build the full package with `makepkg` on an Arch-like distribution. -## Providers +## First run -| Provider | Engine | Authentication | -|---|---|---| -| Nextcloud | `nextcloudcmd` | Login Flow v2 (browser) or credentials via Secret Service | -| OpenCloud | `opencloudcmd` | App password created in the server web UI, stored in Secret Service | +1. Add an account: server address, then sign in with the browser (Nextcloud Login Flow v2) or an app password (OpenCloud). +2. Add folders: pick a local folder and where it maps on the server. For Nextcloud accounts the remote picker lists your existing folders; for OpenCloud you type the path. +3. If the local folder already had files or a previous synchronization, NextSync shows what is about to happen before it starts touching anything. +4. From there it syncs on changes, on schedule, and on server push events. Close the window; the tray keeps working. -Push notifications via `notify_push` apply to Nextcloud. OpenCloud has no `notify_push`, so that account relies on the remote interval trigger instead. +## Deletions travel both ways -## Project status +Sync mirrors deletions too. If a folder disappears locally, it disappears on the server, and the other way around. Keep an independent backup of anything important, and never point a second sync engine at the same local folder. The deletion review stops obvious disasters, but a review is not a backup. -This is an early development release. The architecture is in place: configuration, credentials, state machine, scheduler, sync engine with live progress, filesystem monitoring, deletion guard, and the provider abstraction. The GTK interface is being built next. +## Files on disk -Test it with non-critical data before relying on it for regular synchronization, and always keep independent backups of important files. +| What | Where | +|---|---| +| Configuration | `~/.config/nextsync/` | +| State, logs, avatars | `~/.local/state/nextsync/` | +| Credentials | GNOME Keyring (Secret Service) | -## Development and tests +## Development ```bash -cargo check cargo test cargo clippy --all-targets -- -D warnings +cargo fmt --check ``` -The suite covers configuration, credentials, the state machine, the scheduler, the sync command builders for both providers, the live progress parser, filesystem monitoring, the deletion guard, and the notify_push protocol including a tolerant WebSocket handshake. +The suite covers configuration, credentials, the scheduler, the sync engine, the push protocol, the deletion review, and the interface logic, with GTK smoke tests that tolerate headless environments. CI runs the same checks plus an i18n parity test that fails if any interface string lacks its Spanish translation, and a coverage job. -Real-account tests require an actual server and a desktop session and are marked `#[ignore]`. +More in [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md) and the [CHANGELOG](CHANGELOG.md). -## Documentation +## Credits -- [Implementation plan](plans/2026-08-13-rust-rewrite.md) -- [GNU General Public License v3 or later](LICENSE) +NextSync began life as a fork of [PyNextCloud-Sync](https://github.com/ehstbr/PyNextCloud-Sync) by ehstbr. The code has since been rewritten in Rust and the project has grown into something of its own, but the core idea and the original good judgment are inherited. Like the original, it is released under [GPL-3.0-or-later](LICENSE). ---

-Nextcloud is a registered trademark of Nextcloud GmbH. OpenCloud is a product of the Heinlein Group. NextSync is an independent, unofficial project and is not affiliated with, sponsored by, endorsed by, or otherwise connected to either company. Use is subject to the GNU General Public License version 3 or later. +Nextcloud is a registered trademark of Nextcloud GmbH. OpenCloud is a product of the Heinlein Group. NextSync is an independent, unofficial project and is not affiliated with, sponsored by, or endorsed by either company.

From 0bd067dfb32040561bcbeaad60cdf59ed5652bd0 Mon Sep 17 00:00:00 2001 From: Nacho Date: Thu, 27 Aug 2026 19:11:40 +0200 Subject: [PATCH 2/2] docs: drop fork lineage from the README, state the nextsync-py rewrite --- README.es.md | 8 ++------ README.md | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/README.es.md b/README.es.md index 64cadf5..6d64cbe 100644 --- a/README.es.md +++ b/README.es.md @@ -37,9 +37,9 @@ Es ingeniería aburrida a propósito. La lógica de reconciliación se queda en ## Por qué existe -Empecé con un fork en Python de PyNextCloud-Sync, una pequeña app de GNOME de ehstbr que ya había entendido la idea correcta: no inventar otro algoritmo de sincronización, envolver el motor oficial y hacer que vivir con él sea agradable. Usé esa app, aprendí de ella y compartía la mayoría de sus decisiones. +NextSync empezó siendo [nextsync-py](https://github.com/gnacho/nextsync-py), una pequeña app en Python y GTK que envolvía el motor oficial de línea de comandos de Nextcloud en una experiencia de escritorio de verdad. Funcionaba lo bastante bien como para correr cada día, pero todo pagaba el peaje de Python: un intérprete que llevar encima, un arranque que esperar y tipado dinámico que convertía los errores de lifetime de GObject en sorpresas en tiempo de ejecución en vez de en errores de compilación. -La reescritura en Rust llegó por razones prácticas: quería varias cuentas y varios proveedores en una sola app, un único binario sin runtime de Python y un código donde los callbacks asíncronos y los lifetimes de GObject no pudieran morderme en tiempo de ejecución. La filosofía del envoltorio siguió intacta, la capa de escritorio se reconstruyó y el proyecto creció hasta tener vida propia. Gracias, ehstbr, por publicar el original bajo GPL-3.0-or-later y hacer posible todo esto. +La reescritura en Rust llegó por razones prácticas: varias cuentas y varios proveedores en una sola app, un único binario pequeño y un código donde los callbacks asíncronos y los lifetimes de GObject no pueden morder en tiempo de ejecución. La filosofía del envoltorio siguió intacta y la capa de escritorio se reconstruyó por el camino. ## Qué hace @@ -132,10 +132,6 @@ La batería cubre configuración, credenciales, planificador, motor de sincroniz Más en [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md) y el [CHANGELOG](CHANGELOG.md). -## Créditos - -NextSync empezó siendo un fork de [PyNextCloud-Sync](https://github.com/ehstbr/PyNextCloud-Sync) de ehstbr. El código se ha reescrito en Rust desde entonces y el proyecto ha crecido hasta tener vida propia, pero la idea central y el buen criterio original son herencia. Como el original, se publica bajo [GPL-3.0-or-later](LICENSE). - ---

diff --git a/README.md b/README.md index a9ef86b..d968f0e 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ It is deliberately boring engineering. The reconciliation logic stays in the off ## Why it exists -I started with a Python fork of PyNextCloud-Sync, a small GNOME app by ehstbr that had already figured out the right idea: do not invent another synchronization algorithm, wrap the official engine and make it pleasant to live with. I used that app, learned from it, and agreed with most of its choices. +NextSync started as [nextsync-py](https://github.com/gnacho/nextsync-py), a small Python and GTK app that wrapped the official Nextcloud command line engine in a proper desktop experience. It worked well enough to run every day, but everything paid the Python tax: an interpreter to ship, a startup to wait for, and dynamic typing that turned GObject lifetime mistakes into runtime surprises instead of compiler errors. -The rewrite in Rust happened for practical reasons: I wanted several accounts and several providers in a single app, one binary without a Python runtime, and a codebase where async callbacks and GObject lifetimes could not bite me at runtime. The wrapper philosophy carried over intact, the desktop layer was rebuilt, and the project grew into something of its own. Thank you, ehstbr, for releasing the original under GPL-3.0-or-later and making all of this possible. +The rewrite in Rust happened for practical reasons: several accounts and several providers in a single app, one small binary, and a codebase where async callbacks and GObject lifetimes cannot bite at runtime. The wrapper philosophy carried over intact and the desktop layer was rebuilt along the way. ## What it does @@ -132,10 +132,6 @@ The suite covers configuration, credentials, the scheduler, the sync engine, the More in [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md) and the [CHANGELOG](CHANGELOG.md). -## Credits - -NextSync began life as a fork of [PyNextCloud-Sync](https://github.com/ehstbr/PyNextCloud-Sync) by ehstbr. The code has since been rewritten in Rust and the project has grown into something of its own, but the core idea and the original good judgment are inherited. Like the original, it is released under [GPL-3.0-or-later](LICENSE). - ---