| 1 |
# Phase 3: Remote Image Sources |
| 2 |
|
| 3 |
## Goal |
| 4 |
Implement multiple image source providers for fetching wallpapers from various remote locations. |
| 5 |
|
| 6 |
## Tasks |
| 7 |
|
| 8 |
### 3.1 Provider Architecture |
| 9 |
- [ ] Define `SourceProvider` trait |
| 10 |
- [ ] Create `ProviderRegistry` for provider lookup |
| 11 |
- [ ] URI-based provider selection |
| 12 |
- [ ] Async fetch operations |
| 13 |
|
| 14 |
### 3.2 HTTP Provider |
| 15 |
- [ ] Fetch images from direct URLs |
| 16 |
- [ ] Support redirects and HTTPS |
| 17 |
- [ ] Handle common HTTP errors |
| 18 |
- [ ] Respect Content-Type headers |
| 19 |
|
| 20 |
### 3.3 GitHub Provider |
| 21 |
- [ ] Parse `github://user/repo/path` URIs |
| 22 |
- [ ] Use GitHub API for directory listings |
| 23 |
- [ ] Fetch raw file content |
| 24 |
- [ ] Handle rate limiting (with optional token) |
| 25 |
|
| 26 |
### 3.4 Directory Index Provider |
| 27 |
- [ ] Parse Apache autoindex HTML |
| 28 |
- [ ] Parse nginx autoindex HTML |
| 29 |
- [ ] Extract image links from listings |
| 30 |
- [ ] Support recursive directory traversal |
| 31 |
|
| 32 |
### 3.5 S3 Provider (Optional Feature) |
| 33 |
- [ ] Parse `s3://bucket/prefix` URIs |
| 34 |
- [ ] List objects with prefix |
| 35 |
- [ ] Support S3-compatible endpoints (MinIO, etc.) |
| 36 |
- [ ] Handle authentication |
| 37 |
|
| 38 |
### 3.6 Disk Cache |
| 39 |
- [ ] Cache fetched images to ~/.cache/garbg/ |
| 40 |
- [ ] LRU eviction when cache exceeds size limit |
| 41 |
- [ ] Store metadata (URL, fetch time, ETag) |
| 42 |
- [ ] Conditional requests for cache validation |
| 43 |
|
| 44 |
## Deliverables |
| 45 |
- `garbg set https://example.com/wallpaper.png` fetches and displays |
| 46 |
- `garbg set github://user/repo/wallpapers/` lists and picks random |
| 47 |
- Directory index URLs work for bulk wallpaper sources |
| 48 |
- Fetched images are cached locally |
| 49 |
|
| 50 |
## Provider Trait |
| 51 |
|
| 52 |
```rust |
| 53 |
#[async_trait] |
| 54 |
pub trait SourceProvider: Send + Sync { |
| 55 |
/// Provider identifier |
| 56 |
fn id(&self) -> &str; |
| 57 |
|
| 58 |
/// Check if this provider handles a URI |
| 59 |
fn can_handle(&self, uri: &str) -> bool; |
| 60 |
|
| 61 |
/// List available wallpapers from source |
| 62 |
async fn list(&self, uri: &str) -> Result<Vec<WallpaperEntry>>; |
| 63 |
|
| 64 |
/// Fetch a specific wallpaper |
| 65 |
async fn fetch(&self, entry: &WallpaperEntry) -> Result<FetchedImage>; |
| 66 |
} |
| 67 |
|
| 68 |
pub struct WallpaperEntry { |
| 69 |
pub uri: String, |
| 70 |
pub name: String, |
| 71 |
pub media_type: MediaType, |
| 72 |
pub size: Option<u64>, |
| 73 |
} |
| 74 |
|
| 75 |
pub enum MediaType { |
| 76 |
StaticImage, |
| 77 |
AnimatedImage, |
| 78 |
Video, |
| 79 |
} |
| 80 |
``` |
| 81 |
|
| 82 |
## URI Schemes |
| 83 |
|
| 84 |
| Scheme | Example | Provider | |
| 85 |
|--------|---------|----------| |
| 86 |
| (none) | `/path/to/file.png` | FileProvider | |
| 87 |
| `file://` | `file:///path/to/file.png` | FileProvider | |
| 88 |
| `http://` | `http://example.com/img.png` | HttpProvider | |
| 89 |
| `https://` | `https://example.com/img.png` | HttpProvider | |
| 90 |
| `github://` | `github://user/repo/path` | GitHubProvider | |
| 91 |
| `s3://` | `s3://bucket/prefix` | S3Provider | |
| 92 |
|
| 93 |
## Cache Structure |
| 94 |
|
| 95 |
``` |
| 96 |
~/.cache/garbg/ |
| 97 |
├── index.json # Cache index with metadata |
| 98 |
├── ab/ # First 2 chars of hash |
| 99 |
│ └── abcd1234... # Cached image file |
| 100 |
├── cd/ |
| 101 |
│ └── cdef5678... |
| 102 |
└── ... |
| 103 |
``` |
| 104 |
|
| 105 |
## Files Modified/Created |
| 106 |
- `/garbg/garbg/src/sources/mod.rs` - Sources module |
| 107 |
- `/garbg/garbg/src/sources/provider.rs` - Provider trait |
| 108 |
- `/garbg/garbg/src/sources/file.rs` - Local file provider |
| 109 |
- `/garbg/garbg/src/sources/http.rs` - HTTP provider |
| 110 |
- `/garbg/garbg/src/sources/github.rs` - GitHub provider |
| 111 |
- `/garbg/garbg/src/sources/directory.rs` - Directory index parser |
| 112 |
- `/garbg/garbg/src/sources/s3.rs` - S3 provider (optional) |
| 113 |
- `/garbg/garbg/src/cache/mod.rs` - Cache module |
| 114 |
- `/garbg/garbg/src/cache/disk.rs` - Disk cache implementation |