diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 61aa6c3..0000000 --- a/.gitignore +++ /dev/null @@ -1,65 +0,0 @@ -# Python -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# Virtual Environment -venv/ -ENV/ -env/ -.venv - -# Flask -instance/ -.webassets-cache - -# Environment Variables -.env -.env.local -.env.*.local - -# Database -*.db -*.sqlite -*.sqlite3 - -# IDE -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# OS -.DS_Store -Thumbs.db - -# Logs -*.log -nohup.out - -# Testing -.pytest_cache/ -.coverage -htmlcov/ - -# Backups -*.backup -*.bak diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 1de5767..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,97 +0,0 @@ -# Changelog - -All notable changes to UrNetwork Stats Dashboard will be documented in this file. - -## [2.1.1] - 2024-11-21 - -### ✨ Added -- **Chart Interaction Mode** - Tooltips now show anywhere on chart, not just on data points -- Custom tooltip callbacks with formatted values (3 decimal places + GB unit) -- Better touch/mobile experience for charts -- Login button in header when not logged in - -### 🎨 Improved -- **Chart Text Visibility** - All text now white (#ffffff) instead of gray -- Chart axis labels now #e5e7eb for better readability -- Legend text is bold (weight 500) and larger (13px) -- Tooltip styling with dark background and blue border (#3b82f6) -- Login button styling (blue, prominent) - -### 🔧 Fixed -- **Daily Cleanup** - Changed from weekly (Sunday) to daily (3 AM) -- Keeps only last 7 days of data automatically -- Chart text no longer black/invisible on dark background - -### 📊 Technical -- Added `interaction.mode = 'index'` to all charts -- Added `interaction.intersect = false` for easier tooltip display -- Improved tooltip configuration with better colors and padding -- Login button CSS with `.login-btn` class - ---- - -## [2.1.0] - 2024-11-20 - -### 🎯 Major Changes -- **Clean Design** - Removed gradients, switched to solid Cloudflare-inspired colors -- Changed from purple (#667eea) to blue (#3b82f6) theme -- Solid background (#0c0d0e) instead of gradient -- Removed all glassmorphism/blur effects - -### 📊 Chart Improvements -- Better visibility with new color scheme -- Increased chart line width from 1px to 2px -- Better contrast for data visualization -- Optimized for dark theme readability - -### 🎨 Design Updates -- New stat cards without gradient backgrounds -- Simplified header design -- Cleaner button styles -- Better border colors (#2d3135) -- Improved text colors - ---- - -## [2.0.0] - 2024-11-15 - -### 🎯 Multi-Account Support (MAJOR UPDATE) -- Track unlimited UrNetwork accounts simultaneously -- Account management UI -- Individual charts per account -- Combined statistics -- Account nicknames -- Color-coded accounts - -### 🔐 Authentication Overhaul -- Separate admin password -- Secure session management -- Account-level authentication - -### 📊 Dashboard Enhancements -- React-powered private dashboard -- View modes (combined, paid/unpaid, delta) -- Chart visibility toggles -- Improved layout - -### 💾 Database Changes -- Multi-account schema -- Foreign key relationships -- Migration script from v1.0 -- Data preservation - ---- - -## [1.0.0] - 2024-10-01 - -### Initial Release -- Single account tracking -- Basic charts -- Public/private dashboard -- SQLite database -- Webhook support -- Web installer - ---- - -**Full documentation:** [README.md](README.md) diff --git a/CHART_INTERACTION.md b/CHART_INTERACTION.md deleted file mode 100644 index d075c7d..0000000 --- a/CHART_INTERACTION.md +++ /dev/null @@ -1,233 +0,0 @@ -# 🎯 Graf Tooltip Vylepšení - v2.1.1 - -## ✨ Co se změnilo - -### PŘED -``` -Tooltip se zobrazí JEN když najedeš přímo na datový bod (malý kolečko) -❌ Musíš přesně trefit bod -❌ Obtížné na mobilech -❌ Frustrující když je hodně bodů blízko sebe -``` - -### PO -``` -Tooltip se zobrazí KDEKOLIV na grafu -✅ Stačí najet myší kamkoliv na graf -✅ Automaticky najde nejbližší data -✅ Mnohem lepší UX! -``` - ---- - -## 🔧 Technické Řešení - -Přidal jsem **Chart.js interaction mode**: - -```javascript -interaction: { - mode: 'index', // Najde všechny datasety na indexu - intersect: false // Nemusíš trefit přesně bod -} -``` - -### Vysvětlení: -- **`mode: 'index'`** - Zobrazí tooltip pro všechny datasety na daném X indexu -- **`intersect: false`** - Tooltip se zobrazí i když nejsi přímo nad čárou - ---- - -## 📊 Jak to funguje - -### Single Dataset Graf (např. Total Data) -``` -Graf: ──────●──────●──────●────── - │ │ │ │ -Myš: │ ← zde → │ │ - │ │ │ │ - └─────┴──────┴──────┘ - Tooltip se ukáže u nejbližšího bodu -``` - -### Multi Dataset Graf (např. Paid vs Unpaid) -``` -Paid: ──────●──────●──────●────── -Unpaid: ──────●──────●──────●────── - │ │ │ │ -Myš: │ ← zde → │ │ - │ │ │ │ - -Tooltip ukáže: - Nov 9, 05:52 PM - ━━━━━━━━━━━━━━ - 💰 Paid: 1.234 GB - 📡 Unpaid: 0.567 GB -``` - ---- - -## 🎨 Bonus - Formátované Hodnoty - -Přidal jsem také custom callback pro lepší formátování: - -```javascript -callbacks: { - label: function(context) { - let label = context.dataset.label || ''; - if (label) { - label += ': '; - } - if (context.parsed.y !== null) { - label += context.parsed.y.toFixed(3) + ' GB'; - } - return label; - } -} -``` - -**Výsledek:** -``` -// PŘED -Paid Data: 1.23456789 - -// PO -Paid Data: 1.235 GB ← Vždy 3 des. místa + jednotka -``` - ---- - -## 📱 Výhody - -### Desktop -✅ Rychlejší interakce - nemusíš lovit malé body -✅ Přesnější - ukazuje nejbližší hodnotu -✅ Plynulejší - tooltip plynule sleduje myš - -### Mobile/Touch -✅ Funguje s touch - stačí klepnout kamkoliv -✅ Větší "hit area" - není potřeba trefit malý bod -✅ Lepší UX na menších obrazovkách - ---- - -## 🔄 Kde to funguje - -Toto vylepšení je aplikováno na **VŠECHNY grafy**: - -### Veřejný Dashboard: -- ✅ Total Data Provided (GB) -- ✅ Individual Account Charts - -### Privátní Dashboard: -- ✅ Paid vs Unpaid Data -- ✅ Delta Chart -- ✅ Combined Chart -- ✅ Individual Account Charts - ---- - -## 🧪 Vyzkoušej - -1. **Otevři dashboard** -2. **Najdi graf** -3. **Jeď myší kdekoliv na grafu** (nemusíš trefit bod) -4. **Tooltip se okamžitě ukáže** s nejbližšími daty! - -### Test Multi-Dataset: -Na grafu s více čarami (Paid vs Unpaid): -- Jeď myší horizontálně přes graf -- Tooltip ukáže **obě** hodnoty najednou -- Vidíš data pro všechny datasety v daném čase - ---- - -## 💡 Pro Tipy - -### Rychlé Porovnání -Na multi-dataset grafu můžeš rychle porovnat hodnoty: -``` -Jeď myší zleva doprava → -Tooltip plynule ukazuje jak se mění obě hodnoty -``` - -### Přesné Hodnoty -I když jsou body blízko sebe: -``` -[●●●●●] ← Těsně u sebe -Tooltip vždy ukáže správný nejbližší bod -``` - -### Mobile -Na mobilech: -``` -Klepni kamkoliv na graf -→ Tooltip se ukáže -Jeď prstem po grafu -→ Tooltip sleduje tvůj prst -``` - ---- - -## 🎯 Interaction Modes - -Pro tvou informaci, Chart.js nabízí různé režimy: - -| Mode | Popis | Použití | -|------|-------|---------| -| `'point'` | Jen přesný bod | Původní chování ❌ | -| `'nearest'` | Nejbližší bod | Stále musíš být blízko | -| **`'index'`** | **Celý index** | **← Používáme! ✅** | -| `'dataset'` | Celý dataset | Pro srovnání | -| `'x'` / `'y'` | Podle osy | Specifické případy | - -**Proč `'index'`?** -- Nejlepší pro časové grafy -- Ukáže všechny datasety najednou -- Nejintuitivnější pro uživatele - ---- - -## 📊 Příklad Output - -### Single Chart: -``` -Nov 21, 01:37 PM -━━━━━━━━━━━━━━━━ -Total Data: 169.134 GB -``` - -### Multi Chart: -``` -Nov 21, 01:37 PM -━━━━━━━━━━━━━━━━ -💰 Paid (GB): 123.456 GB -📡 Unpaid (GB): 45.678 GB -``` - ---- - -## 🚀 Instalace - -Už je zahrnuté v **main_clean.py v2.1.1**! - -```bash -cd ~/urio -cp /path/to/main_clean.py main.py -pkill -f main.py -python3 main.py -``` - ---- - -## 📝 Changelog - -### v2.1.1 - 2024-11-21 -- ✅ Added `interaction.mode = 'index'` to all charts -- ✅ Added `interaction.intersect = false` for easier tooltip display -- ✅ Added custom tooltip callback for formatted values (3 decimal places) -- ✅ Improved mobile/touch experience -- ✅ Applied to both public and private dashboard charts - ---- - -**Výsledek: Mnohem lepší UX! Tooltip se ukáže kdekoliv najedeš myší na graf! 🎉** diff --git a/DESIGN_COMPARISON.md b/DESIGN_COMPARISON.md deleted file mode 100644 index 0c25aea..0000000 --- a/DESIGN_COMPARISON.md +++ /dev/null @@ -1,258 +0,0 @@ -# 🎨 Design Update - Clean Cloudflare Style - -## 🔥 Co bylo opraveno - -### Problémy ve v2.0: -1. ❌ **Gradient pozadí** - tmavý fialový gradient byl příliš tmavý -2. ❌ **Fialové barvy** - grafy byly špatně viditelné -3. ❌ **Glassmorphism efekty** - příliš mnoho blur efektů -4. ❌ **Přemrštěné animace** - karty se příliš pohybovaly - -### ✅ Nový Clean Design: -1. ✅ **Čisté tmavé pozadí** - bez gradientu (#0c0d0e) -2. ✅ **Modré téma** - lépe viditelné grafy (#3b82f6) -3. ✅ **Minimální efekty** - čistý, profesionální vzhled -4. ✅ **Jemné animace** - subtilní hover efekty - ---- - -## 📥 Soubory - -### Hlavní Verze - -**[main_clean.py](computer:///mnt/user-data/outputs/main_clean.py)** - ✨ **NOVÁ ČISTÁ VERZE** -- Bez gradientu v pozadí -- Modrá barva místo fialové -- Lépe viditelné grafy -- Inspirováno Cloudflare dashboardem -- **Doporučeno k použití!** - -**[main_enhanced.py](computer:///mnt/user-data/outputs/main_enhanced.py)** - Původní v2.0 -- S gradientem a glassmorphism -- Fialové téma -- Více efektů - ---- - -## 🎨 Vizuální Srovnání - -### Barvy - -**Původní (v2.0 - Fialová):** -```css ---primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); -``` - -**Nová (Clean - Modrá):** -```css ---primary: #3b82f6; /* Čistá modrá */ -background: #0c0d0e; /* Bez gradientu */ -``` - -### Grafy - -**Původní:** -- Fialová čára: `#667eea` -- Slabá viditelnost na tmavém gradientu -- Málo kontrastu - -**Nová:** -- Modrá čára: `#3b82f6` -- Silnější bordura (2px místo 1px) -- Vyšší kontrast -- Lépe viditelné body na grafu - -### Karty - -**Původní:** -```css -background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, ...); -backdrop-filter: blur(10px); -transform: translateY(-5px); /* Příliš mnoho pohybu */ -``` - -**Nová:** -```css -background: #16181a; /* Čistá barva */ -/* Bez blur */ -/* Jemné hover efekty */ -``` - ---- - -## 🚀 Instalace Clean Verze - -### Pro NOVOU instalaci: -```bash -cd ~/urnetwork-stats - -# Stáhni main_clean.py -# Přejmenuj na main.py -mv main_clean.py main.py - -python3 main.py -``` - -### Pro UPGRADE z v2.0: -```bash -cd ~/urio - -# Zazálohuj současnou verzi -cp main.py main_gradient_backup.py - -# Nahraď čistou verzí -cp /path/to/main_clean.py main.py - -# Restartuj -pkill -f main.py -python3 main.py -``` - ---- - -## 🎯 Klíčové Změny v CSS - -### 1. Pozadí -```css -/* PŘED */ -body { - background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); - background-attachment: fixed; -} - -/* PO */ -body { - background: #0c0d0e; /* Čistá tmavá */ -} -``` - -### 2. Primární Barva -```css -/* PŘED */ ---primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - -/* PO */ ---primary: #3b82f6; /* Modrá Cloudflare style */ -``` - -### 3. Stat Karty -```css -/* PŘED */ -.stat-card { - background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); - backdrop-filter: blur(10px); -} -.stat-card:hover { - transform: translateY(-5px); -} - -/* PO */ -.stat-card { - background: #16181a; /* Čistý solid */ -} -.stat-card:hover { - border-color: #3b82f6; /* Jemný highlight */ -} -``` - -### 4. Grafy -```css -/* PŘED */ -borderColor: '#667eea', /* Fialová */ -backgroundColor: 'rgba(102, 126, 234, 0.2)', - -/* PO */ -borderColor: '#3b82f6', /* Modrá */ -backgroundColor: 'rgba(59, 130, 246, 0.15)', /* Světlejší pro kontrast */ -borderWidth: 2, /* Silnější čára */ -``` - ---- - -## 💡 Design Principy - -### Clean Design Philosophy: -1. **Méně je více** - Bez zbytečných efektů -2. **Čitelnost** - Vysoký kontrast, jasné barvy -3. **Konzistence** - Jednotný barevný systém -4. **Cloudflare inspirace** - Profesionální, čistý vzhled - -### Cloudflare Color System: -```css -Background: #0c0d0e (Hlavní pozadí) -Secondary BG: #16181a (Karty) -Card BG: #1a1d1f (Content boxy) -Border: #2d3135 (Okraje) -Primary: #3b82f6 (Modrá) -Text: #e5e7eb (Světlý text) -Text Muted: #9ca3af (Tlumený text) -``` - ---- - -## 🔄 Rollback na Gradient Verzi - -Pokud preferuješ původní gradient design: - -```bash -cd ~/urio - -# Použij original verzi -cp main_gradient_backup.py main.py - -# Nebo použij main_enhanced.py -cp /path/to/main_enhanced.py main.py - -python3 main.py -``` - ---- - -## 📊 Porovnání Výkonu - -### Rendering Speed: -- **Clean**: Rychlejší (bez blur efektů) -- **Gradient**: Pomalejší (backdrop-filter je náročný) - -### Čitelnost Grafů: -- **Clean**: ⭐⭐⭐⭐⭐ (Vynikající) -- **Gradient**: ⭐⭐⭐ (Průměrná) - -### Professional Look: -- **Clean**: ⭐⭐⭐⭐⭐ (Cloudflare style) -- **Gradient**: ⭐⭐⭐⭐ (Moderní, ale ne pro všechny) - ---- - -## 🎨 Customizace - -Chceš jiné barvy? Změň v main_clean.py: - -```css -:root { - --primary: #3b82f6; ← Změň na jinou barvu - /* Příklady: */ - /* Zelená: #10b981 */ - /* Fialová: #8b5cf6 */ - /* Červená: #ef4444 */ - /* Oranžová: #f59e0b */ -} -``` - -Vše ostatní se automaticky přizpůsobí! - ---- - -## ✅ Doporučení - -Pro většinu uživatelů doporučuji **main_clean.py**: -- ✅ Lépe viditelné grafy -- ✅ Čistší design -- ✅ Rychlejší rendering -- ✅ Profesionální vzhled -- ✅ Inspirováno Cloudflare - ---- - -**Vytvořeno s důrazem na čitelnost a profesionální vzhled! 🎉** diff --git a/DOWNLOAD_SUMMARY.md b/DOWNLOAD_SUMMARY.md deleted file mode 100644 index 6dd6585..0000000 --- a/DOWNLOAD_SUMMARY.md +++ /dev/null @@ -1,313 +0,0 @@ -# 🎉 UrNetwork Stats Dashboard v2.1.1 - Complete Package Ready! - -## ✅ Všechny Soubory Připraveny ke Stažení - -Kompletní balík souborů pro UrNetwork Stats Dashboard v2.1.1 je připraven! - ---- - -## 📦 Seznam Souborů (18 souborů) - -### 🐍 Hlavní Aplikace (2 soubory) - -1. **[main_clean.py](computer:///mnt/user-data/outputs/main_clean.py)** - 87 KB ⭐ **POUŽIJ TENTO!** - - Přejmenuj na `main.py` - - Clean Cloudflare design - - Bílý text na grafech - - Tooltip kdekoliv - - Denní cleanup - -2. **[main_enhanced.py](computer:///mnt/user-data/outputs/main_enhanced.py)** - 85 KB - - Alternativa s gradienty - - Fialové téma - - Volitelný - ---- - -### 📖 Dokumentace (12 souborů) - -3. **[README.md](computer:///mnt/user-data/outputs/README.md)** - 10 KB - - Hlavní anglický README - - Kompletní dokumentace - -4. **[README_CZ.md](computer:///mnt/user-data/outputs/README_CZ.md)** - 5.3 KB - - Český README - - Úplná česká dokumentace - -5. **[FILE_INDEX.md](computer:///mnt/user-data/outputs/FILE_INDEX.md)** - 8.1 KB ⭐ - - **ZAČNI ODTUD!** - - Přehled všech souborů - - Instalační návod - - Checklist - -6. **[QUICKSTART.md](computer:///mnt/user-data/outputs/QUICKSTART.md)** - 5.2 KB - - Rychlý start za 5 minut - -7. **[WEBHOOK_GUIDE.md](computer:///mnt/user-data/outputs/WEBHOOK_GUIDE.md)** - 7.9 KB - - 10+ webhook příkladů - - Discord, Slack, Telegram - -8. **[DESIGN_COMPARISON.md](computer:///mnt/user-data/outputs/DESIGN_COMPARISON.md)** - 5.3 KB - - Srovnání designů - - Proč tento design? - -9. **[CHART_INTERACTION.md](computer:///mnt/user-data/outputs/CHART_INTERACTION.md)** - 5.2 KB - - Tooltip vylepšení - - Jak to funguje - -10. **[FIXES_v2.1.md](computer:///mnt/user-data/outputs/FIXES_v2.1.md)** - 6.7 KB - - Všechny opravy v2.1 - -11. **[UPGRADE_GUIDE.md](computer:///mnt/user-data/outputs/UPGRADE_GUIDE.md)** - 6.7 KB - - Migrace z v1.0/v2.0 - -12. **[CHANGELOG.md](computer:///mnt/user-data/outputs/CHANGELOG.md)** - 2.7 KB - - Historie verzí - -13. **[FIX_INSTANCE_FOLDER.md](computer:///mnt/user-data/outputs/FIX_INSTANCE_FOLDER.md)** - 2.8 KB - - Fix pro starší instalace - -14. **[IMMEDIATE_FIX.md](computer:///mnt/user-data/outputs/IMMEDIATE_FIX.md)** - 3.1 KB - - Rychlé opravy - ---- - -### 🛠️ Instalační Soubory (4 soubory) - -15. **[requirements.txt](computer:///mnt/user-data/outputs/requirements.txt)** - 120 B - - Python závislosti - - Pro `pip install -r` - -16. **[install.sh](computer:///mnt/user-data/outputs/install.sh)** - 2.8 KB - - Automatický instalátor - - Bash script - -17. **[.gitignore](computer:///mnt/user-data/outputs/.gitignore)** - * - - Git ignore pravidla - -18. **[migrate.py](computer:///mnt/user-data/outputs/migrate.py)** - 11 KB - - Migrace z v1.0 - ---- - -## 🚀 Co Dělat Nyní - -### Krok 1: Stáhnout Všechny Soubory ⬇️ - -**Minimální sada (pro rychlý start):** -``` -✅ main_clean.py → přejmenuj na main.py -✅ requirements.txt -✅ FILE_INDEX.md → přečti FIRST! -✅ README.md nebo README_CZ.md -``` - -**Doporučená sada (kompletní):** -``` -✅ Všech 18 souborů -``` - -### Krok 2: Instalace 🔧 - -```bash -# 1. Vytvoř složku -mkdir urnetwork-stats -cd urnetwork-stats - -# 2. Stáhni soubory do této složky - -# 3. Přejmenuj hlavní soubor -mv main_clean.py main.py - -# 4. Spusť instalaci -chmod +x install.sh -./install.sh - -# NEBO manuálně: -pip3 install -r requirements.txt -mkdir -p instance - -# 5. Spusť -python3 main.py - -# 6. Otevři prohlížeč -# http://localhost:90 -``` - -### Krok 3: První Spuštění ⚙️ - -1. **Nastav admin heslo** (NENÍ UrNetwork heslo!) -2. **Přidej účty** - Menu → Správa Účtů -3. **Nastav webhooky** (volitelné) - Menu → Nastavení -4. **Hotovo!** 🎉 - ---- - -## 📋 Checklist Před Nahráním na Server/Repo - -- [ ] Všech 18 souborů staženo -- [ ] `main_clean.py` přejmenován na `main.py` -- [ ] Vytvořena složka `docs/` (volitelné) -- [ ] README.md v root složce -- [ ] requirements.txt v root složce -- [ ] install.sh má +x práva (`chmod +x install.sh`) -- [ ] .gitignore přítomen - ---- - -## 📂 Doporučená Struktura Po Stažení - -``` -urnetwork-stats/ # Root složka -├── main.py # ← Z main_clean.py -├── requirements.txt -├── install.sh -├── migrate.py -├── .gitignore -├── README.md -├── README_CZ.md -└── docs/ # Volitelná podsložka - ├── FILE_INDEX.md # ← Začni odtud! - ├── QUICKSTART.md - ├── WEBHOOK_GUIDE.md - ├── DESIGN_COMPARISON.md - ├── CHART_INTERACTION.md - ├── FIXES_v2.1.md - ├── UPGRADE_GUIDE.md - ├── CHANGELOG.md - ├── FIX_INSTANCE_FOLDER.md - └── IMMEDIATE_FIX.md -``` - -**Nebo jednodušeji (bez docs/ složky):** -``` -urnetwork-stats/ -├── main.py -├── requirements.txt -├── install.sh -├── .gitignore -├── README.md -└── (všechny ostatní .md soubory) -``` - ---- - -## 🎯 Priority Po Stažení - -### Musíš Přečíst (Povinné): -1. **[FILE_INDEX.md](computer:///mnt/user-data/outputs/FILE_INDEX.md)** ⭐ - Začni odtud! -2. **[README.md](computer:///mnt/user-data/outputs/README.md)** nebo **[README_CZ.md](computer:///mnt/user-data/outputs/README_CZ.md)** - Hlavní dokumentace - -### Měl bys Přečíst (Doporučené): -3. **[QUICKSTART.md](computer:///mnt/user-data/outputs/QUICKSTART.md)** - Rychlý start -4. **[WEBHOOK_GUIDE.md](computer:///mnt/user-data/outputs/WEBHOOK_GUIDE.md)** - Webhook setup - -### Můžeš Přečíst Později (Volitelné): -5. Ostatní `.md` soubory podle potřeby - ---- - -## 💾 Velikost Balíku - -**Celkem:** ~260 KB (všech 18 souborů) -- Aplikace (main.py): ~87 KB -- Dokumentace: ~70 KB -- Skripty: ~15 KB -- Ostatní: ~88 KB - -**Minimální sada:** ~97 KB -- main.py + requirements.txt + README.md - ---- - -## 🔄 Upgrade z Předchozí Verze? - -### Z v1.0 → v2.1: -1. Záloha `.env` a databáze -2. Stáhni nové soubory -3. Přejmenuj `main_clean.py` → `main.py` -4. Spusť `python3 migrate.py` -5. Restart - -### Z v2.0 → v2.1: -1. Záloha `main.py` -2. Nahraď `main_clean.py` → `main.py` -3. Restart - -📖 **Detaily:** [UPGRADE_GUIDE.md](computer:///mnt/user-data/outputs/UPGRADE_GUIDE.md) - ---- - -## 🐛 První Pomoc - -**Problém:** Port 90 obsazený -```python -# main.py, poslední řádek: -app.run(host="0.0.0.0", port=8080, debug=False) -``` - -**Problém:** Chybí závislosti -```bash -pip3 install -r requirements.txt -``` - -**Problém:** Nemůžu se přihlásit -```bash -echo "ADMIN_PASSWORD=tvoje_heslo" >> .env -``` - -**Problém:** Grafy bez textu -- Ujisti se, že používáš `main_clean.py` (ne `main_enhanced.py`) - ---- - -## 📞 Podpora - -- **Dokumentace:** Všechny `.md` soubory -- **Issues:** GitHub/Forgejo Issues -- **Quick Help:** [FILE_INDEX.md](computer:///mnt/user-data/outputs/FILE_INDEX.md) má FAQ - ---- - -## ✨ Co Je Nového v v2.1.1 - -- ✅ **Tooltip kdekoliv** na grafu (ne jen na bodech) -- ✅ **Bílý text** na grafech (konečně čitelný!) -- ✅ **Denní cleanup** (každý den ve 3:00) -- ✅ **Login button** v headeru -- ✅ Formátované hodnoty (3 des. místa) -- ✅ Better mobile/touch UX - -📖 **Detaily:** [FIXES_v2.1.md](computer:///mnt/user-data/outputs/FIXES_v2.1.md) - ---- - -## 🎉 Hotovo! - -**Máš všech 18 souborů připravených!** - -**Next Steps:** -1. ⬇️ Stáhni všechny soubory -2. 📖 Přečti [FILE_INDEX.md](computer:///mnt/user-data/outputs/FILE_INDEX.md) -3. 🚀 Spusť instalaci -4. 🎊 Užij si! - ---- - -**Made with ❤️ and 🤖 AI** - -**Version:** v2.1.1 -**Date:** November 21, 2024 -**Author:** Vlastík (mxnticek) + Claude (Anthropic) - ---- - -## 🔗 Quick Links - -- [FILE_INDEX.md](computer:///mnt/user-data/outputs/FILE_INDEX.md) - **Začni odtud!** -- [README.md](computer:///mnt/user-data/outputs/README.md) - Hlavní dokumentace -- [main_clean.py](computer:///mnt/user-data/outputs/main_clean.py) - Hlavní aplikace -- [requirements.txt](computer:///mnt/user-data/outputs/requirements.txt) - Závislosti -- [WEBHOOK_GUIDE.md](computer:///mnt/user-data/outputs/WEBHOOK_GUIDE.md) - Webhook návod - -**Stáhni vše a jsi ready to go! 🚀** diff --git a/FILE_INDEX.md b/FILE_INDEX.md deleted file mode 100644 index 14887d6..0000000 --- a/FILE_INDEX.md +++ /dev/null @@ -1,367 +0,0 @@ -# 📦 UrNetwork Stats Dashboard v2.1.1 - Complete Package - -## 📥 Download All Files - -Toto je kompletní balík souborů pro UrNetwork Stats Dashboard v2.1.1. - ---- - -## 📂 Hlavní Soubory - -### 🐍 Aplikace - -**[main_clean.py](computer:///mnt/user-data/outputs/main_clean.py)** - ⭐ **HLAVNÍ SOUBOR** -- Kompletní Flask aplikace -- Multi-account podpora -- Čistý Cloudflare design -- Všechny opravy v2.1.1 -- **Přejmenuj na `main.py` při instalaci!** -- Velikost: ~88 KB - -**[main_enhanced.py](computer:///mnt/user-data/outputs/main_enhanced.py)** - Alternativa s gradienty -- Verze s fialovým gradientem a glassmorphismem -- Pro ty, kdo preferují původní v2.0 design -- Velikost: ~86 KB - ---- - -### 📖 Dokumentace - -**[README.md](computer:///mnt/user-data/outputs/README.md)** - Hlavní anglický README -- Kompletní dokumentace projektu -- Quick start guide -- Webhook příklady -- Troubleshooting - -**[README_CZ.md](computer:///mnt/user-data/outputs/README_CZ.md)** - Český README -- Úplná česká dokumentace -- Rychlý start -- Webhook návod - -**[QUICKSTART.md](computer:///mnt/user-data/outputs/QUICKSTART.md)** - Rychlý start -- Instalace za 5 minut -- První spuštění -- Základní konfigurace - -**[WEBHOOK_GUIDE.md](computer:///mnt/user-data/outputs/WEBHOOK_GUIDE.md)** - Webhook návod -- 10+ webhook příkladů -- Discord, Slack, Telegram -- Dostupné proměnné -- Debugging tipy - -**[DESIGN_COMPARISON.md](computer:///mnt/user-data/outputs/DESIGN_COMPARISON.md)** - Design dokumentace -- Srovnání v2.0 vs v2.1 -- Důvody změn -- Customizace barev - -**[CHART_INTERACTION.md](computer:///mnt/user-data/outputs/CHART_INTERACTION.md)** - Graf interakce -- Tooltip kdekoliv na grafu -- Jak to funguje -- Mobile optimalizace - -**[FIXES_v2.1.md](computer:///mnt/user-data/outputs/FIXES_v2.1.md)** - Seznam oprav v2.1 -- Všechny opravy -- Před/po srovnání -- Technické detaily - -**[UPGRADE_GUIDE.md](computer:///mnt/user-data/outputs/UPGRADE_GUIDE.md)** - Upgrade průvodce -- Migrace z v1.0 -- Upgrade z v2.0 -- Backup strategie - -**[CHANGELOG.md](computer:///mnt/user-data/outputs/CHANGELOG.md)** - Historie změn -- Všechny verze -- Co je nového -- Breaking changes - ---- - -### 🛠️ Instalační Soubory - -**[requirements.txt](computer:///mnt/user-data/outputs/requirements.txt)** - Python závislosti -```txt -Flask==3.0.0 -Flask-SQLAlchemy==3.1.1 -Flask-APScheduler==1.13.1 -requests==2.31.0 -python-dateutil==2.8.2 -gunicorn==21.2.0 -``` - -**[install.sh](computer:///mnt/user-data/outputs/install.sh)** - Automatický instalační script -- Kontrola závislostí -- Instalace balíčků -- Vytvoření složek -- Backup existujících dat - -**[.gitignore](computer:///mnt/user-data/outputs/.gitignore)** - Git ignore file -- Python cache -- Virtual environments -- Database files -- Environment variables - ---- - -### 🔧 Utility Skripty - -**[migrate.py](computer:///mnt/user-data/outputs/migrate.py)** - Migrace z v1.0 -- Automatický upgrade na v2.0 -- Zachování dat -- Backup tvorba - -**[fix_db_path.py](computer:///mnt/user-data/outputs/fix_db_path.py)** - Fix databázové cesty -- Oprava instance folder problémů -- Pro starší instalace - ---- - -## 🚀 Rychlá Instalace - -### Metoda 1: Automatická (Doporučeno) - -```bash -# 1. Stáhni všechny soubory do složky -cd urnetwork-stats - -# 2. Přejmenuj main_clean.py na main.py -mv main_clean.py main.py - -# 3. Spusť instalační script -chmod +x install.sh -./install.sh - -# 4. Spusť aplikaci -python3 main.py -``` - -### Metoda 2: Manuální - -```bash -# 1. Stáhni soubory -cd urnetwork-stats - -# 2. Přejmenuj -mv main_clean.py main.py - -# 3. Instaluj závislosti -pip3 install -r requirements.txt - -# 4. Vytvoř složky -mkdir -p instance - -# 5. Spusť -python3 main.py -``` - -### Metoda 3: S Gunicorn (Produkce) - -```bash -# Po instalaci závislostí -gunicorn --bind 0.0.0.0:90 --workers 4 main:app -``` - ---- - -## 📋 Checklist Po Stažení - -- [ ] Stáhnout všechny soubory -- [ ] Přejmenovat `main_clean.py` → `main.py` -- [ ] Spustit `install.sh` nebo manuální instalaci -- [ ] Otevřít `http://localhost:90` -- [ ] Nastavit admin heslo -- [ ] Přidat UrNetwork účty -- [ ] (Volitelné) Nastavit webhooky -- [ ] (Volitelné) Přidat do systemd - ---- - -## 📊 Struktura Po Instalaci - -``` -urnetwork-stats/ -├── main.py # Hlavní aplikace (z main_clean.py) -├── main_enhanced.py # Alternativa (volitelné) -├── requirements.txt # Závislosti -├── install.sh # Instalační script -├── migrate.py # Migrace script -├── .gitignore # Git ignore -├── .env # Config (vytvoří se automaticky) -├── instance/ -│ └── transfer_stats.db # Databáze (vytvoří se automaticky) -└── docs/ - ├── README.md - ├── README_CZ.md - ├── QUICKSTART.md - ├── WEBHOOK_GUIDE.md - ├── DESIGN_COMPARISON.md - ├── CHART_INTERACTION.md - ├── FIXES_v2.1.md - ├── UPGRADE_GUIDE.md - └── CHANGELOG.md -``` - ---- - -## 🎯 Co Potřebuješ Minimálně - -Pro základní funkčnost: - -1. **Povinné:** - - `main_clean.py` (přejmenuj na `main.py`) - - `requirements.txt` - -2. **Doporučené:** - - `README.md` nebo `QUICKSTART.md` - - `install.sh` (usnadní instalaci) - -3. **Volitelné:** - - Všechny ostatní `.md` soubory (dokumentace) - - `main_enhanced.py` (alternativní design) - - `migrate.py` (jen pokud upgraduješ z v1.0) - ---- - -## 🔄 Upgrade z Předchozí Verze - -### Z v1.0 (Single Account) - -```bash -# 1. Záloha -cp .env .env.backup -cp instance/transfer_stats.db instance/transfer_stats.db.backup - -# 2. Stáhnout nové soubory -# (všechny soubory z tohoto balíku) - -# 3. Přejmenovat -mv main_clean.py main.py - -# 4. Spustit migraci -python3 migrate.py - -# 5. Restart -python3 main.py -``` - -### Z v2.0 (Gradient Design) - -```bash -# Jednoduše nahraď main.py -cp main.py main.py.v2.0.backup -mv main_clean.py main.py -python3 main.py -``` - ---- - -## 📖 První Kroky Po Instalaci - -1. **Otevři prohlížeč:** `http://localhost:90` -2. **Nastav admin heslo:** (NENÍ to tvé UrNetwork heslo!) -3. **Přidej účty:** - - Menu → Správa Účtů - - Přidat Účet - - Zadej UrNetwork email, heslo, přezdívku -4. **Nastav webhooky (volitelné):** - - Menu → Nastavení - - Webhook Management - - Přidej Discord/Slack/Telegram URL + payload -5. **Hotovo!** Dashboard začne sbírat data každých 15 minut - ---- - -## 🐛 Časté Problémy - -### Port 90 je obsazený -```python -# Změň v main.py poslední řádek: -app.run(host="0.0.0.0", port=8080, debug=False) -``` - -### Chybí závislosti -```bash -pip3 install Flask Flask-SQLAlchemy Flask-APScheduler requests python-dateutil -``` - -### Nemůžu se přihlásit -```bash -# Zkontroluj .env -cat .env | grep ADMIN_PASSWORD -# Pokud chybí: -echo "ADMIN_PASSWORD=tvoje_heslo" >> .env -``` - -### Grafy neukazují text -- Ujisti se, že používáš `main_clean.py` (ne `main_enhanced.py`) -- Verze musí být v2.1+ - ---- - -## 💡 Pro Tipy - -### Rychlé Testování -```bash -# Spusť bez instalace systemd -python3 main.py - -# V produkci použij Gunicorn -gunicorn --bind 0.0.0.0:90 main:app -``` - -### Vývoj -```bash -# Debug mode -python3 main.py # Debug je defaultně vypnutý - -# Pro development změň v main.py: -app.run(host="0.0.0.0", port=90, debug=True) -``` - -### Backup -```bash -# Před každým upgradem -cp .env .env.backup -cp instance/transfer_stats.db instance/transfer_stats.db.backup -``` - ---- - -## 📞 Podpora - -- **Issues:** Forgejo Issues -- **Dokumentace:** Všechny `.md` soubory v balíku -- **Discord:** (pokud máš komunitní server) - ---- - -## ✅ Závěrečný Checklist - -Před nahráním na server/repo zkontroluj: - -- [ ] Všechny soubory staženy -- [ ] `main_clean.py` přejmenován na `main.py` -- [ ] `requirements.txt` přítomen -- [ ] `README.md` přítomen -- [ ] `install.sh` má +x práva -- [ ] `.gitignore` přítomen -- [ ] Dokumentace v `docs/` (volitelné) - ---- - -## 🎉 Hotovo! - -Máš kompletní balík souborů pro UrNetwork Stats Dashboard v2.1.1! - -**Co dělat dál:** -1. Stáhni všechny soubory -2. Nahraj na server/do repozitáře -3. Spusť instalaci -4. Užij si! - -**Made with ❤️ and 🤖 AI** - ---- - -**Verze:** v2.1.1 -**Datum:** 21. listopadu 2024 -**Autor:** Vlastík (mxnticek) + Claude (Anthropic) diff --git a/FIXES_v2.1.md b/FIXES_v2.1.md deleted file mode 100644 index ce32e6a..0000000 --- a/FIXES_v2.1.md +++ /dev/null @@ -1,287 +0,0 @@ -# ✅ Opravy v main_clean.py - Finální Verze - -## 🎯 Co bylo opraveno - -### 1. ✅ Grafy - Viditelný Text -**Problém:** Text na grafech byl černý a skoro neviditelný na tmavém pozadí - -**Oprava:** -```javascript -// PŘED - Špatně viditelný -ticks: { color: 'var(--text-muted)' } // Tmavě šedá -legend: { labels: { color: 'var(--text-color)' } } // Není dostatečně světlá - -// PO - Jasně viditelný ✅ -ticks: { color: '#e5e7eb', font: { size: 12 } } // Světle bílá -legend: { - labels: { - color: '#ffffff', // Čistě bílá - font: { size: 13, weight: '500' }, - padding: 15 - } -} -``` - -**Vylepšení:** -- ✅ Osy (X, Y) - bílý text místo šedého -- ✅ Legenda - bílý tučný text -- ✅ Tooltips - tmavé pozadí s modrým rámečkem -- ✅ Větší velikost písma pro lepší čitelnost - ---- - -### 2. ✅ Login Tlačítko v Headeru -**Problém:** Nebylo jasné, kde se přihlásit, když nejsi přihlášený - -**Oprava:** -```html - -{% if session.logged_in %} - -{% else %} - Přihlásit se -{% endif %} -``` - -**CSS:** -```css -.header-nav a.login-btn { - background: #3b82f6; /* Modré pozadí */ - color: white; - font-weight: 600; /* Tučné */ -} -``` - -**Výsledek:** -- ✅ Viditelné modré tlačítko "Přihlásit se" v headeru -- ✅ Zobrazuje se pouze když nejsi přihlášený -- ✅ Zmizí po přihlášení - ---- - -### 3. ✅ Automatické Mazání Starých Dat -**Problém:** Data se mazala jen jednou týdně v neděli - -**Oprava:** -```python -# PŘED - Jednou týdně -@scheduler.task(trigger="cron", day_of_week="sun", hour="0") - -# PO - Každý den ✅ -@scheduler.task(trigger="cron", hour="3", minute="0") -``` - -**Jak to funguje:** -1. **Každý den ve 3:00 ráno** se spustí cleanup job -2. Smaže všechny záznamy **starší než 7 dní** -3. Ponechá data z **posledního týdne** -4. Loguje kolik záznamů bylo smazáno - -**Příklad:** -``` -Dnes je: 21. listopadu 2024 -Smaže se: Vše před 14. listopadem 2024 -Zůstane: 14. - 21. listopadu (poslední 7 dní) -``` - ---- - -## 📊 Před & Po - Vizuální Srovnání - -### Grafy - Text -``` -PŘED: -┌────────────────────────┐ -│ Graf │ -│ (text skoro neviditelný)│ -│ Osa Y: #9ca3af (tmavá) │ -│ Osa X: #9ca3af (tmavá) │ -│ Legenda: #d1d5db │ -└────────────────────────┘ - -PO: -┌────────────────────────┐ -│ Graf │ -│ (text jasně viditelný!) │ -│ Osa Y: #e5e7eb (světlá)│ -│ Osa X: #e5e7eb (světlá)│ -│ Legenda: #ffffff (bílá)│ -└────────────────────────┘ -``` - -### Header -``` -PŘED: -[Veřejný pohled] (když nejsi přihlášený, není jasné kde se přihlásit) - -PO: -[Veřejný pohled] [🔵 Přihlásit se] (jasné modré tlačítko) -``` - -### Cleanup Schedule -``` -PŘED: -Neděle 00:00 → Smaže data starší 7 dní - -PO: -Každý den 03:00 → Smaže data starší 7 dní -``` - ---- - -## 🚀 Instalace Opravené Verze - -```bash -cd ~/urio - -# Zazálohuj současnou verzi -cp main.py main.py.before_fixes - -# Nahraď opravenou verzí -cp /path/to/main_clean.py main.py - -# Restartuj -pkill -f main.py -python3 main.py -``` - ---- - -## ✨ Co se vylepšilo - -### Čitelnost Grafů ⭐⭐⭐⭐⭐ -- **PŘED**: ⭐⭐ (Text skoro neviditelný) -- **PO**: ⭐⭐⭐⭐⭐ (Jasně čitelné vše!) - -### UX - Přihlášení ⭐⭐⭐⭐⭐ -- **PŘED**: ⭐⭐⭐ (Musíš znát URL /login) -- **PO**: ⭐⭐⭐⭐⭐ (Jasné modré tlačítko v headeru) - -### Údržba Databáze ⭐⭐⭐⭐⭐ -- **PŘED**: ⭐⭐⭐⭐ (Týdně - může se hromadit) -- **PO**: ⭐⭐⭐⭐⭐ (Denně - vždy jen poslední týden) - ---- - -## 🎨 Technické Detaily - -### Chart.js Konfigurace -```javascript -// Kompletní chart options pro viditelný text -{ - scales: { - y: { - ticks: { - color: '#e5e7eb', // Světlá barva - font: { size: 12 } // Větší písmo - }, - grid: { - color: 'rgba(45, 49, 53, 0.3)' // Jemná mřížka - } - }, - x: { - ticks: { - color: '#e5e7eb', - font: { size: 11 } - } - } - }, - plugins: { - legend: { - labels: { - color: '#ffffff', // Bílá - font: { size: 13, weight: '500' }, - padding: 15 - } - }, - tooltip: { - backgroundColor: 'rgba(26, 29, 31, 0.95)', // Tmavé pozadí - titleColor: '#ffffff', - bodyColor: '#e5e7eb', - borderColor: '#3b82f6', - borderWidth: 1, - padding: 12 - } - } -} -``` - -### Cleanup Job -```python -@scheduler.task( - id="cleanup_old_stats_job", - trigger="cron", - hour="3", # Každý den ve 3:00 - minute="0" -) -def cleanup_old_stats_job(): - cutoff_date = datetime.datetime.now() - datetime.timedelta(days=7) - # Smaže vše starší než cutoff_date - db.session.query(Stats).filter(Stats.timestamp < cutoff_date).delete() -``` - ---- - -## 💾 Velikost Databáze - -S denním čištěním: -``` -Stats každých 15 min = 96 záznamů/den -7 dní × 96 = 672 záznamů max -3 účty × 672 = ~2000 záznamů max - -Velikost: ~200 KB databáze (velmi malá!) -``` - -Bez čištění (týdně): -``` -Po měsíci: ~8000 záznamů -Velikost: ~800 KB (pořád OK, ale zbytečné) -``` - ---- - -## 🔍 Ověření Změn - -### 1. Grafy -``` -Otevři dashboard → Podívej se na graf -✅ Čísla na osách jsou bílá a čitelná -✅ Legenda je bílá a tučná -✅ Tooltips mají modré ohraničení -``` - -### 2. Login Tlačítko -``` -Odhlásit se (pokud jsi přihlášený) -✅ V headeru se objeví modré tlačítko "Přihlásit se" -Přihlásit se -✅ Tlačítko zmizí, objeví se menu -``` - -### 3. Cleanup Job -```bash -# Zkontroluj logy -tail -f nohup.out | grep cleanup - -# Mělo by se objevit každý den ve 3:00 -# "Running daily stats cleanup job..." -# "Successfully deleted X stats records older than 7 days." -``` - ---- - -## 📝 Changelog - -### v2.1 - 2024-11-21 -- ✅ Fixed chart text visibility (white text instead of dark gray) -- ✅ Added Login button to header when not logged in -- ✅ Changed cleanup schedule from weekly to daily (3 AM) -- ✅ Enhanced tooltip styling with blue borders -- ✅ Increased font sizes for better readability - ---- - -**Všechno opraveno a připraveno k použití! 🎉** - -Grafy jsou nyní perfektně čitelné, login je viditelný a databáze se čistí každý den automaticky! diff --git a/FIX_INSTANCE_FOLDER.md b/FIX_INSTANCE_FOLDER.md deleted file mode 100644 index 8466894..0000000 --- a/FIX_INSTANCE_FOLDER.md +++ /dev/null @@ -1,113 +0,0 @@ -# 🔧 Fix: Databáze v instance/ složce - -## Problém -Pokud vidíš chybu: -``` -✗ Databáze transfer_stats.db nenalezena! -``` - -Ale databáze je ve složce `instance/`: -```bash -ls instance/ -# transfer_stats.db -``` - -## Řešení - -Opravený migrační skript již automaticky hledá databázi v těchto lokacích: -- `transfer_stats.db` (root složka) -- `instance/transfer_stats.db` (Flask standardní umístění) -- `../transfer_stats.db` (parent folder) - -### Použij aktualizované soubory - -Právě jsem opravil oba soubory: -1. **migrate.py** - Nyní hledá DB v instance/ -2. **main_enhanced.py** - Používá správnou cestu `sqlite:///instance/transfer_stats.db` - -### Rychlé řešení - -```bash -# 1. Stáhni znovu opravené soubory z /mnt/user-data/outputs/ -# 2. Překopíruj je do ~/urio/ -cd ~/urio - -# 3. Zkus migraci znovu -python3 migrate.py -``` - -## Alternativní řešení (pokud potřebuješ hned) - -Pokud chceš použít stávající soubory bez stahování nových: - -```bash -cd ~/urio - -# Přesuň databázi do root složky -cp instance/transfer_stats.db . - -# Spusť migraci -python3 migrate.py - -# Po úspěšné migraci, databáze zůstane v root složce -# nebo ji vrať do instance/ -mv transfer_stats.db instance/ -``` - -## Ověření - -Po úspěšné migraci by měl výstup vypadat takto: - -``` -============================================================ - Vytváření záloh -============================================================ -✓ Zazálohován .env → .env.backup -✓ Zazálohována databáze → instance/transfer_stats.db.backup - -============================================================ - Migrace databáze -============================================================ -✓ Nalezena databáze: instance/transfer_stats.db -✓ Vytvořena tabulka accounts -✓ Přidán sloupec account_id do tabulky stats - -Nalezen existující účet: vlastik.novotny2005@gmail.com -Zadejte přezdívku pro tento účet: Hlavní účet - -✓ Migrován účet: vlastik.novotny2005@gmail.com - ✓ Přezdívka: Hlavní účet - ✓ Aktualizováno X statistických záznamů - -✓ Migrace databáze dokončena! -``` - -## Nová verze používá instance/ automaticky - -Opravená verze `main_enhanced.py`: -```python -# Config nyní používá: -SQLALCHEMY_DATABASE_URI = "sqlite:///instance/transfer_stats.db" - -# A automaticky vytvoří instance/ složku, pokud neexistuje -``` - -Takže po migraci vše funguje správně s databází v `instance/` složce. - -## Stáhni opravené soubory - -Všechny soubory v `/mnt/user-data/outputs/` jsou již opravené a ready to use! - -```bash -# Zkopíruj opravené soubory -cd ~/urio -cp /cesta/k/stazenym/migrate.py . -cp /cesta/k/stazenym/main_enhanced.py . - -# A spusť migraci znovu -python3 migrate.py -``` - ---- - -Tohle by mělo problém vyřešit! Zkus to a dej vědět, jestli to funguje. 🚀 diff --git a/IMMEDIATE_FIX.md b/IMMEDIATE_FIX.md deleted file mode 100644 index 6c4e1da..0000000 --- a/IMMEDIATE_FIX.md +++ /dev/null @@ -1,129 +0,0 @@ -# 🚑 OKAMŽITÁ OPRAVA - Database Path Error - -## Problém -``` -sqlite3.OperationalError: unable to open database file -``` - -## ⚡ Rychlé Řešení (30 sekund) - -### Varianta 1: Automatická oprava -```bash -cd ~/urio -python3 fix_db_path.py -python3 main.py -``` - -### Varianta 2: Manuální oprava -```bash -cd ~/urio - -# Přidej do main.py hned za class Config: -# Najdi tuto řádku (řádek ~33): -# SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", "sqlite:///instance/transfer_stats.db") -# -# A nahraď ji tímto (3 řádky): -# BASE_DIR = os.path.abspath(os.path.dirname(__file__)) -# INSTANCE_DIR = os.path.join(BASE_DIR, 'instance') -# SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", f"sqlite:///{os.path.join(INSTANCE_DIR, 'transfer_stats.db')}") -``` - -### Varianta 3: Použij opravený soubor -```bash -cd ~/urio - -# Stáhni znovu main_enhanced.py z outputs/ -# A přepiš jím současný main.py -mv main.py main.py.broken -cp /path/to/main_enhanced.py main.py - -python3 main.py -``` - -## 🔍 Co je problém? - -SQLAlchemy používá relativní cestu `sqlite:///instance/transfer_stats.db`, ale instance folder neexistuje v době, kdy se SQLAlchemy inicializuje. - -## ✅ Co oprava dělá? - -1. **Použije absolutní cestu** místo relativní -2. **Vytvoří instance/ folder** PŘED inicializací SQLAlchemy -3. **Nastaví správnou cestu** k databázi - -## 📝 Změny v kódu - -### PŘED (nefungující): -```python -class Config: - SQLALCHEMY_DATABASE_URI = "sqlite:///instance/transfer_stats.db" - -app = Flask(__name__) -app.config.from_object(Config) -# instance folder se vytváří tady ← TOO LATE! -``` - -### PO (fungující): -```python -class Config: - BASE_DIR = os.path.abspath(os.path.dirname(__file__)) - INSTANCE_DIR = os.path.join(BASE_DIR, 'instance') - SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(INSTANCE_DIR, 'transfer_stats.db')}" - -# instance folder se vytváří tady ← BEFORE app init! -if not os.path.exists(Config.INSTANCE_DIR): - os.makedirs(Config.INSTANCE_DIR) - -app = Flask(__name__) -app.config.from_object(Config) -``` - -## 🎯 Ověření - -Po opravě by měl výstup vypadat takto: -```bash -$ python3 main.py -2025-11-21 12:20:51,319 - INFO - Successfully loaded world map GeoJSON data. -2025-11-21 12:20:51,450 - INFO - Scheduler started - * Serving Flask app 'main' - * Running on http://0.0.0.0:90 -``` - -✅ Bez chyby "unable to open database file"! - -## 🆘 Stále nefunguje? - -Zkontroluj: - -```bash -# 1. Existuje instance složka? -ls -la instance/ - -# 2. Jsou v ní správné soubory? -ls -la instance/transfer_stats.db* - -# 3. Má Python práva na zápis? -touch instance/test.txt && rm instance/test.txt - -# 4. Je databáze validní? -sqlite3 instance/transfer_stats.db ".tables" -``` - -Pokud všechno OK, měl by výstup být: -``` -accounts settings stats webhook -``` - ---- - -## 📦 Aktualizované soubory - -Všechny soubory v `/mnt/user-data/outputs/` jsou již opravené: -- ✅ **main_enhanced.py** - Opravená verze -- ✅ **fix_db_path.py** - Automatický fix skript -- ✅ **migrate.py** - Funguje s instance/ - -Stačí je použít a vše bude fungovat! - ---- - -**Vyřešilo to problém? Dej mi vědět!** 🚀 diff --git a/QUICKSTART.md b/QUICKSTART.md deleted file mode 100644 index a6da15d..0000000 --- a/QUICKSTART.md +++ /dev/null @@ -1,194 +0,0 @@ -# 🚀 UrNetwork Stats Dashboard v2.0 - QUICK START - -## 📦 Balíček obsahuje: - -``` -urnetwork-stats-v2/ -├── main_enhanced.py # Hlavní aplikace (přejmenovat na main.py) -├── migrate.py # Migrační skript pro upgrade -├── install.sh # Instalační skript pro nové instalace -├── README_CZ.md # Kompletní dokumentace -├── UPGRADE_GUIDE.md # Průvodce upgradem -└── QUICKSTART.md # Tento soubor -``` - -## ⚡ Pro NOVOU instalaci (prázdná složka) - -```bash -# 1. Nahrajte všechny soubory do složky -cd ~/urnetwork-stats - -# 2. Přejmenujte hlavní soubor -mv main_enhanced.py main.py - -# 3. Spusťte instalační skript -bash install.sh - -# 4. Spusťte aplikaci -python3 main.py - -# 5. Otevřete v prohlížeči -http://your-server:90 -``` - -## 🔄 Pro UPGRADE existující instalace - -```bash -# 1. Zazálohujte současnou složku -cd ~ -cp -r urio urio_backup - -# 2. Nahrajte POUZE tyto soubory do existující složky: -# - main_enhanced.py → přejmenovat na main.py -# - migrate.py - -# 3. Zastavte běžící aplikaci -pkill -f main.py - -# 4. Spusťte migraci -cd ~/urio -python3 migrate.py - -# 5. Spusťte novou verzi -python3 main.py - -# 6. Přihlaste se novým admin heslem -http://your-server:90 -``` - -## 🎯 První kroky po instalaci - -### 1. Nastavení Admin Hesla -- Při první návštěvě nastavíte admin heslo -- **DŮLEŽITÉ:** Toto není vaše UrNetwork heslo! -- Toto heslo používáte pro přihlášení do dashboardu - -### 2. Přidání UrNetwork Účtů -``` -Dashboard → Správa účtů → Přidat účet - -Vyplňte: - ✓ UrNetwork email (vlastik.novotny2005@gmail.com) - ✓ UrNetwork heslo - ✓ Přezdívka (např. "Domácí účet") -``` - -### 3. Zobrazení Dat -- **Veřejný pohled**: Kombinované statistiky všech účtů -- **Privátní dashboard**: Detailní grafy a správa -- **Správa účtů**: Přidávání/odebírání účtů - -## 🆘 Rychlá pomoc - -### Nemohu se přihlásit -```bash -# Zkontrolujte .env soubor -cat .env | grep ADMIN_PASSWORD - -# Pokud chybí, přidejte -echo "ADMIN_PASSWORD=your_password" >> .env -``` - -### Aplikace neběží -```bash -# Zkontrolujte logy -tail -f nohup.out - -# Nebo spusťte v popředí pro debugging -python3 main.py -``` - -### Port 90 je obsazený -```python -# V main.py změňte poslední řádek: -app.run(host="0.0.0.0", port=8080, debug=False) -# ^^^^ -# Změňte číslo portu -``` - -### Upgrade selhal -```bash -# Obnovte zálohu -cd ~ -rm -rf urio -mv urio_backup urio -cd urio -python3 main.py -``` - -## 📚 Detailní dokumentace - -- **README_CZ.md** - Kompletní feature list a použití -- **UPGRADE_GUIDE.md** - Detailní průvodce upgradem -- **GitHub Issues** - Pro reportování problémů - -## 🎨 Screenshots - -### Veřejný Dashboard -``` -┌─────────────────────────────────────────┐ -│ Celkem placených dat │ 45.234 GB │ -│ Celkem neplacených dat │ 12.456 GB │ -│ Aktivní účty │ 3 │ -│ Výdělky (30 dní) │ $125.67 │ -└─────────────────────────────────────────┘ - -Graf: Kombinovaná data ze všech účtů -Graf: Domácí účet -Graf: Pracovní účet -Graf: Server účet - -Mapa: Lokace poskytovatelů -``` - -### Správa Účtů -``` -┌──────────────────────────────────────────────┐ -│ Přezdívka │ Username │ Stav │ -├──────────────────────────────────────────────┤ -│ [Domácí účet] │ vlastik@... │ Aktivní │ -│ [Pracovní] │ work@... │ Aktivní │ -│ [Server] │ server@... │ Neaktivní│ -└──────────────────────────────────────────────┘ -``` - -## 🔥 Hlavní Nové Funkce - -✅ **Multi-Account** - Sledujte více UrNetwork účtů -✅ **Glassmorphism Design** - Moderní UI s blur efekty -✅ **Kombinované Stats** - Agregovaná data všech účtů -✅ **Individuální Grafy** - Graf pro každý účet zvlášť -✅ **Barevné Odlišení** - Každý účet má svou barvu -✅ **Admin Heslo** - Oddělené od UrNetwork credentials -✅ **Toggle Účtů** - Zapínání/vypínání sledování -✅ **Přezdívky** - Pojmenujte si účty jak chcete - -## 💡 Tipy - -### Pro více než 3 účty -- Snižte frekvenci fetchování v kódu (z 15 na 30 minut) -- Používejte přezdívky pro lepší přehled - -### Pro produkční nasazení -- Nastavte `FORCE_HTTPS=True` v .env -- Použijte Gunicorn místo development serveru -- Nastavte systemd service pro autostart - -### Webhooky -```json -{ - "content": "📊 **${account}**\n💾 Data: ${total_gb} GB\n🕐 ${update_time}" -} -``` - -## 📞 Kontakt & Podpora - -- Original project: techroy23/UrNetwork-Stats-Dashboard -- Enhanced by: Claude/Anthropic -- Issues & Questions: GitHub Issues - ---- - -**Enjoy! 🎉** - -Pro detaily viz README_CZ.md diff --git a/README_CZ.md b/README_CZ.md deleted file mode 100644 index 6aef3ce..0000000 --- a/README_CZ.md +++ /dev/null @@ -1,172 +0,0 @@ -# UrNetwork Stats Dashboard - Vylepšená Multi-Account Verze v2.1 - -🇨🇿 **Český README** | [🇬🇧 English README](README.md) - ---- - -## 🌟 Rychlé Odkazy - -- 🚀 [Rychlý Start](QUICKSTART.md) - Spusť za 5 minut -- 📊 [Návod na Webhooky](WEBHOOK_GUIDE.md) - Discord, Slack, Telegram příklady -- 🎨 [Porovnání Designů](DESIGN_COMPARISON.md) - Proč tento design? -- 🔄 [Průvodce Upgradem](UPGRADE_GUIDE.md) - Migrace z v1.0 -- 📝 [Changelog](CHANGELOG.md) - Historie verzí - ---- - -## O Projektu - -Toto je **výrazně vylepšená multi-account verze** původního [UrNetwork Stats Dashboard](https://github.com/techroy23/UrNetwork-Stats-Dashboard). Sleduj neomezený počet UrNetwork účtů s krásnými grafy, real-time aktualizacemi a webhook notifikacemi. - -**Co je nového ve v2.1:** -- 🎯 **Multi-Account Podpora** - Sleduj neomezený počet UrNetwork účtů -- 🎨 **Čistý Design** - Cloudflare-inspirovaný tmavý vzhled -- 📊 **Lepší Grafy** - Bílý text, tooltip kdekoliv na grafu -- 🔐 **Oddělená Auth** - Admin heslo nezávislé na UrNetwork -- ⚡ **Denní Čištění** - Auto-mazání dat starších 7 dní -- 📱 **Mobilní Optimalizace** - Touch-friendly rozhraní - -> **Vylepšeno AI:** v2.0+ vytvořeno s Claude (Anthropic) pro lepší UX, multi-account podporu a moderní design. - ---- - -## ✨ Klíčové Funkce - -### 🎯 Multi-Account Správa -- ✅ Sleduj neomezený počet UrNetwork účtů současně -- ✅ Kombinované statistiky ze všech účtů -- ✅ Individuální grafy pro každý účet -- ✅ Vlastní přezdívky pro snadnou identifikaci -- ✅ Zapni/vypni účty bez smazání -- ✅ Barevně odlišené pro snadné rozpoznání - -### 📊 Pokročilá Vizualizace -- ✅ Interaktivní Chart.js grafy s tooltipem **kdekoliv na grafu** -- ✅ Celková data, Placená vs Neplacená, Delta grafy -- ✅ Bílý čitelný text na všech grafech (konec mrákání!) -- ✅ Mapa světa ukazující lokace poskytovatelů -- ✅ Real-time aktualizace každou minutu - -### ⚙️ Automatizace -- ✅ Sběr dat každých 15 minut -- ✅ Denní čištění (ponechává posledních 7 dní) -- ✅ Webhook notifikace (Discord, Slack, Telegram) -- ✅ Správa zařízení napříč všemi účty - -### 🎨 Moderní UI -- ✅ Čistý Cloudflare-inspirovaný tmavý vzhled -- ✅ Bez gradientů (lepší viditelnost grafů) -- ✅ Modrá akcent barva (#3b82f6) -- ✅ Plně responzivní (mobil, tablet, desktop) -- ✅ Podpora češtiny a angličtiny - ---- - -## 🚀 Rychlý Start - -```bash -# 1. Klonovat repozitář -git clone https://forgejo.plainrock127.xyz/mxnticek/UrNetwork-Stats-Dashboard-remade -cd UrNetwork-Stats-Dashboard-remade - -# 2. Instalovat závislosti -pip install Flask Flask-SQLAlchemy Flask-APScheduler requests python-dateutil - -# 3. Spustit -python main.py - -# 4. Otevřít prohlížeč -# http://localhost:90 -``` - -**První Spuštění:** -1. Nastav své **admin heslo** (NENÍ to tvé UrNetwork heslo!) -2. Přidej své UrNetwork účty (email + heslo + přezdívka) -3. Hotovo! Dashboard začne sbírat data každých 15 minut - -📖 **Potřebuješ více detailů?** Viz [QUICKSTART.md](QUICKSTART.md) - ---- - -## 📊 Nastavení Webhooků - Rychlé Příklady - -### Discord - Jednoduchý -```json -{ - "content": "📊 **${account}**: ${total_gb} GB" -} -``` - -### Discord - Bohatý Embed (Doporučeno) -```json -{ - "username": "UrNetwork Bot", - "embeds": [{ - "title": "⚡ ${account} - Nová Data!", - "color": 3901635, - "fields": [ - {"name": "💰 Placená", "value": "`${paid_gb} GB`", "inline": true}, - {"name": "📡 Neplacená", "value": "`${unpaid_gb} GB`", "inline": true}, - {"name": "💾 Celkem", "value": "**${total_gb} GB**", "inline": false} - ], - "footer": {"text": "UrNetwork Stats"}, - "timestamp": "${update_time}" - }] -} -``` - -### Telegram -```json -{ - "chat_id": "TVOJE_CHAT_ID", - "text": "📊 *${account}*\n💾 Celkem: ${total_gb} GB\n💰 Placená: ${paid_gb} GB\n📡 Neplacená: ${unpaid_gb} GB", - "parse_mode": "Markdown" -} -``` - -**Dostupné Proměnné:** -- `${account}` - Přezdívka účtu -- `${paid_gb}` - Placená data v GB -- `${unpaid_gb}` - Neplacená data v GB -- `${total_gb}` - Celková data v GB -- `${update_time}` - Časová značka - -📖 **Kompletní webhook návod:** [WEBHOOK_GUIDE.md](WEBHOOK_GUIDE.md) - ---- - -## 🎨 Proč Tento Design? - -Po rozsáhlém testování jsme zvolili **čistý Cloudflare-inspirovaný design** protože: - -1. **Lepší Viditelnost Grafů** - Pevné tmavé pozadí = lepší kontrast -2. **Profesionální Vzhled** - Napodobuje enterprise dashboardy -3. **Bez Únav Očí** - Čisté barvy bez gradientů -4. **Výkon** - Žádné blur efekty = rychlejší rendering -5. **Přístupnost** - Vysoké kontrastní poměry - -**Barevné Schéma:** -```css -Pozadí: #0c0d0e (Tmavá) -Primární: #3b82f6 (Modrá) -Text: #e5e7eb (Světlá) -Úspěch: #10b981 (Zelená) -Chyba: #ef4444 (Červená) -``` - -📖 **Detaily designu:** [DESIGN_COMPARISON.md](DESIGN_COMPARISON.md) - ---- - -## 🙏 Poděkování - -- **Originál:** [techroy23/UrNetwork-Stats-Dashboard](https://github.com/techroy23/UrNetwork-Stats-Dashboard) -- **v2.0+ Vylepšeno:** Claude (Anthropic AI) -- **Design Inspirace:** Cloudflare, Vercel -- **Speciální Díky:** Vlastík (mxnticek) za testování - ---- - -**Verze:** v2.1.1 | **Poslední Aktualizace:** 21. listopadu 2024 - -**Vytvořeno s ❤️ a 🤖 AI** diff --git a/UPGRADE_GUIDE.md b/UPGRADE_GUIDE.md deleted file mode 100644 index 0296898..0000000 --- a/UPGRADE_GUIDE.md +++ /dev/null @@ -1,304 +0,0 @@ -# UrNetwork Stats Dashboard v2.0 - Upgrade Guide - -## 🎯 Hlavní Vylepšení - -### 1. Multi-Account Support ⭐ NOVÉ -**Před:** -- Sledování pouze jednoho UrNetwork účtu -- Nutnost manuálně měnit credentials v .env -- Žádná kombinovaná statistika - -**Po:** -``` -✓ Neomezený počet UrNetwork účtů -✓ Kombinovaná statistika ze všech účtů -✓ Individuální grafy pro každý účet -✓ Snadné přepínání mezi účty -✓ Přezdívky pro lepší orientaci -✓ Zapínání/vypínání sledování -``` - -### 2. Redesign UI 🎨 VYLEPŠENO - -**Design změny:** -```css -Před: Flat dark theme -Po: Glassmorphism + Gradients - -Barvy: - Před: Modrá (#3b82f6) - Po: Fialová gradient (#667eea → #764ba2) - -Efekty: - ✓ Blur backdrop filters - ✓ Smooth hover animations - ✓ Shadow depth effects - ✓ Gradient overlays - ✓ Animated transitions -``` - -### 3. Lepší Bezpečnost 🔐 VYLEPŠENO - -**Před:** -``` -- Přihlášení pomocí UrNetwork credentials -- Hesla v .env otevřeně -``` - -**Po:** -``` -✓ Oddělené admin heslo pro dashboard -✓ UrNetwork credentials bezpečně v databázi -✓ Session management -✓ HTTPS redirect podpora -``` - -### 4. Vylepšené Grafy 📊 ROZŠÍŘENO - -**Nové možnosti:** -- Kombinovaný graf (všechny účty dohromady) -- Individuální grafy pro každý účet -- Barevné odlišení účtů -- Přepínání mezi pohledy -- Lepší legenda a tooltips - -### 5. Správa Zařízení 📱 ROZŠÍŘENO - -**Před:** -``` -Device Name | Status | Client ID | Mode | Remove -``` - -**Po:** -``` -Account | Device Name | Status | Client ID | Mode | Remove - ↓ -Označení které zařízení patří kterému účtu -``` - -## 📊 Srovnání Funkcí - -| Funkce | v1.0 | v2.0 | -|--------|------|------| -| Počet účtů | 1 | Neomezeno | -| Design | Basic Dark | Glassmorphism | -| Grafy | Základní | Multi-account + Combined | -| Admin panel | UrNetwork login | Oddělené admin heslo | -| Webhooky | Základní | S account proměnnou | -| Správa účtů | Manuálně v .env | GUI správa | -| Toggle účtů | ❌ | ✅ | -| Přezdívky | ❌ | ✅ | -| Barevné odlišení | ❌ | ✅ | -| Kombinované stats | ❌ | ✅ | - -## 🚀 Upgrade Proces - -### Krok 1: Příprava -```bash -# 1. Zastavte běžící aplikaci -pkill -f main.py - -# 2. Přejděte do složky aplikace -cd ~/urio - -# 3. Stáhněte nové soubory -# (nebo je nahrajte manuálně) -``` - -### Krok 2: Migrace -```bash -# Spusťte migrační skript -python3 migrate.py -``` - -**Migrační skript automaticky:** -1. ✓ Vytvoří zálohy (.env.backup, transfer_stats.db.backup) -2. ✓ Aktualizuje strukturu databáze -3. ✓ Přidá tabulku accounts -4. ✓ Migruje existující účet -5. ✓ Nastaví admin heslo -6. ✓ Ověří migraci - -### Krok 3: Test -```bash -# Spusťte novou verzi -python3 main.py - -# Otevřete v prohlížeči -http://your-server:90 - -# Přihlaste se pomocím NOVÉHO admin hesla -``` - -### Krok 4: Přidání účtů -``` -1. Přihlaste se do dashboardu -2. Menu → Správa účtů -3. Klikněte "Přidat účet" -4. Vyplňte: - - UrNetwork email - - UrNetwork heslo - - Přezdívku (např. "Domácí", "Práce") -5. Účet se automaticky ověří -``` - -## 🔄 Rollback (pokud něco nejde) - -### Obnovení zálohy -```bash -# Zastavte aplikaci -pkill -f main.py - -# Obnovte zálohy -cp .env.backup .env -cp transfer_stats.db.backup transfer_stats.db -mv main.py.old main.py - -# Spusťte starou verzi -python3 main.py -``` - -## 📱 Použití Multi-Account - -### Přidání druhého účtu -``` -Příklad: Máte 2 UrNetwork účty - -Účet 1 (Existující): - Email: vlastik.novotny2005@gmail.com - → Automaticky migrován - → Přezdívka: "Hlavní účet" - -Účet 2 (Nový): - Email: druhy.ucet@gmail.com - Heslo: ******** - → Přidán přes GUI - → Přezdívka: "Pracovní účet" -``` - -### Zobrazení kombinovaných dat -``` -Veřejný dashboard: - → Zobrazí součet dat obou účtů - → Individual grafy pro každý účet - → Celkové výdělky ze všech účtů - -Privátní dashboard: - → Toggle: "Kombinovaná statistika" / "Jednotlivé účty" - → Filtr podle účtu v sekci Account & Leaderboard - → Zařízení označená účtem -``` - -## 🎨 CSS Customizace - -### Změna barevného schématu -V `main_enhanced.py`, změňte CSS proměnné: - -```css -:root { - /* Změňte tyto hodnoty pro vlastní barevné schéma */ - --primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - --success: #10b981; - --danger: #ef4444; -} -``` - -### Populární barevné schémata: - -**Modrá (Ocean):** -```css ---primary: linear-gradient(135deg, #667eea 0%, #00d4ff 100%); -``` - -**Zelená (Nature):** -```css ---primary: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); -``` - -**Oranžová (Sunset):** -```css ---primary: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); -``` - -## 🐛 Časté Problémy - -### Problém: "Nelze se přihlásit" -**Řešení:** -```bash -# Zkontrolujte ADMIN_PASSWORD v .env -cat .env | grep ADMIN_PASSWORD - -# Pokud chybí, přidejte ho -echo "ADMIN_PASSWORD=your_password" >> .env -``` - -### Problém: "Účet se nepřidává" -**Řešení:** -1. Zkontrolujte UrNetwork credentials -2. Zkuste se přihlásit na bringyour.com -3. Zkontrolujte logy: `tail -f nohup.out` - -### Problém: "Chybí data po migraci" -**Řešení:** -```bash -# Ověřte account_id ve stats tabulce -sqlite3 transfer_stats.db "SELECT COUNT(*) FROM stats WHERE account_id IS NULL;" - -# Pokud je > 0, přiřaďte manuálně -sqlite3 transfer_stats.db "UPDATE stats SET account_id = 1 WHERE account_id IS NULL;" -``` - -### Problém: "Webhook nefunguje" -**Řešení:** -``` -Starý formát: - {"content": "Data: ${total_gb} GB"} - -Nový formát: - {"content": "Account: ${account}, Data: ${total_gb} GB"} - ^^^^^^^^^^^ - Nová proměnná -``` - -## 📈 Performance Tips - -### Pro více než 5 účtů: -```python -# V main_enhanced.py, upravte job interval -@scheduler.task(id="log_stats_job", trigger="cron", minute="0,30") -# místo: minute="0,15,30,45" -# Tím snížíte frekvenci API callů -``` - -### Pro lepší responzivitu: -```bash -# Použijte Gunicorn místo development serveru -pip install gunicorn -gunicorn -w 4 -b 0.0.0.0:90 main_enhanced:app -``` - -## 🎯 Co Dělat Dál - -1. **Přidejte další účty** - - Menu → Správa účtů → Přidat účet - -2. **Nastavte webhooky** - - Menu → Nastavení → Webhook Management - - Použijte `${account}` pro rozlišení účtů - -3. **Customizujte design** - - Změňte CSS proměnné podle svých preferencí - -4. **Monitoring** - - Zkontrolujte logy pravidelně - - Nastavte alerting přes webhooky - -## 📞 Podpora - -- **GitHub Issues**: Pro bug reporty a feature requesty -- **Documentation**: README_CZ.md pro detailní dokumentaci -- **Migration Help**: migrate.py --help pro nápovědu - ---- - -**Enjoy your new multi-account dashboard! 🚀** diff --git a/WEBHOOK_GUIDE.md b/WEBHOOK_GUIDE.md deleted file mode 100644 index 2eda464..0000000 --- a/WEBHOOK_GUIDE.md +++ /dev/null @@ -1,391 +0,0 @@ -# 🔔 Webhook Průvodce - UrNetwork Stats Dashboard - -## 📋 Dostupné Proměnné - -Když webhook systém posílá notifikace, máš k dispozici tyto proměnné: - -| Proměnná | Popis | Příklad | Formát | -|----------|-------|---------|--------| -| `${account}` | Přezdívka účtu | "Hlavní účet" | Text | -| `${paid_gb}` | Placená data v GB | "123.456" | 3 des. místa | -| `${unpaid_gb}` | Neplacená data v GB | "45.678" | 3 des. místa | -| `${total_gb}` | Celková data v GB | "169.134" | 3 des. místa | -| `${update_time}` | Čas aktualizace | "2024-11-21 12:30:45" | YYYY-MM-DD HH:MM:SS | - -## 🎯 Kdy Se Webhooky Spouštějí? - -- **Každých 15 minut** - Když scheduler načte nová data -- **Pro každý aktivní účet** zvlášť -- Pouze pokud se načtení dat povede - ---- - -## 🔥 Příklady Pro Tebe (Vlastík) - -### 1. Discord - Jednoduchá Notifikace 💬 - -```json -{ - "content": "📊 **${account}** aktualizace!\n💾 Celkem: **${total_gb} GB**\n💰 Placená: ${paid_gb} GB | 📡 Neplacená: ${unpaid_gb} GB\n🕐 ${update_time}" -} -``` - -**Výstup:** -``` -📊 **Hlavní účet** aktualizace! -💾 Celkem: **169.134 GB** -💰 Placená: 123.456 GB | 📡 Neplacená: 45.678 GB -🕐 2024-11-21 12:30:45 -``` - ---- - -### 2. Discord - Bohatý Embed (Český) 🇨🇿 - -```json -{ - "embeds": [{ - "title": "📊 UrNetwork - ${account}", - "description": "Nová data byla načtena!", - "color": 3901635, - "fields": [ - { - "name": "💰 Placená Data", - "value": "${paid_gb} GB", - "inline": true - }, - { - "name": "📡 Neplacená Data", - "value": "${unpaid_gb} GB", - "inline": true - }, - { - "name": "💾 Celkem Poskytnutých Dat", - "value": "**${total_gb} GB**", - "inline": false - } - ], - "footer": { - "text": "Aktualizováno" - }, - "timestamp": "${update_time}" - }] -} -``` - ---- - -### 3. Discord - Minimalistický 🎯 - -```json -{ - "content": "⚡ ${account}: **${total_gb} GB** (${paid_gb} / ${unpaid_gb})" -} -``` - -**Výstup:** -``` -⚡ Hlavní účet: **169.134 GB** (123.456 / 45.678) -``` - ---- - -### 4. Discord - S Progress Barem 📊 - -```json -{ - "embeds": [{ - "title": "⚡ ${account} Stats", - "color": 3447003, - "description": "**Celkem: ${total_gb} GB**\n\n💰 Placená: `${paid_gb} GB`\n📡 Neplacená: `${unpaid_gb} GB`", - "footer": { - "text": "${update_time}" - } - }] -} -``` - ---- - -### 5. Slack - Jednoduchá Zpráva 💼 - -```json -{ - "text": ":bar_chart: *${account}* - Aktualizace\nCelkem: *${total_gb} GB* | Placená: ${paid_gb} GB | Neplacená: ${unpaid_gb} GB\n_${update_time}_" -} -``` - ---- - -### 6. Slack - Formátovaná Zpráva 💼 - -```json -{ - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "📊 UrNetwork Stats - ${account}" - } - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Placená Data:*\n${paid_gb} GB" - }, - { - "type": "mrkdwn", - "text": "*Neplacená Data:*\n${unpaid_gb} GB" - }, - { - "type": "mrkdwn", - "text": "*Celkem:*\n${total_gb} GB" - }, - { - "type": "mrkdwn", - "text": "*Čas:*\n${update_time}" - } - ] - } - ] -} -``` - ---- - -### 7. Telegram - Markdown 📱 - -```json -{ - "chat_id": "YOUR_CHAT_ID", - "text": "📊 *${account}* - Aktualizace\n\n💾 *Celkem:* ${total_gb} GB\n💰 Placená: ${paid_gb} GB\n📡 Neplacená: ${unpaid_gb} GB\n\n🕐 _${update_time}_", - "parse_mode": "Markdown" -} -``` - ---- - -### 8. MS Teams - Jednoduchá Karta 🏢 - -```json -{ - "@type": "MessageCard", - "@context": "https://schema.org/extensions", - "summary": "${account} Stats Update", - "themeColor": "0078D7", - "title": "📊 ${account} - UrNetwork Stats", - "sections": [{ - "facts": [ - { - "name": "Placená Data:", - "value": "${paid_gb} GB" - }, - { - "name": "Neplacená Data:", - "value": "${unpaid_gb} GB" - }, - { - "name": "Celkem:", - "value": "${total_gb} GB" - } - ], - "text": "Aktualizováno: ${update_time}" - }] -} -``` - ---- - -### 9. Generic JSON (pro vlastní API) 🔧 - -```json -{ - "event": "urnetwork_update", - "account_name": "${account}", - "data": { - "paid_gb": "${paid_gb}", - "unpaid_gb": "${unpaid_gb}", - "total_gb": "${total_gb}" - }, - "timestamp": "${update_time}" -} -``` - ---- - -### 10. IFTTT Webhook 🔗 - -```json -{ - "value1": "${account}", - "value2": "${total_gb} GB", - "value3": "Placená: ${paid_gb} GB, Neplacená: ${unpaid_gb} GB" -} -``` - ---- - -## 🎨 Doporučené Pro Tebe - -Protože máš UrNetwork setup a pravděpodobně používáš Discord/Telegram, doporučuji: - -### ⭐ Nejlepší Volba - Discord Embed (Český) - -```json -{ - "username": "UrNetwork Bot", - "avatar_url": "https://cdn-icons-png.flaticon.com/512/2920/2920277.png", - "embeds": [{ - "title": "⚡ ${account} - Nová Data!", - "color": 3901635, - "fields": [ - { - "name": "💰 Placená Data", - "value": "`${paid_gb} GB`", - "inline": true - }, - { - "name": "📡 Neplacená Data", - "value": "`${unpaid_gb} GB`", - "inline": true - }, - { - "name": "💾 Celkem", - "value": "**${total_gb} GB**", - "inline": false - } - ], - "footer": { - "text": "UrNetwork Stats Dashboard" - }, - "timestamp": "${update_time}" - }] -} -``` - -### 🚀 Rychlá Varianta - Pro Mobil - -```json -{ - "content": "⚡ **${account}**: ${total_gb} GB\n💰 ${paid_gb} | 📡 ${unpaid_gb}" -} -``` - ---- - -## 📝 Jak Přidat Webhook - -### 1. Discord Webhook URL -``` -1. Jdi do Discord serveru -2. Server Settings → Integrations → Webhooks -3. New Webhook -4. Zkopíruj Webhook URL -5. Vlož do dashboardu v Settings → Webhook Management -``` - -### 2. V Dashboardu -``` -1. Přihlaš se do dashboardu -2. Menu → Settings (Nastavení) -3. Webhook Management -4. Vlož URL: https://discord.com/api/webhooks/... -5. Vlož JSON payload (výše) -6. Přidat Webhook -``` - ---- - -## 🧪 Test Webhooku - -Chceš otestovat, jestli webhook funguje? Spusť manuální fetch: - -```bash -# V dashboardu klikni "Fetch Now" -# nebo z příkazové řádky: -curl -X POST http://localhost:90/trigger -``` - ---- - -## 🔍 Debug - -### Pokud webhook nefunguje: - -1. **Zkontroluj logy:** -```bash -tail -f nohup.out | grep webhook -``` - -2. **Zkontroluj JSON syntax:** -```bash -# Použij online JSON validator -# https://jsonlint.com/ -``` - -3. **Test Discord webhooku:** -```bash -curl -X POST "YOUR_WEBHOOK_URL" \ - -H "Content-Type: application/json" \ - -d '{"content": "Test message"}' -``` - ---- - -## 💡 Pro Tipy - -### Více Webhooků -Můžeš přidat více webhooků - každý dostane notifikaci! -- Discord server 1 -- Discord server 2 -- Slack workspace -- Telegram bot - -### Filtrování Podle Účtu -Chceš notifikace jen pro specifický účet? - -V payloadu použij podmínku (pokud tvůj webhook systém podporuje): -```json -{ - "content": "${account} update: ${total_gb} GB" -} -``` - -A vytvoř samostatný webhook jen když je `${account}` = "Hlavní účet" - -### Rate Limiting -Pozor! Většina služeb má rate limit: -- Discord: 5 zpráv / 2 sekundy per webhook -- Slack: 1 zpráva / sekunda - -Dashboard posílá notifikace každých 15 minut, takže jsi v pohodě! ✅ - ---- - -## 🎯 Tvoje Setup (Doporučení) - -Protože máš pravděpodobně několik účtů, doporučuji: - -```json -{ - "embeds": [{ - "title": "📊 ${account}", - "description": "**${total_gb} GB** poskytnutých dat", - "color": 3901635, - "fields": [ - {"name": "💰 Placená", "value": "${paid_gb} GB", "inline": true}, - {"name": "📡 Neplacená", "value": "${unpaid_gb} GB", "inline": true} - ], - "footer": {"text": "${update_time}"} - }] -} -``` - -Takto dostaneš **jednu zprávu každých 15 minut pro každý účet** s přehledným rozdělením! 🎉 - ---- - -**Potřebuješ pomoct s nastavením? Dej vědět! 🚀** diff --git a/fix_db_path.py b/fix_db_path.py deleted file mode 100644 index 80f2c13..0000000 --- a/fix_db_path.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 -""" -Quick fix script for database path issue -Fixes the main.py file to use absolute paths -""" - -import os -import sys - -def fix_main_py(): - """Fix main.py to use absolute database path""" - - main_file = 'main.py' - - if not os.path.exists(main_file): - print("❌ main.py not found in current directory") - print(" Run this script from the urio folder") - sys.exit(1) - - print("🔧 Fixing database path in main.py...") - - # Read the file - with open(main_file, 'r') as f: - content = f.read() - - # Check if already fixed - if 'BASE_DIR = os.path.abspath(os.path.dirname(__file__))' in content: - print("✅ main.py is already fixed!") - return - - # Fix 1: Update Config class - old_config = '''class Config: - """Flask configuration.""" - SCHEDULER_API_ENABLED = True - SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", "sqlite:///instance/transfer_stats.db")''' - - new_config = '''class Config: - """Flask configuration.""" - SCHEDULER_API_ENABLED = True - # Use absolute path for database - BASE_DIR = os.path.abspath(os.path.dirname(__file__)) - INSTANCE_DIR = os.path.join(BASE_DIR, 'instance') - SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", f"sqlite:///{os.path.join(INSTANCE_DIR, 'transfer_stats.db')}")''' - - if old_config in content: - content = content.replace(old_config, new_config) - print("✅ Updated Config class with absolute paths") - - # Fix 2: Ensure instance folder creation happens before app init - old_init = '''# --- Flask App Initialization --- - -app = Flask(__name__) -app.config.from_object(Config) - -# Ensure instance folder exists -instance_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'instance') -if not os.path.exists(instance_path): - os.makedirs(instance_path)''' - - new_init = '''# --- Flask App Initialization --- - -# Ensure instance folder exists BEFORE creating the app -instance_path = Config.INSTANCE_DIR -if not os.path.exists(instance_path): - os.makedirs(instance_path) - logging.info(f"Created instance directory: {instance_path}") - -app = Flask(__name__) -app.config.from_object(Config)''' - - if old_init in content: - content = content.replace(old_init, new_init) - print("✅ Updated instance folder creation") - - # Write the fixed content - with open(main_file, 'w') as f: - f.write(content) - - print("\n✅ main.py has been fixed!") - print("\nYou can now run:") - print(" python3 main.py") - -if __name__ == '__main__': - print(""" -╔════════════════════════════════════════════════════════════╗ -║ UrNetwork Stats Dashboard - Database Path Fix ║ -╚════════════════════════════════════════════════════════════╝ - """) - - try: - fix_main_py() - except Exception as e: - print(f"\n❌ Error: {e}") - sys.exit(1) diff --git a/install.sh b/install.sh deleted file mode 100644 index 61650eb..0000000 --- a/install.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/bash - -# UrNetwork Stats Dashboard - Installation Script v2.1 -# This script automates the installation process - -set -e # Exit on error - -echo "=========================================" -echo "UrNetwork Stats Dashboard v2.1" -echo "Installation Script" -echo "=========================================" -echo "" - -# Check Python version -echo "[1/6] Checking Python version..." -if ! command -v python3 &> /dev/null; then - echo "❌ Python 3 is not installed!" - echo "Please install Python 3.8+ and try again." - exit 1 -fi - -PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') -echo "✅ Python $PYTHON_VERSION found" -echo "" - -# Check pip -echo "[2/6] Checking pip..." -if ! command -v pip3 &> /dev/null; then - echo "❌ pip3 is not installed!" - echo "Please install pip3 and try again." - exit 1 -fi -echo "✅ pip3 found" -echo "" - -# Install dependencies -echo "[3/6] Installing dependencies..." -echo "This may take a few minutes..." -pip3 install -r requirements.txt -echo "✅ Dependencies installed" -echo "" - -# Create necessary directories -echo "[4/6] Creating directories..." -mkdir -p instance -echo "✅ Directories created" -echo "" - -# Check if already installed -echo "[5/6] Checking existing installation..." -if [ -f ".env" ]; then - echo "⚠️ Found existing .env file" - read -p "Do you want to keep it? (y/n): " keep_env - if [ "$keep_env" != "y" ]; then - mv .env .env.backup - echo "✅ Backed up to .env.backup" - else - echo "✅ Keeping existing configuration" - fi -fi - -if [ -f "instance/transfer_stats.db" ]; then - echo "⚠️ Found existing database" - read -p "Do you want to keep it? (y/n): " keep_db - if [ "$keep_db" != "y" ]; then - mv instance/transfer_stats.db instance/transfer_stats.db.backup - echo "✅ Backed up to transfer_stats.db.backup" - else - echo "✅ Keeping existing database" - fi -fi -echo "" - -# Final instructions -echo "[6/6] Installation complete!" -echo "" -echo "=========================================" -echo "🎉 Ready to start!" -echo "=========================================" -echo "" -echo "To run the dashboard:" -echo " python3 main.py" -echo "" -echo "Then open your browser to:" -echo " http://localhost:90" -echo "" -echo "On first run, you will:" -echo " 1. Set your admin password" -echo " 2. Add your UrNetwork accounts" -echo "" -echo "For production deployment with Gunicorn:" -echo " gunicorn --bind 0.0.0.0:90 --workers 4 main:app" -echo "" -echo "For systemd service setup, see README.md" -echo "" -echo "📖 Documentation:" -echo " - README.md - Full documentation" -echo " - QUICKSTART.md - Quick start guide" -echo " - WEBHOOK_GUIDE.md - Webhook examples" -echo "" -echo "Need help? Check the docs or create an issue!" -echo "=========================================" diff --git a/main_clean.py b/main_clean.py deleted file mode 100644 index e2de183..0000000 --- a/main_clean.py +++ /dev/null @@ -1,2221 +0,0 @@ -# ---------------------------------------- -# UrNetwork Stats Dashboard - Enhanced Multi-Account Edition -# ---------------------------------------- -# Enhanced with modern design, multi-account support, and combined statistics -# ---------------------------------------- - -import os -import time -import datetime -import requests -import logging -import json -from functools import wraps -from flask import ( - Flask, request, render_template_string, - redirect, url_for, flash, session, g, jsonify -) -from flask_sqlalchemy import SQLAlchemy -from flask_apscheduler import APScheduler -from dateutil.parser import isoparse -import secrets -from string import Template - -# --- Application Setup & Configuration --- - -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') - -ENV_FILE = ".env" - -def load_env(): - """Load environment variables from .env file.""" - if os.path.exists(ENV_FILE): - with open(ENV_FILE, 'r') as f: - for line in f: - if '=' in line and not line.strip().startswith('#'): - key, value = line.strip().split('=', 1) - os.environ[key] = value - -load_env() - -class Config: - """Flask configuration.""" - SCHEDULER_API_ENABLED = True - # Use absolute path for database - BASE_DIR = os.path.abspath(os.path.dirname(__file__)) - INSTANCE_DIR = os.path.join(BASE_DIR, 'instance') - SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", f"sqlite:///{os.path.join(INSTANCE_DIR, 'transfer_stats.db')}") - SQLALCHEMY_TRACK_MODIFICATIONS = False - SECRET_KEY = os.getenv("SECRET_KEY", "default-secret-key-for-initial-setup") - UR_API_BASE = "https://api.bringyour.com" - FORCE_HTTPS = os.getenv("FORCE_HTTPS", "False").lower() in ('true', '1', 't') - ENABLE_ACCOUNT_STATS = os.getenv("ENABLE_ACCOUNT_STATS", "True").lower() in ('true', '1', 't') - ENABLE_LEADERBOARD = os.getenv("ENABLE_LEADERBOARD", "True").lower() in ('true', '1', 't') - ENABLE_DEVICE_STATS = os.getenv("ENABLE_DEVICE_STATS", "True").lower() in ('true', '1', 't') - -# --- Flask App Initialization --- - -# Ensure instance folder exists BEFORE creating the app -instance_path = Config.INSTANCE_DIR -if not os.path.exists(instance_path): - os.makedirs(instance_path) - logging.info(f"Created instance directory: {instance_path}") - -app = Flask(__name__) -app.config.from_object(Config) - -db = SQLAlchemy(app) -scheduler = APScheduler() -scheduler.init_app(app) - -# --- Database Models --- - -class Account(db.Model): - """Represents a UrNetwork account.""" - __tablename__ = 'accounts' - id = db.Column(db.Integer, primary_key=True) - username = db.Column(db.String(100), unique=True, nullable=False) - password = db.Column(db.String(200), nullable=False) - nickname = db.Column(db.String(100), nullable=True) - is_active = db.Column(db.Boolean, default=True) - created_at = db.Column(db.DateTime, server_default=db.func.now()) - -class Stats(db.Model): - """Represents a snapshot of paid vs unpaid bytes at a given timestamp.""" - __tablename__ = 'stats' - id = db.Column(db.Integer, primary_key=True) - account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'), nullable=False) - timestamp = db.Column(db.DateTime, server_default=db.func.now()) - paid_bytes = db.Column(db.BigInteger, nullable=False) - paid_gb = db.Column(db.Float, nullable=False) - unpaid_bytes = db.Column(db.BigInteger, nullable=False) - unpaid_gb = db.Column(db.Float, nullable=False) - account = db.relationship('Account', backref='stats') - -class Webhook(db.Model): - """Represents a webhook URL with an optional custom payload.""" - __tablename__ = 'webhook' - id = db.Column(db.Integer, primary_key=True) - url = db.Column(db.String, unique=True, nullable=False) - payload = db.Column(db.Text, nullable=True) - -class Setting(db.Model): - """Represents a key-value setting for the application.""" - __tablename__ = 'settings' - key = db.Column(db.String(50), primary_key=True) - value = db.Column(db.String(100), nullable=False) - -# --- Helper Functions --- - -def get_setting(key, default=None): - """Gets a setting value from the database.""" - setting = Setting.query.get(key) - return setting.value if setting else default - -def get_boolean_setting(key): - """Gets a boolean setting from the database.""" - value = get_setting(key, 'False') - return value.lower() in ('true', '1', 't') - -def is_installed(): - """Check if the application has been configured.""" - return os.getenv("SECRET_KEY") and os.getenv("SECRET_KEY") != "default-secret-key-for-initial-setup" - -def save_env_file(config_data): - """Save configuration data to the .env file.""" - try: - existing_env = {} - if os.path.exists(ENV_FILE): - with open(ENV_FILE, 'r') as f: - for line in f: - if '=' in line and not line.strip().startswith('#'): - key, value = line.strip().split('=', 1) - existing_env[key] = value - - existing_env.update(config_data) - - with open(ENV_FILE, "w") as f: - for key, value in existing_env.items(): - f.write(f"{key}={value}\n") - if "ENABLE_ACCOUNT_STATS" not in existing_env: - f.write("\n# Feature Flags\n") - f.write("ENABLE_ACCOUNT_STATS=True\n") - f.write("ENABLE_LEADERBOARD=True\n") - f.write("ENABLE_DEVICE_STATS=True\n") - if "FORCE_HTTPS" not in existing_env: - f.write("\n# Security Settings\n") - f.write("FORCE_HTTPS=False\n") - load_env() - return True - except IOError as e: - logging.error(f"Failed to write to .env file: {e}") - return False - -def request_with_retry(method, url, retries=3, backoff=5, timeout=30, **kwargs): - """Issue an HTTP request with retries.""" - last_exc = None - for attempt in range(1, retries + 1): - try: - resp = requests.request(method, url, timeout=timeout, **kwargs) - resp.raise_for_status() - return resp - except requests.exceptions.RequestException as e: - last_exc = e - logging.warning(f"[{method.upper()} {url}] attempt {attempt}/{retries} failed: {e}") - if attempt < retries: - time.sleep(backoff) - logging.error(f"All {retries} attempts to {method.upper()} {url} failed: {last_exc}") - return None - -def get_jwt_from_credentials(user, password): - """Fetch a new JWT token using username and password.""" - try: - resp = request_with_retry( - "post", - f"{app.config['UR_API_BASE']}/auth/login-with-password", - headers={"Content-Type": "application/json"}, - json={"user_auth": user, "password": password}, - ) - if not resp: - raise RuntimeError("API request failed after multiple retries.") - data = resp.json() - token = data.get("network", {}).get("by_jwt") - if not token: - err = data.get("message") or data.get("error") or str(data) - raise RuntimeError(f"Login failed: {err}") - return token - except Exception as e: - logging.error(f"Could not get JWT from credentials: {e}") - return None - -def get_valid_jwt(account): - """Gets a valid JWT for API calls for a specific account.""" - if not account: - return None - return get_jwt_from_credentials(account.username, account.password) - -# --- API Fetch Functions --- - -def fetch_transfer_stats(jwt_token): - """Retrieve transfer statistics using the provided JWT.""" - if not jwt_token: return None - resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/transfer/stats", headers={"Authorization": f"Bearer {jwt_token}"}) - if not resp: return None - data = resp.json() - paid = data.get("paid_bytes_provided", 0) - unpaid = data.get("unpaid_bytes_provided", 0) - return { - "paid_bytes": paid, - "paid_gb": paid / 1e9, - "unpaid_bytes": unpaid, - "unpaid_gb": unpaid / 1e9 - } - -def fetch_payment_stats(jwt_token): - """Retrieve account payment statistics using the provided JWT.""" - if not jwt_token: return [] - resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/account/payments", headers={"Authorization": f"Bearer {jwt_token}"}) - if not resp: return [] - return resp.json().get("account_payments", []) - -def fetch_account_details(jwt_token): - """Fetches various account details like points and referrals.""" - if not jwt_token: return {} - headers = {"Authorization": f"Bearer {jwt_token}"} - details = {} - - points_resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/account/points", headers=headers) - if points_resp: - points_data = points_resp.json().get("network_points", []) - details['points'] = sum(p.get('point_value', 0) for p in points_data) - - referral_resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/account/referral-code", headers=headers) - if referral_resp: - details['referrals'] = referral_resp.json() - - ranking_resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/network/ranking", headers=headers) - if ranking_resp: - details['ranking'] = ranking_resp.json().get('network_ranking', {}) - - return details - -def fetch_leaderboard(jwt_token): - """Fetches the global leaderboard.""" - if not jwt_token: return [] - headers = {"Authorization": f"Bearer {jwt_token}"} - resp = request_with_retry("post", f"{app.config['UR_API_BASE']}/stats/leaderboard", headers=headers, json={}) - if not resp: return [] - return resp.json().get("earners", []) - -def fetch_devices(jwt_token): - """Fetches the status of all network clients/devices.""" - if not jwt_token: return [] - headers = {"Authorization": f"Bearer {jwt_token}"} - resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/network/clients", headers=headers) - if not resp: return [] - devices = resp.json().get("clients", []) - provide_mode_map = {-1: "Default", 0: "None", 1: "Network", 2: "Friends & Family", 3: "Public", 4: "Stream"} - for device in devices: - device['provide_mode_str'] = provide_mode_map.get(device.get('provide_mode'), 'Unknown') - return devices - -def remove_device(jwt_token, client_id): - """Removes a device from the network.""" - if not jwt_token: return False, "Authentication token not available." - headers = {"Authorization": f"Bearer {jwt_token}"} - payload = {"client_id": client_id} - resp = request_with_retry("post", f"{app.config['UR_API_BASE']}/network/remove-client", headers=headers, json=payload) - if resp and resp.status_code == 200: - data = resp.json() - if data.get("error"): - return False, data["error"].get("message", "An unknown error occurred.") - return True, "Device removed successfully." - elif resp: - return False, f"API returned status {resp.status_code}." - else: - return False, "Failed to communicate with API." - -def calculate_earnings(payments): - """Calculate total and monthly earnings from a list of payments.""" - total_earnings = 0 - monthly_earnings = 0 - now = datetime.datetime.now(datetime.timezone.utc) - one_month_ago = now - datetime.timedelta(days=30) - - if not payments: - return 0, 0 - - for payment in payments: - if payment.get("completed"): - amount = payment.get("token_amount", 0) - total_earnings += amount - payment_time_str = payment.get("payment_time") - if payment_time_str: - try: - payment_time = isoparse(payment_time_str) - if payment_time > one_month_ago: - monthly_earnings += amount - except (ValueError, TypeError): - logging.warning(f"Could not parse payment_time: {payment_time_str}") - - return total_earnings, monthly_earnings - -def fetch_provider_locations(): - """Retrieve provider locations from the public API.""" - resp = request_with_retry("get", f"{app.config['UR_API_BASE']}/network/provider-locations") - return resp.json() if resp else None - -def send_webhook_notification(stats_data, account_nickname=None): - """Sends a notification to all configured webhooks.""" - with app.app_context(): - webhooks = Webhook.query.all() - if not webhooks: - return - - for webhook in webhooks: - payload_to_send = None - try: - if webhook.payload: - template = Template(webhook.payload) - payload_str = template.safe_substitute( - account=account_nickname or "Unknown", - paid_gb=f"{stats_data['paid_gb']:.3f}", - unpaid_gb=f"{stats_data['unpaid_gb']:.3f}", - total_gb=f"{(stats_data['paid_gb'] + stats_data['unpaid_gb']):.3f}", - update_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - ) - payload_to_send = json.loads(payload_str) - else: - payload_to_send = { - "embeds": [{ - "title": f"UrNetwork Stats Update - {account_nickname or 'Account'}", - "description": "New data has been synced from the UrNetwork API.", - "color": 5814783, - "fields": [ - {"name": "Account", "value": account_nickname or "Unknown", "inline": False}, - {"name": "Total Paid Data", "value": f"{stats_data['paid_gb']:.3f} GB", "inline": True}, - {"name": "Total Unpaid Data", "value": f"{stats_data['unpaid_gb']:.3f} GB", "inline": True}, - {"name": "Total Data Provided", "value": f"{(stats_data['paid_gb'] + stats_data['unpaid_gb']):.3f} GB", "inline": True}, - ], - "footer": {"text": f"Update Time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"} - }] - } - - requests.post(webhook.url, json=payload_to_send, timeout=10) - logging.info(f"Sent webhook notification to {webhook.url}") - except (json.JSONDecodeError, TypeError) as e: - logging.error(f"Failed to parse or substitute custom payload for webhook {webhook.url}: {e}") - except requests.exceptions.RequestException as e: - logging.error(f"Failed to send webhook to {webhook.url}: {e}") - -# --- Authentication Decorator --- -def login_required(f): - """Decorator to ensure a user is logged in.""" - @wraps(f) - def decorated_function(*args, **kwargs): - if not session.get('logged_in'): - flash(g.t['error_login_required'], "error") - next_url = request.url - if app.config['FORCE_HTTPS']: - next_url = next_url.replace('http://', 'https://', 1) - return redirect(url_for('login', next=next_url)) - return f(*args, **kwargs) - return decorated_function - -# --- Scheduled Jobs --- - -@scheduler.task(id="log_stats_job", trigger="cron", minute="0,15,30,45") -def log_stats_job(): - """Scheduled job to fetch and store stats every 15 minutes for all active accounts.""" - with app.app_context(): - if not is_installed(): - logging.warning("log_stats_job skipped: Application is not installed.") - return - - logging.info("Running scheduled stats fetch for all accounts...") - accounts = Account.query.filter_by(is_active=True).all() - - for account in accounts: - try: - jwt = get_valid_jwt(account) - if not jwt: - logging.warning(f"Could not authenticate account {account.username}") - continue - - stats_data = fetch_transfer_stats(jwt) - if not stats_data: - logging.warning(f"Could not fetch stats for account {account.username}") - continue - - entry = Stats( - account_id=account.id, - paid_bytes=stats_data["paid_bytes"], - paid_gb=stats_data["paid_gb"], - unpaid_bytes=stats_data["unpaid_bytes"], - unpaid_gb=stats_data["unpaid_gb"] - ) - db.session.add(entry) - db.session.commit() - logging.info(f"Logged stats for account {account.nickname or account.username} at {entry.timestamp}") - send_webhook_notification(stats_data, account.nickname or account.username) - except Exception as e: - logging.error(f"Failed to fetch stats for account {account.username}: {e}") - -@scheduler.task(id="cleanup_old_stats_job", trigger="cron", hour="3", minute="0") -def cleanup_old_stats_job(): - """Scheduled job to delete stats data older than 7 days, runs daily at 3 AM.""" - with app.app_context(): - if not is_installed(): - logging.warning("cleanup_old_stats_job skipped: Application is not installed.") - return - - logging.info("Running daily stats cleanup job...") - try: - cutoff_date = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=7) - num_rows_deleted = db.session.query(Stats).filter(Stats.timestamp < cutoff_date).delete(synchronize_session=False) - db.session.commit() - - if num_rows_deleted > 0: - logging.info(f"Successfully deleted {num_rows_deleted} stats records older than 7 days.") - else: - logging.info("No old stats records found to delete.") - except Exception as e: - logging.error(f"Scheduled job 'cleanup_old_stats_job' failed: {e}") - db.session.rollback() - -# --- Internationalization (i18n) --- - -TEXTS = { - 'cs': { - 'nav_public': 'Veřejný pohled', - 'nav_owner_dashboard': 'Panel vlastníka', - 'nav_overview': 'Přehled', - 'nav_account': 'Účet & Žebříček', - 'nav_devices': 'Zařízení', - 'nav_settings': 'Nastavení', - 'nav_accounts': 'Správa účtů', - 'nav_login': 'Přihlásit se', - 'nav_logout': 'Odhlásit se', - 'title_public_dashboard': 'Veřejný panel', - 'title_owner_dashboard': 'Panel vlastníka', - 'title_account_page': 'Účet & Žebříček', - 'title_devices_page': 'Správa zařízení', - 'title_settings': 'Nastavení', - 'title_accounts_page': 'Správa účtů', - 'title_login': 'Přihlásit se', - 'title_setup': 'Počáteční nastavení', - 'card_paid_data': 'Celkem placených dat', - 'card_unpaid_data': 'Celkem neplacených dat', - 'card_earnings_30d': 'Výdělky (30 dní)', - 'card_total_earnings': 'Celkové výdělky', - 'card_last_update': 'Poslední aktualizace', - 'card_account_points': 'Body účtu', - 'card_your_rank': 'Vaše pozice', - 'card_total_referrals': 'Celkem doporučení', - 'card_active_accounts': 'Aktivní účty', - 'card_total_devices': 'Celkem zařízení', - 'chart_total_data_gb': 'Celková poskytnutá data (GB)', - 'chart_paid_vs_unpaid': 'Placená vs. neplacená data (GB)', - 'chart_delta': 'Změna dat za interval (GB)', - 'chart_paid': 'Placená (GB)', - 'chart_unpaid': 'Neplacená (GB)', - 'chart_no_data': 'Nedostatek dat pro zobrazení grafu.', - 'history_title': 'Detailní historie', - 'history_timestamp': 'Časová značka', - 'history_change': 'Změna (GB)', - 'btn_fetch_now': 'Načíst nyní', - 'btn_clear_data': 'Vymazat všechna data', - 'btn_add_account': 'Přidat účet', - 'confirm_clear_data': 'Jste si jisti? Tímto smažete všechna historická data statistik.', - 'next_fetch': 'Další automatické načtení:', - 'login_header': 'Přihlaste se do svého panelu', - 'login_username': 'Administrátorské heslo', - 'login_password': 'Heslo', - 'login_button': 'Přihlásit se', - 'error_login_required': 'Pro zobrazení této stránky se musíte přihlásit.', - 'error_invalid_credentials': 'Neplatné heslo.', - 'flash_logged_in': 'Byli jste úspěšně přihlášeni.', - 'flash_logged_out': 'Byli jste odhlášeni.', - 'flash_settings_saved': 'Nastavení bylo úspěšně uloženo.', - 'flash_fetch_success': 'Nejnovější statistiky byly úspěšně načteny a uloženy.', - 'flash_fetch_fail': 'Nepodařilo se načíst statistiky: ', - 'flash_clear_success': 'Úspěšně smazáno {count} záznamů z databáze.', - 'flash_clear_fail': 'Při mazání databáze došlo k chybě.', - 'flash_account_added': 'Účet byl úspěšně přidán.', - 'flash_account_removed': 'Účet byl úspěšně odstraněn.', - 'flash_account_updated': 'Účet byl úspěšně aktualizován.', - 'webhook_title': 'Správa webhooků', - 'webhook_desc': 'Přidejte webhooky pro zasílání oznámení.', - 'webhook_url_label': 'URL adresa webhooku', - 'webhook_payload_label': 'Vlastní JSON Payload (volitelné)', - 'webhook_payload_placeholder': 'Např.: {"content": "Účet: ${account}, Data: ${total_gb} GB"}', - 'webhook_add_btn': 'Přidat Webhook', - 'webhook_current': 'Aktuální Webhooky', - 'webhook_delete_btn': 'Smazat', - 'webhook_flash_added': 'Webhook úspěšně přidán.', - 'webhook_flash_deleted': 'Webhook úspěšně smazán.', - 'webhook_flash_invalid_url': 'Je vyžadována platná URL adresa webhooku.', - 'webhook_flash_exists': 'Tato URL adresa webhooku je již zaregistrována.', - 'accounts_username': 'Uživatelské jméno', - 'accounts_nickname': 'Přezdívka', - 'accounts_status': 'Stav', - 'accounts_actions': 'Akce', - 'accounts_active': 'Aktivní', - 'accounts_inactive': 'Neaktivní', - 'accounts_toggle': 'Přepnout', - 'accounts_remove': 'Odebrat', - 'accounts_add_title': 'Přidat nový účet', - 'accounts_add_username': 'UrNetwork uživatelské jméno', - 'accounts_add_password': 'UrNetwork heslo', - 'accounts_add_nickname': 'Přezdívka (volitelné)', - 'combined_stats': 'Kombinovaná statistika', - 'individual_accounts': 'Jednotlivé účty', - 'view_combined': 'Zobrazit kombinovanou statistiku', - 'view_individual': 'Zobrazit jednotlivé účty', - 'map_title': 'Lokace poskytovatelů', - 'map_legend_title': 'Počet poskytovatelů', - 'map_legend_hover': 'Přejeďte myší přes zemi', - 'leaderboard_title': 'Žebříček', - 'leaderboard_rank': 'Pořadí', - 'leaderboard_name': 'Jméno sítě', - 'leaderboard_data': 'Poskytnutá data (MiB)', - 'devices_title': 'Stav a správa zařízení', - 'devices_status': 'Stav', - 'devices_name': 'Jméno zařízení', - 'devices_id': 'ID klienta', - 'devices_mode': 'Režim poskytování', - 'devices_account': 'Účet', - 'devices_remove': 'Odebrat', - 'devices_online': 'Online', - 'devices_offline': 'Offline', - 'devices_confirm_remove': 'Opravdu chcete odebrat toto zařízení?', - 'flash_device_removed': 'Zařízení úspěšně odebráno.', - 'flash_device_remove_fail': 'Nepodařilo se odebrat zařízení: ' - }, - 'en': { - 'nav_public': 'Public View', - 'nav_owner_dashboard': 'Owner Dashboard', - 'nav_overview': 'Overview', - 'nav_account': 'Account & Leaderboard', - 'nav_devices': 'Devices', - 'nav_settings': 'Settings', - 'nav_accounts': 'Account Management', - 'nav_login': 'Login', - 'nav_logout': 'Logout', - 'title_public_dashboard': 'Public Dashboard', - 'title_owner_dashboard': 'Owner Dashboard', - 'title_account_page': 'Account & Leaderboard', - 'title_devices_page': 'Device Management', - 'title_settings': 'Settings', - 'title_accounts_page': 'Account Management', - 'title_login': 'Login', - 'title_setup': 'Initial Setup', - 'card_paid_data': 'Total Paid Data', - 'card_unpaid_data': 'Total Unpaid Data', - 'card_earnings_30d': 'Earnings (30 Days)', - 'card_total_earnings': 'Total Earnings', - 'card_last_update': 'Last Update', - 'card_account_points': 'Account Points', - 'card_your_rank': 'Your Rank', - 'card_total_referrals': 'Total Referrals', - 'card_active_accounts': 'Active Accounts', - 'card_total_devices': 'Total Devices', - 'chart_total_data_gb': 'Total Data Provided (GB)', - 'chart_paid_vs_unpaid': 'Paid vs. Unpaid Data (GB)', - 'chart_delta': 'Data Change per Interval (GB)', - 'chart_paid': 'Paid (GB)', - 'chart_unpaid': 'Unpaid (GB)', - 'chart_no_data': 'Not enough data to display a chart.', - 'history_title': 'Detailed History', - 'history_timestamp': 'Timestamp', - 'history_change': 'Change (GB)', - 'btn_fetch_now': 'Fetch Now', - 'btn_clear_data': 'Clear All Data', - 'btn_add_account': 'Add Account', - 'confirm_clear_data': 'Are you sure? This will delete all historical stats data.', - 'next_fetch': 'Next automatic fetch:', - 'login_header': 'Sign in to your dashboard', - 'login_username': 'Admin Password', - 'login_password': 'Password', - 'login_button': 'Sign in', - 'error_login_required': 'You must be logged in to view this page.', - 'error_invalid_credentials': 'Invalid password.', - 'flash_logged_in': 'You have been logged in successfully.', - 'flash_logged_out': 'You have been logged out.', - 'flash_settings_saved': 'Settings saved successfully.', - 'flash_fetch_success': 'Successfully fetched and saved latest stats.', - 'flash_fetch_fail': 'Failed to fetch stats: ', - 'flash_clear_success': 'Successfully cleared {count} records from the database.', - 'flash_clear_fail': 'An error occurred while clearing the database.', - 'flash_account_added': 'Account added successfully.', - 'flash_account_removed': 'Account removed successfully.', - 'flash_account_updated': 'Account updated successfully.', - 'webhook_title': 'Webhook Management', - 'webhook_desc': 'Add webhooks to send notifications.', - 'webhook_url_label': 'Webhook URL', - 'webhook_payload_label': 'Custom JSON Payload (optional)', - 'webhook_payload_placeholder': 'E.g.: {"content": "Account: ${account}, Data: ${total_gb} GB"}', - 'webhook_add_btn': 'Add Webhook', - 'webhook_current': 'Current Webhooks', - 'webhook_delete_btn': 'Delete', - 'webhook_flash_added': 'Webhook added successfully.', - 'webhook_flash_deleted': 'Webhook deleted successfully.', - 'webhook_flash_invalid_url': 'A valid Webhook URL is required.', - 'webhook_flash_exists': 'This webhook URL is already registered.', - 'accounts_username': 'Username', - 'accounts_nickname': 'Nickname', - 'accounts_status': 'Status', - 'accounts_actions': 'Actions', - 'accounts_active': 'Active', - 'accounts_inactive': 'Inactive', - 'accounts_toggle': 'Toggle', - 'accounts_remove': 'Remove', - 'accounts_add_title': 'Add New Account', - 'accounts_add_username': 'UrNetwork Username', - 'accounts_add_password': 'UrNetwork Password', - 'accounts_add_nickname': 'Nickname (optional)', - 'combined_stats': 'Combined Statistics', - 'individual_accounts': 'Individual Accounts', - 'view_combined': 'View Combined Stats', - 'view_individual': 'View Individual Accounts', - 'map_title': 'Provider Locations', - 'map_legend_title': 'Provider Count', - 'map_legend_hover': 'Hover over a country', - 'leaderboard_title': 'Leaderboard', - 'leaderboard_rank': 'Rank', - 'leaderboard_name': 'Network Name', - 'leaderboard_data': 'Data Provided (MiB)', - 'devices_title': 'Device Status & Management', - 'devices_status': 'Status', - 'devices_name': 'Device Name', - 'devices_id': 'Client ID', - 'devices_mode': 'Provide Mode', - 'devices_account': 'Account', - 'devices_remove': 'Remove', - 'devices_online': 'Online', - 'devices_offline': 'Offline', - 'devices_confirm_remove': 'Are you sure you want to remove this device?', - 'flash_device_removed': 'Device removed successfully.', - 'flash_device_remove_fail': 'Failed to remove device: ' - } -} - -def get_locale(): - """Detects the best language match from request headers.""" - return request.accept_languages.best_match(TEXTS.keys()) or 'en' - -# --- HTML Templates --- - -LAYOUT_TEMPLATE = """ - - -
- - -Nastavte administrátorské heslo pro váš dashboard.
- -Poté budete moci přidat své UrNetwork účty v nastavení.
-{{ t.chart_no_data }}
{% endif %} -{{ t.chart_no_data }}
{% endif %} -| {{ t.accounts_nickname }} | -{{ t.accounts_username }} | -{{ t.accounts_status }} | -{{ t.accounts_actions }} | -
|---|---|---|---|
| {{ account.nickname or account.username }} | -{{ account.username }} | -- - {{ t.accounts_active if account.is_active else t.accounts_inactive }} - - | -- - - | -
| Zatím nemáte přidané žádné účty. | -|||
{{ t.webhook_desc }}
- -{{ webhook.url }}
-{{ webhook.payload or 'Default Discord Payload' }}
-
- Zatím nemáte nakonfigurované žádné webhooky.
- {% endfor %} -Nastavte administrátorské heslo pro váš dashboard.
- -Poté budete moci přidat své UrNetwork účty v nastavení.
-{{ t.chart_no_data }}
{% endif %} -{{ t.chart_no_data }}
{% endif %} -| {{ t.accounts_nickname }} | -{{ t.accounts_username }} | -{{ t.accounts_status }} | -{{ t.accounts_actions }} | -
|---|---|---|---|
| {{ account.nickname or account.username }} | -{{ account.username }} | -- - {{ t.accounts_active if account.is_active else t.accounts_inactive }} - - | -- - - | -
| Zatím nemáte přidané žádné účty. | -|||
{{ t.webhook_desc }}
- -{{ webhook.url }}
-{{ webhook.payload or 'Default Discord Payload' }}
-
- Zatím nemáte nakonfigurované žádné webhooky.
- {% endfor %} -