diff --git a/abcex.py b/abcex.py new file mode 100644 index 0000000..5894864 --- /dev/null +++ b/abcex.py @@ -0,0 +1,33 @@ +# from https://github.com/zordsdavini/abcex + +class Abcex: + + abc_map = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 'a', + 11: 'b', 12: 'c', 13: 'd', 14: 'e', 15: 'f', 16: 'g', 17: 'h', 18: + 'i', 19: 'j', 20: 'k', 21: 'l', 22: 'm', 23: 'n', 24: 'o', 25: 'p', + 26: 'q', 27: 'r', 28: 's', 29: 't', 30: 'u', 31: 'v', 32: 'w', 33: + 'x', 34: 'y', 35: 'z'} + + inv_abc_map = {str(v): k for k, v in abc_map.items()} + + def encode(self, number): + number = int(number) + result = '' + + while number > 0: + result = "%s%s" % (self.abc_map[number % 36], result) + number //= 36 + + return result + + + def decode(self, string): + result = 0 + string = str(string) + string = reversed(str(string)) + + for i, c in enumerate(string): + result = 36**i * self.inv_abc_map[c] + result + + return result + diff --git a/bcolors.py b/bcolors.py new file mode 100644 index 0000000..224364b --- /dev/null +++ b/bcolors.py @@ -0,0 +1,12 @@ +# from https://stackoverflow.com/questions/287871/print-in-terminal-with-colors + + +class bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' diff --git a/default.db b/default.db index 8de0e5e..3c7c613 100644 Binary files a/default.db and b/default.db differ diff --git a/model.py b/model.py new file mode 100644 index 0000000..c2aac6c --- /dev/null +++ b/model.py @@ -0,0 +1,57 @@ +import sqlite3 + +from abcex import Abcex + + +class Model: + def __init__(self): + self.conn = sqlite3.connect('ztm.db') + self.conn.row_factory = sqlite3.Row + self.abcex = Abcex() + + def get_tasks_by_tag(self, tag_name): + query = ''' + SELECT t.* FROM task t + LEFT JOIN tag_task tgt ON t.id = tgt.task_id + LEFT JOIN tag tg ON tg.id = tgt.tag_id + WHERE tg.name = ? + ''' + + return self.conn.execute(query, tag_name) + + def get_all_tasks(self): + query = ''' + SELECT t.* FROM task t + ''' + + return self.conn.execute(query) + + def create_task_draft(self, description): + query = ''' + INSERT INTO task + (description, created_at) + VALUES + (?, DATETIME('now')) + ''' + cursor = self.conn.cursor() + cursor.execute(query, (description,)) + task_id = cursor.lastrowid + + aid = self.abcex.encode(task_id) + cursor.execute('UPDATE task SET aid=? WHERE id=?', (aid, task_id)) + + self.conn.commit() + + return aid + + def get_task(self, aid): + query = ''' + SELECT t.* FROM task t + LEFT JOIN tag_task tgt ON t.id = tgt.task_id + LEFT JOIN tag tg ON tg.id = tgt.tag_id + WHERE t.aid = ? + ''' + cursor = self.conn.cursor() + results = cursor.execute(query, (aid,)) + + return results.fetchone() diff --git a/tags b/tags index 45bb11e..a5ba879 100644 --- a/tags +++ b/tags @@ -1,2 +1,35 @@ !_TAG_FILE_SORTED 2 /0=unsorted, 1=sorted, 2=foldcase/ -sqlite3 /home/arnas/Skleps/ztm/ztm.py /^import sqlite3$/;" i language:Python +a /home/arnas/Skleps/ztm/ztm.py /^ a = Main()$/;" v language:Python +Abcex /home/arnas/Skleps/ztm/model.py /^from abcex import Abcex$/;" i language:Python +about /home/arnas/Skleps/ztm/ztm.py /^ def about(self):$/;" f language:Python +add /home/arnas/Skleps/ztm/ztm.py /^ def add(self):$/;" f language:Python +add_tag /home/arnas/Skleps/ztm/ztm.py /^ def add_tag(self, task_id):$/;" f language:Python +bcolors /home/arnas/Skleps/ztm/bcolors.py /^class bcolors:$/;" c language:Python +bcolors /home/arnas/Skleps/ztm/ztm.py /^from bcolors import bcolors$/;" i language:Python +BOLD /home/arnas/Skleps/ztm/bcolors.py /^ BOLD = '\\033[1m'$/;" v language:Python class:bcolors +create_task_draft /home/arnas/Skleps/ztm/model.py /^ def create_task_draft(self, description):$/;" m language:Python class:Model +ENDC /home/arnas/Skleps/ztm/bcolors.py /^ ENDC = '\\033[0m'$/;" v language:Python class:bcolors +FAIL /home/arnas/Skleps/ztm/bcolors.py /^ FAIL = '\\033[91m'$/;" v language:Python class:bcolors +fzfCall /home/arnas/Skleps/ztm/ztm.py /^ def fzfCall(self, elements):$/;" f language:Python +get_all_tasks /home/arnas/Skleps/ztm/model.py /^ def get_all_tasks(self):$/;" m language:Python class:Model +get_task /home/arnas/Skleps/ztm/model.py /^ def get_task(self, aid):$/;" m language:Python class:Model +get_tasks_by_tag /home/arnas/Skleps/ztm/model.py /^ def get_tasks_by_tag(self, tag_name):$/;" m language:Python class:Model +HEADER /home/arnas/Skleps/ztm/bcolors.py /^ HEADER = '\\033[95m'$/;" v language:Python class:bcolors +Main /home/arnas/Skleps/ztm/ztm.py /^class Main:$/;" c language:Python +manage_task /home/arnas/Skleps/ztm/ztm.py /^ def manage_task(self, aid):$/;" f language:Python +manage_task_about /home/arnas/Skleps/ztm/ztm.py /^ def manage_task_about(self, aid):$/;" f language:Python +manage_task_menu /home/arnas/Skleps/ztm/ztm.py /^ def manage_task_menu(self, aid):$/;" f language:Python +menu /home/arnas/Skleps/ztm/ztm.py /^ def menu(self):$/;" f language:Python +Model /home/arnas/Skleps/ztm/model.py /^class Model:$/;" c language:Python +Model /home/arnas/Skleps/ztm/ztm.py /^from model import Model$/;" i language:Python +OKBLUE /home/arnas/Skleps/ztm/bcolors.py /^ OKBLUE = '\\033[94m'$/;" v language:Python class:bcolors +OKGREEN /home/arnas/Skleps/ztm/bcolors.py /^ OKGREEN = '\\033[92m'$/;" v language:Python class:bcolors +run /home/arnas/Skleps/ztm/ztm.py /^ def run(self):$/;" m language:Python class:Main +search /home/arnas/Skleps/ztm/ztm.py /^ def search(self):$/;" f language:Python +sqlite3 /home/arnas/Skleps/ztm/model.py /^import sqlite3$/;" i language:Python +subprocess /home/arnas/Skleps/ztm/ztm.py /^import subprocess$/;" i language:Python +sys /home/arnas/Skleps/ztm/ztm.py /^import sys$/;" i language:Python +UNDERLINE /home/arnas/Skleps/ztm/bcolors.py /^ UNDERLINE = '\\033[4m'$/;" v language:Python class:bcolors +WARNING /home/arnas/Skleps/ztm/bcolors.py /^ WARNING = '\\033[93m'$/;" v language:Python class:bcolors +__init__ /home/arnas/Skleps/ztm/model.py /^ def __init__(self):$/;" m language:Python class:Model +__init__ /home/arnas/Skleps/ztm/ztm.py /^ def __init__(self):$/;" m language:Python class:Main diff --git a/ztm.py b/ztm.py index 3d58d1f..2830493 100644 --- a/ztm.py +++ b/ztm.py @@ -1,3 +1,124 @@ -import sqlite3 +import sys +import subprocess + +from model import Model +from bcolors import bcolors +class Main: + def __init__(self): + self.model = Model() + + def run(self): + print(''' + _oo (o)__(o) \/ + >-(_ \(__ __) (OO) + / _/ ( ) ,'.--.) + / / )( / /|_|_\\ + / ( ( )| \_.--. + ( `-. )/ '. \) \\ + `--.._) ( `-.(_.' + +Task manager from Zordsdavini (2018) + ''') + + self.menu() + + def menu(self): + menu = input('What you want to do? (?+/tcq) ') + + if menu == 'q': + print('bye o/') + sys.exit(0) + + elif menu == '?': + self.about() + + elif menu == '/': + self.search() + + elif menu == '+': + self.add() + + def about(self): + print(''' +Short instruction +----------------- +? - help (this dialog) ++ - add +/ - search +t - tag manager +c - configuration +q - exit + ''') + self.menu() + + def search(self): + tasks = [] + tasksData = self.model.get_all_tasks() + if not tasksData: + self.add() + tasksData = self.model.get_all_tasks() + + for t in self.model.get_all_tasks(): + tasks.append('%s: %s' % (t[1], t[2])) + + selected = self.fzfCall(tasks) + + def add(self): + print('\n' + bcolors.HEADER + 'Adding task\n' + bcolors.ENDC) + description = input('Description: ') + aid = self.model.create_task_draft(description) + self.manage_task(aid) + + + def add_tag(self, task_id): + question = input('Do you want to add tag? ([y]/n) ') + if question == 'y' or question == '': + self.add_tag(task_id) + pass + + def manage_task(self, aid): + task = self.model.get_task(aid) + print('\n' + bcolors.HEADER + 'Managing: [' + task['aid'] + '] ' + task['description'] + '\n' + bcolors.ENDC) + + print() + self.manage_task_menu(aid) + + def manage_task_menu(self, aid): + menu = input('What you want to do? (?e*+-v&q) ') + + if menu == 'q': + print('bye o/') + sys.exit(0) + + elif menu == '?': + self.manage_task_about(aid) + + def manage_task_about(self, aid): + print(''' +Short instruction +----------------- +? - help (this dialog) +e - edit content +* - toggle long term ++ - add tag +- - remove tag +v - mark done +& - add child task +q - exit + ''') + self.manage_task_menu(aid) + + def fzfCall(self, elements): + try: + p = subprocess.Popen(['echo', '\n'.join(elements)], stdout=subprocess.PIPE) + p2 = subprocess.check_output(('fzf'), stdin=p.stdout) + return p2 + except: + return None + + +if __name__ == '__main__': + a = Main() + a.run()