1 | 'use strict'
|
2 |
|
3 | var Trello = require('node-trello')
|
4 | var Promise = require('bluebird')
|
5 | var moment = require('moment')
|
6 | var _ = require('lodash')
|
7 |
|
8 | module.exports = function initializeModule (options) {
|
9 | var t = Promise.promisifyAll(new Trello(options.trelloKey, options.trelloToken))
|
10 | var dailyLabel = options.trelloLabel
|
11 | var mainBoard
|
12 |
|
13 | function init (boardName) {
|
14 | return Promise.try(function () {
|
15 | return findBoard(boardName || options.trelloBoard)
|
16 | }).then(function (board) {
|
17 | mainBoard = board
|
18 | return mainBoard
|
19 | }).catch(function (err) {
|
20 | console.log('Error initiating', err)
|
21 | })
|
22 | }
|
23 |
|
24 | function findBoard (boardName) {
|
25 | return Promise.try(function () {
|
26 | return t.getAsync('/1/members/me')
|
27 | }).then(function (data) {
|
28 | return data.idBoards
|
29 | }).map(function (id) {
|
30 | return t.getAsync('/1/boards/' + id, {lists: 'all'})
|
31 | }).filter(function (board) {
|
32 | return board.name === boardName
|
33 | }).then(function (boards) {
|
34 | if (boardName === undefined) {
|
35 | throw new Error('boardName not set in ENV')
|
36 | } else if (boards.length === 0) {
|
37 | throw new Error('No results found.')
|
38 | } else {
|
39 | return boards[0]
|
40 | }
|
41 | }).catch(function (err) {
|
42 | console.log('Error finding board', err)
|
43 | })
|
44 | }
|
45 |
|
46 | function getOrCreateList (board, listName) {
|
47 | return Promise.filter(board.lists, function (list) {
|
48 | return list.name === listName
|
49 | }).filter(function (list) {
|
50 | return list.closed === false
|
51 | }).then(function (lists) {
|
52 | if (lists.length > 0) {
|
53 | return lists[0]
|
54 | } else {
|
55 | return createList({
|
56 | name: listName,
|
57 | board: board,
|
58 | position: 'top'
|
59 | })
|
60 | }
|
61 | }).catch(function (err) {
|
62 | console.log('Error in getOrCreateList', err)
|
63 | })
|
64 | }
|
65 |
|
66 | function createList (opts) {
|
67 | return Promise.try(function () {
|
68 | return t.postAsync('/1/lists', {
|
69 | name: opts.name,
|
70 | idBoard: opts.board,
|
71 | idListSource: opts.sourceList,
|
72 | position: opts.position
|
73 | })
|
74 | }).catch(function (err) {
|
75 | console.log('Error creating list', err)
|
76 | })
|
77 | }
|
78 |
|
79 | function moveCardPosition (opts) {
|
80 | return Promise.resolve().then(function () {
|
81 | return t.getAsync('/1/lists/' + opts.targetList, {cards: 'open'})
|
82 | }).then(function (result) {
|
83 | return _.sortBy(result.cards, 'desc')
|
84 | }).filter(function (card) {
|
85 | return (opts.dailyOnly && _.includes(card.idLabels, opts.dailyLabel))
|
86 | }).then(function (cards) {
|
87 | return cards.reduce(function (prev, card) {
|
88 | return prev.then(function () {
|
89 | return t.putAsync('/1/cards/' + card.id, {pos: card.desc || opts.pos})
|
90 | })
|
91 | }, Promise.resolve())
|
92 | }).catch(function (err) {
|
93 | console.log('Error in moveCardPosition', err)
|
94 | })
|
95 | }
|
96 |
|
97 | function checkDefaultLists (listName, processListName) {
|
98 | return Promise.try(function () {
|
99 | return mainBoard || init()
|
100 | }).then(function (board) {
|
101 | return Promise.all([
|
102 | getOrCreateList(board, listName || options.todayList),
|
103 | getOrCreateList(board, processListName || 'Daily Processes')
|
104 | ]).spread(function (targetList, sourceList) {
|
105 | return {
|
106 | boardId: board.id,
|
107 | targetList: targetList.id,
|
108 | sourceList: sourceList.id
|
109 | }
|
110 | })
|
111 | })
|
112 | }
|
113 |
|
114 | function getOpenLists () {
|
115 | return Promise.try(function () {
|
116 | return mainBoard || init()
|
117 | }).then(function (board) {
|
118 | return t.getAsync('/1/boards/' + board.id + '/lists/open')
|
119 | }).catch(function (err) {
|
120 | if (err) throw new Error('Unable to get lists')
|
121 | })
|
122 | }
|
123 |
|
124 | function archiveEmptyLists () {
|
125 | return Promise.try(function () {
|
126 | return mainBoard || init()
|
127 | }).then(function (board) {
|
128 | return t.getAsync('/1/boards/' + board.id + '/lists?cards=open')
|
129 | }).filter(function (list) {
|
130 | return _.isEmpty(list.cards)
|
131 | }).then(function (lists) {
|
132 | lists = _.groupBy(lists, 'name')
|
133 | for (var name in lists) {
|
134 | if (lists.hasOwnProperty(name)) {
|
135 | _.each(lists[name], function (list, key) {
|
136 | if (key !== 0) {
|
137 | t.putAsync('/1/lists/' + list.id + '/closed?value=true')
|
138 | }
|
139 | })
|
140 | }
|
141 | }
|
142 | })
|
143 | }
|
144 |
|
145 |
|
146 | function getLists () {
|
147 | return Promise.try(function () {
|
148 | return getOpenLists()
|
149 | }).then(function (lists) {
|
150 | return lists.forEach(function (list) {
|
151 | console.log(list.name)
|
152 | return list.name
|
153 | })
|
154 | }).catch(function (err) {
|
155 | if (err) throw new Error('Could not list list names')
|
156 | })
|
157 | }
|
158 |
|
159 |
|
160 | function listCards (listName) {
|
161 | return Promise.try(function () {
|
162 | return getOpenLists()
|
163 | }).filter(function (list) {
|
164 | return list.name === listName
|
165 | }).then(function (list) {
|
166 | return t.getAsync('/1/lists/' + list[0].id, {cards: 'open'})
|
167 | }).then(function (list) {
|
168 | return Promise.map(list.cards, function (card) {
|
169 | if (card.closed === false) {
|
170 | console.log(card.name)
|
171 | }
|
172 | })
|
173 | }).catch(function (err) {
|
174 | if (err) throw new Error('Could not find list')
|
175 | })
|
176 | }
|
177 |
|
178 | function createToday () {
|
179 | return Promise.try(function () {
|
180 | return mainBoard || init()
|
181 | }).then(function (board) {
|
182 | return checkDefaultLists(options.todayList)
|
183 | }).then(function (result) {
|
184 | Promise.try(function () {
|
185 | return createList({
|
186 | name: moment().format('MMMM Do, YYYY'),
|
187 | board: result.boardId,
|
188 | sourceList: result.sourceList,
|
189 | position: '3'
|
190 | })
|
191 | }).then(function (list) {
|
192 | return t.postAsync('/1/lists/' + list.id + '/moveAllCards', {
|
193 | idBoard: result.boardId,
|
194 | idList: result.targetList
|
195 | })
|
196 | }).then(function () {
|
197 | return moveCardPosition({
|
198 | targetList: result.targetList,
|
199 | dailyLabel: dailyLabel,
|
200 | dailyOnly: true,
|
201 | pos: 'top'
|
202 | })
|
203 | }).then(function () {
|
204 | return removeDuplicates(options.todayList)
|
205 | }).then(function () {
|
206 | return archiveEmptyLists()
|
207 | }).then(function () {
|
208 | console.log('Done')
|
209 | })
|
210 | }).catch(function (err) {
|
211 | console.log('Error in createToday', err)
|
212 | })
|
213 | }
|
214 |
|
215 | function createCard (cardText, list, position) {
|
216 | return Promise.try(function () {
|
217 | return mainBoard || init()
|
218 | }).then(function (board) {
|
219 | return checkDefaultLists(list)
|
220 | }).then(function (result) {
|
221 | return t.postAsync('/1/cards', {
|
222 | name: cardText,
|
223 | pos: position || 'top',
|
224 | due: null,
|
225 | idList: result.targetList,
|
226 | urlSource: null
|
227 | })
|
228 | }).then(function () {
|
229 | console.log('Created card:', cardText)
|
230 | }).catch(function (err) {
|
231 | console.log('Error creating card', err)
|
232 | })
|
233 | }
|
234 |
|
235 | function removeDuplicates (listName, dailyOnly) {
|
236 | return Promise.try(function () {
|
237 | return mainBoard || init()
|
238 | }).then(function (board) {
|
239 | return checkDefaultLists(listName || options.todayList)
|
240 | }).then(function (result) {
|
241 | if (listName == null) {
|
242 | return result.targetList
|
243 | } else {
|
244 | return Promise.try(function () {
|
245 | return getOpenLists()
|
246 | }).filter(function (result) {
|
247 | return listName === result.name
|
248 | }).then(function (result) {
|
249 | return result[0].id
|
250 | }).catch(function (err) {
|
251 | console.log('Unable to find ' + listName, err)
|
252 | })
|
253 | }
|
254 | }).then(function (result) {
|
255 | if (dailyOnly == null) {
|
256 | dailyOnly = true
|
257 | }
|
258 |
|
259 | return Promise.try(function () {
|
260 | return t.getAsync('/1/lists/' + result, {cards: 'open'})
|
261 | }).then(function (result) {
|
262 | return _.difference(result.cards, _.uniq(result.cards, 'name'))
|
263 | }).filter(function (card) {
|
264 | return (dailyOnly && _.includes(card.idLabels, dailyLabel))
|
265 | }).map(function (card) {
|
266 | return Promise.try(function () {
|
267 | return t.delAsync('/1/cards/' + card.id)
|
268 | }).then(function () {
|
269 |
|
270 | })
|
271 | }).then(function (result) {
|
272 |
|
273 | })
|
274 | }).catch(function (err) {
|
275 | console.log('Error removing duplicates', err)
|
276 | })
|
277 | }
|
278 |
|
279 | return {
|
280 | getLists: getLists,
|
281 | archive: archiveEmptyLists,
|
282 | listCards: listCards,
|
283 | createCard: createCard,
|
284 | createToday: createToday,
|
285 | removeDuplicates: removeDuplicates
|
286 | }
|
287 | }
|