Files
jared 24e0072c21
CI / Tests (Linux, Python 3.12) (push) Successful in 9m24s
feat: add PowerShell port for Windows users without Python
Adds tagsync.ps1, a self-contained PowerShell rewrite of the full
tagsync tool. Uses Invoke-RestMethod for Dropbox REST calls, DPAPI-
encrypted file for token storage, JSON for state, and native
Register-ScheduledTask for scheduling. Only external dependency is
exiftool.exe (same as the Python version).

Updates README to lead with the PowerShell quick start, with Python
instructions in a separate section below.
2026-04-20 16:54:52 -04:00

8.5 KiB

Dropbox Tag Sync

Bring Dropbox web tags down to your computer so you can search for tagged files in File Explorer (Windows) or Finder (macOS) as if they were first-class local tags.

The problem this solves

Dropbox lets you add tags to files from its web interface. Those tags live in Dropbox's cloud metadata — they are not stored inside the files themselves. The Dropbox desktop app syncs file contents, but it does not copy tags onto your local files. As a result, tags you rely on for search and organization show up on dropbox.com but are invisible to Finder, Spotlight, File Explorer, and Windows Search.

This tool closes that gap. It connects to Dropbox, reads each file's tags, and writes them to your local files in a form your operating system treats as a first-class tag.


Windows — PowerShell (no Python required)

Requirements: Windows 10/11, PowerShell 5.1+, ExifTool on your PATH.

Quick start

.\tagsync.ps1 wizard

If you get an execution policy error, run this first (once, per machine):

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

Commands

All commands are run as .\tagsync.ps1 <command>.

Command What it does
wizard Interactive setup (run this first)
run One-shot sync using saved settings
run -DryRun Show what would change without touching files
run -Verbose Show every file action during sync
status Show config, token presence, and schedule state
schedule install Install the background scheduled task
schedule install -Interval 30 Install, running every 30 minutes
schedule uninstall Remove the background scheduled task
schedule status Show whether the scheduled task is installed
reset -All Clear stored token, settings, and local state
reset -Token Clear only the token

Where things are stored (Windows / PowerShell)

Item Location
Token ~\.dropbox_tag_sync\token.dpapi (DPAPI-encrypted, current user only)
Settings ~\.dropbox_tag_sync\config.json
Local state cache ~\.dropbox_tag_sync\state.json
Scheduled task Task Scheduler, name: DropboxTagSync

Troubleshooting (Windows / PowerShell)

"exiftool not found" — install from https://exiftool.org/, place exiftool.exe on your PATH (e.g. C:\Windows\), then confirm exiftool -ver works in a terminal.

Windows tags don't show in Explorer — Explorer's Tags column may be hidden; right-click a column header and add Tags. Windows Search may need a few minutes to re-index.

"not found locally" — the file exists in Dropbox but hasn't synced down yet. Let Dropbox finish syncing, or mark the file as "always keep on this device" if it is online-only.

Token wrong or revoked — run .\tagsync.ps1 reset -Token, then .\tagsync.ps1 wizard to enter a new one.

State got into a weird state — run .\tagsync.ps1 reset -State. The next run will re-examine every file; no data is lost.


macOS / Windows — Python

Requirements: Python 3.9+, packages in requirements.txt, and (Windows only) ExifTool on your PATH.

Quick start

pip install -r requirements.txt
python tagsync.py wizard

The wizard detects your OS, finds your Dropbox folder, walks you through creating a read-only Dropbox access token, previews what will be tagged, applies the tags, and offers to install a background scheduler.

Commands

All commands are run as python tagsync.py <command>.

Command What it does
wizard Interactive setup (run this first)
run Perform a one-shot sync using saved settings
run --dry-run Show what would change without touching any files
status Show config, token presence, and schedule state
schedule install Install the background scheduled task
schedule install --interval 30 Install, running every 30 minutes
schedule uninstall Remove the background scheduled task
schedule status Show whether the scheduler is installed and loaded
reset --all Clear stored token, settings, and local state DB
reset --token Clear only the token

