@nzz/q-server
Version:
__Q__ is a system that lets journalists create visual elements for stories. It is developed by [NZZ Storytelling](https://www.nzz.ch/storytelling) and used in the [NZZ](https://www.nzz.ch) newsroom.
135 lines (112 loc) • 3.33 kB
JavaScript
const Boom = require('boom');
const fetch = require('node-fetch');
const getDb = require('../../db.js').getDb;
const server = require('../../server').getServer();
const db = getDb();
const statusUpdated = 'updated';
const statusNotUpdated = 'not updated';
const statusFailed = 'failed';
module.exports = {
path: '/admin/migration/{tool}/{id?}',
method: 'GET',
config: {
auth: 'q-auth',
cors: {
credentials: true
},
description: 'Executes migration of items in database for specified tool or for a single item with the specified id respectively',
tags: ['api']
},
handler: (request, reply) => {
const tool = request.params.tool;
if (!server.settings.app.tools.get(`/${tool}/baseUrl`)) {
return reply(Boom.notImplemented(`no base url configuration for ${tool} found`));
}
const options = {
keys: [tool],
include_docs: true,
reduce: false
};
if (request.params.id) {
db.get(request.params.id, async(err, item) => {
if (err) {
return reply(Boom.create(err.statusCode, err.description));
}
let migrationStatus = await migrateItem(item, tool);
return reply({
status: migrationStatus.status
}).type('application/json');
});
} else {
db.view('items', 'byTool', options, async(err, data) => {
if (err) {
return reply(Boom.create(err.statusCode, err.description));
}
const items = data.rows.map(item => {
return item.doc;
});
let migrationStatuses = items.map(async item => {
return await migrateItem(item, tool);
})
migrationStatuses = await Promise.all(migrationStatuses);
const stats = migrationStatuses.reduce((groupedStats, migrationStatus) => {
const status = migrationStatus.status;
if(!groupedStats[status]) {
groupedStats[status] = [];
}
groupedStats[status].push(migrationStatus.id);
return groupedStats;
}, {});
return reply(stats).type('application/json');
});
}
}
}
function migrateItem(item, tool) {
return new Promise(async (resolve, reject) => {
const baseUrl = server.settings.app.tools.get(`/${tool}/baseUrl`);
const body = {
item: item
}
try {
const response = await fetch(`${baseUrl}/migration`, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json'
}
})
if (response.status === 200) {
const json = await response.json();
await saveItem(json.item);
return resolve({
id: item._id,
status: statusUpdated
});
}
if (response.status === 304) {
return resolve({
id: item._id,
status: statusNotUpdated
});
}
throw new Error(`item ${item._id} could not be migrated`);
} catch (e) {
server.log(['error'], e);
resolve({
id: item._id,
status: statusFailed
});
}
});
}
function saveItem(item) {
return new Promise((resolve, reject) => {
db.insert(item, (err, res) => {
if (err) {
reject(err);
}
});
resolve(item);
});
}