Commit 592e3698 authored by Sean Breckenridge's avatar Sean Breckenridge 💬

version 0.1.3:

* improve typing
* make the todo.txt file optional
if the user doesnt provide one,
it tests ~/.config/todo/todo.txt
and ~/.todo/todo.txt.
parent 65109362
#!/usr/bin/env python3
import os
import sys
import re
from datetime import datetime
from typing import Union, List, Set, Optional
from typing import Union, List, Set, Optional, Tuple
from pathlib import Path
from shutil import copyfile
......@@ -47,7 +46,7 @@ all_tags: List[str] = []
def prompt_todo(add_due: bool, time_format: str) -> Optional[todotxtio.Todo]:
# prompt the user for a new todo (just the text)
todo_text = input_dialog(title="Add Todo:").run()
todo_text: Optional[str] = input_dialog(title="Add Todo:").run()
if todo_text is None:
return None
......@@ -58,25 +57,25 @@ def prompt_todo(add_due: bool, time_format: str) -> Optional[todotxtio.Todo]:
# project tags
print("Enter one or more tags, hit 'Tab' to autocomplete")
projects_raw = prompt("[Enter Project Tags]> ",
completer=FuzzyWordCompleter(all_tags),
complete_while_typing=True,
validator=ProjectTagValidator(),
bottom_toolbar=HTML(
"<b>Todo:</b> {}".format(todo_text)))
projects_raw: str = prompt("[Enter Project Tags]> ",
completer=FuzzyWordCompleter(all_tags),
complete_while_typing=True,
validator=ProjectTagValidator(),
bottom_toolbar=HTML(
"<b>Todo:</b> {}".format(todo_text)))
todo_project_tags: Set[str] = set(projects_raw.split())
# select priority
todo_priority = button_dialog(title="Priority:",
text="A is highest, C is lowest",
buttons=[
("A", "A"),
("B", "B"),
("C", "C"),
]).run()
todo_priority: str = button_dialog(title="Priority:",
text="A is highest, C is lowest",
buttons=[
("A", "A"),
("B", "B"),
("C", "C"),
]).run()
# ask if the user wants to add a time
add_time = button_dialog(
add_time: bool = button_dialog(
title="Deadline:",
text="Do you want to add a deadline for this todo?",
buttons=[
......@@ -85,14 +84,15 @@ def prompt_todo(add_due: bool, time_format: str) -> Optional[todotxtio.Todo]:
]).run()
# prompt for adding a deadline
todo_time = None
todo_time: Optional[datetime] = None
if add_time:
while todo_time is None:
todo_time_str = input_dialog(
todo_time_str: Optional[str] = input_dialog(
title="Describe the deadline.",
text=
"For example:\n'9AM', 'noon', 'tomorrow at 10PM', 'may 30th at 8PM'"
).run()
# if user hit cancel
if todo_time_str is None:
add_time = False
break
......@@ -106,12 +106,10 @@ def prompt_todo(add_due: bool, time_format: str) -> Optional[todotxtio.Todo]:
todo_time_str)).run()
# create todotxtio.Todo object based on responses.
new_todo = todotxtio.Todo(text=todo_text,
priority=todo_priority)
new_todo: todotxtio.Todo = todotxtio.Todo(text=todo_text,
priority=todo_priority)
if todo_time is not None:
new_todo.tags = {
"deadline": datetime.strftime(todo_time, time_format)
}
new_todo.tags = {"deadline": datetime.strftime(todo_time, time_format)}
if add_due:
new_todo.tags["due"] = datetime.strftime(todo_time, "%Y-%m-%d")
......@@ -124,8 +122,8 @@ def full_backup(todotxt_file: PathIsh) -> None:
"""
Backs up the todo.txt file before writing to it
"""
backup_file = f"{todotxt_file}.full.bak"
copyfile(todotxt_file, backup_file)
backup_file: PathIsh = f"{todotxt_file}.full.bak"
copyfile(str(todotxt_file), str(backup_file))
def parse_projects(todo_sources: List[List[todotxtio.Todo]]):
......@@ -139,15 +137,47 @@ def parse_projects(todo_sources: List[List[todotxtio.Todo]]):
all_tags = [f"+{t}" for t in seen_tags]
def check_file_arg(todotxt_filepath: Tuple[PathIsh]) -> Optional[PathIsh]:
if len(todotxt_filepath): # if arguments were passed
todotxt_file: PathIsh = todotxt_filepath[0]
if not os.path.exists(todotxt_file):
click.echo(f"The provided file '{todotxt_file}' does not exist.",
err=True)
return None
else:
return todotxt_file
else: # no todo file passed, test some common locations
home: PathIsh = Path.home()
for possible_locations in (
# specify rarer location first, more likely you're using it
os.path.join(home, ".config/todo/todo.txt"),
os.path.join(home, ".todo/todo.txt"),
):
if os.path.exists(possible_locations):
click.echo(
f"Found todo.txt file at {possible_locations}, using...")
return possible_locations
else:
return None
@click.command()
@click.argument("todotxt-file", type=click.Path(exists=True))
@click.argument("todotxt-file", nargs=-1)
@click.option("--add-due",
is_flag=True,
help="Add due: key/value flag based on deadline:")
@click.option("--time-format",
default="%Y-%m-%d-%H-%M",
help="Specify a different time format for deadline:")
def cli(todotxt_file: PathIsh, add_due: bool, time_format: str):
def cli(todotxt_file: Optional[PathIsh], add_due: bool, time_format: str):
# handle argument
todotxt_file = check_file_arg(todotxt_file)
if todotxt_file is None:
ctx = click.get_current_context()
click.echo(ctx.get_help())
ctx.exit()
# read from main todo.txt file
todos: List[todotxtio.Todo] = todotxtio.from_file(todotxt_file)
......@@ -160,7 +190,9 @@ def cli(todotxt_file: PathIsh, add_due: bool, time_format: str):
done_file: PathIsh = os.path.join(os.path.dirname(todotxt_file),
"done.txt")
if not os.path.exists(done_file):
click.secho(f"Could not find the done.txt file at {done_file}", err=True, fg="red")
click.secho(f"Could not find the done.txt file at {done_file}",
err=True,
fg="red")
else:
todo_sources.append(todotxtio.from_file(done_file))
......@@ -173,7 +205,8 @@ def cli(todotxt_file: PathIsh, add_due: bool, time_format: str):
# write back to file
if new_todo is not None:
todos.append(new_todo)
click.echo("{}: {}".format(click.style("Adding Todo", fg="green"), new_todo))
click.echo("{}: {}".format(click.style("Adding Todo", fg="green"),
new_todo))
todotxtio.to_file(todotxt_file, todos)
......
......@@ -14,7 +14,7 @@ with io.open('README.md', encoding='utf-8') as fo:
setup(
name='full-todotxt',
version="0.1.2",
version="0.1.3",
url='https://github.com/seanbreckenridge/full_todotxt',
author='Sean Breckenridge',
author_email='seanbrecke@gmail.com',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment