Spaces:
Sleeping
Sleeping
| """ | |
| ResearchRadar — SettingsScreen. | |
| User-configurable interest keywords, ranking weights, and API keys. | |
| All settings are persisted as JSON in the app data directory. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import logging | |
| import os | |
| from kivy.lang import Builder | |
| from kivy.properties import ( | |
| NumericProperty, | |
| ObjectProperty, | |
| StringProperty, | |
| ) | |
| from kivy.uix.screenmanager import Screen | |
| logger = logging.getLogger(__name__) | |
| _KV_PATH = os.path.join(os.path.dirname(__file__), 'kv', 'settings.kv') | |
| if os.path.exists(_KV_PATH): | |
| Builder.load_file(_KV_PATH) | |
| _DEFAULT_SETTINGS = { | |
| 'interests': { | |
| 'ml': 'deep learning transformers attention', | |
| 'ai': 'artificial intelligence language models', | |
| 'cs': 'software engineering algorithms', | |
| 'neuroscience': 'synaptic plasticity cortex neurons', | |
| 'bci': 'brain computer interface EEG decoding', | |
| }, | |
| 'weight_relevance': 0.60, | |
| 'weight_citation': 0.30, | |
| 'weight_recency': 0.10, | |
| 'top_n': 5, | |
| 'schedule_day': 'sun', | |
| 'schedule_hour': 8, | |
| 'semantic_scholar_key': '', | |
| 'pubmed_key': '', | |
| } | |
| class SettingsScreen(Screen): | |
| """Settings screen with interest keywords, weights, and API keys.""" | |
| # Interest text fields | |
| ml_keywords = StringProperty('') | |
| ai_keywords = StringProperty('') | |
| cs_keywords = StringProperty('') | |
| neuro_keywords = StringProperty('') | |
| bci_keywords = StringProperty('') | |
| # Weights | |
| weight_relevance = NumericProperty(0.60) | |
| weight_citation = NumericProperty(0.30) | |
| weight_recency = NumericProperty(0.10) | |
| # Other | |
| top_n = NumericProperty(5) | |
| semantic_scholar_key = StringProperty('') | |
| pubmed_key = StringProperty('') | |
| def on_enter(self): | |
| self._load_settings() | |
| def _get_settings_path(self) -> str: | |
| from kivy.app import App | |
| app = App.get_running_app() | |
| if app and hasattr(app, 'data_dir'): | |
| return os.path.join(app.data_dir, 'settings.json') | |
| return os.path.join(os.path.expanduser('~'), '.researchradar', 'settings.json') | |
| def _load_settings(self): | |
| path = self._get_settings_path() | |
| settings = dict(_DEFAULT_SETTINGS) | |
| if os.path.exists(path): | |
| try: | |
| with open(path, 'r', encoding='utf-8') as f: | |
| saved = json.load(f) | |
| settings.update(saved) | |
| except (json.JSONDecodeError, OSError): | |
| logger.warning('Could not load settings — using defaults') | |
| interests = settings.get('interests', {}) | |
| self.ml_keywords = interests.get('ml', '') | |
| self.ai_keywords = interests.get('ai', '') | |
| self.cs_keywords = interests.get('cs', '') | |
| self.neuro_keywords = interests.get('neuroscience', '') | |
| self.bci_keywords = interests.get('bci', '') | |
| self.weight_relevance = settings.get('weight_relevance', 0.60) | |
| self.weight_citation = settings.get('weight_citation', 0.30) | |
| self.weight_recency = settings.get('weight_recency', 0.10) | |
| self.top_n = settings.get('top_n', 5) | |
| self.semantic_scholar_key = settings.get('semantic_scholar_key', '') | |
| self.pubmed_key = settings.get('pubmed_key', '') | |
| def save_settings(self): | |
| """Validate and persist settings to JSON.""" | |
| # Normalise weights to sum to 1.0 | |
| total = self.weight_relevance + self.weight_citation + self.weight_recency | |
| if total > 0: | |
| self.weight_relevance /= total | |
| self.weight_citation /= total | |
| self.weight_recency /= total | |
| settings = { | |
| 'interests': { | |
| 'ml': self.ml_keywords, | |
| 'ai': self.ai_keywords, | |
| 'cs': self.cs_keywords, | |
| 'neuroscience': self.neuro_keywords, | |
| 'bci': self.bci_keywords, | |
| }, | |
| 'weight_relevance': round(self.weight_relevance, 2), | |
| 'weight_citation': round(self.weight_citation, 2), | |
| 'weight_recency': round(self.weight_recency, 2), | |
| 'top_n': int(self.top_n), | |
| 'semantic_scholar_key': self.semantic_scholar_key, | |
| 'pubmed_key': self.pubmed_key, | |
| } | |
| path = self._get_settings_path() | |
| os.makedirs(os.path.dirname(path), exist_ok=True) | |
| try: | |
| with open(path, 'w', encoding='utf-8') as f: | |
| json.dump(settings, f, indent=2) | |
| logger.info('Settings saved to %s', path) | |
| except OSError: | |
| logger.error('Failed to save settings', exc_info=True) | |
| # Apply to running app | |
| from kivy.app import App | |
| app = App.get_running_app() | |
| if app and hasattr(app, 'apply_settings'): | |
| app.apply_settings(settings) | |