示例#1
0
    def do_t_due(self, line):
        """Set task's due date
        t_due <id> <date>

        Date can be specified as a relative offset:
        - +5M: in 5 minutes
        - +3H: in 3 hours
        - +1D: in 1 day
        - +6W: in 6 weeks

        As a day in the week:
        - tomorrow:      tomorrow, same hour
        - tuesday 12:10: next tuesday, at 12:10
        - fr 15:30:      next friday, at 15:30

        Or as an absolute date or time:
        - 10:38:            at 10:38 today
        - 25/09/2010 12:10: on the 25th of September, 2010, at 12:10
        - 23/02/2010:       on the 23th of February, 2010
        - 01/04:            on the 1st of April
        - 12:               on the 12th of current month

        To reset a due date, use "none"."""
        if len(line.split())<2:
            raise YokadiException("Give a task id and time, date or date & time")
        taskId, line=line.strip().split(" ", 1)
        task=dbutils.getTaskFromId(taskId)

        if line.lower()=="none":
            task.dueDate=None
            print "Due date for task '%s' reset" % task.title
        else:
            task.dueDate = dateutils.parseHumaneDateTime(line)
            print "Due date for task '%s' set to %s" % (task.title, task.dueDate.ctime())
示例#2
0
文件: bugcmd.py 项目: ryanakca/yokadi
    def do_bug_edit(self, line):
        """Edit a bug.
        bug_edit <id>"""
        task = dbutils.getTaskFromId(line)

        # Create task line
        taskLine = parseutils.createLine("", task.title, task.getKeywordDict())

        # Edit
        while True:
            print "(Press Ctrl+C to cancel)"
            try:
                line = tui.editLine(taskLine)
                if not line.strip():
                    tui.warning("Indicate a bug title !")
                    continue
            except KeyboardInterrupt:
                print
                print "Cancelled"
                return
            foo, title, keywordDict = parseutils.parseLine(task.project.name+" "+line)
            if dbutils.updateTask(task, task.project.name, title, keywordDict):
                break
        editBugKeywords(keywordDict)
        task.setKeywordDict(keywordDict)

        # Update bug
        task.urgency = computeUrgency(keywordDict)
示例#3
0
 def do_t_describe(self, line):
     """Starts an editor to enter a longer description of a task.
     t_describe <id>"""
     task=dbutils.getTaskFromId(line)
     try:
         description = tui.editText(task.description)
     except Exception, e:
         raise YokadiException(e)
示例#4
0
 def getTaskFromId(self, line):
     line = line.strip()
     if line == '_':
         if self.lastTaskId is None:
             raise YokadiException("No previous task defined")
         line = str(self.lastTaskId)
     task = dbutils.getTaskFromId(line)
     if line != '_':
         self.lastTaskId = task.id
     return task
示例#5
0
    def do_t_project(self, line):
        """Set task's project.
        t_project <id> <project>"""
        tokens = line.split(" ")
        if len(tokens)!=2:
            raise YokadiException("You should give two arguments: <task id> <project>")
        task=dbutils.getTaskFromId(tokens[0])
        projectName = tokens[1]

        task.project = dbutils.getOrCreateProject(projectName)
        if task.project:
            print "Moved task '%s' to project '%s'" % (task.title, projectName)
示例#6
0
 def _t_set_status(self, line, status):
     task=dbutils.getTaskFromId(line)
     if task.recurrence and status == "done":
         task.dueDate = task.recurrence.getNext(task.dueDate)
         print "Task '%s' next occurrence is scheduled at %s" % (task.title, task.dueDate)
         print "To *really* mark this task done and forget it, remove its recurrence first with t_recurs %s none" % task.id
     else:
         task.status = status
         if status == "done":
             task.doneDate = datetime.now()
         else:
             task.doneDate = None
         print "Task '%s' marked as %s" % (task.title, status)
示例#7
0
    def do_t_remove(self, line):
        parser = self.parser_t_remove()
        options, args = parser.parse_args(line)
        task=dbutils.getTaskFromId(' '.join(args))
        if not options.force:
            if not tui.confirm("Remove task '%s'" % task.title):
                return
        projectId = task.project.id
        task.destroySelf()
        print "Task '%s' removed" % (task.title)

        # Delete project with no associated tasks
        if Task.select(Task.q.projectID == projectId).count() == 0:
            Project.delete(projectId)
