UNPKG

8.6 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 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 /* Print all open list names from the default board */
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 /* Print out open cards from a given list */
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 // console.log('Deleted card: ' + card.name + ' (' + card.id + ')')
270 })
271 }).then(function (result) {
272 // console.log('Done deleting duplicates.')
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}