Files
immish/docs/backup.md

340 lines
13 KiB
Markdown

# Backup & Upload
This document describes the photo/video backup functionality, including foreground and background uploads.
## Backup Overview
The backup system automatically uploads photos and videos from the device to the server:
```
┌─────────────────────────────────────────────────────────────┐
│ Backup Flow │
├─────────────────────────────────────────────────────────────┤
│ Device Photos → Backup Service → Server │
│ │
│ 1. Select albums to backup │
│ 2. Find new/changed assets │
│ 3. Check for duplicates (hash) │
│ 4. Upload assets │
│ 5. Update local database │
└─────────────────────────────────────────────────────────────┘
```
## Backup Configuration
### Backup Controller Screen
```
┌─────────────────────────────────────────────────────────────┐
│ ← Backup │
├─────────────────────────────────────────────────────────────┤
│ Backup Status │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ✓ Backup Complete │ │
│ │ 1,234 of 1,234 backed up │ │
│ │ Last backup: 2 hours ago │ │
│ └─────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Backup Albums │
│ [Select albums to backup] │
├─────────────────────────────────────────────────────────────┤
│ Excluded Albums │
│ [Select albums to exclude] │
├─────────────────────────────────────────────────────────────┤
│ Settings │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Background Backup [Toggle: ON] │ │
│ │ Use Wi-Fi only [Toggle: ON] │ │
│ │ Require charging [Toggle: OFF] │ │
│ │ Ignore iCloud assets [Toggle: OFF] │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## Album Selection
### Backup Albums
- Select which device albums to back up
- "Recents" includes all photos
- Individual albums for selective backup
### Excluded Albums
- Exclude specific albums
- Useful for Screenshots, WhatsApp Images, etc.
- Takes precedence over selected albums
### Album Selection Logic
```
Backup Candidates = Selected Albums - Excluded Albums
If "Recents" selected (Android):
- Back up all device photos
- Individual album folders tracked for sync
If "Recents" selected (iOS):
- Use "All Photos" album
- Check against excluded albums per asset
```
## Backup Process
### Step 1: Build Upload Candidates
```
1. Get selected backup albums
2. Get excluded backup albums
3. For each selected album:
a. Check if album modified since last backup
b. Get assets newer than last backup time
c. Add album name to asset metadata
4. Remove assets from excluded albums
```
### Step 2: Remove Already Uploaded
```
1. Check local duplicates database
2. Call server to check existing assets
POST /assets/exist
Body:
{
"deviceAssetIds": ["local-id-1", "local-id-2", ...],
"deviceId": "device-uuid"
}
Response:
{
"existingIds": ["local-id-1"]
}
```
### Step 3: Upload Assets
For each asset:
```
1. Get original file from device
2. If live photo, also get video component
3. Calculate upload metadata
4. Upload via multipart form
POST /assets
Content-Type: multipart/form-data
Fields:
- deviceAssetId: local ID
- deviceId: device UUID
- fileCreatedAt: creation timestamp
- fileModifiedAt: modification timestamp
- isFavorite: boolean
- duration: video duration
Files:
- assetData: the file
- livePhotoData: motion video (if applicable)
```
### Step 4: Handle Response
```
200 OK: Asset already exists (duplicate)
201 Created: Asset uploaded successfully
Response:
{
"id": "remote-asset-uuid",
"deviceAssetId": "local-id",
...
}
```
## Upload Progress Tracking
### Progress Model
```
CurrentUploadAsset {
id: String // Local asset ID
fileName: String // File name
fileType: String // IMAGE, VIDEO, etc.
fileSize: Integer // Bytes
fileCreatedAt: DateTime
iCloudAsset: Boolean // Downloading from iCloud
}
UploadProgress {
bytesUploaded: Integer
totalBytes: Integer
percentage: Double
}
```
### Progress UI
```
┌─────────────────────────────────────────────────────────────┐
│ Uploading... │
│ │
│ IMG_1234.jpg │
│ [████████████░░░░░░░░░░░░░░░░░] 45% │
│ │
│ 12 of 50 • 2.4 MB / 5.1 MB │
└─────────────────────────────────────────────────────────────┘
```
## Background Backup
### Platform Differences
**Android:**
- Uses WorkManager for scheduling
- Triggers on content changes
- Requires battery optimization disabled
**iOS:**
- Uses Background App Refresh
- Limited execution time
- BGProcessingTask for longer uploads
### Background Service Configuration
```
RequireUnmetered: true/false // Wi-Fi only
RequireCharging: true/false // Charging only
TriggerDelay: 5000ms // Minimum delay
MaxDelay: 50000ms // Maximum delay
```
### Background Notification
```
┌─────────────────────────────────────────────────────────────┐
│ Immich │
│ Uploading 12/50 photos... │
│ [Progress bar] │
└─────────────────────────────────────────────────────────────┘
```
### Background Process Flow
```
1. System triggers background task
2. Acquire lock (prevent concurrent runs)
3. Load translations
4. Initialize database
5. Set API endpoint
6. Get selected/excluded albums
7. Run backup process
8. Update last backup timestamps
9. Release lock
```
## iCloud Assets (iOS)
### Handling iCloud Photos
1. Check if asset is locally available
2. If not, option to download from iCloud
3. Show progress during download
4. Upload after download complete
### Settings
- `ignoreIcloudAssets`: Skip assets not on device
## Album Sync Feature
### Purpose
Automatically organize uploads into server albums matching device album names.
### How It Works
1. Asset uploaded with album names in metadata
2. After upload, check for matching albums
3. Create album if doesn't exist
4. Add asset to album
### API
```
POST /albums/{albumName}/assets
Body:
{
"assetIds": ["uploaded-asset-id"]
}
```
## Duplicate Detection
### Hash-Based Detection
1. Calculate file hash (checksum)
2. Store in local duplicates database
3. Skip uploads for known duplicates
### Server-Side Check
```
POST /assets/exist
Checks if assets already on server by device ID + local ID
```
## Error Handling
### Retry Logic
- Failed uploads retry automatically
- Exponential backoff
- Maximum retry attempts
### Error Notifications
```
┌─────────────────────────────────────────────────────────────┐
│ ⚠️ Upload Failed │
│ IMG_5678.jpg could not be uploaded │
│ Error: Network connection lost │
└─────────────────────────────────────────────────────────────┘
```
### Common Errors
| Error | Cause | Action |
|-------|-------|--------|
| Network error | No connection | Retry when online |
| Quota exceeded | Storage full | Stop backup, notify user |
| File not found | Asset deleted | Skip asset |
| Permission denied | Gallery access lost | Request permission |
## Failed Uploads Screen
### Layout
```
┌─────────────────────────────────────────────────────────────┐
│ ← Failed Uploads │
├─────────────────────────────────────────────────────────────┤
│ 5 uploads failed │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 📷 IMG_1234.jpg │ │
│ │ Network timeout │ │
│ │ [Retry] │ │
│ └─────────────────────────────────────────────────────┘ │
│ ... │
├─────────────────────────────────────────────────────────────┤
│ [Retry All] │
└─────────────────────────────────────────────────────────────┘
```
## Backup Statistics
### Tracked Metrics
- Total assets to backup
- Successfully uploaded
- Failed uploads
- Duplicate (already on server)
- Last backup timestamp
### Storage Usage
```
GET /users/me
Response includes:
{
"quotaUsageInBytes": 1234567890,
"quotaSizeInBytes": 10737418240
}
```
## Cellular Data Settings
### Options
- `useCellularForUploadPhotos`: Allow photo upload on cellular
- `useCellularForUploadVideos`: Allow video upload on cellular
---
[Previous: Gallery Viewer](./gallery-viewer.md) | [Next: Download](./download.md)