示例#8
0
    def do_t_add_keywords(self, line):
        """Add keywords to an existing task
        t_add_keyword <id> <keyword1> <keyword2>[=<value>]...
        """
        tokens = line.split(" ", 1)
        if len(tokens) < 2:
            raise YokadiException("You should give at least two arguments: <task id> <keyword>")
        task = dbutils.getTaskFromId(tokens[0])
        remainingText, newKwDict = parseutils.extractKeywords(tokens[1])

        dbutils.createMissingKeywords(newKwDict.keys())

        kwDict = task.getKeywordDict()
        kwDict.update(newKwDict)
        task.setKeywordDict(kwDict)
示例#9
0
    def do_t_edit(self, line):
        """Edit a task.
        t_edit <id>"""

        def editComplete(text, state):
            """ Specific completer for the edit prompt.
            This subfunction should stay here because it needs to access to cmd members"""
            if state == 0:
                origline = readline.get_line_buffer()
                line = origline.lstrip()
                stripped = len(origline) - len(line)
                begidx = readline.get_begidx() - stripped
                endidx = readline.get_endidx() - stripped
                if begidx>0:
                    self.completion_matches = projectAndKeywordCompleter("", text, line, begidx, endidx, shift=1)
                else:
                    self.completion_matches = []
            try:
                return self.completion_matches[state]
            except IndexError:
                return None

        old_completer = readline.get_completer() # Backup previous completer to restore it in the end
        readline.set_completer(editComplete)     # Switch to specific completer

        task = dbutils.getTaskFromId(line)

        # Create task line
        taskLine = parseutils.createLine("", task.title, task.getKeywordDict())

        while True:
            # Edit
            print "(Press Ctrl+C to cancel)"
            try:
                line = tui.editLine(taskLine)
                if not line.strip():
                    tui.warning("Indicate a task title !")
                    continue
            except KeyboardInterrupt:
                print
                print "Cancelled"
                readline.set_completer(old_completer)   # Restore standard completer
                return
            foo, title, keywordDict = parseutils.parseLine(task.project.name+" "+line)
            if dbutils.updateTask(task, task.project.name, title, keywordDict):
                break

        readline.set_completer(old_completer)   # Restore standard completer
示例#10
0
    def do_t_add_keywords(self, line):
        """Add keywords to an existing task
        t_add_keyword <id> <@keyword1> <@keyword2>[=<value>]...
        """
        tokens = parseutils.simplifySpaces(line).split(" ", 1)
        if len(tokens) < 2:
            raise YokadiException("You should give at least two arguments: <task id> <keyword>")
        task = dbutils.getTaskFromId(tokens[0])
        garbage, keywordFilters = parseutils.extractKeywords(tokens[1])
        newKwDict = parseutils.keywordFiltersToDict(keywordFilters)
        if garbage:
            raise YokadiException("Cannot parse line, got garbage (%s). Maybe you forgot to add @ before keyword ?"
                                   % garbage)

        dbutils.createMissingKeywords(newKwDict.keys())

        kwDict = task.getKeywordDict()
        kwDict.update(newKwDict)
        task.setKeywordDict(kwDict)
