'use strict';
var Command = require('ember-cli/lib/models/command');
var chalk = require('chalk');
var path = require('path');
var Q = require("q");
var request = require("request");
var _ = require('lodash');
var fs = require('fs');
// taken from http://stackoverflow.com/a/17238793
// `condition` is a function that returns a boolean
// `body` is a function that returns a promise
// returns a promise for the completion of the loop
function promiseWhile(condition, body) {
var done = Q.defer();
function loop() {
// When the result of calling `condition` is no longer true, we are
// done.
if (!condition()) return done.resolve();
// Use `when`, in case `body` does not return a promise.
// When it completes loop again otherwise, if it fails, reject the
// done promise
Q.when(body(), loop, done.reject);
}
// Start running the loop in the next tick so that this function is
// completely async. It would be unexpected if `body` was called
// synchronously the first time.
Q.nextTick(loop);
// The promise
return done.promise;
}
module.exports = Command.extend({
name: 'dl-fixtures',
description: "Download fixtures",
works: 'everywhere',
availableOptions: [
{ name: 'type', type: String, default: 'documents', aliases: ['t'], description: "type of obejcts to downloads" },
{ name: 'url', type: String, aliases: ['u'], description: "Source url" },
{ name: 'dest', type: String, aliases: ['d'], description: "File destination" },
{ name: 'page', type: Number, default: 1 , aliases: ['p'], description: "number of page to download"},
{ name: 'format', type: String, default: 'es6' , aliases: ['f'], description: "Format for module export, es6 or require"},
],
run: function(commandOptions, rawArgs) {
//TODO: check that commandOptions.url is not empty
var dest = commandOptions.dest || "." + path.sep + commandOptions.type + ".js"
var format = commandOptions.format || 'es6';
var ids = [];
var pageIndex = 1;
var nextPageUrl = commandOptions.url;
return promiseWhile(
function() { return pageIndex <= commandOptions.page && nextPageUrl },
function() {
var deferred = Q.defer();
request.get({url: nextPageUrl, json: true}, function (err, res, body) {
if (err) {
return deferred.reject(err);
} else if (res.statusCode !== 200) {
err = new Error("Unexpected status code: " + res.statusCode);
err.res = res;
return deferred.reject(err);
}
nextPageUrl = body.next_page_url;
pageIndex++;
ids = _.reduce(
body.documents,
function(res, doc) {
res.push(doc.id);
return res;
},
ids
);
deferred.resolve(ids);
});
return deferred.promise;
}
).then(function() {
return Q.all(_.map(ids, function(id) {
var deferred = Q.defer();
request.get({url: commandOptions.url + id, json: true}, function (err, res, body) {
if (err) {
return deferred.reject(err);
} else if (res.statusCode !== 200) {
err = new Error("Unexpected status code: " + res.statusCode);
err.res = res;
return deferred.reject(err);
}
deferred.resolve(body.document);
});
return deferred.promise;
}));
}).then(function(res) {
var deferred = Q.defer();
var prefix = (format==='es6')?'export default ':"module.exports = ";
fs.writeFile(dest, prefix + JSON.stringify(res,null,2) + ";", function(err) {
if(err) {
return deferred.reject(err);
}
deferred.resolve();
});
return deferred.promise;
});
}
});