-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexportTrelloBoards.js
181 lines (163 loc) · 6.65 KB
/
exportTrelloBoards.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
const Trello = require('trello')
const config = require('./config.json')
const {writeExport} = require('./diskUtils')
const trello = new Trello(config.appKey, config.userToken)
const dev = false
const fetchOrganisationBoards = organizationId => {
console.log('# Fetching boards for organization "' + organizationId + '" :')
// get all boards
const boards = [],
boardsP = trello.getOrgBoards(organizationId)
return boardsP
.then(fetchedBoards => {
console.log('## ' + fetchedBoards.length + ' boards fetched')
if (dev && fetchedBoards.length > 1){
fetchedBoards.splice(1, fetchedBoards.length - 1) //keep only one board during dev
console.log('## Dev mode, only one board fetched : ', fetchedBoards.map(b => b.name))
}
return fetchedBoards.reduce((prevP, currentBoard) => {
return prevP.then(([prevBoard, prevLists, prevCards, prevActions, prevCustomFields, prevChecklists, prevMembers]) => {
// save previous stuff for board
if (prevBoard) {
console.log('Items fetched for "' + prevBoard.name + '" :')
prevBoard.lists = prevLists
prevBoard.cards = prevCards
prevBoard.actions = prevActions
prevBoard.customFields = prevCustomFields
prevBoard.checklists = prevChecklists
prevBoard.members = prevMembers
console.log('- ' + prevLists.length + ' lists fetched')
console.log('- ' + prevCards.length + ' cards fetched')
console.log('- ' + prevActions.length + ' actions fetched')
console.log('- ' + prevCustomFields.length + ' CF fetched')
console.log('- ' + prevChecklists.length + ' checklists fetched')
console.log('- ' + prevMembers.length + ' members fetched')
// console.log('prevBoard with cards and lists', prevBoard)
// add board to boards array
boards.push(prevBoard)
}
// fetch new stuff for current board
return fetchDataForBoard(currentBoard)
})
.catch(err => {
console.error('Error when fetching board ' + currentBoard.name, err.toString())
})
}, Promise.resolve([]))
.then(([prevBoard, prevLists, prevCards, prevActions, prevCustomFields, prevChecklists, prevMembers]) => {
// save stuff for last board
if (prevBoard) {
console.log('## Items fetched for "' + prevBoard.name + '" :')
prevBoard.lists = prevLists
prevBoard.cards = prevCards
prevBoard.actions = prevActions
prevBoard.customFields = prevCustomFields
prevBoard.checklists = prevChecklists
prevBoard.members = prevMembers
console.log('- ' + prevLists.length + ' lists fetched')
console.log('- ' + prevCards.length + ' cards fetched')
console.log('- ' + prevActions.length + ' actions fetched')
console.log('- ' + prevCustomFields.length + ' CF fetched')
console.log('- ' + prevChecklists.length + ' checklists fetched')
console.log('- ' + prevMembers.length + ' members fetched')
// console.log('prevBoard with cards and lists', prevBoard)
// add board to boards array
boards.push(prevBoard)
}
// fetch new stuff for current board
return Promise.resolve()
})
})
.then(() => {
//get attachments for cards board by board
console.log('### Fetched attachments for all cards :')
return boards.reduce((prevBoardP, currentBoard, index) =>
prevBoardP.then(() => fetchAttachmentsForCards(currentBoard.cards, (index + 1) + '/' + boards.length + ' ' + currentBoard.name + ': '))
, Promise.resolve()
)
})
.then(() => {
return writeExport(organizationId, boards) //write to disk
})
.catch(err => {
console.error('Error when getBoards', err.toString())
})
}
const fetchDataForBoard = board => {
const listsP = trello.getListsOnBoard(board.id),
cardsP = trello.getCardsOnBoard(board.id),
actionsP = trello.getActionsOnBoard(board.id),
customFieldsP = trello.getCustomFieldsOnBoard(board.id),
checklistsP = trello.makeRequest('get', `/1/boards/${board.id}/checklists`),
membersP = trello.getBoardMembers(board.id),
results = []
//execute promises one by one
return [Promise.resolve(board), listsP, cardsP, actionsP, customFieldsP, checklistsP, membersP]
.reduce((previousP, current) =>
previousP.then(result => {
results.push(result)
return current
}))
.then(finalResult => {
results.push(finalResult)
return results
})
}
/**
* Returns chunks of size n.
* @param {Array<any>} array any array
* @param {number} n size of chunk
*/
function* chunks(array, n) {
for (let i = 0; i < array.length; i += n) yield array.slice(i, i + n)
}
const fetchAttachmentsForCards = (cards, boardStatus) => {
// 1 by 1
let index = 0
return cards.reduce((previousP, currentCard) => {
//treat last card request
return previousP.then(previousAttachments => {
//skip if no fetch
if (previousAttachments && previousAttachments.length) {
//console.log(boardStatus + 'Fetched attachments for cards ' + (index) + '/' + cards.length + ' : ' + previousAttachments.length)
//make sure there is no errors like this
// {
// "name": "UnauthorizedError",
// "message": "unauthorized card permission requested",
// "statusCode": 401
// }
const attachmentFiltered = previousAttachments.filter(a => !a.statusCode)
if (attachmentFiltered.length != previousAttachments.length)
console.error((previousAttachments.length - attachmentFiltered.length) + 'error(s) occurred during fetch for card ' + cards[index].name)
//match attachments to cards
cards[index].attachments = attachmentFiltered
index++
}
//request next attachments if next cards has any
if (currentCard.badges.attachments) {
console.log('### ' + boardStatus + 'Fetch attachments for card ' + (index + 1) + '/' + cards.length)
return trello.getAttachmentsOnCard(currentCard.id)
} else {
currentCard.attachments = []
console.log('### ' + boardStatus + 'Skip attachments for card ' + (index + 1) + '/' + cards.length)
index++ //pre-increment for next card
return Promise.resolve([]) //fake empty array of attachments
}
})
.catch(err => {
console.error('Error when fetching attachments for card ' + cards[index].name, err.toString())
})
}, Promise.resolve([]))
}
// check if config.organizationIds is an array and not empty
if (!Array.isArray(config.organizationIds) || !config.organizationIds.length) {
console.error('config.organizationIds is not an array or is empty')
process.exit(1)
}
// fetch all boards for all organizations
// Promise.all(config.organizationIds.map(id => fetchOrganisationBoards(id)))
config.organizationIds.reduce((prevP, currentId) => {
return prevP.then(() => fetchOrganisationBoards(currentId))
}, Promise.resolve())
.then(() => {
console.log('All organizations fetched')
})