From d89bb1532acb6199d19233a4ec629099a7e15db7 Mon Sep 17 00:00:00 2001 From: Matthias Luebken Date: Thu, 5 Jan 2012 15:51:22 +0100 Subject: [PATCH 1/8] bugfix: backup multiple boards --- example_backup.js | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/example_backup.js b/example_backup.js index 64039b7..b00ca88 100644 --- a/example_backup.js +++ b/example_backup.js @@ -1,28 +1,31 @@ -var app_key = ''; -var oauth_access_token = ''; -var organization = ''; +var app_key = ; +var oauth_access_token = ; +var organization = ; + var fs = require('fs'); var Trello = require("./main.js"); var t = new Trello(app_key, oauth_access_token); t.api("/1/organization/" + organization + "/boards/all", function(err, data) { - if(err) throw err; - for(board in data) { - var board_id = data[board].id; - var board_name = data[board].name; - t.api('/1/board/' + board_id + '/cards/all', function(err, data) { - if(err) throw err; - var filename = board_name + " - " + new Date().toString() + ".json"; - console.log('Backing up ' + data.length + ' cards for board "' + board_name); - - fs.writeFile(filename, JSON.stringify(data), function(err) { - if(err) { - console.log(err); - } else { - console.log("Saved to " + filename); - } - }); - }); - } -}); \ No newline at end of file + if(err) throw err; + for (var i=0; i < data.length; i++) { + backupCards(data[i].id, data[i].name); + } +}); + +function backupCards(board_id, board_name) { + t.api('/1/board/' + board_id + '/cards/all', function(err, data) { + if(err) throw err; + var filename = board_name + " - " + new Date().toString() + ".json"; + console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); + + fs.writeFile(filename, JSON.stringify(data), function(err) { + if(err) { + console.log(err); + } else { + console.log("Saved to " + filename); + } + }); + }); +} \ No newline at end of file From 9ae7fca99ec1a78939b7fc3bfa6e7f848d825423 Mon Sep 17 00:00:00 2001 From: Matthias Luebken Date: Fri, 6 Jan 2012 19:36:37 +0100 Subject: [PATCH 2/8] refactoring to object --- example_backup.js | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/example_backup.js b/example_backup.js index afb0600..129b71b 100644 --- a/example_backup.js +++ b/example_backup.js @@ -1,21 +1,23 @@ -var app_key = ; -var oauth_access_token = ; -var organization = ; - - -var fs = require('fs'); var Trello = require("./main.js"); -var t = new Trello(app_key, oauth_access_token); +var fs = require('fs'); -t.get("/1/organization/" + organization + "/boards/all", function(err, data) { - if(err) throw err; - for (var i=0; i < data.length; i++) { - backupCards(data[i].id, data[i].name); - } -}); +var trello_backup = function(app_key, oauth_access_token, organization) { + this.organization = organization; + this.trello = new Trello(app_key, oauth_access_token); +} -function backupCards(board_id, board_name) { - t.get('/1/board/' + board_id + '/cards/all', function(err, data) { +trello_backup.prototype.backupOrganization = function() { + var self = this; + this.trello.get("/1/organization/" + this.organization + "/boards/all", function(err, data) { + if(err) throw err; + for (var i=0; i < data.length; i++) { + self.backupCards(data[i].id, data[i].name); + } + }); +} + +trello_backup.prototype.backupCards = function(board_id, board_name) { + this.trello.get('/1/board/' + board_id + '/cards/all', function(err, data) { if(err) throw err; var filename = board_name + " - " + new Date().toString() + ".json"; console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); @@ -29,3 +31,15 @@ function backupCards(board_id, board_name) { }); }); } + +exports = module.exports = trello_backup; + +//config +var app_key = ''; +var oauth_access_token = ''; +var organization = ''; + +//usage +var tb = new trello_backup(app_key, oauth_access_token, organization); +tb.backupOrganization(); + From d55352aed327e3cfc049002d2f193c45887f416c Mon Sep 17 00:00:00 2001 From: Matthias Luebken Date: Fri, 6 Jan 2012 19:40:54 +0100 Subject: [PATCH 3/8] Extracted code from example usage --- backup.js | 35 +++++++++++++++++++++++++++++++++++ example_backup.js | 38 ++------------------------------------ 2 files changed, 37 insertions(+), 36 deletions(-) create mode 100644 backup.js diff --git a/backup.js b/backup.js new file mode 100644 index 0000000..5cf5629 --- /dev/null +++ b/backup.js @@ -0,0 +1,35 @@ +var Trello = require("./main.js"); +var fs = require('fs'); + +var trello_backup = function(app_key, oauth_access_token, organization) { + this.organization = organization; + this.trello = new Trello(app_key, oauth_access_token); +} + +trello_backup.prototype.backupOrganization = function() { + var self = this; + this.trello.get("/1/organization/" + this.organization + "/boards/all", function(err, data) { + if(err) throw err; + for (var i=0; i < data.length; i++) { + self.backupCards(data[i].id, data[i].name); + } + }); +} + +trello_backup.prototype.backupCards = function(board_id, board_name) { + this.trello.get('/1/board/' + board_id + '/cards/all', function(err, data) { + if(err) throw err; + var filename = board_name + " - " + new Date().toString() + ".json"; + console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); + + fs.writeFile(filename, JSON.stringify(data), function(err) { + if(err) { + console.log(err); + } else { + console.log("Saved to " + filename); + } + }); + }); +} + +exports = module.exports = trello_backup; \ No newline at end of file diff --git a/example_backup.js b/example_backup.js index 129b71b..96aaca7 100644 --- a/example_backup.js +++ b/example_backup.js @@ -1,38 +1,4 @@ -var Trello = require("./main.js"); -var fs = require('fs'); - -var trello_backup = function(app_key, oauth_access_token, organization) { - this.organization = organization; - this.trello = new Trello(app_key, oauth_access_token); -} - -trello_backup.prototype.backupOrganization = function() { - var self = this; - this.trello.get("/1/organization/" + this.organization + "/boards/all", function(err, data) { - if(err) throw err; - for (var i=0; i < data.length; i++) { - self.backupCards(data[i].id, data[i].name); - } - }); -} - -trello_backup.prototype.backupCards = function(board_id, board_name) { - this.trello.get('/1/board/' + board_id + '/cards/all', function(err, data) { - if(err) throw err; - var filename = board_name + " - " + new Date().toString() + ".json"; - console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); - - fs.writeFile(filename, JSON.stringify(data), function(err) { - if(err) { - console.log(err); - } else { - console.log("Saved to " + filename); - } - }); - }); -} - -exports = module.exports = trello_backup; +var TrelloBackup = require("./backup.js"); //config var app_key = ''; @@ -40,6 +6,6 @@ var oauth_access_token = ''; var organization = ''; //usage -var tb = new trello_backup(app_key, oauth_access_token, organization); +var tb = new TrelloBackup(app_key, oauth_access_token, organization); tb.backupOrganization(); From cee09ca68cc1225c04de3a0f2d04e22f65009689 Mon Sep 17 00:00:00 2001 From: Matthias Luebken Date: Fri, 6 Jan 2012 23:44:08 +0100 Subject: [PATCH 4/8] basic csv support --- backup.js | 61 ++++++++++++++++++++++++++++++++++++++--------- example_backup.js | 4 +++- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/backup.js b/backup.js index 5cf5629..87b6e9c 100644 --- a/backup.js +++ b/backup.js @@ -1,9 +1,10 @@ var Trello = require("./main.js"); var fs = require('fs'); -var trello_backup = function(app_key, oauth_access_token, organization) { +var trello_backup = function(app_key, oauth_access_token, organization, data_type) { this.organization = organization; this.trello = new Trello(app_key, oauth_access_token); + this.data_type = data_type; //json, csv } trello_backup.prototype.backupOrganization = function() { @@ -17,19 +18,57 @@ trello_backup.prototype.backupOrganization = function() { } trello_backup.prototype.backupCards = function(board_id, board_name) { + var self = this; this.trello.get('/1/board/' + board_id + '/cards/all', function(err, data) { if(err) throw err; - var filename = board_name + " - " + new Date().toString() + ".json"; - console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); - - fs.writeFile(filename, JSON.stringify(data), function(err) { - if(err) { - console.log(err); - } else { - console.log("Saved to " + filename); - } - }); + self.writeCards(board_name, data); }); } +trello_backup.prototype.writeCards = function(board_name, data) { + var filename = board_name + " - " + new Date().toString() + "." + this.data_type; + console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); + + var string; + if(this.data_type == 'csv') { + string = this.createCSV(data); + }else { + string = JSON.stringify(data); + } + + fs.writeFile(filename, string, function(err) { + if(err) { + console.log(err); + } else { + console.log("Saved to " + filename); + } + }); +} + +trello_backup.prototype.createCSV = function(data) { + var csv = ""; + //title + var card = data[0]; + for(key in card) { + csv += key + ", "; + } + csv = csv.substr(0, csv.length-2); + csv += '\n'; + + //data + for (var i=0; i < data.length; i++) { + var card = data[i]; + for(key in card) { + var prop = card[key].toString(); + prop = prop.replace(/"/g,' '); // remove " + prop = prop.replace(/,/g,' '); // remove , + prop = prop.replace(/\n/g, ' '); // remove new lines + csv += prop + ", "; + } + csv = csv.substr(0, csv.length-2); + csv += '\n'; + }; + return csv; +} + exports = module.exports = trello_backup; \ No newline at end of file diff --git a/example_backup.js b/example_backup.js index 96aaca7..674bd41 100644 --- a/example_backup.js +++ b/example_backup.js @@ -1,11 +1,13 @@ var TrelloBackup = require("./backup.js"); + //config var app_key = ''; var oauth_access_token = ''; var organization = ''; +var data_type = 'csv'; //json, csv //usage -var tb = new TrelloBackup(app_key, oauth_access_token, organization); +var tb = new TrelloBackup(app_key, oauth_access_token, organization, data_type); tb.backupOrganization(); From fb81e716709de5aa43b7c315589c29d507d34c6b Mon Sep 17 00:00:00 2001 From: David Johnson Date: Sun, 8 Jan 2012 02:11:33 -0800 Subject: [PATCH 5/8] Revising example to backup lists and cards for multiple boards This copies heavily from the revised code from adcloud to correct the problem with multiple board backup corrupting the base filename and overwriting backups. --- example_backup.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/example_backup.js b/example_backup.js index 1fd2007..8fa557b 100644 --- a/example_backup.js +++ b/example_backup.js @@ -7,22 +7,24 @@ var Trello = require("./main.js"); var t = new Trello(app_key, oauth_access_token); t.get("/1/organization/" + organization + "/boards/all", function(err, data) { - if(err) throw err; - for(board in data) { - var board_id = data[board].id; - var board_name = data[board].name; - t.api('/1/board/' + board_id + '/cards/all', function(err, data) { - if(err) throw err; - var filename = board_name + " - " + new Date().toString() + ".json"; - console.log('Backing up ' + data.length + ' cards for board "' + board_name); - - fs.writeFile(filename, JSON.stringify(data), function(err) { - if(err) { - console.log(err); - } else { - console.log("Saved to " + filename); - } - }); - }); - } + if(err) throw err; + for (var i=0; i < data.length; i++) { + backupLists(data[i].id, data[i].name); + } }); + +function backupLists(board_id, board_name) { + t.get('/1/board/' + board_id + '/lists/all', function(err, data) { + if(err) throw err; + var filename = board_name + " - " + new Date().toString() + ".json"; + console.log('Backing up ' + data.length + ' cards for board "' + board_name + '"'); + + fs.writeFile(filename, JSON.stringify(data), function(err) { + if(err) { + console.log(err); + } else { + console.log("Saved to " + filename); + } + }); + }); +} \ No newline at end of file From cc01a6813d574614bf1b8b9b5b80f277eb127e51 Mon Sep 17 00:00:00 2001 From: David Johnson Date: Sun, 8 Jan 2012 10:05:22 -0800 Subject: [PATCH 6/8] Corrected typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0076621..f46573c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Node wrapper for Trello's HTTP API. * With these values [visit this other link](https://trello.com/1/connect?key=&name=MyApp&response_type=token) (Replacing, of course <PUBLIC_KEY> for the public key value obtained). -* Authorice MyApp to read the application +* Authorize MyApp to read the application * MyApp now have the token. From 4a68ba7722f06853570985379b9c3f99c338e72e Mon Sep 17 00:00:00 2001 From: David Johnson Date: Sun, 8 Jan 2012 10:05:22 -0800 Subject: [PATCH 7/8] Corrected typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0076621..f46573c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Node wrapper for Trello's HTTP API. * With these values [visit this other link](https://trello.com/1/connect?key=&name=MyApp&response_type=token) (Replacing, of course <PUBLIC_KEY> for the public key value obtained). -* Authorice MyApp to read the application +* Authorize MyApp to read the application * MyApp now have the token. From 8714c77cb3b9a0baa16e68eadabc4859c3827eb2 Mon Sep 17 00:00:00 2001 From: David Johnson Date: Sun, 8 Jan 2012 16:17:47 -0800 Subject: [PATCH 8/8] Added recursive CSV to create CSV with one row per card including all the list information This recurses through each list and then creates unique rows for each card including the list fields in the CSV. --- backup.js | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/backup.js b/backup.js index 18b9e3c..61ea1fb 100644 --- a/backup.js +++ b/backup.js @@ -57,25 +57,56 @@ trello_backup.prototype.writeCards = function(board_name, data) { trello_backup.prototype.createCSV = function(data) { var csv = ""; //title - var card = data[0]; - for(key in card) { - csv += key + ", "; + var list = data[0]; + for(key in list) { + if (key != "cards") { + csv += key + ", "; + } } + // ensure the card keys are always at the end + for(key2 in list.cards[0]) { + csv += key2 + ", "; + } csv = csv.substr(0, csv.length-2); csv += '\n'; //data + // builds the list csv piece and then prepends this to every card entry for (var i=0; i < data.length; i++) { - var card = data[i]; - for(key in card) { - var prop = card[key].toString(); + var list = data[i]; + var list_csv = "" + for(key in list) { + if (key != "cards") { + var prop = list[key].toString(); prop = prop.replace(/"/g,' '); // remove " prop = prop.replace(/,/g,' '); // remove , prop = prop.replace(/\n/g, ' '); // remove new lines - csv += prop + ", "; - } - csv = csv.substr(0, csv.length-2); - csv += '\n'; + list_csv += prop + ", "; + }; + }; + + // make sure not to add an extra field + list_csv = list_csv.substr(0, list_csv.length-2); + + // card data or dump list information if no cards + if (list.cards != null) { + for (var j=0; j < list.cards.length; j++) { + csv += list_csv + ","; + var card = list.cards[j] + for(key in card) { + var prop = card[key].toString(); + prop = prop.replace(/"/g,' '); // remove " + prop = prop.replace(/,/g,' '); // remove , + prop = prop.replace(/\n/g, ' '); // remove new lines + csv += prop + ", "; + }; + csv = csv.substr(0, csv.length-2); + csv += '\n'; + }; + } else { + csv += list_csv; + csv += '\n'; + }; }; return csv; }