# 🌍 World Trends Collector

Modulinė Python sistema, automatiškai renkanti **realaus laiko**, **valandinius** ir
**dieninius** trendus visoms ~195 pasaulio šalims iš įvairių nemokamų viešų
šaltinių (Google Trends, RSS, GDELT, Reddit, Wikipedia, NewsAPI, GNews).

## Pagrindinės savybės

- ✅ 7 kolektoriai (galima išjungti / įjungti per `config.yaml`)
- ✅ ISO 3166-1 šalys per `pycountry` su Google Trends `pn` ir laiko juostų žemėlapiu
- ✅ MySQL schema su `countries`, `sources`, `trends`, `trend_history`, `trend_links`
- ✅ Tekstų valymas (emoji, kontroliniai simboliai), kalbos aptikimas
- ✅ Sentimento analizė (VADER + TextBlob fallback)
- ✅ Automatinė kategorijų klasifikacija pagal raktažodžius
- ✅ Panašių trendų grupavimas (RapidFuzz token_set_ratio)
- ✅ APScheduler – periodinis paleidimas su atskirais intervalais
- ✅ CSV/JSON eksportas
- ✅ FastAPI + Chart.js dashboard
- ✅ Klaidų tolerancija, retry, robots.txt, pauzės tarp užklausų

---

## Greitas pradžios vadovas

### 1. Reikalavimai

- Python **3.10+**
- MySQL **8.0+** arba MariaDB **10.5+**

### 2. Įdiegti priklausomybes

```bash
git clone <šio projekto adresas> world-trends
cd world-trends
python -m venv .venv && source .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```

### 3. MySQL DB

Sukurkite vartotoją ir duomenų bazę:

```sql
CREATE DATABASE world_trends CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'trends'@'localhost' IDENTIFIED BY 'pakeiskime-tikra-slaptazodi';
GRANT ALL ON world_trends.* TO 'trends'@'localhost';
FLUSH PRIVILEGES;
```

Schemą galite pritaikyti dviem būdais:

**A.** Tiesiogiai SQL failu:
```bash
mysql -u trends -p world_trends < sql/schema.sql
```

**B.** Per Python (rekomenduojama – iškart užpildoma `countries` lentelė):
```bash
python -m trends_collector.main init-db
```

### 4. Konfigūracija

Atidarykite `config.yaml` ir pakeiskite:

- `database.password` – arba nustatykite `export TRENDS_DB_PASS=...`
- `countries:` – galite palikti `["LT","LV","EE","US","JP"]` arba įdėti `"ALL"`
- (neprivaloma) `api_keys.newsapi`, `api_keys.gnews` – jei turite raktus

Visi raktai turi atitinkančias **env. kintamųjų atitikmenis** (pvz. `NEWSAPI_KEY`),
kurie perrašo YAML reikšmes.

### 5. Bandomasis paleidimas (3–5 šalims)

```bash
# vienkartinis paleidimas – iškart parodo, ar viskas veikia
python -m trends_collector.main run-once
```

Sekite `logs/trends.log` arba terminalo išvestį. Esant teisingam DB sujungimui
matysite, kaip kolektoriai pradeda darbą per visas konfiguruotas šalis.

### 6. Pastovus veikimas

```bash
python -m trends_collector.main run
```

Intervalai (pvz. `google_trends` kas 30 min, `rss` kas 30 min, `gdelt` kas 60 min)
nurodomi `config.yaml -> collectors:`.

### 7. Web dashboard

```bash
python -m trends_collector.main dashboard
# Atidarykite naršyklėje: http://localhost:8080
```

### 8. Eksportas dabar

```bash
python -m trends_collector.main export --hours 24
# rezultatai: exports/trends_<YYYYMMDDTHHMMSSZ>.{json,csv}
```

---

## Architektūra