示例#11
0
    def do_t_urgency(self, line):
        """Defines urgency of a task.
        t_urgency <id> <value>"""
        tokens = line.split(" ")
        if len(tokens)!=2:
            raise YokadiException("You must provide a taskId and an urgency value") 
        task = dbutils.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 YokadiException("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
示例#12
0
    def do_t_show(self, line):
        parser = self.parser_t_show()
        options, args = parser.parse_args(line)

        task=dbutils.getTaskFromId(' '.join(args))

        if options.output in ("all", "summary"):
            keywordDict = task.getKeywordDict()
            keywordArray = []
            for name, value in keywordDict.items():
                txt = name
                if value:
                    txt += "=" + str(value)
                keywordArray.append(txt)
                keywordArray.sort()
            keywords = ", ".join(keywordArray)
            fields = [
                ("Project", task.project.name),
                ("Title", task.title),
                ("Created", task.creationDate),
                ("Due", task.dueDate),
                ("Status", task.status),
                ("Urgency", task.urgency),
                ("Recurrence", task.recurrence),
                ("Keywords", keywords),
                ]

            if task.status == "done":
                fields.append(("Done", task.doneDate))

            tui.renderFields(fields)

        if options.output in ("all", "description") and task.description:
            if options.output == "all":
                print
            print task.description
示例#13
0
    def testGetTaskFromId(self):
        tui.addInputAnswers("y")
        t1 = dbutils.addTask("x", "t1", {})

        task = dbutils.getTaskFromId(str(t1.id))
        self.assertEquals(task, t1)
示例#14
0
    def do_t_recurs(self, line):
        """Make a task recurs
        t_recurs <id> yearly <dd/mm> <HH:MM>
        t_recurs <id> monthly <dd> <HH:MM>
        t_recurs <id> monthly <first/second/third/last> <mo, tu, we, th, fr, sa, su> <hh:mm>
        t_recurs <id> quarterly <dd> <HH:MM>
        t_recurs <id> quarterly <first/second/third/last> <mo, tu, we, th, fr, sa, su> <hh:mm>
        t_recurs <id> weekly <mo, tu, we, th, fr, sa, su> <hh:mm>
        t_recurs <id> daily <HH:MM>
        t_recurs <id> none (remove recurrence)"""
        tokens = line.split()
        if len(tokens) < 2:
            raise YokadiException("You should give at least two arguments: <task id> <recurrence>")
        task = dbutils.getTaskFromId(tokens[0])
        
        # Define recurrence:
        freq = byminute = byhour = byweekday = bymonthday = bymonth = None

        tokens[1] = tokens[1].lower()

        if tokens[1] == "none":
            if task.recurrence:
                task.recurrence.destroySelf()
                task.recurrence = None
            return
        elif tokens[1] == "daily":
            if len(tokens) != 3:
                raise YokadiException("You should give time for daily task")
            freq = rrule.DAILY
            byhour, byminute = dateutils.getHourAndMinute(tokens[2])
        elif tokens[1] == "weekly":
            freq = rrule.WEEKLY
            if len(tokens) != 4:
                raise YokadiException("You should give day and time for weekly task")
            byweekday = dateutils.getWeekDayNumberFromDay(tokens[2].lower())
            byhour, byminute = dateutils.getHourAndMinute(tokens[3])
        elif tokens[1] in ("monthly","quarterly"):
            if tokens[1] == "monthly":
                freq = rrule.MONTHLY
            else:
                # quarterly
                freq = rrule.YEARLY
                bymonth = [1,4,7,10]
            if len(tokens) < 4:
                raise YokadiException("You should give day and time for %s task" % (tokens[1],))
            try:
                bymonthday = int(tokens[2])
                byhour, byminute = dateutils.getHourAndMinute(tokens[3])
            except ValueError:
                POSITION = { "first" : 1, "second" : 2, "third" : 3, "fourth" : 4, "last" : -1 }
                if tokens[2].lower() in POSITION.keys() and len(tokens) == 5:
                    byweekday = rrule.weekday(dateutils.getWeekDayNumberFromDay(tokens[3].lower()),
                                              POSITION[tokens[2]])
                    byhour, byminute = dateutils.getHourAndMinute(tokens[4])
                    bymonthday = None # Default to current day number - need to be blanked                    
                else:
                    raise YokadiException("Unable to understand date. See help t_recurs for details")
        elif tokens[1] == "yearly":
            freq = rrule.YEARLY
            rDate = dateutils.parseHumaneDateTime(" ".join(tokens[2:]))
            bymonth = rDate.month
            bymonthday = rDate.day
            byhour = rDate.hour
            byminute = rDate.minute
        else:
            raise YokadiException("Unknown frequency. Available: daily, weekly, monthly and yearly")

        if task.recurrence is None:
            task.recurrence = Recurrence()
        rr = rrule.rrule(freq, byhour=byhour, byminute=byminute, byweekday=byweekday,
                         bymonthday=bymonthday, bymonth=bymonth)
        task.recurrence.setRrule(rr)
        task.dueDate = task.recurrence.getNext()