Skip to content

Commit

Permalink
Merge pull request #1 from somaromero/background-image-setup
Browse files Browse the repository at this point in the history
Load multiple images setup
  • Loading branch information
somaromero authored Sep 4, 2024
2 parents 7cfbbc7 + e53a814 commit b8056f8
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 18 deletions.
2 changes: 1 addition & 1 deletion dist/api.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/app.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "directus-extension-pdf-builder",
"description": "This package is a node for Directus flows, utilizing the PDFMake library for generating PDF documents.",
"icon": "extension",
"version": "1.0.6",
"version": "1.1.0",
"keywords": [
"directus",
"directus-extension",
Expand Down
81 changes: 73 additions & 8 deletions src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import * as pdfFonts from './vfs_fonts.js';

export default {
id: 'operation-pdf-builder',
handler: async ({filename, folder, storage, template, fonts}, {services, database, accountability, getSchema}) => {
handler: async ({filename, folder, storage, template, fonts, images}, {
services,
database,
accountability,
getSchema
}) => {
const {FilesService, AssetsService} = services;
const schema = await getSchema({database});
const filesService = new FilesService({
Expand All @@ -23,8 +28,7 @@ export default {
pdfMake.vfs = await getBase64Fonts(fonts, assetsService);
pdfMake.fonts = getPdfMakeFonts(fonts);

console.log('VFS:', pdfMake.vfs);
console.log('Fonts:', pdfMake.fonts);
template['images'] = await addImages(images, assetsService, filesService);

const pdfDocGenerator = pdfMake.createPdf(template);

Expand Down Expand Up @@ -92,12 +96,40 @@ async function streamToBuffer(stream) {
}

async function fetchExternalFont(url) {
return await fetch(url, {headers: {responseType: 'arraybuffer'}}).then((response) => {
return Buffer.from(response.data, 'binary').toString('base64');
}).catch((error) => {
try {
const response = await fetch(url);

if (!response.ok) {
console.error(`HTTP error! status: ${response.status}`);
return false;
}

const arrayBuffer = await response.arrayBuffer();
return Buffer.from(arrayBuffer).toString('base64');
} catch (error) {
console.error('Error fetching external font:', error);
return false;
});
}
}

async function fetchExternalImage(url) {
try {
const response = await fetch(url);

if (!response.ok) {
console.error(`HTTP error! status: ${response.status}`);
return false;
}

const contentType = response.headers.get('content-type');
const arrayBuffer = await response.arrayBuffer();
const base64Image = Buffer.from(arrayBuffer).toString('base64');

return `data:${contentType};base64,${base64Image}`;
} catch (error) {
console.error('Error fetching external image:', error);
return false;
}
}

async function fetchInternalFont(uuid, assetsService) {
Expand All @@ -113,6 +145,22 @@ async function fetchInternalFont(uuid, assetsService) {
});
}

async function fetchInternalImage(uuid, assetsService, filesService) {
return assetsService.getAsset(uuid)
.then(async (fileStream) => {
const {stream} = fileStream;
const {type} = await filesService.readOne(uuid);
const buffer = await streamToBuffer(stream);
const base64Image = Buffer.from(buffer).toString('base64');

return `data:${type};base64,${base64Image}`;
})
.catch((error) => {
console.error('Error fetching internal image:', error);
return false;
});
}

async function getBase64Fonts(fonts, assetsService) {
const base64Fonts = [];
// Load the default pdfMake fonts
Expand Down Expand Up @@ -163,8 +211,25 @@ function getPdfMakeFonts(fonts) {
};
}
return fontList;
}catch (e) {
} catch (e) {
console.error(e);
return false;
}
}

async function addImages(images, assetsService, filesService) {
let imageList = {};

if (Array.isArray(images)) {
for (const image of images) {
const {image_name, url} = image;
if (uuidValidate(url)) {
imageList[image_name] = await fetchInternalImage(url, assetsService, filesService);
} else if (url) {
imageList[image_name] = await fetchExternalImage(url, assetsService);
}
}
}

return imageList;
}
74 changes: 69 additions & 5 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ export default {
name: 'PDF Builder Operation',
icon: 'picture_as_pdf',
description: 'Generate a pdf with flow data and the template.',
overview: ({filename}) => [
overview: ({filename, fonts}) => [
{
label: 'Filename',
text: filename,
},
{
label: 'Fonts',
text: getFontList(fonts),
}
],
options: [
Expand Down Expand Up @@ -41,7 +45,7 @@ export default {
},
{
field: 'filename',
name: 'Filename',
name: '$t:fields.directus_files.filename_download',
type: 'string',
meta: {
width: 'full',
Expand All @@ -50,7 +54,7 @@ export default {
},
{
field: 'folder',
name: 'Folder',
name: '$t:folder',
type: 'uuid',
meta: {
width: 'half',
Expand All @@ -59,7 +63,7 @@ export default {
},
{
field: 'storage',
name: 'Storage',
name: '$t:fields.directus_files.storage',
type: 'string',
meta: {
width: 'half',
Expand All @@ -72,7 +76,7 @@ export default {
},
{
field: 'template',
name: 'Template',
name: '$t:template',
type: 'json',
meta: {
width: 'full',
Expand Down Expand Up @@ -145,6 +149,66 @@ export default {
]
}
}
},
{
field: 'images',
name: 'Images',
type: 'json',
meta: {
width: 'full',
interface: 'list',
special: 'cast-json',
options: {
template: '{{ image_name }}',
fields: [
{
field: 'image_name',
name: 'Name',
type: 'string',
meta: {
width: 'full',
interface: 'input',
required: true,
options: {
placeholder: 'image',
iconRight: 'image',
}
}
},
{
field: 'url',
name: 'Url',
type: 'string',
meta: {
width: 'full',
interface: 'input',
required: true,
options: {
placeholder: 'https://example.com/image.jpg',
iconRight: 'link',
}
}
},
]
}
}
}
],
};

function getFontList(fonts) {
if (!Array.isArray(fonts)) {
return '$t:no_items';
} else {
const uniqueFonts = fonts.reduce((acc, current) => {
const font = acc.find(item => item.font_family === current.font_family);
if (!font) {
return acc.concat([current]);
} else {
return acc;
}
}, []);

return uniqueFonts.map(font => `${font.font_family} - ${font.font_type}`).join(uniqueFonts.length > 1 ? ', ' : '');
}
}

0 comments on commit b8056f8

Please sign in to comment.