pyarchinit-mini 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli_interface/cli_app.py +497 -0
- desktop_gui/__init__.py +52 -0
- desktop_gui/dialogs.py +1980 -0
- desktop_gui/gui_app.py +109 -0
- desktop_gui/harris_matrix_editor.py +970 -0
- desktop_gui/icons.py +70 -0
- desktop_gui/inventario_dialog_extended.py +966 -0
- desktop_gui/main_window.py +1695 -0
- desktop_gui/media_manager_advanced.py +112 -0
- desktop_gui/postgres_installer_dialog.py +357 -0
- desktop_gui/thesaurus_dialog.py +463 -0
- desktop_gui/us_dialog_extended.py +1975 -0
- pyarchinit_mini/__init__.py +30 -0
- pyarchinit_mini/api/__init__.py +87 -0
- pyarchinit_mini/api/dependencies.py +63 -0
- pyarchinit_mini/api/inventario.py +107 -0
- pyarchinit_mini/api/schemas.py +186 -0
- pyarchinit_mini/api/site.py +220 -0
- pyarchinit_mini/api/us.py +107 -0
- pyarchinit_mini/database/__init__.py +13 -0
- pyarchinit_mini/database/connection.py +167 -0
- pyarchinit_mini/database/manager.py +231 -0
- pyarchinit_mini/database/migrations.py +136 -0
- pyarchinit_mini/database/postgres_installer.py +375 -0
- pyarchinit_mini/database/schemas.py +177 -0
- pyarchinit_mini/dto/__init__.py +16 -0
- pyarchinit_mini/dto/inventario_dto.py +57 -0
- pyarchinit_mini/dto/site_dto.py +62 -0
- pyarchinit_mini/dto/us_dto.py +237 -0
- pyarchinit_mini/exceptions.py +23 -0
- pyarchinit_mini/harris_matrix/__init__.py +11 -0
- pyarchinit_mini/harris_matrix/enhanced_visualizer.py +465 -0
- pyarchinit_mini/harris_matrix/matrix_generator.py +449 -0
- pyarchinit_mini/harris_matrix/matrix_visualizer.py +366 -0
- pyarchinit_mini/harris_matrix/pyarchinit_visualizer.py +473 -0
- pyarchinit_mini/media_manager/__init__.py +9 -0
- pyarchinit_mini/media_manager/media_handler.py +276 -0
- pyarchinit_mini/models/__init__.py +28 -0
- pyarchinit_mini/models/base.py +32 -0
- pyarchinit_mini/models/harris_matrix.py +117 -0
- pyarchinit_mini/models/inventario_materiali.py +98 -0
- pyarchinit_mini/models/media.py +109 -0
- pyarchinit_mini/models/site.py +32 -0
- pyarchinit_mini/models/thesaurus.py +179 -0
- pyarchinit_mini/models/us.py +104 -0
- pyarchinit_mini/pdf_export/__init__.py +9 -0
- pyarchinit_mini/pdf_export/pdf_generator.py +1036 -0
- pyarchinit_mini/pdf_export/pdf_generator_backup.py +1013 -0
- pyarchinit_mini/pdf_export/pyarchinit_finds_template.py +404 -0
- pyarchinit_mini/pdf_export/pyarchinit_inventory_template.py +353 -0
- pyarchinit_mini/pdf_export/usm_implementation.py +465 -0
- pyarchinit_mini/scripts/__init__.py +3 -0
- pyarchinit_mini/scripts/setup_user_env.py +315 -0
- pyarchinit_mini/services/__init__.py +13 -0
- pyarchinit_mini/services/inventario_service.py +347 -0
- pyarchinit_mini/services/media_service.py +451 -0
- pyarchinit_mini/services/periodizzazione_service.py +417 -0
- pyarchinit_mini/services/site_service.py +254 -0
- pyarchinit_mini/services/thesaurus_service.py +358 -0
- pyarchinit_mini/services/us_service.py +446 -0
- pyarchinit_mini/utils/__init__.py +27 -0
- pyarchinit_mini/utils/exceptions.py +38 -0
- pyarchinit_mini/utils/stratigraphic_validator.py +347 -0
- pyarchinit_mini/utils/validators.py +219 -0
- pyarchinit_mini-0.1.1.dist-info/METADATA +372 -0
- pyarchinit_mini-0.1.1.dist-info/RECORD +72 -0
- pyarchinit_mini-0.1.1.dist-info/WHEEL +5 -0
- pyarchinit_mini-0.1.1.dist-info/entry_points.txt +6 -0
- pyarchinit_mini-0.1.1.dist-info/top_level.txt +4 -0
- web_interface/app.py +404 -0
- web_interface/templates/base.html +187 -0
- web_interface/templates/dashboard.html +226 -0
cli_interface/cli_app.py
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Interactive CLI for PyArchInit-Mini
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from rich.panel import Panel
|
|
12
|
+
from rich.prompt import Prompt, Confirm
|
|
13
|
+
from rich.progress import track
|
|
14
|
+
from datetime import datetime
|
|
15
|
+
|
|
16
|
+
# Add parent directory to path for imports
|
|
17
|
+
sys.path.append('..')
|
|
18
|
+
|
|
19
|
+
from pyarchinit_mini.database.connection import DatabaseConnection
|
|
20
|
+
from pyarchinit_mini.database.manager import DatabaseManager
|
|
21
|
+
from pyarchinit_mini.services.site_service import SiteService
|
|
22
|
+
from pyarchinit_mini.services.us_service import USService
|
|
23
|
+
from pyarchinit_mini.services.inventario_service import InventarioService
|
|
24
|
+
from pyarchinit_mini.harris_matrix.matrix_generator import HarrisMatrixGenerator
|
|
25
|
+
from pyarchinit_mini.harris_matrix.matrix_visualizer import MatrixVisualizer
|
|
26
|
+
from pyarchinit_mini.pdf_export.pdf_generator import PDFGenerator
|
|
27
|
+
|
|
28
|
+
console = Console()
|
|
29
|
+
|
|
30
|
+
class PyArchInitCLI:
|
|
31
|
+
"""Interactive CLI for PyArchInit-Mini"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, database_url: str = None):
|
|
34
|
+
self.console = console
|
|
35
|
+
|
|
36
|
+
# Setup database
|
|
37
|
+
if not database_url:
|
|
38
|
+
database_url = os.getenv("DATABASE_URL", "sqlite:///./pyarchinit_mini.db")
|
|
39
|
+
|
|
40
|
+
self.db_conn = DatabaseConnection.from_url(database_url)
|
|
41
|
+
self.db_conn.create_tables()
|
|
42
|
+
self.db_manager = DatabaseManager(self.db_conn)
|
|
43
|
+
|
|
44
|
+
# Initialize services
|
|
45
|
+
self.site_service = SiteService(self.db_manager)
|
|
46
|
+
self.us_service = USService(self.db_manager)
|
|
47
|
+
self.inventario_service = InventarioService(self.db_manager)
|
|
48
|
+
self.matrix_generator = HarrisMatrixGenerator(self.db_manager)
|
|
49
|
+
self.matrix_visualizer = MatrixVisualizer()
|
|
50
|
+
self.pdf_generator = PDFGenerator()
|
|
51
|
+
|
|
52
|
+
def show_welcome(self):
|
|
53
|
+
"""Show welcome screen"""
|
|
54
|
+
welcome_text = """
|
|
55
|
+
🏛️ [bold blue]PyArchInit-Mini CLI[/bold blue]
|
|
56
|
+
Archaeological Data Management System
|
|
57
|
+
|
|
58
|
+
Gestione dati archeologici via interfaccia a riga di comando
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
self.console.print(Panel(welcome_text, title="Benvenuto", border_style="blue"))
|
|
62
|
+
|
|
63
|
+
def show_main_menu(self):
|
|
64
|
+
"""Show main menu and handle selection"""
|
|
65
|
+
while True:
|
|
66
|
+
self.console.print("\n" + "="*50)
|
|
67
|
+
self.console.print("[bold]MENU PRINCIPALE[/bold]")
|
|
68
|
+
self.console.print("="*50)
|
|
69
|
+
|
|
70
|
+
options = [
|
|
71
|
+
"1. 🏛️ Gestione Siti Archeologici",
|
|
72
|
+
"2. 📋 Gestione Unità Stratigrafiche (US)",
|
|
73
|
+
"3. 📦 Gestione Inventario Materiali",
|
|
74
|
+
"4. 🔗 Harris Matrix",
|
|
75
|
+
"5. 📊 Statistiche e Report",
|
|
76
|
+
"6. 📄 Export PDF",
|
|
77
|
+
"7. ⚙️ Configurazione Database",
|
|
78
|
+
"8. ❓ Aiuto",
|
|
79
|
+
"0. 🚪 Esci"
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
for option in options:
|
|
83
|
+
self.console.print(option)
|
|
84
|
+
|
|
85
|
+
choice = Prompt.ask("\nSeleziona un'opzione", choices=["0","1","2","3","4","5","6","7","8"])
|
|
86
|
+
|
|
87
|
+
if choice == "0":
|
|
88
|
+
self.console.print("[green]Arrivederci! 👋[/green]")
|
|
89
|
+
break
|
|
90
|
+
elif choice == "1":
|
|
91
|
+
self.sites_menu()
|
|
92
|
+
elif choice == "2":
|
|
93
|
+
self.us_menu()
|
|
94
|
+
elif choice == "3":
|
|
95
|
+
self.inventario_menu()
|
|
96
|
+
elif choice == "4":
|
|
97
|
+
self.harris_matrix_menu()
|
|
98
|
+
elif choice == "5":
|
|
99
|
+
self.statistics_menu()
|
|
100
|
+
elif choice == "6":
|
|
101
|
+
self.export_menu()
|
|
102
|
+
elif choice == "7":
|
|
103
|
+
self.database_menu()
|
|
104
|
+
elif choice == "8":
|
|
105
|
+
self.show_help()
|
|
106
|
+
|
|
107
|
+
def sites_menu(self):
|
|
108
|
+
"""Sites management menu"""
|
|
109
|
+
while True:
|
|
110
|
+
self.console.print("\n[bold blue]🏛️ GESTIONE SITI[/bold blue]")
|
|
111
|
+
|
|
112
|
+
options = [
|
|
113
|
+
"1. Lista Siti",
|
|
114
|
+
"2. Crea Nuovo Sito",
|
|
115
|
+
"3. Visualizza Sito",
|
|
116
|
+
"4. Modifica Sito",
|
|
117
|
+
"5. Elimina Sito",
|
|
118
|
+
"6. Cerca Siti",
|
|
119
|
+
"0. Torna al Menu Principale"
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
for option in options:
|
|
123
|
+
self.console.print(option)
|
|
124
|
+
|
|
125
|
+
choice = Prompt.ask("Seleziona", choices=["0","1","2","3","4","5","6"])
|
|
126
|
+
|
|
127
|
+
if choice == "0":
|
|
128
|
+
break
|
|
129
|
+
elif choice == "1":
|
|
130
|
+
self.list_sites()
|
|
131
|
+
elif choice == "2":
|
|
132
|
+
self.create_site()
|
|
133
|
+
elif choice == "3":
|
|
134
|
+
self.view_site()
|
|
135
|
+
elif choice == "4":
|
|
136
|
+
self.edit_site()
|
|
137
|
+
elif choice == "5":
|
|
138
|
+
self.delete_site()
|
|
139
|
+
elif choice == "6":
|
|
140
|
+
self.search_sites()
|
|
141
|
+
|
|
142
|
+
def list_sites(self):
|
|
143
|
+
"""List all sites"""
|
|
144
|
+
try:
|
|
145
|
+
sites = self.site_service.get_all_sites(size=50)
|
|
146
|
+
|
|
147
|
+
if not sites:
|
|
148
|
+
self.console.print("[yellow]Nessun sito trovato[/yellow]")
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
table = Table(title="Siti Archeologici")
|
|
152
|
+
table.add_column("ID", style="cyan")
|
|
153
|
+
table.add_column("Nome Sito", style="green")
|
|
154
|
+
table.add_column("Comune", style="blue")
|
|
155
|
+
table.add_column("Provincia", style="magenta")
|
|
156
|
+
table.add_column("Nazione", style="red")
|
|
157
|
+
|
|
158
|
+
for site in sites:
|
|
159
|
+
table.add_row(
|
|
160
|
+
str(site.id_sito),
|
|
161
|
+
site.sito,
|
|
162
|
+
site.comune or "-",
|
|
163
|
+
site.provincia or "-",
|
|
164
|
+
site.nazione or "-"
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
self.console.print(table)
|
|
168
|
+
|
|
169
|
+
except Exception as e:
|
|
170
|
+
self.console.print(f"[red]Errore: {e}[/red]")
|
|
171
|
+
|
|
172
|
+
def create_site(self):
|
|
173
|
+
"""Create new site"""
|
|
174
|
+
self.console.print("\n[bold]CREA NUOVO SITO[/bold]")
|
|
175
|
+
|
|
176
|
+
try:
|
|
177
|
+
site_data = {}
|
|
178
|
+
|
|
179
|
+
site_data['sito'] = Prompt.ask("Nome Sito")
|
|
180
|
+
site_data['nazione'] = Prompt.ask("Nazione", default="Italia")
|
|
181
|
+
site_data['regione'] = Prompt.ask("Regione", default="")
|
|
182
|
+
site_data['comune'] = Prompt.ask("Comune", default="")
|
|
183
|
+
site_data['provincia'] = Prompt.ask("Provincia", default="")
|
|
184
|
+
site_data['definizione_sito'] = Prompt.ask("Definizione Sito", default="")
|
|
185
|
+
site_data['descrizione'] = Prompt.ask("Descrizione", default="")
|
|
186
|
+
|
|
187
|
+
# Remove empty strings
|
|
188
|
+
site_data = {k: v for k, v in site_data.items() if v}
|
|
189
|
+
|
|
190
|
+
site = self.site_service.create_site(site_data)
|
|
191
|
+
self.console.print(f"[green]✅ Sito '{site_data['sito']}' creato con successo![/green]")
|
|
192
|
+
|
|
193
|
+
except Exception as e:
|
|
194
|
+
self.console.print(f"[red]Errore nella creazione: {e}[/red]")
|
|
195
|
+
|
|
196
|
+
def view_site(self):
|
|
197
|
+
"""View site details"""
|
|
198
|
+
try:
|
|
199
|
+
sites = self.site_service.get_all_sites(size=20)
|
|
200
|
+
if not sites:
|
|
201
|
+
self.console.print("[yellow]Nessun sito disponibile[/yellow]")
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
# Show sites list
|
|
205
|
+
self.console.print("\n[bold]SELEZIONA SITO[/bold]")
|
|
206
|
+
for i, site in enumerate(sites, 1):
|
|
207
|
+
self.console.print(f"{i}. {site.sito} ({site.comune})")
|
|
208
|
+
|
|
209
|
+
choice = Prompt.ask("Numero sito (0 per annullare)", default="0")
|
|
210
|
+
|
|
211
|
+
try:
|
|
212
|
+
site_idx = int(choice) - 1
|
|
213
|
+
if 0 <= site_idx < len(sites):
|
|
214
|
+
site = sites[site_idx]
|
|
215
|
+
|
|
216
|
+
# Show site details
|
|
217
|
+
info_text = f"""
|
|
218
|
+
[bold]Nome:[/bold] {site.sito}
|
|
219
|
+
[bold]Comune:[/bold] {site.comune or 'N/A'}
|
|
220
|
+
[bold]Provincia:[/bold] {site.provincia or 'N/A'}
|
|
221
|
+
[bold]Regione:[/bold] {site.regione or 'N/A'}
|
|
222
|
+
[bold]Nazione:[/bold] {site.nazione or 'N/A'}
|
|
223
|
+
[bold]Definizione:[/bold] {site.definizione_sito or 'N/A'}
|
|
224
|
+
[bold]Descrizione:[/bold] {site.descrizione or 'N/A'}
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
self.console.print(Panel(info_text, title=f"Dettagli Sito: {site.sito}"))
|
|
228
|
+
|
|
229
|
+
# Show related data counts
|
|
230
|
+
site_name = site.sito
|
|
231
|
+
us_count = self.us_service.count_us({'sito': site_name})
|
|
232
|
+
inv_count = self.inventario_service.count_inventario({'sito': site_name})
|
|
233
|
+
|
|
234
|
+
self.console.print(f"\n[blue]US associate: {us_count}[/blue]")
|
|
235
|
+
self.console.print(f"[blue]Reperti catalogati: {inv_count}[/blue]")
|
|
236
|
+
|
|
237
|
+
except (ValueError, IndexError):
|
|
238
|
+
self.console.print("[red]Selezione non valida[/red]")
|
|
239
|
+
|
|
240
|
+
except Exception as e:
|
|
241
|
+
self.console.print(f"[red]Errore: {e}[/red]")
|
|
242
|
+
|
|
243
|
+
def us_menu(self):
|
|
244
|
+
"""US management menu"""
|
|
245
|
+
while True:
|
|
246
|
+
self.console.print("\n[bold blue]📋 GESTIONE US[/bold blue]")
|
|
247
|
+
|
|
248
|
+
options = [
|
|
249
|
+
"1. Lista US",
|
|
250
|
+
"2. Crea Nuova US",
|
|
251
|
+
"3. Visualizza US",
|
|
252
|
+
"4. Lista US per Sito",
|
|
253
|
+
"0. Torna al Menu Principale"
|
|
254
|
+
]
|
|
255
|
+
|
|
256
|
+
for option in options:
|
|
257
|
+
self.console.print(option)
|
|
258
|
+
|
|
259
|
+
choice = Prompt.ask("Seleziona", choices=["0","1","2","3","4"])
|
|
260
|
+
|
|
261
|
+
if choice == "0":
|
|
262
|
+
break
|
|
263
|
+
elif choice == "1":
|
|
264
|
+
self.list_us()
|
|
265
|
+
elif choice == "2":
|
|
266
|
+
self.create_us()
|
|
267
|
+
elif choice == "3":
|
|
268
|
+
self.view_us()
|
|
269
|
+
elif choice == "4":
|
|
270
|
+
self.list_us_by_site()
|
|
271
|
+
|
|
272
|
+
def list_us(self):
|
|
273
|
+
"""List all US"""
|
|
274
|
+
try:
|
|
275
|
+
us_list = self.us_service.get_all_us(size=50)
|
|
276
|
+
|
|
277
|
+
if not us_list:
|
|
278
|
+
self.console.print("[yellow]Nessuna US trovata[/yellow]")
|
|
279
|
+
return
|
|
280
|
+
|
|
281
|
+
table = Table(title="Unità Stratigrafiche")
|
|
282
|
+
table.add_column("Sito", style="cyan")
|
|
283
|
+
table.add_column("Area", style="green")
|
|
284
|
+
table.add_column("US", style="blue", justify="right")
|
|
285
|
+
table.add_column("Descrizione", style="white")
|
|
286
|
+
table.add_column("Anno", style="magenta", justify="right")
|
|
287
|
+
|
|
288
|
+
for us in us_list:
|
|
289
|
+
table.add_row(
|
|
290
|
+
us.sito or "-",
|
|
291
|
+
us.area or "-",
|
|
292
|
+
str(us.us),
|
|
293
|
+
(us.d_stratigrafica or "")[:40] + "..." if len(us.d_stratigrafica or "") > 40 else (us.d_stratigrafica or "-"),
|
|
294
|
+
str(us.anno_scavo) if us.anno_scavo else "-"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
self.console.print(table)
|
|
298
|
+
|
|
299
|
+
except Exception as e:
|
|
300
|
+
self.console.print(f"[red]Errore: {e}[/red]")
|
|
301
|
+
|
|
302
|
+
def harris_matrix_menu(self):
|
|
303
|
+
"""Harris Matrix menu"""
|
|
304
|
+
while True:
|
|
305
|
+
self.console.print("\n[bold blue]🔗 HARRIS MATRIX[/bold blue]")
|
|
306
|
+
|
|
307
|
+
options = [
|
|
308
|
+
"1. Genera Matrix per Sito",
|
|
309
|
+
"2. Visualizza Matrix",
|
|
310
|
+
"3. Esporta Matrix",
|
|
311
|
+
"4. Statistiche Matrix",
|
|
312
|
+
"0. Torna al Menu Principale"
|
|
313
|
+
]
|
|
314
|
+
|
|
315
|
+
for option in options:
|
|
316
|
+
self.console.print(option)
|
|
317
|
+
|
|
318
|
+
choice = Prompt.ask("Seleziona", choices=["0","1","2","3","4"])
|
|
319
|
+
|
|
320
|
+
if choice == "0":
|
|
321
|
+
break
|
|
322
|
+
elif choice == "1":
|
|
323
|
+
self.generate_harris_matrix()
|
|
324
|
+
elif choice == "2":
|
|
325
|
+
self.view_harris_matrix()
|
|
326
|
+
elif choice == "3":
|
|
327
|
+
self.export_harris_matrix()
|
|
328
|
+
elif choice == "4":
|
|
329
|
+
self.harris_matrix_stats()
|
|
330
|
+
|
|
331
|
+
def generate_harris_matrix(self):
|
|
332
|
+
"""Generate Harris Matrix for a site"""
|
|
333
|
+
try:
|
|
334
|
+
# Get sites
|
|
335
|
+
sites = self.site_service.get_all_sites(size=20)
|
|
336
|
+
if not sites:
|
|
337
|
+
self.console.print("[yellow]Nessun sito disponibile[/yellow]")
|
|
338
|
+
return
|
|
339
|
+
|
|
340
|
+
# Select site
|
|
341
|
+
self.console.print("\n[bold]SELEZIONA SITO[/bold]")
|
|
342
|
+
for i, site in enumerate(sites, 1):
|
|
343
|
+
self.console.print(f"{i}. {site.sito}")
|
|
344
|
+
|
|
345
|
+
choice = Prompt.ask("Numero sito", default="0")
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
site_idx = int(choice) - 1
|
|
349
|
+
if 0 <= site_idx < len(sites):
|
|
350
|
+
site_name = sites[site_idx].sito
|
|
351
|
+
|
|
352
|
+
with self.console.status(f"[bold green]Generando Harris Matrix per {site_name}..."):
|
|
353
|
+
# Generate matrix
|
|
354
|
+
graph = self.matrix_generator.generate_matrix(site_name)
|
|
355
|
+
levels = self.matrix_generator.get_matrix_levels(graph)
|
|
356
|
+
stats = self.matrix_generator.get_matrix_statistics(graph)
|
|
357
|
+
|
|
358
|
+
# Show statistics
|
|
359
|
+
stats_text = f"""
|
|
360
|
+
[bold]Sito:[/bold] {site_name}
|
|
361
|
+
[bold]Totale US:[/bold] {stats['total_us']}
|
|
362
|
+
[bold]Relazioni:[/bold] {stats['total_relationships']}
|
|
363
|
+
[bold]Livelli:[/bold] {stats['levels']}
|
|
364
|
+
[bold]Matrix Valida:[/bold] {'Sì' if stats['is_valid'] else 'No'}
|
|
365
|
+
[bold]US Isolate:[/bold] {stats['isolated_us']}
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
self.console.print(Panel(stats_text, title="Statistiche Harris Matrix"))
|
|
369
|
+
|
|
370
|
+
# Show levels
|
|
371
|
+
if levels:
|
|
372
|
+
self.console.print("\n[bold]LIVELLI STRATIGRAFICI:[/bold]")
|
|
373
|
+
for level, us_list in levels.items():
|
|
374
|
+
self.console.print(f"Livello {level}: US {', '.join(map(str, us_list))}")
|
|
375
|
+
|
|
376
|
+
# Ask for export
|
|
377
|
+
if Confirm.ask("Vuoi esportare la matrix?"):
|
|
378
|
+
filename = f"harris_matrix_{site_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
|
379
|
+
|
|
380
|
+
with self.console.status("[bold green]Esportando matrix..."):
|
|
381
|
+
exports = self.matrix_visualizer.export_to_formats(graph, levels, filename)
|
|
382
|
+
|
|
383
|
+
self.console.print(f"[green]✅ Matrix esportata in: {', '.join(exports.keys())}[/green]")
|
|
384
|
+
for format_type, path in exports.items():
|
|
385
|
+
self.console.print(f" {format_type}: {path}")
|
|
386
|
+
|
|
387
|
+
except (ValueError, IndexError):
|
|
388
|
+
self.console.print("[red]Selezione non valida[/red]")
|
|
389
|
+
|
|
390
|
+
except Exception as e:
|
|
391
|
+
self.console.print(f"[red]Errore: {e}[/red]")
|
|
392
|
+
|
|
393
|
+
def statistics_menu(self):
|
|
394
|
+
"""Statistics and reports menu"""
|
|
395
|
+
self.console.print("\n[bold blue]📊 STATISTICHE[/bold blue]")
|
|
396
|
+
|
|
397
|
+
try:
|
|
398
|
+
# Get basic statistics
|
|
399
|
+
total_sites = self.site_service.count_sites()
|
|
400
|
+
total_us = self.us_service.count_us()
|
|
401
|
+
total_inventory = self.inventario_service.count_inventario()
|
|
402
|
+
|
|
403
|
+
stats_text = f"""
|
|
404
|
+
[bold]STATISTICHE GENERALI[/bold]
|
|
405
|
+
|
|
406
|
+
🏛️ [bold]Siti Archeologici:[/bold] {total_sites}
|
|
407
|
+
📋 [bold]Unità Stratigrafiche:[/bold] {total_us}
|
|
408
|
+
📦 [bold]Reperti Catalogati:[/bold] {total_inventory}
|
|
409
|
+
|
|
410
|
+
[bold]DATABASE:[/bold] {self.db_conn.connection_string.split('://')[0].upper()}
|
|
411
|
+
[bold]DATA AGGIORNAMENTO:[/bold] {datetime.now().strftime('%d/%m/%Y %H:%M')}
|
|
412
|
+
"""
|
|
413
|
+
|
|
414
|
+
self.console.print(Panel(stats_text, title="Dashboard Statistiche"))
|
|
415
|
+
|
|
416
|
+
# Site statistics
|
|
417
|
+
if total_sites > 0:
|
|
418
|
+
sites = self.site_service.get_all_sites(size=10)
|
|
419
|
+
|
|
420
|
+
table = Table(title="Statistiche per Sito")
|
|
421
|
+
table.add_column("Sito", style="cyan")
|
|
422
|
+
table.add_column("US", style="blue", justify="right")
|
|
423
|
+
table.add_column("Reperti", style="green", justify="right")
|
|
424
|
+
|
|
425
|
+
for site in sites:
|
|
426
|
+
site_name = site.sito
|
|
427
|
+
us_count = self.us_service.count_us({'sito': site_name})
|
|
428
|
+
inv_count = self.inventario_service.count_inventario({'sito': site_name})
|
|
429
|
+
|
|
430
|
+
table.add_row(site_name, str(us_count), str(inv_count))
|
|
431
|
+
|
|
432
|
+
self.console.print(table)
|
|
433
|
+
|
|
434
|
+
except Exception as e:
|
|
435
|
+
self.console.print(f"[red]Errore: {e}[/red]")
|
|
436
|
+
|
|
437
|
+
def show_help(self):
|
|
438
|
+
"""Show help information"""
|
|
439
|
+
help_text = """
|
|
440
|
+
[bold blue]AIUTO PYARCHINIT-MINI CLI[/bold blue]
|
|
441
|
+
|
|
442
|
+
[bold]COMANDI PRINCIPALI:[/bold]
|
|
443
|
+
• Gestione Siti: Crea, visualizza, modifica siti archeologici
|
|
444
|
+
• Gestione US: Gestisci unità stratigrafiche
|
|
445
|
+
• Inventario: Cataloga e gestisci reperti
|
|
446
|
+
• Harris Matrix: Genera matrici stratigrafiche
|
|
447
|
+
• Statistiche: Visualizza report e statistiche
|
|
448
|
+
• Export: Esporta dati in PDF
|
|
449
|
+
|
|
450
|
+
[bold]NAVIGAZIONE:[/bold]
|
|
451
|
+
• Usa i numeri per selezionare le opzioni
|
|
452
|
+
• Premi 0 per tornare al menu precedente
|
|
453
|
+
• Premi Ctrl+C per uscire in qualsiasi momento
|
|
454
|
+
|
|
455
|
+
[bold]DATABASE:[/bold]
|
|
456
|
+
La CLI si connette automaticamente al database configurato.
|
|
457
|
+
Usa la variabile d'ambiente DATABASE_URL per configurare la connessione.
|
|
458
|
+
|
|
459
|
+
[bold]ESEMPI:[/bold]
|
|
460
|
+
export DATABASE_URL="postgresql://user:pass@localhost/pyarchinit"
|
|
461
|
+
export DATABASE_URL="sqlite:///./mio_database.db"
|
|
462
|
+
|
|
463
|
+
[bold]SUPPORTO:[/bold]
|
|
464
|
+
GitHub: https://github.com/pyarchinit/pyarchinit-mini
|
|
465
|
+
Email: enzo.ccc@gmail.com
|
|
466
|
+
"""
|
|
467
|
+
|
|
468
|
+
self.console.print(Panel(help_text, title="Aiuto"))
|
|
469
|
+
|
|
470
|
+
def run(self):
|
|
471
|
+
"""Run the CLI application"""
|
|
472
|
+
try:
|
|
473
|
+
self.show_welcome()
|
|
474
|
+
self.show_main_menu()
|
|
475
|
+
except KeyboardInterrupt:
|
|
476
|
+
self.console.print("\n[yellow]Operazione interrotta dall'utente[/yellow]")
|
|
477
|
+
except Exception as e:
|
|
478
|
+
self.console.print(f"\n[red]Errore imprevisto: {e}[/red]")
|
|
479
|
+
finally:
|
|
480
|
+
self.db_conn.close()
|
|
481
|
+
|
|
482
|
+
@click.command()
|
|
483
|
+
@click.option('--database-url', '-d', help='Database URL connection string')
|
|
484
|
+
@click.option('--version', is_flag=True, help='Show version information')
|
|
485
|
+
def main(database_url, version):
|
|
486
|
+
"""PyArchInit-Mini Interactive CLI"""
|
|
487
|
+
|
|
488
|
+
if version:
|
|
489
|
+
console.print("[bold blue]PyArchInit-Mini CLI v0.1.0[/bold blue]")
|
|
490
|
+
console.print("Archaeological Data Management System")
|
|
491
|
+
return
|
|
492
|
+
|
|
493
|
+
cli = PyArchInitCLI(database_url)
|
|
494
|
+
cli.run()
|
|
495
|
+
|
|
496
|
+
if __name__ == '__main__':
|
|
497
|
+
main()
|
desktop_gui/__init__.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Desktop GUI package for PyArchInit-Mini
|
|
3
|
+
|
|
4
|
+
This package provides a complete Tkinter-based desktop interface for
|
|
5
|
+
archaeological data management including:
|
|
6
|
+
|
|
7
|
+
- Site management
|
|
8
|
+
- Stratigraphic units (US) management
|
|
9
|
+
- Inventory management
|
|
10
|
+
- Harris Matrix generation and visualization
|
|
11
|
+
- PDF export capabilities
|
|
12
|
+
- Media file management
|
|
13
|
+
- Statistics and reporting
|
|
14
|
+
|
|
15
|
+
Main Components:
|
|
16
|
+
- main_window.py: Main application window with tabs and navigation
|
|
17
|
+
- dialogs.py: Dialog classes for data entry and specialized functions
|
|
18
|
+
- gui_app.py: Application launcher and dependency checker
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
from desktop_gui.gui_app import main
|
|
22
|
+
main()
|
|
23
|
+
|
|
24
|
+
Or run directly:
|
|
25
|
+
python desktop_gui/gui_app.py
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
__version__ = "0.1.0"
|
|
29
|
+
__author__ = "PyArchInit Team"
|
|
30
|
+
|
|
31
|
+
# Import main classes for easier access
|
|
32
|
+
from .main_window import PyArchInitGUI
|
|
33
|
+
from .dialogs import (
|
|
34
|
+
SiteDialog,
|
|
35
|
+
USDialog,
|
|
36
|
+
InventarioDialog,
|
|
37
|
+
HarrisMatrixDialog,
|
|
38
|
+
PDFExportDialog,
|
|
39
|
+
MediaManagerDialog,
|
|
40
|
+
StatisticsDialog
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
'PyArchInitGUI',
|
|
45
|
+
'SiteDialog',
|
|
46
|
+
'USDialog',
|
|
47
|
+
'InventarioDialog',
|
|
48
|
+
'HarrisMatrixDialog',
|
|
49
|
+
'PDFExportDialog',
|
|
50
|
+
'MediaManagerDialog',
|
|
51
|
+
'StatisticsDialog'
|
|
52
|
+
]
|