7 Commits

6 changed files with 28 additions and 14 deletions

View File

@@ -5,7 +5,7 @@ A curses CLI for Asana, using the Asana API.
* python 3
* [python-asana](https://github.com/Asana/python-asana)
* [urwid](http://urwid.org)
* [pyhon-dateutil](https://github.com/dateutil/dateutil/)
* [python-dateutil](https://github.com/dateutil/dateutil/)
## Setup
### Create an Asana OAuth app

View File

@@ -25,6 +25,7 @@ class AsanaService(object):
]
STORY_FIELDS = [
'created_at',
'created_by.name',
'html_text',
'text',
@@ -74,7 +75,7 @@ class AsanaService(object):
Task,
self.client.tasks.find_by_project(project_id, params=params)
)
def get_stories(self, task_id):
stories = self.client.stories.find_by_task(task_id, params = {
'opt_fields': self.STORY_FIELDS

View File

@@ -27,7 +27,7 @@ class Task(AsanaObject):
return super(Task, self).name()
def assignee(self):
if 'assignee' in self.object_dict:
if 'assignee' in self.object_dict and self.object_dict['assignee']:
return User(self.object_dict['assignee'])
else:
return None
@@ -57,7 +57,7 @@ class Task(AsanaObject):
return datetime.strftime('%b %d, %Y %H:%M')
elif 'due_on' in self.object_dict and self.object_dict['due_on']:
date = dateutil.parser.parse(self.object_dict['due_on'])
date.strftime('%b %d, %Y')
return date.strftime('%b %d, %Y')
else:
return 'no due date'
@@ -188,7 +188,7 @@ class HTMLTextParser(HTMLParser):
self.text.append(Text(data))
def handle_endtag(self, tag):
data = self.text.pop()
data = self.text.pop() if len(self.text) > 0 else Text("")
Class = self.tag_stack.pop()
if tag == 'ul' or tag =='ol':
@@ -211,6 +211,13 @@ class Story(AsanaObject):
else:
return ''
def created_at(self):
if 'created_at' in self.object_dict:
return dateutil.parser.parse(self.object_dict['created_at']) \
.replace(tzinfo=timezone.utc).astimezone(tz=None)
else:
return ''
def text(self):
if 'html_text' in self.object_dict:
parser = HTMLTextParser()

View File

@@ -1,3 +1,3 @@
asana==0.7.0
python-dateutil==2.6.1
asana==0.8.2
python-dateutil==2.8.0
urwid==2.0.1

View File

@@ -1,6 +1,7 @@
palette = [
('atm_section', 'white,bold', 'dark blue'),
('author', 'bold,dark blue', ''),
('timestamp', 'underline', ''),
('custom_fields', 'dark red', ''),
('header', 'bold,light green', ''),
('project', 'yellow', ''),

View File

@@ -13,15 +13,15 @@ class TaskDetails(object):
body = [
urwid.Text(('task', task.name())),
urwid.Divider('-'),
urwid.Divider(''),
Memberships(task, on_subtask_click, on_project_click).component(),
urwid.Divider('-'),
urwid.Divider(''),
Assignee(task, on_assignee_click).component(),
DueDate(task, on_due_date_click).component(),
CustomFields(task).component(),
urwid.Divider('='),
urwid.Divider(''),
urwid.Text(task.description()),
urwid.Divider('-'),
urwid.Divider(''),
]
if task.subtasks():
@@ -49,7 +49,7 @@ class Assignee(object):
assignee = "unassigned"
self.assignee = urwid.SelectableIcon([('bold', 'Assignee: '), ('', assignee)])
self.assignee = urwid.SelectableIcon([('strong', 'Assignee: '), ('', assignee)])
self.on_click = on_click
#urwid.connect_signal(self.assignee, 'keypress', self.on_keypress)
@@ -65,7 +65,8 @@ class Assignee(object):
class DueDate(object):
def __init__(self, task, on_click):
self.due_date = urwid.SelectableIcon([('bold', 'Due: '), ('', task.due_date())])
due_date = task.due_date()
self.due_date = urwid.SelectableIcon([('strong', 'Due: '), ('', str(task.due_date()))])
self.on_click = on_click
#urwid.connect_signal(self.due_date, 'keypress', self.on_keypress)
@@ -116,7 +117,11 @@ class CustomFields(object):
class Stories(object):
def __init__(self, stories):
components = [
urwid.Text([('author', s.creator())] + s.text())
urwid.Text([
('timestamp', s.created_at().strftime('%Y-%m-%d %H:%M')),
' ',
('author', s.creator()),
] + s.text())
for s in stories]
self.stories = urwid.Pile(components)