Zipping and Unzipping files in Adobe Air/Javascript - javascript

I'm not particularly using Flex but I am using javascript and html and css in a adobe air application. I would like to be able to unzip and zip files. I've looked at a few libraries but none worked as I needed it to. I read somewhere that I could use Fzip library but I need to do this in javascript most preferably but the files are actionscript files. Any advice? Thanks.

You can use almost any actionscript library with html/javascript air app. Example:
Download swc file for airxzip: http://code.google.com/p/airxzip/downloads/list
Rename swc to zip and unzip it
Rename included library.swf to coltware_airxzip.swf
Include the library on your page like this:
<script src="coltware_airxzip.swf" type="application/x-shockwave-flash"></script>
This reads a zip file and writes contents to output folder on the desktop (given you have included jQuery and the AIRAliases.js file from the SDK):
var input = new air.File();
input.addEventListener(air.Event.SELECT, function(event) {
var outputDirectory = air.File.desktopDirectory.resolvePath('output');
var reader = new window.runtime.com.coltware.airxzip.ZipFileReader();
reader.open(event.currentTarget);
$.each(reader.getEntries(), function(i, entry) {
if (!entry.isDirectory()) {
var stream = new air.FileStream();
stream.open(outputDirectory.resolvePath(entry.getFilename()), air.FileMode.WRITE);
stream.writeBytes(reader.unzip(entry));
stream.close();
}
});
});
input.browseForOpen('Select a zip file...', [new air.FileFilter('Zip files', '*.zip')]);

I wrote a sample app for Adobe Air + FZip using javascript.
Figured I'd share that here in case anyone else arrives here via Google.
Can never have too many working examples right?
Example -> http://www.drybydesign.com/?p=233

Related

How to get custom ttf font working with jsPDF.output()

I've added the jsPDF library to my Titanium project to generate PDFs client side, which has been working great. But now I want to localize the app for Arabic countries, which means that I have the add a custom font. This works perfectly if you use doc.save('file.pdf'), but it doesn't seem to work correctly for doc.output(). I have to use output because I'm using jsPDF outside of a browser.
To make the library work in Titanium I've had to strip all of the references to window, because it's not running in a browser or webview.
I've tried writing the file from different sources, but nothing seems to yield any results.
My current implementation:
doc = new jsPDF();
var f = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'fonts/markazi-text.regular.ttf');
var contents = f.read();
var base64font = Ti.Utils.base64encode(contents).toString();
doc.addFileToVFS("MarkaziText-Regular", base64font);
doc.addFont('MarkaziText-Regular', 'markazi-text', 'normal');
doc.setFontSize(20);
doc.setFont('markazi-text', 'normal');
doc.text('The quick brown fox jumps over the lazy dog', 20, 20);
var tempFile = Ti.Filesystem.getFile(Ti.Filesystem.getTempDirectory(), 'report.pdf');
if (tempFile.exists()) {
tempFile.deleteFile();
}
tempFile.write(doc.output());
I've also tried to write the file from a blob:
var reader = new FileReader();
reader.onloadend = function () {
tempFile.write(reader.result);
};
reader.readAsText(getBlob(buildDocument()));
But the pdf is empty if I use this. I've also tried the library in a webview within a titanium application, which does work but I don't really want to go that road. It would require too many changes to the code.
Expected:
Actual:
I've finally resolved it by creating a local HTML file. In this HTML file I've loaded jsPDF and my own JavaScript to generate a PDF file. I've loaded this HTML file in a WebView.
I'm generating all the data needed for the PDF in an Alloy controller. I'm sending this data to my WebView JavaScript by firing an app event and catching it in the WebView.
After the PDF is created I trigger an app event in the WebView that contains the base64 data of the jsPDF doc:
Ti.App.fireEvent('app:pdfdone', {
output: doc.output('dataurlstring').replace("data:application/pdf;filename=generated.pdf;base64,", "")
});
I finally save this as a file in the Alloy controller:
var f = Ti.Filesystem.getFile(Ti.Filesystem.getTempDirectory(), 'doc.pdf');
f.write(Ti.Utils.base64decode(e.output));

Programmatically download and insert README.md with photos into HTML

