Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIO-7615: Add option to migrate pdf files to copy and migrate commands #79

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions commands/copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ module.exports = function(program, next) {
.option('--src-admin-key [key]', 'The Admin API Key to provide to the source form')
.option('--dst-admin-key [key]', 'The Admin API Key to provide to the destination form')
.option('--full', 'Will copy full form or resource structure')
.option(
'--migrate-pdf-files [migratePdfFiles]',
'Pass this option if you want to migrate PDF files from source PDF server to the destination for PDF forms',
false
)
.action(series([
require('../src/authenticate')({
src: 1,
Expand Down
5 changes: 5 additions & 0 deletions commands/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ module.exports = function(program, next) {
.option('--dst-key [key]', 'The API Key to provide to the destination form')
.option('--src-admin-key [key]', 'The Admin API Key to provide to the source form')
.option('--dst-admin-key [key]', 'The Admin API Key to provide to the destination form')
.option(
'--migrate-pdf-files [migratePdfFiles]',
'Pass this option if you want to migrate PDF files from source PDF server to the destination for PDF forms',
false
)
.option('--start-with [startWith]', 'Start the migration from a specific form. Useful to replay migrations.')
.option('--delete [delete]', 'Deletes all submissions in the destination form before the migration occurs.')
.option('--delete-previous [deletePrevious]', 'Deletes previous submissions that have been migrated with the migrate script.')
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"JSONStream": "^1.3.5",
"adm-zip": "^0.5.5",
"async": "^3.2.4",
"axios": "^1.7.7",
"colors": "^1.4.0",
"commander": "^6.2.0",
"core-js": "^3.24.1",
Expand Down
12 changes: 9 additions & 3 deletions src/copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
var async = require('async');
var _ = require('lodash');
var fetch = require('./fetch');
const {migratePdfFileForForm} = require('./utils');

module.exports = function(options, done) {
var type = options.params[0].trim();
Expand Down Expand Up @@ -31,7 +32,7 @@ module.exports = function(options, done) {
return next('Invalid form type given: ' + type);
}

var copyComponents = function(form, cb) {
var copyComponents = async function(form, cb) {
if (options.full) {
const formPart = _.omit(form, ['_id', '_vid', 'created', 'modified', 'machineName']);
destForm = _.assign(formPart, {components: [...formPart.components, ...destForm.components]});
Expand All @@ -40,15 +41,20 @@ module.exports = function(options, done) {
const formPart = _.pick(form, ['title', 'components', 'tags', 'properties', 'settings']);
destForm = _.assign(formPart, {components: [...formPart.components, ...destForm.components]});
}

if (options.migratePdfFiles) {
await migratePdfFileForForm(destForm, options);
}

return cb();
};

// For each source form, copy the components after uniquifying them.
async.eachSeries(sourceForms, function(src, cb) {
fetch(options)({
url: src
}).then(({body: form}) => {
copyComponents(form, cb);
}).then(async({body: form}) => {
await copyComponents(form, cb);
}).catch(err => {
console.log('Loading form ' + src + ' returned error: ' + err.message.red);
cb(err);
Expand Down
31 changes: 18 additions & 13 deletions src/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const request = require('request');
const formTransform = require('./transforms/form');
const fetch = require('./fetch');
const path = require('path');
const axios = require('axios');
const {migratePdfFileForForm} = require('./utils');

module.exports = function(options, next) {
let isProject = false;
Expand Down Expand Up @@ -295,30 +297,33 @@ module.exports = function(options, next) {
console.log(`Creating form ${_dest}`.green);

fetch(options.srcOptions)({
url: _src
}).then(({body}) => {
url: _src,
}).then(async({body}) => {
const dstProject = _dest.replace(`/${body.path}`, '');
request({
json: true,
method: 'POST',
url: `${dstProject}/form`,
headers: headers.dst,
body: {
try {
const destForm = {
title: body.title,
display: body.display,
path: body.path,
name: body.name,
type: body.type,
components: body.components,
settings: body.settings || {}
}
}, (err, resp) => {
if (err) {
return done(err);
};

if (options.migratePdfFiles) {
await migratePdfFileForForm(destForm, options);
}

await axios.post(`${dstProject}/form`, destForm, {'headers': {...headers.dst}});

// Migrate the data to this form.
deleteThenMigrate();
});
}
catch (err) {
console.log(err);
return done(err);
}
});
});
};
Expand Down
44 changes: 44 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';
const axios = require('axios');
const crypto = require('crypto');

async function getPdfFile(url) {
const response = await axios.get(url, {responseType: 'arraybuffer'});
const buffer = Buffer.from(response.data, 'binary'); // Get the file buffer
const fileName = `${crypto.randomUUID()}.pdf`;

return {
name: fileName,
buffer
};
}

async function migratePdfFileForForm(form, options) {
if (form.display !== 'pdf' || !form.settings.pdf) {
return;
}

const destUploadUrl = `${options.dstOptions.server}/${options.dstOptions.projectName}/upload`;
const file = await getPdfFile(form.settings.pdf.src + '.pdf');
const formData = new FormData();
const fileBlob = new Blob([file.buffer], {type: 'application/pdf'});

formData.set('file', fileBlob, file.name);

const result = await axios.post(destUploadUrl, formData, {
headers: {
'x-token': options.dstOptions.key,
'Content-Type': 'multipart/form-data',
}
});

// Assign new pdf file info to the form
form.settings.pdf = {
src: `${options.dstOptions.server}/pdf-proxy${result.data.path}`,
id: result.data.file
};
}

module.exports = {
migratePdfFileForForm
};
25 changes: 22 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,15 @@ aws4@^1.8.0:
resolved "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3"
integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==

axios@^1.7.7:
version "1.7.7"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f"
integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
Expand Down Expand Up @@ -760,9 +769,9 @@ create-server@~1.0.1:
connected "~0.0.2"

cross-spawn@^7.0.2:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
version "7.0.3"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
Expand Down Expand Up @@ -1379,6 +1388,11 @@ flatted@^3.1.0:
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==

follow-redirects@^1.15.6:
version "1.15.9"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==

font-awesome@^4.7.0:
version "4.7.0"
resolved "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
Expand Down Expand Up @@ -2645,6 +2659,11 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"

proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==

psl@^1.1.28:
version "1.9.0"
resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
Expand Down