Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55970ab144 | ||
|
|
65bd30d026 | ||
|
|
6243a9bb68 | ||
|
|
3a5837ae5d | ||
|
|
dac83e00a1 | ||
| 86e1d830de | |||
| 0fff014307 | |||
| 6664d299b9 | |||
| 7f76ebd441 | |||
| 5d176075a7 | |||
| e18c923202 | |||
| 6ba98525d5 | |||
| 3894b81ebc |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,6 +1,8 @@
|
||||
*.swp
|
||||
*.pyc
|
||||
|
||||
tags
|
||||
|
||||
.state
|
||||
.oauth
|
||||
secrets.py
|
||||
|
||||
36
cmdasana.py
36
cmdasana.py
@@ -58,12 +58,13 @@ class CmdAsana:
|
||||
},
|
||||
)
|
||||
(url, state) = self.client.session.authorization_url()
|
||||
print("Go to the following link and enter the code:")
|
||||
print(url)
|
||||
try:
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
except Exception:
|
||||
print("Go to the following link and enter the code:")
|
||||
print(url)
|
||||
pass
|
||||
|
||||
code = sys.stdin.readline().strip()
|
||||
token = self.client.session.fetch_token(code=code)
|
||||
@@ -134,6 +135,7 @@ class CmdAsana:
|
||||
def update(task):
|
||||
task_list,_ = self.frame.contents[1]
|
||||
task_list.insertNewTask(task)
|
||||
self.loop.draw_screen()
|
||||
|
||||
thread = Thread(target=runInThread)
|
||||
thread.start()
|
||||
@@ -169,12 +171,17 @@ class CmdAsana:
|
||||
|
||||
def userTypeAhead(self, text, callback):
|
||||
def runInThread():
|
||||
users = self.client.workspaces.typeahead(self.state['workspace_id'],
|
||||
{
|
||||
'type': 'user',
|
||||
'query': text,
|
||||
'count': 5
|
||||
})
|
||||
if self.state['workspace_id'] != PERSONAL:
|
||||
users = self.client.workspaces \
|
||||
.typeahead(self.state['workspace_id'],
|
||||
{
|
||||
'type': 'user',
|
||||
'query': text,
|
||||
'count': 5
|
||||
})
|
||||
else:
|
||||
users = [self.me]
|
||||
|
||||
callback(users)
|
||||
self.loop.draw_screen()
|
||||
|
||||
@@ -263,10 +270,11 @@ class CmdAsana:
|
||||
def runInThread():
|
||||
task = self.client.tasks.find_by_id(task_id)
|
||||
stories = self.client.stories.find_by_task(task_id)
|
||||
update(task, stories)
|
||||
subtasks = self.client.tasks.subtasks(task_id)
|
||||
update(task, stories, subtasks)
|
||||
|
||||
def update(task, stories):
|
||||
task_details = ui.TaskDetails(task, stories)
|
||||
def update(task, stories, subtasks):
|
||||
task_details = ui.TaskDetails(task, stories, subtasks)
|
||||
self.connectDetailsSignals(task_details)
|
||||
self.replaceBody(task_details)
|
||||
|
||||
@@ -294,6 +302,9 @@ class CmdAsana:
|
||||
'updatetask',
|
||||
'usertypeahead',
|
||||
'assigntask',
|
||||
'complete',
|
||||
'newtask',
|
||||
'details',
|
||||
])
|
||||
|
||||
urwid.register_signal(ui.AssigneeTypeAhead, [
|
||||
@@ -332,6 +343,9 @@ class CmdAsana:
|
||||
urwid.connect_signal(task_details, 'updatetask', self.updateTask)
|
||||
urwid.connect_signal(task_details, 'usertypeahead', self.userTypeAhead)
|
||||
urwid.connect_signal(task_details, 'assigntask', self.assignTask)
|
||||
urwid.connect_signal(task_details, 'complete', self.completeTask)
|
||||
urwid.connect_signal(task_details, 'newtask', self.newTask)
|
||||
urwid.connect_signal(task_details, 'details', self.showDetails)
|
||||
|
||||
def handleInput(self, key):
|
||||
if key in ('q', 'Q'):
|
||||
|
||||
102
ui.py
102
ui.py
@@ -12,6 +12,7 @@ palette = [
|
||||
('header', 'bold,light green', ''),
|
||||
('secondary', 'light gray', ''),
|
||||
('task', 'light green', ''),
|
||||
('project', 'yellow', ''),
|
||||
('section', 'white', 'dark green'),
|
||||
('workspace', 'white', 'dark blue'),
|
||||
('pager', 'standout', ''),
|
||||
@@ -61,7 +62,7 @@ class ProjectIcon(urwid.SelectableIcon):
|
||||
super(ProjectIcon, self).__init__(project['name'])
|
||||
|
||||
def keypress(self, size, key):
|
||||
if key in ('enter', 'left', 'l'):
|
||||
if key in ('enter', 'right', 'l'):
|
||||
self.onClick(self.project['id'])
|
||||
else:
|
||||
return super(ProjectIcon, self).keypress(size, key)
|
||||
@@ -71,8 +72,8 @@ class ProjectList(urwid.ListBox):
|
||||
self.projects = projects
|
||||
|
||||
body = urwid.SimpleFocusListWalker(
|
||||
[ProjectIcon({'name': 'My Tasks', 'id': None},
|
||||
self.loadProject),
|
||||
[urwid.AttrMap(ProjectIcon({'name': 'My Tasks', 'id': None},
|
||||
self.loadProject), 'project'),
|
||||
None]
|
||||
)
|
||||
super(ProjectList, self).__init__(body)
|
||||
@@ -82,8 +83,8 @@ class ProjectList(urwid.ListBox):
|
||||
self.body.pop()
|
||||
for i in range(50):
|
||||
try:
|
||||
self.body.append(ProjectIcon(self.projects.next(),
|
||||
self.loadProject))
|
||||
self.body.append(urwid.AttrMap(ProjectIcon(self.projects.next(),
|
||||
self.loadProject), 'project'))
|
||||
except StopIteration:
|
||||
return
|
||||
|
||||
@@ -112,7 +113,8 @@ class TaskList(urwid.ListBox):
|
||||
body = urwid.SimpleFocusListWalker([])
|
||||
for task_widget,_ in task_widgets.contents:
|
||||
self.connectSignals(task_widget)
|
||||
style = 'section' if task_widget.task['name'][-1] == ':' else 'task'
|
||||
style = 'section' if len(task_widget.task['name']) and \
|
||||
task_widget.task['name'][-1] == ':' else 'task'
|
||||
body.append(urwid.AttrMap(task_widget, style, focus_map='selected'))
|
||||
|
||||
super(TaskList, self).__init__(body)
|
||||
@@ -264,8 +266,37 @@ class AssigneeTypeAhead(urwid.Pile):
|
||||
self.contents = [self.contents[0]]
|
||||
self.edit.set_edit_text(user['name'])
|
||||
|
||||
class TaskDetails(urwid.Pile):
|
||||
def __init__(self, task, stories):
|
||||
class ProjectTypeAhead(urwid.Pile):
|
||||
def __init__(self, task):
|
||||
body = [('pack', urwid.AttrMap(ProjectIcon(project, self.loadProject),
|
||||
'project'))
|
||||
for project in task['projects']]
|
||||
|
||||
|
||||
self.edit = urwid.Edit('Add Project: ')
|
||||
urwid.connect_signal(self.edit, 'change', self.typeAhead)
|
||||
|
||||
body.append(('pack', self.edit))
|
||||
|
||||
super(ProjecTypeAhead).__init__(body)
|
||||
|
||||
def typeAhead(self, widget, text):
|
||||
urwid.emit_signal(self, 'projecttypeahead', text, self.updateTypeAhead)
|
||||
|
||||
def updateTypeAhead(self, projects):
|
||||
projects = [(TypeAheadButton(p, self.add), ('pack', None))
|
||||
for p in projects]
|
||||
|
||||
body = [('pack', urwid.AttrMap(ProjectIcon(project, self.loadProject),
|
||||
'project'))
|
||||
for project in self.task['projects']]
|
||||
|
||||
body.append(('pack', self.edit))
|
||||
|
||||
self.contents = body + projects
|
||||
|
||||
class TaskDetails(urwid.ListBox):
|
||||
def __init__(self, task, stories, subtasks):
|
||||
self.task = task
|
||||
self.stories = stories
|
||||
|
||||
@@ -283,27 +314,54 @@ class TaskDetails(urwid.Pile):
|
||||
urwid.connect_signal(assignee_type_ahead, 'usertypeahead',
|
||||
self.userTypeAhead)
|
||||
urwid.connect_signal(assignee_type_ahead, 'assigntask', self.assignTask)
|
||||
|
||||
containers = []
|
||||
|
||||
projects = [('pack', ProjectIcon(project, self.loadProject))
|
||||
for project in task['projects']]
|
||||
if task['parent'] != None:
|
||||
parent = TaskEdit(task['parent'])
|
||||
urwid.connect_signal(parent, 'updatetask', self.updateSubtask)
|
||||
urwid.connect_signal(parent, 'details', self.showDetails)
|
||||
|
||||
body = projects + \
|
||||
#Remap enter to load details of parent
|
||||
urwid.connect_signal(parent, 'newtask', self.showDetails)
|
||||
containers.append(parent)
|
||||
|
||||
all_subtasks = [t for t in subtasks]
|
||||
subtask_list = TaskList(all_subtasks)
|
||||
urwid.connect_signal(subtask_list, 'complete', self.completeTask)
|
||||
urwid.connect_signal(subtask_list, 'newtask', self.newTask)
|
||||
urwid.connect_signal(subtask_list, 'updatetask', self.updateSubtask)
|
||||
urwid.connect_signal(subtask_list, 'details', self.showDetails)
|
||||
|
||||
body = containers + \
|
||||
[
|
||||
('pack', urwid.Divider('=')),
|
||||
('pack', task_name_edit),
|
||||
('pack', assignee_type_ahead),
|
||||
('pack', urwid.Divider('-')),
|
||||
('pack', self.description_edit),
|
||||
('pack', urwid.Divider('-')),
|
||||
urwid.Divider('='),
|
||||
task_name_edit,
|
||||
assignee_type_ahead,
|
||||
urwid.Divider('-'),
|
||||
self.description_edit,
|
||||
urwid.Divider('-'),
|
||||
urwid.BoxAdapter(subtask_list, len(all_subtasks)),
|
||||
urwid.Divider('-'),
|
||||
] + \
|
||||
[('pack', urwid.Text('[' + story['created_by']['name'] + '] ' + \
|
||||
story['text'])) for story in stories] + \
|
||||
[
|
||||
('weight', 1, urwid.Filler(comment_edit, 'bottom'))
|
||||
]
|
||||
[urwid.Text('[' + story['created_by']['name'] + '] ' + \
|
||||
story['text']) for story in stories] + \
|
||||
[comment_edit]
|
||||
|
||||
super(TaskDetails, self).__init__(body)
|
||||
|
||||
def completeTask(self, task_id):
|
||||
urwid.emit_signal(self, 'complete', task_id)
|
||||
|
||||
def newTask(self, task_after_id=None):
|
||||
urwid.emit_signal(self, 'newtask', task_after_id)
|
||||
|
||||
def updateSubtask(self, task_id, name):
|
||||
urwid.emit_signal(self, 'updatetask', task_id, name)
|
||||
|
||||
def showDetails(self, task_id):
|
||||
urwid.emit_signal(self, 'details', task_id)
|
||||
|
||||
def keypress(self, size, key):
|
||||
key = super(TaskDetails, self).keypress(size, key)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user