235 lines
8.3 KiB
Python
235 lines
8.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Configuration system for PunimTag
|
|
Manages settings for face recognition, auto-tagging, and organization-specific defaults
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
from typing import Dict, Any, List, Optional
|
|
from dataclasses import dataclass, asdict
|
|
from pathlib import Path
|
|
|
|
|
|
@dataclass
|
|
class FaceRecognitionConfig:
|
|
"""Face recognition settings"""
|
|
confidence_threshold: float = 0.6
|
|
face_quality_threshold: float = 0.3
|
|
max_face_distance: float = 0.6
|
|
min_face_size: int = 80
|
|
detection_model: str = 'cnn'
|
|
enable_gpu: bool = True
|
|
enable_clustering: bool = True
|
|
cluster_min_size: int = 3
|
|
cluster_epsilon: float = 0.3
|
|
|
|
|
|
@dataclass
|
|
class AutoTaggingConfig:
|
|
"""Auto-tagging settings"""
|
|
enabled: bool = True
|
|
tag_seasons: bool = True
|
|
tag_locations: bool = True
|
|
tag_time_of_day: bool = True
|
|
tag_indoor_outdoor: bool = False # Requires additional ML models
|
|
confidence_threshold: float = 0.7
|
|
|
|
|
|
@dataclass
|
|
class ProcessingConfig:
|
|
"""Image processing settings"""
|
|
batch_size: int = 100
|
|
max_workers: int = 4
|
|
create_thumbnails: bool = True
|
|
thumbnail_size: tuple = (200, 200)
|
|
supported_formats: Optional[List[str]] = None
|
|
skip_processed: bool = True
|
|
|
|
def __post_init__(self):
|
|
if self.supported_formats is None:
|
|
self.supported_formats = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.gif']
|
|
|
|
|
|
@dataclass
|
|
class DatabaseConfig:
|
|
"""Database settings"""
|
|
backup_enabled: bool = True
|
|
backup_interval_hours: int = 24
|
|
optimize_on_startup: bool = True
|
|
vacuum_on_startup: bool = False
|
|
|
|
|
|
@dataclass
|
|
class JewishOrgConfig:
|
|
"""Jewish organization specific settings"""
|
|
hebrew_calendar_support: bool = True
|
|
default_event_tags: Optional[List[str]] = None
|
|
default_location_tags: Optional[List[str]] = None
|
|
holiday_auto_tagging: bool = True
|
|
|
|
def __post_init__(self):
|
|
if self.default_event_tags is None:
|
|
self.default_event_tags = [
|
|
'shabbat', 'wedding', 'bar_mitzvah', 'bat_mitzvah', 'brit_milah',
|
|
'baby_naming', 'shiva', 'yahrzeit', 'rosh_hashanah', 'yom_kippur',
|
|
'sukkot', 'simchat_torah', 'chanukah', 'tu_bishvat', 'purim',
|
|
'passover', 'lag_baomer', 'shavuot', 'tisha_bav', 'synagogue_service',
|
|
'torah_reading', 'kiddush', 'havdalah', 'community_dinner',
|
|
'study_session', 'board_meeting', 'fundraiser', 'youth_group',
|
|
'hebrew_school', 'adult_education'
|
|
]
|
|
|
|
if self.default_location_tags is None:
|
|
self.default_location_tags = [
|
|
'synagogue', 'sanctuary', 'social_hall', 'classroom', 'library',
|
|
'kitchen', 'office', 'parking_lot', 'garden', 'sukkah',
|
|
'home', 'restaurant', 'community_center', 'school', 'cemetery',
|
|
'israel', 'jerusalem', 'tel_aviv', 'haifa', 'safed'
|
|
]
|
|
|
|
|
|
class PunimTagConfig:
|
|
"""Main configuration class"""
|
|
|
|
def __init__(self, config_file: str = 'punimtag_config.json'):
|
|
self.config_file = config_file
|
|
self.face_recognition = FaceRecognitionConfig()
|
|
self.auto_tagging = AutoTaggingConfig()
|
|
self.processing = ProcessingConfig()
|
|
self.database = DatabaseConfig()
|
|
self.jewish_org = JewishOrgConfig()
|
|
|
|
# Load existing config if available
|
|
self.load()
|
|
|
|
def load(self):
|
|
"""Load configuration from file"""
|
|
if os.path.exists(self.config_file):
|
|
try:
|
|
with open(self.config_file, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
|
|
# Update configurations
|
|
if 'face_recognition' in data:
|
|
self.face_recognition = FaceRecognitionConfig(**data['face_recognition'])
|
|
if 'auto_tagging' in data:
|
|
self.auto_tagging = AutoTaggingConfig(**data['auto_tagging'])
|
|
if 'processing' in data:
|
|
self.processing = ProcessingConfig(**data['processing'])
|
|
if 'database' in data:
|
|
self.database = DatabaseConfig(**data['database'])
|
|
if 'jewish_org' in data:
|
|
self.jewish_org = JewishOrgConfig(**data['jewish_org'])
|
|
|
|
except Exception as e:
|
|
print(f"Error loading config: {e}")
|
|
print("Using default configuration")
|
|
|
|
def save(self):
|
|
"""Save configuration to file"""
|
|
try:
|
|
config_data = {
|
|
'face_recognition': asdict(self.face_recognition),
|
|
'auto_tagging': asdict(self.auto_tagging),
|
|
'processing': asdict(self.processing),
|
|
'database': asdict(self.database),
|
|
'jewish_org': asdict(self.jewish_org)
|
|
}
|
|
|
|
with open(self.config_file, 'w', encoding='utf-8') as f:
|
|
json.dump(config_data, f, indent=2, ensure_ascii=False)
|
|
|
|
except Exception as e:
|
|
print(f"Error saving config: {e}")
|
|
|
|
def reset_to_defaults(self):
|
|
"""Reset all settings to defaults"""
|
|
self.face_recognition = FaceRecognitionConfig()
|
|
self.auto_tagging = AutoTaggingConfig()
|
|
self.processing = ProcessingConfig()
|
|
self.database = DatabaseConfig()
|
|
self.jewish_org = JewishOrgConfig()
|
|
|
|
def get_tag_suggestions(self, category: str = None) -> List[str]:
|
|
"""Get tag suggestions for a category"""
|
|
suggestions = {
|
|
'event': self.jewish_org.default_event_tags,
|
|
'location': self.jewish_org.default_location_tags,
|
|
'time': ['morning', 'afternoon', 'evening', 'night'],
|
|
'season': ['spring', 'summer', 'fall', 'winter'],
|
|
'weather': ['sunny', 'cloudy', 'rainy', 'snowy'],
|
|
'group_size': ['solo', 'couple', 'small_group', 'large_group', 'crowd'],
|
|
'age_group': ['children', 'youth', 'adults', 'seniors', 'mixed_ages'],
|
|
'formality': ['formal', 'casual', 'semiformal', 'religious_attire'],
|
|
'activity': ['eating', 'praying', 'studying', 'celebrating', 'socializing',
|
|
'ceremony', 'performance', 'sports', 'crafts', 'music']
|
|
}
|
|
|
|
if category:
|
|
return suggestions.get(category, [])
|
|
|
|
# Return all suggestions if no category specified
|
|
all_tags = []
|
|
for tags in suggestions.values():
|
|
all_tags.extend(tags)
|
|
return sorted(set(all_tags))
|
|
|
|
def update_setting(self, section: str, key: str, value: Any):
|
|
"""Update a specific setting"""
|
|
if hasattr(self, section):
|
|
section_obj = getattr(self, section)
|
|
if hasattr(section_obj, key):
|
|
setattr(section_obj, key, value)
|
|
self.save()
|
|
return True
|
|
return False
|
|
|
|
def get_setting(self, section: str, key: str, default: Any = None):
|
|
"""Get a specific setting value"""
|
|
if hasattr(self, section):
|
|
section_obj = getattr(self, section)
|
|
if hasattr(section_obj, key):
|
|
return getattr(section_obj, key)
|
|
return default
|
|
|
|
|
|
# Global configuration instance
|
|
config = PunimTagConfig()
|
|
|
|
|
|
def get_config() -> PunimTagConfig:
|
|
"""Get the global configuration instance"""
|
|
return config
|
|
|
|
|
|
def create_default_config(filepath: str = 'punimtag_config.json'):
|
|
"""Create a default configuration file"""
|
|
config = PunimTagConfig(filepath)
|
|
config.save()
|
|
return config
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Demo configuration usage
|
|
print("PunimTag Configuration Demo")
|
|
print("=" * 40)
|
|
|
|
config = PunimTagConfig()
|
|
|
|
print("Current face recognition threshold:", config.face_recognition.confidence_threshold)
|
|
print("Auto-tagging enabled:", config.auto_tagging.enabled)
|
|
print("Batch size:", config.processing.batch_size)
|
|
|
|
print("\nJewish organization event tags:")
|
|
for tag in config.jewish_org.default_event_tags[:10]:
|
|
print(f" - {tag}")
|
|
|
|
print("\nTag suggestions for 'event' category:")
|
|
suggestions = config.get_tag_suggestions('event')[:5]
|
|
for tag in suggestions:
|
|
print(f" - {tag}")
|
|
|
|
# Save configuration
|
|
config.save()
|
|
print(f"\nConfiguration saved to {config.config_file}") |