Skip to content

Commit

Permalink
pdf/docx/screenshot wiring
Browse files Browse the repository at this point in the history
  • Loading branch information
btopro committed Jun 20, 2022
1 parent fe2d1b4 commit 6cb1dea
Show file tree
Hide file tree
Showing 10 changed files with 473 additions and 100 deletions.
22 changes: 0 additions & 22 deletions api/services/media/format/docxToHtml.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { stdResponse } from "../../../utilities/requestHelpers.js";
import { getBrowserInstance } from '../../../utilities/getBrowserInstance.js';

import df from 'mammoth';
const { convertToHtml } = df;
Expand Down Expand Up @@ -31,26 +30,6 @@ export default async function handler(req, res) {
.then((result) => {
return result.value; // The generated HTML
});
// generate a screenshot of the HTML blob
// capture options
var screenshotOptions = {
quality: 75,
type: 'jpeg',
encoding: "base64"
};
let browser = null
try {
browser = await getBrowserInstance();
let page = await browser.newPage();
await page.setContent(html)
img = await page.screenshot(screenshotOptions)
} catch (error) {
console.log(error)
} finally {
if (browser !== null) {
await browser.close()
}
}
}
catch(e) {
// put in the output
Expand All @@ -61,7 +40,6 @@ export default async function handler(req, res) {
{
contents: html,
filename: buffer.filename,
image: img
},
{
methods: "GET,OPTIONS,PATCH,DELETE,POST,PUT"
Expand Down
58 changes: 0 additions & 58 deletions api/services/website/screenshot.js

This file was deleted.

61 changes: 61 additions & 0 deletions api/services/website/screenshotUrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { getBrowserInstance } from '../../utilities/getBrowserInstance.js';
import { stdResponse, invalidRequest, stdPostBody } from "../../utilities/requestHelpers.js";

export default async function handler(req, res) {
const body = stdPostBody(req);
const urlToCapture = body.urlToCapture;
// Perform URL validation
if (!urlToCapture || !urlToCapture.trim()) {
res = invalidRequest(res, 'enter a valid url');
}
else {
if (!urlToCapture.includes("https://")) {
// try to fake it
urlToCapture = `https://${urlToCapture}`;
}

// capture options
var browserGoToOptions = {
timeout: 10000,
waitUntil: 'networkidle2',
};
var screenshotOptions = {
quality: body.quality ? parseInt(body.quality) : 75,
type: 'jpeg',
encoding: "base64"
};
var base64 = '';
let browser = null
try {
browser = await getBrowserInstance();
let page = await browser.newPage();
await page.goto(urlToCapture, browserGoToOptions);
// special support for isolating a tweet
if (urlToCapture.includes('twitter.com')) {
await page.waitForSelector("article[data-testid='tweet']");
const element = await page.$("article[data-testid='tweet']");
base64 = await element.screenshot(screenshotOptions);
}
else {
screenshotOptions.fullPage = true;
base64 = await page.screenshot(screenshotOptions);
}
res = stdResponse(res,
{
url: urlToCapture,
image: base64
}, {
methods: "GET,OPTIONS,PATCH,DELETE,POST,PUT",
cache: 1800
}
);
} catch (error) {
console.log(error)
res = invalidRequest(res, 'something went wrong', 500);
} finally {
if (browser !== null) {
await browser.close()
}
}
}
}
131 changes: 131 additions & 0 deletions elements/micro-frontend-registry/demo/docx-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { LitElement, css, html } from "lit";
import { MicroFrontendRegistry } from "../micro-frontend-registry.js";
import { enableServices } from '../lib/microServices.js';

export class DocxExample extends LitElement {
static get tag() {
return "docx-example";
}
static get styles() {
return [
css`
:host {
display: block;
}
textarea {
display: block;
}
#asciihere {
background-color: black;
font-family: monospace;
white-space: pre;
}
`,
];
}
constructor() {
super();
// enable these services
enableServices(['core']);
}

// ascii to image
asciiImgRender() {
return html`
<label>Upload image file to get ASCII art</label>
<input type="file" id="ascii" @change="${this.asciiImgUpload}" />
<textarea id="asciiresponse" rows="10" cols="50"></textarea>
<h1>Ascii that was in the file upload</h1>
<pre id="asciihere"></pre>
`;
}

asciiImgUpload(event) {
const files = event.target.files;
const formData = new FormData();
formData.append('upload', files[0]);
MicroFrontendRegistry.call('@core/imgToAscii', formData, this.toAsciiResponse.bind(this));
}

toAsciiResponse(data) {
this.shadowRoot.querySelector("#asciihere").innerHTML = data.data.image;
this.shadowRoot.querySelector("#asciiresponse").value = JSON.stringify(data);
}

// docx to html
docxToHtmlRender() {
return html`
<label>Upload Docx file to get HTML</label>
<input type="file" id="upload" @change="${this.docxToHtmlUpload}" />
<textarea id="response" rows="10" cols="50"></textarea>
<h1>HTML that was in the file upload</h1>
<div id="here"></div>
`;
}

docxToHtmlUpload(event) {
const files = event.target.files;
const formData = new FormData();
formData.append('upload', files[0]);
MicroFrontendRegistry.call('@core/docxToHtml', formData, this.docxToHtmlResponse.bind(this));
}

docxToHtmlResponse(data) {
console.log(data);
this.shadowRoot.querySelector("#here").innerHTML = data.data.contents;
}

// docx to pdf file
docxToPdfRender() {
return html`
<label>Docx file to get PDF</label>
<input type="file" id="uploadpdf" @change="${this.docxToPdfUpload.bind(this)}" />
<h1>PDF file</h1>
<iframe id="pdfframe" width="100%" height="500px"></iframe>
`;
}

docxToPdfUpload(event) {
const files = event.target.files;
const formData = new FormData();
formData.append('upload', files[0]);
MicroFrontendRegistry.call('@core/docxToPdf', formData, this.docxToPdfResponse.bind(this));
}

docxToPdfResponse(data) {
console.log(data);
this.shadowRoot.querySelector("#pdfframe").src = `data:application/pdf;base64,${data.data.pdf}`;
this.shadowRoot.querySelector("#response").value = JSON.stringify(data);
}

screenshotUrlRender() {
return html`
<label>Enter a URL to get a screenshot of it</label>
<input type="text" id="screenshot" />
<button id="getthething" @click="${this.screenshotUrlLink}">Get a screenshot</button>
<h1>Image will appear here</h1>
<img id="replaceimg" src="" alt="" />
`;
}

screenshotUrlLink(event) {
const urlToCapture = this.shadowRoot.querySelector('#screenshot').value;
MicroFrontendRegistry.call('@core/screenshotUrl', {urlToCapture: urlToCapture, quality: 80 }, this.screenshotUrlResponse.bind(this));
}

screenshotUrlResponse(data) {
this.shadowRoot.querySelector("#replaceimg").src = `data:image/jpeg;base64, ${data.data.image}`;
this.shadowRoot.querySelector("#replaceimg").alt = `screenshot of ${data.data.url}`;
}

render() {
return html`
${this.asciiImgRender()}
${this.docxToHtmlRender()}
${this.docxToPdfRender()}
${this.screenshotUrlRender()}
`;
}
}

customElements.define(DocxExample.tag, DocxExample);
12 changes: 12 additions & 0 deletions elements/micro-frontend-registry/lib/microServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ export function enableCoreServices() {
}
);

// screenshot
MicroFrontendRegistry.add({
endpoint: "/api/services/website/screenshotUrl",
name: "@core/screenshotUrl",
title: "Screenshot page",
description: "Takes screenshot of a URL and returns image",
params: {
urlToCapture: "full url with https",
quality: "Optional image quality parameter"
}
});

// docxToPdf
MicroFrontendRegistry.add({
endpoint: "/api/services/media/format/docxToPdf",
Expand Down
3 changes: 2 additions & 1 deletion elements/micro-frontend-registry/micro-frontend-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,10 @@ class MicroFrontendRegistryEl extends HTMLElement {
async call(name, params = {}, callback = null, caller = null) {
const item = this.get(name);
if (item) {
// support for formdata which is already encoded
const data = await fetch(item.endpoint, {
method: "POST",
body: JSON.stringify(params),
body: params instanceof FormData ? params : JSON.stringify(params),
}).then((d) => (d.ok ? d.json() : null));
// endpoints can require a callback be hit every time
if (item.callback) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
import { StorybookUtilities } from "@lrnwebcomponents/storybook-utilities/storybook-utilities.js";
import "./micro-frontend-registry.js";
import "./demo/mf-htmlmd-example.js";
import "./demo/docx-example.js";
// need to account for polymer goofiness when webpack rolls this up

export default {
Expand Down Expand Up @@ -51,6 +52,11 @@ export const example = () => {
<mf-htmlmd-example></mf-htmlmd-example>
`);
};

export const docxAndScreenshot = () => {
return getRenderString(html`<docx-example></docx-example>`);
};

// via https://stackoverflow.com/questions/70657298/render-lit-lit-html-templateresult-as-string
const getRenderString = (data) => {
const { strings, values } = data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,10 @@ class MicroFrontendRegistryEl extends HTMLElement {
async call(name, params = {}, callback = null, caller = null) {
const item = this.get(name);
if (item) {
// support for formdata which is already encoded
const data = await fetch(item.endpoint, {
method: "POST",
body: JSON.stringify(params),
body: params instanceof FormData ? params : JSON.stringify(params),
}).then((d) => (d.ok ? d.json() : null));
// endpoints can require a callback be hit every time
if (item.callback) {
Expand Down
10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@
"rebuild-wcfcache": "./node_modules/.bin/gulp",
"new": "yarn run rebuild-wcfcache && wcf element && yarn run test-suite-inject && yarn install --link-duplicates"
},
"peerDependencies": {
"@web/test-runner": "0.13.27",
"@web/test-runner-commands": "0.6.1",
"@web/test-runner-playwright": "0.8.8",
"puppeteer": "13.5.2"
},
"dependencies": {
"fetch-ie8": "1.5.0",
"lunr": "2.3.9",
Expand All @@ -74,6 +68,10 @@
"html-pdf": "3.0.1"
},
"devDependencies": {
"@web/test-runner": "0.13.27",
"@web/test-runner-commands": "0.6.1",
"@web/test-runner-playwright": "0.8.8",
"puppeteer": "13.5.2",
"patch-package": "6.4.7",
"validate-element-name": "3.0.0",
"@babel/core": "^7.9.0",
Expand Down

1 comment on commit 6cb1dea

@vercel
Copy link

@vercel vercel bot commented on 6cb1dea Jun 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lrnwebcomponents – ./

lrnwebcomponents-elmsln.vercel.app
lrnwebcomponents.vercel.app
lrnwebcomponents-git-master-elmsln.vercel.app

Please sign in to comment.