VFS for Google Drive, 1st working version

This commit is contained in:
Xuan Sang LE 2018-02-28 15:33:57 +01:00
parent 77336716b5
commit 28ab98b055
9 changed files with 178 additions and 20 deletions

View File

@ -304,6 +304,8 @@ class FileDiaLog extends BaseDialog
(@find "bt-cancel").set "onbtclick", (e) ->
me.quit()
($ filename).css("display", "block").val @data.file.basename or "Untitled" if @data and @data.file
if @data and @data.file
($ filename).css("display", "block").val @data.file.basename or "Untitled"
@trigger "resize"
this.OS.register "FileDiaLog", FileDiaLog

View File

@ -103,9 +103,11 @@ self.OS.API =
.done (data) ->
_API.loaded q, p, "OK"
c(data)
o.remove()
.fail (e, s) ->
_API.loaded q, p, "FAIL"
f(e, s)
o.remove()
o.click()

View File

@ -353,7 +353,7 @@ self.OS.GUI =
_OS.cleanup()
# get setting from conf
_OS.systemSetting(conf)
console.log _OS.setting
#console.log _OS.setting
# load theme
_GUI.loadTheme _OS.setting.appearance.theme
# initDM

View File

@ -60,6 +60,16 @@
self.items.unshift(e)
if(u) self.update()
}
self.root.replaceItem = function(o, n, u)
{
var ix = self.items.indexOf(o)
if(ix >= 0)
{
self.items[ix] = n
if(u) self.update()
}
}
self.root.remove = function(e,u)
{
var i = self.items.indexOf(e)

View File

@ -56,6 +56,11 @@
e.closable = self.closable
self.refs.list.root.push(e,u)
}
self.root.replaceItem = function(o,n,u)
{
n.closable = self.closable
self.refs.list.root.replaceItem(o,n,u)
}
self.root.unshift = function(e,u)
{
self.refs.list.root.unshift(e,u)

View File

@ -36,6 +36,12 @@ class BaseFileHandler
isRoot: () -> (not @genealogy) or (@genealogy.size is 0)
child: (name) ->
if @isRoot()
return @path + name
else
return @path + "/" + name
isHidden: () ->
return false if not @basename
@basename[0] is "."
@ -44,10 +50,20 @@ class BaseFileHandler
return -1 unless @path
return @path.hash()
getb64: (m) ->
return "" unless @cache
b64 = @cache.asBase64()
return "data:#{m};base64,#{b64}"
sendB64: (m, f) ->
me = @
return unless @cache
if typeof @cache is "string"
b64 = @cache.asBase64()
b64 = "data:#{m};base64,#{b64}"
f(b64)
else
reader = new FileReader()
reader.readAsDataURL(@cache)
reader.onload = () ->
f reader.result
reader.onerror = (e) ->
return _courrier.osfail "Cannot ecode file: #{me.path}", (_API.throwe "OS.VFS"), e
parent: () ->
return @ if @isRoot()
return (@protocol + ":///" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
@ -140,7 +156,8 @@ class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
return f { error: "#{@path} is not a directory" } if @info.type is "file"
_API.handler.mkdir "#{@path}/#{p}", f
when "write"
_API.handler.write @path, p, f
@sendB64 p, (data) ->
_API.handler.write me.path, data, f
when "upload"
return if @info.type is "file"
_API.handler.upload @path, f

View File

@ -9,6 +9,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
@setting = _OS.setting.VFS.gdrive
return _courrier.oserror "Unknown API setting for google drive VFS", (_API.throwe "OS.VFS"), null unless @setting
@gid = 'root' if @isRoot()
@cache = ""
oninit: (f) ->
me = @
@ -28,6 +29,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fn = (r) ->
return f() if r
# perform the login
G_CACHE = {"gdv:///":"root"}
gapi.auth2.getAuthInstance().signIn()
gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
@ -65,21 +67,49 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: () ->
return "webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size"
isFolder: () ->
return @info.mimeType is "application/vnd.google-apps.folder"
save: (id, m, f) ->
me = @
user = gapi.auth2.getAuthInstance().currentUser.get()
oauthToken = user.getAuthResponse().access_token
xhr = new XMLHttpRequest()
url = 'https://www.googleapis.com/upload/drive/v3/files/' + id + '?uploadType=media'
xhr.open('PATCH', url)
xhr.setRequestHeader 'Authorization', 'Bearer ' + oauthToken
xhr.setRequestHeader 'Content-Type', m
xhr.setRequestHeader 'Content-Encoding', 'base64'
xhr.setRequestHeader 'Content-Transfer-Encoding', 'base64'
error = (e, s) ->
_courrier.oserror "VFS cannot save : #{me.path}", e, s
xhr.onreadystatechange = () ->
if ( xhr.readyState == 4 )
if ( xhr.status == 200 )
f { result: JSON.parse(xhr.responseText) }
else
error xhr, xhr.status
xhr.onerror = () ->
error xhr, xhr.status
@sendB64 m, (data) ->
xhr.send data.replace /^data:[^;]+;base64,/g, ""
action: (n, p, f) ->
me = @
switch n
when "read"
return unless @info.id
if @info.mimeType is "application/vnd.google-apps.folder"
if @isFolder()
gapi.client.drive.files.list {
q: "'#{me.info.id}' in parents and trashed = false",
fields: "files(#{me.fields()})"
}
.then (r) ->
return unless r.result.files and r.result.files.length > 0
return unless r.result.files
for file in r.result.files
file.path = me.path + "/" + file.name
file.path = me.child file.name
file.mime = file.mimeType
file.filename = file.name
file.type = "file"
@ -87,6 +117,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
if file.mimeType is "application/vnd.google-apps.folder"
file.mime = "dir"
file.type = "dir"
file.size = 0
f { result: r.result.files }
else
gapi.client.drive.files.get {
@ -97,19 +128,101 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f r.body
when "mk"
return f { error: "#{@path} is not a directory" } unless @isFolder()
meta =
name: p,
parents: [@info.id],
mimeType: 'application/vnd.google-apps.folder'
gapi.client.drive.files.create {
resource: meta,
fields: 'id'
}
.execute (r) ->
#console.log r
return _courrier.oserror "VFS cannot create : #{p}", (_API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.child p] = r.result.id
f r
return
when "write"
return
gid = G_CACHE[me.path]
if gid
@save gid, p, f
else
console.log "New file"
dir = @parent().asFileHandler()
dir.onready () ->
meta =
name: me.basename,
mimeType: p,
parents: [dir.info.id]
gapi.client.drive.files.create {
resource: meta,
fields: 'id'
}
.execute (r) ->
return _courrier.oserror "VFS cannot write : #{me.path}", (_API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.path] = r.result.id
me.save r.result.id, p, f
when "upload"
return
return unless @isFolder()
q = _courrier.getMID()
#insert a temporal file selector
o = ($ '<input>').attr('type', 'file').css("display", "none")
o.change () ->
#_API.loading q, p
fo = o[0].files[0]
file = (me.child fo.name).asFileHandler()
file.cache = fo
file.write fo.type, f
o.remove()
#_API.loaded q, p, "OK"
#_API.loaded q, p, "FAIL"
o.click()
when "remove"
return
return unless @info.id
gapi.client.drive.files.delete {
fileId: me.info.id
}
.execute (r) ->
#console.log r
return _courrier.oserror "VFS cannot delete : #{me.path}", (_API.throwe "OS.VFS"), r unless r
G_CACHE[me.path] = null
f { result: true }
when "publish"
return
when "download"
return
gapi.client.drive.files.get {
fileId: me.info.id,
alt: 'media'
}
.then (r) ->
return _courrier.oserror "VFS cannot get file : #{me.path}", (_API.throwe "OS.VFS"), r unless r.body
blob = new Blob [r.body], { type: "octet/stream" }
_API.saveblob me.basename, blob
when "move"
return
dest = p.asFileHandler().parent().asFileHandler()
dest.onready () ->
previousParents = me.info.parents.join ','
gapi.client.drive.files.update {
fileId: me.info.id,
addParents: dest.info.id,
removeParents: previousParents,
fields: "id"
}
.execute (r) ->
return _courrier.oserror "VFS cannot move : #{me.path}", (_API.throwe "OS.VFS"), r unless r
f r
else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n

View File

@ -88,6 +88,7 @@ class Files extends this.OS.GUI.BaseApplication
chdir: (p) ->
me = @
console.log "ch"
dir = if p then p.asFileHandler() else me.currdir
dir.read (d) ->
if(d.error)
@ -102,7 +103,7 @@ class Files extends this.OS.GUI.BaseApplication
d.result.unshift p
($ me.navinput).val dir.path
me.view.set "path", dir.path
console.log d.result
#console.log d.result
me.view.set "data", d.result
mnFile:() ->
@ -252,7 +253,7 @@ class Files extends this.OS.GUI.BaseApplication
@openDialog "PromptDialog",
(d) ->
fp = "#{me.currdir.path}/#{d}".asFileHandler()
fp.write "", (r) ->
fp.write "text/plain", (r) ->
me.error "Fail to create #{d}: #{r.error}" if r.error
, "New file", { label: "File name:" }

View File

@ -112,6 +112,7 @@ class NotePad extends this.OS.GUI.BaseApplication
open: (file) ->
#find table
i = @findTabByFile file
@fileview.set "preventUpdate", true
return @tabarea.set "selected", i if i isnt -1
return @newtab file if file.path.toString() is "Untitled"
me = @
@ -163,7 +164,7 @@ class NotePad extends this.OS.GUI.BaseApplication
save: (file) ->
me = @
file.write (file.getb64 "text/plain"), (d) ->
file.write "text/plain", (d) ->
return me.error "Error saving file #{file.basename}" if d.error
file.dirty = false
file.text = file.basename
@ -191,7 +192,6 @@ class NotePad extends this.OS.GUI.BaseApplication
@currfile.selected = false
file.selected = true
#console.log cnt
@fileview.set "preventUpdate", true
@tabarea.push file, true
#@currfile = @file
#TODO: fix problem : @tabarea.set "selected", cnt
@ -255,7 +255,15 @@ class NotePad extends this.OS.GUI.BaseApplication
me = @
saveas = () ->
me.openDialog "FileDiaLog", (d, n) ->
me.currfile.setPath "#{d}/#{n}"
file = "#{d}/#{n}".asFileHandler()
file.cache = me.currfile.cache
file.dirty = me.currfile.dirty
file.um = me.currfile.um
file.cursor = me.currfile.cursor
file.selected = me.currfile.selected
file.text = me.currfile.text
me.tabarea.replaceItem me.currfile, file, false
me.currfile = file
me.save me.currfile
, "Save as", { file: me.currfile }
switch e