```
world-trends/
├── config.yaml              # konfigūracija (raktai, intervalai, šalys)
├── requirements.txt
├── sql/schema.sql           # MySQL schema (alternatyva init-db komandai)
├── trends_collector/
│   ├── main.py              # CLI sąsaja
│   ├── config.py            # YAML + env. kintamųjų užkrovimas
│   ├── database.py          # SQLAlchemy modeliai + DatabaseHandler
│   ├── countries.py         # ISO 3166, GT geo, laiko juostos
│   ├── pipeline.py          # apdorojimo grandinė
│   ├── scheduler.py         # APScheduler darbai
│   ├── logger.py            # rotacinis loger'is
│   ├── collectors/
│   │   ├── base.py          # BaseCollector + TrendItem
│   │   ├── google_trends.py # pytrends (daily + realtime)
│   │   ├── rss.py           # feedparser, šalies specifiniai feed'ai
│   │   ├── reddit.py        # public .json (be PRAW)
│   │   ├── gdelt.py         # GDELT DOC 2.0 API
│   │   ├── wikipedia.py     # pageviews + current events
│   │   ├── newsapi.py       # NewsAPI.org
│   │   └── gnews.py         # GNews.io
│   ├── processors/
│   │   ├── text_cleaner.py  # emoji, NFKC, kalbos aptikimas
│   │   ├── categorizer.py   # keyword-based klasifikacija
│   │   ├── sentiment.py     # VADER + TextBlob fallback
│   │   └── deduplicator.py  # RapidFuzz panašumas
│   ├── exporters/csv_json.py
│   └── utils/http.py        # requests + retry + robots.txt
├── dashboard/
│   ├── app.py               # FastAPI maršrutai
│   └── templates/index.html # Chart.js UI
└── examples/                # pavyzdžiai (žr. žemiau)
```

## Duomenų srautas

```
   collector.collect_for_country(country)
            │  -> List[TrendItem]
            ▼
        pipeline._persist:
        1. clean_text(keyword)          (emoji, NFKC)
        2. detect_language(text)
        3. categorize(text, hint)       (raktažodžiai)
        4. score_sentiment(text)        (VADER / TextBlob)
        5. best_match() su 48h atgal    (panašių trendų susiejimas)
        6. db.upsert_trend(...)
        7. db.add_trend_link(a,b,sim)   (jei panašus)
            │
            ▼
        MySQL: trends + trend_history + trend_links
```

## Naudoti su nepilnu API raktų rinkiniu

NewsAPI / GNews kolektoriai veikia tik turint raktą. Be jų vis tiek dirbs:

- **Google Trends** (`pytrends`, be raktų)
- **RSS** (BBC, Reuters, vietiniai portalai)
- **GDELT** (be raktų)
- **Reddit** (`/r/<sub>/hot.json`)
- **Wikipedia** (Pageviews API)

Tai sudaro **5 nepriklausomus šaltinius** be jokio raktelio – pakanka prasmingam
trendų aprėpimui.

## Pavyzdžiai

Žiūrėkite `examples/` katalogą:

- `examples/quickstart_lt_lv_ee_us_jp.sh` – pilnas paleidimas 5 šalims
- `examples/inspect_results.py` – SQL užklausos pavyzdžiai

## Pagarba šaltiniams

Sistema:

1. Įdeda `User-Agent` antraštę (`http.user_agent` config'e).
2. Tikrina `robots.txt` prieš HTML scraping (RSS, custom puslapiai).
3. Daro `time.sleep(default_sleep_between_requests)` po kiekvienos užklausos.
4. Naudoja `tenacity` retry su eksponentine atidėjimo strategija.
5. Atskiria klaidas šaltiniuje – jei vienas šaltinis žlunga, kiti dirba toliau.

**Atminkite**, kad NewsAPI nemokama pakopa skirta tik ne komerciniam naudojimui.
Reddit politika kinta – jei matote 403/429, sumažinkite užklausų dažnumą arba
įdiekite oficialų OAuth per PRAW (raktai `config.yaml -> api_keys`).

## Trikčių šalinimas

| Simptomas | Veiksmas |
|---|---|
| `pytrends` 429 klaidos | sumažinkite `interval_minutes_realtime` |
| `pymysql.err.OperationalError: 1045` | patikrinkite DB slaptažodį / vartotoją |
| `langdetect.LangDetectException` | normalu, paprastai dėl labai trumpų eilučių |
| `Reddit 403` | nustatykite individualų `http.user_agent` su kontaktu |
| Tuščia `countries` | įvykdykite `python -m trends_collector.main init-db` |

## Licencija

MIT (žr. LICENSE, jei pridėtas). Trečiųjų šalių šaltinių licencijos – jų pačių
sąlygomis.
