Skip to content

Commit

Permalink
Merge pull request #1 from jecortez/todo-commands
Browse files Browse the repository at this point in the history
Adding capability for TODO list management, fixing up existing comman…
  • Loading branch information
jecortez authored Jan 1, 2019
2 parents b833651 + 9ee3e85 commit c42574e
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 51 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ To report Bad Habits, use the `hab bad` key command:

It is symmetric to `hab good` in that it also supports auto complete and creating new habits.

To add to your todo list, use the `hab todo` key command.

<img src="doc/hab_todo_add.png" width="550px"/>

You can also check off existing todo list items by searching for an existing item, and selecting it.

<img src="doc/hab_todo_clear.png" width="550px"/>

## Keeping habit list up to date

The autocomplete habits will get stale after you change habits in the online interface or create new ones through key commands.
Expand Down
Binary file added doc/hab_todo_add.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/hab_todo_clear.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 61 additions & 6 deletions habitica.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from requests.auth import AuthBase
import xml.etree.ElementTree as et
import json
from uuid import UUID


logging.basicConfig(level=logging.INFO, format="%(message)s")
Expand Down Expand Up @@ -37,10 +38,42 @@ def __call__(self, r):
api = slumber.API('https://habitica.com/api/v3', auth=HabiticaAuth(user_id, api_token))


def __is_valid_uuid(uuid_to_test, version=4):
"""
Check if uuid_to_test is a valid UUID.
Parameters
----------
uuid_to_test : str
version : {1, 2, 3, 4}
Returns
-------
`True` if uuid_to_test is a valid UUID, otherwise `False`.
"""
try:
uuid_obj = UUID(uuid_to_test, version=version)
except:
return False

return str(uuid_obj) == uuid_to_test


def report_habit(args):
''' Report good or bad behavior for a habit. '''
direction = "up" if args.up else "down"
print(api.tasks(args.habit_id)('score')(direction).post())
if __is_valid_uuid(args.habit_id):
print(api.tasks(args.habit_id)('score')(direction).post())
else:
print(api.tasks.user.post({'type': 'habit', 'text': args.habit_id}))


def report_todo(args):
''' Mark a todo as complete or create a new one '''
if __is_valid_uuid(args.todo_id):
print(api.tasks(args.todo_id)('score')('up').post())
else:
print(api.tasks.user.post({'type': 'todo', 'text': args.todo_id}))


def refresh_tasks(args):
Expand All @@ -53,23 +86,41 @@ def refresh_tasks(args):
tasks_json.append({
'text': task['text'],
'id': task['id'],
'type': task['type']
})

with codecs.open(TASKS_FILENAME, 'w', encoding='utf8') as tasks_file:
json.dump(tasks_json, tasks_file, indent=2)


def __filter_tasks(task_list, task_type):
filter_key = ''
if task_type == 'todo':
filter_key = 'todo'
else:
filter_key = 'habit'
filtered_tasks = [task for task in task_list if task['type'].lower() == filter_key]
return filtered_tasks


def __get_subtitle_text(task_type):
if task_type == 'good':
return "Nice job! Report this Good Habit."
elif task_type == 'bad':
return "Report this Bad Habit."
elif task_type == 'todo':
return "Add an item to your Todo list."


def autocomplete(args):
''' Return XML autocomplete items matching a query, for use with Alfred. '''

# Read tasks from local file
with codecs.open(TASKS_FILENAME, encoding='utf8') as tasks_file:
task_list = json.load(tasks_file)
task_list = __filter_tasks(json.load(tasks_file), args.task_type)

# Determine subtitle task based on whether this is a good habit or bad habit
subtitle_text = "Nice job! Report this Good Habit." if args.task_type == 'good'\
else "Report this Bad Habit." if args.task_type == 'bad'\
else ""
subtitle_text = __get_subtitle_text(args.task_type)

# Create an autcomplete 'item' for each task matched
items = et.Element('items')
Expand Down Expand Up @@ -102,7 +153,7 @@ def _add_item(items, text, task_type, id_):
parser = argparse.ArgumentParser(description="Log habit activity.")
subparsers = parser.add_subparsers(help="sub-commands for interfacing with Habitica")

report_subparser = subparsers.add_parser('report', help="Report habit behavior")
report_subparser = subparsers.add_parser('report_habit', help="Report habit behavior")
report_subparser.add_argument('habit_id', help="The ID of a habit to report.")
report_subparser.set_defaults(func=report_habit)
report_subparser.add_argument(
Expand All @@ -111,6 +162,10 @@ def _add_item(items, text, task_type, id_):
help="If this is a positive habit (default is false)."
)

report_todo_subparser = subparsers.add_parser('report_todo', help="Report TODO behavior")
report_todo_subparser.add_argument('todo_id', help="The ID of a todo to report.")
report_todo_subparser.set_defaults(func=report_todo)

refresh_subparser = subparsers.add_parser(
'refresh',
help="Refresh local list of autocomplete suggestions for tasks."
Expand Down
Loading

0 comments on commit c42574e

Please sign in to comment.