- JavaScript 24.5%
- CSS 23.7%
- Python 23.3%
- Kotlin 15.7%
- HTML 12.4%
- Other 0.4%
| android | ||
| db | ||
| extension | ||
| flask | ||
| .env.sample | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.sample.yml | ||
| LICENSE | ||
| README.md | ||
Shortener
A private URL shortening service with a web dashboard, browser extension and Android app. Automatically fetches Open Graph metadata (title, description, image) from target pages and tracks click counts.
Features
- URL shortening — custom or auto-generated short codes (6 characters)
- Open Graph metadata — automatic fetching of title, description and image from the target page, with manual editing
- Click counter — traffic tracking with bot detection
- Dashboard — link management, search, pagination, copy to clipboard
- Browser extension — shorten links via popup or context menu (right-click)
- Android app — share any URL via Android Share Sheet to shorten it instantly, with a built-in WebView dashboard
- Internationalization — English (default) and Czech, language auto-detected from browser or set via env variable
Tech stack
| Layer | Technology |
|---|---|
| Backend | Flask, Gunicorn, SQLAlchemy |
| Database | MariaDB 11 |
| Frontend | Jinja2, vanilla JS, CSS (dark mode) |
| Android | Kotlin, WebView, EncryptedSharedPreferences |
| Infra | Docker Compose |
Project structure
shortener/
├── docker-compose.sample.yml # Docker Compose template
├── .env.sample # Environment variables template
├── db/
│ └── init.sql # Initial SQL schema
├── flask/
│ ├── Dockerfile
│ ├── requirements.txt
│ └── app/
│ ├── __init__.py # Flask app factory
│ ├── models.py # Models (User, ShortURL)
│ ├── routes.py # Endpoints (auth, API, redirect)
│ ├── cli.py # CLI commands (create-user, sync-db)
│ ├── i18n.py # Internationalization
│ ├── og_fetcher.py # OG metadata fetcher
│ ├── translations/ # JSON translation files (en, cs)
│ ├── templates/ # Jinja2 templates
│ └── static/ # CSS, JS, images
├── extension/ # Browser extension (Manifest v3)
└── android/ # Android app (Kotlin)
└── app/src/main/java/com/shortener/app/
├── AuthManager.kt # Auth, cookies, API calls
├── MainActivity.kt # WebView dashboard
├── SetupActivity.kt # Server & credentials setup
└── ShareActivity.kt # Share Sheet handler
Installation
-
Prepare configuration:
cp .env.sample .env cp docker-compose.sample.yml docker-compose.ymlEdit
.env— set at leastMYSQL_ROOT_PASSWORD,MYSQL_PASSWORD,SECRET_KEYandSITE_URL. -
Start containers:
docker compose up -d -
Create a user:
docker compose exec flask flask create-user <username>You will be prompted for a password.
-
Sync database schema (on update):
docker compose exec flask flask sync-dbCompares models with the database and adds missing tables, columns and indexes. Extra structures are listed and require confirmation before removal.
-
Access:
The dashboard runs at
http://localhost:8002.
Environment variables
| Variable | Description | Default |
|---|---|---|
MYSQL_ROOT_PASSWORD |
MariaDB root password | — |
MYSQL_DATABASE |
Database name | shortener |
MYSQL_USER |
Application database user | shortener |
MYSQL_PASSWORD |
Application database user password | — |
SECRET_KEY |
Key for signing session cookies | random |
LOG_LEVEL |
Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | WARNING |
SITE_URL |
Public URL of the service (no trailing slash) | — |
LANGUAGE |
UI language: auto (detect from browser), en, cs |
auto |
API
All API endpoints require authentication.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/urls |
List URLs (query: q, offset, limit) |
POST |
/api/urls |
Create a shortened link |
PUT |
/api/urls/<id> |
Edit OG metadata |
DELETE |
/api/urls/<id> |
Delete a link |
GET |
/api/urls/<id>/image |
OG image (binary) |
GET |
/api/suggest-code |
Suggest a random short code |
Redirect: GET /<short_code> → target URL (HTTP 301).
Browser extension
See extension/README.md for installation and usage.
Android app
See android/README.md for building and usage.
License
Česká verze
Soukromá služba pro zkracování URL s webovým dashboardem, rozšířením pro prohlížeč a Android aplikací. Automaticky stahuje Open Graph metadata (titulek, popis, obrázek) z cílových stránek a sleduje počty kliknutí.
Funkce
- Zkracování URL — vlastní nebo automaticky generované krátké kódy (6 znaků)
- Open Graph metadata — automatické stahování titulku, popisu a obrázku z cílové stránky s možností ruční úpravy
- Počítadlo kliknutí — sledování návštěvnosti s detekcí botů
- Dashboard — správa odkazů, vyhledávání, stránkování, kopírování do schránky
- Rozšíření pro prohlížeč — zkrácení odkazu přes popup nebo kontextové menu
- Android aplikace — sdílení URL přes Android Share Sheet pro okamžité zkrácení, s vestavěným WebView dashboardem
- Internacionalizace — angličtina (výchozí) a čeština, jazyk detekován z prohlížeče nebo nastaven přes env proměnnou
Instalace
-
Příprava konfigurace:
cp .env.sample .env cp docker-compose.sample.yml docker-compose.ymlUpravte
.env— nastavte minimálněMYSQL_ROOT_PASSWORD,MYSQL_PASSWORD,SECRET_KEYaSITE_URL. -
Spuštění kontejnerů:
docker compose up -d -
Vytvoření uživatele:
docker compose exec flask flask create-user <jméno>Příkaz se zeptá na heslo.
-
Synchronizace schématu databáze (při aktualizaci):
docker compose exec flask flask sync-dbPorovná modely s databází a přidá chybějící tabulky, sloupce a indexy. Přebytečné struktury vypíše a zeptá se na potvrzení před odstraněním.
-
Přístup:
Dashboard běží na
http://localhost:8002.
Proměnné prostředí
| Proměnná | Popis | Výchozí |
|---|---|---|
MYSQL_ROOT_PASSWORD |
Root heslo MariaDB | — |
MYSQL_DATABASE |
Název databáze | shortener |
MYSQL_USER |
Uživatel aplikace | shortener |
MYSQL_PASSWORD |
Heslo uživatele aplikace | — |
SECRET_KEY |
Klíč pro podepisování session cookies | náhodný |
LOG_LEVEL |
Úroveň logování (DEBUG, INFO, WARNING, ERROR, CRITICAL) | WARNING |
SITE_URL |
Veřejná URL služby (bez lomítka na konci) | — |
LANGUAGE |
Jazyk UI: auto (detekce z prohlížeče), en, cs |
auto |
Rozšíření pro prohlížeč
Viz extension/README.md.
Android aplikace
Viz android/README.md.