add docs part 1
This commit is contained in:
+339
@@ -0,0 +1,339 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user