UNPKG

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