|
6 | 6 | #
|
7 | 7 | # Distributed under terms of the MIT license.
|
8 | 8 |
|
| 9 | +from ConfigParser import RawConfigParser |
9 | 10 | from tasklib.task import TaskWarrior
|
10 | 11 | from trello import TrelloClient
|
11 | 12 |
|
12 |
| -### BEGIN OF CONFIG ### (In next version this go to to configfile) |
| 13 | +def parse_config(config_file): |
| 14 | + """ |
| 15 | + Parse config file and return true if all ok |
| 16 | + All config settings are stored in globar vars |
| 17 | +
|
| 18 | + :config_file: config file name |
| 19 | + """ |
| 20 | + global trello_api_key, trello_api_secret, trello_token, trello_token_secret |
| 21 | + global taskwarrior_taskrc_location, taskwarrior_data_location |
| 22 | + global sync_projects |
| 23 | + sync_projects = [] |
| 24 | + conf = RawConfigParser() |
| 25 | + try: |
| 26 | + conf.read(config_file) |
| 27 | + except Exception: |
| 28 | + return False |
| 29 | + if (not conf.has_option('DEFAULT', 'trello_api_key') or |
| 30 | + not conf.has_option('DEFAULT', 'trello_api_secret') or |
| 31 | + not conf.has_option('DEFAULT', 'trello_token') or |
| 32 | + not conf.has_option('DEFAULT', 'trello_token_secret') or |
| 33 | + not conf.has_option('DEFAULT', 'sync_projects')): |
| 34 | + return False |
| 35 | + for sync_project in conf.get('DEFAULT', 'sync_projects').split(): |
| 36 | + if conf.has_section(sync_project): |
| 37 | + if conf.has_option(sync_project, 'tw_project_name') and conf.has_option(sync_project, 'trello_board_name'): |
| 38 | + project = {} |
| 39 | + project['tw_project_name'] = conf.get(sync_project, 'tw_project_name') |
| 40 | + project['trello_board_name'] = conf.get(sync_project, 'trello_board_name') |
| 41 | + if conf.has_option(sync_project, 'trello_todo_list'): |
| 42 | + project['trello_todo_list'] = conf.get(sync_project, 'trello_todo_list') |
| 43 | + else: |
| 44 | + project['trello_todo_list'] = 'To Do' |
| 45 | + if conf.has_option(sync_project, 'trello_doing_list'): |
| 46 | + project['trello_doing_list'] = conf.get(sync_project, 'trello_doing_list') |
| 47 | + else: |
| 48 | + project['trello_doing_list'] = 'Doing' |
| 49 | + if conf.has_option(sync_project, 'trello_done_list'): |
| 50 | + project['trello_done_list'] = conf.get(sync_project, 'trello_done_list') |
| 51 | + else: |
| 52 | + project['trello_done_list'] = 'Done' |
| 53 | + sync_projects.append(project) |
| 54 | + else: |
| 55 | + return False |
| 56 | + else: |
| 57 | + return False |
| 58 | + trello_api_key = conf.get('DEFAULT', 'trello_api_key') |
| 59 | + trello_api_secret = conf.get('DEFAULT', 'trello_api_secret') |
| 60 | + trello_token = conf.get('DEFAULT', 'trello_token') |
| 61 | + trello_token_secret = conf.get('DEFAULT', 'trello_token_secret') |
| 62 | + if conf.has_option('DEFAULT', 'taskwarrior_taskrc_location'): |
| 63 | + taskwarrior_taskrc_location = conf.get('DEFAULT', 'taskwarrior_taskrc_location') |
| 64 | + else: |
| 65 | + taskwarrior_taskrc_location = '~/.taskrc' |
| 66 | + if conf.has_option('DEFAULT', 'taskwarrior_data_location'): |
| 67 | + taskwarrior_data_location = conf.get('DEFAULT', 'taskwarrior_data_location') |
| 68 | + else: |
| 69 | + taskwarrior_data_location = '~/.task' |
| 70 | + return True |
13 | 71 |
|
14 |
| -# Set TaskWarrior |
15 |
| -taskwarrior_taskrc_location = '~/.taskrc' |
16 |
| -taskwarrior_data_location = '~/.task' |
17 | 72 |
|
18 |
| -# Set Trello auth |
19 |
| -trello_api_key = '' |
20 |
| -trello_api_secret = '' |
21 |
| -trello_token = '' |
22 |
| -trello_token_secret = '' |
| 73 | +def get_trello_boards(): |
| 74 | + """ Get all Trello boards """ |
| 75 | + trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_token, token_secret=trello_token_secret) |
| 76 | + return trello_client.list_boards() |
| 77 | + |
| 78 | +def get_trello_board(board_name): |
| 79 | + """ |
| 80 | + Returns Trello board from name |
| 81 | + If does not exist create it and returns new board |
23 | 82 |
|
24 |
| -# Set sync projects/boards |
25 |
| -sync_projects = ['Connectical'] |
| 83 | + :board_name: the board name |
| 84 | + """ |
| 85 | + trello_boards = get_trello_boards() |
| 86 | + for trello_board in trello_boards: |
| 87 | + if trello_board.name == board_name: |
| 88 | + return trello_board |
| 89 | + return create_trello_board(board_name) |
26 | 90 |
|
27 |
| -### END OF CONFIG ### |
| 91 | +def create_trello_board(board_name): |
| 92 | + """ |
| 93 | + Create Trello board and returns it |
28 | 94 |
|
29 |
| -# Create a trello client |
30 |
| -trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_token, token_secret=trello_token_secret) |
| 95 | + :board_name: the board name |
| 96 | + """ |
| 97 | + trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_token, token_secret=trello_token_secret) |
| 98 | + return trello_client.add_board(board_name) |
31 | 99 |
|
32 |
| -def get_trello_boards(): |
33 |
| - """ Get all Trello boards """ |
34 |
| - trello_boards = trello_client.list_boards() |
35 |
| - if len(trello_boards) > 0: |
36 |
| - return trello_boards |
37 |
| - else: |
38 |
| - return None |
| 100 | +def get_trello_lists(board_name): |
| 101 | + """ |
| 102 | + Returns a set of list objects |
39 | 103 |
|
40 |
| -def get_tw_project_tasks(project): |
| 104 | + :board_name: the board name |
| 105 | + """ |
| 106 | + return get_trello_board(board_name).open_lists() |
| 107 | + |
| 108 | +def get_trello_list(board_name, trello_lists, list_name): |
| 109 | + """ |
| 110 | + Returns a list object |
| 111 | +
|
| 112 | + :board_name: the board name |
| 113 | + :trello_lists: the set of lists |
| 114 | + :list_name: the list name |
| 115 | + """ |
| 116 | + for trello_list in trello_lists: |
| 117 | + if trello_list.name == list_name: |
| 118 | + return trello_list |
| 119 | + return create_trello_list(board_name, list_name) |
| 120 | + |
| 121 | +def create_trello_list(board_name, list_name): |
| 122 | + """ |
| 123 | + Returns a new list object from project name and listname |
| 124 | +
|
| 125 | + :board_name: the board name |
| 126 | + :list_name: the list name |
| 127 | + """ |
| 128 | + trello_board = get_trello_board(board_name) |
| 129 | + return trello_board.add_list(list_name) |
| 130 | + |
| 131 | +def upload_tw_task(tw_task, trello_list): |
| 132 | + """ |
| 133 | + Upload all contents of task to list creating a new card and storing cardid |
| 134 | +
|
| 135 | + :tw_task: TaskWarrior task object |
| 136 | + :trello_list: Trello list object |
| 137 | + """ |
| 138 | + new_trello_card = trello_list.add_card(tw_task['description']) |
| 139 | + if tw_task['due']: |
| 140 | + new_trello_card.set_due(tw_task['due']) |
| 141 | + # Save the Trello Card ID into Task |
| 142 | + tw_task['trelloid'] = new_trello_card.id |
| 143 | + tw_task.save() |
| 144 | + |
| 145 | +def get_tw_project_tasks(project_name): |
41 | 146 | """
|
42 | 147 | Fetch all tasks from a project
|
43 | 148 |
|
44 |
| - :project: the project name |
| 149 | + :project_name: the project name |
45 | 150 | """
|
46 |
| - tw_project_tasks = TaskWarrior(taskrc_location=taskwarrior_taskrc_location, data_location=taskwarrior_data_location).tasks.filter(project=project) |
47 |
| - if len(project_tasks) > 0: |
48 |
| - return tw_project_tasks |
49 |
| - else: |
50 |
| - return None |
| 151 | + return TaskWarrior(taskrc_location=taskwarrior_taskrc_location, data_location=taskwarrior_data_location).tasks.filter(project=project_name) |
51 | 152 |
|
52 |
| -def get_trello_board_id(project): |
| 153 | +def upload_new_tw_tasks(project_name, board_name, todo_list_name, doing_list_name, done_list_name): |
53 | 154 | """
|
54 |
| - Returns Trello board ID from name |
55 |
| - If not exists create it and returns new ID |
| 155 | + Upload new TaskWarrior tasks that never uploaded before |
56 | 156 |
|
57 |
| - :project: the project name |
| 157 | + :project_name: the project name |
| 158 | + :board_name: the name of Trello board |
| 159 | + :todo_list_name: name of list for todo taks |
| 160 | + :doing_list_name: name of list for active tasks |
| 161 | + :done_list_name: name of list for done tasks |
58 | 162 | """
|
59 |
| - trello_boards = get_trello_boards() |
60 |
| - if trello_boards: |
61 |
| - for trello_board in trello_boards: |
62 |
| - if trello_board.name == project: |
63 |
| - return trello_board.id |
64 |
| - return create_trello_board(project) |
| 163 | + tw_tasks = get_tw_project_tasks(project_name) |
| 164 | + trello_lists = get_trello_lists(board_name) |
| 165 | + for tw_task in tw_tasks: |
| 166 | + if not tw_task['trelloid']: |
| 167 | + if tw_task.completed: |
| 168 | + upload_tw_task(tw_task, get_trello_list(board_name, trello_lists, done_list_name)) |
| 169 | + tw_task['trellolistname'] = done_list_name |
| 170 | + tw_task.save() |
| 171 | + elif tw_task.active: |
| 172 | + upload_tw_task(tw_task, get_trello_list(board_name, trello_lists, doing_list_name)) |
| 173 | + tw_task['trellolistname'] = doing_list_name |
| 174 | + tw_task.save() |
| 175 | + else: |
| 176 | + if tw_task['trellolistname']: |
| 177 | + upload_tw_task(tw_task, get_trello_list(board_name, trello_lists, tw_task['trellolistname'])) |
| 178 | + else: |
| 179 | + upload_tw_task(tw_task, get_trello_list(board_name, trello_lists, todo_list_name)) |
| 180 | + tw_task['trellolistname'] = todo_list_name |
| 181 | + tw_task.save() |
65 | 182 |
|
66 | 183 | def main():
|
67 | 184 | for project in sync_projects:
|
68 |
| - print (get_trello_board_id(project)) |
| 185 | + upload_new_tw_tasks(project['tw_project_name'], |
| 186 | + project['trello_board_name'], |
| 187 | + project['trello_todo_list'], |
| 188 | + project['trello_doing_list'], |
| 189 | + project['trello_done_list']) |
| 190 | + #print (get_trello_board_id(project)) |
| 191 | + #print (get_trello_list(project, 'Movida')) |
| 192 | + # upload_new_tw_tasks(project) |
69 | 193 |
|
70 | 194 | if __name__ == "__main__":
|
71 |
| - main() |
72 |
| - |
73 |
| -# Import all tasks into object |
74 |
| -#tw = task.TaskWarrior() |
75 |
| -#task.TaskWarrior().tasks.filter(project='Connecticale') |
76 |
| -#all_tasks = task.TaskWarrior().tasks.all() |
77 |
| - |
78 |
| -# Create a trello client |
79 |
| -#trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_token, token_secret=trello_token_secret) |
80 |
| - |
81 |
| -# Get all boards in trello (to find tello board id) |
82 |
| -#trello_boards = trello_client.list_boards() |
83 |
| - |
84 |
| -def upload_new(project, board_id): |
85 |
| - # Get tasks from project |
86 |
| - project_tasks = task.TaskWarrior().tasks.filter(project=project) |
87 |
| - if len(project_tasks) > 0: |
88 |
| - |
89 |
| - # Get lists from board |
90 |
| - trello_lists = trello_client.get_board(board_id).open_lists() |
91 |
| - # Get base lists |
92 |
| - todo_list = None |
93 |
| - doing_list = None |
94 |
| - done_list = None |
95 |
| - for trello_list in trello_lists: |
96 |
| - if trello_list.name == 'To Do': |
97 |
| - todo_list = trello_list |
98 |
| - if trello_list.name == 'Doing': |
99 |
| - doing_list = trello_list |
100 |
| - if trello_list.name == 'Done': |
101 |
| - done_list = trello_list |
102 |
| - # TODO: Make base lists if not present |
103 |
| - |
104 |
| - for project_task in project_tasks: |
105 |
| - # If trelloid is empty is a new task crated by taskwarrior |
106 |
| - if not project_task['trelloid']: |
107 |
| - if project_task.completed: |
108 |
| - new_card = done_list.add_card(project_task['description']) |
109 |
| - if project_task['due']: |
110 |
| - new_card.set_due(project_task['due']) |
111 |
| - print ('Completed') |
112 |
| - return |
113 |
| - if project_task.active: |
114 |
| - new_card = doing_list.add_card(project_task['description']) |
115 |
| - if project_task['due']: |
116 |
| - new_card.set_due(project_task['due']) |
117 |
| - print ('Active') |
118 |
| - return |
119 |
| - new_card = todo_list.add_card(project_task['description']) |
120 |
| - if project_task['due']: |
121 |
| - new_card.set_due(project_task['due']) |
122 |
| - print ('new') |
123 |
| - |
124 |
| - |
125 |
| -#def main(): |
126 |
| - # Do the samba |
127 |
| -# for project in sync_projects: |
128 |
| - # Try find project - board id correspondence |
129 |
| -# board_id = None |
130 |
| -# for board in trello_boards: |
131 |
| -# if board.name == project: |
132 |
| -# board_id = board.id |
133 |
| -# if not board_id: |
134 |
| - #TODO: Create the board |
135 |
| -# print ('Board not found') |
136 |
| -# return |
137 |
| -# upload_new(project, board_id) |
138 |
| - # Get the board |
139 |
| - #trello_board = trello_client.get_board(board_id) |
140 |
| - # And get lists from board |
141 |
| - #trello_lists = trello_board.open_lists() |
142 |
| - |
143 |
| - |
144 |
| - |
| 195 | + if parse_config('trellowarrior.conf'): |
| 196 | + main() |
0 commit comments