I'm using the HTML5 FileSystem API in a Chrome Packaged App to write to a log file. I want the user to be able to download this file, so I tried something along the lines of:
fs.root.getFile('log.txt', {create: false}, function(fileEntry) {
var url = fileEntry.toURL();
// do something with the file url
});
This doesn't help though, because the URL is something like filesystem:chrome-extension://eekedjcagggbfigdmifkmhkjbhiklnpj/temporary/log.txt and it's not possible to open it somewhere.
What technique would you recommend to make a FileSystem API file in a Packaged App downloadable?
Edit: After reading through Ben Well's answer below, I realized that I'll have to clarify even more what I want. It would seem especially nice to me if there would be a technique that doesn't imply loading the HTML5 Filesystem API file contents, building a blob from it and writing that to a user-chosen path with chrome.fileSystem API.
Have you tried using chrome.fileSystem.chooseEntry? This API lets your app save files to the user's hard disk, wherever they want, letting your program have a Save As kind of command. This is a bit different to a download link, but is also more in harmony with V2 apps being like native apps.
chrome.fileSystem pops up a dialog asking the user to choose a location for a file. If you use the options for saving files, this returns you a file entry that has permissions to write to the location chosen by the user. The user can also create new files when you use these options.
Related
I'm using the Google Drive API to generate a downloadable link for a file that looks like this:
https://www.googleapis.com/drive/v3/files/{file_id}?access_token={access_token}&alt=media
The problem is files are being downloaded without name and without extension.
If I add the extension manually after the file downloads it still works, but it's bad to tell my users they have to do that every time, and the user would have to know which extension the file actually has.
If I call https://www.googleapis.com/drive/v3/files/?access_token={access_token}
I can't see the files I've uploaded... I think it could be a problem related to having access to the files' metadata, but I did authorize the auth.files.metadata scope.
I generate the access token using the refresh token and obtained the refresh token from the Oauth Playground... I'm confident I used the proper credentials for my application, but I could triple-check if someone suggests this could be the problem.
What can I do to debug this?
My chrome app needs to save a file with human-readable or standard format such as SQLite (It should be readable outside Chrome).
Is there any API suitable for this purpose?
Some files with .localstorage extension (SQLite format) are in Chrome\User Data\Default\Local Storage folder. Is it possible to create such files by the app?
Edited: The app should not ask user for extra permission.
Thanks for your consideration.
chrome.fileSystem API is what you need.
You will need to ask the user at least once where to save the file, but then you can retain the entry to write again to the same file/folder.
There is no way around asking the user to "escape the sandbox".
You'll want to use the Quota Management API. This is per-origin storage, and you request specific amounts of quota.
It sounds like you also want your users to open the files directly? There's an HTML5 filesystem explorer Chrome app that you can use. It'll show you the files, and you can figure things out from their URLs (e.g. I'm currently using filesystem:http://localhost:8000/temporary/bar for a local experiment).
Or are you looking for something more user friendly? I think you have to use file save in that case, the same way Google Drive does.
I am building a chrome app for Digital Signage where I need the user to select some files from a particular folder (preferably in the app's directory) i.e audio, videos, photos which should be created by the app on install.
The sample code provided by Google requires that the user navigates to a folder like this
chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(theEntry) {
if (!theEntry) {
output.textContent = 'No Directory selected.';
return;
}
// use local storage to retain access to this file
chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)});
loadDirEntry(theEntry);
});
However, my app simply needs the name of files in that (say Video) known directory for the user to build a playlist, rather than actually selecting a video file.
Is this supported in chrome.fileSystem API? Any pointers to how I cold get this done?
It sounds like you should be using either the app's sandboxed file systems, or the app's install folder itself.
The sandboxed file systems allow the app to store whatever data it wants, in whatever structure it wants. There are two to choose from: persistent or temporary. Temporary may be cleared at any point in time. To use these check out this article. Some of its code may be out of date with the spec. Note also apps need to request the unlimitedStorage to use these.
The install folder itself can be used in a read only way. To do this you use chrome.runtime.getPackageDirectoryEntry.
I've succeeded in using the filesystem API in a Chrome App on my Chromebook. But none of the examples I've found allow you to open files from Google Drive. Any number of apps on the Chromebook (supplied or added) open the exact same dialog but with Google Drive showing on the left along with Download and External Drive.
Is there a simple example App which shows how this is done?
Or am I simply missing some concept which will make even the Diff or TextEdit examples work this way if done (like pushing the App to the store, perhaps -- right now I'm just loading and packing my own off local storage)?
From reading your comment it seems that you will want to use google drive sdk in order to integrate the 'open file' dialog into your web app.
and even more to the point - the file 'picker' - In order to integrate the file picker you will need to use google JS client lib. Then you will be able to open the file dialog with a code like this:
// Use the Google Loader script to load the google.picker script.
google.setOnLoadCallback(createPicker);
google.load('picker', '1');
// Create and render a Picker object for searching images.
function createPicker() {
var picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.IMAGE_SEARCH).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
Good luck.
The answer to this is to use the <input type="file" name="somename" size="chars"> code in the browser. That is what is producing this. It creates a standard way to read in the file from disk or Google drive. It's what I've seen in multiple apps. All the API stuff is a red herring, if what one wants is to get access to this simple dialog.
However, it doesn't allow me to WRITE, just to read, since one would expect it to be returning only the content of the file, not a file handle of any sort, or even the full name. I'll play with it and figure out whether there's any hook I can find to tell me to write it to Google drive (using the links Ido provided above). If anyone has suggestions on where to snag the full path (or an interesting Google Drive path) somewhere using this, I'll love to hear them.
I wanted to ensure the documents I let user download are programmatically manipulated throughout program.
I came to know that File API does give Apps the opportunity to manipulate them. But how can we store the Files in the sandboxed location?
You cannot directly read or write anything to the file system. You always have to go through either the usual upload/save dialog, or rely on desktop drag-and-drop (you can drag files into most modern browsers, and out of Google Chrome, at least).
It seems you can't let the browser download the file directly into File API's sandbox now. You have to fetch the file by yourself in JavaScript and write it to a file through File API. If the file is from the same origin, you can just fetch it by XHR.