### Install syncrclone Source: https://github.com/jwink3101/syncrclone/blob/master/readme.md Install syncrclone using pip. Ensure you have Python 3.6+ installed. ```bash python -m pip install git+https://github.com/Jwink3101/syncrclone ``` -------------------------------- ### Install syncrclone and rclone Source: https://context7.com/jwink3101/syncrclone/llms.txt Installs rclone using its official script and then installs syncrclone using pip. Includes a verification step. ```bash # 1. Install rclone (https://rclone.org/install/) curl https://rclone.org/install.sh | sudo bash # 2. Install syncrclone (Python 3.6+ required) python -m pip install git+https://github.com/Jwink3101/syncrclone # 3. Verify installation syncrclone --version # syncrclone-20231117.0.BETA ``` -------------------------------- ### Example of Rename Propagation Source: https://context7.com/jwink3101/syncrclone/llms.txt Demonstrates how syncrclone reports a move operation when rename tracking is enabled, instead of a delete and transfer. ```bash # With renamesA = "hash", if you rename documents/report.pdf → documents/final.pdf # on side A, syncrclone will emit: # Move on B: 'documents/report.pdf' --> 'documents/final.pdf' # instead of: # Delete on B: 'documents/report.pdf' # Transfer A >>> B: 'documents/final.pdf' ``` -------------------------------- ### Run WebDAV Server for Testing Source: https://github.com/jwink3101/syncrclone/blob/master/docs/tests.md This command starts a local WebDAV server for testing purposes. Ensure the specified directory exists and is accessible. ```bash rclone serve webdav \ -v --vfs-cache-mode writes \ --no-modtime \ --addr localhost:8080 \ --user g --pass p . ``` -------------------------------- ### Minimal syncrclone Configuration Example Source: https://context7.com/jwink3101/syncrclone/llms.txt A basic Python configuration for syncrclone, setting up two remotes (local and Backblaze B2), a unique name, rclone settings, and comparison/conflict resolution options. ```python # config.py – minimal working example syncing a local folder to Backblaze B2 import hashlib, subprocess ## ── Remotes ────────────────────────────────────────────────────────────────── remoteA = "/home/user/documents" # local path remoteB = "b2:my-bucket/documents" # rclone remote ## ── Unique pair name (used to namespace stored file lists) ─────────────────── name = subprocess.check_output(["hostname"]).decode().strip() name += hashlib.md5(f"{remoteA}{remoteB}".encode()).hexdigest() ## ── rclone settings ────────────────────────────────────────────────────────── rclone_exe = "rclone" rclone_flags = ["--config", "/home/user/.config/rclone/rclone.conf"] rclone_env = {} # e.g. {"RCLONE_CONFIG_PASS": "secret"} rclone_flagsA = [] rclone_flagsB = ["--b2-hard-delete"] # side-specific flags ## ── Comparison & conflict resolution ───────────────────────────────────────── compare = "mtime" # "mtime" | "hash" | "size" dt = 1.1 # mtime tolerance in seconds conflict_mode = "newer" # "newer" | "older" | "A" | "B" | "tag" | "smaller" | "larger" tag_conflict = False # rename the losing file instead of overwriting ## ── Rename / move tracking ─────────────────────────────────────────────────── renamesA = None # None | "size" | "mtime" | "hash" renamesB = None ## ── Hash optimisation (skip recomputing unchanged files on local/sftp) ─────── reuse_hashesA = False reuse_hashesB = False ## ── Backups ─────────────────────────────────────────────────────────────────── backup = True # back up files before overwriting/deleting backup_with_copy = None # None=auto | True=always copy | False=always move sync_backups = False # mirror backups to the other remote too ``` -------------------------------- ### Local Mode Syncrclone Usage Source: https://github.com/jwink3101/syncrclone/blob/master/readme.md When in local mode, syncrclone searches for '.syncrclone/config.py' upwards from the current directory. This example shows how to run it from a subdirectory. ```bash cd /path/to/local/files syncrclone ``` ```bash cd /path/to/local/files syncrclone .syncrclone/config ``` ```bash cd /path/to/local/files/deeper/sub/dirs/ syncrclone # Will automatically find it ``` ```bash cd /path/to/local/files/deeper/sub/dirs/ syncrclone ../../../.syncrclone/config.py ``` -------------------------------- ### Configure Filters with Include/Exclude Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Apply rclone filters using the `--filter` flag for robust include/exclude logic. Filters are tested sequentially, and the first match determines inclusion or exclusion. This example excludes all `.exc` files except those ending in `.keep.exc`. ```python filter_flags = ['--filter','+ *.keep.exc', '--filter','- *.exc'] ``` -------------------------------- ### WebDAV Remote Configuration Source: https://github.com/jwink3101/syncrclone/blob/master/docs/tests.md Configuration for a WebDAV remote in rclone. This setup is used for manual testing of WebDAV functionality. ```ini [test] type = webdav url = http://localhost:8080 vendor = other user = g pass = zPWIrpgPau25I-H66JwYVkw ``` -------------------------------- ### File Filtering with rclone Flags Source: https://context7.com/jwink3101/syncrclone/llms.txt Configure file filtering using rclone's --exclude and --filter flags. This example shows excluding specific file types, macOS metadata, and temporary files, as well as using priority ordering for include/exclude patterns. ```python # config.py # Exclude macOS metadata and common temp files filter_flags = [ "--exclude", ".DS_Store", "--exclude", ".Spotlight-V100/**", "--exclude", ".Trashes/**", "--exclude", "*.tmp", "--exclude", "~$*", # Office lock files ] ``` ```python # Include/exclude pattern with priority ordering filter_flags = [ "--filter", "+ *.keep.exc", # keep these first "--filter", "- *.exc", # then exclude all other .exc files ] ``` ```python # Exclude files listed in a separate filter file (path relative to config) filter_flags = ["--filter-from", "filters.txt"] ``` ```python # Exclude git-tracked files, sync everything else (local-mode example) import subprocess with open(".syncrclone/git-files.txt", "wt") as f: subprocess.call(["git", "ls-files"], cwd="../", stdout=f) filter_flags = ["--exclude-from", ".syncrclone/git-files.txt"] ``` -------------------------------- ### Set Dynamic Name using Socket Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Obtain a dynamic name for the sync operation using the fully qualified domain name (FQDN) from the socket module. This can provide a more unique identifier depending on network setup. ```python import socket name = socket.getfqdn() ``` -------------------------------- ### Set Dynamic Name from Environment Variable Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Set a dynamic name for the sync operation by reading it from an environment variable. This allows external configuration of the sync name, for example, via `.bashrc`. ```python import os name = os.environ['SYNCRCLONE_NAME'] ``` -------------------------------- ### Get Rclone Config Password from User Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Securely retrieve the rclone configuration password from the user using `getpass` for environment variable injection. The password is automatically redacted in debug logs. ```python from getpass import getpass rclone_env = {'RCLONE_CONFIG_PASS':getpass('Password: ')} ``` -------------------------------- ### Execute Post-Sync Shell Script for Notifications Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md This Python code defines a post-sync shell command to send macOS notifications using 'terminal-notifier'. It dynamically includes sync statistics and the log file name. Ensure 'terminal-notifier' is installed. ```python post_sync_shell = """ terminal-notifier \ -title "syncrclone Done" \ -subtitle "MACHINE" \ -message "$STATS" \ -open "file://$PWD/logs/$LOGNAME" """.replace('MACHINE',name) # use a dynamic name ``` -------------------------------- ### Break Syncrclone Lock Source: https://github.com/jwink3101/syncrclone/blob/master/docs/misc.md Use the `syncrclone --break-lock` command to forcibly remove lock files, allowing a new sync job to start. Specify `both` to break locks on both local and remote configurations if applicable. ```bash syncrclone --break-lock both ``` -------------------------------- ### Basic syncrclone Usage Source: https://github.com/jwink3101/syncrclone/blob/master/readme.md Initiate a syncrclone process by providing the configuration file path. The first run will consider all files as new. ```bash syncrclone config.py ``` -------------------------------- ### Shell Command Execution in Syncrclone Source: https://context7.com/jwink3101/syncrclone/llms.txt Configure pre- and post-sync shell commands using string, list, or dictionary formats. The dictionary format allows for additional subprocess.Popen options. Ensure shell=True is used for string commands. ```python pre_sync_shell = "echo 'Starting sync' | logger -t syncrclone" post_sync_shell = 'echo "$STATS" | mail -s "Sync complete" admin@example.com' ``` ```python post_sync_shell = ["terminal-notifier", "-title", "syncrclone", "-message", "%s"] ``` ```python post_sync_shell = { "cmd": "curl -s -d 'payload={"text":"%(STATS)s"}' https://hooks.slack.com/T0/B0/xxx", "shell": True, "env": {"HOME": "/home/user"}, } ``` -------------------------------- ### Run a syncrclone Sync Source: https://context7.com/jwink3101/syncrclone/llms.txt Executes a syncrclone synchronization. Can point to an explicit config file path or run in local mode where the config is auto-discovered. ```bash # Remote mode – explicit config path syncrclone /path/to/sync/config.py # Local mode – auto-discovers .syncrclone/config.py by searching upwards cd /path/to/local/files syncrclone # From a subdirectory – still finds the config automatically cd /path/to/local/files/projects/docs syncrclone # Expected output (abridged): # 2023-11-17 12:00:01: syncrclone (20231117.0.BETA) # 2023-11-17 12:00:01: Refreshing file lists concurrently # 2023-11-17 12:00:03: Refreshed file list on A '/home/user/documents' # 2023-11-17 12:00:03: 1234 files, 4.50 Gb # 2023-11-17 12:00:05: Refreshed file list on B 'b2:my-bucket/documents' # ... # 2023-11-17 12:01:22: A >>> B 3 files, 1.20 Mb | A <<< B 1 files, 500.00 Kb # 2023-11-17 12:01:22: Time: 01m22.34s (rclone 01m20.00s, shell 0.00s) ``` -------------------------------- ### Convert .json to .json.xz with xz Source: https://github.com/jwink3101/syncrclone/blob/master/docs/misc.md Use the `xz` command-line tool to compress .json files back to .json.xz format. ```bash xz A-name_fl.json ``` -------------------------------- ### Perform an Interactive Sync Source: https://context7.com/jwink3101/syncrclone/llms.txt Shows planned actions and prompts the user for confirmation before proceeding with the sync. Allows for manual control over the sync process. ```bash # Interactive: show planned actions, then prompt before proceeding syncrclone --interactive config.py # (PLANNED) # Transfer A >>> B: 'documents/newfile.txt' # Would you like to continue? Y/[N]: y ``` -------------------------------- ### Set Syncrclone Attribute Settings Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Configure attribute settings for robust sync and clear conflict resolution. Use hashes for everything and tag all conflicts for the most reliable results. Consider 'mtime' for general use if hashes are not easily available. ```python compare = 'hash' conflict_mode = 'tag' renamesA = 'hash' renamesB = 'hash' ``` ```python compare = 'mtime' conflict_mode = 'newer_tag' ``` ```python renames(AB) = 'hash' ``` ```python renames(AB) = 'mtime' ``` ```python compare = 'mtime' conflict_mode = 'newer_tag' renamesA = 'hash' renamesB = 'mtime' ``` ```python compare = 'size' conflict_mode = 'tag' renamesA = None renamesB = None ``` ```python renamesA = 'size' renamesB = 'size' ``` -------------------------------- ### Generate a New Config File for syncrclone Source: https://context7.com/jwink3101/syncrclone/llms.txt Generates a new syncrclone configuration file. Use an explicit path for remote mode or '.' for local mode to create the config in the current directory. ```bash # Remote mode: write config to an explicit path syncrclone --new /path/to/sync/config.py # Local mode: auto-creates .syncrclone/config.py in the current directory cd /path/to/local/files syncrclone --new . # Config file written to '.syncrclone/config.py' ``` -------------------------------- ### Convert .json.xz to .json with xz Source: https://github.com/jwink3101/syncrclone/blob/master/docs/misc.md Use the `xz` command-line tool to decompress .json.xz files to .json format. The `--keep` flag preserves the original compressed file. ```bash xz -d --keep A-name_fl.json.xz ``` -------------------------------- ### Alternate Working Directories for Metadata Source: https://context7.com/jwink3101/syncrclone/llms.txt Configure alternate working directories (workdirA/workdirB) to store syncrclone metadata separately from the synced remotes. This is useful for managing metadata on a different location or remote. Note that workdirA/B must not overlap with remoteA/B and is not compatible with sync_backups = True. ```python # config.py remoteA = "sftp:server:/home/user/data" remoteB = "b2:my-bucket/data" # Store all syncrclone metadata on a third remote (e.g. local machine) workdirA = "/home/user/.syncrclone-meta/server-b2-A" workdirB = "/home/user/.syncrclone-meta/server-b2-B" # NOTE: workdirA/B must NOT overlap remoteA/B respectively # NOTE: not compatible with sync_backups = True ``` -------------------------------- ### Configure Backup with Move Option Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Enables backups to be performed using 'move' instead of 'copy'. This can be more efficient on remotes that don't support server-side copy, but may lead to confusing states if a run is interrupted. ```python backup_with_copy = False ``` -------------------------------- ### Configure File Listing Status Updates Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Sets the interval for status updates during file listing. Useful for monitoring progress on slow remotes. ```python list_status_dt = 10s ``` -------------------------------- ### Inspecting Stored File Lists Source: https://context7.com/jwink3101/syncrclone/llms.txt Learn how to access and decompress the stored file lists generated by syncrclone on each remote. These lists are stored as compressed JSON files and can be inspected using standard command-line tools. ```bash # File list location (on each remote): # /.syncrclone/A-_fl.json.xz # /.syncrclone/B-_fl.json.xz # Download and decompress (example for a local remote) xz -d --keep /path/to/A/.syncrclone/A-myname_fl.json.xz # Produces: A-myname_fl.json (array of rclone lsjson file objects) # Re-compress after manual editing xz A-myname_fl.json ``` -------------------------------- ### Perform a Dry-Run Sync Source: https://context7.com/jwink3101/syncrclone/llms.txt Simulates a sync operation by printing all planned actions without making any changes. Useful for previewing the impact of a sync. ```bash # Dry-run: print all planned actions, then exit without modifying anything syncrclone --dry-run config.py # (DRY RUN) # Transfer A >>> B: 'documents/newfile.txt' # Delete (with backup) on B: 'documents/old.txt' ``` -------------------------------- ### Make Script Executable Source: https://github.com/jwink3101/syncrclone/blob/master/utils/run_interval.md Use this command to grant execute permissions to the bash script. ```bash $ chmod +x myscript.sh ``` -------------------------------- ### Configure C-Style Formatting for Shell Commands Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Enables C-style formatting for pre-, post-, and fail-shell commands when specified as a list or within a dictionary. This helps reduce escaping issues with str.format and brackets. ```python Added C-Style formatting to pre-, post-, fail-shell commands when specified as a list or list inside a dict. Used C-Style to help reduce escaping needed of str.format and bracket. ``` -------------------------------- ### Override Configuration Options at Runtime Source: https://context7.com/jwink3101/syncrclone/llms.txt Allows specific configuration options to be temporarily overridden for a single run using the `--override` flag. This is useful for one-time adjustments without modifying the main configuration file. ```bash # Force a full hash recompute for this run only (ignoring cached hashes) syncrclone --override "reuse_hashesA = False" --override "reuse_hashesB = False" config.py # Run without backups for a one-time cleanup syncrclone --override "backup = False" config.py # Change conflict resolution for this run syncrclone --override "conflict_mode = 'A'" config.py ``` -------------------------------- ### Set Dynamic Remote Directory using Hostname Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Dynamically set remote directories using the machine's hostname for unique identification. This is useful when the same sync configuration is used across multiple machines. ```python import os,subprocess remoteA = os.path.expanduser('~/syndirs/documents') remoteB = 'remoteB:path/to/remote' # use hostname for a unique name name = subprocess.check_output(['hostname']).decode().strip() ``` -------------------------------- ### Configure File Comparison Mode Source: https://context7.com/jwink3101/syncrclone/llms.txt Sets how syncrclone determines if a file has changed. 'mtime' is the default, using modification time and size. 'hash' is more reliable but slower. 'size' is fastest but cannot detect in-place edits of the same size. ```python # config.py excerpts showing each comparison mode # --- mtime (default): compare size + modification time within `dt` tolerance --- compare = "mtime" dt = 1.1 # seconds; handles FAT filesystem 2-second granularity if set to 2.1 # --- hash: compare cryptographic hashes (most reliable, but slower on local/sftp) --- compare = "hash" hash_fail_fallback = "mtime" # fall back to mtime if no common hash is available # --- size only: fastest, but cannot detect in-place edits of the same size --- compare = "size" ``` -------------------------------- ### Configure rclone Environment for syncrclone Source: https://github.com/jwink3101/syncrclone/blob/master/readme.md Specify the rclone configuration file path or environment variables within your syncrclone configuration file. This ensures syncrclone uses the correct rclone settings. ```python rclone_env = {'RCLONE_CONFIG': 'rclone.cfg'} ``` ```python rclone_flags = ['--config','rclone.cfg'] ``` -------------------------------- ### Update Syncrclone Configuration Files Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md A workflow for updating your syncrclone configuration file to incorporate new options from newer versions. It involves creating a temporary new file, merging changes, and then replacing the old configuration. ```bash $ cd /path/to/config/ $ syncrclone --new tmpnew.py mv config.py config.py.BAK mv tmpnew.py config.py ``` -------------------------------- ### Define Pre/Post Sync Shell Hooks Source: https://context7.com/jwink3101/syncrclone/llms.txt Allows execution of arbitrary shell commands before or after a sync operation. The `$STATS` and `$LOGNAME` variables are available in the post-sync hook for dynamic command execution. ```python # config.py pre_sync_shell = "" post_sync_shell = 'echo "Sync done: $STATS"' stop_on_shell_error = False ``` -------------------------------- ### Log and Debug Functions in Config Environment Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Adds `log()` and `debug()` functions to the config environment, with `print()` aliased to `log()`. This provides enhanced logging capabilities within the configuration. ```python Adds `log()` (and makes `print() = log()`) and `debug()` to the config environment ``` -------------------------------- ### Specify Temporary Directory for Files Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Allows specifying a custom directory for temporary files using the `tempdir` option. This is independent of rclone's `--temp-dir` setting and can be useful for managing disk usage. ```python tempdir = /path/to/temp/files ``` -------------------------------- ### Programmatic Syncrclone Usage with Python API Source: https://context7.com/jwink3101/syncrclone/llms.txt Control syncrclone from Python by creating a Config object and using the SyncRClone class. This allows for dynamic configuration overrides and programmatic execution of sync tasks. The result object provides access to post-run statistics. ```python from syncrclone.cli import Config from syncrclone.main import SyncRClone # Build and parse a config config = Config("/path/to/config.py") config.parse() # Override individual settings in code config.dry_run = False config.backup = True config.avoid_relist = True # Run the sync (equivalent to calling syncrclone config.py on the CLI) result = SyncRClone(config) # Inspect post-run statistics print(result.stats()) # A >>> B 3 files, 1.20 Mb | A <<< B 1 files, 500.00 Kb # A: New 3 | Deleted 0 | Backed Up 0 | Moved 0 # B: New 1 | Deleted 0 | Backed Up 3 | Moved 0 # Time: 22.45s (rclone 21.10s, shell 0.00s) ``` -------------------------------- ### Configure Rename/Move Tracking Source: https://context7.com/jwink3101/syncrclone/llms.txt Enables detection of renamed or moved files to propagate these changes instead of performing delete/re-upload operations. Options include hash-based tracking (most reliable) or mtime+size tracking (faster). Disabling is recommended for object stores. ```python # config.py # Hash-based tracking (most reliable; rclone fetches hashes from the remote) renamesA = "hash" renamesB = "hash" # mtime + size tracking (faster, but more ambiguous) renamesA = "mtime" renamesB = "mtime" # Disable rename tracking entirely (safe default for object stores) renamesA = None renamesB = None ``` -------------------------------- ### Perform Final Transfer with Size-Only and ModTime/Checksum Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md The final transfer is performed in two passes: first with `--size-only`, and second with `ModTime` or hashes using `--checksum`. This ensures data integrity and efficiency. ```bash The final transfer happens in doubles: First does with `--size-only` regardless of settings and the second uses `ModTime` or hashes with `--checksum` ``` -------------------------------- ### Set Dynamic Remote Directory based on Hostname Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Conditionally set remote directories based on the specific hostname. This allows for different configurations on different machines while using a single config file. ```python import subprocess hostname = subprocess.check_output(['hostname']).decode().strip() if hostname == 'machine1': remoteA = '/path/to/machine1/documents' elif hostname == 'machine2': remoteA = '/different/path/to/documents' else: raise ValueError(f"Unrecognized host {hostname}") remoteB = 'remoteB:path/to/remote' name = hostname ``` -------------------------------- ### Set Dynamic Name for Local Mode Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Set a dynamic name for the sync operation when in local mode, typically by using the machine's hostname. This ensures unique identification even when the config is in the default local directory. ```python import os,subprocess name = subprocess.check_output(['hostname']).decode().strip() ``` -------------------------------- ### Configure Avoid Relist Default Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Sets 'avoid_relist' to True by default, which is suitable for most situations. If issues arise, it can be explicitly set to False. ```python avoid_relist=True is NOW THE DEFAULT. ``` -------------------------------- ### Dynamic Remote Paths Based on Hostname Source: https://context7.com/jwink3101/syncrclone/llms.txt Dynamically set remote paths based on the current hostname using Python's conditional logic. This allows for different configurations on different machines. It also demonstrates generating a unique name per machine. ```python # config.py – machine-aware config shared across multiple hosts import os, subprocess, hashlib, socket hostname = socket.getfqdn() if hostname == "laptop.local": remoteA = os.path.expanduser("~/Documents") elif hostname == "workstation.local": remoteA = "/mnt/data/Documents" else: raise ValueError(f"Unknown host: {hostname}") remoteB = "gdrive:Backups/Documents" # Unique name per machine so each host keeps its own file list name = hostname name += hashlib.md5(f"{remoteA}{remoteB}".encode()).hexdigest() # Per-host rclone config password (prompted once) from getpass import getpass rclone_env = {"RCLONE_CONFIG_PASS": getpass("rclone config password: ")} ``` -------------------------------- ### Override a Syncrclone Setting for a Single Run Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md Use the --override flag to temporarily change a configuration setting for the current command execution only. This is useful for testing or one-off changes without modifying the main configuration file. ```bash $ syncrclone --override "reuse_hashesB = False" ``` -------------------------------- ### Bash Script for Interval Execution Source: https://github.com/jwink3101/syncrclone/blob/master/utils/run_interval.md This script runs a command, then sleeps for 30 minutes before repeating. It saves its process ID to a file for later termination. Redirect output to /dev/null if the command manages its own logging. ```bash #!/usr/bin/env bash echo $$ > pid while true; do syncrclone /path/to/config.py 1> /dev/null 2>&1 sleep 1800 done ``` -------------------------------- ### Configure Conflict Resolution Mode Source: https://context7.com/jwink3101/syncrclone/llms.txt Determines how syncrclone handles files modified on both sides since the last sync. Options include preferring the newer file, always preferring side A, tagging both sides with timestamps, or preferring the larger file. ```python # config.py # Keep whichever side has the newer mtime; tag (rename) the other conflict_mode = "newer" tag_conflict = True # Result: report.pdf → report.20231117T120000.B.pdf (older B copy renamed) # report.pdf ← report.pdf (newer A copy wins) # Always prefer side A conflict_mode = "A" tag_conflict = False # B's version is backed up, not tagged # Tag BOTH sides with a timestamp suffix – no data is lost or overwritten conflict_mode = "tag" # Result: report.20231117T120000.A.pdf and report.20231117T120000.B.pdf # (original filename is freed; both versions transferred to both remotes) # Prefer the larger file (useful for append-only logs) conflict_mode = "larger" ``` -------------------------------- ### Specify Subprocess Popen Flags Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Allows specifying subprocess.Popen flags for pre/post/fail_shell values. This provides more control over how shell commands are executed. ```python Added the ability to specify subprocess.Popen flags for the pre/post/fail`_shell` values. ``` -------------------------------- ### Exclude Git-Tracked Files with Syncrclone Source: https://github.com/jwink3101/syncrclone/blob/master/docs/config_tips.md This Python snippet configures syncrclone to exclude files that are already tracked by git. It generates a list of git-tracked files and uses it to inform syncrclone's exclusion rules. Ensure your git repository is up-to-date before running. ```python remoteA = "../" # set automatically # ... # Set up all of your main filters FIRST! filter_flags = [] # import subprocess topdir = subprocess.check_output(['git','rev-parse','--show-toplevel']) topdir = topdir.decode().strip() with open('git-files.txt','wt') as file: subprocess.call(['git','ls-files'],cwd=topdir,stdout=file) filter_flags.extend(['--exclue-from','.syncrclone/git-files.txt']) ``` -------------------------------- ### Kill Script using PID File Source: https://github.com/jwink3101/syncrclone/blob/master/utils/run_interval.md Terminate the background script by reading its process ID from the 'pid' file and sending a kill signal. ```bash $ kill $(cat pid) ``` -------------------------------- ### Reset Sync State Source: https://context7.com/jwink3101/syncrclone/llms.txt Discards stored file-list snapshots, forcing the next sync to treat all files as new. This effectively resets the sync process, propagating no deletions and treating all files as if they were just added. ```bash # Best practice: run a normal sync first, then reset syncrclone config.py syncrclone --reset-state config.py # On the next run all files on both sides are considered "new" # (conflicts become tag conflicts, no deletes propagated) ``` -------------------------------- ### Generate Unique Name for Sync Pair Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Appends a unique hash to the name to ensure uniqueness per sync pair. Useful when configuring multiple sync pairs. ```python name += hashlib.md5(f"{remoteA}{remoteB}".encode()).hexdigest() ``` -------------------------------- ### Run Script in Background Source: https://github.com/jwink3101/syncrclone/blob/master/utils/run_interval.md Execute the script in the background, redirecting its output and running it detached from the terminal. ```bash $ nohup myscript.sh 1> /dev/null 2>&1 & ``` -------------------------------- ### Handle Errant Bytes in Rclone Response Source: https://github.com/jwink3101/syncrclone/blob/master/docs/changelog.md Improves the handling of rclone responses to account for errant bytes, ensuring more robust transfer processing. Addresses issue #16. ```python Changes handling of rclone response during transfer in case of errant bytes. See #16 ``` -------------------------------- ### Break Stale Lock Files Source: https://context7.com/jwink3101/syncrclone/llms.txt Removes lock files that may be preventing a sync operation due to an interrupted previous run. Can target both remotes or specific sides (A or B). ```bash # Break locks on both remotes syncrclone --break-lock both config.py # Break lock on side A only syncrclone --break-lock A config.py # Break lock on side B only syncrclone --break-lock B config.py ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.