I have a personal website written in AngularJS and NodeJS, and in the tech projects section I would like to embed README.md from a project on GitHub my account (the same way github.com) does it. I don't think iframe<> works for md files. So I have tried converting to HTML and PDF.
The second part of the README.md I want looks like this:
In particular, I would like to import the README.md files into my HTML. I have found two ways to do it:
Download the file, and convert to HTML.
var md_to_html = function(src, dest) {
// Get the markdown
var md = fs.readFileSync(src, "utf8");
var converter = new Remarkable();
var html = converter.render(md);
fs.writeFile(dest, html, function(err) {
if (err) {
return console.log(err);
}
console.log(dest + " was saved!");
});
}
Or Download the file, and convert to PDF.
var md_to_pdf = function(src, dest) {
fs.createReadStream(src)
.pipe(markdownpdf())
.pipe(fs.createWriteStream(dest));
}
Both work, however the photo disappears. That is because the dependencies let's say doc/img/photo.jpg does not get downloaded with the README. I have also written scripts to download the dependencies. But neither insert the photo into the README.pdf or README.html.
Has anyone done something like this? Embedded markdown in HTML with photos, or converted them to PDF or HTML with photos? If I could just import it kind of like a PDF with iframe<> that would be ideal, but if not, I will program it myself. But how?

Reading a text file then setting as variables to use for authentication in Javascript [duplicate]

