def Init(): ftpath = os.path.realpath(__file__) ftpath = os.path.dirname(ftpath) ftpath = os.path.join(ftpath, 'stream') plugins = Plugins(ftpath) plugins.loads() Redirect()#.log() keys = { 'digit': string.digits, 'lower': string.ascii_lowercase, 'upper': string.ascii_uppercase, 'punc': string.punctuation, 'mult': ['<tab>', '<bs>', '<cr>', '<space>', '<esc>', '<c-j>'] } for cls, v in keys.items(): for k in v: key = k name = k if k == '|': name = key = '\\|' if k == '\\': name = '\\\\' if key == '"' : name = '\\%s' % key if cls == 'mult': name = name.replace('<', '<lt>') command='inoremap <expr> %s Input_Monitor("%s", "%s")' % \ (key, cls, name) vim.command(command)
def Init(): ftpath = os.path.realpath(__file__) ftpath = os.path.dirname(ftpath) ftpath = os.path.join(ftpath, 'prompt') plugins = Plugins(ftpath) plugins.loads() log.info(__Handles)
def __init__(self): self.log = logging.getLogger('disper') self.log.setLevel(logging.WARNING) self._options_init() self.plugins = Plugins(self) #self.plugins.call('init') # can't really do here since list of plugins isn't read yet # add default options # TODO do initial parsing too so errors can be traced to config self.options_append(self.config_read_default())
def __init__(self, filename=None, data_path=None): # Based in Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py self.version = __import__('pytrainer').get_version() #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("pytrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile(self.environment, self.data_path, self) self.uc = UC() self.windowmain = None self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) self.athlete = Athlete(data_path, self) self.stats = Stats(self._sport_service, self) pool_size = self.profile.getIntValue("pytraining", "activitypool_size", default=1) self.activitypool = ActivityPool(self, size=pool_size) #preparamos la ventana principal self.windowmain = Main(self._sport_service, data_path, self, self.version, gpxDir=self.profile.gpxdir) self.date = Date(self.windowmain.calendar) self.waypoint = Waypoint(data_path, self) self.extension = Extension(data_path, self) self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) self.loadPlugins() self.loadExtensions() self.windowmain.setup() self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() logging.debug('<<')
class Executor: plugins = None def process_command(self, message): # 1. Разбор строки как словаря message_dict = json.loads(message) print('message_dict: %s' % message_dict) # 2. Проверка на безопасность if "key" in message_dict and message_dict["key"] == app.settings.key: print('Прошли проверку безопасности.') command = None # Проверка наличия команды if "command" in message_dict: command = message_dict["command"] # Уточнение типа команды if "plugin" in message_dict: plugin = message_dict["plugin"] if plugin: print('Need plugin: %s' % plugin) # Запускаем указанную команду print('We will run next command: %s' % command) if plugin: plugin_command = command[0] plugin_args = command[1:] if plugin in self.plugins.available: # Плагин есть в загруженных if plugin_command in self.plugins.available[plugin].functions.available: # Run function self.plugins.available[plugin].functions.available[plugin_command].func(plugin_args) else: print('Function "%s" not found in that plugin.' % plugin_command) else: print('Plugin "%s" not found.' % plugin) else: # Если команда не требует плагина - просто выполняем её. subprocess.run(command) def __init__(self): self.plugins = Plugins() self.plugins.print()
def __init__(self): self.log = logging.getLogger("disper") self.log.setLevel(logging.WARNING) self._options_init() self.plugins = Plugins(self) # self.plugins.call('init') # can't really do here since list of plugins isn't read yet self.switcher = Switcher() # add default options # TODO do initial parsing too so errors can be traced to config conffile = os.path.join(os.getenv("HOME"), ".disper", "config") if os.path.exists(conffile): f = open(conffile, "r") opts = "" for l in f.readlines(): opts += l.split("#", 1)[0] + " " f.close() self.options_append(shlex.split(opts))
def __init__(self,filename = None, data_path = None): #Version constants self.version ="1.10.0-dev" #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile(self.environment, self.data_path,self) self.uc = UC() self.windowmain = None self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) self.athlete = Athlete(data_path,self) self.stats = Stats(self._sport_service, self) pool_size = self.profile.getIntValue("pytraining","activitypool_size", default=1) self.activitypool = ActivityPool(self, size=pool_size) #preparamos la ventana principal self.windowmain = Main(self._sport_service, data_path,self,self.version, gpxDir=self.profile.gpxdir) self.date = Date(self.windowmain.calendar) self.waypoint = Waypoint(data_path,self) self.extension = Extension(data_path, self) self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) self.loadPlugins() self.loadExtensions() self.windowmain.setup() self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() logging.debug('<<')
class PluginLoaderTest(unittest.TestCase): def setUp(self): configuration = config.Configuration('tests/plugins/test_pluginloader.config.json') self.plugins = Plugins(configuration) def tearDown(self): pass def test_config_one(self): plugins = self.plugins.all_plugins() watchers = plugins.get("watchers") watcher_names = [watcher.name for watcher in watchers] watcher_names.sort() self.assertEqual(watcher_names, ["tests/plugins/test_pluginloader_testplugins/debug"]) self.assertIsNotNone(plugins.get("hourly")) self.assertIsNotNone(plugins.get("seven_minutes"))
class PluginLoaderTest(unittest.TestCase): def setUp(self): configuration = config.Configuration( 'tests/plugins/test_pluginloader.config.json') self.plugins = Plugins(configuration) def tearDown(self): pass def test_config_one(self): plugins = self.plugins.all_plugins() watchers = plugins.get("watchers") watcher_names = [watcher.name for watcher in watchers] watcher_names.sort() self.assertEqual(watcher_names, ["tests/plugins/test_pluginloader_testplugins/debug"]) self.assertIsNotNone(plugins.get("hourly")) self.assertIsNotNone(plugins.get("seven_minutes"))
class Loader(Owner): def __init__(self, init_cfg: dict, init_state: dict, path: dict, sig: SignalHandlerDummy): self._sig = sig self.reload = False self._restore_filename = None self._lock = threading.Lock() self._stts_lock = threading.Lock() self._join_lock = threading.Lock() self._pub = PubSub() self._sig.set_wakeup_callback( lambda: self.sub_call('default', 'terminal_stop', True)) self._logger = logger.Logger(self) proxies.add_logger(self._logger.add('Proxy')) self._cfg = ConfigHandler(cfg=init_cfg, state=init_state, path=path, log=self._logger.add('CFG'), owner=self) self._logger.init(cfg=self._cfg, owner=self) self._log = self._logger.add('SYSTEM') self._listen = Listener(cfg=self._cfg, log=self._logger.add('REC'), owner=self) self._notifier = MajordomoNotifier(cfg=self._cfg, log=self._logger.add('Notifier'), owner=self) self._tts = stts.TextToSpeech(cfg=self._cfg, log=self._logger.add('TTS')) self._play = Player(cfg=self._cfg, log=self._logger.add('Player'), owner=self) self._music = music_constructor(cfg=self._cfg, logger=self._logger, owner=self) self._stt = stts.SpeechToText(cfg=self._cfg, log=self._logger.add('STT'), owner=self) self._mm = ModuleManager(cfg=self._cfg, log=self._logger.add('MM'), owner=self) self._updater = Updater(cfg=self._cfg, log=self._logger.add('Updater'), owner=self) self._backup = Backup(cfg=self._cfg, log=self._logger.add('Backup'), owner=self) self._terminal = MDTerminal(cfg=self._cfg, log=self._logger.add('Terminal'), owner=self) self._server = server_constructor(cfg=self._cfg, logger=self._logger, owner=self) self._plugins = Plugins(cfg=self._cfg, log=self._logger.add('Plugins'), owner=self) self._duplex_pool = DuplexPool(cfg=self._cfg, log=self._logger.add('DP'), owner=self) self._discovery = DiscoveryServer(cfg=self._cfg, log=self._logger.add('Discovery')) def start_all_systems(self): self._music.start() self._play.start() self._play.say_info(F( 'Приветствую. Голосовой терминал настраивается, три... два... один...' ), 0, wait=0.5) self._stt.start() self._cfg.start() self._notifier.start() self._mm.start() self._updater.start() self._terminal.start() self._server.start() self._discovery.start() self._backup.start() self._plugins.start() self.messenger( lambda: self.log(available_version_msg(self._cfg.version_info), logger.INFO), None) self.sub_call('default', 'version', self._cfg.version_str) self.volume_callback(self.get_volume()) def stop_all_systems(self): self._cfg.config_save(final=True) self.join_thread(self._plugins) self._mm.stop() self.join_thread(self._discovery) self.join_thread(self._server) self.join_thread(self._terminal) self.join_thread(self._backup) self.join_thread(self._updater) self.join_thread(self._notifier) self.join_thread(self._duplex_pool) self._play.quiet() self._play.kill_popen() self._play.say_info(F('Голосовой терминал завершает свою работу.')) self._stt.stop() self._play.stop() self.join_thread(self._music) if self._restore_filename: self._backup.restore(self._restore_filename) self._restore_filename = '' self.join_thread(self._logger.remote_log) self._pub.stopping = True self._logger.join() self._pub.join() self._pub.report() def log(self, msg: str, lvl=logger.DEBUG): self._log(msg, lvl) def join_thread(self, obj): def obj_log(msg_: str, lvl=logger.DEBUG): if log_present: obj.log(msg_, lvl) def diagnostic_msg() -> str: _call = getattr(obj, 'diagnostic_msg', None) return ' {}'.format(_call()) if callable(_call) else '' with self._join_lock: close_signal = getattr(obj, 'close_signal', None) if close_signal: close_signal() if not obj.work: return log_present = callable(getattr(obj, 'log', None)) obj.work = False obj_log('stopping...') stop_time = time.time() obj.join() stop_time = time.time() - stop_time if not obj.is_alive(): obj_log('stop.', logger.INFO) else: obj_log('stopping error.', logger.ERROR) name_ = '.'.join(getattr(obj.log, 'name', [''])) if log_present else None name_ = name_ or str(obj) msg = 'Thread \'{}\' stuck and not stopping in {}!{}'.format( name_, pretty_time(stop_time), diagnostic_msg()) self.log(msg, logger.ERROR) def subscribe(self, event, callback, channel='default') -> bool: return self._pub.subscribe(event, callback, channel) def unsubscribe(self, event, callback, channel='default') -> bool: return self._pub.unsubscribe(event, callback, channel) def registration(self, event: str, channel='default'): return self._pub.registration(event, channel) def has_subscribers(self, event: str, channel='default') -> bool: return self._pub.has_subscribers(event, channel) def events_list(self, channel='default') -> list: return self._pub.events_list(channel) def send_notify(self, event: str, *args, **kwargs): return self._pub.sub_call('default', event, *args, **kwargs) def sub_call(self, channel: str, event: str, *args, **kwargs): return self._pub.sub_call(channel, event, *args, **kwargs) @staticmethod def messenger(call, callback, *args, **kwargs) -> bool: return Messenger(call, callback, *args, **kwargs)() def insert_module(self, module) -> bool: return self._mm.insert_module(module) def extract_module(self, callback) -> bool: return self._mm.extract_module(callback) def insert_detectors(self, detector): detector = prepare_detectors(detector) if not detector: return def callback(): with self._lock: detectors.DETECTORS.update(detector) self.__reconfigure_terminal(detector) # noinspection PyTypeChecker self.terminal_call('callme', callback, save_time=False) def extract_detectors(self, detector): detector = prepare_detectors(detector, True) if not detector: return def callback(): with self._lock: [detectors.DETECTORS.pop(x, None) for x in detector] self.__reconfigure_terminal(detector) # noinspection PyTypeChecker self.terminal_call('callme', callback, save_time=False) def add_stt_provider(self, name: str, entrypoint) -> bool: with self._stts_lock: if name not in STT.PROVIDERS: STT.PROVIDERS[name] = entrypoint return True return False def remove_stt_provider(self, name: str): with self._stts_lock: try: return STT.PROVIDERS.pop(name) except KeyError: return None def add_tts_provider(self, name: str, entrypoint) -> bool: with self._stts_lock: if name not in TTS.PROVIDERS: TTS.PROVIDERS[name] = entrypoint return True return False def remove_tts_provider(self, name: str): with self._stts_lock: try: return TTS.PROVIDERS.pop(name) except KeyError: return None def tts_providers(self) -> list: with self._stts_lock: return list(TTS.PROVIDERS.keys()) def stt_providers(self) -> list: with self._stts_lock: return list(STT.PROVIDERS.keys()) def is_tts_provider(self, name: str) -> bool: return name in TTS.PROVIDERS def is_stt_provider(self, name: str) -> bool: return name in STT.PROVIDERS def plugins_status(self, state: str) -> dict: return self._plugins.status(state) def get_plugin(self, name: str) -> object: try: return self._plugins.modules[name] except KeyError: raise RuntimeError('Plugin \'{}\' not found'.format(name)) except Exception as e: raise RuntimeError('Error accessing to plugin \'{}\': {}'.format( name, e)) def list_notifications(self) -> list: return self._notifier.list_notifications() def add_notifications(self, events: list, is_self=False) -> list: return self._notifier.add_notifications(events, is_self) def remove_notifications(self, events: list) -> list: return self._notifier.remove_notifications(events) def say(self, msg: str, lvl: int = 2, alarm=None, wait=0, is_file: bool = False, blocking: int = 0): self._play.say(msg, lvl, alarm, wait, is_file, blocking) def play(self, file, lvl: int = 2, wait=0, blocking: int = 0): self._play.play(file, lvl, wait, blocking) def say_info(self, msg: str, lvl: int = 2, alarm=None, wait=0, is_file: bool = False): self._play.say_info(msg, lvl, alarm, wait, is_file) def set_lvl(self, lvl: int) -> bool: return self._play.set_lvl(lvl) def clear_lvl(self): self._play.clear_lvl() def quiet(self): self._play.quiet() def full_quiet(self): self._play.full_quiet() def really_busy(self) -> bool: return self._play.really_busy() @state_cache(interval=0.008) def noising(self) -> bool: return self._play.noising() def kill_popen(self): self._play.kill_popen() def listen(self, hello: str = '', deaf: bool = True, voice: bool = False) -> tuple: return self._stt.listen(hello, deaf, voice) def voice_record(self, hello: str or None, save_to: str, convert_rate=None, convert_width=None, limit=8): return self._stt.voice_record(hello, save_to, convert_rate, convert_width, limit) def voice_recognition(self, audio, quiet: bool = False, fusion=None) -> str: return self._stt.voice_recognition(audio, quiet, fusion) @property def max_mic_index(self) -> int: return self._stt.max_mic_index @max_mic_index.setter def max_mic_index(self, val: int): self._stt.max_mic_index = val @property def mic_index(self) -> int: return self._stt.get_mic_index() def phrase_from_files(self, files: list) -> tuple: return self._stt.phrase_from_files(files) def multiple_recognition(self, file_or_adata, providers: list) -> list: return self._stt.multiple_recognition(file_or_adata, providers) @property def sys_say_chance(self) -> bool: return self._stt.sys_say.chance def music_state(self) -> str: return self._music.state() def music_play(self, uri): self._music.play(uri) def music_pause(self, paused=None): self._music.pause(paused) @property def music_plays(self) -> bool: return self._music.plays @property def music_volume(self): return self._music.volume @music_volume.setter def music_volume(self, vol): self._music.volume = vol @property def music_real_volume(self): return self._music.real_volume @music_real_volume.setter def music_real_volume(self, vol): self._music.real_volume = vol @property def music_track_name(self) -> str or None: return self._music.get_track_name() def tts(self, msg, realtime: bool = True): return self._tts.tts(msg, realtime) def ask_again_callback(self): self._pub.call('ask_again') def voice_activated_callback(self): self._pub.call('voice_activated') def speech_recognized_callback(self, status: bool): if status and self._cfg.gts('alarm_recognized'): self.play(self._cfg.path['bimp']) self._pub.call( 'speech_recognized_{}success'.format('' if status else 'un')) def record_callback(self, start_stop: bool): self._pub.call('start_record' if start_stop else 'stop_record') def say_callback(self, start_stop: bool): self._pub.call('start_talking' if start_stop else 'stop_talking') def speech_recognized(self, start_stop: bool): self._pub.call('start_recognized' if start_stop else 'stop_recognized') def music_status_callback(self, status: str): self._pub.call('music_status', status if status is not None else 'error') def music_volume_callback(self, volume: int): self._pub.call('music_volume', volume if volume is not None else -1) def volume_callback(self, volume: int): self._pub.call('volume', volume) @property def srv_ip(self) -> str: return self._cfg['smarthome']['ip'] def update(self): self._updater.update() def manual_rollback(self): self._updater.manual_rollback() def backup_manual(self): self._backup.manual_backup() def backup_restore(self, filename: str): if not self._restore_filename and filename: self._restore_filename = filename self.die_in(3, reload=True) def backup_list(self) -> list: return self._backup.backup_list() def modules_tester(self, phrase: str, call_me=None, rms=None, model=None): return self._mm.tester(phrase, call_me, rms, model) def die_in(self, wait, reload=False): self.reload = reload self._sig.die_in(wait) @property def get_volume_status(self) -> dict: music_volume = self._music.real_volume return { 'volume': self.get_volume(), 'music_volume': music_volume if music_volume is not None else -1 } def terminal_call(self, cmd: str, data='', lvl: int = 0, save_time: bool = True): self._terminal.call(cmd, data, lvl, save_time) def terminal_listen(self) -> bool: return self._terminal.listening def recognition_forever(self, interrupt_check: callable, callback: callable): return self._listen.recognition_forever(interrupt_check, callback) def get_vad_detector(self, source_or_mic, vad_mode=None, vad_lvl=None, energy_lvl=None, energy_dynamic=None): return self._listen.get_vad_detector(source_or_mic, vad_mode, vad_lvl, energy_lvl, energy_dynamic) def detected_fake(self, text: str, rms=None, model=None, cb=None): self._listen.detected_fake(text, rms, model, cb) def listener_listen(self, r=None, mic=None, vad=None): return self._listen.listen(r, mic, vad) def background_listen(self): return self._listen.background_listen() def get_volume(self) -> int: control = self._cfg.gt('volume', 'line_out', '') card = self._cfg.gt('volume', 'card', 0) if not control or control == volume_.UNDEFINED: return -2 return volume_.get_volume(control, card) def set_volume(self, vol) -> int: control = self._cfg.gt('volume', 'line_out', '') card = self._cfg.gt('volume', 'card', 0) if not control or control == volume_.UNDEFINED: return -2 try: return volume_.set_volume(vol, control, card) except RuntimeError as e: self.log('set_volume({}): {}'.format(vol, e), logger.WARN) return -1 def settings_from_inside(self, cfg: dict) -> bool: with self._lock: return self._cfg.update_from_dict(cfg) def settings_from_srv(self, cfg: str or dict) -> dict: # Reload modules if their settings could be changes with self._lock: diff = self._cfg.update_from_external(cfg) reload_terminal = False detector_reconfigure = False vad_reconfigure = False if diff is None: self._cfg.print_cfg_no_change() return {} lang, lang_check = None, None if is_sub_dict('settings', diff) and ('lang' in diff['settings'] or 'lang_check' in diff['settings']): # re-init lang lang = diff['settings'].pop('lang', None) lang_check = diff['settings'].pop('lang_check', None) self._cfg.lang_init() if lang: # reload phrases self._stt.reload() # reload modules self._mm.reload() if is_sub_dict('models', diff): # reload models. Reload terminal - later self._cfg.models_load() reload_terminal = True if is_sub_dict('log', diff): # reload logger self._logger.reload() if is_sub_dict('cache', diff): # re-check tts cache self._cfg.tts_cache_check() if is_sub_dict('proxy', diff): # re-init proxy self._cfg.proxies_init() if is_sub_dict('music', diff): # reconfigure music server self.music_reload() if is_sub_dict('update', diff): # update 'update' interval self._updater.reload() if is_sub_dict('backup', diff): # update backup interval self._backup.reload() if is_sub_dict('smarthome', diff): if 'allow_addresses' in diff['smarthome']: # re-init allow ip addresses self._cfg.allow_addresses_init() if 'disable_server' in diff['smarthome']: # handle [smarthome] disable_server self.messenger(self.server_reload, None) # resubscribe self._notifier.reload(diff) self._duplex_pool.reload() if is_sub_dict('noise_suppression', diff): # reconfigure APM. Reload terminal - later self._cfg.apm_configure() reload_terminal = True if is_sub_dict('listener', diff): reload_terminal = True detector_reconfigure = 'detector' in diff['listener'] vad_reconfigure = bool([ key for key in ('vad_mode', 'vad_chrome') if key in diff['listener'] ]) if is_sub_dict('settings', diff) or reload_terminal: # reload terminal # noinspection PyTypeChecker self.terminal_call('reload', (detector_reconfigure, vad_reconfigure), save_time=False) # restore lang's if lang is not None: diff['settings']['lang'] = lang if lang_check is not None: diff['settings']['lang_check'] = lang_check # check and reload plugins self._plugins.reload(diff) self._cfg.print_cfg_change() self._cfg.config_save() return diff def music_reload(self): self._music = music_constructor(self._cfg, self._logger, self, self._music) def server_reload(self): self._server = server_constructor(self._cfg, self._logger, self, self._server) def __reconfigure_terminal(self, detector: set or dict): if self._cfg['listener'][ 'detector'] in detector or self._cfg.detector.NAME in detector: # noinspection PyProtectedMember self._terminal._reload((True, False))
def __init__(self): self.plugins = Plugins() self.plugins.print()
class pyTrainer: def __init__(self, filename=None, data_path=None): # Based on Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py self.version = __import__('pytrainer').get_version() #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(self.startup_options.conf_dir, data_path) self.environment.create_directories() self.environment.clear_temp_dir() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.info("pytrainer version %s" % (self.version)) self.data_path = data_path # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile() # Write the default config to disk self.profile.saveProfile() self.uc = UC() self.profilewindow = None self.ddbb = DDBB(self.profile.sqlalchemy_url) logging.debug('connecting to DDBB') self.ddbb.connect() logging.info('Checking if some upgrade action is needed...') initialize_data(self.ddbb, self.environment.conf_dir) # Loading shared services logging.debug('Loading sport service...') self._sport_service = SportService(self.ddbb) logging.debug('Loading record service...') self.record = Record(self._sport_service, data_path, self) logging.debug('Loading athlete service...') self.athlete = Athlete(data_path, self) logging.debug('Loading stats service...') self.stats = Stats(self) logging.debug('Initializing activity pool...') pool_size = self.profile.getIntValue("pytraining", "activitypool_size", default=1) self.activitypool = ActivityService(self, size=pool_size) #Loading main window self.windowmain = None logging.debug('Loading main window...') self.windowmain = Main(self._sport_service, data_path, self, self.version, gpxDir=self.profile.gpxdir) # Select initial date depending on user's preference self.selectInitialDate() logging.debug('Loading waypoint service...') self.waypoint = WaypointService(data_path, self) logging.debug('Loading extension service...') self.extension = Extension(data_path, self) logging.debug('Loading plugins service...') self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) logging.debug('Loading plugins...') self.loadPlugins() logging.debug('Loading extensions...') self.loadExtensions() logging.debug('Setting values for graphs, maps and waypoint editor...') self.windowmain.setup() self.windowmain.on_calendar_selected(None) logging.debug('Refreshing sport list... is this needed?') self.refreshMainSportList() logging.debug('Launching main window...') self.windowmain.run() logging.debug('<<') def get_options(self): ''' Define usage and accepted options for command line startup returns: options - dict with option: value pairs ''' usage = '''usage: %prog [options] For more help on valid options try: %prog -h ''' parser = OptionParser(usage=usage) parser.set_defaults(log_level=logging.WARNING, validate=False, equip=False, newgraph=True, conf_dir=None, log_type="file") parser.add_option("-d", "--debug", action="store_const", const=logging.DEBUG, dest="log_level", help="enable logging at debug level") parser.add_option("-i", "--info", action="store_const", const=logging.INFO, dest="log_level", help="enable logging at info level") parser.add_option("-w", "--warn", action="store_const", const=logging.WARNING, dest="log_level", help="enable logging at warning level") parser.add_option("--error", action="store_const", const=logging.ERROR, dest="log_level", help="enable logging at error level") parser.add_option( "--valid", action="store_true", dest="validate", help= "enable validation of files imported by plugins (details at info or debug logging level) - note plugin must support validation" ) parser.add_option("--oldgraph", action="store_false", dest="newgraph", help="Turn off new graphing approach") parser.add_option( "--newgraph", action="store_true", dest="newgraph", help="Deprecated Option: Turn on new graphing approach") parser.add_option( "--confdir", dest="conf_dir", help= "Specify the directory where application configuration will be stored." ) parser.add_option( "--logtype", dest="log_type", metavar="TYPE", type="choice", choices=["file", "console"], help= "Specify where logging should be output to. TYPE is one of 'file' (default), or 'console'." ) (options, args) = parser.parse_args() return options def set_logging(self, level, log_type): '''Setup rotating log file with customized format''' if ("console" == log_type): handler = logging.StreamHandler(sys.stdout) else: handler = logging.handlers.RotatingFileHandler( self.environment.log_file, maxBytes=100000, backupCount=5) formatter = logging.Formatter( '%(asctime)s|%(levelname)s|%(module)s|%(funcName)s|%(message)s') handler.setFormatter(formatter) logging.getLogger('').addHandler(handler) self.set_logging_level(self.startup_options.log_level) def set_logging_level(self, level): '''Set level of information written to log''' logging.debug("Setting logger to level: " + str(level)) logging.getLogger('').setLevel(level) logging.getLogger('sqlalchemy.engine').setLevel(level) def quit(self): logging.debug('--') logging.info("Exit!") #self.webservice.stop() self.windowmain.gtk_main_quit() logging.shutdown() sys.exit( ) # Any nonzero value is considered "abnormal termination" by shells and the like def selectInitialDate(self): logging.debug('>>') # self.windowmain.calendar comes from SimpleGladeApp initialisation, not really sure how... :? self.date = Date(self.windowmain.calendar) if self.profile.getValue("pytraining", "prf_startscreen") == "last_entry": logging.info( "User selection is to display last entry in start screen") last_entry_date = self.record.getLastRecordDateString() try: logging.info("Last activity found on %s" % last_entry_date) self.date.setDate(last_entry_date) except: logging.error( "No data available regarding last activity date. Default date will be today" ) logging.debug("Traceback: %s" % traceback.format_exc()) else: logging.info( "User selection is to display current day in start screen") logging.debug('Setting date to %s' % self.date.getDate().strftime("%Y-%m-%d")) logging.debug('<<') def loadPlugins(self): logging.debug('>>') activeplugins = self.plugins.getActivePlugins() if (len(activeplugins) < 1): logging.info("No active plugins") else: for plugin in activeplugins: # From version 1.10 on all file imports are managed via File -> import wizard # Only showing garmintools_full and garmin-hr in 'File' dropdown plugin_name = os.path.basename(plugin) if (plugin_name == "garmintools_full" or plugin_name == "garmin-hr"): txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.addImportPlugin(txtbutton) else: logging.debug( 'From version 1.10 on, file import plugins are managed via File -> Import. Not displaying plugin ' + plugin_name) logging.debug('<<') def loadExtensions(self): logging.debug('>>') activeextensions = self.extension.getActiveExtensions() if (len(activeextensions) < 1): logging.info("No active extensions") else: for extension in activeextensions: txtbutton = self.extension.loadExtension(extension) self.windowmain.addExtension(txtbutton) logging.debug('<<') def runPlugin(self, widget, pathPlugin): logging.debug('>>') self.pluginClass = self.plugins.importClass(pathPlugin) pluginFiles = self.pluginClass.run() if pluginFiles is not None: logging.debug("Plugin returned %d files" % (len(pluginFiles))) #process returned GPX files for (pluginFile, sport) in pluginFiles: if os.path.isfile(pluginFile): logging.info('File exists. Size: %d. Sport: %s' % (os.path.getsize(pluginFile), sport)) if self.record.importFromGPX(pluginFile, sport) is None: logging.error("Error importing file " + pluginFile) else: logging.error('File ' + pluginFile + ' not valid') else: logging.debug("No files returned from Plugin") self.refreshListRecords() self.refreshGraphView("day") logging.debug('<<') def runExtension(self, extension, id): logging.debug('>>') #print("Extension id: %s" % str(id)) activity = self.activitypool.get_activity(id) txtbutton, pathExtension, type = extension self.extensionClass = self.extension.importClass(pathExtension) self.extensionClass.run(id, activity) #if type == "record": # #Si es record le tenemos que crear el googlemaps, el gpx y darle el id de la bbdd # alert = self.extension.runExtension(pathExtension,id) logging.debug('<<') def refreshMainSportList(self): logging.debug('>>') sports = self._sport_service.get_all_sports() self.windowmain.updateSportList(sports) logging.debug('<<') def refreshGraphView(self, view, sport=None): logging.debug('>>') if self.windowmain is None: logging.debug("First call to refreshGraphView") logging.debug('<<') return date_selected = self.date.getDate() if view == "record": logging.debug('record view') if self.windowmain.recordview.get_current_page() == 0: self.refreshRecordGraphView("info") elif self.windowmain.recordview.get_current_page() == 1: self.refreshRecordGraphView("graphs") elif self.windowmain.recordview.get_current_page() == 2: self.refreshRecordGraphView("map") elif self.windowmain.recordview.get_current_page() == 3: self.refreshRecordGraphView("heartrate") elif self.windowmain.recordview.get_current_page() == 4: self.refreshRecordGraphView("analytics") elif view == "day": logging.debug('day view') self.windowmain.actualize_dayview(date_selected) elif view == "week": logging.debug('week view') date_range = DateRange.for_week_containing(date_selected) self.windowmain.actualize_weekview(date_range) elif view == "month": logging.debug('month view') date_range = DateRange.for_month_containing(date_selected) nameMonth, daysInMonth = getNameMonth(date_selected) self.windowmain.actualize_monthview(date_range, nameMonth, daysInMonth) elif view == "year": logging.debug('year view') date_range = DateRange.for_year_containing(date_selected) self.windowmain.actualize_yearview(date_range, date_selected.year) elif view == "listview": logging.debug('list view') self.refreshListView() elif view == "athlete": logging.debug('athlete view') self.windowmain.on_athleteview_activate() elif view == "stats": logging.debug('stats view') self.windowmain.on_statsview_activate() else: print "Unknown view %s" % view logging.debug('<<') def refreshRecordGraphView(self, view, id_record=None): logging.debug('>>') logging.info('Working on ' + view + ' graph') if id_record is not None: #Refresh called for a specific record #Select correct record in treeview model = self.windowmain.recordTreeView.get_model() #Loop through all records in treeview looking for the correct one to highlight for i, row in enumerate(model): if row[0] == id_record: self.windowmain.recordTreeView.set_cursor(i) else: selected, iter = self.windowmain.recordTreeView.get_selection( ).get_selected() if iter: id_record = selected.get_value(iter, 0) else: id_record = None view = "info" activity = self.activitypool.get_activity(id_record) if view == "info": self.windowmain.actualize_recordview(activity) if view == "graphs": self.windowmain.actualize_recordgraph(activity) if view == "map": self.refreshMapView() if view == "heartrate": self.windowmain.actualize_heartrategraph(activity) self.windowmain.actualize_hrview(activity) if view == "analytics": self.windowmain.actualize_analytics(activity) logging.debug('<<') def refreshMapView(self, full_screen=False): logging.debug('>>') if self.windowmain is None: logging.debug('Called before windowmain initialisation') logging.debug('<<') return selected, iter = self.windowmain.recordTreeView.get_selection( ).get_selected() id_record = selected.get_value(iter, 0) activity = self.activitypool.get_activity(id_record) logging.debug('Trying to show map for record ' + str(id_record)) self.windowmain.actualize_map(activity, full_screen) logging.debug('<<') def refreshListRecords(self): logging.debug('>>') #Refresh list records date = self.date.getDate() if self.windowmain.activeSport: sport = self._sport_service.get_sport_by_name( self.windowmain.activeSport) else: sport = None self.windowmain.actualize_recordTreeView(date) #Mark the monthly calendar to show which days have activity? record_list = self.record.getRecordDayList(date, sport) self.windowmain.actualize_calendar(record_list) logging.debug('<<') def refreshAthleteView(self): logging.debug('>>') self.athlete.refresh() self.windowmain.actualize_athleteview(self.athlete) logging.debug('<<') def refreshStatsView(self): logging.debug('>>') self.stats.refresh() self.windowmain.actualize_statsview( self.stats, self.activitypool.get_all_activities()) logging.debug('<<') def refreshListView(self, condition=None): logging.debug('>>') record_list = self.record.getRecordListByCondition(condition) self.windowmain.actualize_listview(record_list) logging.debug('<<') def refreshWaypointView(self, default_waypoint=None, redrawmap=1): logging.debug('>>') waypoint_list = self.waypoint.getAllWaypoints() self.windowmain.actualize_waypointview(waypoint_list, default_waypoint, redrawmap) logging.debug('<<') def editExtensions(self): logging.debug('>>') before = self.extension.getActiveExtensions() self.extension.manageExtensions() after = self.extension.getActiveExtensions() self.setExtensions(before, after) logging.debug('<<') def importData(self): logging.debug('>>') activeplugins_before = self.plugins.getActivePlugins() self.importdata.runImportdata() activeplugins_after = self.plugins.getActivePlugins() #Need to check for plugins that have been disabled (were active and now are not) self.setMenuPlugins(activeplugins_before, activeplugins_after) self.refreshListRecords() self.refreshGraphView(self.windowmain.selected_view) logging.debug('<<') def editGpsPlugins(self): logging.debug('>>') activeplugins_before = self.plugins.getActivePlugins() self.plugins.managePlugins() activeplugins_after = self.plugins.getActivePlugins() #Need to check for plugins that have been disabled (were active and now are not) self.setMenuPlugins(activeplugins_before, activeplugins_after) logging.debug('<<') def setMenuPlugins(self, activeplugins_before, activeplugins_after): logging.debug('>>') #Need to check for plugins that have been disabled (were active and now are not) for plugin in activeplugins_before: if plugin not in activeplugins_after: #disabled plugin -> need to unload plugin txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.removeImportPlugin(txtbutton) #Need to check for plugins that have been enabled (were not active and now are) for plugin in activeplugins_after: if plugin not in activeplugins_before: #new active plugin -> need to load plugin plugin_name = os.path.basename(plugin) if (plugin_name == "garmintools_full" or plugin_name == "garmin-hr"): txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.addImportPlugin(txtbutton) else: logging.debug( 'From version 1.10 on file import plugins are managed via File -> Import. Not displaying plugin ' + plugin_name) logging.debug('<<') def setExtensions(self, before, after): logging.debug('>>') #Need to check for extensions that have been disabled (were active and now are not) for extension in before: if extension not in after: #disabled extension -> need to unload extension print "Need to disable extension %s " % extension txtbutton = self.extension.loadExtension(extension) self.windowmain.removeExtension(txtbutton) #Need to check for plugins that have been enabled (were not active and now are) for extension in after: if extension not in before: #new active extension -> need to load extension logging.debug("Enabling extension %s " % extension) txtbutton = self.extension.loadExtension(extension) self.windowmain.addExtension(txtbutton) logging.debug('<<') def newRecord(self, title=None, distance=None, time=None, upositive=None, unegative=None, bpm=None, calories=None, comment=None, view=None): logging.debug('>>') date = self.date.getDate() self.record.newRecord(date, title, distance, time, upositive, unegative, bpm, calories, comment) self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def editRecord(self, id_record, view=None): logging.debug("Editing record with id: '%s'", id_record) self.record.editRecord(id_record) self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def removeRecord(self, id_record, confirm=False, view=None): logging.debug('>>') if confirm: activity = self.activitypool.get_activity(id_record) self.activitypool.remove_activity_from_db(activity) else: msg = _("Delete this database entry?") params = [id_record, True] warning = Warning(self.data_path, self.removeRecord, params) warning.set_text(msg) warning.run() self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def removeWaypoint(self, id_waypoint, confirm=False): logging.debug('>>') if confirm: self.waypoint.removeWaypoint(id_waypoint) self.refreshWaypointView() else: msg = _("Delete this waypoint?") params = [id_waypoint, True] warning = Warning(self.data_path, self.removeWaypoint, params) warning.set_text(msg) warning.run() logging.debug('<<') def updateWaypoint(self, id_waypoint, lat, lon, name, desc, sym): logging.debug('>>') self.waypoint.updateWaypoint(id_waypoint, lat, lon, name, desc, sym) self.refreshWaypointView(id_waypoint) logging.debug('<<') def exportCsv(self): logging.debug('>>') from save import Save save = Save(self.data_path, self.record) save.run() logging.debug('<<') def editProfile(self): logging.debug('>>') from gui.windowprofile import WindowProfile self.profile.refreshConfiguration() if self.profilewindow is None: self.profilewindow = WindowProfile(self._sport_service, self.data_path, self.profile, pytrainer_main=self) logging.debug("setting data values") self.profilewindow.setValues(self.profile.configuration) self.profilewindow.run() self.profilewindow = None else: self.profilewindow.setValues(self.profile.configuration) self.profilewindow.present() self.profile.refreshConfiguration() self.activitypool.clear_pool() self.windowmain.setup() logging.debug('<<')
def __init__(self, filename=None, data_path=None): # Based on Django's approach -> http://code.djangoproject.com/svn/django/trunk/django/__init__.py self.version = __import__('pytrainer').get_version() #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(self.startup_options.conf_dir, data_path) self.environment.create_directories() self.environment.clear_temp_dir() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.info("pytrainer version %s" % (self.version)) self.data_path = data_path # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile() # Write the default config to disk self.profile.saveProfile() self.uc = UC() self.profilewindow = None self.ddbb = DDBB(self.profile.sqlalchemy_url) logging.debug('connecting to DDBB') self.ddbb.connect() logging.info('Checking if some upgrade action is needed...') initialize_data(self.ddbb, self.environment.conf_dir) # Loading shared services logging.debug('Loading sport service...') self._sport_service = SportService(self.ddbb) logging.debug('Loading record service...') self.record = Record(self._sport_service, data_path, self) logging.debug('Loading athlete service...') self.athlete = Athlete(data_path, self) logging.debug('Loading stats service...') self.stats = Stats(self) logging.debug('Initializing activity pool...') pool_size = self.profile.getIntValue("pytraining", "activitypool_size", default=1) self.activitypool = ActivityService(self, size=pool_size) #Loading main window self.windowmain = None logging.debug('Loading main window...') self.windowmain = Main(self._sport_service, data_path, self, self.version, gpxDir=self.profile.gpxdir) # Select initial date depending on user's preference self.selectInitialDate() logging.debug('Loading waypoint service...') self.waypoint = WaypointService(data_path, self) logging.debug('Loading extension service...') self.extension = Extension(data_path, self) logging.debug('Loading plugins service...') self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) logging.debug('Loading plugins...') self.loadPlugins() logging.debug('Loading extensions...') self.loadExtensions() logging.debug('Setting values for graphs, maps and waypoint editor...') self.windowmain.setup() self.windowmain.on_calendar_selected(None) logging.debug('Refreshing sport list... is this needed?') self.refreshMainSportList() logging.debug('Launching main window...') self.windowmain.run() logging.debug('<<')
def __init__(self, init_cfg: dict, init_state: dict, path: dict, sig: SignalHandlerDummy): self._sig = sig self.reload = False self._restore_filename = None self._lock = threading.Lock() self._stts_lock = threading.Lock() self._join_lock = threading.Lock() self._pub = PubSub() self._sig.set_wakeup_callback( lambda: self.sub_call('default', 'terminal_stop', True)) self._logger = logger.Logger(self) proxies.add_logger(self._logger.add('Proxy')) self._cfg = ConfigHandler(cfg=init_cfg, state=init_state, path=path, log=self._logger.add('CFG'), owner=self) self._logger.init(cfg=self._cfg, owner=self) self._log = self._logger.add('SYSTEM') self._listen = Listener(cfg=self._cfg, log=self._logger.add('REC'), owner=self) self._notifier = MajordomoNotifier(cfg=self._cfg, log=self._logger.add('Notifier'), owner=self) self._tts = stts.TextToSpeech(cfg=self._cfg, log=self._logger.add('TTS')) self._play = Player(cfg=self._cfg, log=self._logger.add('Player'), owner=self) self._music = music_constructor(cfg=self._cfg, logger=self._logger, owner=self) self._stt = stts.SpeechToText(cfg=self._cfg, log=self._logger.add('STT'), owner=self) self._mm = ModuleManager(cfg=self._cfg, log=self._logger.add('MM'), owner=self) self._updater = Updater(cfg=self._cfg, log=self._logger.add('Updater'), owner=self) self._backup = Backup(cfg=self._cfg, log=self._logger.add('Backup'), owner=self) self._terminal = MDTerminal(cfg=self._cfg, log=self._logger.add('Terminal'), owner=self) self._server = server_constructor(cfg=self._cfg, logger=self._logger, owner=self) self._plugins = Plugins(cfg=self._cfg, log=self._logger.add('Plugins'), owner=self) self._duplex_pool = DuplexPool(cfg=self._cfg, log=self._logger.add('DP'), owner=self) self._discovery = DiscoveryServer(cfg=self._cfg, log=self._logger.add('Discovery'))
def setUp(self): configuration = config.Configuration('tests/plugins/test_pluginloader.config.json') self.plugins = Plugins(configuration)
class Disper: # static information name = "disper" version = "0.3.0" prefix = build.prefix prefix_share = build.prefix_share # option parsing argv = [] parser = None # option parser object options = None # parsed options args = None # parsed arguments # real work switcher = None # switcher object plugins = None # plugins object log = None def __init__(self): self.log = logging.getLogger("disper") self.log.setLevel(logging.WARNING) self._options_init() self.plugins = Plugins(self) # self.plugins.call('init') # can't really do here since list of plugins isn't read yet self.switcher = Switcher() # add default options # TODO do initial parsing too so errors can be traced to config conffile = os.path.join(os.getenv("HOME"), ".disper", "config") if os.path.exists(conffile): f = open(conffile, "r") opts = "" for l in f.readlines(): opts += l.split("#", 1)[0] + " " f.close() self.options_append(shlex.split(opts)) def _options_init(self): """initialize default command-line options""" usage = "usage: %prog [options] (-l|-s|-c|-e|-p|-i)" version = " ".join(map(str, [self.name, self.version])) self.parser = optparse.OptionParser(usage=usage, version=version) self.add_option( "-v", "--verbose", action="store_const", dest="debug", const=logging.INFO, help="show what's happening" ) self.add_option( "-q", "--quiet", action="store_const", dest="debug", const=logging.ERROR, help="be quiet and only show errors", ) self.add_option( "-r", "--resolution", dest="resolution", help='set resolution, e.g. "800x600", or "auto" to detect the display\'s preferred ' + 'resolution, or "max" to use the maximum resolution advertised. For extend it ' + "is possible to enter a single resolution for all displays or a comma-separated " + "list of resolutions (one for each display). Beware that many displays advertise " + 'resolutions they can not fully show, so "max" is not advised.', ) self.add_option( "-d", "--displays", dest="displays", help='comma-separated list of displays to operate on, or "auto" to detect; ' + "the first is the primary display.", ) self.add_option( "-t", "--direction", dest="direction", choices=["left", "right", "top", "bottom"], help='where to extend displays: "left", "right", "top", or "bottom"', ) self.add_option( "", "--scaling", dest="scaling", choices=["default", "native", "scaled", "centered", "aspect-scaled"], help='flat-panel scaling mode: "default", "native", "scaled", "centered", or "aspect-scaled"', ) self.add_option( "", "--plugins", dest="plugins", help='comma-separated list of plugins to enable. Special names: "user" for all user plugins ' + 'in ~/.disper/hooks; "all" for all plugins found; "none" for no plugins.', ) self.add_option( "", "--cycle-stages", dest="cycle_stages", help="colon-separated list command-line arguments to cycle through", ) group = optparse.OptionGroup(self.parser, "Actions", "Select exactly one of the following actions") self._add_option( group, "-l", "--list", action="append_const", const="list", dest="actions", help="list the attached displays", ) self._add_option( group, "-s", "--single", action="append_const", const="single", dest="actions", help="only enable the primary display", ) self._add_option( group, "-S", "--secondary", action="append_const", const="secondary", dest="actions", help="only enable the secondary display", ) self._add_option( group, "-c", "--clone", action="append_const", const="clone", dest="actions", help="clone displays" ) self._add_option( group, "-e", "--extend", action="append_const", const="extend", dest="actions", help="extend displays" ) self._add_option( group, "-p", "--export", action="append_const", const="export", dest="actions", help="export current settings to standard output", ) self._add_option( group, "-i", "--import", action="append_const", const="import", dest="actions", help="import current settings from standard input", ) self._add_option( group, "-C", "--cycle", action="append_const", const="cycle", dest="actions", help="cycle through the list of cycle stages", ) self.parser.add_option_group(group) def add_option(self, *args, **kwargs): """adds an option to the parser. Implements append_const for Python<2.5 too""" return self._add_option(self.parser, *args, **kwargs) def _add_option(self, obj, *args, **kwargs): """portable optarg add_option function that implements the append_const action for Python versions below 2.5; has an extra first argument as the object on which add_option should be called.""" if sys.hexversion < 0x020500F0 and "action" in kwargs and kwargs["action"] == "append_const": # after: http://permalink.gmane.org/gmane.comp.python.optik.user/284 def append_const_cb(const): def cb(opt, opt_str, value, parser): if not getattr(parser.values, opt.dest): setattr(parser.values, opt.dest, list()) getattr(parser.values, opt.dest).append(const) return cb kwargs["action"] = "callback" kwargs["callback"] = append_const_cb(kwargs["const"]) del kwargs["const"] return obj.add_option(*args, **kwargs) def options_append(self, args): """parses command-line options; can be called multiple times""" self.argv += args def options_parse(self, args=None): """parses command-line options given; adds options to current list if set""" if args: self.options_append(args) (self.options, self.args) = self.parser.parse_args(self.argv) # need exactly one action if not self.options.actions: self.options.actions = [] elif len(self.options.actions) > 1: self.parser.error( "conflicting actions, please specify exactly one action: " + ", ".join(self.options.actions) ) raise SystemExit(2) if "import" in self.options.actions or "export" in self.options.actions: if self.options.resolution: self.log.warning("specified resolution ignored for %s" % self.options.actions[0]) if self.options.displays: self.log.warning("specified displays ignored for %s" % self.options.actions[0]) # apply defaults here to be able to detect if they were set explicitly or not if not self.options.direction: self.options.direction = "right" if not self.options.resolution: self.options.resolution = "auto" if not self.options.displays: self.options.displays = "auto" if not self.options.scaling: self.options.scaling = "default" if not self.options.debug: self.options.debug = logging.WARNING if self.options.plugins == None: self.options.plugins = "user" self.log.setLevel(self.options.debug) self.options.plugins = map(lambda x: x.strip(), self.options.plugins.split(",")) if self.options.displays != "auto": self.options.displays = map(lambda x: x.strip(), self.options.displays.split(",")) if self.options.resolution not in ["auto", "max"]: self.options.resolution = map(lambda x: x.strip(), self.options.resolution.split(",")) self.plugins.set_enabled(self.options.plugins) def switch(self): """Switch to configuration as specified in the options""" if len(self.options.actions) == 0: self.log.info("no action specified") # show help if no action specified self.parser.print_help() raise SystemExit(2) if "single" in self.options.actions: if self.options.displays != "auto": self.log.warning("specified displays ignored for single") self.switch_primary() elif "secondary" in self.options.actions: if self.options.displays != "auto": self.log.warning("specified displays ignored for secondary") self.switch_secondary() elif "clone" in self.options.actions: self.switch_clone() elif "extend" in self.options.actions: self.switch_extend() elif "export" in self.options.actions: print self.export_config() elif "import" in self.options.actions: self.import_config("\n".join(sys.stdin)) elif "cycle" in self.options.actions: self._cycle(self.options.cycle_stages.split(":")) elif "list" in self.options.actions: # list displays with resolutions displays = self.options.displays if displays == "auto": displays = self.switcher.get_displays() for disp in displays: res = self.switcher.get_resolutions_display(disp) res.sort() print "display %s: %s" % (disp, self.switcher.get_display_name(disp)) print " resolutions: " + str(res) else: self.log.critical("program error, unrecognised action: " + ", ".join(self.options.actions)) raise SystemExit(2) def switch_primary(self, res=None): """Only enable primary display. @param res resolution to use; or 'auto' for default or None for option""" return self.switch_single(self.switcher.get_primary_display()) def switch_secondary(self, res=None): """Only enable secondary display. @param res resolution to use; or 'auto' for default or None for option""" primary = self.switcher.get_primary_display() try: display = [x for x in self.switcher.get_displays() if x != primary][0] except IndexError: self.log.critical("No secondary display found, falling back to primary.") return self.switch_single(primary, res) return self.switch_single(display, res) def switch_single(self, display=None, res=None): """Only enable one display. @param display display to enable; or 'auto' for primary or None for option @param res resolution to use; or 'auto' for default or None for option""" if not display: display = self.options.displays if display == "auto": display = self.switcher.get_primary_display() elif isinstance(display, list) and len(display) > 1: self.log.warning("single output requested but multiple specified; using first one") display = display[0] if display: display = [display] return self.switch_clone(display, res) def switch_clone(self, displays=None, res=None): """Clone displays. @param displays list of displays; or 'auto' for default or None for option @param res resolution; or 'auto' for default, 'max' for max or None for option""" # figure out displays if not displays: displays = self.options.displays if displays == "auto": displays = self.switcher.get_displays() self.log.info("auto-detected displays: " + ", ".join(displays)) else: self.log.info("using specified displays: " + ", ".join(displays)) # figure out resolutions if not res: res = self.options.resolution if type(res) == list or type(res) == tuple: if len(res) != 1: raise TypeError("need single resolution for clone") res = res[0] if res == "auto" or res == "max": r = self.switcher.get_resolutions(displays).common() if len(r) == 0: self.log.critical("displays share no common resolution") raise SystemExit(1) if res == "max": # ignore any preferred resolution for s in r: s.weight = 0 res = sorted(r)[-1] else: res = Resolution(res) # and switch result = self.switcher.switch_clone(displays, res) self.plugins.set_layout_clone(displays, res) self.plugins.call("switch") return result def switch_extend(self, displays=None, direction=None, ress=None): """Extend displays. @param displays list of displays; or 'auto for default or None for option @param direction direction to extend; or None for option @param ress list of resolutions; or 'auto' for default or 'max' for max or None for option""" # figure out displays if not displays: displays = self.options.displays if displays == "auto": displays = self.switcher.get_displays() self.log.info("auto-detected displays: " + ", ".join(displays)) else: self.log.info("using specified displays: " + ", ".join(displays)) # figure out resolutions if not ress: ress = self.options.resolution if ress == "max": # max resolution for each # override auto-detection weights and get highest resolution ress = self.switcher.get_resolutions(displays) for rl in ress.values(): for r in rl: r.weight = 0 ress = ress.select() self.log.info("maximum resolutions for displays: " + str(ress)) elif ress == "auto": # use preferred resolution for each ress = self.switcher.get_resolutions(displays).select() self.log.info("preferred resolutions for displays: " + str(ress)) else: # list of resolutions specified ress = ResolutionSelection(ress, displays) if len(ress) == 1: ress = ress * len(displays) elif len(ress) != len(displays): self.log.critical( 'resolution: must specify either "auto", "max", a single value, or one for each display' ) raise SystemExit(2) self.log.info("selected resolutions for displays: " + str(ress)) # figure out direction if not direction: direction = self.options.direction # and switch result = self.switcher.switch_extend(displays, direction, ress) self.plugins.set_layout_extend(displays, direction, ress) self.plugins.call("switch") return result def export_config(self): return self.switcher.export_config() def import_config(self, data): result = self.switcher.import_config(data) self.plugins.call("switch") return result def _cycle(self, stages): # read last state stage = 0 disperconf = os.path.join(os.getenv("HOME"), ".disper") statefile = os.path.join(disperconf, "last_cycle_stage") if os.path.exists(statefile): f = open(statefile, "r") stage = int(f.readline()) f.close() # apply next stage += 1 if stage >= len(stages): stage = 0 self.argv = filter(lambda x: x != "-C" and x != "--cycle", self.argv) self.options_parse(shlex.split(stages[stage])) try: self.switch() finally: # write new state to file; do it here to make sure that a # failing configuration doesn't block the cycling if not os.path.exists(disperconf): os.mkdir(disperconf) f = open(statefile, "w") f.write(str(stage) + "\n") f.close()
class Disper: # static information name = 'disper' version = '0.3.1' prefix = build.prefix prefix_share = build.prefix_share # option parsing argv = [] parser = None # option parser object options = None # parsed options args = None # parsed arguments # real work _switcher = None # switcher object, see Disper.switcher() plugins = None # plugins object log = None conffile = None # last configuration file read def __init__(self): self.log = logging.getLogger('disper') self.log.setLevel(logging.WARNING) self._options_init() self.plugins = Plugins(self) #self.plugins.call('init') # can't really do here since list of plugins isn't read yet # add default options # TODO do initial parsing too so errors can be traced to config self.options_append(self.config_read_default()) def _options_init(self): '''initialize default command-line options''' usage = "usage: %prog [options] (-l|-s|-c|-e|-p|-i)" version = ' '.join(map(str, [self.name, self.version])) self.parser = optparse.OptionParser(usage=usage, version=version) self.add_option('-v', '--verbose', action='store_const', dest='debug', const=logging.INFO, help='show what\'s happening') self.add_option('-q', '--quiet', action='store_const', dest='debug', const=logging.ERROR, help='be quiet and only show errors') self.add_option( '-r', '--resolution', dest='resolution', help= 'set resolution, e.g. "800x600", or "auto" to detect the display\'s preferred ' + 'resolution, "max" to use the maximum resolution advertised, or "off" to disable ' + 'the display entirely. For extend it is possible to enter a single resolution for ' + 'all displays or a comma-separated list of resolutions (one for each display). ' + 'Beware that many displays advertise resolutions they can not fully show, ' + 'so "max" is not advised.') self.add_option( '-d', '--displays', dest='displays', help= 'comma-separated list of displays to operate on, or "auto" to detect; ' + 'the first is the primary display.') self.add_option( '-t', '--direction', dest='direction', choices=['left', 'right', 'top', 'bottom'], help='where to extend displays: "left", "right", "top", or "bottom"' ) self.add_option( '', '--scaling', dest='scaling', choices=[ 'default', 'native', 'scaled', 'centered', 'aspect-scaled' ], help= 'flat-panel scaling mode: "default", "native", "scaled", "centered", or "aspect-scaled"' ) self.add_option( '', '--plugins', dest='plugins', help= 'comma-separated list of plugins to enable. Special names: "user" for all user plugins ' + 'in %s/hooks; "all" for all plugins found; "none" for no plugins.' % (os.environ.get('XDG_CONFIG_HOME', os.path.join('~', '.config', 'disper')))) self.add_option( '', '--cycle-stages', dest='cycle_stages', default='-c:-s:-S', help= 'colon-separated list command-line arguments to cycle through; "-S:-c:-s" by default' ) group = optparse.OptionGroup( self.parser, 'Actions', 'Select exactly one of the following actions') self._add_option(group, '-l', '--list', action='append_const', const='list', dest='actions', help='list the attached displays') self._add_option(group, '-s', '--single', action='append_const', const='single', dest='actions', help='only enable the primary display') self._add_option(group, '-S', '--secondary', action='append_const', const='secondary', dest='actions', help='only enable the secondary display') self._add_option(group, '-c', '--clone', action='append_const', const='clone', dest='actions', help='clone displays') self._add_option(group, '-e', '--extend', action='append_const', const='extend', dest='actions', help='extend displays') self._add_option(group, '-p', '--export', action='append_const', const='export', dest='actions', help='export current settings to standard output') self._add_option(group, '-i', '--import', action='append_const', const='import', dest='actions', help='import current settings from standard input') self._add_option(group, '-C', '--cycle', action='append_const', const='cycle', dest='actions', help='cycle through the list of cycle stages') self.parser.add_option_group(group) def add_option(self, *args, **kwargs): '''adds an option to the parser. Implements append_const for Python<2.5 too''' return self._add_option(self.parser, *args, **kwargs) def _add_option(self, obj, *args, **kwargs): '''portable optarg add_option function that implements the append_const action for Python versions below 2.5; has an extra first argument as the object on which add_option should be called.''' if sys.hexversion < 0x020500f0 and 'action' in kwargs and \ kwargs['action'] == 'append_const': # after: http://permalink.gmane.org/gmane.comp.python.optik.user/284 def append_const_cb(const): def cb(opt, opt_str, value, parser): if not getattr(parser.values, opt.dest): setattr(parser.values, opt.dest, list()) getattr(parser.values, opt.dest).append(const) return cb kwargs['action'] = 'callback' kwargs['callback'] = append_const_cb(kwargs['const']) del kwargs['const'] return obj.add_option(*args, **kwargs) def options_append(self, args): '''parses command-line options; can be called multiple times''' self.argv += args def options_parse(self, args=None): '''parses command-line options given; adds options to current list if set''' if args: self.options_append(args) (self.options, self.args) = self.parser.parse_args(self.argv) # need exactly one action if not self.options.actions: self.options.actions = [] elif len(self.options.actions) > 1: self.parser.error( 'conflicting actions, please specify exactly one action: ' + ', '.join(self.options.actions)) raise SystemExit(2) if 'import' in self.options.actions or 'export' in self.options.actions: if self.options.resolution: self.log.warning('specified resolution ignored for %s' % self.options.actions[0]) if self.options.displays: self.log.warning('specified displays ignored for %s' % self.options.actions[0]) # apply defaults here to be able to detect if they were set explicitly or not if not self.options.direction: self.options.direction = "right" if not self.options.resolution: self.options.resolution = "auto" if not self.options.displays: self.options.displays = "auto" if not self.options.scaling: self.options.scaling = "default" if not self.options.debug: self.options.debug = logging.WARNING if self.options.plugins == None: self.options.plugins = "user" self.log.setLevel(self.options.debug) self.options.plugins = map(lambda x: x.strip(), self.options.plugins.split(',')) if self.options.displays != 'auto': self.options.displays = map(lambda x: x.strip(), self.options.displays.split(',')) if self.options.resolution not in ['auto', 'max', 'off']: self.options.resolution = map(lambda x: x.strip(), self.options.resolution.split(',')) self.plugins.set_enabled(self.options.plugins) def config_read_default(self): '''Return default options from configuration files''' # Read old-style and XDG-style configuration files home = os.environ.get('HOME', '/') xdg_config_dirs = [os.path.join(home, '.disper')] + \ [os.environ.get('XDG_CONFIG_HOME', os.path.join(home, '.config', 'disper'))] + \ os.environ.get('XDG_CONFIG_DIRS', '/etc/xdg/disper').split(':') xdg_config_dirs = filter(lambda x: x and os.path.exists(x), xdg_config_dirs) # since later configuration files override previous ones, reverse order of reading # TODO allow override of action, since multiple actions would now conflict xdg_config_dirs = reversed(xdg_config_dirs) opts = '' for d in xdg_config_dirs: conffile = os.path.join(d, 'config') if not os.path.exists(conffile): continue f = open(conffile, 'r') opts = '' for l in f.readlines(): opts += l.split('#', 1)[0] + ' ' f.close() # remember which configuration file was read last self.conffile = conffile return shlex.split(opts) def switch(self): '''Switch to configuration as specified in the options''' if len(self.options.actions) == 0: self.log.info('no action specified') # show help if no action specified self.parser.print_help() raise SystemExit(2) if 'single' in self.options.actions: self.switch_primary() elif 'secondary' in self.options.actions: self.switch_secondary() elif 'clone' in self.options.actions: self.switch_clone() elif 'extend' in self.options.actions: self.switch_extend() elif 'export' in self.options.actions: print self.export_config() elif 'import' in self.options.actions: self.import_config('\n'.join(sys.stdin)) elif 'cycle' in self.options.actions: self._cycle(self.options.cycle_stages.split(':')) elif 'list' in self.options.actions: # list displays with resolutions displays = self.options.displays if displays == 'auto': displays = self.switcher().get_displays() for disp in displays: res = self.switcher().get_resolutions_display(disp) res.sort() print 'display %s: %s' % ( disp, self.switcher().get_display_name(disp)) print ' resolutions: ' + str(res) else: self.log.critical('program error, unrecognised action: ' + ', '.join(self.options.actions)) raise SystemExit(2) def switch_primary(self, res=None): '''Only enable primary display. @param res resolution to use; or 'auto' for default or None for option''' if self.options.displays and self.options.displays != 'auto': return self.switch_single(self.options.displays[0]) else: return self.switch_single(self.switcher().get_primary_display()) def switch_secondary(self, res=None): '''Only enable secondary display. @param res resolution to use; or 'auto' for default or None for option''' if self.options.displays and self.options.displays != 'auto': if len(self.options.displays) >= 2: return self.switch_single(self.options.displays[1]) else: self.log.critical( 'No secondary display found, falling back to primary.') return self.switch_single(self.options.displays[0]) else: primary = self.switcher().get_primary_display() try: display = [ x for x in self.switcher().get_displays() if x != primary ][0] except IndexError: self.log.critical( 'No secondary display found, falling back to primary.') return self.switch_single(primary, res) return self.switch_single(display, res) def switch_single(self, display=None, res=None): '''Only enable one display. @param display display to enable; or 'auto' for primary or None for option @param res resolution to use; or 'auto' for default or None for option''' if not display: display = self.options.displays if display == 'auto': display = self.switcher().get_primary_display() elif isinstance(display, list) and len(display) > 1: self.log.warning( 'single output requested but multiple specified; using first one' ) display = display[0] if display: display = [display] return self.switch_clone(display, res) def switch_clone(self, displays=None, res=None): '''Clone displays. @param displays list of displays; or 'auto' for default or None for option @param res resolution; or 'auto' for default, 'max' for max, 'off' to disable the display, 'none' or None for option''' # figure out displays if not displays: displays = self.options.displays if displays == 'auto': displays = self.switcher().get_displays() self.log.info('auto-detected displays: ' + ', '.join(displays)) else: self.log.info('using specified displays: ' + ', '.join(displays)) # figure out resolutions if not res: res = self.options.resolution if type(res) == list or type(res) == tuple: if len(res) != 1: raise TypeError('need single resolution for clone') res = res[0] if res in ['auto', 'max']: r = self.switcher().get_resolutions(displays).common() if len(r) == 0: self.log.critical('displays share no common resolution') raise SystemExit(1) if res == 'max': # ignore any preferred resolution for s in r: s.weight = 0 res = sorted(r)[-1] else: res = Resolution(res) # and switch result = self.switcher().switch_clone(displays, res) self.plugins.set_layout_clone(displays, res) self.plugins.call('switch') return result def switch_extend(self, displays=None, direction=None, ress=None): '''Extend displays. @param displays list of displays; or 'auto for default or None for option @param direction direction to extend; or None for option @param ress list of resolutions; or 'auto' for default or 'max' for max or None for option''' # figure out displays if not displays: displays = self.options.displays if displays == 'auto': displays = self.switcher().get_displays() self.log.info('auto-detected displays: ' + ', '.join(displays)) else: self.log.info('using specified displays: ' + ', '.join(displays)) # figure out resolutions if not ress: ress = self.options.resolution if ress == 'max': # max resolution for each # override auto-detection weights and get highest resolution ress = self.switcher().get_resolutions(displays) for rl in ress.values(): for r in rl: r.weight = 0 ress = ress.select() self.log.info('maximum resolutions for displays: ' + str(ress)) elif ress == 'auto': # use preferred resolution for each ress = self.switcher().get_resolutions(displays).select() self.log.info('preferred resolutions for displays: ' + str(ress)) else: # list of resolutions specified ress = ResolutionSelection(ress, displays) if len(ress) == 1: ress = ress * len(displays) elif len(ress) != len(displays): self.log.critical( 'resolution: must specify either "auto", "max", a single value, or one for each display' ) raise SystemExit(2) self.log.info('selected resolutions for displays: ' + str(ress)) # figure out direction if not direction: direction = self.options.direction # and switch result = self.switcher().switch_extend(displays, direction, ress) self.plugins.set_layout_extend(displays, direction, ress) self.plugins.call('switch') return result def export_config(self): return self.switcher().export_config() def import_config(self, data): result = self.switcher().import_config(data) self.plugins.call('switch') return result def _cycle(self, stages): # read last state stage = 0 disperconf = None # TODO use X root window hint instead of file (which doesn't adhere to XDG) if self.conffile: disperconf = os.path.dirname(self.conffile) else: home = os.environ.get('HOME', '/') disperconf = os.environ.get( 'XDG_CONFIG_HOME', os.path.join(home, '.config', 'disper')) statefile = os.path.join(disperconf, 'last_cycle_stage') self.log.debug('Cycle state file: ' + statefile) if os.path.exists(statefile): f = open(statefile, 'r') stage = int(f.readline()) f.close() # apply next stage += 1 if stage >= len(stages): stage = 0 self.argv = filter(lambda x: x != '-C' and x != '--cycle', self.argv) self.options_parse(shlex.split(stages[stage])) try: self.switch() finally: # write new state to file; do it here to make sure that a # failing configuration doesn't block the cycling if not os.path.exists(disperconf): self.log.info( 'Creating disper configuration directory for statefile: ' + disperconf) os.mkdir(disperconf) f = open(statefile, 'w') f.write(str(stage) + '\n') f.close() def switcher(self): '''Return switcher object (singleton). This is implemented as a method, so that it can be created only when needed to avoid errors when displaying help.''' if not self._switcher: self._switcher = Switcher() return self._switcher
class pyTrainer: def __init__(self,filename = None, data_path = None): #Version constants self.version ="1.10.0-dev" #Process command line options self.startup_options = self.get_options() #Setup logging self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None # Checking profile logging.debug('Checking configuration and profile...') self.profile = Profile(self.environment, self.data_path,self) self.uc = UC() self.windowmain = None self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() initialize_data(self.ddbb, self.environment.conf_dir) self._sport_service = SportService(self.ddbb) self.record = Record(self._sport_service, data_path, self) self.athlete = Athlete(data_path,self) self.stats = Stats(self._sport_service, self) pool_size = self.profile.getIntValue("pytraining","activitypool_size", default=1) self.activitypool = ActivityPool(self, size=pool_size) #preparamos la ventana principal self.windowmain = Main(self._sport_service, data_path,self,self.version, gpxDir=self.profile.gpxdir) self.date = Date(self.windowmain.calendar) self.waypoint = Waypoint(data_path,self) self.extension = Extension(data_path, self) self.plugins = Plugins(data_path, self) self.importdata = Importdata(self._sport_service, data_path, self, self.profile) self.loadPlugins() self.loadExtensions() self.windowmain.setup() self.windowmain.on_calendar_selected(None) self.refreshMainSportList() self.windowmain.run() logging.debug('<<') def get_options(self): ''' Define usage and accepted options for command line startup returns: options - dict with option: value pairs ''' usage = '''usage: %prog [options] For more help on valid options try: %prog -h ''' parser = OptionParser(usage=usage) parser.set_defaults(log_level=logging.ERROR, validate=False, equip=False, newgraph=True, conf_dir=None, log_type="file") parser.add_option("-d", "--debug", action="store_const", const=logging.DEBUG, dest="log_level", help="enable logging at debug level") parser.add_option("-i", "--info", action="store_const", const=logging.INFO, dest="log_level", help="enable logging at info level") parser.add_option("-w", "--warn", action="store_const", const=logging.WARNING, dest="log_level", help="enable logging at warning level") parser.add_option("--valid", action="store_true", dest="validate", help="enable validation of files imported by plugins (details at info or debug logging level) - note plugin must support validation") parser.add_option("--oldgraph", action="store_false", dest="newgraph", help="Turn off new graphing approach") parser.add_option("--newgraph", action="store_true", dest="newgraph", help="Deprecated Option: Turn on new graphing approach") parser.add_option("--confdir", dest="conf_dir", help="Specify the directory where application configuration will be stored.") parser.add_option("--logtype", dest="log_type", metavar="TYPE", type="choice" , choices=["file", "console"], help="Specify where logging should be output to. TYPE is one of 'file' (default), or 'console'.") (options, args) = parser.parse_args() return options def set_logging(self, level, log_type): '''Setup rotating log file with customized format''' if("console" == log_type): handler = logging.StreamHandler(sys.stdout) else: handler = logging.handlers.RotatingFileHandler(self.environment.log_file, maxBytes=100000, backupCount=5) formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(module)s|%(funcName)s|%(message)s') handler.setFormatter(formatter) logging.getLogger('').addHandler(handler) self.set_logging_level(self.startup_options.log_level) def set_logging_level(self, level): '''Set level of information written to log''' logging.debug("Setting logger to level: "+ str(level)) logging.getLogger('').setLevel(level) def quit(self): logging.debug('--') logging.info("Exit!") #self.webservice.stop() self.windowmain.gtk_main_quit() logging.shutdown() sys.exit() # Any nonzero value is considered "abnormal termination" by shells and the like def loadPlugins(self): logging.debug('>>') activeplugins = self.plugins.getActivePlugins() if (len(activeplugins)<1): logging.info("No active plugins") else: for plugin in activeplugins: txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.addImportPlugin(txtbutton) logging.debug('<<') def loadExtensions(self): logging.debug('>>') activeextensions = self.extension.getActiveExtensions() if (len(activeextensions)<1): logging.info("No active extensions") else: for extension in activeextensions: txtbutton = self.extension.loadExtension(extension) self.windowmain.addExtension(txtbutton) logging.debug('<<') def runPlugin(self,widget,pathPlugin): logging.debug('>>') self.pluginClass = self.plugins.importClass(pathPlugin) pluginFiles = self.pluginClass.run() if pluginFiles is not None: logging.debug("Plugin returned %d files" % (len(pluginFiles)) ) #process returned GPX files for (pluginFile, sport) in pluginFiles: if os.path.isfile(pluginFile): logging.info('File exists. Size: %d. Sport: %s' % (os.path.getsize(pluginFile), sport)) if self.record.importFromGPX(pluginFile, sport) is None: logging.error("Error importing file "+pluginFile) else: logging.error('File '+pluginFile+' not valid') else: logging.debug("No files returned from Plugin") self.refreshListRecords() self.refreshGraphView("day") logging.debug('<<') def runExtension(self,extension,id): logging.debug('>>') #print("Extension id: %s" % str(id)) activity = self.activitypool.get_activity(id) txtbutton,pathExtension,type = extension self.extensionClass = self.extension.importClass(pathExtension) self.extensionClass.run(id, activity) #if type == "record": # #Si es record le tenemos que crear el googlemaps, el gpx y darle el id de la bbdd # alert = self.extension.runExtension(pathExtension,id) logging.debug('<<') def refreshMainSportList(self): logging.debug('>>') sports = self._sport_service.get_all_sports() self.windowmain.updateSportList(sports) logging.debug('<<') def refreshGraphView(self, view, sport=None): logging.debug('>>') if self.windowmain is None: logging.debug("First call to refreshGraphView") logging.debug('<<') return date_selected = self.date.getDate() if view=="record": logging.debug('record view') if self.windowmain.recordview.get_current_page()==0: self.refreshRecordGraphView("info") elif self.windowmain.recordview.get_current_page()==1: self.refreshRecordGraphView("graphs") elif self.windowmain.recordview.get_current_page()==2: self.refreshRecordGraphView("map") elif self.windowmain.recordview.get_current_page()==3: self.refreshRecordGraphView("heartrate") elif self.windowmain.recordview.get_current_page()==4: self.refreshRecordGraphView("analytics") elif view=="day": logging.debug('day view') sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordList(date_selected, sport_id) self.windowmain.actualize_dayview(record_list=record_list) #selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() elif view=="week": logging.debug('week view') date_range = DateRange.for_week_containing(date_selected) sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordPeriod(date_range, sport_id) self.windowmain.actualize_weekview(record_list, date_range) elif view=="month": logging.debug('month view') date_range = DateRange.for_month_containing(date_selected) sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordPeriod(date_range, sport_id) nameMonth, daysInMonth = self.date.getNameMonth(date_selected) self.windowmain.actualize_monthview(record_list, nameMonth) self.windowmain.actualize_monthgraph(record_list, daysInMonth) elif view=="year": logging.debug('year view') date_range = DateRange.for_year_containing(date_selected) sport = self.windowmain.activeSport sport_id = self.record.getSportId(sport) record_list = self.record.getrecordPeriod(date_range, sport_id) self.windowmain.actualize_yearview(record_list, date_selected.year) self.windowmain.actualize_yeargraph(record_list) elif view=="listview": logging.debug('list view') self.refreshListView() elif view=="athlete": logging.debug('athlete view') self.windowmain.on_athleteview_activate() elif view=="stats": logging.debug('stats view') self.windowmain.on_statsview_activate() else: print "Unknown view %s" % view logging.debug('<<') def refreshRecordGraphView(self, view, id_record=None): logging.debug('>>') logging.info('Working on '+view+' graph') if id_record is not None: #Refresh called for a specific record #Select correct record in treeview model = self.windowmain.recordTreeView.get_model() #Loop through all records in treeview looking for the correct one to highlight for i,row in enumerate(model): if row[0] == id_record: self.windowmain.recordTreeView.set_cursor(i) else: selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() if iter: id_record = selected.get_value(iter,0) else: id_record = None view="info" activity = self.activitypool.get_activity(id_record) if view=="info": self.windowmain.actualize_recordview(activity) if view=="graphs": self.windowmain.actualize_recordgraph(activity) if view=="map": self.refreshMapView() if view=="heartrate": self.windowmain.actualize_heartrategraph(activity) self.windowmain.actualize_hrview(activity) if view=="analytics": self.windowmain.actualize_analytics(activity) logging.debug('<<') def refreshMapView(self, full_screen=False): logging.debug('>>') if self.windowmain is None: logging.debug('Called before windowmain initialisation') logging.debug('<<') return selected,iter = self.windowmain.recordTreeView.get_selection().get_selected() id_record = selected.get_value(iter,0) activity = self.activitypool.get_activity(id_record) logging.debug('Trying to show map for record '+str(id_record)) self.windowmain.actualize_map(activity, full_screen) logging.debug('<<') def refreshListRecords(self): logging.debug('>>') #Refresh list view #self.refreshListView() # old variant self.refreshListView(self.windowmain.listsearch.condition) #Refresh list records date = self.date.getDate() sport = self.windowmain.activeSport id_sport = self.record.getSportId(sport) record_ids = self.record.getrecordList(date, id_sport) self.windowmain.actualize_recordTreeView(record_ids) #Mark the monthly calendar to show which days have activity? record_list = self.record.getRecordDayList(date, id_sport) self.windowmain.actualize_calendar(record_list) logging.debug('<<') def refreshAthleteView(self): logging.debug('>>') self.athlete.refresh() self.windowmain.actualize_athleteview(self.athlete) logging.debug('<<') def refreshStatsView(self): logging.debug('>>') self.stats.refresh() self.windowmain.actualize_statsview(self.stats, self.record.getAllRecordList()) logging.debug('<<') def refreshListView(self,condition=None): logging.debug('>>') record_list = self.record.getRecordListByCondition(condition) self.windowmain.actualize_listview(record_list) logging.debug('<<') def refreshWaypointView(self,default_waypoint=None,redrawmap=1): logging.debug('>>') waypoint_list = self.waypoint.getAllWaypoints() self.windowmain.actualize_waypointview(waypoint_list,default_waypoint,redrawmap) logging.debug('<<') def editExtensions(self): logging.debug('>>') before = self.extension.getActiveExtensions() self.extension.manageExtensions() after = self.extension.getActiveExtensions() self.setExtensions(before, after) logging.debug('<<') def importData(self): logging.debug('>>') activeplugins_before = self.plugins.getActivePlugins() self.importdata.runImportdata() activeplugins_after = self.plugins.getActivePlugins() #Need to check for plugins that have been disabled (were active and now are not) self.setMenuPlugins(activeplugins_before, activeplugins_after) self.refreshListRecords() self.refreshGraphView(self.windowmain.selected_view) logging.debug('<<') def editGpsPlugins(self): logging.debug('>>') activeplugins_before = self.plugins.getActivePlugins() self.plugins.managePlugins() activeplugins_after = self.plugins.getActivePlugins() #Need to check for plugins that have been disabled (were active and now are not) self.setMenuPlugins(activeplugins_before, activeplugins_after) logging.debug('<<') def setMenuPlugins(self, activeplugins_before, activeplugins_after): logging.debug('>>') #Need to check for plugins that have been disabled (were active and now are not) for plugin in activeplugins_before: if plugin not in activeplugins_after: #disabled plugin -> need to unload plugin txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.removeImportPlugin(txtbutton) #Need to check for plugins that have been enabled (were not active and now are) for plugin in activeplugins_after: if plugin not in activeplugins_before: #new active plugin -> need to load plugin txtbutton = self.plugins.loadPlugin(plugin) self.windowmain.addImportPlugin(txtbutton) logging.debug('<<') def setExtensions(self, before, after): logging.debug('>>') #Need to check for extensions that have been disabled (were active and now are not) for extension in before: if extension not in after: #disabled extension -> need to unload extension print "Need to disable extension %s " % extension txtbutton = self.extension.loadExtension(extension) self.windowmain.removeExtension(txtbutton) #Need to check for plugins that have been enabled (were not active and now are) for extension in after: if extension not in before: #new active extension -> need to load extension logging.debug("Enabling extension %s " % extension) txtbutton = self.extension.loadExtension(extension) self.windowmain.addExtension(txtbutton) logging.debug('<<') def newRecord(self,title=None,distance=None,time=None,upositive=None,unegative=None,bpm=None,calories=None,comment=None,view=None): logging.debug('>>') date = self.date.getDate() self.record.newRecord(date, title, distance, time, upositive, unegative, bpm, calories, comment) self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def editRecord(self, id_record, view=None): logging.debug("Editing record with id: '%s'", id_record) self.record.editRecord(id_record) self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def removeRecord(self, id_record, confirm = False, view=None): logging.debug('>>') if confirm: self.record.removeRecord(id_record) else: msg = _("Delete this database entry?") params = [id_record,True] warning = Warning(self.data_path,self.removeRecord,params) warning.set_text(msg) warning.run() self.refreshListRecords() if view is not None: self.refreshGraphView(view) logging.debug('<<') def removeWaypoint(self,id_waypoint, confirm = False): logging.debug('>>') if confirm: self.waypoint.removeWaypoint(id_waypoint) self.refreshWaypointView() else: msg = _("Delete this waypoint?") params = [id_waypoint,True] warning = Warning(self.data_path,self.removeWaypoint,params) warning.set_text(msg) warning.run() logging.debug('<<') def updateWaypoint(self,id_waypoint,lat,lon,name,desc,sym): logging.debug('>>') self.waypoint.updateWaypoint(id_waypoint,lat,lon,name,desc,sym) self.refreshWaypointView(id_waypoint) logging.debug('<<') def exportCsv(self): logging.debug('>>') from save import Save save = Save(self.data_path, self.record) save.run() logging.debug('<<') def editProfile(self): logging.debug('>>') self.profile.editProfile(self._sport_service) self.activitypool.clear_pool() self.windowmain.setup() logging.debug('<<')
def setUp(self): configuration = config.Configuration( 'tests/plugins/test_pluginloader.config.json') self.plugins = Plugins(configuration)
credential_key = getpass.getpass('Credential Key:') credential_manager = CredentialManager(credentials_file, credential_key) config.credential_manager = credential_manager ## -- test just resets the db everytime -- from models import Base from db import engine if not settings.in_production(): Base.metadata.drop_all(engine) Base.metadata.create_all(engine) from repos import repotracker from plugins import RepoWatcher, Plugins from plugins.base import PluginTestError #-- Load plugins loaded_plugins = Plugins(configuration) if args.tests: print "======================= Loading plugins =======================" plugins = loaded_plugins.enabled_plugins() print "======================= Running Plugin Tests =======================" for plugin_area in plugins: for plugin in plugins[plugin_area]: print "Running test for ", plugin.__module__ try: plugin.test() except PluginTestError, pte: print "Test Failed for ", plugin.__module__ print pte.message sys.exit(1)