|
1 'use strict'; |
|
2 |
|
3 var Command = require('ember-cli/lib/models/command'); |
|
4 var chalk = require('chalk'); |
|
5 var path = require('path'); |
|
6 var Q = require("q"); |
|
7 var request = require("request"); |
|
8 var _ = require('lodash'); |
|
9 var fs = require('fs'); |
|
10 |
|
11 // taken from http://stackoverflow.com/a/17238793 |
|
12 // `condition` is a function that returns a boolean |
|
13 // `body` is a function that returns a promise |
|
14 // returns a promise for the completion of the loop |
|
15 function promiseWhile(condition, body) { |
|
16 |
|
17 var done = Q.defer(); |
|
18 |
|
19 function loop() { |
|
20 // When the result of calling `condition` is no longer true, we are |
|
21 // done. |
|
22 if (!condition()) return done.resolve(); |
|
23 // Use `when`, in case `body` does not return a promise. |
|
24 // When it completes loop again otherwise, if it fails, reject the |
|
25 // done promise |
|
26 Q.when(body(), loop, done.reject); |
|
27 } |
|
28 |
|
29 // Start running the loop in the next tick so that this function is |
|
30 // completely async. It would be unexpected if `body` was called |
|
31 // synchronously the first time. |
|
32 Q.nextTick(loop); |
|
33 |
|
34 // The promise |
|
35 return done.promise; |
|
36 } |
|
37 |
|
38 |
|
39 module.exports = Command.extend({ |
|
40 name: 'dl-fixtures', |
|
41 description: "Download fixtures", |
|
42 works: 'everywhere', |
|
43 availableOptions: [ |
|
44 { name: 'type', type: String, default: 'documents', aliases: ['t'], description: "type of obejcts to downloads" }, |
|
45 { name: 'url', type: String, aliases: ['u'], description: "Source url" }, |
|
46 { name: 'dest', type: String, aliases: ['d'], description: "File destination" }, |
|
47 { name: 'page', type: Number, default: 1 , aliases: ['p'], description: "number of page to download"}, |
|
48 ], |
|
49 run: function(commandOptions, rawArgs) { |
|
50 |
|
51 //TODO: check that commandOptions.url is not empty |
|
52 |
|
53 var dest = commandOptions.dest || "." + path.sep + commandOptions.type + ".js" |
|
54 |
|
55 var ids = []; |
|
56 var pageIndex = 1; |
|
57 var nextPageUrl = commandOptions.url; |
|
58 |
|
59 return promiseWhile( |
|
60 function() { return pageIndex <= commandOptions.page && nextPageUrl }, |
|
61 function() { |
|
62 var deferred = Q.defer(); |
|
63 request.get({url: nextPageUrl, json: true}, function (err, res, body) { |
|
64 if (err) { |
|
65 return deferred.reject(err); |
|
66 } else if (res.statusCode !== 200) { |
|
67 err = new Error("Unexpected status code: " + res.statusCode); |
|
68 err.res = res; |
|
69 return deferred.reject(err); |
|
70 } |
|
71 nextPageUrl = body.next_page_url; |
|
72 pageIndex++; |
|
73 |
|
74 ids = _.reduce( |
|
75 body.documents, |
|
76 function(res, doc) { |
|
77 res.push(doc.id); |
|
78 return res; |
|
79 }, |
|
80 ids |
|
81 ); |
|
82 deferred.resolve(ids); |
|
83 }); |
|
84 return deferred.promise; |
|
85 } |
|
86 ).then(function() { |
|
87 return Q.all(_.map(ids, function(id) { |
|
88 var deferred = Q.defer(); |
|
89 request.get({url: commandOptions.url + id, json: true}, function (err, res, body) { |
|
90 if (err) { |
|
91 return deferred.reject(err); |
|
92 } else if (res.statusCode !== 200) { |
|
93 err = new Error("Unexpected status code: " + res.statusCode); |
|
94 err.res = res; |
|
95 return deferred.reject(err); |
|
96 } |
|
97 deferred.resolve(body.document); |
|
98 }); |
|
99 return deferred.promise; |
|
100 })); |
|
101 }).then(function(res) { |
|
102 var deferred = Q.defer(); |
|
103 fs.writeFile(dest, "module.exports = " + JSON.stringify(res,null,2) + ";", function(err) { |
|
104 if(err) { |
|
105 return deferred.reject(err); |
|
106 } |
|
107 deferred.resolve(); |
|
108 }); |
|
109 return deferred.promise; |
|
110 }); |
|
111 } |
|
112 }); |