At the moment, due to the security policy Chromium can not read local files via ajax without --allow-file-access-from-files. But I currently need to create a web application where the database is a xml-file (in the extreme case, json), located in one dir with index.html. It is understood that the user can run this application locally. Are there workarounds for reading xml- (json-) file, without wrapping it in a function and change to js extension?
loadXMLFile('./file.xml').then(xml => {
// working with xml
});
function loadXMLFile(filename) {
return new Promise(function(resolve, reject) {
if('ActiveXObject' in window) {
// If is IE
var xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
xmlDoc.async = false;
xmlDoc.load(filename);
resolve(xmlDoc.xml);
} else {
/*
* how to read xml file if is not IE?
* ...
* resolve(something);
*/
}
}
}
Accessing file: protocol at chromium using XMLHttpRequest() or <link> element without --allow-file-access-from-files flag set at chromium instance launch is not enabled by default.
--allow-file-access-from-files
By default, file:// URIs cannot read other file:// URIs. This is an
override for developers who need the old behavior for testing.
At the moment, due to the security policy Chromium can not read local
files via ajax without --allow-file-access-from-files. But I
currently need to create a web application where the database is a
xml-file (in the extreme case, json), located in one dir with
index.html. It is understood that the user can run this application
locally. Are there workarounds for reading xml- (json-) file, without
wrapping it in a function and change to js extension?
If user is aware that local files are to be used by the application you can utilize <input type="file"> element for user to upload file from user local filesystem, process file using FileReader, then proceed with application.
Else, advise user that use of application requires launching chromium with --allow-file-access-from-files flag set, which can be done by creating a launcher for this purpose, specifying a different user data directory for the instance of chromium. The launcher could be, for example
/usr/bin/chromium-browser --user-data-dir="/home/user/.config/chromium-temp" --allow-file-access-from-files
See also How do I make the Google Chrome flag “--allow-file-access-from-files” permanent?
The above command could also be run at terminal
$ /usr/bin/chromium-browser --user-data-dir="/home/user/.config/chromium-temp" --allow-file-access-from-files
without creating a desktop launcher; where when the instance of chromium is closed run
$ rm -rf /home/user/.config/chromium-temp
to remove the configuration folder for the instance of chromium.
Once the flag is set, user can include <link> element with rel="import" attribute and href pointing to local file and type set to "application/xml", for option other than XMLHttpRequest to get file. Access XML document using
const doc = document.querySelector("link[rel=import]").import;
See Is there a way to know if a link/script is still pending or has it failed.
Another alternative, though more involved, would be to use requestFileSystem to to store the file at LocalFileSystem.
See
How to use webkitRequestFileSystem at file: protocol
jQuery File Upload Plugin: Is possible to preserve the structure of uploaded folders?
How to Write in file (user directory) using JavaScript?
Or create or modify a chrome app and use
chrome.fileSystem
See GoogleChrome/chrome-app-samples/filesystem-access.
The simplest approach would be to provide a means for file upload by affirmative user action; process the uploaded file, then proceed with the application.
const reader = new FileReader;
const parser = new DOMParser;
const startApp = function startApp(xml) {
return Promise.resolve(xml || doc)
};
const fileUpload = document.getElementById("fileupload");
const label = document.querySelector("label[for=fileupload]");
const handleAppStart = function handleStartApp(xml) {
console.log("xml document:", xml);
label.innerHTML = currentFileName + " successfully uploaded";
// do app stuff
}
const handleError = function handleError(err) {
console.error(err)
}
let doc;
let currentFileName;
reader.addEventListener("loadend", handleFileRead);
reader.addEventListener("error", handleError);
function handleFileRead(event) {
label.innerHTML = "";
currentFileName = "";
try {
doc = parser.parseFromString(reader.result, "application/xml");
fileUpload.value = "";
startApp(doc)
.then(function(data) {
handleAppStart(data)
})
.catch(handleError);
} catch (e) {
handleError(e);
}
}
function handleFileUpload(event) {
let file = fileUpload.files[0];
if (/xml/.test(file.type)) {
reader.readAsText(file);
currentFileName = file.name;
}
}
fileUpload.addEventListener("change", handleFileUpload)
<input type="file" name="fileupload" id="fileupload" accept=".xml" />
<label for="fileupload"></label>
use document.implementation.createDocument("", "", null)
instead of new ActiveXObject('Microsoft.XMLDOM').
You can find the API through GOOGLE. Good luck.
If I understand correctly, the deliverable is intended to run locally so you will not be able to set any flags for local file access on a user's machine. Something I've done in a pinch is to pack it up as an executable with something like nw.js and keep the external data files. Otherwise, you're probably looking at loading as script using a JSON schema in a JS file.
I had a similar problem before. I solved by simply embedding the XML file into the HTML using PHP. Since the application is loaded locally from disk, size, cache etc. are not a concern.
If you're using Webpack, you can instead directly import the file using a loader like this or this, in which case the file is included into the resulting bundled javascript.
You can load XML through a string of text using DOMParser, Just load your file and parse the text using the .parseFromString. You could use an if statement containing (window.DOMParser) to check if the DOMParser is supported

Illustrator JS Script Run without app.activeDocument

I have been using Illustrators API to create a script that is able to export .ai files swatches into a JSON format.
This however is all by having to open the Illustrator file and click
File > Scripts > Run My Script.
This is something that is very tedious and was wondering if there was a way in order to take the the files location (file path) and just execute the program using something like Node which will just use my already existing code and my AI file.
Currently I have something that looks along the lines of:
var Exporter = function() {
this.swatchGroup = 'ClientColours';
this.myApp = app.activeDocument;
this.chosenSwatchGroup();
this.writeFile(); };
What I am thinking is there not a way to instead of having this.myApp = app.activeDocument; to rather have something like this.myApp = Path(../my location);?
I have been making us of this documentation Jongware and Adobe Documentation just cant seem to find the answer I am looking for in order to get closer to this sort of automation.
EDIT
Did some digging and found the application documentation and there is a 'path' property just not sure on its implementation. Documentation
Yes, you can do this by providing path. But you have to open that file and that file will be your activeDocument. For eg :
var file = File("../your location");
app.open(file);
this.myApp = app.activeDocument;
By this, the file at your location will get open in Illustrator and will be activeDocument.

HTML/Javascript: Getting a List of all files and subdirectories in a given directory

I am working on an interface that allows the to access the file system on the client side. The user should be able to browse through the file system, select a directory and my system will display list of files and sub-directories of the selected directory.
I have tried using HTML5 File API, but that apparently only allows users to select files (not folders).
Any pointers/help in this direction will be appreciated.
This cannot be done in JavaScript as it would be a potential security issue. Only files selected by the user via a file dialog can be accessed using JavaScript.
Here's a pretty nice article on the File API if you haven't come across it yet.
If it's still an open issue, then let me give you a solution that might work for you.
HTML
File input for selecting a directory:
<input type="file" id="file-input" webkitdirectory="" directory=""/>
JavaScript
The following script collects all files from the given folder and from ALL sub folders.
Even from sub-subfolders, etc.
$("#file-input").on("change", function(e) {
var thefiles = e.target.files;
$.each(thefiles, function(i, item) {
var thefile = item;
var reader = new FileReader();
reader.onload = function() {
files.push(thefile);
};
reader.readAsArrayBuffer(thefile);
});
});

Categories