def do_t_urgency(self, line): """Defines urgency of a task. t_urgency <id> <value>""" tokens = parseutils.simplifySpaces(line).split(" ") if len(tokens) != 2: raise BadUsageException( "You must provide a taskId and an urgency value") task = self.getTaskFromId(tokens[0]) try: # Do not use isdigit(), so that we can set negative urgency. This # make it possible to stick tasks to the bottom of the list. urgency = int(tokens[1]) except ValueError: raise BadUsageException("Task urgency must be a digit") if urgency > 100: tui.warning("Max urgency is 100") urgency = 100 elif urgency < -99: tui.warning("Min urgency is -99") urgency = -99 task.urgency = urgency self.session.merge(task) self.session.commit()
def _t_add(self, cmd, line): """Code shared by t_add, bug_add and n_add.""" parser = self._parser_t_add(cmd) args = parser.parse_args(line) line = " ".join(args.cmd) if not line: raise BadUsageException("Missing parameters") projectName, title, keywordDict = parseutils.parseLine(line) projectName = self._realProjectName(projectName) if not title: raise BadUsageException("Missing title") if args.crypt: # Obfuscate line in history length = readline.get_current_history_length() if length > 0: # Ensure history is positive to avoid crash with bad readline setup readline.replace_history_item( length - 1, "%s %s " % (cmd, line.replace(title, "<...encrypted...>"))) # Encrypt title title = self.cryptoMgr.encrypt(title) task = dbutils.addTask(projectName, title, keywordDict) if not task: tui.reinjectInRawInput(u"%s %s" % (cmd, line)) return None self.lastTaskId = task.id if args.describe: self.do_t_describe(self.lastTaskId) return task
def do_t_reorder(self, line): """Reorder tasks of a project. It works by starting an editor with the task list: you can then change the order of the lines and save the list. The urgency field will be updated to match the order. t_reorder <project_name>""" try: project = Project.byName(line) except SQLObjectNotFound: raise BadUsageException("You must provide a valid project name") taskList = Task.select(AND(Task.q.projectID == project.id, Task.q.status != 'done'), orderBy=-Task.q.urgency) lines = ["%d,%s" % (x.id, x.title) for x in taskList] text = tui.editText("\n".join(lines)) ids = [] for line in text.split("\n"): line = line.strip() if not "," in line: continue id = int(line.split(",")[0]) ids.append(id) ids.reverse() for urgency, id in enumerate(ids): task = Task.get(id) task.urgency = urgency
def do_t_reorder(self, line): """Reorder tasks of a project. It works by starting an editor with the task list: you can then change the order of the lines and save the list. The urgency field will be updated to match the order. t_reorder <project_name>""" try: project = self.session.query(Project).filter_by(name=line).one() except (MultipleResultsFound, NoResultFound): raise BadUsageException("You must provide a valid project name") taskList = self.session.query(Task).filter( Task.projectId == project.id, Task.status != 'done').order_by(desc(Task.urgency)) lines = ["%d,%s" % (x.id, x.title) for x in taskList] text = tui.editText("\n".join(lines)) ids = [] for line in text.split("\n"): line = line.strip() if not "," in line: continue ids.append(int(line.split(",")[0])) ids.reverse() for urgency, taskId in enumerate(ids): task = self.session.query(Task).get(taskId) task.urgency = urgency self.session.merge(task) self.session.commit()
def do_p_edit(self, line): """Edit a project. p_edit <project name>""" project = dbutils.getOrCreateProject(line, createIfNeeded=False) if not project: raise YokadiException("Project does not exist.") # Create project line projectLine = parseutils.createLine(project.name, "", project.getKeywordDict()) # Edit line = tui.editLine(projectLine) # Update project projectName, garbage, keywordDict = parseutils.parseLine(line) if garbage: raise BadUsageException("Cannot parse line, got garbage (%s)" % garbage) if not dbutils.createMissingKeywords(keywordDict.keys()): return try: project.name = projectName except DuplicateEntryError: raise YokadiException( "A project named %s already exists. Please find another name" % projectName) project.setKeywordDict(keywordDict)
def do_t_apply(self, line): """Apply a command to several tasks. t_apply <id1>[,<id2>,[<id3>]...]] <command> <args> Use x-y to select task range from x to y Use __ to select all tasks previously selected with t_list""" ids = [] if "__" in line: if self.lastTaskIds: line = line.replace( "__", ",".join([str(i) for i in self.lastTaskIds])) else: raise BadUsageException( "You must select tasks with t_list prior to use __") rangeId = re.compile("(\d+)-(\d+)") tokens = re.split("[\s|,]", line) if len(tokens) < 2: raise BadUsageException("Give at least a task id and a command") idScan = True # Indicate we are parsing ids cmdTokens = [] # Command that we want to apply for token in tokens: if token == "": continue if idScan: result = rangeId.match(token) if result: ids.extend( list( range(int(result.group(1)), int(result.group(2)) + 1))) elif token.isdigit(): ids.append(int(token)) else: # Id list is finished. Grab rest of line. cmdTokens.append(token) idScan = False else: cmdTokens.append(token) if not cmdTokens: raise BadUsageException("Give a command to apply") cmd = cmdTokens.pop(0) for taskId in ids: line = " ".join([cmd, str(taskId), " ".join(cmdTokens)]) print("Executing: %s" % line) self.onecmd(line.strip())
def do_k_add(self, line): """Add a keyword k_add @<keyword1> [@<keyword2>...]""" if not line: raise BadUsageException("You must provide at least one keyword name") for keyword in line.split(): try: Keyword(name=keyword) print "Keyword %s has been created" % keyword except DuplicateEntryError: print "Keyword %s already exist" % keyword
def getProjectFromName(name, parameterName="project_name"): """ Helper function which returns a project given its name, or raise a YokadiException if it does not exist. """ name = name.strip() if len(name) == 0: raise BadUsageException("Missing <%s> parameter" % parameterName) try: session = db.getSession() return session.query(Project).filter_by(name=name).one() except NoResultFound: raise YokadiException("Project '%s' not found. Use p_list to see all projects." % name)
def do_k_add(self, line): """Add a keyword k_add @<keyword1> [@<keyword2>...]""" session = db.getSession() if not line: raise BadUsageException("You must provide at least one keyword name") for keyword in line.split(): try: session.add(Keyword(name=keyword)) session.commit() print("Keyword %s has been created" % keyword) except IntegrityError: session.rollback() print("Keyword %s already exist" % keyword)
def do_t_medit(self, line): """Mass edit tasks of a project. t_medit <project_name> Starts a text editor with the task list, you can then: - edit tasks text and keywords - mark tasks as done or started - add new tasks - adjust urgency - delete tasks """ if not line: raise BadUsageException("Missing parameters") projectName = parseutils.parseOneWordName(line) projectName = self._realProjectName(projectName) project = dbutils.getOrCreateProject(projectName) if not project: return oldList = massedit.createEntriesForProject(project) oldText = massedit.createMEditText(oldList) newText = oldText while True: newText = tui.editText(newText, suffix=".medit") if newText == oldText: print("No changes") return try: newList = massedit.parseMEditText(newText) except massedit.ParseError as exc: print(exc) print() if tui.confirm("Modify text and try again"): lst = newText.splitlines() lst.insert(exc.lineNumber, "# ^ " + exc.message) newText = "\n".join(lst) continue else: return try: massedit.applyChanges(project, oldList, newList) self.session.commit() break except YokadiException as exc: print(exc) print() if not tui.confirm("Modify text and try again"): return
def getProjectFromName(name, parameterName="project_name"): """ Helper function which returns a project given its name, or raise a YokadiException if it does not exist. """ name = name.strip() if len(name) == 0: raise BadUsageException("Missing <%s> parameter" % parameterName) try: return Project.byName(name) except SQLObjectNotFound: raise YokadiException( "Project '%s' not found. Use p_list to see all projects." % name)
def do_a_add(self, line): """Add an alias on a command Ex. create an alias 'la' for 't_list -a': a_add la t_list -a""" tokens = line.split() if len(tokens) < 2: raise BadUsageException("You should provide an alias name and a command") name = tokens[0] if name in self.aliases: raise YokadiException("There is already an alias named {}.".format(name)) command = " ".join(tokens[1:]) session = db.getSession() db.Alias.add(session, name, command) session.commit() self._updateAliasDict()
def do_c_set(self, line): """Set a configuration key to value : c_set <key> <value>""" line = line.split() if len(line) < 2: raise BadUsageException("You should provide two arguments : the parameter key and the value") name = line[0] value = " ".join(line[1:]) session = db.getSession() p = session.query(Config).filter_by(name=name, system=False) if p.count() == 0: raise YokadiException("Sorry, no parameter match") else: if self.checkParameterValue(name, value): p[0].value = value tui.info("Parameter updated") else: raise YokadiException("Parameter value is incorrect")
def do_c_set(self, line): """Set a configuration key to value : c_set <key> <value>""" line = line.split() if len(line) < 2: raise BadUsageException( "You should provide two arguments : the parameter key and the value" ) name = line[0] value = " ".join(line[1:]) p = Config.select(AND(Config.q.name == name, Config.q.system == False)) if p.count() == 0: tui.error("Sorry, no parameter match") else: if self.checkParameterValue(name, value): p[0].value = value tui.info("Parameter updated") else: tui.error("Parameter value is incorrect")
def do_p_add(self, line): """Add new project. Will prompt to create keywords if they do not exist. p_add <projectName> [@<keyword1>] [@<keyword2>]""" if not line: print "Give at least a project name !" return projectName, garbage, keywordDict = parseutils.parseLine(line) if garbage: raise BadUsageException("Cannot parse line, got garbage (%s)" % garbage) try: project = Project(name=projectName) except DuplicateEntryError: raise YokadiException( "A project named %s already exists. Please find another name" % projectName) print "Added project '%s'" % projectName if not dbutils.createMissingKeywords(keywordDict.keys()): return None project.setKeywordDict(keywordDict)
def do_a_add(self, line): """Add an alias on a command Ex. create an alias 'la' for 't_list -a': a_add la t_list -a""" tokens = line.split() if len(tokens) < 2: raise BadUsageException( "You should provide an alias name and a command") name = tokens[0] command = " ".join(tokens[1:]) self.aliases.update({name: command}) try: aliases = Config.selectBy(name="ALIASES")[0] except IndexError: # Config entry does not exist. Create it. aliases = Config(name="ALIASES", value="{}", system=True, desc="User command aliases") aliases.value = repr(self.aliases)