def decryptEncryptedTasks(cursor): sql = "select id, title, description from task where title like ?" rows = cursor.execute(sql, (CRYPTO_PREFIX + "%",)).fetchall() if not rows: return if CRYPTO_ALGO is None: msg = ("This database contains encrypted data but pycrypto is not" " installed.\n" "Please install pycrypto and try again.") raise updateutils.UpdateError(msg) if not tui.confirm("This database contains encrypted tasks, but Yokadi no " "longer supports encryption.\n" "These tasks need to be decrypted to continue using " "Yokadi.\n" "Do you want to decrypt your tasks?"): raise updateutils.UpdateCanceledError() checkText = getCheckText(cursor) while True: phrase = getPassphrase() cypher = CRYPTO_ALGO.new(phrase) if checkPassphrase(cypher, checkText): break else: if not tui.confirm("Wrong passphrase, try again?"): raise updateutils.UpdateCanceledError() for row in rows: decryptTask(cursor, cypher, row)
def testConfirm(self): tui.addInputAnswers("zog", "y") value = tui.confirm("bla") self.assertTrue(value) tui.addInputAnswers("zog", "n") value = tui.confirm("bla") self.assertFalse(value)
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 = 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 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 do_k_edit(self, line): """Edit a keyword k_edit @<keyword>""" session = db.getSession() keyword = dbutils.getKeywordFromName(line) oldName = keyword.name newName = tui.editLine(oldName) if newName == "": print("Cancelled") return lst = session.query(Keyword).filter_by(name=newName).all() if len(lst) == 0: # Simple case: newName does not exist, just rename the existing keyword keyword.name = newName session.merge(keyword) session.commit() print("Keyword %s has been renamed to %s" % (oldName, newName)) return # We already have a keyword with this name, we need to merge print("Keyword %s already exists" % newName) if not tui.confirm("Do you want to merge %s and %s" % (oldName, newName)): return # Check we can merge conflictingTasks = [] for task in keyword.tasks: kwDict = task.getKeywordDict() if oldName in kwDict and newName in kwDict and kwDict[ oldName] != kwDict[newName]: conflictingTasks.append(task) if len(conflictingTasks) > 0: # We cannot merge tui.error("Cannot merge keywords %s and %s because they are both" " used with different values in these tasks:" % (oldName, newName)) for task in conflictingTasks: print("- %d, %s" % (task.id, task.title)) print("Edit these tasks and try again") return # Merge for task in keyword.tasks: kwDict = task.getKeywordDict() if newName not in kwDict: kwDict[newName] = kwDict[oldName] del kwDict[oldName] task.setKeywordDict(kwDict) session.delete(keyword) session.commit() print("Keyword %s has been merged with %s" % (oldName, newName))
def do_k_remove(self, line): """Remove a keyword k_remove @<keyword>""" keyword = dbutils.getKeywordFromName(line) if keyword.tasks: print "The keyword %s is used by the following tasks: %s" % (keyword.name, ", ".join(str(task.id) for task in keyword.tasks)) if tui.confirm("Do you really want to remove this keyword"): keyword.destroySelf() print "Keyword %s has been removed" % keyword.name
def do_p_merge(self, line): session = db.getSession() parser = self.parser_p_merge() args = parser.parse_args(line) src = getProjectFromName(args.source_project) dst = getProjectFromName(args.destination_project) if not args.force: if not tui.confirm("Merge project '{}' into '{}'".format(src.name, dst.name)): return dst.merge(session, src) print("Project '{}' merged into '{}'".format(src.name, dst.name))
def do_p_remove(self, line): session = db.getSession() parser = self.parser_p_remove() args = parser.parse_args(line) project = getProjectFromName(args.project) nbTasks = len(project.tasks) if not args.force: if not tui.confirm("Remove project '%s' and its %d tasks" % (project.name, nbTasks)): return session.delete(project) session.commit() print("Project removed")
def do_k_remove(self, line): """Remove a keyword k_remove @<keyword>""" session = db.getSession() keyword = dbutils.getKeywordFromName(line) if keyword.tasks: print("The keyword %s is used by the following tasks: %s" % (keyword.name, ", ".join(str(task.id) for task in keyword.tasks))) if tui.confirm("Do you really want to remove this keyword"): session.delete(keyword) session.commit() print("Keyword %s has been removed" % keyword.name)
def do_p_merge(self, line): session = db.getSession() parser = self.parser_p_merge() args = parser.parse_args(line) src = getProjectFromName(args.source_project) dst = getProjectFromName(args.destination_project) if not args.force: if not tui.confirm("Merge project '{}' into '{}'".format( src.name, dst.name)): return dst.merge(session, src) print("Project '{}' merged into '{}'".format(src.name, dst.name))
def do_k_edit(self, line): """Edit a keyword k_edit @<keyword>""" session = db.getSession() keyword = dbutils.getKeywordFromName(line) oldName = keyword.name newName = tui.editLine(oldName) if newName == "": print("Cancelled") return lst = session.query(Keyword).filter_by(name=newName).all() if len(lst) == 0: # Simple case: newName does not exist, just rename the existing keyword keyword.name = newName session.merge(keyword) session.commit() print("Keyword %s has been renamed to %s" % (oldName, newName)) return # We already have a keyword with this name, we need to merge print("Keyword %s already exists" % newName) if not tui.confirm("Do you want to merge %s and %s" % (oldName, newName)): return # Check we can merge conflictingTasks = [] for task in keyword.tasks: kwDict = task.getKeywordDict() if oldName in kwDict and newName in kwDict and kwDict[oldName] != kwDict[newName]: conflictingTasks.append(task) if len(conflictingTasks) > 0: # We cannot merge tui.error("Cannot merge keywords %s and %s because they are both" " used with different values in these tasks:" % (oldName, newName)) for task in conflictingTasks: print("- %d, %s" % (task.id, task.title)) print("Edit these tasks and try again") return # Merge for task in keyword.tasks: kwDict = task.getKeywordDict() if newName not in kwDict: kwDict[newName] = kwDict[oldName] del kwDict[oldName] task.setKeywordDict(kwDict) session.delete(keyword) session.commit() print("Keyword %s has been merged with %s" % (oldName, newName))
def do_t_remove(self, line): parser = self.parser_t_remove() args = parser.parse_args(line) task = self.getTaskFromId(args.id) if not args.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)
def do_k_remove(self, line): """Remove a keyword k_remove @<keyword>""" session = db.getSession() keyword = dbutils.getKeywordFromName(line) if keyword.tasks: taskList = ", ".join(str(task.id) for task in keyword.tasks) print("The keyword {} is used by the following tasks: {}".format(keyword.name, taskList)) if not tui.confirm("Do you really want to remove this keyword"): return session.delete(keyword) session.commit() print("Keyword {} has been removed".format(keyword.name))
def do_t_remove(self, line): parser = self.parser_t_remove() args = parser.parse_args(line) task = self.getTaskFromId(args.id) if not args.force: if not tui.confirm("Remove task '%s'" % task.title): return project = task.project self.session.delete(task) print("Task '%s' removed" % (task.title)) # Delete project with no associated tasks if self.session.query(Task).filter_by(project=project).count() == 0: self.session.delete(project) self.session.commit()
def do_k_remove(self, line): """Remove a keyword k_remove @<keyword>""" session = db.getSession() keyword = dbutils.getKeywordFromName(line) if keyword.tasks: taskList = ", ".join(str(task.id) for task in keyword.tasks) print("The keyword {} is used by the following tasks: {}".format( keyword.name, taskList)) if not tui.confirm("Do you really want to remove this keyword"): return session.delete(keyword) session.commit() print("Keyword {} has been removed".format(keyword.name))
def do_p_remove(self, line): parser = self.parser_p_remove() args = parser.parse_args(line) project = getProjectFromName(args.project) taskList = Task.select(Task.q.projectID == project.id) taskList = list(taskList) if not args.force: if not tui.confirm("Remove project '%s' and its %d tasks" % (project.name, len(taskList))): return print "Removing project tasks:" for task in taskList: task.delete(task.id) print "- task %(id)-3s: %(title)-30s" % dict(id=str(task.id), title=str(task.title)) project.delete(project.id) print "Project removed"
def getOrCreateKeyword(keywordName, interactive=True): """Get a keyword by its name. Create it if needed @param keywordName: keyword name as a string @param interactive: Ask user before creating keyword (this is the default) @type interactive: Bool @return: Keyword instance or None if user cancel creation""" session = db.getSession() try: return session.query(Keyword).filter_by(name=keywordName).one() except (NoResultFound, MultipleResultsFound): if interactive and not tui.confirm("Keyword '%s' does not exist, create it" % keywordName): return None keyword = Keyword(name=keywordName) session.add(keyword) print("Added keyword '%s'" % keywordName) return keyword
def getOrCreateKeyword(keywordName, interactive=True): """Get a keyword by its name. Create it if needed @param keywordName: keyword name as a string @param interactive: Ask user before creating keyword (this is the default) @type interactive: Bool @return: Keyword instance or None if user cancel creation""" result = Keyword.selectBy(name=keywordName) result = list(result) if len(result): return result[0] if interactive and not tui.confirm("Keyword '%s' does not exist, create it" % keywordName): return None keyword = Keyword(name=keywordName) print "Added keyword '%s'" % keywordName return keyword
def do_t_purge(self, line): parser = self.parser_t_purge() args = parser.parse_args(line) filters = [] filters.append(Task.q.status == "done") filters.append(Task.q.doneDate < (datetime.now() - timedelta(days=args.delay))) tasks = Task.select(AND(*filters)) if tasks.count() == 0: print "No tasks need to be purged" return print "The following tasks will be removed:" print "\n".join(["%s: %s" % (task.id, task.title) for task in tasks]) if args.force or tui.confirm("Do you really want to remove those tasks (this action cannot be undone)?"): Task.deleteMany(AND(*filters)) print "Tasks deleted" else: print "Purge canceled"
def getOrCreateKeyword(keywordName, interactive=True): """Get a keyword by its name. Create it if needed @param keywordName: keyword name as a string @param interactive: Ask user before creating keyword (this is the default) @type interactive: Bool @return: Keyword instance or None if user cancel creation""" session = db.getSession() try: return session.query(Keyword).filter_by(name=keywordName).one() except (NoResultFound, MultipleResultsFound): if interactive and not tui.confirm( "Keyword '%s' does not exist, create it" % keywordName): return None keyword = Keyword(name=keywordName) session.add(keyword) print("Added keyword '%s'" % keywordName) return keyword
def do_t_purge(self, line): parser = self.parser_t_purge() args = parser.parse_args(line) filters = [] filters.append(Task.q.status == "done") filters.append( Task.q.doneDate < (datetime.now() - timedelta(days=args.delay))) tasks = Task.select(AND(*filters)) if tasks.count() == 0: print "No tasks need to be purged" return print "The following tasks will be removed:" print "\n".join(["%s: %s" % (task.id, task.title) for task in tasks]) if args.force or tui.confirm( "Do you really want to remove those tasks (this action cannot be undone)?" ): Task.deleteMany(AND(*filters)) print "Tasks deleted" else: print "Purge canceled"
def getOrCreateProject(projectName, interactive=True, createIfNeeded=True): """Get a project by its name. Create it if needed @param projectName: project name as a string @param interactive: Ask user before creating project (this is the default) @type interactive: Bool @param createIfNeeded: create project if it does not exist (this is the default) @type createIfNeeded: Bool @return: Project instance or None if user cancel creation or createIfNeeded is False""" result = Project.selectBy(name=projectName) result = list(result) if len(result): return result[0] if not createIfNeeded: return None if interactive and not tui.confirm("Project '%s' does not exist, create it" % projectName): return None project = Project(name=projectName) print "Added project '%s'" % projectName return project
def getOrCreateProject(projectName, interactive=True, createIfNeeded=True): """Get a project by its name. Create it if needed @param projectName: project name as a string @param interactive: Ask user before creating project (this is the default) @type interactive: Bool @param createIfNeeded: create project if it does not exist (this is the default) @type createIfNeeded: Bool @return: Project instance or None if user cancel creation or createIfNeeded is False""" session = db.getSession() result = session.query(Project).filter_by(name=projectName).all() if len(result): return result[0] if not createIfNeeded: return None if interactive and not tui.confirm("Project '%s' does not exist, create it" % projectName): return None project = Project(name=projectName) session.add(project) print("Added project '%s'" % projectName) return project
def getOrCreateProject(projectName, interactive=True, createIfNeeded=True): """Get a project by its name. Create it if needed @param projectName: project name as a string @param interactive: Ask user before creating project (this is the default) @type interactive: Bool @param createIfNeeded: create project if it does not exist (this is the default) @type createIfNeeded: Bool @return: Project instance or None if user cancel creation or createIfNeeded is False""" session = db.getSession() result = session.query(Project).filter_by(name=projectName).all() if len(result): return result[0] if not createIfNeeded: return None if interactive and not tui.confirm( "Project '%s' does not exist, create it" % projectName): return None project = Project(name=projectName) session.add(project) print("Added project '%s'" % projectName) return project