|
1 | 1 | # Mergin Maps Media Sync |
2 | | -Sync media files from Mergin Maps projects to other storage backends. Currently, supported backend are MinIO (S3-like) backend, Google Drive and local drive (mostly used for testing). |
| 2 | +Sync media files from Mergin Maps projects to other storage backends. Currently, supported backends are MinIO (S3-like), Dropbox, Google Drive and local drive (mostly used for testing). |
3 | 3 |
|
4 | 4 | Sync works in two modes, in COPY mode, where media files are only copied to external drive and MOVE mode, where files are |
5 | 5 | subsequently removed from Mergin Maps project (on cloud). |
@@ -68,6 +68,58 @@ docker run -it \ |
68 | 68 |
|
69 | 69 | The specification of `MINIO__BUCKET_SUBPATH` is optional and can be skipped if the files should be stored directly in `MINIO__BUCKET`. |
70 | 70 |
|
| 71 | +#### Using Dropbox backend |
| 72 | + |
| 73 | +You will need a Dropbox app with an OAuth2 refresh token. Follow these steps once to generate your credentials: |
| 74 | + |
| 75 | +1. Go to [https://www.dropbox.com/developers/apps](https://www.dropbox.com/developers/apps) and create a new app. |
| 76 | + - Choose **Scoped access** → **Full Dropbox** (or **App folder** if you prefer isolation). |
| 77 | + - Under _Permissions_, enable **`files.content.write`** and **`sharing.write`**, then save. |
| 78 | +2. On the app's _Settings_ tab, note your **App key** and **App secret**. |
| 79 | +3. Generate a refresh token by running the following and following the prompts: |
| 80 | + ```shell |
| 81 | + pip install dropbox |
| 82 | + python3 - <<'EOF' |
| 83 | + import dropbox |
| 84 | + from dropbox import DropboxOAuth2FlowNoRedirect |
| 85 | +
|
| 86 | + APP_KEY = "<your_app_key>" |
| 87 | + APP_SECRET = "<your_app_secret>" |
| 88 | +
|
| 89 | + auth_flow = DropboxOAuth2FlowNoRedirect(APP_KEY, APP_SECRET, token_access_type="offline") |
| 90 | + print("Authorize this app:", auth_flow.start()) |
| 91 | + code = input("Enter auth code: ").strip() |
| 92 | + result = auth_flow.finish(code) |
| 93 | + print("Refresh token:", result.refresh_token) |
| 94 | + EOF |
| 95 | + ``` |
| 96 | +4. Copy the printed **refresh token** — this is a long-lived credential that media-sync uses to authenticate. |
| 97 | +
|
| 98 | +```shell |
| 99 | +docker run -it \ |
| 100 | + --name mergin-media-sync \ |
| 101 | + -e MERGIN__USERNAME=john \ |
| 102 | + -e MERGIN__PASSWORD=myStrongPassword \ |
| 103 | + -e MERGIN__PROJECT_NAME=john/my_project \ |
| 104 | + -e DRIVER=dropbox \ |
| 105 | + -e DROPBOX__APP_KEY=your_app_key \ |
| 106 | + -e DROPBOX__APP_SECRET=your_app_secret \ |
| 107 | + -e DROPBOX__REFRESH_TOKEN=your_refresh_token \ |
| 108 | + -e DROPBOX__FOLDER=mediasync \ |
| 109 | + lutraconsulting/mergin-media-sync python3 media_sync_daemon.py |
| 110 | +``` |
| 111 | +
|
| 112 | +Uploaded files are exposed as direct-download shared links (`?dl=1`) stored in the GeoPackage reference column. If a shared link already exists for a file it is reused automatically. |
| 113 | +
|
| 114 | +`DROPBOX__FOLDER` is optional. When set, all files are placed under that folder in your Dropbox (e.g. `DROPBOX__FOLDER=mediasync` stores files at `/mediasync/img1.png`). |
| 115 | +
|
| 116 | +| Environment variable | Required | Description | |
| 117 | +|---|---|---| |
| 118 | +| `DROPBOX__APP_KEY` | yes | Dropbox app key (from the developer console) | |
| 119 | +| `DROPBOX__APP_SECRET` | yes | Dropbox app secret (from the developer console) | |
| 120 | +| `DROPBOX__REFRESH_TOKEN` | yes | Long-lived OAuth2 refresh token (generated above) | |
| 121 | +| `DROPBOX__FOLDER` | no | Root folder inside Dropbox for all uploaded files | |
| 122 | +
|
71 | 123 | #### Using Google Drive backend |
72 | 124 | For setup instructions and more details, please refer to our [Google Drive guide](./docs/google-drive-setup.md). |
73 | 125 |
|
@@ -136,6 +188,11 @@ To run automatic tests: |
136 | 188 | export TEST_MINIO_URL="localhost:9000" |
137 | 189 | export TEST_MINIO_ACCESS_KEY=EXAMPLE |
138 | 190 | export TEST_MINIO_SECRET_KEY=EXAMPLEKEY |
| 191 | + # Dropbox backend tests (optional) |
| 192 | + export TEST_DROPBOX_APP_KEY=<app_key> |
| 193 | + export TEST_DROPBOX_APP_SECRET=<app_secret> |
| 194 | + export TEST_DROPBOX_REFRESH_TOKEN=<refresh_token> |
| 195 | + export TEST_DROPBOX_FOLDER=mediasync-test |
139 | 196 | pipenv run pytest test/ |
140 | 197 | ``` |
141 | 198 |
|
|
0 commit comments