11# SnapSort
22
3- A very opinionated solution for a personal problem of organizing a photos/videos library. SnapSort helps you organize
4- media files (images/videos) and edit metadata.
3+ A very opinionated solution for a very personal problem of organizing a photos/videos library. SnapSort helps you
4+ (read: me) organize media files (images/videos) and edit metadata.
5+
6+ ## Table of Contents
7+
8+ - [ Features] ( #features )
9+ - [ Metadata Management] ( #metadata-management )
10+ - [ Library Organization] ( #library-organization )
11+ - [ Setup and Usage] ( #setup-and-usage )
12+ - [ Contribution and Development] ( #contribution-and-development )
13+ - [ Running a development instance] ( #running-a-development-instance )
14+ - [ Project structure] ( #project-structure )
15+ - [ Future Improvements] ( #future-improvements )
516
617## Features
718
@@ -19,7 +30,9 @@ media files (images/videos) and edit metadata.
1930Media library is organized in a "Year / Month / Day" hierarchy. The Day folder may have a ` - Keyword ` suffix
2031depending on whether any of the files within that folder contains a keyword which can be used as a folder label.
2132
22- The files follow the following naming convention: ` TYPE-YYYYMMDD-INDEX `
33+ The files use the following naming convention: ` TAG-YYYYMMDD-INDEX ` <br />
34+ ` TAG ` will be ` IMG ` or ` VID ` depending on the type of the media. A special keyword ` Edit ` can be added to the file to
35+ overwrite ` TAG ` to be ` EDT ` .
2336
2437```
2538library/
@@ -29,152 +42,124 @@ library/
2942 |- IMG-20250101-000.jpg
3043 |- VID-20250101-000.mp4
3144 |- 02 - Birthday/
45+ |- EDT-20250102-000.jpg
3246 |- IMG-20250102-000.jpg
3347 |- IMG-20250102-001.jpg
3448```
3549
36- ## Prerequisites
37-
38- - [ Node.js] ( https://nodejs.org/ ) (v18 or later)
39- - [ PNPM] ( https://pnpm.io/ ) package manager
40- - [ Docker] ( https://www.docker.com/ ) and [ Docker Compose] ( https://docs.docker.com/compose/ ) (for PostgreSQL database)
41- - [ ExifTool] ( https://exiftool.org/ ) (for metadata manipulation)
42- - [ FFmpeg] ( https://ffmpeg.org/ ) (for video processing)
43-
44- ## Installation
45-
46- 1 . Clone the repository:
47-
48- ``` bash
49- git clone https://github.com/bhatushar/snap-sort.git
50- cd snap-sort
51- ```
52-
53- 2 . Install dependencies:
54-
55- ``` bash
56- pnpm install
57- ```
58-
59- 3 . Create a ` .env ` file based on the provided ` .env.example ` :
60-
61- ``` bash
62- cp .env.example .env
63- ```
64-
65- 4 . Edit the ` .env ` file to configure your environment:
50+ ## Setup and Usage
6651
67- - Set database credentials
68- - Configure paths to ExifTool and FFmpeg
69- - Set file storage directories
52+ ** Prerequisites:**
7053
71- 5 . Start the PostgreSQL database using Docker:
54+ - [ Docker] ( https://www.docker.com/ )
55+ - [ Ability to use Docker] ( https://www.youtube.com/watch?v=DQdB7wFEygo )
7256
73- ``` bash
74- pnpm db:start
75- ```
57+ ** Docker Compose configuration:**
7658
77- 6 . Initialize the database:
78- ``` bash
79- pnpm db:push
80- ```
59+ ``` yaml
60+ services :
61+ snapsort :
62+ image : bhatushar/snapsort
63+ ports :
64+ - ' 3990:3990'
65+ volumes :
66+ - ' /app-data:/app/data'
67+ - ' /library:/app/library'
68+ environment :
69+ TZ : Asia/Calcutta
70+ restart : unless-stopped
71+ ` ` `
8172
82- ## Running the Application
73+ ` /app-data` is where SnapSort will store its internal files like the database, user-uploaded media, and thumbnails.<br/>
74+ ` /library` is where your media will go once processed by SnapSort.<br/>
8375
84- ### Development Mode
76+ Run the container with `docker compose up -d` and you should be able to access the website on `localhost:3990`.
8577
86- Run the application in development mode:
78+ When you first launch the application, it will ask you to create a login password. SnapSort currently doesn't support
79+ multiple users.<br/>
80+ After logging in, you'll land on the homepage where you can upload new media files for processing. You can edit the date
81+ and time information, add titles to your media, tag them with keywords... Oh wait, you can't use keywords?
8782
88- ``` bash
89- pnpm dev
90- ```
83+ That's because you need to create the keywords first!<br/>
84+ Go to Settings > Manage Keywords. On the top-right, there will be an option to add keywords.<br/>
85+ Here, you can set the name of the keyword, its type/category, and whether to use it to label folders.<br/>
86+ Now you can go back and start tagging your files.
9187
92- To make the development server accessible on your local network :
88+ Whatever changes you make will not persist until you save them. When you click the 'Save' button, you get two options :
9389
94- ``` bash
95- pnpm dev-network
96- ```
90+ 1. _Apply Changes_ : This will only store your changes in SnapSort's internal database. Your files will remain intact.
91+ This is useful if you want to come back in the future and revise your changes.
92+ 2. _Move to Library_ : This is the final step. It will apply your changes to your files and move them to the library.
9793
98- ### Production Mode
94+ # # Contribution and Development
9995
100- Build the application for production:
96+ This project is developed using the SvelteKit framework with TypeScript support. It uses a locally hosted SQLite
97+ database, and the DB connection is managed by Drizzle.<br/>
98+ Internally, it relies on [ExifTool](https://exiftool.org/) (for reading/writing metadata) and
99+ [FFmpeg](https://ffmpeg.org/) (for generating thumbnails for videos).
101100
102- ``` bash
103- pnpm build
104- ```
105-
106- Preview the production build:
107-
108- ``` bash
109- pnpm preview
110- ```
101+ # ## Running a development instance
111102
112- Run the production server :
103+ Set up the project :
113104
114105` ` ` bash
115- node build
106+ git clone https://github.com/bhatushar/snapsort.git
107+ cd snapsort
108+ pnpm install
116109` ` `
117110
118- ## Database Management
119-
120- - Push schema changes to the database:
121-
122- ``` bash
123- pnpm db:push
124- ```
125-
126- - Create migrations:
127-
128- ``` bash
129- pnpm db:migrate
130- ```
131-
132- - Open Drizzle Studio to manage database:
133- ``` bash
134- pnpm db:studio
135- ```
136-
137- ## Project Structure
138-
139- - ` /src ` : Source code
140- - ` /lib ` : Library code
141- - ` /server ` : Server-side code
142- - ` /db ` : Database models and operations
143- - ` /routes ` : SvelteKit routes
144- - ` /static ` : Static assets
145-
146- ## Configuration
147-
148- The application requires several environment variables to be set in the ` .env ` file:
149-
150- ### Database Configuration
111+ Create an `.env.development` file :
151112
152- ```
153- DATABASE_URL=postgresql://root:mysecretpassword@localhost:5432/snapsort
154- POSTGRES_USER=root
155- POSTGRES_PASSWORD=mysecretpassword
156- ```
157-
158- ### External Tools
113+ ` ` ` dotenv
114+ # Database credentials
115+ DATABASE_URL="file:/path/to/db.sqlite3"
159116
160- ```
117+ # Path to external binaries
161118EXIFTOOL_PATH="/path/to/exiftool"
162- FFMPEG_PATH="/path/to/ffmpeg"
163- ```
164-
165- ### File Storage
119+ FFMPEG_PATH="/path/toffmpeg"
166120
167- ```
121+ # Path to data storage
168122FILE_UPLOAD_DIR="/path/to/uploaded-files"
169123LIBRARY_ROOT_DIR="/path/to/library"
170124` ` `
171125
172- ## Usage
126+ Run database migrations and fire up the server :
127+
128+ ` ` ` bash
129+ pnpm db:migrate:dev
130+ pnpm dev
131+ ` ` `
173132
174- 1 . Start the application and navigate to the web interface
175- 2 . Create new keywords
176- 3 . Upload your media files
177- 4 . Edit metadata as needed (date/time, description, GPS data, keywords)
178- 5 . Apply the changes to temporarily modify the queued files
179- 6 . Move files to the library to permanently save files
180- 7 . Export metadata when needed for backup
133+ If you want to run a production server, you need to create an `.env.production` file and run `pnpm start`.
134+
135+ # ## Project structure
136+
137+ - `src/` :
138+ - `lib/` :
139+ - `components/` : Contains various UI components which can be imported in Svelte Pages
140+ - `server/` : Server-only code
141+ - `db/` :
142+ - `index.ts` : Manages database connection and exposes a wrapper for all database interactions
143+ - `schema.ts` : Defines the database structure which Drizzle uses to create migrations
144+ - `exiftool-wrapper.ts` : Manages all interactions with ExifTool
145+ - `file-manager.ts` : Handles all operations for uploaded files (create, rename, copy, delete)
146+ - `validation-schema.ts` : Zod schemas to validate external input
147+ - `routes/` : SvelteKit routes
148+ - ` api/`
149+ - `export-exif/+server.ts` : Endpoint for exporting Exif data for all library files
150+ - `thumbnail/[file_id]/+server.ts` : Endpoint for fetching thumbnail using the file ID
151+
152+ # # Future Improvements
153+
154+ - Google Photos Integration : Currently, I use Google Photos as a cloud backup (I know it's not a real backup, hush!).
155+ Once the files are committed to the library, they should also be uploaded to Google Photos. In the distant future, I
156+ might look into extending this to multiple cloud providers.
157+ - Add Tests : Now that the MVP is developed, a robust testing suite is needed. My photos are too precious to expose to
158+ untested code.
159+ - Backup/Restore : It's "technically" possible by manually cloning the app-data folder... But perhaps something more
160+ robust.
161+ - Multi-user Support : The more, the merrier!
162+ - Modify/Delete Existing Keywords : So far, I haven't faced a need to update a Keyword once it's created. Nonetheless, it
163+ is a useful feature.
164+ - Custom File Formats : I know I said it's opinionated, but it would still be nice to let users decide how they want
165+ their media to be organized.
0 commit comments