airi-utcn/press-review
AIRI@UTCN Press Review
Automated press review platform for the Artificial Intelligence Research Institute at the Technical University of Cluj-Napoca (UTCN).
Monitors Romanian press for mentions of the institute, affiliated researchers, and research units via RSS feeds and Google Search.
Quick start
docker compose up --build- Press review:
http://localhost:8000/ - Social graph:
http://localhost:8000/graph.html
A collection run fires at startup, then every 30 minutes (configurable in data/config.json).
Project layout
press-review/
├── app/ FastAPI service + scheduler + matching logic
├── data/ JSON files — config, articles, graph, people
├── static/ HTML frontend (no build step)
├── tests/ pytest test suite
└── reference/ Original manual press review (docx)Configuration
RSS sources — data/config.json → sources
{ "name": "My Source", "rss_url": "https://example.com/feed.rss", "homepage": "https://example.com" }Keywords — data/config.json → keywords
{
"institute": ["AIRI", "AIRi@UTCN"],
"university": ["UTCN", "Universitatea Tehnică din Cluj-Napoca"],
"research_units": ["Trusted AI", "Robotics and IoT"]
}Changes take effect on the next collection run; no restart needed.
People — data/people.json
Each entry:
{
"name": "Firstname Lastname",
"role": "researcher",
"research_unit": "Trusted AI",
"profile_url": "https://airi.utcluj.ro/people/slug",
"aliases": ["Firstname Lastname", "F. Lastname", "LASTNAME, Firstname"]
}Aliases can be generated automatically:
from app.people_importer import generate_aliases
generate_aliases("Doina Liana Pisla")How matching works
- Normalization — text and terms are NFD-decomposed and lower-cased, making matching diacritics-insensitive ("Călin" = "Calin").
- Word boundaries — terms are matched with
\b…\bso "UTCN" does not match "BUTCNA". - Relevance rules:
- Any
institutekeyword → relevant. - Any
research_unitskeyword → relevant. - Any
universitykeyword and at least one tracked person → relevant.
matched_keywords and matched_persons on each article in data/articles.json show exactly what triggered inclusion.
Graph
The social graph (/graph.html) shows:
Edges: MENTIONED_IN, PUBLISHED_BY, AFFILIATED_WITH, MATCHED_BY, CO_MENTIONED_WITH.
The date filter bar (Total / Lunar / Săptămânal / Zilnic) limits visible nodes to the selected period.
API
Read
Write
All write operations persist to data/ and take effect immediately without restart.
Running tests
pip install -r requirements.txt pytest
pytest tests/ -v