Am working on an offline application using HTML5 and jquery for mobile. i want to back up files from the local storage using jszip. below is a code snippet of what i have done...
if (localStorageKeys.length > 0) {
for (var i = 0; i < localStorageKeys.length; i++) {
var key = localStorageKeys[i];
if (key.search(_instrumentId) != -1) {
var data = localStorage.getItem(localStorageKeys[i])
var zip = new JSZip();
zip.file(localStorageKeys[i] + ".txt", data);
var datafile = document.getElementById('backupData');
datafile.download = "DataFiles.zip";
datafile.href = window.URL.createObjectURL(zip.generate({ type: "blob" }));
}
else {
}
}
}
in the code above am looping through the localstorage content and saving ezch file in a text format. the challenge that am facing is how to create several text files inside DataFiles.zip as currently am only able to create one text file inside the zipped folder. Am new to javascript so bare with any ambiguity in my question.
thanks in advance.
Just keep calling zip.file().
Look at the example from their documentation page (comments mine):
var zip = new JSZip();
// Add a text file with the contents "Hello World\n"
zip.file("Hello.txt", "Hello World\n");
// Add a another text file with the contents "Goodbye, cruel world\n"
zip.file("Goodbye.txt", "Goodbye, cruel world\n");
// Add a folder named "images"
var img = zip.folder("images");
// Add a file named "smile.gif" to that folder, from some Base64 data
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"base64"}).then(function (content) {
location.href="data:application/zip;base64," + content;
});
The important thing is to understand the code you've written - learn what each line does. If you do this, you'd realize that you just need to call zip.file() again to add another file.
Adding to #Jonathon Reinhart answer,
You could also set both file name and path at the same time
// create a file and a folder
zip.file("nested/hello.txt", "Hello World\n");
// same as
zip.folder("nested").file("hello.txt", "Hello World\n");
If you receive a list of files ( from ui or array or whatever ) you can make a compress before and then archive. The code is something like this:
function upload(files){
var zip = new JSZip();
let archive = zip.folder("test");
files.map(function(file){
files.file(file.name, file.raw, {base64: true});
}.bind(this));
return archive.generateAsync({
type: "blob",
compression: "DEFLATE",
compressionOptions: {
level: 6
}
}).then(function(content){
// send to server or whatever operation
});
}
this worked for me at multiple json files. Maybe it helps.
In case you want to zip files and need a base64 output, you can use the below code-
import * as JSZip from 'jszip'
var zip = new JSZip();
zip.file("Hello.json", this.fileContent);
zip.generateAsync({ type: "base64" }).then(function (content) {
const base64Data = content
Related
I have a large number of PDF files split across multiple folders (in a tree structure) in my Google Drive. I'd like to retain the PDF files while also creating a copy of each PDF document in Google Docs format which has been OCRd. The Google Docs file needs to have the same name as the PDF file.
How do I do this?
As part of this, I tried to at least convert one file into PDF by code but ran into issues there as well.
function pdfToDoc() {
var fileBlob = DriveApp.getFileById('<ID>').getBlob();
var resource = {
title: fileBlob.getName(),
mimeType: fileBlob.getContentType()
};
var options = {
ocr: true
};
var docFile = Drive.Files.insert(resource, fileBlob, options); // <-- Google said "Empty response (line 10, file "Code")"
Logger.log(docFile.alternateLink);
}
I followed this tutorial but made some changes because I'm using v3 of Drive API. Here is the snippet:
var blob = DriveApp.getFileById('FILE_ID').getBlob();
Logger.log(blob)
var text = pdfToText(blob, {ocrLanguage: "en"});
Logger.log(text);
/**
* Convert pdf file (blob) to a text file on Drive, using built-in OCR.
* By default, the text file will be placed in the root folder, with the same
* name as source pdf (but extension 'txt'). Options:
*/
function pdfToText ( pdfFile, options ) {
// Ensure Advanced Drive Service is enabled
try {
Drive.Files.list();
}
catch (e) {
throw new Error( "Enable 'Drive API' in Resources - Advanced Google Services." );
}
// Prepare resource object for file creation
var parents = [];
var pdfName = "Sample Docs";
Logger.log(pdfName)
var resource = {
name: pdfName,
mimeType: MimeType.GOOGLE_DOCS,
parents: parents
};
// Save PDF as GDOC
resource.title = pdfName.replace(/pdf$/, '');
var insertOpts = {
'ocr': true,
'ocrLanguage': 'en'
}
Logger.log(resource.title)
var gdocFile = Drive.Files.create(resource, pdfFile, insertOpts);
// Get text from GDOC
var gdocDoc = DocumentApp.openById(gdocFile.id);
var text = gdocDoc.getBody().getText();
// Save text file, if requested
resource.name = pdfName.replace(/pdf$/, 'txt');
resource.mimeType = MimeType.PLAIN_TEXT;
var textBlob = Utilities.newBlob(text, MimeType.PLAIN_TEXT, resource.name);
var textFile = Drive.Files.create(resource, textBlob);
return text;
}
Initially, DriveApp cannot convert pdf to Google Docs directly so I used Advance Drive Service. Just follow this link on how to enable advanced services.
Hope this helps.
i have an m3u file that i wanna extract information from it. can i read as a text file?
Any idea how to read a text file or m3u deployed in a server in JavaScript or HTML line by line and get information from it ?
I created a basic example using just Javascript, starting with the example that I linked in the comments above. Just read in the text file using FileReader and create a loop in the onload function, where you parse out the records that you want. I based my file spec off of wikipedia, using the Example 6.
Result: https://jsfiddle.net/1sce9mv6/6/
Javascript:
document.getElementById('file').onchange = function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(progressEvent) {
// Entire file for debugging
//console.log(this.result);
// By lines
var lines = this.result.split('\n');
console.log('File read.');
//Check if this is an m3u file
if (lines[0].includes("#EXTM3U")) {
console.log("File header found!");
//Go through each line
for (var line = 1; line < lines.length; line++) {
//Process line
if (lines[line].includes("#EXTINF")) {
//print full line
console.log(lines[line]);
//split each line into the elements
var currentLine = lines[line].substring(7).split(',');
console.log("Runtime: " + currentLine[0]);
console.log("Song:" + currentLine[1]);
} else {
continue;
}
}
} else {
console.log(lines[0]);
console.log("Not m3u file...");
}
};
reader.readAsText(file);
};
HTML:
<input type="file" name="file" id="file">
References:
How to use Javascript to read local text file and read line by line?
https://en.wikipedia.org/wiki/M3U#Examples
I would recommend using jQuery for this.
If you're trying to read the file line by line then use:
<script>
$.get("item.txt", function(data) {
});
</script>
Where the argument data is the resultant file information. Even if you are just trying to get the data byte by byte this would work fine. I am not super familiar with .m3u files, but this advice should help.
In our meteor app, the client will upload some files using collectionFS-filesystem which i store it to an uploads folders in root directory of my app.
//My CFS uploads collection
uploads = new FS.Collection("uploads", {
stores: [new FS.Store.FileSystem("uploads", {path: "~/uploads"})]
});
Later, i want to save the files to the database using collectionFS-gridFS.
//My CFS grid collection
files = new FS.Collection("files", {
stores: [new FS.Store.GridFS("files")]
});
How do i read the data from the file on server so that i can store the file to db? Can i use the file from the CFS-filesystem collection to convert it to CFS-gridFS file in anyway?
Thanks in advance.
I had accept the answer by #perusopersonale. However, below is my approach which i used to achieve this, based on documentation from here and here
uploads.find(document_id).forEach(function (fileObj) {
var type = fileObj.type();
var name = fileObj.name();
var readStream = fileObj.createReadStream(fileObj.collectionName);
var newFile = new FS.File();
newFile.attachData(readStream, {type: type});
newFile.name(name);
files.insert(newFile);
});
I don't understand why you want to use both. However I have to implement something similar (read from a cfs filesystem, do something and then reinsert in another db), here a version modified that should accomplish what you are triyng to do:
var fileObj = uploads.findOne(objId);
var newName = "newfilename"; //file name
//fileObj.copies.uploads.key contains the filename for store :"uploads"
fs.readFile( "~/uploads/"+fileObj.copies.uploads.key, function (err, data) {
var newFile = new FS.File();
newFile.attachData(data,{type: 'application/octet-stream'}, function(error){
newFile.name( newName);
file.insert(newFile);
});
});
I'm trying to insert an image into a pdf I'm creating server-side with PDFkit. I'm using cfs:dropbox to store my files. Before when I was using cvs:filesystem, it was easy to add the images to my pdf's cause they were right there. Now that they're stored remotely, I'm not sure how to add them, since PDFkit does not support adding images with just the url. It will, however, accept a buffer. How can I get a buffer from my CollectionFS files?
So far I have something like this:
var portrait = Portraits.findOne('vS2yFy4gxXdjTtz5d');
readStream = portrait.createReadStream('portraits');
I tried getting the buffer two ways so far:
First using dataMan, but the last command never comes back:
var dataMan = new DataMan.ReadStream(readStream, portrait.type());
var buffer = Meteor.wrapAsync(Function.prototype.bind(dataMan.getBuffer, dataMan))();
Second buffering the stream manually:
var buffer = new Buffer(0);
readStream.on('readable', function() {
buffer = Buffer.concat([buffer, readStream.read()]);
});
readStream.on('end', function() {
console.log(buffer.toString('base64'));
});
That never seems to come back either. I double-checked my doc to make sure it was there and it has a valid url and the image appears when I put the url in my browser. Am I missing something?
I had to do something similar and since there's no answer to this question, here is how I do it:
// take a cfs file and return a base64 string
var getBase64Data = function(file, callback) {
// callback has the form function (err, res) {}
var readStream = file.createReadStream();
var buffer = [];
readStream.on('data', function(chunk) {
buffer.push(chunk);
});
readStream.on('error', function(err) {
callback(err, null);
});
readStream.on('end', function() {
callback(null, buffer.concat()[0].toString('base64'));
});
};
// wrap it to make it sync
var getBase64DataSync = Meteor.wrapAsync(getBase64Data);
// get a cfs file
var file = Files.findOne();
// get the base64 string
var base64str = getBase64DataSync(file);
// get the buffer from the string
var buffer = new Buffer(base64str, 'base64')
Hope it'll help!
I have the following JS function which serves as a first prototype for a mozilla thunderbird extension.
The goal is to connect to a server and download a sample file, then unzipping it and storing the contents in the thunderbird profile folder.
Now this all works fine, except that the execution of the function stops after creating the zip file on the file system. So i have to restart the function again, in order to get the second part of the function executed which extracts the user.js file from the zip file.
Any ideas what the problem could be?
function downloadFile(httpLoc) {
// get profile directory
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
var profilePath = file.path;
// change profile directory to native style
profilePath = profilePath.replace(/\\/gi , "\\\\");
profilePath = profilePath.toLowerCase();
// download the zip file
try {
//new obj_URI object
var obj_URI = Components.classes["#mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI(httpLoc, null, null);
//new file object
var obj_TargetFile = Components.classes["#mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
//set to download the zip file into the profil direct
obj_TargetFile.initWithPath(profilePath + "\/" + "test.zip");
//if file the zip file doesn't exist, create it
if(!obj_TargetFile.exists()) {
alert("zip file wird erstellt");
obj_TargetFile.create(0x00,0644);
}
//new persitence object
var obj_Persist = Components.classes["#mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Components.interfaces.nsIWebBrowserPersist);
// with persist flags if desired ??
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
obj_Persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
//save file to target
obj_Persist.saveURI(obj_URI,null,null,null,null,obj_TargetFile);
} catch (e) {
alert(e);
} finally {
// unzip the user.js file to the profile direc
// creat a zipReader, open the zip file
var zipReader = Components.classes["#mozilla.org/libjar/zip-reader;1"]
.createInstance(Components.interfaces.nsIZipReader);
zipReader.open(obj_TargetFile);
//new file object, thats where the user.js will be extracted
var obj_UnzipTarget = Components.classes["#mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
//set path for the user.js
obj_UnzipTarget.initWithPath(profilePath + "\/" + "user.js");
// if user.js doesn't exist, create it
if(!obj_UnzipTarget.exists()) {
alert("user.js wird erstellt");
obj_UnzipTarget.create(0x00,0644);
}
// extract the user.js out of the zip file, to the specified path
zipReader.extract("user.js", obj_UnzipTarget);
zipReader.close();
}
}
var hello = {
click: function() {
downloadFile("http://pse2.iam.unibe.ch/profiles/profile.zip");
},
};
saveURI is asynchronous, so you need to set the progress listener on the persist object to know when it has finished. Here's an example of setting a progress listener and later on there's a check to see whether the transfer has finished.