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 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 _parseListLine(self, parser, line): """ Parse line with parser, returns a tuple of the form (options, projectList, filters) """ args = parser.parse_args(line) if len(args.filter) > 0: projectName, keywordFilters = parseutils.extractKeywords(u" ".join( args.filter)) else: projectName = "" keywordFilters = [] if self.kFilters: # Add keyword filter keywordFilters.extend(self.kFilters) if not projectName: if self.pFilter: # If a project filter is defined, use it as none was provided projectName = self.pFilter else: # Take all project if none provided projectName = "%" if projectName.startswith("!"): projectName = self._realProjectName(projectName[1:]) projectList = Project.select(NOT(LIKE(Project.q.name, projectName))) else: projectName = self._realProjectName(projectName) projectList = Project.select(LIKE(Project.q.name, projectName)) if projectList.count() == 0: raise YokadiException("Found no project matching '%s'" % projectName) # Check keywords exist parseutils.warnIfKeywordDoesNotExist(keywordFilters) # Filtering and sorting according to parameters filters = [] # Filter on keywords for keywordFilter in keywordFilters: filters.append(keywordFilter.filter()) # Search if args.search: for word in args.search: if word.startswith("@"): tui.warning( "Maybe you want keyword search (without -s option) " "instead of plain text search?") filters.append( OR(LIKE(Task.q.title, "%" + word + "%"), LIKE(Task.q.description, "%" + word + "%"))) return args, projectList, filters
def encrypt(self, data): """Encrypt user data. @return: encrypted data""" if not CRYPT: tui.warning("Crypto functions not available") return data self.askPassphrase() return self._encrypt(data)
def _t_edit(self, line): """Code shared by t_edit and bug_edit.""" 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 task = self.getTaskFromId(line) if self.cryptoMgr.isEncrypted(task.title): self.cryptoMgr.force_decrypt = True # Decryption must be turned on to edit title = self.cryptoMgr.decrypt(task.title) # Create task line taskLine = parseutils.createLine("", title, task.getKeywordDict()) oldCompleter = readline.get_completer( ) # Backup previous completer to restore it in the end readline.set_completer(editComplete) # Switch to specific completer while True: # Edit print "(Press Ctrl+C to cancel)" try: line = tui.editLine(taskLine) if not line.strip(): tui.warning("Missing title") continue except KeyboardInterrupt: print print "Cancelled" task = None break foo, title, keywordDict = parseutils.parseLine(task.project.name + " " + line) if self.cryptoMgr.isEncrypted(task.title): title = self.cryptoMgr.encrypt(title) if dbutils.updateTask(task, task.project.name, title, keywordDict): break readline.set_completer(oldCompleter) # Restore standard completer return task
def processDbPathArg(dbPath, dataDir): if not dbPath: return basepaths.getDbPath(dataDir) dbPath = os.path.abspath(dbPath) dbDir = os.path.dirname(dbPath) tui.warning('--db option is deprecated and will be removed in the next version, use --datadir instead') if not os.path.isdir(dbDir): tui.error("Directory '{}' does not exist".format(dbDir)) sys.exit(1) return dbPath
def writeHistory(self): """Writes shell history to disk""" try: # Open r/w and close file to create one if needed historyFile = open(self.historyPath, "w", encoding='utf-8') historyFile.close() readline.set_history_length(1000) readline.write_history_file(self.historyPath) except Exception as e: tui.warning("Fail to save history to %s. Error was:\n\t%s" % (self.historyPath, e))
def _parseListLine(self, parser, line): """ Parse line with parser, returns a tuple of the form (options, projectList, filters) """ args = parser.parse_args(line) if len(args.filter) > 0: projectName, keywordFilters = parseutils.extractKeywords(" ".join(args.filter)) else: projectName = "" keywordFilters = [] if self.kFilters: # Add keyword filter keywordFilters.extend(self.kFilters) if not projectName: if self.pFilter: # If a project filter is defined, use it as none was provided projectName = self.pFilter else: # Take all project if none provided projectName = "%" if projectName.startswith("!"): projectName = self._realProjectName(projectName[1:]) projectList = self.session.query(Project).filter(Project.name.notlike(projectName)).all() else: projectName = self._realProjectName(projectName) projectList = self.session.query(Project).filter(Project.name.like(projectName)).all() if len(projectList) == 0: raise YokadiException("Found no project matching '%s'" % projectName) # Check keywords exist parseutils.warnIfKeywordDoesNotExist(keywordFilters) # Filtering and sorting according to parameters filters = [] # Filter on keywords for keywordFilter in keywordFilters: filters.append(keywordFilter.filter()) # Search if args.search: for word in args.search: if word.startswith("@"): tui.warning("Maybe you want keyword search (without -s option) " "instead of plain text search?") filters.append(or_(Task.title.like("%" + word + "%"), Task.description.like("%" + word + "%"))) return args, projectList, filters
def _t_edit(self, line): """Code shared by t_edit and bug_edit.""" 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 task = self.getTaskFromId(line) if self.cryptoMgr.isEncrypted(task.title): self.cryptoMgr.force_decrypt = True # Decryption must be turned on to edit title = self.cryptoMgr.decrypt(task.title) # Create task line taskLine = parseutils.createLine("", title, task.getKeywordDict()) oldCompleter = readline.get_completer() # Backup previous completer to restore it in the end readline.set_completer(editComplete) # Switch to specific completer while True: # Edit print("(Press Ctrl+C to cancel)") try: line = tui.editLine(taskLine) if not line.strip(): tui.warning("Missing title") continue except KeyboardInterrupt: print() print("Cancelled") task = None break foo, title, keywordDict = parseutils.parseLine(task.project.name + " " + line) if self.cryptoMgr.isEncrypted(task.title): title = self.cryptoMgr.encrypt(title) if dbutils.updateTask(task, task.project.name, title, keywordDict): break readline.set_completer(oldCompleter) # Restore standard completer self.session.merge(task) return task
def writeHistory(self): """Writes shell history to disk""" try: # Open r/w and close file to create one if needed historyFile = file(self.historyPath, "w") historyFile.close() readline.set_history_length(1000) readline.write_history_file(self.historyPath) except Exception, e: tui.warning("Fail to save history to %s. Error was:\n\t%s" % (self.historyPath, e))
def processDbPathArg(dbPath, dataDir): if not dbPath: return basepaths.getDbPath(dataDir) dbPath = os.path.abspath(dbPath) dbDir = os.path.dirname(dbPath) tui.warning( '--db option is deprecated and will be removed in the next version, use --datadir instead' ) if not os.path.isdir(dbDir): tui.error("Directory '{}' does not exist".format(dbDir)) sys.exit(1) return dbPath
def _parseListLine(self, parser, line): """ Parse line with parser, returns a tuple of the form (options, projectList, filters) """ args = parser.parse_args(line) if len(args.filter) > 0: projectName, filters = parseutils.extractKeywords(" ".join( args.filter)) else: projectName = "" filters = [] if self.kFilters: # Add keyword filter filters.extend(self.kFilters) if not projectName: if self.pFilter: # If a project filter is defined, use it as none was provided projectName = self.pFilter else: # Take all project if none provided projectName = "%" if projectName.startswith("!"): projectName = self._realProjectName(projectName[1:]) projectList = self.session.query(Project).filter( Project.name.notlike(projectName)).all() else: projectName = self._realProjectName(projectName) projectList = self.session.query(Project).filter( Project.name.like(projectName)).all() if len(projectList) == 0: raise YokadiException("Found no project matching '%s'" % projectName) # Check keywords exist parseutils.warnIfKeywordDoesNotExist(filters) # Search if args.search: for word in args.search: if word.startswith("@"): tui.warning( "Maybe you want keyword search (without -s option) " "instead of plain text search?") condition = or_(Task.title.like("%" + word + "%"), Task.description.like("%" + word + "%")) filters.append(DbFilter(condition)) return args, projectList, filters
def writeHistory(self): """Writes shell history to disk""" try: fileutils.createParentDirs(self.historyPath) # Open r/w and close file to create one if needed historyFile = open(self.historyPath, "w", encoding='utf-8') historyFile.close() readline.set_history_length(1000) readline.write_history_file(self.historyPath) except Exception as e: tui.warning("Fail to save history to %s. Error was:\n\t%s" % (self.historyPath, e))
def decrypt(self, data): """Decrypt user data. @return: decrypted data""" if not self.isEncrypted(data): # Just return data as is if it's not encrypted return data if not CRYPT: tui.warning("Crypto functions not available") return data if not self.force_decrypt: # No flag to force decryption, just return fixed string to indicate # data is encrypted return "<... encrypted data...>" # Ask passphrase if needed and decrypt data self.askPassphrase() if self.passphrase: data = self._decrypt(data) else: data = "<...Failed to decrypt data...>" return data
def warnYokadiDbEnvVariable(): if os.getenv('YOKADI_DB'): tui.warning('The YOKADI_DB environment variable is deprecated and will be removed in the next version, use the' ' --datadir command-line option instead')
def _t_edit(self, line, keywordEditor=None): """Code shared by t_edit and bug_edit. if keywordEditor is not None it will be called after editing the task. Returns the modified task if OK, None if cancelled""" 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 task = self.getTaskFromId(line) # Create task line keywordDict = task.getKeywordDict() userKeywordDict, keywordDict = dbutils.splitKeywordDict(keywordDict) taskLine = parseutils.createLine("", task.title, userKeywordDict) oldCompleter = readline.get_completer() # Backup previous completer to restore it in the end readline.set_completer(editComplete) # Switch to specific completer # Edit try: while True: print("(Press Ctrl+C to cancel)") try: line = tui.editLine(taskLine) if not line.strip(): tui.warning("Missing title") continue except KeyboardInterrupt: print() print("Cancelled") return None _, title, userKeywordDict = parseutils.parseLine(task.project.name + " " + line) if dbutils.createMissingKeywords(userKeywordDict.keys()): # We were able to create missing keywords if there were any, # we can now exit the edit loop break finally: readline.set_completer(oldCompleter) keywordDict.update(userKeywordDict) if keywordEditor: keywordEditor(keywordDict) task.title = title task.setKeywordDict(keywordDict) return task
def _t_edit(self, line, keywordEditor=None): """Code shared by t_edit and bug_edit. if keywordEditor is not None it will be called after editing the task. Returns the modified task if OK, None if cancelled""" 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 task = self.getTaskFromId(line) if self.cryptoMgr.isEncrypted(task.title): self.cryptoMgr.force_decrypt = True # Decryption must be turned on to edit title = self.cryptoMgr.decrypt(task.title) # Create task line keywordDict = task.getKeywordDict() userKeywordDict, keywordDict = dbutils.splitKeywordDict(keywordDict) taskLine = parseutils.createLine("", title, userKeywordDict) oldCompleter = readline.get_completer( ) # Backup previous completer to restore it in the end readline.set_completer(editComplete) # Switch to specific completer # Edit try: while True: print("(Press Ctrl+C to cancel)") try: line = tui.editLine(taskLine) if not line.strip(): tui.warning("Missing title") continue except KeyboardInterrupt: print() print("Cancelled") return None _, title, userKeywordDict = parseutils.parseLine( task.project.name + " " + line) if self.cryptoMgr.isEncrypted(task.title): title = self.cryptoMgr.encrypt(title) if dbutils.createMissingKeywords(userKeywordDict.keys()): # We were able to create missing keywords if there were any, # we can now exit the edit loop break finally: readline.set_completer(oldCompleter) keywordDict.update(userKeywordDict) if keywordEditor: keywordEditor(keywordDict) task.title = title task.setKeywordDict(keywordDict) return task
def warnYokadiDbEnvVariable(): if os.getenv('YOKADI_DB'): tui.warning( 'The YOKADI_DB environment variable is deprecated and will be removed in the next version, use the' ' --datadir command-line option instead')
from yokadi.ycli import tui from yokadi.core import db from yokadi.core.yokadiexception import YokadiException from sqlobject import SQLObjectNotFound # Prefix used to recognise encrypted message CRYPTO_PREFIX = "---YOKADI-ENCRYPTED-MESSAGE---" # AES Key length KEY_LENGTH = 32 try: from Crypto.Cipher import AES as Cypher CRYPT = True except ImportError: tui.warning("Python Cryptographic Toolkit module not found. You will not be able to use cryptographic function") tui.warning("like encrypting or decrypting task title or description") tui.warning("You can find pycrypto here http://www.pycrypto.org") CRYPT = False # TODO: add unit test class YokadiCryptoManager(object): """Manager object for Yokadi cryptographic operation""" def __init__(self): # Cache encryption passphrase self.passphrase = None # Force decryption (and ask passphrase) instead of decrypting only when passphrase was # previously provided self.force_decrypt = False
from yokadi.core import db from yokadi.core.yokadiexception import YokadiException from sqlobject import SQLObjectNotFound # Prefix used to recognise encrypted message CRYPTO_PREFIX = "---YOKADI-ENCRYPTED-MESSAGE---" # AES Key length KEY_LENGTH = 32 try: from Crypto.Cipher import AES as Cypher CRYPT = True except ImportError: tui.warning( "Python Cryptographic Toolkit module not found. You will not be able to use cryptographic function" ) tui.warning("like encrypting or decrypting task title or description") tui.warning("You can find pycrypto here http://www.pycrypto.org") CRYPT = False # TODO: add unit test class YokadiCryptoManager(object): """Manager object for Yokadi cryptographic operation""" def __init__(self): # Cache encryption passphrase self.passphrase = None # Force decryption (and ask passphrase) instead of decrypting only when passphrase was # previously provided