What's in this repo

File / folder Purpose
tagsync.ps1 PowerShell entry point (Windows, no Python)
tagsync.py Python CLI entry point
tagsync/ Python package with all the logic
requirements.txt Python dependencies

Inside tagsync/:

File Purpose
wizard.py Interactive setup flow
core.py Dropbox listing, tag fetching, sync loop
config.py Settings file + secure token storage
detect.py OS / Dropbox folder / dependency detection
platform_macos.py Finder-xattr writer + launchd scheduler
platform_windows.py ExifTool-based XMP writer + Task Scheduler

Where things are stored (Python)

Item Location
Token (preferred) macOS Keychain / Windows Credential Manager
Token (fallback) ~/.dropbox_tag_sync/token (mode 0600)
Settings ~/.dropbox_tag_sync/config.json
Local state cache ~/.dropbox_tag_sync/state.db
Log (macOS) ~/Library/Logs/dropbox-tag-sync.log
launchd plist ~/Library/LaunchAgents/com.dropboxtagsync.agent.plist
Windows task Task Scheduler, name: DropboxTagSync

How it works

  1. You create a Dropbox access token with read-only metadata scope. The wizard walks you through this.
  2. The tool lists every file in your Dropbox and asks Dropbox which tags each file has.
  3. For files whose tags have changed since the last run, it writes those tags to the local copy.
  4. A small state cache remembers what was written so subsequent runs only touch files whose tags actually changed.

Nothing is ever deleted from Dropbox. The tool only reads from Dropbox and writes to local files on your machine.

The important platform difference

macOS and Windows store "file tags" in fundamentally different ways.

macOS — clean and invisible

macOS has a universal, built-in tag system. Tags are stored in an extended attribute (xattr) alongside the file, not inside it. The tool writes the xattr directly. Consequences:

  • Every file type can be tagged (text, zip, source code, anything).
  • The file's contents are untouched, so Dropbox does not see the file as modified and does not re-upload it.
  • The file's modification time does not change.

Windows — embeds tags into the file

Windows has no universal tag store. The "Tags" field in Explorer is actually the XMP:Subject metadata field embedded inside the file.

Consequences:

  • Only file formats that support XMP (images, PDFs, Office docs, most audio and video) can be tagged. The tool skips unsupported formats by default and can optionally write a .tags.json sidecar next to them instead.
  • Because the tag lives inside the file, writing it does modify the file. Dropbox will notice and re-upload the file once.
  • If Dropbox Smart Sync leaves some files online-only, tagging one would trigger a download. The tool can skip online-only files (on by default in the wizard).

Plan for the first Windows run. If there are many tagged files, the first run will queue a large number of re-uploads. Schedule it overnight, on a good connection, and expect a one-time spike in Dropbox activity. Subsequent runs are quiet.

One-time Dropbox app setup

The wizard will open this page and walk you through it, but for reference:

  1. Go to https://www.dropbox.com/developers/apps and click Create app.
  2. Choose:
    • Scoped access
    • Full Dropbox
    • A name of your choosing (e.g. tag-sync)
  3. Open the Permissions tab and enable files.metadata.read.
  4. Click Submit.
  5. On the Settings tab, scroll to OAuth 2 → Generated access token and click Generate. Paste that token into the wizard.

The generated token only has permission to read file metadata. It cannot modify anything in Dropbox even if it leaked.

Safety summary

  • Read-only with Dropbox (token scope: files.metadata.read).
  • Non-destructive on macOS: only extended attributes are written.
  • Content-modifying on Windows: rewrites the XMP metadata section of supported files (one-time re-upload per tagged file is expected).
  • Idempotent: safe to run as often as you like.
  • Resumable: if interrupted, the next run picks up where it left off.
  • One-way: tags flow cloud → local only. Tagging on the web is still the source of truth.