Re: Simple API proposal for writing file in local file system

Hi!


2013/10/18 Ehsan Akhgari <ehsan.akhgari@gmail.com>

> Hi Jeremie,
>
> Have you seen this proposal? <http://lists.w3.org/Archives/**
> Public/public-script-coord/**2013JulSep/0379.html<http://lists.w3.org/Archives/Public/public-script-coord/2013JulSep/0379.html>>
>  It's not clear to me if your proposal here is trying to solve problems
> that the above proposal doesn't already solve...
>

Yes, I saw that proposal but no, I do not suggest to solve the same problem.

I found that proposal for an abstract file system very good when the
application have to work in its own world.
Unfortunately there is a few cases where it is very convenient to allow to
actually truly write on the os file system.

Here a few concrete example:

   - When the user want to export his file to an external storage (Hard
   drive, USB storage, SD Card, etc.) In that case it where web dev use the
   data URI workaround to "download" the file.
   - When the user want to use a resource available in its file system and
   want to update that resource with any change he made to have some other
   application using it as well (mostly native apps on desktop). For example,
   editing an image and put it back on the file system to have another native
   application accessing it (let's say for example Adobe Lightroom). So being
   able to open a file and perform (silent) saving on the original file allows
   to build smoother workflow when using a native app and a web app at the
   same time.

As Mozilla teams are currently completely overwhelmed by the Firefox OS
project, they tend to forget those use cases that are very common on
Desktop. On the other hand, I think that FileWriter is way to complex and
there is a middle simpler ground that can solve the most common use cases
such as the two above.

My proposal does not suggest to do something different than what is
currently possible (except the silent saving). Just to ease the life of Web
dev by avoiding them to work around their usual problem:

   - Instantiate a full DOM object and listen for its events just to pick a
   file sucks
   - Being unable to silently save a file granted by the user to be savable
   sucks.

I don't try to solve more than this. It's just common issues for web dev
like me and that will make my life easier if it would be possible do this
simply, efficiently and in a secure way.

Best,
Jérémie

On 2013-10-18 8:07 AM, Jeremie Patonnier wrote:
>
>> Hello!
>>
>> As a Web developer, I recently dig into the proposed FileSystem API [1]
>> which cover many use cases except one: How a user can actually allows a
>> web
>> application to really write something in the user local file system (even
>> if it's slow). On the other hand, the File API: Writer [2] cover that need
>> but with a very overwelming interface which make very hard to use for
>> simple open/save operation.
>>
>> There are well known workaround but we could make the life of web
>> developer
>> easier by providing a simple convenient and secure interface to do this.
>>
>>
>> *# Accessing a file.*
>>
>>
>> Currently, as per the File API [3], the only way to access a file in the
>> user file system is by using the <input type="file"> element. For some
>> reason, web developer don't want to expose such input to the user
>> (basically, because it's impossible to change its look and feel
>> consistently across browsers). To work around this, they hide it and
>> perform a fake click on it to prompt the user to pick some files.
>>
>> We could provide a method that allow to do the same. In terms of security,
>> it would also make easier to track malicious attempt to acces the file
>> system as we will be able to monitor all access through that single
>> method.
>>
>> partial interface Navigator {
>>    Promise openFile();
>> }
>>
>> In case of success, the Promise will get a FileList object as the user can
>> pick more than one file.
>>
>>
>> *# Writing a file*
>>
>>
>> Currently, the only way to write a file on the user file system is to turn
>> a File object into a data URI with the MIME type application/octet-stream
>> in order to force a download of the file. This allows the user to save the
>> file wherever he wants on his device.
>>
>> This is very rough and have two drawbacks:
>>
>>     1. if the user has setup his browser to always put downloaded file in
>> a
>>
>>     given repository, it could require some extra action from the user to
>> move
>>     the file in his file system. This lead to a bad user experience that
>> many
>>     web developers wish to avoid.
>>     2. if the user has previously open the file that need to be put back
>> in
>>
>>     his file system, it's impossible to perform a silent writing. The
>> user is
>>     always prompt to perform the overriding itself. Once again, it's a
>> bad user
>>     experience that web developers wish to avoid.
>>
>> To solve those two issues, we could provide a save method that will allow
>> to bypass any download setup and to provide a secure way of making silent
>> writing.
>>
>> Note: It is worth noticing that Microsoft did something similare for IE11
>> with the msSaveBlob [4] and msSaveOrOpenBlob [5] methods
>>
>> partial interface Navigator {
>>    Promise saveFile(File file, optional boolean silent);
>> }
>>
>> Note: it would be possible to add some events to keep track of the writing
>> operation, but Promise are good enough as we just want to save files in
>> the
>> local file system rather than making some intensive IO operation. If a web
>> developer want to do that it would be better for him to relay on the
>> FileSystem API.
>>
>> Making secured silent writing require two things:
>>
>> 1. Only file picked by the user and explicitely chose as writable by him
>> can be silently writen. The LockedFile object in the FileSystem API draft
>> is close to that but looks unnecessary complicated. I suggest to make
>> something simple by extending the File interface.
>>
>> partial interface File {
>>    readonly attribute DOMString? mode; // It can be 'readonly' or
>> 'writable'
>>    readonly attribute boolean? lock; // If true, only that tab can modify
>> the file
>> }
>>
>> In order to sustain this, the 'mode' and 'lock' must be set when calling
>> the openFile method:
>>
>> partial interface Navigator {
>>    Promise openFile(optional DOMString mode, optional boolean lock);
>> }
>>
>>     - The 'mode' indicate if the File is 'readonly' or 'writable'. The
>>
>>     browser must retain the information of the location in the file
>> system for
>>     all writable files object, but this information will never be exposed
>> to
>>     web content.
>>     - The 'lock' indicate if the browser must put a lock on the file,
>>
>>     allowing only the tab which access it first to write back into the
>> file
>>     (It's an internal lock maintain by the browser, it is never put at
>> the file
>>     system level, I'm not sure but I think there are to many side effects
>> to
>>     allow such a hard lock). If another tab has already put a lock on the
>> file,
>>     the Promise will fail with an appropriate error message. The lock is
>>     released when the File object is destroyed (it is garbage collected,
>> the
>>     tab using it is shutdown, etc.). Note: it could be convenient to have
>> a
>>     setLock method to change the lock state.
>>
>> If a File object is created without using the openFile method, the mode
>> and
>> lock will be null;
>>
>> The saving steps should be the following:
>>
>>     1. If a File object is saved using the saveFile method:
>>        1. If the object has its mode set to 'readonly' or null
>>           1. The user is prompt to choose where to save the file
>>        2. If the object has its mode set to 'writable'
>>        1. If the silent parameter is set to true
>>              1. if the file is no longer available in the file system
>>                 1. If the object has its lock set to true
>>                    1. The file is recreated using the data available in
>> the
>>                    File object
>>                 2. If the object has its lock set to false
>>                    1. The user is prompt to choose where to save the file
>>                 2. otherwise
>>                 1. The file on the file system is silently overridden by
>> the
>>
>>                 content of the File object
>>              2. If the silent parameter is set to false
>>              1. if the file is no longer available in the file system
>>                 1. The user is prompt to choose where to save the file
>>              2. Otherwise
>>                 1. The user is prompt to allow the override
>>
>>
>> 2. The first time a silent saving is performed, the user must be prompt to
>> allow this (possible answer are never, this time only, for the rest of the
>> session, or forever); If the user chose 'never', any call to the saveFile
>> method will be done as if the silent parameter were set to false (whatever
>> its true value).
>>
>> In order to avoid nasty security issues, the calls to the saveFile method
>> from script hosted on third party domain should never be allowed to be
>> silent and each saving prompt should display which domain is trying to
>> write on the file system.
>>
>> [1] http://w3c.github.io/**filesystem-api/Overview.html<http://w3c.github.io/filesystem-api/Overview.html>
>> [2] http://dev.w3.org/2009/dap/**file-system/file-writer.html<http://dev.w3.org/2009/dap/file-system/file-writer.html>
>> [3] http://dev.w3.org/2006/webapi/**FileAPI/<http://dev.w3.org/2006/webapi/FileAPI/>
>> [4] http://msdn.microsoft.com/en-**us/library/hh772331%28v=vs.85%**
>> 29.aspx<http://msdn.microsoft.com/en-us/library/hh772331%28v=vs.85%29.aspx>
>> [5] http://msdn.microsoft.com/en-**us/library/hh772332%28v=vs.85%**
>> 29.aspx<http://msdn.microsoft.com/en-us/library/hh772332%28v=vs.85%29.aspx>
>>
>> Best,
>>
>>
>


-- 
Jeremie
.............................
Web : http://jeremie.patonnier.net
Twitter : @JeremiePat <http://twitter.com/JeremiePat>

Received on Friday, 18 October 2013 18:13:07 UTC