- Preview modal redesigned: fullscreen dark immersive lightbox (no white shell) — frosted gradient top bar (filename + position + close), centered media with soft shadow, frosted bottom bar (mime + blue Download pill), translucent circular nav buttons, mobile touch-swipe navigation - Upload progress HUD (bottom-right panel) removed; upload progress now surfaces via the existing toast (x/y uploading → ✓ uploaded); cancelAll / hud state dropped - CSS: lightbox-* replaces preview-* and upload-hud blocks; zero leftover refs
URL Manager
A URL management tool that helps you organize and access your links efficiently.
Features
- Create and manage short links
- Template links with dynamic parameters
- Bookmark pages with automatic title and summary extraction
- Screenshot capture for bookmarked pages
- Advanced search capabilities
- REST API access
- In-process background task scheduling (APScheduler)
- Network security scanner (NetScan)
Prerequisites
- Python 3.12+
- uv — fast Python package manager
- just — command runner (
brew install just) - Docker + Docker Compose (for containerised setup)
Quick Start (Local)
# 1. Install dependencies and apply migrations
just install
# 2. Install Playwright browsers (for screenshot capture)
just install-browsers
# 3. Run the full stack (Django + Tailwind watcher)
just dev-all
The app will be available at http://localhost:8000
Run
just(no arguments) to see all available recipes.
Local Development Commands
| Recipe | Description |
|---|---|
just dev |
Run Django server + Tailwind together |
just tailwind |
Run Tailwind CSS watcher (standalone) |
just migrate |
Apply pending migrations |
just makemigrations |
Generate new migrations |
just shell |
Open Django shell |
just dbshell |
Open raw DB shell |
just superuser |
Create a superuser |
just build-css |
Build minified Tailwind CSS |
just collectstatic |
Collect static files |
just test |
Run tests |
just compilemessages |
Compile i18n translation files |
just makemessages |
Extract translatable strings (zh_Hans) |
Docker Commands
| Recipe | Description |
|---|---|
just docker-build |
Build images |
just docker-start |
Start all services (detached) |
just docker-stop |
Stop all services |
just docker-restart |
Restart services |
just docker-logs |
Tail logs (all services) |
just docker-logs web |
Tail logs for a specific service |
just docker-shell |
Shell into the web container |
just docker-migrate |
Run migrations inside Docker |
just docker-static |
Collect static files inside Docker |
just docker-rebuild web |
Rebuild and restart a specific service |
Docker Services
web— Django server on port 8000 (APScheduler runs in-process)node— Tailwind CSS compiler
Usage
Managing Links
- Create a new link at
/create/ - Access a link at
http://localhost:8000/your-alias - For template links use
{param, default=value}syntax in the URL
Managing Pages (Bookmarks)
- Add a bookmark at
/ui/pages/new/— title and summary are auto-extracted - Screenshots are captured automatically in the background
- View all bookmarks at
/ui/pages/
X (Twitter) Bookmarks
The app includes an offline archive of X.com bookmarks. Export your bookmarks from X, then import them for full-text search, filtering, and browsing — no further API calls needed.
1. Export bookmarks from X
Use x-bookmarks-exporter to download your X bookmarks as JSON files:
# Install
git clone https://github.com/nickcam/x-bookmarks-exporter.git
cd x-bookmarks-exporter
npm install
# Configure — copy .env.example to .env and fill in your X credentials
cp .env.example .env
# Export (produces individual <tweet_id>.json files in data/bookmarks/)
npm run export
The exporter produces either:
- A directory of
<tweet_id>.jsonfiles (one per bookmark), or - A
bookmarks_index.jsonfile containing all bookmarks in a{"bookmarks": [...]}wrapper.
Both formats are supported.
2. Import into URL Manager
Via management command:
# Import a directory of JSON files
just import-bookmarks data/bookmarks/
# Import an index file
just import-bookmarks data/bookmarks_index.json
# Import a single file
just import-bookmarks data/single_bookmark.json
# Wipe existing bookmarks first, then re-import
just import-bookmarks data/bookmarks/ --clear
The command reports created, updated, unchanged, and skipped counts. Re-importing the same data is safe — unchanged items are detected via content hash and skipped.
Via REST API:
# Bulk import (export-format payload)
curl -X POST http://localhost:8000/api/bookmarks/import/ \
-H "Content-Type: application/json" \
-d '{"bookmarks": [{...}, {...}]}'
# Bulk upsert (flat array, either format)
curl -X POST http://localhost:8000/api/bookmarks/bulk/ \
-H "Content-Type: application/json" \
-d '[{"tweet_id": "123", "text": "hello"}, ...]'
3. Browse imported bookmarks
- Web UI: visit
/ui/bookmarks/— filter by media type, search by text/author, view full details - API:
GET /api/bookmarks/with filters like?q=search&has_video=true&author=screen_name - API docs:
/ui/api-docs/(Bookmarks section)
Dedup behaviour
Each bookmark is keyed by tweet_id. On re-import:
- New tweet_id → created
- Existing tweet_id, content changed → updated (engagement counts, media, etc. refreshed)
- Existing tweet_id, content identical →
unchanged(onlylast_imported_atbumped; no save/signal overhead)
Network Scanner (NetScan)
Available at /ui/netscan/. Create a scan profile to automatically monitor your home network for security issues (router exposure, DNS, TLS certs, camera access).
API
- List pages:
GET /api/pages/ - Full API docs:
/ui/api-docs/
Architecture
core/ — Django project config, APScheduler setup
links/ — Main app: links, pages, tags, posts, collections
netscan/ — Network security scanner
templates/ — Base HTML templates
Background tasks (screenshot capture, page metadata extraction, network scans) run via APScheduler in-process — no separate worker or Redis needed.
Dependencies
Managed with uv via pyproject.toml.
# Add a new package
uv add package-name
# Sync environment from lockfile
uv sync
Favicon
Generated using the Zen Tokyo Zoo font (https://fonts.gstatic.com/s/zentokyozoo/).
Image Resizing (Cloudflare)
- Bind a custom domain
- Enable image resizing: https://developers.cloudflare.com/images/transform-images/