Really-amin commited on
Commit
5ccfb05
·
verified ·
1 Parent(s): 18830d1

Create setup.py

Browse files
Files changed (1) hide show
  1. setup.py +776 -0
setup.py ADDED
@@ -0,0 +1,776 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Complete Setup Script for Iran Legal Dashboard
4
+ ==============================================
5
+ Enhanced setup with dependency management, environment setup, and comprehensive initialization
6
+ """
7
+
8
+ import sqlite3
9
+ import json
10
+ import os
11
+ import sys
12
+ import logging
13
+ import subprocess
14
+ import shutil
15
+ from datetime import datetime
16
+ from typing import Dict, List, Optional
17
+ from pathlib import Path
18
+
19
+ # Configure logging
20
+ logging.basicConfig(
21
+ level=logging.INFO,
22
+ format='%(asctime)s - %(levelname)s - %(message)s',
23
+ handlers=[
24
+ logging.FileHandler('setup.log'),
25
+ logging.StreamHandler(sys.stdout)
26
+ ]
27
+ )
28
+ logger = logging.getLogger(__name__)
29
+
30
+ class SetupManager:
31
+ """Complete setup manager for the Iran Legal Dashboard"""
32
+
33
+ def __init__(self):
34
+ self.project_root = Path.cwd()
35
+ self.data_dir = self.project_root / "data"
36
+ self.logs_dir = self.project_root / "logs"
37
+ self.temp_dir = self.project_root / "temp"
38
+ self.config_file = self.project_root / "config.json"
39
+
40
+ def run_complete_setup(self):
41
+ """Run the complete setup process"""
42
+ logger.info("🚀 Starting Iran Legal Dashboard Complete Setup...")
43
+
44
+ try:
45
+ # Step 1: Check system requirements
46
+ if not self.check_system_requirements():
47
+ return False
48
+
49
+ # Step 2: Check and install dependencies
50
+ if not self.setup_dependencies():
51
+ return False
52
+
53
+ # Step 3: Create directory structure
54
+ self.create_directory_structure()
55
+
56
+ # Step 4: Create configuration
57
+ self.create_configuration()
58
+
59
+ # Step 5: Initialize database
60
+ if not self.setup_database():
61
+ return False
62
+
63
+ # Step 6: Create sample data
64
+ self.create_sample_data()
65
+
66
+ # Step 7: Setup environment files
67
+ self.create_environment_files()
68
+
69
+ # Step 8: Verify installation
70
+ if not self.verify_installation():
71
+ return False
72
+
73
+ # Step 9: Create launcher scripts
74
+ self.create_launcher_scripts()
75
+
76
+ logger.info("✅ Setup completed successfully!")
77
+ self.show_final_instructions()
78
+ return True
79
+
80
+ except Exception as e:
81
+ logger.error(f"❌ Setup failed: {e}")
82
+ return False
83
+
84
+ def check_system_requirements(self) -> bool:
85
+ """Check system requirements"""
86
+ logger.info("🔍 Checking system requirements...")
87
+
88
+ # Check Python version
89
+ python_version = sys.version_info
90
+ if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 7):
91
+ logger.error("❌ Python 3.7+ is required")
92
+ return False
93
+
94
+ logger.info(f"✅ Python {python_version.major}.{python_version.minor}.{python_version.micro}")
95
+
96
+ # Check available disk space (at least 100MB)
97
+ try:
98
+ free_space = shutil.disk_usage('.').free / (1024 * 1024) # MB
99
+ if free_space < 100:
100
+ logger.warning(f"⚠️ Low disk space: {free_space:.1f}MB available")
101
+ else:
102
+ logger.info(f"✅ Disk space: {free_space:.1f}MB available")
103
+ except Exception as e:
104
+ logger.warning(f"⚠️ Could not check disk space: {e}")
105
+
106
+ # Check write permissions
107
+ try:
108
+ test_file = self.project_root / "test_write.tmp"
109
+ test_file.write_text("test")
110
+ test_file.unlink()
111
+ logger.info("✅ Write permissions OK")
112
+ except Exception as e:
113
+ logger.error(f"❌ No write permissions: {e}")
114
+ return False
115
+
116
+ return True
117
+
118
+ def setup_dependencies(self) -> bool:
119
+ """Check and install Python dependencies"""
120
+ logger.info("📦 Setting up dependencies...")
121
+
122
+ required_packages = {
123
+ 'streamlit': '>=1.28.0',
124
+ 'pandas': '>=1.5.0',
125
+ 'plotly': '>=5.0.0',
126
+ 'requests': '>=2.25.0',
127
+ 'beautifulsoup4': '>=4.9.0',
128
+ 'Pillow': '>=8.0.0',
129
+ 'python-dateutil': '>=2.8.0'
130
+ }
131
+
132
+ missing_packages = []
133
+
134
+ for package, version in required_packages.items():
135
+ try:
136
+ if package == 'beautifulsoup4':
137
+ import bs4
138
+ logger.info(f"✅ {package} is available")
139
+ elif package == 'Pillow':
140
+ import PIL
141
+ logger.info(f"✅ {package} is available")
142
+ elif package == 'python-dateutil':
143
+ import dateutil
144
+ logger.info(f"✅ {package} is available")
145
+ else:
146
+ __import__(package)
147
+ logger.info(f"✅ {package} is available")
148
+ except ImportError:
149
+ missing_packages.append(f"{package}{version}")
150
+ logger.warning(f"⚠️ {package} is missing")
151
+
152
+ if missing_packages:
153
+ logger.info("📥 Installing missing packages...")
154
+
155
+ # Create requirements.txt
156
+ requirements_content = "\n".join(missing_packages)
157
+ requirements_file = self.project_root / "requirements.txt"
158
+ requirements_file.write_text(requirements_content)
159
+
160
+ try:
161
+ # Try to install packages
162
+ subprocess.check_call([
163
+ sys.executable, "-m", "pip", "install", "-r", str(requirements_file)
164
+ ])
165
+ logger.info("✅ Dependencies installed successfully")
166
+ except subprocess.CalledProcessError as e:
167
+ logger.error(f"❌ Failed to install dependencies: {e}")
168
+ logger.info("Please run: pip install -r requirements.txt")
169
+ return False
170
+
171
+ return True
172
+
173
+ def create_directory_structure(self):
174
+ """Create necessary directories"""
175
+ logger.info("📁 Creating directory structure...")
176
+
177
+ directories = [
178
+ self.data_dir,
179
+ self.logs_dir,
180
+ self.temp_dir,
181
+ self.project_root / "assets",
182
+ self.project_root / "backups",
183
+ self.project_root / "exports"
184
+ ]
185
+
186
+ for directory in directories:
187
+ try:
188
+ directory.mkdir(exist_ok=True)
189
+ logger.info(f"✅ Created/verified directory: {directory}")
190
+ except Exception as e:
191
+ logger.error(f"❌ Failed to create directory {directory}: {e}")
192
+
193
+ def create_configuration(self):
194
+ """Create configuration file"""
195
+ logger.info("⚙️ Creating configuration...")
196
+
197
+ config = {
198
+ "app": {
199
+ "name": "Iran Legal Information Dashboard",
200
+ "version": "1.0.0",
201
+ "description": "Legal document management and analysis system",
202
+ "created": datetime.now().isoformat()
203
+ },
204
+ "database": {
205
+ "type": "sqlite",
206
+ "path": str(self.data_dir / "iran_legal.db"),
207
+ "backup_interval": "daily",
208
+ "max_backups": 7
209
+ },
210
+ "ai": {
211
+ "enabled": True,
212
+ "min_score_threshold": 0.3,
213
+ "keyword_extraction_limit": 10
214
+ },
215
+ "scraping": {
216
+ "enabled": True,
217
+ "default_timeout": 15,
218
+ "max_concurrent": 5,
219
+ "delay_between_requests": 1,
220
+ "trusted_domains": [
221
+ "dastour.ir",
222
+ "mizanonline.ir",
223
+ "judiciary.ir",
224
+ "majlis.ir",
225
+ "rc.majlis.ir"
226
+ ]
227
+ },
228
+ "ui": {
229
+ "language": "fa",
230
+ "theme": "modern",
231
+ "items_per_page": 20,
232
+ "enable_animations": True
233
+ },
234
+ "security": {
235
+ "enable_logging": True,
236
+ "max_upload_size": "10MB",
237
+ "allowed_file_types": ["pdf", "txt", "docx"]
238
+ },
239
+ "paths": {
240
+ "data": str(self.data_dir),
241
+ "logs": str(self.logs_dir),
242
+ "temp": str(self.temp_dir),
243
+ "backups": str(self.project_root / "backups"),
244
+ "exports": str(self.project_root / "exports")
245
+ }
246
+ }
247
+
248
+ try:
249
+ with open(self.config_file, 'w', encoding='utf-8') as f:
250
+ json.dump(config, f, indent=2, ensure_ascii=False)
251
+ logger.info(f"✅ Configuration created: {self.config_file}")
252
+ except Exception as e:
253
+ logger.error(f"❌ Failed to create configuration: {e}")
254
+
255
+ def setup_database(self) -> bool:
256
+ """Initialize database with tables and sample data"""
257
+ logger.info("🗄️ Setting up database...")
258
+
259
+ db_path = self.data_dir / "iran_legal.db"
260
+
261
+ try:
262
+ with sqlite3.connect(str(db_path)) as conn:
263
+ # Enable WAL mode and foreign keys
264
+ conn.execute("PRAGMA journal_mode=WAL;")
265
+ conn.execute("PRAGMA foreign_keys = ON;")
266
+
267
+ # Create tables
268
+ self._create_database_tables(conn)
269
+
270
+ # Add sample data
271
+ self._add_sample_data(conn)
272
+
273
+ logger.info(f"✅ Database initialized: {db_path}")
274
+ return True
275
+
276
+ except Exception as e:
277
+ logger.error(f"❌ Database setup failed: {e}")
278
+ return False
279
+
280
+ def _create_database_tables(self, conn: sqlite3.Connection):
281
+ """Create database tables"""
282
+
283
+ # Documents table
284
+ conn.execute("""
285
+ CREATE TABLE IF NOT EXISTS documents (
286
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
287
+ title TEXT NOT NULL,
288
+ content TEXT NOT NULL,
289
+ source TEXT,
290
+ category TEXT,
291
+ ai_score REAL DEFAULT 0.0,
292
+ keywords TEXT,
293
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
294
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
295
+ file_size INTEGER DEFAULT 0,
296
+ language TEXT DEFAULT 'fa',
297
+ status TEXT DEFAULT 'active'
298
+ )
299
+ """)
300
+
301
+ # Scraped items table
302
+ conn.execute("""
303
+ CREATE TABLE IF NOT EXISTS scraped_items (
304
+ id TEXT PRIMARY KEY,
305
+ url TEXT NOT NULL UNIQUE,
306
+ title TEXT,
307
+ content TEXT,
308
+ domain TEXT,
309
+ rating_score REAL DEFAULT 0.0,
310
+ word_count INTEGER DEFAULT 0,
311
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
312
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
313
+ status TEXT DEFAULT 'completed',
314
+ last_scraped TIMESTAMP DEFAULT CURRENT_TIMESTAMP
315
+ )
316
+ """)
317
+
318
+ # System logs table
319
+ conn.execute("""
320
+ CREATE TABLE IF NOT EXISTS system_logs (
321
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
322
+ timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
323
+ level TEXT NOT NULL,
324
+ component TEXT,
325
+ message TEXT NOT NULL,
326
+ details TEXT
327
+ )
328
+ """)
329
+
330
+ # User sessions table (for future multi-user support)
331
+ conn.execute("""
332
+ CREATE TABLE IF NOT EXISTS user_sessions (
333
+ id TEXT PRIMARY KEY,
334
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
335
+ last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
336
+ ip_address TEXT,
337
+ user_agent TEXT,
338
+ active BOOLEAN DEFAULT 1
339
+ )
340
+ """)
341
+
342
+ # Performance indexes
343
+ indexes = [
344
+ "CREATE INDEX IF NOT EXISTS idx_documents_category ON documents(category);",
345
+ "CREATE INDEX IF NOT EXISTS idx_documents_ai_score ON documents(ai_score);",
346
+ "CREATE INDEX IF NOT EXISTS idx_documents_created_at ON documents(created_at);",
347
+ "CREATE INDEX IF NOT EXISTS idx_scraped_domain ON scraped_items(domain);",
348
+ "CREATE INDEX IF NOT EXISTS idx_scraped_rating ON scraped_items(rating_score);",
349
+ "CREATE INDEX IF NOT EXISTS idx_scraped_created_at ON scraped_items(created_at);",
350
+ "CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON system_logs(timestamp);",
351
+ "CREATE INDEX IF NOT EXISTS idx_logs_level ON system_logs(level);"
352
+ ]
353
+
354
+ for index in indexes:
355
+ conn.execute(index)
356
+
357
+ conn.commit()
358
+ logger.info("✅ Database tables created")
359
+
360
+ def _add_sample_data(self, conn: sqlite3.Connection):
361
+ """Add comprehensive sample data"""
362
+
363
+ # Sample documents
364
+ sample_documents = [
365
+ {
366
+ 'title': 'قانون اساسی جمهوری اسلامی ایران - فصل اول',
367
+ 'content': '''فصل اول - اصول کلی
368
+
369
+ اصل یکم: حکومت ایران، جمهوری اسلامی است که ملت ایران بر اساس ایمان دیرینه‌اش به حاکمیت حق و عدالت قرآن، در انقلاب اسلامی سال ۱۳۵۷ تحت رهبری امام خمینی به آن رأی مثبت داد.
370
+
371
+ اصل دوم: جمهوری اسلامی، نظامی است مبتنی بر ایمان به خدای یکتا، حاکمیت و قانون الهی، عدل، ایمان و تقوا، و در حکومت، دین مبین اسلام مذهب جعفری اثنی عشری.
372
+
373
+ اصل سوم: برای نیل به اهداف مندرج در اصل دوم، دولت جمهوری اسلامی ایران موظف است تمام امکانات خود را برای دستیابی به مقاصد ذیل به کار گیرد:
374
+ ۱- ایجاد محیط مساعد برای رشد فضایل اخلاقی بر پایه ایمان و تقوا و مبارزه با تمام مظاهر فساد و تباهی
375
+ ۲- ارتقاء سطح آگاهی عمومی در همه زمینه‌ها با بهره‌گیری درست از مطبوعات، رسانه‌های گروهی و سایر وسایل
376
+ ۳- آموزش و پرورش و تربیت بدنی رایگان برای همه در همه سطوح و تسهیل و تعمیم آموزش عالی''',
377
+ 'source': 'قانون اساسی ج.ا.ایران',
378
+ 'category': 'قانون',
379
+ 'ai_score': 0.95,
380
+ 'keywords': json.dumps(['قانون اساسی', 'جمهوری اسلامی', 'حاکمیت', 'عدالت', 'اسلام']),
381
+ 'file_size': 2450,
382
+ 'language': 'fa'
383
+ },
384
+ {
385
+ 'title': 'قانون مجازات اسلامی - احکام عمومی',
386
+ 'content': '''باب اول - احکام عمومی
387
+
388
+ ماده ۱- مجازات‌ها به اعتبار کیفیت به سه دسته تقسیم می‌شوند:
389
+ الف) حدود
390
+ ب) قصاص
391
+ ج) تعزیرات
392
+
393
+ ماده ۲- حدود عبارت است از مجازات‌هایی که نوع و میزان آنها در شرع مقدس تعیین شده و حق العبد محسوب نمی‌شود.
394
+
395
+ ماده ۳- قصاص عبارت است از مجازاتی که در شرع مقدس تعیین شده و حق العبد محسوب می‌شود.
396
+
397
+ ماده ۴- تعزیرات عبارت است از مجازات‌هایی غیر از حدود و قصاص که برای تأدیب مرتکب یا جلوگیری از تکرار جرم یا ارتداع دیگران تعیین می‌شود.
398
+
399
+ ماده ۵- هرگاه برای یک عمل مجرمانه، مجازات حد یا قصاص و نیز تعزیر تعیین شده باشد، مجازات حد یا قصاص مانع از اجرای تعزیر نیست مگر آنکه قانون طور دیگری مقرر داشته باشد.''',
400
+ 'source': 'قانون مجازات اسلامی',
401
+ 'category': 'قانون',
402
+ 'ai_score': 0.88,
403
+ 'keywords': json.dumps(['مجازات', 'حدود', 'قصاص', 'تعزیرات', 'شرع']),
404
+ 'file_size': 1850,
405
+ 'language': 'fa'
406
+ },
407
+ {
408
+ 'title': 'قانون مدنی - قراردادها',
409
+ 'content': '''فصل اول - احکام عمومی قراردادها
410
+
411
+ ماده ۱۰- قراردادها برای متعاقدینی که آنها را منعقد نمده‌اند لازم‌الاجرا و قابل فسخ نیست مگر به رضایت طرفین یا در مواردی که قانون تجویز کرده است.
412
+
413
+ ماده ۱۱- در قراردادها نه تنها به الفاظ بلکه به قصد و نیت طرفین نیز اعتبار است.
414
+
415
+ ماده ۱۲- مجهول‌بودن مبیع یا ثمن مانع از صحت بیع است مگر آنکه مجهول بودن آن خفیف و متعارف باشد.
416
+
417
+ ماده ۱۳- در عقود و ایقاعات، عبرت به قصد و معنی است نه به الفاظ.
418
+
419
+ ماده ۱۴- تصرف در مال غیر بدون اذن مالک موجب ضمان است.''',
420
+ 'source': 'قانون مدنی',
421
+ 'category': 'قرارداد',
422
+ 'ai_score': 0.82,
423
+ 'keywords': json.dumps(['قرارداد', 'متعاقدین', 'بیع', 'ثمن', 'مبیع']),
424
+ 'file_size': 1620,
425
+ 'language': 'fa'
426
+ },
427
+ {
428
+ 'title': 'قانون آیین دادرسی کیفری - کلیات',
429
+ 'content': '''باب اول - کلیات
430
+
431
+ ماده ۱- این قانون آیین تعقیب و محاکمه جرایم و اجرای احکام کیفری را تعیین می‌کند.
432
+
433
+ ماده ۲- دادرسی کیفری بر اساس احترام به کرامت انسانی، حفظ حقوق فردی و اجتماعی، حق دفاع، برائت ذمه، آزادی و امنیت اشخاص استوار است.
434
+
435
+ ماده ۳- هیچ کس را نمی‌توان بدون حکم مقام قضایی ذی‌صلاح دستگیر، بازداشت یا زندانی کرد.
436
+
437
+ ماده ۴- متهم حق دارد در تمام مراحل دادرسی وکیل انتخاب کند.
438
+
439
+ ماده ۵- تفتیش مسکن، محل کسب و کار، وسایل نقلیه یا اماکن دیگر جز در موارد مستثنی قانونی منوط به حکم مقام قضایی است.''',
440
+ 'source': 'قانون آیین دادرسی کیفری',
441
+ 'category': 'حکم',
442
+ 'ai_score': 0.90,
443
+ 'keywords': json.dumps(['دادرسی', 'کیفری', 'متهم', 'دادگاه', 'قاضی']),
444
+ 'file_size': 2100,
445
+ 'language': 'fa'
446
+ }
447
+ ]
448
+
449
+ # Insert sample documents
450
+ for doc in sample_documents:
451
+ conn.execute("""
452
+ INSERT INTO documents (title, content, source, category, ai_score, keywords, file_size, language)
453
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
454
+ """, (
455
+ doc['title'], doc['content'], doc['source'], doc['category'],
456
+ doc['ai_score'], doc['keywords'], doc['file_size'], doc['language']
457
+ ))
458
+
459
+ # Sample scraped items
460
+ sample_scraped = [
461
+ {
462
+ 'id': 'sample_dastour_001',
463
+ 'url': 'https://dastour.ir/bakhshodare/ghanoon-asasi',
464
+ 'title': 'متن کامل قانون اساسی جمهوری اسلامی ایران',
465
+ 'content': 'قانون اساسی جمهوری اسلامی ایران که در سال ۱۳۵۸ تصویب و در سال ۱۳۶۸ بازنگری شد، مشتمل بر ۱۷۷ اصل است که در ۱۴ فصل تنظیم شده است. این قانون بنیادی‌ترین و مهم‌ترین قانون کشور محسوب می‌شود.',
466
+ 'domain': 'dastour.ir',
467
+ 'rating_score': 0.95,
468
+ 'word_count': 15420,
469
+ 'status': 'completed'
470
+ },
471
+ {
472
+ 'id': 'sample_mizan_001',
473
+ 'url': 'https://mizanonline.ir/fa/news/legal-reforms-2024',
474
+ 'title': 'اصلاحات جدید در نظام حقوقی کشور - ۱۴۰۳',
475
+ 'content': 'در راستای بهبود نظام حقوقی کشور و همسو شدن با تحولات جهانی، مجموعه‌ای از اصلاحات قانونی در دست بررسی قرار گرفته که شامل تغییرات در قوانین مدنی، جزایی و اداری می‌شود. این اصلاحات با هدف تسریع روند دادرسی و حفظ حقوق شهروندان طراحی شده‌اند.',
476
+ 'domain': 'mizanonline.ir',
477
+ 'rating_score': 0.78,
478
+ 'word_count': 852,
479
+ 'status': 'completed'
480
+ },
481
+ {
482
+ 'id': 'sample_judiciary_001',
483
+ 'url': 'https://judiciary.ir/news/supreme-court-decisions-2024',
484
+ 'title': 'آرای مهم دیوان عالی کشور در سال ۱۴۰۳',
485
+ 'content': 'دیوان عالی کشور در سال جاری مجموعه‌ای از آرای مهم و تأثیرگذار در خصوص تفسیر قوانین مختلف صادر کرده که نقش به‌سزایی در وحدت رویه قضایی و شفاف‌سازی مسائل حقوقی خواهد داشت. این آرا شامل موضوعات مدنی، کیفری و اداری می‌شود.',
486
+ 'domain': 'judiciary.ir',
487
+ 'rating_score': 0.87,
488
+ 'word_count': 1240,
489
+ 'status': 'completed'
490
+ }
491
+ ]
492
+
493
+ # Insert sample scraped items
494
+ for item in sample_scraped:
495
+ conn.execute("""
496
+ INSERT INTO scraped_items (id, url, title, content, domain, rating_score, word_count, status)
497
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
498
+ """, (
499
+ item['id'], item['url'], item['title'], item['content'],
500
+ item['domain'], item['rating_score'], item['word_count'], item['status']
501
+ ))
502
+
503
+ # Add system log entry
504
+ conn.execute("""
505
+ INSERT INTO system_logs (level, component, message, details)
506
+ VALUES (?, ?, ?, ?)
507
+ """, ('INFO', 'setup', 'Database initialized with sample data',
508
+ json.dumps({'documents': len(sample_documents), 'scraped_items': len(sample_scraped)})))
509
+
510
+ conn.commit()
511
+ logger.info(f"✅ Added {len(sample_documents)} sample documents and {len(sample_scraped)} scraped items")
512
+
513
+ def create_sample_data(self):
514
+ """Create additional sample data files"""
515
+ logger.info("📝 Creating sample data files...")
516
+
517
+ # Create sample upload file
518
+ sample_text = """نمونه متن حقوقی
519
+
520
+ این یک نمونه متن حقوقی است که می‌توانید برای تست سیستم استفاده کنید.
521
+
522
+ ماده ۱- این متن به عنوان نمونه تهیه شده است.
523
+ ماده ۲- محتوای این متن صرفاً جنبه آموزشی دارد.
524
+
525
+ تبصره: این متن قابلیت آپلود و تحلیل توسط سیستم هوش مصنوعی را دارد.
526
+ """
527
+
528
+ sample_file = self.temp_dir / "sample_legal_text.txt"
529
+ sample_file.write_text(sample_text, encoding='utf-8')
530
+ logger.info(f"✅ Sample file created: {sample_file}")
531
+
532
+ def create_environment_files(self):
533
+ """Create environment and configuration files"""
534
+ logger.info("🔧 Creating environment files...")
535
+
536
+ # Create .streamlit directory and config
537
+ streamlit_dir = self.project_root / ".streamlit"
538
+ streamlit_dir.mkdir(exist_ok=True)
539
+
540
+ # Streamlit config
541
+ streamlit_config = """[theme]
542
+ primaryColor = "#667eea"
543
+ backgroundColor = "#ffffff"
544
+ secondaryBackgroundColor = "#f0f2f6"
545
+ textColor = "#262730"
546
+ font = "sans serif"
547
+
548
+ [server]
549
+ headless = true
550
+ port = 8501
551
+ enableCORS = false
552
+ enableXsrfProtection = false
553
+
554
+ [browser]
555
+ gatherUsageStats = false
556
+ """
557
+
558
+ (streamlit_dir / "config.toml").write_text(streamlit_config)
559
+
560
+ # Create .env file
561
+ env_content = """# Iran Legal Dashboard Environment Variables
562
+
563
+ # Application Settings
564
+ APP_NAME="Iran Legal Information Dashboard"
565
+ APP_VERSION="1.0.0"
566
+ DEBUG=false
567
+
568
+ # Database Settings
569
+ DATABASE_PATH="./data/iran_legal.db"
570
+ DATABASE_BACKUP_ENABLED=true
571
+
572
+ # Security Settings
573
+ SECRET_KEY="your-secret-key-here"
574
+ MAX_UPLOAD_SIZE=10485760
575
+
576
+ # Feature Flags
577
+ ENABLE_AI_ANALYSIS=true
578
+ ENABLE_WEB_SCRAPING=true
579
+ ENABLE_LOGGING=true
580
+
581
+ # External Services (if needed)
582
+ # API_KEY=""
583
+ # EXTERNAL_SERVICE_URL=""
584
+ """
585
+
586
+ env_file = self.project_root / ".env"
587
+ env_file.write_text(env_content)
588
+
589
+ logger.info("✅ Environment files created")
590
+
591
+ def verify_installation(self) -> bool:
592
+ """Verify the installation"""
593
+ logger.info("🔍 Verifying installation...")
594
+
595
+ checks = [
596
+ (self.data_dir / "iran_legal.db", "Database file"),
597
+ (self.config_file, "Configuration file"),
598
+ (self.project_root / ".streamlit" / "config.toml", "Streamlit config"),
599
+ (self.project_root / ".env", "Environment file")
600
+ ]
601
+
602
+ all_good = True
603
+ for file_path, description in checks:
604
+ if file_path.exists():
605
+ logger.info(f"✅ {description}: OK")
606
+ else:
607
+ logger.error(f"❌ {description}: Missing")
608
+ all_good = False
609
+
610
+ # Test database connection
611
+ try:
612
+ db_path = self.data_dir / "iran_legal.db"
613
+ with sqlite3.connect(str(db_path)) as conn:
614
+ cursor = conn.execute("SELECT COUNT(*) FROM documents")
615
+ doc_count = cursor.fetchone()[0]
616
+ cursor = conn.execute("SELECT COUNT(*) FROM scraped_items")
617
+ scraped_count = cursor.fetchone()[0]
618
+ logger.info(f"✅ Database connectivity: OK ({doc_count} documents, {scraped_count} scraped items)")
619
+ except Exception as e:
620
+ logger.error(f"❌ Database connectivity: Failed - {e}")
621
+ all_good = False
622
+
623
+ return all_good
624
+
625
+ def create_launcher_scripts(self):
626
+ """Create launcher scripts for different platforms"""
627
+ logger.info("🚀 Creating launcher scripts...")
628
+
629
+ # Windows batch file
630
+ windows_script = """@echo off
631
+ echo Starting Iran Legal Dashboard...
632
+ echo.
633
+
634
+ :: Check if Python is available
635
+ python --version >nul 2>&1
636
+ if errorlevel 1 (
637
+ echo Python is not installed or not in PATH
638
+ pause
639
+ exit /b 1
640
+ )
641
+
642
+ :: Check if Streamlit is available
643
+ python -c "import streamlit" >nul 2>&1
644
+ if errorlevel 1 (
645
+ echo Installing required packages...
646
+ pip install -r requirements.txt
647
+ )
648
+
649
+ :: Start the application
650
+ echo Starting application on http://localhost:8501
651
+ echo Press Ctrl+C to stop
652
+ echo.
653
+ streamlit run streamlit_app.py
654
+
655
+ pause
656
+ """
657
+
658
+ windows_file = self.project_root / "start_dashboard.bat"
659
+ windows_file.write_text(windows_script)
660
+
661
+ # Unix shell script
662
+ unix_script = """#!/bin/bash
663
+ echo "Starting Iran Legal Dashboard..."
664
+ echo
665
+
666
+ # Check if Python is available
667
+ if ! command -v python3 &> /dev/null; then
668
+ echo "Python 3 is not installed or not in PATH"
669
+ exit 1
670
+ fi
671
+
672
+ # Check if Streamlit is available
673
+ python3 -c "import streamlit" 2>/dev/null
674
+ if [ $? -ne 0 ]; then
675
+ echo "Installing required packages..."
676
+ pip3 install -r requirements.txt
677
+ fi
678
+
679
+ # Start the application
680
+ echo "Starting application on http://localhost:8501"
681
+ echo "Press Ctrl+C to stop"
682
+ echo
683
+ streamlit run streamlit_app.py
684
+ """
685
+
686
+ unix_file = self.project_root / "start_dashboard.sh"
687
+ unix_file.write_text(unix_script)
688
+
689
+ # Make shell script executable
690
+ try:
691
+ unix_file.chmod(0o755)
692
+ except Exception:
693
+ pass # Windows doesn't support chmod
694
+
695
+ # Create requirements.txt
696
+ requirements = """streamlit>=1.28.0
697
+ pandas>=1.5.0
698
+ plotly>=5.0.0
699
+ requests>=2.25.0
700
+ beautifulsoup4>=4.9.0
701
+ Pillow>=8.0.0
702
+ python-dateutil>=2.8.0
703
+ """
704
+
705
+ requirements_file = self.project_root / "requirements.txt"
706
+ requirements_file.write_text(requirements)
707
+
708
+ logger.info("✅ Launcher scripts created")
709
+
710
+ def show_final_instructions(self):
711
+ """Show final setup instructions"""
712
+ logger.info("\n" + "="*60)
713
+ logger.info("🎉 SETUP COMPLETED SUCCESSFULLY!")
714
+ logger.info("="*60)
715
+ logger.info("")
716
+ logger.info("📋 NEXT STEPS:")
717
+ logger.info("")
718
+ logger.info("1. To start the application:")
719
+
720
+ if os.name == 'nt': # Windows
721
+ logger.info(" Windows: Double-click 'start_dashboard.bat'")
722
+ logger.info(" Or run: streamlit run streamlit_app.py")
723
+ else: # Unix-like
724
+ logger.info(" Unix/Linux/macOS: ./start_dashboard.sh")
725
+ logger.info(" Or run: streamlit run streamlit_app.py")
726
+
727
+ logger.info("")
728
+ logger.info("2. Open your browser and go to: http://localhost:8501")
729
+ logger.info("")
730
+ logger.info("📁 IMPORTANT FILES:")
731
+ logger.info(f" • Main app: streamlit_app.py")
732
+ logger.info(f" • Database: {self.data_dir}/iran_legal.db")
733
+ logger.info(f" • Config: {self.config_file}")
734
+ logger.info(f" • Logs: {self.logs_dir}/")
735
+ logger.info("")
736
+ logger.info("🔧 TROUBLESHOOTING:")
737
+ logger.info(" • Check setup.log for detailed logs")
738
+ logger.info(" • Ensure Python 3.7+ is installed")
739
+ logger.info(" • Run 'pip install -r requirements.txt' if needed")
740
+ logger.info("")
741
+ logger.info("📚 FEATURES READY:")
742
+ logger.info(" ✅ Document management")
743
+ logger.info(" ✅ AI analysis engine")
744
+ logger.info(" ✅ Web scraping service")
745
+ logger.info(" ✅ Search functionality")
746
+ logger.info(" ✅ Analytics dashboard")
747
+ logger.info("")
748
+ logger.info("="*60)
749
+
750
+ def main():
751
+ """Main setup function"""
752
+ print("🚀 Iran Legal Dashboard Setup")
753
+ print("=" * 40)
754
+
755
+ setup_manager = SetupManager()
756
+
757
+ try:
758
+ success = setup_manager.run_complete_setup()
759
+
760
+ if success:
761
+ print("\n✅ Setup completed successfully!")
762
+ print("Run 'streamlit run streamlit_app.py' to start the application.")
763
+ else:
764
+ print("\n❌ Setup failed. Check setup.log for details.")
765
+ sys.exit(1)
766
+
767
+ except KeyboardInterrupt:
768
+ print("\n\n⚠️ Setup interrupted by user")
769
+ sys.exit(1)
770
+ except Exception as e:
771
+ logger.error(f"Unexpected error: {e}")
772
+ print(f"\n❌ Unexpected error: {e}")
773
+ sys.exit(1)
774
+
775
+ if __name__ == "__main__":
776
+ main()