litemm 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- litemm-0.1.0/.gitignore +15 -0
- litemm-0.1.0/.python-version +1 -0
- litemm-0.1.0/PKG-INFO +356 -0
- litemm-0.1.0/README.md +333 -0
- litemm-0.1.0/package-lock.json +119 -0
- litemm-0.1.0/package.json +8 -0
- litemm-0.1.0/pyproject.toml +54 -0
- litemm-0.1.0/src/mm/__init__.py +9 -0
- litemm-0.1.0/src/mm/_version.py +34 -0
- litemm-0.1.0/src/mm/cli/__init__.py +82 -0
- litemm-0.1.0/src/mm/cli/_utils.py +210 -0
- litemm-0.1.0/src/mm/cli/config_cmd.py +53 -0
- litemm-0.1.0/src/mm/cli/db/__init__.py +127 -0
- litemm-0.1.0/src/mm/cli/db/clean.py +71 -0
- litemm-0.1.0/src/mm/cli/db/stats.py +310 -0
- litemm-0.1.0/src/mm/cli/db/sync.py +108 -0
- litemm-0.1.0/src/mm/cli/dedup.py +55 -0
- litemm-0.1.0/src/mm/cli/geo.py +61 -0
- litemm-0.1.0/src/mm/cli/importer.py +104 -0
- litemm-0.1.0/src/mm/cli/info.py +63 -0
- litemm-0.1.0/src/mm/cli/init.py +64 -0
- litemm-0.1.0/src/mm/cli/search.py +94 -0
- litemm-0.1.0/src/mm/cli/server.py +56 -0
- litemm-0.1.0/src/mm/config.py +208 -0
- litemm-0.1.0/src/mm/core/__init__.py +1 -0
- litemm-0.1.0/src/mm/core/dedup.py +44 -0
- litemm-0.1.0/src/mm/core/embeddings.py +143 -0
- litemm-0.1.0/src/mm/core/geocoding.py +427 -0
- litemm-0.1.0/src/mm/core/importer.py +138 -0
- litemm-0.1.0/src/mm/core/metadata.py +318 -0
- litemm-0.1.0/src/mm/core/scanner.py +155 -0
- litemm-0.1.0/src/mm/core/tagger.py +144 -0
- litemm-0.1.0/src/mm/core/thumbnail.py +275 -0
- litemm-0.1.0/src/mm/db/__init__.py +5 -0
- litemm-0.1.0/src/mm/db/_seed.py +170 -0
- litemm-0.1.0/src/mm/db/async_repository.py +68 -0
- litemm-0.1.0/src/mm/db/dto.py +76 -0
- litemm-0.1.0/src/mm/db/helpers.py +126 -0
- litemm-0.1.0/src/mm/db/mixins/__init__.py +11 -0
- litemm-0.1.0/src/mm/db/mixins/_albums.py +98 -0
- litemm-0.1.0/src/mm/db/mixins/_cli.py +275 -0
- litemm-0.1.0/src/mm/db/mixins/_config.py +53 -0
- litemm-0.1.0/src/mm/db/mixins/_media.py +240 -0
- litemm-0.1.0/src/mm/db/mixins/_metadata.py +63 -0
- litemm-0.1.0/src/mm/db/mixins/_smart_albums.py +185 -0
- litemm-0.1.0/src/mm/db/mixins/_stats.py +393 -0
- litemm-0.1.0/src/mm/db/mixins/_tags.py +110 -0
- litemm-0.1.0/src/mm/db/mixins/_users.py +85 -0
- litemm-0.1.0/src/mm/db/models.py +228 -0
- litemm-0.1.0/src/mm/db/sync_repo.py +41 -0
- litemm-0.1.0/src/mm/db/vector_store.py +102 -0
- litemm-0.1.0/src/mm/server/__init__.py +0 -0
- litemm-0.1.0/src/mm/server/app.py +105 -0
- litemm-0.1.0/src/mm/server/dependencies.py +140 -0
- litemm-0.1.0/src/mm/server/routers/albums.py +81 -0
- litemm-0.1.0/src/mm/server/routers/auth.py +98 -0
- litemm-0.1.0/src/mm/server/routers/batch.py +56 -0
- litemm-0.1.0/src/mm/server/routers/library.py +136 -0
- litemm-0.1.0/src/mm/server/routers/media.py +318 -0
- litemm-0.1.0/src/mm/server/routers/smart_albums.py +124 -0
- litemm-0.1.0/src/mm/server/routers/stats.py +63 -0
- litemm-0.1.0/src/mm/server/routers/tags.py +44 -0
- litemm-0.1.0/src/mm/server/routers/users.py +59 -0
- litemm-0.1.0/src/mm/server/schemas.py +203 -0
- litemm-0.1.0/src/mm/server/smart_albums.py +447 -0
- litemm-0.1.0/src/mm/server/utils.py +94 -0
- litemm-0.1.0/tests/conftest.py +21 -0
- litemm-0.1.0/tests/test_dedup.py +77 -0
- litemm-0.1.0/tests/test_repository.py +77 -0
- litemm-0.1.0/tests/test_scanner.py +40 -0
- litemm-0.1.0/uv.lock +2411 -0
- litemm-0.1.0/web/.gitignore +24 -0
- litemm-0.1.0/web/README.md +73 -0
- litemm-0.1.0/web/eslint.config.js +23 -0
- litemm-0.1.0/web/index.html +18 -0
- litemm-0.1.0/web/package-lock.json +4545 -0
- litemm-0.1.0/web/package.json +42 -0
- litemm-0.1.0/web/public/vite.svg +1 -0
- litemm-0.1.0/web/src/App.tsx +38 -0
- litemm-0.1.0/web/src/api/client.ts +28 -0
- litemm-0.1.0/web/src/api/types.ts +136 -0
- litemm-0.1.0/web/src/components/album-card.tsx +67 -0
- litemm-0.1.0/web/src/components/auth-image.tsx +43 -0
- litemm-0.1.0/web/src/components/bottom-bar.tsx +333 -0
- litemm-0.1.0/web/src/components/floating-search-bar.tsx +640 -0
- litemm-0.1.0/web/src/components/gallery/gallery-grid.tsx +54 -0
- litemm-0.1.0/web/src/components/gallery/index.ts +4 -0
- litemm-0.1.0/web/src/components/gallery/justified-gallery.tsx +120 -0
- litemm-0.1.0/web/src/components/gallery/media-tile.tsx +177 -0
- litemm-0.1.0/web/src/components/media-detail/index.ts +2 -0
- litemm-0.1.0/web/src/components/media-detail/info-dialog.tsx +546 -0
- litemm-0.1.0/web/src/components/media-detail/media-detail-panel.tsx +216 -0
- litemm-0.1.0/web/src/components/media-detail.tsx +3 -0
- litemm-0.1.0/web/src/components/menu-dropdown.tsx +327 -0
- litemm-0.1.0/web/src/components/ui/button.tsx +42 -0
- litemm-0.1.0/web/src/components/ui/card.tsx +23 -0
- litemm-0.1.0/web/src/components/ui/input.tsx +20 -0
- litemm-0.1.0/web/src/components/ui/scroll-area.tsx +46 -0
- litemm-0.1.0/web/src/components/ui/select.tsx +20 -0
- litemm-0.1.0/web/src/components/ui/star-rating.tsx +41 -0
- litemm-0.1.0/web/src/hooks/use-detail-panel.ts +45 -0
- litemm-0.1.0/web/src/hooks/use-infinite-scroll.ts +33 -0
- litemm-0.1.0/web/src/hooks/use-pinch-zoom.ts +61 -0
- litemm-0.1.0/web/src/index.css +81 -0
- litemm-0.1.0/web/src/layouts/app-layout.tsx +565 -0
- litemm-0.1.0/web/src/lib/format.ts +105 -0
- litemm-0.1.0/web/src/lib/icons.ts +33 -0
- litemm-0.1.0/web/src/lib/media-url.ts +33 -0
- litemm-0.1.0/web/src/lib/utils.ts +6 -0
- litemm-0.1.0/web/src/main.tsx +12 -0
- litemm-0.1.0/web/src/pages/albums.tsx +487 -0
- litemm-0.1.0/web/src/pages/dashboard.tsx +81 -0
- litemm-0.1.0/web/src/pages/login.tsx +68 -0
- litemm-0.1.0/web/src/pages/media-library.tsx +648 -0
- litemm-0.1.0/web/src/pages/profile.tsx +46 -0
- litemm-0.1.0/web/src/pages/settings.tsx +343 -0
- litemm-0.1.0/web/src/stores/album-section.ts +22 -0
- litemm-0.1.0/web/src/stores/auth.ts +62 -0
- litemm-0.1.0/web/src/stores/media.ts +219 -0
- litemm-0.1.0/web/src/stores/theme.ts +354 -0
- litemm-0.1.0/web/tsconfig.app.json +40 -0
- litemm-0.1.0/web/tsconfig.json +7 -0
- litemm-0.1.0/web/tsconfig.node.json +26 -0
- litemm-0.1.0/web/vite.config.ts +38 -0
litemm-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
litemm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: litemm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Media Manager & Visualizer
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: aiosqlite>=0.22.1
|
|
7
|
+
Requires-Dist: click>=8.3.1
|
|
8
|
+
Requires-Dist: fastapi[standard]>=0.115
|
|
9
|
+
Requires-Dist: lunar-python>=1.4.8
|
|
10
|
+
Requires-Dist: numpy>=1.24
|
|
11
|
+
Requires-Dist: peewee-aio>=2.2.2
|
|
12
|
+
Requires-Dist: peewee-async>=1.2.1
|
|
13
|
+
Requires-Dist: peewee>=3.19.0
|
|
14
|
+
Requires-Dist: pillow-heif>=0.18
|
|
15
|
+
Requires-Dist: pillow>=10.0
|
|
16
|
+
Requires-Dist: pyyaml>=6.0
|
|
17
|
+
Requires-Dist: rawpy>=0.26.1
|
|
18
|
+
Provides-Extra: clip
|
|
19
|
+
Requires-Dist: open-clip-torch>=2.24; extra == 'clip'
|
|
20
|
+
Requires-Dist: pillow>=10.0; extra == 'clip'
|
|
21
|
+
Requires-Dist: torch>=2.0; extra == 'clip'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
<div align="center">
|
|
25
|
+
|
|
26
|
+
# 📸 MM — Universal Organizer for Media
|
|
27
|
+
|
|
28
|
+
**A self-hosted, AI-powered media library manager for photos, videos, and audio.**
|
|
29
|
+
|
|
30
|
+
Scan, tag, search, deduplicate, and browse your media collection with a beautiful web UI.
|
|
31
|
+
|
|
32
|
+
[](https://github.com/HSPK/mm/stargazers)
|
|
33
|
+
[](https://github.com/HSPK/mm/network/members)
|
|
34
|
+
[](https://github.com/HSPK/mm/issues)
|
|
35
|
+
[](https://github.com/HSPK/mm/commits)
|
|
36
|
+
[](https://github.com/HSPK/mm/blob/main/LICENSE)
|
|
37
|
+
[](https://python.org)
|
|
38
|
+
[](https://typescriptlang.org)
|
|
39
|
+
[](https://fastapi.tiangolo.com)
|
|
40
|
+
[](https://react.dev)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
[Features](#-features) · [Quick Start](#-quick-start) · [Installation](#-installation) · [Usage](#-usage) · [Web UI](#-web-ui) · [API](#-api) · [Contributing](#-contributing)
|
|
45
|
+
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ✨ Features
|
|
51
|
+
|
|
52
|
+
<table>
|
|
53
|
+
<tr>
|
|
54
|
+
<td width="50%">
|
|
55
|
+
|
|
56
|
+
### 🔍 Smart Scanning
|
|
57
|
+
- Recursive media discovery with parallel processing
|
|
58
|
+
- SHA-256 hashing for integrity & deduplication
|
|
59
|
+
- EXIF, video, and audio metadata extraction
|
|
60
|
+
- Support for RAW, HEIC/HEIF, and 30+ formats
|
|
61
|
+
|
|
62
|
+
</td>
|
|
63
|
+
<td width="50%">
|
|
64
|
+
|
|
65
|
+
### 🤖 AI-Powered
|
|
66
|
+
- CLIP-based image embeddings (ViT-B-32)
|
|
67
|
+
- Natural language image search ("sunset over ocean")
|
|
68
|
+
- Zero-shot auto-tagging (~36 categories)
|
|
69
|
+
- Visual similarity search
|
|
70
|
+
|
|
71
|
+
</td>
|
|
72
|
+
</tr>
|
|
73
|
+
<tr>
|
|
74
|
+
<td>
|
|
75
|
+
|
|
76
|
+
### 🌍 Offline Geocoding
|
|
77
|
+
- Reverse geocoding from GPS EXIF data
|
|
78
|
+
- GeoNames cities15000 dataset (no API keys needed)
|
|
79
|
+
- Chinese province/city name support
|
|
80
|
+
- Chinese lunar & solar festival detection
|
|
81
|
+
|
|
82
|
+
</td>
|
|
83
|
+
<td>
|
|
84
|
+
|
|
85
|
+
### 🖼️ Beautiful Web UI
|
|
86
|
+
- Responsive gallery with justified layout
|
|
87
|
+
- Pinch-to-zoom thumbnail resizing
|
|
88
|
+
- Infinite scroll with date grouping
|
|
89
|
+
- Detail panel with full metadata & map
|
|
90
|
+
|
|
91
|
+
</td>
|
|
92
|
+
</tr>
|
|
93
|
+
<tr>
|
|
94
|
+
<td>
|
|
95
|
+
|
|
96
|
+
### 📁 Library Management
|
|
97
|
+
- Manual & smart albums (auto-generated)
|
|
98
|
+
- Star ratings, tags, batch operations
|
|
99
|
+
- Template-based file import & organization
|
|
100
|
+
- Multi-library support with runtime switching
|
|
101
|
+
|
|
102
|
+
</td>
|
|
103
|
+
<td>
|
|
104
|
+
|
|
105
|
+
### ⚡ Performance
|
|
106
|
+
- SQLite-backed (zero config, portable)
|
|
107
|
+
- WebP thumbnail caching (4 sizes) with ETag
|
|
108
|
+
- Async API server (FastAPI + Uvicorn)
|
|
109
|
+
- Background CLIP processing
|
|
110
|
+
|
|
111
|
+
</td>
|
|
112
|
+
</tr>
|
|
113
|
+
</table>
|
|
114
|
+
|
|
115
|
+
## 🏗️ Architecture
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
119
|
+
│ Web UI (React) │
|
|
120
|
+
│ React 19 · TailwindCSS · Zustand · Vite │
|
|
121
|
+
└──────────────────┬───────────────────────────────────────────┘
|
|
122
|
+
│ REST API
|
|
123
|
+
┌──────────────────▼───────────────────────────────────────────┐
|
|
124
|
+
│ FastAPI Server │
|
|
125
|
+
│ Auth · Media · Albums · Smart Albums · Tags · Stats │
|
|
126
|
+
└──────────────────┬───────────────────────────────────────────┘
|
|
127
|
+
│
|
|
128
|
+
┌──────────────────▼───────────────────────────────────────────┐
|
|
129
|
+
│ Core Engines │
|
|
130
|
+
│ Scanner · Metadata · Embeddings · Tagger · Geocoding · ... │
|
|
131
|
+
└──────────────────┬───────────────────────────────────────────┘
|
|
132
|
+
│
|
|
133
|
+
┌──────────────────▼───────────────────────────────────────────┐
|
|
134
|
+
│ SQLite (Peewee ORM / aiosqlite) │
|
|
135
|
+
│ Media · Metadata · Tags · Embeddings · Albums │
|
|
136
|
+
└──────────────────────────────────────────────────────────────┘
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 🚀 Quick Start
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Install with uv (recommended)
|
|
143
|
+
uv pip install -e .
|
|
144
|
+
|
|
145
|
+
# Create a new library (interactive)
|
|
146
|
+
mm init ~/Photos
|
|
147
|
+
|
|
148
|
+
# Start the web server
|
|
149
|
+
mm server
|
|
150
|
+
# → Open http://localhost:8000
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## 📦 Installation
|
|
154
|
+
|
|
155
|
+
### Prerequisites
|
|
156
|
+
|
|
157
|
+
- **Python 3.10+**
|
|
158
|
+
- **[uv](https://docs.astral.sh/uv/)** (recommended) or pip
|
|
159
|
+
- **exiftool** — for EXIF metadata extraction
|
|
160
|
+
- **ffmpeg** / **ffprobe** — for video/audio metadata & thumbnails
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# macOS
|
|
164
|
+
brew install exiftool ffmpeg
|
|
165
|
+
|
|
166
|
+
# Ubuntu / Debian
|
|
167
|
+
sudo apt install libimage-exiftool-perl ffmpeg
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Install mm
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Clone the repository
|
|
174
|
+
git clone https://github.com/HSPK/mm.git
|
|
175
|
+
cd mm
|
|
176
|
+
|
|
177
|
+
# Install with uv
|
|
178
|
+
uv pip install -e .
|
|
179
|
+
|
|
180
|
+
# (Optional) Install CLIP support for AI features
|
|
181
|
+
uv pip install -e ".[clip]"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Build the Frontend
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
cd web
|
|
188
|
+
npm install
|
|
189
|
+
npm run build
|
|
190
|
+
cd ..
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 📖 Usage
|
|
194
|
+
|
|
195
|
+
### CLI Commands
|
|
196
|
+
|
|
197
|
+
| Command | Description |
|
|
198
|
+
|---|---|
|
|
199
|
+
| `mm init [dir]` | Create or open a media library (interactive setup) |
|
|
200
|
+
| `mm server [dir]` | Start the web UI server |
|
|
201
|
+
| `mm import <source>` | Import media files into the active library |
|
|
202
|
+
| `mm search` | Search by text, image, or tags (requires CLIP) |
|
|
203
|
+
| `mm dedup` | Find and remove duplicate media files by hash |
|
|
204
|
+
| `mm info <file>` | Show detailed file metadata |
|
|
205
|
+
| `mm config [key] [value]` | Get or set library config values |
|
|
206
|
+
| `mm geo update` | Offline reverse geocode GPS-tagged media |
|
|
207
|
+
| `mm db list` | List all registered databases |
|
|
208
|
+
| `mm db set <n>` | Switch the active database |
|
|
209
|
+
| `mm db add <path>` | Register an existing database file |
|
|
210
|
+
| `mm db rm <n>` | Unregister a database (optionally delete) |
|
|
211
|
+
| `mm db stats` | Show detailed library statistics |
|
|
212
|
+
| `mm db clean` | Remove entries for files no longer on disk |
|
|
213
|
+
| `mm db sync <dir>` | Clean stale entries and re-scan changed files |
|
|
214
|
+
|
|
215
|
+
### Library Setup
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Create a new library interactively
|
|
219
|
+
mm init ~/Photos
|
|
220
|
+
|
|
221
|
+
# View all config values
|
|
222
|
+
mm config
|
|
223
|
+
|
|
224
|
+
# Set the import template
|
|
225
|
+
mm config import_template "{year}/{year}-{month:02d}-{day:02d}/{original_name}{ext}"
|
|
226
|
+
|
|
227
|
+
# Sync database with disk (remove stale + re-scan)
|
|
228
|
+
mm db sync ~/Photos
|
|
229
|
+
|
|
230
|
+
# Parallel sync with 8 workers
|
|
231
|
+
mm db sync ~/Photos -j 8
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Searching
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Semantic search by text (requires CLIP)
|
|
238
|
+
mm search --text "sunset at the beach"
|
|
239
|
+
|
|
240
|
+
# Search by image similarity
|
|
241
|
+
mm search --image ~/Photos/reference.jpg --top-k 20
|
|
242
|
+
|
|
243
|
+
# Filter by tags
|
|
244
|
+
mm search --tag landscape --tag nature
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Deduplication
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Find and remove duplicate media files (by hash)
|
|
251
|
+
mm dedup
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Importing & Organizing
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Import from SD card (copies into library using configured template)
|
|
258
|
+
mm import ~/DCIM
|
|
259
|
+
|
|
260
|
+
# Move instead of copy
|
|
261
|
+
mm import ~/DCIM --move
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Web Server
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# Start on default port (8000)
|
|
268
|
+
mm server
|
|
269
|
+
|
|
270
|
+
# Specify library directory
|
|
271
|
+
mm server ~/Photos
|
|
272
|
+
|
|
273
|
+
# Custom host and port
|
|
274
|
+
mm server -h 0.0.0.0 -p 9000
|
|
275
|
+
|
|
276
|
+
# Development mode with auto-reload
|
|
277
|
+
mm server --reload
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## 🌐 Web UI
|
|
281
|
+
|
|
282
|
+
The web interface provides a full-featured media browser:
|
|
283
|
+
|
|
284
|
+
- **Library** — Browse all media with infinite scroll, date grouping, and adjustable thumbnail sizes
|
|
285
|
+
- **Albums** — Smart albums auto-generated by tag, camera, year, festival, and location
|
|
286
|
+
- **Search** — Quick filtering and semantic search
|
|
287
|
+
- **Detail View** — Full metadata, EXIF info, location, tags, and star ratings
|
|
288
|
+
- **Batch Operations** — Multi-select for bulk tagging, rating, and deletion
|
|
289
|
+
- **Settings** — Theme switching (light/dark), library management
|
|
290
|
+
- **Auth** — User accounts with token-based authentication
|
|
291
|
+
|
|
292
|
+
## 🔌 API
|
|
293
|
+
|
|
294
|
+
mm exposes a comprehensive REST API at `/api/`:
|
|
295
|
+
|
|
296
|
+
| Endpoint | Description |
|
|
297
|
+
|---|---|
|
|
298
|
+
| `/api/auth/*` | Authentication (login, setup, logout) |
|
|
299
|
+
| `/api/media` | Media CRUD, thumbnails, file streaming |
|
|
300
|
+
| `/api/batch/*` | Bulk operations (tags, ratings, delete) |
|
|
301
|
+
| `/api/albums/*` | Album management |
|
|
302
|
+
| `/api/smart-albums/*` | Smart album definitions & resolution |
|
|
303
|
+
| `/api/tags` | Tag CRUD with usage counts |
|
|
304
|
+
| `/api/stats` | Library statistics & timeline |
|
|
305
|
+
| `/api/library` | Multi-library switching |
|
|
306
|
+
| `/api/users` | User management (admin) |
|
|
307
|
+
|
|
308
|
+
Interactive API docs available at **`/docs`** (Swagger UI) when the server is running.
|
|
309
|
+
|
|
310
|
+
## 🛠️ Tech Stack
|
|
311
|
+
|
|
312
|
+
| Component | Technology |
|
|
313
|
+
|---|---|
|
|
314
|
+
| **Backend** | Python 3.10+, FastAPI, Peewee ORM, SQLite |
|
|
315
|
+
| **AI/ML** | OpenCLIP (ViT-B-32), PyTorch |
|
|
316
|
+
| **Frontend** | React 19, TypeScript, TailwindCSS, Vite |
|
|
317
|
+
| **State** | Zustand |
|
|
318
|
+
| **UI Kit** | shadcn/ui, Radix UI, Lucide Icons |
|
|
319
|
+
| **Media** | Pillow, pillow-heif, rawpy, exiftool, ffmpeg |
|
|
320
|
+
| **Geocoding** | GeoNames (offline), lunar-python |
|
|
321
|
+
|
|
322
|
+
## 🤝 Contributing
|
|
323
|
+
|
|
324
|
+
Contributions are welcome! Here's how to get started:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
# Clone and install in dev mode
|
|
328
|
+
git clone https://github.com/HSPK/mm.git
|
|
329
|
+
cd mm
|
|
330
|
+
uv pip install -e ".[clip]"
|
|
331
|
+
|
|
332
|
+
# Install dev dependencies
|
|
333
|
+
uv pip install -e ".[dev]"
|
|
334
|
+
|
|
335
|
+
# Run tests
|
|
336
|
+
pytest
|
|
337
|
+
|
|
338
|
+
# Start frontend dev server
|
|
339
|
+
cd web && npm install && npm run dev
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Please open an issue first to discuss what you would like to change.
|
|
343
|
+
|
|
344
|
+
## 📄 License
|
|
345
|
+
|
|
346
|
+
This project is open source. See the [LICENSE](LICENSE) file for details.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
<div align="center">
|
|
351
|
+
|
|
352
|
+
**If you find mm useful, please consider giving it a ⭐!**
|
|
353
|
+
|
|
354
|
+
[](https://star-history.com/#HSPK/mm&Date)
|
|
355
|
+
|
|
356
|
+
</div>
|
litemm-0.1.0/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 📸 MM — Universal Organizer for Media
|
|
4
|
+
|
|
5
|
+
**A self-hosted, AI-powered media library manager for photos, videos, and audio.**
|
|
6
|
+
|
|
7
|
+
Scan, tag, search, deduplicate, and browse your media collection with a beautiful web UI.
|
|
8
|
+
|
|
9
|
+
[](https://github.com/HSPK/mm/stargazers)
|
|
10
|
+
[](https://github.com/HSPK/mm/network/members)
|
|
11
|
+
[](https://github.com/HSPK/mm/issues)
|
|
12
|
+
[](https://github.com/HSPK/mm/commits)
|
|
13
|
+
[](https://github.com/HSPK/mm/blob/main/LICENSE)
|
|
14
|
+
[](https://python.org)
|
|
15
|
+
[](https://typescriptlang.org)
|
|
16
|
+
[](https://fastapi.tiangolo.com)
|
|
17
|
+
[](https://react.dev)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
[Features](#-features) · [Quick Start](#-quick-start) · [Installation](#-installation) · [Usage](#-usage) · [Web UI](#-web-ui) · [API](#-api) · [Contributing](#-contributing)
|
|
22
|
+
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## ✨ Features
|
|
28
|
+
|
|
29
|
+
<table>
|
|
30
|
+
<tr>
|
|
31
|
+
<td width="50%">
|
|
32
|
+
|
|
33
|
+
### 🔍 Smart Scanning
|
|
34
|
+
- Recursive media discovery with parallel processing
|
|
35
|
+
- SHA-256 hashing for integrity & deduplication
|
|
36
|
+
- EXIF, video, and audio metadata extraction
|
|
37
|
+
- Support for RAW, HEIC/HEIF, and 30+ formats
|
|
38
|
+
|
|
39
|
+
</td>
|
|
40
|
+
<td width="50%">
|
|
41
|
+
|
|
42
|
+
### 🤖 AI-Powered
|
|
43
|
+
- CLIP-based image embeddings (ViT-B-32)
|
|
44
|
+
- Natural language image search ("sunset over ocean")
|
|
45
|
+
- Zero-shot auto-tagging (~36 categories)
|
|
46
|
+
- Visual similarity search
|
|
47
|
+
|
|
48
|
+
</td>
|
|
49
|
+
</tr>
|
|
50
|
+
<tr>
|
|
51
|
+
<td>
|
|
52
|
+
|
|
53
|
+
### 🌍 Offline Geocoding
|
|
54
|
+
- Reverse geocoding from GPS EXIF data
|
|
55
|
+
- GeoNames cities15000 dataset (no API keys needed)
|
|
56
|
+
- Chinese province/city name support
|
|
57
|
+
- Chinese lunar & solar festival detection
|
|
58
|
+
|
|
59
|
+
</td>
|
|
60
|
+
<td>
|
|
61
|
+
|
|
62
|
+
### 🖼️ Beautiful Web UI
|
|
63
|
+
- Responsive gallery with justified layout
|
|
64
|
+
- Pinch-to-zoom thumbnail resizing
|
|
65
|
+
- Infinite scroll with date grouping
|
|
66
|
+
- Detail panel with full metadata & map
|
|
67
|
+
|
|
68
|
+
</td>
|
|
69
|
+
</tr>
|
|
70
|
+
<tr>
|
|
71
|
+
<td>
|
|
72
|
+
|
|
73
|
+
### 📁 Library Management
|
|
74
|
+
- Manual & smart albums (auto-generated)
|
|
75
|
+
- Star ratings, tags, batch operations
|
|
76
|
+
- Template-based file import & organization
|
|
77
|
+
- Multi-library support with runtime switching
|
|
78
|
+
|
|
79
|
+
</td>
|
|
80
|
+
<td>
|
|
81
|
+
|
|
82
|
+
### ⚡ Performance
|
|
83
|
+
- SQLite-backed (zero config, portable)
|
|
84
|
+
- WebP thumbnail caching (4 sizes) with ETag
|
|
85
|
+
- Async API server (FastAPI + Uvicorn)
|
|
86
|
+
- Background CLIP processing
|
|
87
|
+
|
|
88
|
+
</td>
|
|
89
|
+
</tr>
|
|
90
|
+
</table>
|
|
91
|
+
|
|
92
|
+
## 🏗️ Architecture
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
96
|
+
│ Web UI (React) │
|
|
97
|
+
│ React 19 · TailwindCSS · Zustand · Vite │
|
|
98
|
+
└──────────────────┬───────────────────────────────────────────┘
|
|
99
|
+
│ REST API
|
|
100
|
+
┌──────────────────▼───────────────────────────────────────────┐
|
|
101
|
+
│ FastAPI Server │
|
|
102
|
+
│ Auth · Media · Albums · Smart Albums · Tags · Stats │
|
|
103
|
+
└──────────────────┬───────────────────────────────────────────┘
|
|
104
|
+
│
|
|
105
|
+
┌──────────────────▼───────────────────────────────────────────┐
|
|
106
|
+
│ Core Engines │
|
|
107
|
+
│ Scanner · Metadata · Embeddings · Tagger · Geocoding · ... │
|
|
108
|
+
└──────────────────┬───────────────────────────────────────────┘
|
|
109
|
+
│
|
|
110
|
+
┌──────────────────▼───────────────────────────────────────────┐
|
|
111
|
+
│ SQLite (Peewee ORM / aiosqlite) │
|
|
112
|
+
│ Media · Metadata · Tags · Embeddings · Albums │
|
|
113
|
+
└──────────────────────────────────────────────────────────────┘
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 🚀 Quick Start
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Install with uv (recommended)
|
|
120
|
+
uv pip install -e .
|
|
121
|
+
|
|
122
|
+
# Create a new library (interactive)
|
|
123
|
+
mm init ~/Photos
|
|
124
|
+
|
|
125
|
+
# Start the web server
|
|
126
|
+
mm server
|
|
127
|
+
# → Open http://localhost:8000
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 📦 Installation
|
|
131
|
+
|
|
132
|
+
### Prerequisites
|
|
133
|
+
|
|
134
|
+
- **Python 3.10+**
|
|
135
|
+
- **[uv](https://docs.astral.sh/uv/)** (recommended) or pip
|
|
136
|
+
- **exiftool** — for EXIF metadata extraction
|
|
137
|
+
- **ffmpeg** / **ffprobe** — for video/audio metadata & thumbnails
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# macOS
|
|
141
|
+
brew install exiftool ffmpeg
|
|
142
|
+
|
|
143
|
+
# Ubuntu / Debian
|
|
144
|
+
sudo apt install libimage-exiftool-perl ffmpeg
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Install mm
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Clone the repository
|
|
151
|
+
git clone https://github.com/HSPK/mm.git
|
|
152
|
+
cd mm
|
|
153
|
+
|
|
154
|
+
# Install with uv
|
|
155
|
+
uv pip install -e .
|
|
156
|
+
|
|
157
|
+
# (Optional) Install CLIP support for AI features
|
|
158
|
+
uv pip install -e ".[clip]"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Build the Frontend
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
cd web
|
|
165
|
+
npm install
|
|
166
|
+
npm run build
|
|
167
|
+
cd ..
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 📖 Usage
|
|
171
|
+
|
|
172
|
+
### CLI Commands
|
|
173
|
+
|
|
174
|
+
| Command | Description |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `mm init [dir]` | Create or open a media library (interactive setup) |
|
|
177
|
+
| `mm server [dir]` | Start the web UI server |
|
|
178
|
+
| `mm import <source>` | Import media files into the active library |
|
|
179
|
+
| `mm search` | Search by text, image, or tags (requires CLIP) |
|
|
180
|
+
| `mm dedup` | Find and remove duplicate media files by hash |
|
|
181
|
+
| `mm info <file>` | Show detailed file metadata |
|
|
182
|
+
| `mm config [key] [value]` | Get or set library config values |
|
|
183
|
+
| `mm geo update` | Offline reverse geocode GPS-tagged media |
|
|
184
|
+
| `mm db list` | List all registered databases |
|
|
185
|
+
| `mm db set <n>` | Switch the active database |
|
|
186
|
+
| `mm db add <path>` | Register an existing database file |
|
|
187
|
+
| `mm db rm <n>` | Unregister a database (optionally delete) |
|
|
188
|
+
| `mm db stats` | Show detailed library statistics |
|
|
189
|
+
| `mm db clean` | Remove entries for files no longer on disk |
|
|
190
|
+
| `mm db sync <dir>` | Clean stale entries and re-scan changed files |
|
|
191
|
+
|
|
192
|
+
### Library Setup
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Create a new library interactively
|
|
196
|
+
mm init ~/Photos
|
|
197
|
+
|
|
198
|
+
# View all config values
|
|
199
|
+
mm config
|
|
200
|
+
|
|
201
|
+
# Set the import template
|
|
202
|
+
mm config import_template "{year}/{year}-{month:02d}-{day:02d}/{original_name}{ext}"
|
|
203
|
+
|
|
204
|
+
# Sync database with disk (remove stale + re-scan)
|
|
205
|
+
mm db sync ~/Photos
|
|
206
|
+
|
|
207
|
+
# Parallel sync with 8 workers
|
|
208
|
+
mm db sync ~/Photos -j 8
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Searching
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Semantic search by text (requires CLIP)
|
|
215
|
+
mm search --text "sunset at the beach"
|
|
216
|
+
|
|
217
|
+
# Search by image similarity
|
|
218
|
+
mm search --image ~/Photos/reference.jpg --top-k 20
|
|
219
|
+
|
|
220
|
+
# Filter by tags
|
|
221
|
+
mm search --tag landscape --tag nature
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Deduplication
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Find and remove duplicate media files (by hash)
|
|
228
|
+
mm dedup
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Importing & Organizing
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Import from SD card (copies into library using configured template)
|
|
235
|
+
mm import ~/DCIM
|
|
236
|
+
|
|
237
|
+
# Move instead of copy
|
|
238
|
+
mm import ~/DCIM --move
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Web Server
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Start on default port (8000)
|
|
245
|
+
mm server
|
|
246
|
+
|
|
247
|
+
# Specify library directory
|
|
248
|
+
mm server ~/Photos
|
|
249
|
+
|
|
250
|
+
# Custom host and port
|
|
251
|
+
mm server -h 0.0.0.0 -p 9000
|
|
252
|
+
|
|
253
|
+
# Development mode with auto-reload
|
|
254
|
+
mm server --reload
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## 🌐 Web UI
|
|
258
|
+
|
|
259
|
+
The web interface provides a full-featured media browser:
|
|
260
|
+
|
|
261
|
+
- **Library** — Browse all media with infinite scroll, date grouping, and adjustable thumbnail sizes
|
|
262
|
+
- **Albums** — Smart albums auto-generated by tag, camera, year, festival, and location
|
|
263
|
+
- **Search** — Quick filtering and semantic search
|
|
264
|
+
- **Detail View** — Full metadata, EXIF info, location, tags, and star ratings
|
|
265
|
+
- **Batch Operations** — Multi-select for bulk tagging, rating, and deletion
|
|
266
|
+
- **Settings** — Theme switching (light/dark), library management
|
|
267
|
+
- **Auth** — User accounts with token-based authentication
|
|
268
|
+
|
|
269
|
+
## 🔌 API
|
|
270
|
+
|
|
271
|
+
mm exposes a comprehensive REST API at `/api/`:
|
|
272
|
+
|
|
273
|
+
| Endpoint | Description |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `/api/auth/*` | Authentication (login, setup, logout) |
|
|
276
|
+
| `/api/media` | Media CRUD, thumbnails, file streaming |
|
|
277
|
+
| `/api/batch/*` | Bulk operations (tags, ratings, delete) |
|
|
278
|
+
| `/api/albums/*` | Album management |
|
|
279
|
+
| `/api/smart-albums/*` | Smart album definitions & resolution |
|
|
280
|
+
| `/api/tags` | Tag CRUD with usage counts |
|
|
281
|
+
| `/api/stats` | Library statistics & timeline |
|
|
282
|
+
| `/api/library` | Multi-library switching |
|
|
283
|
+
| `/api/users` | User management (admin) |
|
|
284
|
+
|
|
285
|
+
Interactive API docs available at **`/docs`** (Swagger UI) when the server is running.
|
|
286
|
+
|
|
287
|
+
## 🛠️ Tech Stack
|
|
288
|
+
|
|
289
|
+
| Component | Technology |
|
|
290
|
+
|---|---|
|
|
291
|
+
| **Backend** | Python 3.10+, FastAPI, Peewee ORM, SQLite |
|
|
292
|
+
| **AI/ML** | OpenCLIP (ViT-B-32), PyTorch |
|
|
293
|
+
| **Frontend** | React 19, TypeScript, TailwindCSS, Vite |
|
|
294
|
+
| **State** | Zustand |
|
|
295
|
+
| **UI Kit** | shadcn/ui, Radix UI, Lucide Icons |
|
|
296
|
+
| **Media** | Pillow, pillow-heif, rawpy, exiftool, ffmpeg |
|
|
297
|
+
| **Geocoding** | GeoNames (offline), lunar-python |
|
|
298
|
+
|
|
299
|
+
## 🤝 Contributing
|
|
300
|
+
|
|
301
|
+
Contributions are welcome! Here's how to get started:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# Clone and install in dev mode
|
|
305
|
+
git clone https://github.com/HSPK/mm.git
|
|
306
|
+
cd mm
|
|
307
|
+
uv pip install -e ".[clip]"
|
|
308
|
+
|
|
309
|
+
# Install dev dependencies
|
|
310
|
+
uv pip install -e ".[dev]"
|
|
311
|
+
|
|
312
|
+
# Run tests
|
|
313
|
+
pytest
|
|
314
|
+
|
|
315
|
+
# Start frontend dev server
|
|
316
|
+
cd web && npm install && npm run dev
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Please open an issue first to discuss what you would like to change.
|
|
320
|
+
|
|
321
|
+
## 📄 License
|
|
322
|
+
|
|
323
|
+
This project is open source. See the [LICENSE](LICENSE) file for details.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
<div align="center">
|
|
328
|
+
|
|
329
|
+
**If you find mm useful, please consider giving it a ⭐!**
|
|
330
|
+
|
|
331
|
+
[](https://star-history.com/#HSPK/mm&Date)
|
|
332
|
+
|
|
333
|
+
</div>
|