Initial commit
This commit is contained in:
commit
c1d55f17fb
|
@ -0,0 +1 @@
|
|||
/__pycache__/
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
suffixes = {"sub": ".txt",
|
||||
"note": ".md"}
|
||||
|
||||
def getItem(num):
|
||||
with open(os.getenv("TODO_FILE"), "r") as todoFile:
|
||||
return todoFile.readlines()[num-1]
|
||||
|
||||
def getSub(item):
|
||||
if "/:" not in item:
|
||||
return None
|
||||
try:
|
||||
sub=re.findall("[^ ]+/:[.A-Za-z0-9_]+", item)[0]
|
||||
except IndexError:
|
||||
return None
|
||||
return sub.split("/:")
|
||||
|
||||
def addSub(num, sub, edit=True):
|
||||
with open(os.getenv("TODO_FILE"), "r") as todoFile:
|
||||
lines = todoFile.readlines()
|
||||
if getSub(lines[num-1]) is not None and getSub(lines[num-1])[0] != sub:
|
||||
sys.exit("The item already has a sub \"" + sub + "\":" + "\n" + lines[num-1][:-1])
|
||||
if not os.path.exists(os.path.join(os.getenv("TODO_DIR"), sub)):
|
||||
os.mkdir(os.path.join(os.getenv("TODO_DIR"), sub))
|
||||
f, name = tempfile.mkstemp(suffixes[sub], "", os.path.join(os.getenv("TODO_DIR"), sub))
|
||||
lines[num-1] = lines[num-1][:-1] + " " + sub + "/:" + os.path.basename(name) + "\n"
|
||||
with open(os.getenv("TODO_FILE"), "w") as todoFile:
|
||||
todoFile.writelines(lines)
|
||||
if edit:
|
||||
editSub(num)
|
||||
|
||||
def editSub(num):
|
||||
sub = getSub(getItem(num))
|
||||
if sub is None:
|
||||
sys.exit("This item does not have a sub")
|
||||
editor = os.getenv("EDITOR").split()
|
||||
subprocess.call(editor + [os.path.join(os.getenv("TODO_DIR"), sub[0], sub[1])])
|
||||
|
||||
def showSub(item, indent=0, color=True):
|
||||
sub = getSub(item)
|
||||
if sub is None:
|
||||
sys.exit("This item does not have a sub")
|
||||
command = ["todo.sh", "listfile", os.path.join(sub[0], sub[1])]
|
||||
if not color:
|
||||
command.insert(1, "-p")
|
||||
p = subprocess.Popen(command, stdout=subprocess.PIPE)
|
||||
output = p.communicate()[0].decode("utf-8")
|
||||
output = '\n'.join(" "*indent + i for i in output.splitlines()[:-2]) + "\n"
|
||||
return output
|
||||
|
||||
def showAll(out=sys.stdout, color=True):
|
||||
command = ["todo.sh", "list"]
|
||||
if not color:
|
||||
command.insert(1, "-p")
|
||||
p = subprocess.Popen(command, stdout=subprocess.PIPE)
|
||||
lines = p.communicate()[0].decode("utf-8").splitlines()
|
||||
for line in lines:
|
||||
out.write(line + "\n")
|
||||
if getSub(line) is not None:
|
||||
out.write(showSub(line, indent=2, color=color))
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 3:
|
||||
showAll()
|
||||
elif argv[2] == "add":
|
||||
if len(argv) != 5:
|
||||
sys.exit("Usage: " + argv[1] + " add [itemNum] [subName]")
|
||||
itemNum = int(argv[3])
|
||||
addSub(itemNum, argv[4])
|
||||
elif argv[2] == "edit":
|
||||
if len(argv) != 4:
|
||||
sys.exit("Usage: " + argv[1] + " edit [itemNum]")
|
||||
itemNum = int(argv[3])
|
||||
editSub(itemNum)
|
||||
else:
|
||||
sys.exit("Command not recognized")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import unittest
|
||||
import sub
|
||||
import os
|
||||
|
||||
TEST_DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_data")
|
||||
|
||||
class TestGetSub(unittest.TestCase):
|
||||
def test_no_sub(self):
|
||||
self.assertEqual(sub.getSub("(Z) gibberish"), None)
|
||||
|
||||
def test_sub_at_bol(self):
|
||||
self.assertEqual(sub.getSub("sub/:test gibberish"), ["sub", "test"])
|
||||
|
||||
def test_sub_at_eol(self):
|
||||
self.assertEqual(sub.getSub("(Z) gibberish sub/:test"), ["sub", "test"])
|
||||
|
||||
def test_sub_mid_line(self):
|
||||
self.assertEqual(sub.getSub("(Z) sub/:test gibberish"), ["sub", "test"])
|
||||
|
||||
def test_sub_missing_folder(self):
|
||||
self.assertEqual(sub.getSub("(Z) gibberish /:test"), None)
|
||||
|
||||
def test_sub_missing_file(self):
|
||||
self.assertEqual(sub.getSub("(Z) sub/: gibberish"), None)
|
||||
|
||||
def setup_environment(path):
|
||||
os.environ["TODO_DIR"] = os.path.join(TEST_DATA_DIR, path)
|
||||
os.environ["TODO_FILE"] = os.path.join(TEST_DATA_DIR, path, "todo.txt")
|
||||
os.environ["DONE_FILE"] = os.path.join(TEST_DATA_DIR, path, "done.txt")
|
||||
os.environ["REPORT_FILE"] = os.path.join(TEST_DATA_DIR, path, "report.txt")
|
||||
os.environ["TODOTXT_CFG_FILE"] = os.path.join(TEST_DATA_DIR, "todo.cfg")
|
||||
|
||||
class TestShowSub(unittest.TestCase):
|
||||
def test_show(self):
|
||||
setup_environment("test1")
|
||||
|
||||
output = sub.showSub("(Z) gibberish sub/:test1.txt\n", color=False)
|
||||
self.assertEqual(output, "1 this is test 1\n")
|
||||
|
||||
class TestShowAll(unittest.TestCase):
|
||||
def test_show_all_one(self):
|
||||
self.show_all_tester("test1", "1 (Z) gibberish sub/:test1.txt\n 1 this is test 1\n--\nTODO: 1 of 1 tasks shown\n")
|
||||
|
||||
def test_show_all_two(self):
|
||||
self.show_all_tester("test2", "1 (Z) gibberish sub/:test1.txt\n 1 this is test 1\n2 (Z) more gibberish sub/:test2.txt\n 1 this is test 2\n--\nTODO: 2 of 2 tasks shown\n")
|
||||
|
||||
def show_all_tester(self, path, expected_output):
|
||||
from io import StringIO
|
||||
setup_environment(path)
|
||||
|
||||
out = StringIO()
|
||||
sub.showAll(out=out, color=False)
|
||||
output = out.getvalue()
|
||||
self.assertEqual(output, expected_output)
|
||||
|
||||
class TestAdd(unittest.TestCase):
|
||||
def setUp(self):
|
||||
import shutil
|
||||
shutil.rmtree(os.path.join(TEST_DATA_DIR, "test3"))
|
||||
os.mkdir(os.path.join(TEST_DATA_DIR, "test3"))
|
||||
|
||||
def test_add_sub(self):
|
||||
with open(os.path.join(TEST_DATA_DIR, "test3/todo.txt"), "w") as f:
|
||||
f.write("(Z) gibberish")
|
||||
setup_environment("test3")
|
||||
sub.addSub(1, "sub", False)
|
||||
out = sub.getSub(sub.getItem(1))
|
||||
self.assertTrue(out is not None)
|
||||
fileExists = os.path.isfile(os.path.join(os.getenv("TODO_DIR"), out[0], out[1]))
|
||||
self.assertTrue(fileExists)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1 @@
|
|||
this is test 1
|
|
@ -0,0 +1 @@
|
|||
(Z) gibberish sub/:test1.txt
|
|
@ -0,0 +1 @@
|
|||
this is test 1
|
|
@ -0,0 +1 @@
|
|||
this is test 2
|
|
@ -0,0 +1,2 @@
|
|||
(Z) gibberish sub/:test1.txt
|
||||
(Z) more gibberish sub/:test2.txt
|
Loading…
Reference in New Issue