def _complete(self, spec, relative_to=None): in_spec = self.spec.strip().strip(PTaskSpec.SEPARATOR) full_spec = PTaskSpec.get(in_spec, relative_to=relative_to) ptask_area = None # is the supplied spec a ptask area? if so, print sub directories # if not, get the parent spec and print its sub directories try: ptask_area = PTaskArea(full_spec) except PTaskAreaError: in_spec = PTaskSpec.parent(in_spec) full_spec = PTaskSpec.parent(full_spec) try: ptask_area = PTaskArea(full_spec) except PTaskAreaError: pass if not ptask_area: return # append the child name to the input spec and print them out for completion match_specs = [] for area_dir in ptask_area.dirs(children=True, product_dirs=True): if in_spec: match_specs.append(in_spec + PTaskSpec.SEPARATOR + area_dir) else: match_specs.append(area_dir) return [m + PTaskSpec.SEPARATOR for m in match_specs]
def _create_ptask(self): parent = PTaskSpec.parent(self.spec) name = PTaskSpec.name(self.spec) # create if not self.ptask: try: self.logger.debug("Creating ptask: " + str(self.spec)) self._ptask = PTask.create( name, self.ptask_type, self.description, creator_username=self.creator, parent_spec=parent, start_date=str(self.start_date), due_date=str(self.due_date), ) except PTaskError as e: raise ActionError("Failed to create ptask: " + str(e)) # update else: try: self.logger.debug("Updating ptask: " + str(self.spec)) self.ptask.update( description=self.description, start_date=str(self.start_date), due_date=str(self.due_date), ) except PTaskError as e: raise ActionError("Failed to update ptask: " + str(e))
def siblings(self): parent_spec = PTaskSpec.parent(self.spec) try: parent_area = PTaskArea(parent_spec) except PTaskAreaError: return [] return [c for c in parent_area.children if c.spec != self.spec]
def __init__(self, spec, ptask_type=None, description=None, creator=None, start_date=None, due_date=None, source=None, force=True): super(PTaskCreateAction, self).__init__( spec, ptask_type=ptask_type, description=description, creator=creator, start_date=start_date, due_date=due_date, source=source, force=force, ) # allow calling code to override the target to specify the ptask type # to create if ptask_type is None: if self.__class__.target_type is not 'ptask': ptask_type = self.__class__.target_type else: raise ActionError("PTask type is required.") # do some initial validation on the supplied spec parent = PTaskSpec.parent(spec) if parent != "": try: parent = PTask.get(parent) except PTaskError: raise ActionError("Parent ptask does not exist: " + parent) name = PTaskSpec.name(spec) try: name = validate_ptask_name(name) except PTaskError as e: raise ActionError("Invalid ptask name: " + str(e)) # input self._spec = spec self._ptask_type = ptask_type self._description = description self._creator = creator self._start_date = start_date self._due_date = due_date self._source = source self._force = force # to create self._ptask = None self._ptask_area = None self._ptask_version = None
def _print_ptask_env(self): # remove any whitespace on the head/tail of the spec spec = self.spec.strip() ptask_area = None if self.version: spec = PTaskSpec.VERSION.join([spec, str(self.version)]) replace_match = re.match("\.?/([=\w]+)/([=\w]+)/", spec) # handle 'none' as a valid spec - unset current ptask (set it to root) if spec.lower() == 'none': spec = "" full_spec = PTaskSpec.get(spec) try: ptask_area = PTaskArea(full_spec) except: pass # special character '-' indicates use the last set ptask spec elif spec == "-": ptask_area = PTaskArea.previous() # set to a similar ptask with text replacement elif replace_match: cur_area_spec = PTaskArea.current().spec repl_spec = cur_area_spec.replace( replace_match.group(1), replace_match.group(2)) try: ptask_area = PTaskArea(repl_spec) except: pass # use the supplied spec relative to the current ptask else: relative_to = PTaskArea.current().spec while ptask_area is None: try: full_spec = PTaskSpec.get(spec, relative_to=relative_to) except PTaskSpecError as e: raise ActionError(str(e)) try: # if this is successful, we'll break out of the while ptask_area = PTaskArea(full_spec) except PTaskAreaError as e: # no match, check the parent relative spec relative_to = PTaskSpec.parent(relative_to) # there is no parent, break out of the while if relative_to is None: break # dump out commands used for setting the environment for the supplied # spec. if not ptask_area: raise ActionError( "Could not determine ptask area from: " + str(spec), ) ptask = None # delay the db query to this point to prevent multiple, unnecessary db # queries. if we're at this point, we know there's at least a # corresponding directory on disk. if ptask_area.base_spec: try: ptask = PTask.get(ptask_area.base_spec) except PTaskError as e: pass if not ptask and ptask_area.spec != "": raise ActionError("Could not determine ptask from: " + str(spec)) ptask_area.set(shell=self.shell, ptask=ptask)
def _print_ptask_env(self): # remove any whitespace on the head/tail of the spec spec = self.spec.strip() ptask_area = None if self.version: spec = PTaskSpec.VERSION.join([spec, str(self.version)]) replace_match = re.match("\.?/([=\w]+)/([=\w]+)/", spec) # handle 'none' as a valid spec - unset current ptask (set it to root) if spec.lower() == 'none': spec = "" full_spec = PTaskSpec.get(spec) try: ptask_area = PTaskArea(full_spec) except: pass # special character '-' indicates use the last set ptask spec elif spec == "-": ptask_area = PTaskArea.previous() # set to a similar ptask with text replacement elif replace_match: cur_area_spec = PTaskArea.current().spec repl_spec = cur_area_spec.replace(replace_match.group(1), replace_match.group(2)) try: ptask_area = PTaskArea(repl_spec) except: pass # use the supplied spec relative to the current ptask else: relative_to = PTaskArea.current().spec while ptask_area is None: try: full_spec = PTaskSpec.get(spec, relative_to=relative_to) except PTaskSpecError as e: raise ActionError(str(e)) try: # if this is successful, we'll break out of the while ptask_area = PTaskArea(full_spec) except PTaskAreaError as e: # no match, check the parent relative spec relative_to = PTaskSpec.parent(relative_to) # there is no parent, break out of the while if relative_to is None: break # dump out commands used for setting the environment for the supplied # spec. if not ptask_area: raise ActionError( "Could not determine ptask area from: " + str(spec), ) ptask = None # delay the db query to this point to prevent multiple, unnecessary db # queries. if we're at this point, we know there's at least a # corresponding directory on disk. if ptask_area.base_spec: try: ptask = PTask.get(ptask_area.base_spec) except PTaskError as e: pass if not ptask and ptask_area.spec != "": raise ActionError("Could not determine ptask from: " + str(spec)) ptask_area.set(shell=self.shell, ptask=ptask)
def prompt(self): parent_spec = PTaskSpec.parent(self.spec) template_options = [] if parent_spec: par_ptask = PTask.get(parent_spec) par_ptask_type = par_ptask.ptask_type else: par_ptask_type = 'none' ptask_area = PTaskArea(parent_spec, validate=False) master_config = ptask_area.config( PROJECT_MASTER_CONFIG_PATH, composite_ancestors=True, ) if not master_config or not hasattr(master_config, 'hierarchy'): raise ActionError("Unable to find project master config.") if not self.ptask_type in master_config.hierarchy[par_ptask_type]: raise ActionError( "Cannot create '{t}' ptask inside '{p}' ptask".format( t=self.ptask_type, p=par_ptask_type, )) # ---- prompt for missing fields if not self.source and self.ptask_type in master_config.templates: for template_spec in master_config.templates[self.ptask_type]: trimmed_spec = re.sub("^templates?=", "", template_spec, flags=re.IGNORECASE) template_options.append( (re.sub("[=_-]+", " ", trimmed_spec).title(), template_spec)) self._source = Output.prompt_menu( "Select a template to source", prompt_str="Selection", options=template_options, help_str="Please choose from the templates listed.", none_option=True, custom_prompt="Custom Source", custom_blank=False) # see if the ptask already exists if not self.ptask: try: self._ptask = PTask.get(self.spec) except PTaskError: pass else: if not self.force: raise ActionAborted("PTask already exists.") else: if not self._description: self._description = self.ptask.description if not self._start_date: self._start_date = self.ptask.start_date if not self._due_date: self._due_date = self.ptask.due_date if (not self.description or not self.start_date or not self.due_date): if self.force: raise ActionError( "Cannot force creation without required fields.") else: print "\nPlease enter information about this new {b}{t}{r}:".\ format( b=Style.bright, t=self.ptask_type, r=Style.reset, ) ptask_display = " [{pt}] {b}{s}{r}".format( pt=self.ptask_type, b=Style.bright, s=self.spec, r=Style.reset, ) if not self.description: self._description = Output.prompt( '{pd} description'.format(pd=ptask_display), blank=False, ) if not self.start_date: self._start_date = Output.prompt_date( '{pd} start date'.format(pd=ptask_display), blank=False, ) if not self.due_date: self._due_date = Output.prompt_date( '{pd} due date'.format(pd=ptask_display), blank=False, )
def prompt(self): parent_spec = PTaskSpec.parent(self.spec) template_options = [] if parent_spec: par_ptask = PTask.get(parent_spec) par_ptask_type = par_ptask.ptask_type else: par_ptask_type = 'none' ptask_area = PTaskArea(parent_spec, validate=False) master_config = ptask_area.config( PROJECT_MASTER_CONFIG_PATH, composite_ancestors=True, ) if not master_config or not hasattr(master_config, 'hierarchy'): raise ActionError("Unable to find project master config.") if not self.ptask_type in master_config.hierarchy[par_ptask_type]: raise ActionError( "Cannot create '{t}' ptask inside '{p}' ptask".format( t=self.ptask_type, p=par_ptask_type, ) ) # ---- prompt for missing fields if not self.source and self.ptask_type in master_config.templates: for template_spec in master_config.templates[self.ptask_type]: trimmed_spec = re.sub( "^templates?=", "", template_spec, flags=re.IGNORECASE ) template_options.append( ( re.sub("[=_-]+", " ", trimmed_spec).title(), template_spec ) ) self._source = Output.prompt_menu( "Select a template to source", prompt_str="Selection", options=template_options, help_str="Please choose from the templates listed.", none_option=True, custom_prompt="Custom Source", custom_blank=False ) # see if the ptask already exists if not self.ptask: try: self._ptask = PTask.get(self.spec) except PTaskError: pass else: if not self.force: raise ActionAborted("PTask already exists.") else: if not self._description: self._description = self.ptask.description if not self._start_date: self._start_date = self.ptask.start_date if not self._due_date: self._due_date = self.ptask.due_date if (not self.description or not self.start_date or not self.due_date): if self.force: raise ActionError( "Cannot force creation without required fields." ) else: print "\nPlease enter information about this new {b}{t}{r}:".\ format( b=Style.bright, t=self.ptask_type, r=Style.reset, ) ptask_display = " [{pt}] {b}{s}{r}".format( pt=self.ptask_type, b=Style.bright, s=self.spec, r=Style.reset, ) if not self.description: self._description = Output.prompt( '{pd} description'.format(pd=ptask_display), blank=False, ) if not self.start_date: self._start_date = Output.prompt_date( '{pd} start date'.format(pd=ptask_display), blank=False, ) if not self.due_date: self._due_date = Output.prompt_date( '{pd} due date'.format(pd=ptask_display), blank=False, )