Skip to content

Commit 7f0ffaf

Browse files
aborrusoclaude
andcommitted
fix: Migliora filtri ricerca Exa e UX interattiva (v2.0.23)
- Esclusi URL /esporta/ e titoli errore da risultati Exa - Gestione CTRL+C pulita in tutti input interattivi - Prompt nome file con istruzioni chiare - Fix \r per nascondere ^C visibile 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 431644c commit 7f0ffaf

4 files changed

Lines changed: 38 additions & 15 deletions

File tree

LOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
Questo file documenta gli avanzamenti significativi e le decisioni chiave del progetto `normattiva_2_md`.
44

5+
## 2025-12-27
6+
7+
### Fix ricerca naturale Exa e UX interattiva
8+
9+
**v2.0.23**
10+
11+
- Filtro risultati Exa: esclusi URL `/esporta/` non supportati e titoli con "errore"
12+
- Gestione CTRL+C pulita in tutti gli input interattivi (ricerca, nome file, sovrascrittura)
13+
- Prompt nome file migliorato: "(INVIO per confermare, o scrivi nome desiderato)"
14+
- Fix carriage return `\r` per nascondere `^C` visibile
15+
516
## 2025-12-25
617

718
### 📊 Analisi schema dati violenza di genere

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "normattiva2md"
7-
version = "2.0.22"
7+
version = "2.0.23"
88
description = "Convertitore da XML Akoma Ntoso a formato Markdown con download automatico delle leggi citate e cross-references inline (CLI: normattiva2md)"
99
readme = "README.md"
1010
requires-python = ">=3.7"

src/normattiva2md/cli.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,13 @@ def main():
299299
else:
300300
# Genera nome file snake_case
301301
suggested_filename = generate_snake_case_filename(selected_title)
302-
filename_input = input(
303-
f"📝 Nome file [{suggested_filename}]: "
304-
).strip()
302+
try:
303+
filename_input = input(
304+
f"📝 Nome file (INVIO per confermare, o scrivi nome desiderato) [{suggested_filename}]: "
305+
).strip()
306+
except KeyboardInterrupt:
307+
print("\r❌ Operazione annullata dall'utente", file=sys.stderr)
308+
sys.exit(0)
305309

306310
# Valida input: ignora risposte di conferma troppo corte
307311
if filename_input and filename_input.lower() not in [
@@ -328,13 +332,17 @@ def main():
328332

329333
# Verifica se il file esiste già
330334
if os.path.exists(output_file):
331-
overwrite = (
332-
input(
333-
f"⚠️ Il file '{output_file}' esiste già. Sovrascrivere? (s/N): "
335+
try:
336+
overwrite = (
337+
input(
338+
f"⚠️ Il file '{output_file}' esiste già. Sovrascrivere? (s/N): "
339+
)
340+
.strip()
341+
.lower()
334342
)
335-
.strip()
336-
.lower()
337-
)
343+
except KeyboardInterrupt:
344+
print("\r❌ Operazione annullata dall'utente", file=sys.stderr)
345+
sys.exit(0)
338346
if overwrite not in ["s", "si", "sì", "y", "yes"]:
339347
print("❌ Download annullato dall'utente", file=sys.stderr)
340348
sys.exit(0)
@@ -344,7 +352,7 @@ def main():
344352
print(f"✅ URL selezionato: {input_source}", file=sys.stderr)
345353

346354
except (EOFError, KeyboardInterrupt):
347-
print("❌ Operazione annullata dall'utente", file=sys.stderr)
355+
print("\r❌ Operazione annullata dall'utente", file=sys.stderr)
348356
sys.exit(0)
349357
else:
350358
# Selezione automatica - usa il comportamento precedente

src/normattiva2md/exa_api.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
import json
55
import requests
6-
from .normattiva_api import is_normattiva_url # Per la validazione URL
6+
from .normattiva_api import is_normattiva_url, is_normattiva_export_url # Per la validazione URL
77

88
def lookup_normattiva_url(
99
search_query, debug_json=False, auto_select=True, exa_api_key=None
@@ -105,11 +105,15 @@ def lookup_normattiva_url(
105105

106106
for i, result in enumerate(results):
107107
url = result.get("url")
108-
if url and is_normattiva_url(url):
108+
if url and is_normattiva_url(url) and not is_normattiva_export_url(url):
109109
# Calcola un punteggio di preferenza
110110
preference_score = 0
111111
title = result.get("title", "").lower()
112112

113+
# Skippa risultati con "errore" nel titolo (pagine di errore di normattiva.it)
114+
if "errore" in title:
115+
continue
116+
113117
# Penalizza URL caricaDettaglioAtto (restituiscono HTML, non XML)
114118
if "/caricaDettaglioAtto?" in url:
115119
preference_score -= 50
@@ -216,8 +220,8 @@ def lookup_normattiva_url(
216220
else:
217221
print(f"❌ Scelta non valida: {choice}", file=sys.stderr)
218222
return None
219-
except (ValueError, EOFError):
220-
print("❌ Input non valido, ricerca annullata", file=sys.stderr)
223+
except (ValueError, EOFError, KeyboardInterrupt):
224+
print("\r❌ Ricerca annullata dall'utente", file=sys.stderr)
221225
return None
222226

223227
# Selezione automatica

0 commit comments

Comments
 (0)