I'm trying to fetch the contents of page 4 of a PDF file using 'pdfjs-dist'.
I've tried to replace the 'pdfjs-dist' module with 'const pdfjs = require("pdfjs/es5/build/pdf")' but with no success.
What could be problem?
Thanks in advance!
const pdfjs = require('pdfjs-dist'); // Fetch PDF
async function getContent(src) {
const doc = await pdfjs.getDocument(src).promise // note the use of the property promise
const page = await doc.getPage(4)
return await page.getTextContent()
}
console.log(getContent('pdfs/Quantum.pdf'))
It's too late to reply to this questions but let me add the solution that worked for me for those who will wish to implement the some issue.
This is the code that will work fine
// Install the latest version of pdf.js via npm i pdfjs-dist
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
let pdf_path = "{RELATIVE_PATH_TO_YOUR_FILE}/sample.pdf";
async function getContent(src: any){
const doc = await pdfjsLib.getDocument(src).promise;
const page = await doc.getPage(1);
const strings: any = await page.getTextContent();
let ITEMS_STRINGS = strings.items.map((item: any) => item.str);
let PDF_STRINGS: string = ITEMS_STRINGS.join(" ");
return PDF_STRINGS;
}
console.log(await getContent(`${pdf_path}`));
This will work fine
Related
const unzipper = require("unzipper");
const fs = require("fs-extra");
async function test() {
const file = "old.zip";
const password = "abc";
const directory = await unzipper.Open.file(file);
console.log("password", password);
const extracted = await directory.files[0].buffer(password);
fs.writeFileSync("extracted/", extracted);
}
test();
I have two files, old.zip and new.zip. The only difference is that when I created old zip using winrar, I checked legacy encryption. You can see the picture below.
My code works for old zip, but not new.zip. Is there any other way to extract the new.zip file?
edit: change title from using javascript => in Node js
I'm using the azure file storage, and using express JS to write a backend to render the contents stored in the azure file storage.
I am writing the code based on https://learn.microsoft.com/en-us/javascript/api/#azure/storage-file-share/shareserviceclient?view=azure-node-latest
const { ShareServiceClient, StorageSharedKeyCredential } = require("#azure/storage-file-share");
const account = "<account>";
const accountKey = "<accountkey>";
const credential = new StorageSharedKeyCredential(account, accountKey);
const serviceClient = new ShareServiceClient(
`https://${account}.file.core.windows.net`,
credential
);
const shareName = "<share name>";
const fileName = "<file name>";
// [Node.js only] A helper method used to read a Node.js readable stream into a Buffer
async function streamToBuffer(readableStream) {
return new Promise((resolve, reject) => {
const chunks = [];
readableStream.on("data", (data) => {
chunks.push(data instanceof Buffer ? data : Buffer.from(data));
});
readableStream.on("end", () => {
resolve(Buffer.concat(chunks));
});
readableStream.on("error", reject);
});
}
And you can view the contents through
const downloadFileResponse = await fileClient.download();
const output = await streamToBuffer(downloadFileResponse.readableStreamBody)).toString()
Thing is, I only want to find if the file exists and not spend time downloading the entire file, how could I do this?
I looked at https://learn.microsoft.com/en-us/javascript/api/#azure/storage-file-share/shareserviceclient?view=azure-node-latest
to see if the file client class has what I want, but it doesn't seem to have methods useful for this.
If you are using #azure/storage-file-share (version 12.x) Node package, there's an exists method in ShareFileClient. You can use that to find if a file exists or not. Something like:
const fileExists = await fileClient.exists();//returns true or false.
i try to activate Revit Levels and 2D Minimap extension in autodesk forge viewer, but can not get AEC Model Data. I got this worning`
i tried to get AEC data with this code
const url = window.location.search;
console.log(url);
const svf_path = `${url.replace("?", "/storage/").replace(/%20/g, " ")}`;
Autodesk.Viewing.endpoint.getItemApi = (endpoint, derivativeUrn, api) => {
return svf_path;
};
Autodesk.Viewing.Initializer(options, async () => {
const paths = svf_path.split("/");
const [dest, svf_dir] = [paths[2], paths[3]];
const url = `/api/viewer/dest/${dest}/svf/${svf_dir}/manifest`;
const response = await fetch(url);
const manifest = await response.json();
const init_div = document.getElementById("init_div");
viewer = new Autodesk.Viewing.GuiViewer3D(init_div, config3d);
const viewerDocument = new Autodesk.Viewing.Document(manifest);
const viewable = viewerDocument.getRoot().getDefaultGeometry();
viewer.start();
await viewerDocument.downloadAecModelData();
viewer.loadDocumentNode(viewerDocument, viewable)
.then(function (result) {
Autodesk.Viewing.Document.getAecModelData(viewable);
})
});
wats wrong in my code?
The warning comes from the BubbleNode.prototype.getAecModelData method. You are not calling it in your code but it's possible that it's being called by the LevelsExtension itself. Try configuring the extension so that it doesn't detect the AEC data automatically by passing in { autoDetectAecModelData: false } as the extension options.
Btw. to debug the issue on your side, you can also try getting the non-minified version of viewer3D.js, put a breakpoint to where the warning is being logged, and see the call stack when the breakpoint is hit.
I'm trying to do this with just pure Javascript and the SDK. I am not using Node.js. I'm converting my application from v2 to v10 of the SDK azure-storage-js-v10
The azure-storage.blob.js bundled file is compatible with UMD
standard, if no module system is found, following global variable
will be exported: azblob
My code is here:
const serviceURL = new azblob.ServiceURL(`https://${account}.blob.core.windows.net${accountSas}`, pipeline);
const containerName = "container";
const containerURL = azblob.ContainerURL.fromServiceURL(serviceURL, containerName);
const blobURL = azblob.BlobURL.fromContainerURL(containerURL, blobName);
const downloadBlobResponse = await blobURL.download(azblob.Aborter.none, 0);
The downloadBlobResponse looks like this:
downloadBlobResponse
Using v10, how can I convert the downloadBlobResponse into a new blob so it can be used in the FileSaver saveAs() function?
In azure-storage-js-v2 this code worked on smaller files:
let readStream = blobService.createReadStream(containerName, blobName, (err, res) => {
if (error) {
// Handle read blob error
}
});
// Use event listener to receive data
readStream.on('data', data => {
// Uint8Array retrieved
// Convert the array back into a blob
var newBlob = new Blob([new Uint8Array(data)]);
// Saves file to the user's downloads directory
saveAs(newBlob, blobName); // FileSaver.js
});
I've tried everything to get v10 working, any help would be greatly appreciated.
Thanks,
You need to get the body by await blobBody.
downloadBlobResponse = await blobURL.download(azblob.Aborter.none, 0);
// data is a browser Blob type
const data = await downloadBlobResponse.blobBody;
Thanx Mike Coop and Xiaoning Liu!
I was busy making a Vuejs plugin to download blobs from a storage account. Thanx to you, I was able to make this work.
var FileSaver = require('file-saver');
const { BlobServiceClient } = require("#azure/storage-blob");
const downloadButton = document.getElementById("download-button");
const downloadFiles = async() => {
try {
if (fileList.selectedOptions.length > 0) {
reportStatus("Downloading files...");
for await (const option of fileList.selectedOptions) {
var blobName = option.text;
const account = '<account name>';
const sas = '<blob sas token>';
const containerName = '< container name>';
const blobServiceClient = new BlobServiceClient(`https://${account}.blob.core.windows.net${sas}`);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobClient = containerClient.getBlobClient(blobName);
const downloadBlockBlobResponse = await blobClient.download(blobName, 0, undefined);
const data = await downloadBlockBlobResponse.blobBody;
// Saves file to the user's downloads directory
FileSaver.saveAs(data, blobName); // FileSaver.js
}
reportStatus("Done.");
listFiles();
} else {
reportStatus("No files selected.");
}
} catch (error) {
reportStatus(error.message);
}
};
downloadButton.addEventListener("click", downloadFiles);
Thanks Xiaoning Liu!
I'm still learning about async javascript functions and promises. Guess I was just missing another "await". I saw that "downloadBlobResponse.blobBody" was a promise and also a blob type, but, I couldn't figure out why it wouldn't convert to a new blob. I kept getting the "Iterator getter is not callable" error.
Here's my final working solution:
// Create a BlobURL
const blobURL = azblob.BlobURL.fromContainerURL(containerURL, blobName);
// Download blob
downloadBlobResponse = await blobURL.download(azblob.Aborter.none, 0);
// In browsers, get downloaded data by accessing downloadBlockBlobResponse.blobBody
const data = await downloadBlobResponse.blobBody;
// Saves file to the user's downloads directory
saveAs(data, blobName); // FileSaver.js
I am trying to read the Chrome console using Selenium Webdriver in node.js, but so far it is unsuccessful. There are no errors. But all it returns is an empty array [].
The following is a snippet of the HTML and JavaScript function. When run manually in Chrome, these write to the console just fine.
<button name="button1" type="button" onclick="test_console()">Test</button>
function test_console() {
console.log("Hello World");
}
The following is the code I am using in node.js to try to get the output to Chrome.
const webdriver = require('selenium-webdriver');
const chromeDriver = require('selenium-webdriver/chrome');
const logging = require('selenium-webdriver').logging;
const path = require('chromeDriver').path;
const service = new chromeDriver.ServiceBuilder(path).build();
chromeDriver.setDefaultService(service);
const {By, Key} = webdriver;
webdriver.promise.USE_PROMISE_MANAGER = false;
const CHROME_BIN_PATH = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
const prefs = new logging.Preferences();
prefs.setLevel(logging.Type.BROWSER, logging.Level.ALL);
const options = new chromeDriver.Options();
options.setChromeBinaryPath(CHROME_BIN_PATH);
options.addArguments(
'headless',
'disable-gpu',
'verbose',
'disable-impl-side-painting',
);
const main = async () => {
try {
const driver = await new webdriver.Builder()
.withCapabilities(webdriver.Capabilities.chrome())
.setLoggingPrefs(prefs)
.forBrowser('chrome')
.setChromeOptions(options)
.build();
await driver.get('http://example.com/example.html');
//clicking this button manually in Chrome writes to the console
await driver.findElement(By.name('button1')).click();
await driver.manage().logs().get(logging.Type.BROWSER)
.then(function(entries) {
console.log(entries);
});
await driver.close();
await driver.quit();
} catch (error) {
await driver.close();
await driver.quit();
console.log(error);
}
};
main();
I'm sure the issue is simple, probably a configuration problem. I just cant figure out what the problem might be. I even resorted to reading the webdriver source code in Git to see if I could see anything, but to no avail.
As far as I can tell, getting the contents of the console from Chrome using webdriver is a no go.
I ended up solving the issue in this manner:
//append a div to the body of the page
await driver.executeScript("var div = document.createElement('div'); div.id = 'console_log'; document.body.appendChild(div);");
//override console.log to write the log message to the new div
await driver.executeScript("console.log = function(message){document.getElementById('console_log').innerHTML += message}");
//get the contents of the new div
const console_log = await driver.findElement(By.id('console_log'));
console.log(await console_log.getAttribute('innerHTML'));