Spaces:
Sleeping
Sleeping
File size: 9,807 Bytes
abc1d97 60e9d75 857d022 60e9d75 abc1d97 60e9d75 abc1d97 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 0c2fdb7 60e9d75 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | ---
title: DIS IPL 2026 — Predictions
emoji: 🏏
colorFrom: blue
colorTo: red
sdk: docker
app_port: 7860
pinned: false
license: mit
---
# 🏏 DIS IPL 2026 — Team Match Predictions
A full-featured IPL match prediction app for your team. Built with Python (Flask) + SQLite.
---
## ⚡ Quick Start
```bash
pip install -r requirements.txt
set ADMIN_PASSWORD=your-admin-password-for-results-panel
# Optional: set PORT=7860 to match Hugging Face; default local port is 5000
set SECRET_KEY=long-random-string-for-session-cookies
python app.py
```
When you run **`python app.py`**, **live reload is on by default**: editing `app.py`, templates, `static/`, or seed JSON (`users.json`, etc.) restarts the dev server automatically. Set **`FLASK_DEBUG=0`** (or `false` / `off`) to disable. Production / Hugging Face uses **gunicorn** and does not use this dev reloader.
Open **`http://127.0.0.1:5000/`** when running `python app.py` locally (default port **5000**). On Hugging Face Spaces, use the Space URL. **No passwords** for team members — pick your name on the home page (roster comes from the database after the first sync from `users.json`; new players from Admin appear automatically).
Admins use **Admin login** in the nav and enter `ADMIN_PASSWORD` (legacy: `ADMIN_SECRET` if `ADMIN_PASSWORD` is unset).
### Hugging Face Spaces (free tier — persistent state without paid disk)
The Space container disk is **ephemeral**. The app can save `ipl_predictions.db` to:
- **[Storage Buckets](https://huggingface.co/docs/hub/storage-buckets)** — S3-style object storage (see the [Python buckets guide](https://huggingface.co/docs/huggingface_hub/guides/buckets)).
- **A private Hub dataset** — Git + LFS history per upload.
You can set **both** `DIS_STATE_BUCKET` and `DIS_STATE_REPO`: every save uploads to **each** configured target (redundant backup). On restore, the app tries the **bucket first**, then the **dataset** if the local file is still missing or too small.
#### What you need to do (one-time)
1. **Create a Hugging Face account** (free) if you don’t have one.
2. **Create storage** (one or both):
- **Bucket:** private bucket, e.g. **`Jay-Rajput/dis-ipl-state`** (Hub UI or [`hf buckets create`](https://huggingface.co/docs/huggingface_hub/guides/buckets)).
- **Dataset:** private dataset with the same or another id, e.g. **`Jay-Rajput/dis-ipl-state`** ([new dataset](https://huggingface.co/new-dataset)). Dataset and bucket are different Hub resources; the id string can match on both sides.
3. **Create an access token** with **read/write** on the bucket and dataset you use: [Settings → Access Tokens](https://huggingface.co/settings/tokens).
4. **Create a Space**: [New Space](https://huggingface.co/new-space) → SDK **Docker** → connect this repo. **CPU basic** is enough (free).
5. **Add Space secrets** (Space → **Settings** → **Repository secrets**):
| Secret | Value |
|--------|--------|
| `ADMIN_PASSWORD` | Strong password for the admin panel |
| `SECRET_KEY` | Long random string (keep the same across redeploys so sessions stay valid) |
| `HF_TOKEN` | Token with write access to your bucket and/or dataset |
| `DIS_STATE_BUCKET` | *(optional)* Bucket id, e.g. `Jay-Rajput/dis-ipl-state` |
| `DIS_STATE_REPO` | *(optional)* Dataset id, e.g. `Jay-Rajput/dis-ipl-state` |
6. **Rebuild / restart** the Space. Use the app once, then wait **~10–30 seconds** so the background upload finishes before you restart the Space to test restore.
#### How it behaves
- After a **prediction** is saved or **results are settled** (points applied for every player who had a pick), the app **uploads the full database** to **each** configured target (bucket and/or dataset) **before the page finishes loading**, so the file on Hub always includes **all members**’ predictions and scores. Other admin tweaks still use a quick background upload.
- On a **cold start**, if the local DB is missing or very small, it tries **bucket first**, then **dataset**.
- Optional **`DIS_FORCE_HUB_RESTORE=1`** forces a download from Hub (overwrites local DB). Use only when you intend to reset from remote state.
#### Optional (not required for free hosting)
- Paid Hugging Face **persistent disk** mounted at `/data`: you may set **`DIS_DATA_DIR=/data`** to keep SQLite on that volume ([Spaces storage docs](https://huggingface.co/docs/hub/spaces-storage)).
- To override bundled JSON at runtime, place `users.json` / `matches.json` / `players.json` under the same directory as the database when using `DIS_DATA_DIR`.
**Bundled data:** `users.json`, `matches.json`, and `players.json` in the repo seed the DB; the name picker reads **active users from the database**.
---
## 🎮 How It Works
### Points System
| Event | Points |
|---|---|
| ✅ Correct winner | **+bid amount** (e.g. bid 100 → earn 100) |
| ❌ Wrong winner | **−bid amount** (e.g. bid 100 → lose 100) |
| ⭐ Correct MOTM | **+75 bonus** |
| 🚫 Wrong MOTM | **−25 penalty** |
| 🤷 No MOTM predicted | **0** (safe, no risk) |
| 🌧️ Match abandoned | **bid refunded** (no winner/MOTM points) |
| 🚫 No prediction made | **0** (missed opportunity only) |
### Starting Points
- Every player starts with **1,000 points**
- Admin can adjust per-player starting points when adding them
- Points can go negative (no floor — creates drama!)
### Bid Rules
- Minimum bid: **10 points**
- Maximum bid: **500 points** OR your current balance (whichever is lower)
- Quick-bid buttons: 10%, 25%, 50%, 75%, 100% of your max bid
### Prediction Lock
- Predictions lock automatically **at the scheduled match start time**
- Once locked, no new predictions or edits are allowed
- The lock is automatic — no admin action needed
---
## 👥 Admin Guide
### Adding Matches
1. Go to **Admin → Add Match**
2. Select Team 1, Team 2, date, and time
3. Add venue and match number (optional but recommended)
4. Predictions are allowed **only on the match’s calendar day**, until the scheduled start time, then they lock automatically
### Setting Results
1. Go to **Admin → Set Results**
2. Select the winner and Man of the Match
3. Click "Set Result & Settle" — points are calculated automatically
4. If you made a mistake, check **"Reverse previous settlement & recalculate"** and re-submit
### Managing Users
- Add players: **Admin → Users → Add New Player**
- Manually adjust points (for disputes, bonuses, etc.)
- Disable/enable users
### Match Statuses
| Status | Meaning |
|---|---|
| `upcoming` | Predictions open |
| `locked` | Auto-locked at scheduled start (no new predictions) |
| `live` | Match in progress (manual — set for drama!) |
| `completed` | Match done, result can be entered |
| `abandoned` | Rain/DLS/etc — bids are automatically refunded |
| `postponed` | Rescheduled — set new date/time by deleting and re-adding |
---
## 🌍 Real-World Scenarios Handled
| Scenario | How it's handled |
|---|---|
| **2 matches in a day** | Both appear on dashboard; predict each separately |
| **Match abandoned** | Admin sets status → bids refunded automatically |
| **Wrong result entered** | Admin uses "Recalculate" to reverse & redo |
| **User forgets to predict** | No penalty — just missed opportunity |
| **User has ≤ 10 pts** | Can bid all remaining points (no forced minimum) |
| **Player name variations** (V Kohli vs Virat Kohli) | Fuzzy last-name matching |
| **No MOTM predicted** | Zero impact — neither bonus nor penalty |
| **Admin needs to correct MOTM** | Re-enter result with "Recalculate" checked |
| **New user joins mid-season** | Admin adds with custom starting points |
| **Suspended/banned user** | Admin disables account — they can't log in |
---
## 🗂️ File Structure
```
ipl-predictions/
├── app.py # Main Flask app (all routes + logic)
├── requirements.txt
├── ipl_predictions.db # SQLite DB (auto-created)
└── templates/
├── base.html # Shared layout, nav, styling
├── login.html # Login page
├── dashboard.html # Home — today's matches
├── matches.html # All matches list
├── predict.html # Prediction form
├── leaderboard.html # Full leaderboard + podium
├── history.html # Personal stats & history
├── admin.html # Admin panel
└── admin_predictions.html # Per-match prediction viewer
```
---
## 🔧 Configuration (in app.py)
```python
POINTS_CONFIG = {
'initial': 1000, # Starting points per player
'min_bid': 10, # Minimum bid
'max_bid': 500, # Maximum bid cap
'correct_winner': 1.0, # Multiplier on bid for correct winner
'wrong_winner': -1.0, # Multiplier on bid for wrong winner
'correct_motm': 75, # Flat bonus for correct MOTM
'wrong_motm': -25, # Flat penalty for wrong MOTM
'lock_minutes_before': 0, # 0 = at start; set e.g. 30 to lock N minutes before
}
```
Change these values and restart the app. Existing settled predictions are unaffected.
---
## 🚀 Production Deployment
For production (not just local use):
```bash
# Install gunicorn
pip install gunicorn
# Run with gunicorn
gunicorn -w 4 -b 0.0.0.0:5000 app:app
```
Also set a real secret key:
```bash
export SECRET_KEY="your-very-long-random-secret-key-here"
```
---
## 🏏 IPL 2025 Teams
| Team | Abbr |
|---|---|
| Mumbai Indians | MI |
| Chennai Super Kings | CSK |
| Royal Challengers Bengaluru | RCB |
| Kolkata Knight Riders | KKR |
| Sunrisers Hyderabad | SRH |
| Delhi Capitals | DC |
| Rajasthan Royals | RR |
| Punjab Kings | PBKS |
| Lucknow Super Giants | LSG |
| Gujarat Titans | GT |
|