You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Evently is a platform that scrapes event data from multiple Moroccan sources, enriches each event with nearby bus and tramway transport info, indexes everything into Elasticsearch, and serves it through a FastAPI backend with a frontend UI.
4
-
All scraping and indexing are automated using GitHub Actions on a scheduled cron job.
3
+
Evently is a platform that scrapes event data from multiple Moroccan sources, geocodes each event venue using **Nominatim (OpenStreetMap)**, enriches each event with nearby bus and tramway transport info, indexes everything into Elasticsearch, and serves it through a FastAPI backend with a frontend UI.
4
+
5
+
Scraping and indexing are automated on a daily scheduled cron job at midnight,
6
+
with **Slack alerts** on failure.
7
+
8
+
## Scheduling
9
+
-**Apache Airflow** — used for local/self-hosted deployments (runs inside Docker)
10
+
-**GitHub Actions** — alternative for cloud deployments using Elastic Cloud
5
11
6
12
---
7
13
8
14
## 📌 Features
9
15
10
16
### 🔍 Scraping
11
-
- Collects events in parallel from multiple sources (Casaevents, Eventbrite, Events.ma, Guichet)
17
+
- Collects events in parallel from multiple Moroccan sources
12
18
- Parallel scraping for faster data collection
13
19
20
+
### 📍 Geocoding
21
+
- Each event venue is geocoded using the **Nominatim API** (OpenStreetMap) via `geopy`
22
+
- Converts venue names and addresses into **coordinates (longitude, latitude)**
23
+
- Coordinates are used downstream for transport enrichment via KDTree spatial indexing
24
+
14
25
### 🚌 Transport Integration
15
26
- Each event is automatically enriched with nearby **Casabus** and **Tramway** lines at indexing time
16
-
- Uses a **KDTree spatial index** for near-instant transport lookups
17
-
- Transport data is precomputed and stored directly in the event document — no per-request calculation
27
+
- Uses a **KDTree spatial index** built from precomputed local transport data to find nearest lines
28
+
- Transport data is fetched **once** from the **Overpass API** (OpenStreetMap), stored locally as JSON, and reused at every indexing run — no live API calls during the pipeline
29
+
- Transport lines are stored directly in the event document — no per-request spatial computation
18
30
19
31
### 🧠 Elasticsearch
20
32
- Events are indexed with duplicate prevention using hashed unique IDs (MD5)
@@ -43,10 +55,20 @@ All scraping and indexing are automated using GitHub Actions on a scheduled cron
43
55
44
56
### 🎨 Frontend
45
57
- Dynamic event loading from API
46
-
- Pagination, search, and filter support
47
-
48
-
### 🔄 GitHub Actions Automation
49
-
A scheduled workflow runs all scrapers and Elasticsearch indexing automatically on a cron schedule.
58
+
- Search bar with debounce and clear button
59
+
- Filters panel: city, category, date, upcoming only, sort
60
+
- Grid and list view toggle
61
+
- Event detail modal with transport info
62
+
- Favorites system with save/remove
63
+
- Share events via Twitter, Facebook, WhatsApp, or copy link
64
+
- Pagination with ellipsis
65
+
66
+
### 🔄 Airflow Scheduling
67
+
- Daily scraping and indexing triggered automatically at **midnight**
68
+
- DAG: `evently_daily_scraping`
69
+
- Retries up to **2 times** on failure with a 5 minute delay
70
+
-**Slack notifications** on both success and failure
71
+
- Airflow UI accessible at `http://localhost:8080`
50
72
51
73
---
52
74
@@ -56,85 +78,112 @@ A scheduled workflow runs all scrapers and Elasticsearch indexing automatically
56
78
Events_Project/
57
79
│
58
80
├── elastic/
59
-
│ ├── elastic_script.py # indexing + transport enrichment
At indexing time, each event's coordinates are used to query a **KDTree** built from all bus and tramway stop coordinates. The nearest lines (within 0.5km) are stored directly on the event document in Elasticsearch.
213
+
```
214
+
Scrapers (parallel)
215
+
↓
216
+
Nominatim API — geocode venue name → coordinates
217
+
↓
218
+
KDTree spatial index — coordinates → nearest bus/tramway lines
219
+
(from precomputed local JSON, originally fetched from Overpass API)
220
+
↓
221
+
Elasticsearch — event + coordinates + transport lines indexed together
At indexing time, each event's venue is geocoded to coordinates, which are used to query a **KDTree** built from all bus and tramway stop coordinates. The nearest lines within 0.5km are stored directly on the event document in Elasticsearch.
162
229
163
-
This means `/transport/{event_id}` is just a simple document read — no spatial computation happens at request time.
230
+
This means `/transport/{event_id}` is just a simple document read — no spatial computation or API call happens at request time.
231
+
232
+
---
233
+
234
+
## 🐳 Docker Commands Reference
235
+
236
+
```bash
237
+
# First run or after changing Dockerfile/requirements
238
+
docker compose up --build
239
+
240
+
# After changing only Python/JS/HTML files
241
+
docker compose up
242
+
243
+
# Full clean restart (wipes data volumes)
244
+
docker compose down -v
245
+
docker compose up --build
246
+
247
+
# View logs for a specific service
248
+
docker compose logs airflow-scheduler
249
+
docker compose logs fastapi
250
+
```
164
251
165
252
---
166
253
@@ -170,4 +257,6 @@ This means `/transport/{event_id}` is just a simple document read — no spatial
170
257
2. Store favorites in Elasticsearch instead of in-memory
0 commit comments