{
  "markdown": "# ARS Sicilia - Archivio Consultabile Sedute Assemblea\n\n**Piattaforma civic tech per trasparenza e consultazione sedute dell'Assemblea Regionale Siciliana**\n\n> Questo progetto nasce da un'idea semplice da civic hacker: la trasparenza deve essere efficace. Non basta dire \"i video sono online\": chi vuole capire se e quando si è parlato di un argomento oggi ha davanti solo un elenco di video. Portarli su YouTube con metadati strutturati e trascrizione automatica, e creare un sito consultabile con categorie e digest AI cambia tutto: si può cercare nel testo, collegare sedute e video, e usare le trascrizioni come materia prima per analisi civica.\n\n**🌐 Consulta il sito:** [aborruso.github.io/ars_sicilia](https://aborruso.github.io/ars_sicilia/)\n\n---\n\n## 🎯 Cosa Offre il Progetto\n\n- ✅ **Sito web consultabile** - pagine statiche generate con Astro\n- ✅ **Categorie tematiche** - Filtra sedute per argomento (Sanità, Bilancio, Lavoro, etc.)\n- ✅ **Video YouTube ricercabili** - Metadati strutturati, playlist annuali, token univoci\n- ✅ **Digest AI automatici** - Sintesi generate da trascrizioni video con LLM\n- ✅ **Estrazione disegni legge** - Dati legislativi estratti da PDF ordini del giorno\n- ✅ **Feed RSS pubblico** - Aggiornamenti automatici ultimi 20 video con digest disponibile\n- ✅ **Design accessibile** - WCAG 2.1 AA, mobile-first, semantic HTML\n- ✅ **Dati aperti** - CSV, JSONL, JSON pubblicamente accessibili\n\n---\n\n## 🏗️ Architettura Sistema\n\nIl progetto è composto da tre livelli:\n\n### 1. Frontend - Sito Web Statico (Astro + Tailwind)\n\nSito statico generato a build-time con design system \"Editorial Civic\":\n\n- **Tecnologie**: Astro 5.0, Tailwind CSS 3.4, TypeScript\n- **Pagine**: Homepage, lista sedute paginata, singola seduta, singolo video, categorie, About\n- **SEO**: Sitemap automatico, structured data (Schema.org VideoObject), OpenGraph\n- **Hosting**: GitHub Pages con deploy automatico\n- **Design**: Palette istituzionale (Navy, Ambra, Salvia), tipografia editoriale (Fraunces + Manrope)\n\n📖 **Documentazione design**: [docs/design-system.md](docs/design-system.md)\n\n### 2. Backend - Pipeline Automatizzata (Python)\n\nSistema di acquisizione e pubblicazione video sedute:\n\n- **Crawler incrementale** - Estrae metadati sedute dal 10/12/2025 in poi\n- **Download video HLS** - yt-dlp per scaricare stream video ARS\n- **Upload YouTube** - API v3 con OAuth2, playlist annuali, metadati ricchi\n- **Generazione digest AI** - LLM (Gemini 2.5 Flash) per sintesi automatiche\n- **Estrazione disegni legge** - Pipeline PDF→testo→JSON strutturato\n\n**Script principali:**\n- `scripts/build_anagrafica.py` - Aggiorna anagrafica video\n- `scripts/upload_single.py` - Test upload singolo video\n- `scripts/generate_digests.sh` - Genera digest AI da trascrizioni\n- `scripts/extract_odg_data.sh` - Estrae disegni legge da PDF OdG\n- `scripts/generate_rss.py` - Genera feed RSS pubblico\n\n### 3. Data Layer - Dati Strutturati\n\nDataset pubblici in formato aperto:\n\n- `data/anagrafica_video.csv` - Metadati completi sedute (35+ record)\n- `data/disegni_legge.jsonl` - Disegni di legge estratti da OdG\n- `data/digest/{youtube_id}.json` - Digest AI per ogni video\n- `rss.xml` - Feed RSS pubblico (ultimi 20 video con digest disponibile)\n\n---\n\n## 🚀 Quick Start\n\n### Consultare il Sito\n\nVisita [aborruso.github.io/ars_sicilia](https://aborruso.github.io/ars_sicilia/) per:\n- Esplorare sedute per data o categoria\n- Guardare video direttamente dalla pagina\n- Leggere digest AI automatici\n- Accedere ai documenti ufficiali (OdG, Resoconti)\n\n### Accedere ai Dati Aperti\n\nTutti i dataset sono pubblicamente accessibili nel repository:\n\n```bash\n# Clona repository\ngit clone https://github.com/aborruso/ars_sicilia.git\n\n# Esplora dati\ncd ars_sicilia/data\ncat anagrafica_video.csv | head -20\ncat disegni_legge.jsonl | jq .\n```\n\n### Feed RSS\n\nAbbonati al feed per ricevere aggiornamenti automatici:\n\n**URL feed**: [https://aborruso.github.io/ars_sicilia/rss.xml](https://aborruso.github.io/ars_sicilia/rss.xml)\n\nIl feed ufficiale include solo video con digest generato e non vuoto.\n\n---\n\n## 💻 Setup Sviluppo Locale\n\n### Prerequisiti\n\n- Node.js 18+ e npm\n- Python 3.10+ (opzionale, solo per backend)\n- Git\n\n### Frontend - Sito Web\n\n```bash\n# Installa dipendenze\nnpm install\n\n# Build data + sito (genera dist/)\nnpm run build\n\n# Dev server con hot reload\nnpm run dev\n# Apri http://localhost:4321\n```\n\n### Creare nuove pagine in Markdown\n\nÈ possibile aggiungere pagine statiche in Markdown dentro `src/pages/`.  \nConsulta la guida completa: `docs/markdown-guide.md`.\n\n**Struttura generata:**\n- `dist/index.html` - Homepage\n- `dist/sedute/` - Lista sedute paginata\n- `dist/sedute/[anno]/[mese]/[giorno]/[seduta]/` - Pagine singole\n- `dist/sitemap-0.xml`, `dist/rss.xml` - SEO\n\n### Backend - Pipeline Python (Opzionale)\n\nSolo necessario se vuoi replicare la pipeline di acquisizione/pubblicazione:\n\n```bash\n# Crea virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate  # Linux/Mac\n# .venv\\Scripts\\activate   # Windows\n\n# Installa dipendenze\npip3 install -r requirements.txt\n\n# Testa crawler\npython3 scripts/build_anagrafica.py\n\n# Genera digest AI (richiede configurazione LLM)\n./scripts/generate_digests.sh\n```\n\n---\n\n## 📊 Stack Tecnologico\n\n### Frontend\n- **Framework**: Astro 5.0 (generazione statica)\n- **Styling**: Tailwind CSS 3.4 + Typography plugin\n- **Language**: TypeScript\n- **Plugins**: @astrojs/sitemap, @astrojs/rss\n- **Build**: npm scripts + prebuild hook (build-data.mjs)\n- **Deploy**: GitHub Actions → GitHub Pages\n\n### Backend\n- **Language**: Python 3.10+\n- **Scraping**: BeautifulSoup4, requests\n- **Video**: yt-dlp (download HLS)\n- **YouTube API**: google-api-python-client, oauth2client\n- **AI**: LLM CLI (gemini-2.5-flash per digest)\n- **Data**: PyYAML, csv-parse, markitdown (PDF→text)\n- **CLI Tools**: miller (mlr), jq, qv (trascrizioni YouTube)\n\n---\n\n## 🤖 Pipeline YouTube - Setup Avanzato\n\n<details>\n<summary><strong>⚠️ Sezione tecnica - Solo per sviluppatori che vogliono replicare la pipeline YouTube</strong></summary>\n\n### Requisiti\n\n- Account YouTube verificato (per video >15 minuti)\n- Progetto Google Cloud con YouTube Data API v3 abilitata\n- Credenziali OAuth2 (client ID + secret)\n\n### Setup Google Cloud e YouTube API\n\n#### 1. Crea Progetto Google Cloud\n\n1. Vai su [Google Cloud Console](https://console.cloud.google.com/)\n2. Clicca \"Nuovo Progetto\" → Nome: `ars-youtube-uploader`\n3. Nel progetto, vai su \"API & Services\" → \"Library\"\n4. Cerca \"YouTube Data API v3\" → Clicca \"Abilita\"\n\n#### 2. Configura OAuth Consent Screen\n\n1. Vai su \"API & Services\" → \"OAuth consent screen\"\n2. Seleziona \"External\" → Compila:\n   - App name: `ARS Video Uploader`\n   - User support email: tua email\n3. Scopes: aggiungi `https://www.googleapis.com/auth/youtube.upload`\n4. Test users: aggiungi email Google del canale YouTube\n\n#### 3. Crea Credenziali OAuth 2.0\n\n1. Vai su \"API & Services\" → \"Credentials\"\n2. \"Create Credentials\" → \"OAuth client ID\"\n3. Application type: \"Desktop app\" → Name: `ARS Uploader Desktop`\n4. Download JSON → Salva come `config/youtube_secrets.json`\n\n#### 4. Prima Autenticazione\n\n```bash\n# Esegui upload test\npython3 scripts/upload_single.py --dry-run\n\n# Al primo avvio si apre browser per autorizzazione\n# Token salvato in config/token.json per riuso\n```\n\n### Configurazione Playlist e Channel ID\n\n#### Ottieni Channel ID\n\n1. Vai su [YouTube Studio](https://studio.youtube.com)\n2. Impostazioni → Canale → Copia ID canale (es. `UCxxx...` o `@ARSSicilia`)\n3. Apri `config/config.yaml`:\n   ```yaml\n   youtube:\n     channel_id: \"@ARSSicilia\"  # O UCxxxxxxxxxxxxxxxxxxx\n   ```\n\n#### Crea Playlist Annuali\n\n1. YouTube Studio → Playlist → Crea nuova playlist\n   - Nome: `ARS 2025 - Sedute Assemblea`\n   - Visibilità: Pubblica\n2. Copia ID dall'URL: `https://www.youtube.com/playlist?list=PLxxx...`\n3. Apri `config/config.yaml`:\n   ```yaml\n   youtube:\n     playlists:\n       \"2025\": \"PLxxxxxxxxxxxxxxxxxxx\"\n       \"2026\": \"PLyyyyyyyyyyyyyyyyyy\"\n   ```\n\n### Utilizzo\n\n#### Test Upload Singolo Video\n\n```bash\n# Preview senza caricare\npython3 scripts/upload_single.py --dry-run\n\n# Upload reale primo video da anagrafica\npython3 scripts/upload_single.py\n```\n\n#### Build Anagrafica Video\n\n```bash\n# Aggiorna metadati sedute (crawler incrementale)\n./scripts/run_daily.sh\n\n# Con venv\n.venv/bin/python3 scripts/build_anagrafica.py\n```\n\n#### Generazione Digest AI\n\n```bash\n# Genera digest per video con trascrizione\n./scripts/generate_digests.sh\n```\n\n#### Estrazione Disegni Legge\n\n```bash\n# Estrai disegni da PDF ordini del giorno\n./scripts/extract_odg_data.sh\n\n# Forza rielaborazione di tutti i PDF (ignora dedup per pdf_url)\n./scripts/extract_odg_data.sh --reprocess\n```\n\n### Automazione GitHub Actions\n\nIl progetto include workflow automatici che girano ogni notte:\n\n- **`daily_upload.yml`** - 🕐 01:37 UTC ogni giorno:\n  - Aggiorna anagrafica sedute con crawler incrementale\n  - Carica fino a 4 video/giorno su YouTube (rispetta quota API)\n  - Commit automatico di `data/anagrafica_video.csv`\n  - **Triggera automaticamente il deploy del sito** (grazie a `WORKFLOW_PAT`)\n\n- **`extract_odg.yml`** - 🕐 03:47 UTC ogni giorno:\n  - Estrae disegni di legge dai PDF ordini del giorno\n  - Salva in `data/disegni_legge.jsonl`\n  - **Triggera automaticamente il deploy del sito**\n\n- **`publish_rss.yml`** - 🕐 02:17 UTC ogni giorno:\n  - Genera feed RSS aggiornato\n  - Pubblica `feed.xml` su branch gh-pages\n\n- **`deploy-site.yml`** - 🔄 Automatico al push su `data/` o `src/`:\n  - Build sito statico Astro con `npm run build`\n  - Deploy su GitHub Pages\n\n**Secret richiesti** (Settings → Secrets):\n- `YT_CLIENT_SECRET_JSON` - Contenuto `config/youtube_secrets.json`\n- `YT_TOKEN_JSON` - Contenuto `config/token.json`\n- `WORKFLOW_PAT` - Personal Access Token con scope `repo` e `workflow` (per triggerare deploy automatico)\n- `GEMINI_API_KEY` - API key per Gemini (generazione digest)\n\n### 🔄 Workflow Manuale Post-Upload (Temporaneo)\n\n**⚠️ IMPORTANTE**: Fino a completa automazione, dopo che i workflow notturni hanno uploadato nuovi video su YouTube, è necessario eseguire manualmente:\n\n#### 0. Aggiorna la repository\n\n```bash\n# Allinea la working copy con l'ultimo stato del repository\ngit pull\n```\n\n#### 1. Download Trascrizioni\n\n```bash\n# Scarica sottotitoli automatici da YouTube (SRT + TXT)\n./scripts/download_transcripts.sh\n```\n\n**Perché manuale?** Il download trascrizioni usa YouTube Data API con OAuth locale (`config/youtube_secrets.json` + `config/token.json`), non disponibile nei workflow standard.\n\n#### 2. Generazione Digest AI\n\n```bash\n# Genera sintesi JSON da trascrizioni usando Gemini 2.5 Flash\n./scripts/generate_digests.sh\n```\n\n**Richiede**: trascrizioni già scaricate (step 1).  \n**Output**: `data/digest/{youtube_id}.json` per ogni video.\n\n#### 3. Commit e Deploy\n\n```bash\n# Aggiungi trascrizioni e digest al repository\ngit add data/trascrizioni/ data/digest/\ngit commit -m \"chore: add transcripts and AI digests\"\ngit push\n```\n\n**Il deploy del sito avverrà automaticamente** grazie al workflow `deploy-site.yml` che si triggera automaticamente sui push in `data/` (usa `WORKFLOW_PAT` per bypassare la limitazione di GitHub Actions).\n\n#### Frequenza Consigliata\n\n- **Giornaliera**: Dopo il workflow notturno `daily_upload.yml` (02:30 UTC circa)\n- **Verificare**: Se ci sono nuovi video con `youtube_id` ma senza trascrizione in `data/trascrizioni/`\n\n#### Automazione Futura\n\nQuesti step manuali saranno automatizzati quando:\n- [ ] Trascrizioni: usare servizio esterno o self-hosted per bypassare blocco GitHub Actions\n- [ ] Digest: integrare nel workflow notturno dopo download trascrizioni\n\n### Limiti e Quota YouTube API\n\n- **Quota giornaliera**: 10,000 units/day (default)\n- **Costo upload video**: ~1,600 units\n- **Costo playlist insert**: ~50 units\n- **Totale per video**: ~1,650 units\n- **Max upload/giorno**: ~6 video\n\nSe serve più quota, richiedi aumento su Google Cloud Console.\n\n### Troubleshooting\n\n#### Errore \"File credenziali non trovato\"\nVerifica che `config/youtube_secrets.json` esista con credenziali OAuth2 da Google Cloud.\n\n#### Errore \"Quota exceeded\"\nHai superato limite giornaliero (10,000 units). Aspetta 24h o richiedi aumento quota.\n\n#### Token scaduto\nElimina `config/token.json` e riavvia script per ri-autenticarsi.\n\n#### Download fallito\n- Verifica connessione internet\n- Verifica che `config/youtube_secrets.json` e `config/token.json` siano validi\n- Rigenera il token OAuth se necessario (scope: `youtube.readonly` e `youtube.force-ssl`)\n\n</details>\n\n---\n\n## 📚 Documentazione\n\n- 📋 [PRD.md](PRD.md) - Product Requirements Document completo\n- 🎨 [docs/design-system.md](docs/design-system.md) - Design system \"Editorial Civic\"\n- 📊 [LOG.md](LOG.md) - Changelog dettagliato progetto (aggiornato quotidianamente)\n- 🏗️ [openspec/project.md](openspec/project.md) - Specifica architettura backend + frontend\n- 🔍 [ars_sicilia_api/](ars_sicilia_api/) - Client Python per API disegni di legge ARS\n- 📖 [ars_sicilia_api/API_DOCUMENTATION.md](ars_sicilia_api/API_DOCUMENTATION.md) - Documentazione API ricerca legislativa\n- 🔎 [ars_sicilia_api/GUIDA_ALLA_RICERCA.md](ars_sicilia_api/GUIDA_ALLA_RICERCA.md) - Sintassi query avanzate\n\n---\n\n## 📂 Struttura Progetto\n\n```\nars_sicilia/\n├── src/                          # Frontend Astro\n│   ├── pages/                    # Routing (index, sedute, video, about)\n│   ├── components/               # Componenti React/Astro\n│   ├── layouts/                  # Layout base\n│   └── lib/                      # Data loaders, utilities\n├── scripts/                      # Backend Python\n│   ├── build_anagrafica.py       # Crawler sedute\n│   ├── upload_single.py          # Test upload YouTube\n│   ├── generate_digests.sh       # Digest AI\n│   ├── extract_odg_data.sh       # Estrai disegni legge\n│   └── build-data.mjs            # Build data per Astro (JS)\n├── data/                         # Dataset pubblici\n│   ├── anagrafica_video.csv      # Metadati sedute\n│   ├── disegni_legge.jsonl       # Disegni legge estratti\n│   ├── digest/                   # Digest AI JSON\n│   └── logs/                     # Log upload, build\n├── config/                       # Configurazione\n│   ├── config.yaml               # Config backend Python\n│   ├── digest.yaml               # Template prompt LLM\n│   ├── digest-schema.json        # Schema JSON digest\n│   ├── youtube_secrets.json      # Credenziali OAuth2 (non versionato)\n│   └── token.json                # Token OAuth2 (auto-generato)\n├── docs/                         # Documentazione\n│   └── design-system.md          # Guida design system\n├── ars_sicilia_api/              # Client API disegni legge\n├── dist/                         # Output build Astro (GitHub Pages)\n├── package.json                  # Dipendenze frontend\n├── requirements.txt              # Dipendenze backend Python\n├── tailwind.config.mjs           # Config Tailwind CSS\n└── astro.config.mjs              # Config Astro\n```\n\n---\n\n## 📊 Dati Aperti\n\nTutti i dataset sono pubblicamente accessibili e versionati su GitHub:\n\n### Dataset Disponibili\n\n| File | Formato | Descrizione | Record |\n|------|---------|-------------|--------|\n| `data/anagrafica_video.csv` | CSV | Metadati completi sedute e video | 35+ |\n| `data/disegni_legge.jsonl` | JSONL | Disegni di legge estratti da OdG | Variabile |\n| `data/digest/{youtube_id}.json` | JSON | Digest AI generati da trascrizioni | 20+ |\n| `rss.xml` | RSS 2.0 | Feed pubblico ultimi 20 video con digest disponibile | 20 |\n\n### Schema Anagrafica Video (CSV)\n\nCampi principali:\n- `numero_seduta` - Numero seduta (es. \"219\")\n- `data_seduta` - Data seduta (YYYY-MM-DD)\n- `data_video` - Data video effettiva (YYYY-MM-DD)\n- `ora_video` - Ora inizio video (HH:MM)\n- `youtube_id` - ID video YouTube (vuoto se non uploadato)\n- `odg_url` - Link PDF ordine del giorno\n- `resoconto_stenografico_url` - Link resoconto finale\n- `duration_minutes` - Durata video in minuti\n- `last_check` - Timestamp ultimo aggiornamento\n\n### Schema Disegni Legge (JSONL)\n\nCampi per record:\n- `titolo_disegno` - Titolo completo\n- `numero_disegno` - Numero DDL (solo parte numerica)\n- `legislatura` - Numero romano (es. \"XVIII\")\n- `data_ora` - Data e ora seduta (ISO 8601)\n- `pdf_url` - URL PDF sorgente\n- `url_disegno` - URL ICARO generato\n\nNota: lo script normalizza `numero_disegno` con regex `[0-9]+` e scarta record senza numero.\n\n### Licenza Dati\n\nI dati estratti sono derivati da fonti pubbliche dell'Assemblea Regionale Siciliana. Il software di estrazione è open source.\n\n---\n\n## 🗺️ Roadmap\n\n### In Sviluppo\n- [ ] Search engine full-text con Pagefind\n- [ ] Dashboard query disegni legge (legislatura, anno, firmatario)\n- [ ] Linkage automatico video↔disegni discussi\n\n### Prossimi Passi\n- [ ] Trascrizione automatica: export testo per analisi\n- [ ] Dark mode per sito web\n- [ ] Pagina About con storytelling civic hacking\n- [ ] API pubblica per interrogare anagrafica\n\n### Idee Future\n- [ ] Notifiche Telegram/email per nuove sedute\n- [ ] Analisi sentiment discussioni parlamentari\n- [ ] Timeline legislativa per singolo DDL\n- [ ] Integrazione dati voti elettronici\n\n---\n\n## 🤝 Contributi e Licenza\n\n### Come Contribuire\n\n1. Fork repository\n2. Crea branch feature: `git checkout -b feature/nome-feature`\n3. Commit modifiche: `git commit -m 'Add: descrizione'`\n4. Push branch: `git push origin feature/nome-feature`\n5. Apri Pull Request\n\n### Linee Guida\n\n- Segui convenzioni esistenti (Python PEP 8, Prettier per JS/TS)\n- Aggiungi test per nuove funzionalità\n- Aggiorna documentazione e LOG.md\n- Mantieni commit atomici e messaggi chiari\n\n### Licenza\n\nQuesto progetto è software libero sviluppato per rendere accessibili i lavori dell'Assemblea Regionale Siciliana.\n\n### Crediti\n\n**Sviluppo**: Civic hacker e contributor GitHub\n\n**Tecnologie**: Astro, Tailwind CSS, Python, YouTube Data API, LLM CLI\n\n**Skill AI utilizzati**:\n- `frontend-design` - Design system \"Editorial Civic\"\n- `openspec` - Gestione proposte architetturali\n\n**Fonti dati**: [Assemblea Regionale Siciliana](https://www.ars.sicilia.it)\n\nFonte utile di approfondimento (slegata dalle pagine sedute ARS e dal motore di ricerca DDL): [Studi e pubblicazioni](https://www.ars.sicilia.it/studi-e-pubblicazioni), dove sono pubblicati dossier, note di lettura e altri documenti elaborati dal Servizio Studi e dal Servizio Bilancio a supporto dei lavori parlamentari delle Commissioni e dell'Aula.\n\n---\n\n## 📞 Contatti\n\n- **Issues GitHub**: [github.com/aborruso/ars_sicilia/issues](https://github.com/aborruso/ars_sicilia/issues)\n- **Feed RSS**: [aborruso.github.io/ars_sicilia/rss.xml](https://aborruso.github.io/ars_sicilia/rss.xml)\n- **Repository**: [github.com/aborruso/ars_sicilia](https://github.com/aborruso/ars_sicilia)\n\n---\n\n**Progetto civic tech per trasparenza democratica**\n*Ultimo aggiornamento: 2025-12-28*\n",
  "bytes": 18828,
  "sha": "9fd7a04452124c75538053663d99dfc1bfd61c1c1f333c6ed8de61bed8e6dd94",
  "repo_slug": "aborruso/ars_sicilia",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_aborruso_ars_sicilia_wiki_index_md_eac00b34/readme"
}