Skip to content

Commit

Permalink
fix(backup): Fixed weirdness with streams
Browse files Browse the repository at this point in the history
refs: TryGhost/Toolbox#334
refs: #468

- the old streams wiring didn't handle the 404 error
- my previous attempt at changing the stream code  hung on success instead
- this is more modern code, but works on node 12 for both the success and failure case
  • Loading branch information
ErisDS committed May 19, 2022
1 parent fa46ccf commit 0665bc1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 33 deletions.
44 changes: 30 additions & 14 deletions lib/tasks/import/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ const semver = require('semver');
const FormData = require('form-data');
const {Cookie} = require('tough-cookie');

const {promisify} = require('util');
const stream = require('stream');
const pipeline = promisify(stream.pipeline);
const fsp = require('fs').promises;

const {SystemError} = require('../../errors');

const bases = {
Expand All @@ -15,6 +20,16 @@ const bases = {
5: '/ghost/api/admin'
};

function streamFile(url, options, filePath) {
return pipeline(
got.stream(url, {...options}),
fs.createWriteStream(filePath)
).catch((err) => {
fsp.unlink(filePath);
throw err;
});
}

function getBaseUrl(version, url) {
const basePath = bases[semver.major(version)];

Expand Down Expand Up @@ -128,26 +143,27 @@ async function runImport(version, url, auth, exportFile) {

async function downloadContentExport(version, url, auth, outputFile) {
const authOpts = await getAuthOpts(version, url, auth);
let endpoint = '/db/';

await new Promise((resolve, reject) => {
const ws = fs.createWriteStream(outputFile);
const resp = got.stream('/db/', {...authOpts}).pipe(ws);

resp.on('finish', () => resolve()).on('error', reject);
});
await streamFile(endpoint, authOpts, outputFile);
}

async function downloadMembersExport(version, url, auth, outputFile) {
const authOpts = await getAuthOpts(version, url, auth);
let endpoint = '/members/upload/';

await new Promise((resolve, reject) => {
const ws = fs.createWriteStream(outputFile);
got
.stream('/members/upload/', {...authOpts})
.on('finish', () => resolve())
.on('error', reject)
.pipe(ws);
});
if (semver.lt(version, '3.20.0')) {
endpoint = '/members/csv/';
}

try {
await streamFile(endpoint, authOpts, outputFile);
} catch (error) {
// Members endpoint may not exist, we can ignore this
if (error.statusCode !== 404) {
throw error;
}
}
}

module.exports = {
Expand Down
24 changes: 5 additions & 19 deletions lib/tasks/import/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,6 @@ async function importTask(ui, instance, exportFile) {
}], false);
}

async function tryMembersDownload(version, url, authData, membersFile) {
try {
await downloadMembersExport(version, url, authData, membersFile);
} catch (error) {
// Members endpoint may not exist, we can ignore this
if (!error.statusCode === 404) {
throw error;
}
}
}

async function exportTask(ui, instance, contentFile, membersFile) {
const url = instance.config.get('url');

Expand All @@ -61,14 +50,11 @@ async function exportTask(ui, instance, contentFile, membersFile) {

const authData = await ui.prompt(authPrompts);

return ui.listr([{
title: 'Exporting content',
task: () => downloadContentExport(instance.version, url, authData, contentFile)
}, {
title: 'Exporting members',
task: () => tryMembersDownload(instance.version, url, authData, membersFile),
enabled: () => !!membersFile
}], false);
await downloadContentExport(instance.version, url, authData, contentFile);

if (membersFile) {
await downloadMembersExport(instance.version, url, authData, membersFile);
}
}

module.exports = {
Expand Down

0 comments on commit 0665bc1

Please sign in to comment.