def load(self): """ Loads a task if the active file is available. """ try: _parser = parser.parse_config(self._paths['active_file'], self.HEADER_ACTIVE_FILE) # parse expected options into a dict to de-dupe keys = ('name', 'start_time') opts = dict(o for o in _parser.options if o[0] in keys) # check for all keys for k in keys: if not opts.get(k): return False task_name = opts.get('name')[0] # setup the paths task_dir = self._get_task_dir(task_name) task_config = os.path.join(task_dir, 'task.cfg') # validate start time value = opts.get('start_time')[0] start_time = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S.%f') # get user id for process ownership when running task # here, we use the owner of the active file file_meta = os.stat(self._paths['active_file']) owner = file_meta.st_uid # parse task config and send its options to registered plugins _parser = parser.parse_config(task_config, self.HEADER_TASK_CONFIG) registration.run_option_hooks(_parser) self._name = common.from_utf8(task_name) self._start_time = start_time self._owner = owner self._paths['task_dir'] = task_dir self._paths['task_config'] = task_config self._loaded = True except (parser.ParseError, ValueError, TypeError, OSError): # something failed, cleanup self._clean() self._clean_prior() return self._loaded
def test__parse_config(self): """ parser.parse_config: check for proper errors raised. """ # raises, missing file with self.assertRaises(parser.ParseError): parser.parse_config('non_exist', 'header-name') # raises, good file, mismatched header value with self.assertRaises(parser.ParseError): parser.parse_config(self.test_config, 'wrong_header_value') # all good.. returns parser self.assertIsInstance(parser.parse_config(self.test_config, 'header_value'), parser.SettingParser)
def test__parse_config(self): """ parser.parse_config: check for proper errors raised. """ # raises, missing file with self.assertRaises(parser.ParseError): parser.parse_config('non_exist', 'header-name') # raises, good file, mismatched header value with self.assertRaises(parser.ParseError): parser.parse_config(self.test_config, 'wrong_header_value') # all good.. returns parser self.assertIsInstance( parser.parse_config(self.test_config, 'header_value'), parser.SettingParser)
def get_list_info(self, task_name=None): """ Lists all tasks and associated information. `task_name` Task name to limit. Default: return all valid tasks. Returns list of tuples (task_name, options, block_options) """ try: tasks = [] # get all tasks dirs tasks_dir = os.path.join(self._paths['base_dir'], 'tasks') if task_name: # if task folder doesn't exist, return nothing if not os.path.isdir(os.path.join(tasks_dir, task_name)): return [] task_names = [task_name] else: task_names = [ name for name in os.listdir(tasks_dir) if os.path.isdir(os.path.join(tasks_dir, name)) ] task_names.sort() for name in task_names: try: # parse task config and run option hooks task_config = os.path.join(tasks_dir, name, 'task.cfg') parser_ = parser.parse_config(task_config, self.HEADER_TASK_CONFIG) registration.run_option_hooks(parser_, disable_missing=False) tasks.append((name, parser_.options, parser_.blocks)) except (parser.ParseError, errors.InvalidTaskConfig): tasks.append((name, None, None)) return tasks except OSError: return []
def _edit_file(filename): """ Launches editor for given filename. """ proc = subprocess.Popen("{0} {1}".format(editor, filename), shell=True) proc.communicate() if proc.returncode == 0: try: # parse temp configuration file parser_ = parser.parse_config(filename, "task") registration.run_option_hooks(parser_, disable_missing=False) except (parser.ParseError, errors.InvalidTaskConfig) as exc: reason = unicode(getattr(exc, "reason", exc)) raise errors.InvalidTaskConfig(task_config, reason=reason) return True else: return False
def _edit_file(filename): """ Launches editor for given filename. """ proc = subprocess.Popen('{0} {1}'.format(editor, filename), shell=True) proc.communicate() if proc.returncode == 0: try: # parse temp configuration file parser_ = parser.parse_config(filename, 'task') registration.run_option_hooks(parser_, disable_missing=False) except (parser.ParseError, errors.InvalidTaskConfig) as exc: reason = unicode(getattr(exc, 'reason', exc)) raise errors.InvalidTaskConfig(task_config, reason=reason) return True else: return False
def get_list_info(self, task_name=None): """ Lists all tasks and associated information. `task_name` Task name to limit. Default: return all valid tasks. Returns list of tuples (task_name, options, block_options) """ try: tasks = [] # get all tasks dirs tasks_dir = os.path.join(self._paths['base_dir'], 'tasks') if task_name: # if task folder doesn't exist, return nothing if not os.path.isdir(os.path.join(tasks_dir, task_name)): return [] task_names = [task_name] else: task_names = [name for name in os.listdir(tasks_dir) if os.path.isdir(os.path.join(tasks_dir, name))] task_names.sort() for name in task_names: try: # parse task config and run option hooks task_config = os.path.join(tasks_dir, name, 'task.cfg') parser_ = parser.parse_config(task_config, self.HEADER_TASK_CONFIG) registration.run_option_hooks(parser_, disable_missing=False) tasks.append((name, parser_.options, parser_.blocks)) except (parser.ParseError, errors.InvalidTaskConfig): tasks.append((name, None, None)) return tasks except OSError: return []
def start(self, task_name): """ Starts a new task matching the provided name. `task_name` Name of existing task to start. Returns boolean. * Raises a ``TaskNotFound`` exception if task doesn't exist, an ``InvalidTaskConfig` exception if task config file is invalid, or ``DaemonFailStart`` exception if task daemons failed to fork. """ self._clean_prior() if self._loaded: raise errors.ActiveTask # get paths task_dir = os.path.join(self._paths['base_dir'], 'tasks', task_name) task_config = os.path.join(task_dir, 'task.cfg') if not os.path.isdir(task_dir): raise errors.TaskNotFound(task_name) try: # raise if task config is missing if not os.path.isfile(task_config): reason = u"Config file could not be found." raise errors.InvalidTaskConfig(task_config, reason=reason) # parse task config and send its options to registered plugins _parser = parser.parse_config(task_config, self.HEADER_TASK_CONFIG) registration.run_option_hooks(_parser) except parser.ParseError as exc: raise errors.InvalidTaskConfig(task_config, reason=unicode(exc)) # populate task info self._name = common.from_utf8(task_name) self._start_time = datetime.datetime.now() self._owner = os.getuid() self._paths['task_dir'] = task_dir self._paths['task_config'] = task_config self._loaded = True # task is setup, save active file # note, order is *important*; this is needed first # for the daemon to load self._save_active_file() # shell the focusd daemon try: started = daemon.shell_focusd(self._paths['base_dir']) # user cancelled or passwords failed? except (KeyboardInterrupt, ValueError): self._clean() return False # no event plugins registered, carry on except errors.NoPluginsRegistered: return True # failed, cleanup our mess if not started: self._clean() raise errors.DaemonFailStart return True