mirror of
https://github.com/lxsang/antos-frontend.git
synced 2025-04-07 17:16:44 +02:00
352 lines
11 KiB
CoffeeScript
352 lines
11 KiB
CoffeeScript
# Copyright 2017-2018 Xuan Sang LE <xsang.le AT gmail DOT com>
|
|
|
|
# AnTOS Web desktop is is licensed under the GNU General Public
|
|
# License v3.0, see the LICENCE file for more information
|
|
|
|
# This program is free software: you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License as
|
|
# published by the Free Software Foundation, either version 3 of
|
|
# the License, or (at your option) any later version.
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
#along with this program. If not, see https://www.gnu.org/licenses/.
|
|
String.prototype.asFileHandler = () ->
|
|
list = @split "://"
|
|
handlers = _API.VFS.findHandlers list[0]
|
|
if not handlers or handlers.length is 0
|
|
_courrier.osfail __("VFS unknown handler: {0}", @), (_API.throwe "OS.VFS"), @
|
|
return null
|
|
return new handlers[0](@)
|
|
|
|
this.OS.API.VFS =
|
|
handlers: { }
|
|
register: ( protos, cls ) ->
|
|
return self.OS.API.VFS.handlers[protos] = cls # if typeof protos is "string"
|
|
#_API.VFS.handlers[v] = cls for v in protos
|
|
findHandlers: (proto) ->
|
|
l = (v for k, v of _API.VFS.handlers when proto.trim().match (new RegExp k , "g"))
|
|
return l
|
|
|
|
class BaseFileHandler
|
|
constructor: (path) ->
|
|
@dirty = false
|
|
@cache = undefined
|
|
@setPath path
|
|
|
|
setPath: (p) ->
|
|
@ready = false
|
|
return unless p
|
|
@path = p.toString()
|
|
list = @path.split "://"
|
|
@protocol = list[0]
|
|
return unless list.length > 1
|
|
re = list[1].replace(/^\/+|\/+$/g, '')
|
|
return if re is ""
|
|
@genealogy = re.split("/")
|
|
@basename = @genealogy[@genealogy.length - 1] unless @isRoot()
|
|
@ext = @basename.split( "." ).pop() unless @basename.lastIndexOf(".") is 0 or @basename.indexOf( "." ) is -1
|
|
asFileHandler: () ->
|
|
@
|
|
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 "."
|
|
|
|
hash: () ->
|
|
return -1 unless @path
|
|
return @path.hash()
|
|
|
|
sendB64: (m, f) ->
|
|
me = @
|
|
return f "" 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 __("VFS Cannot encode file: {0}", me.path), (_API.throwe "OS.VFS"), e
|
|
parent: () ->
|
|
return @ if @isRoot()
|
|
return (@protocol + "://" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
|
|
|
|
onready: (f, err) ->
|
|
# read meta data
|
|
return f() if @ready
|
|
me = @
|
|
me.meta (d) ->
|
|
if d.error
|
|
return if err then err d else _courrier.osfail "#{me.path}: #{d.error}", (_API.throwe "OS.VFS"), d.error
|
|
me.info = d.result
|
|
me.ready = true
|
|
f()
|
|
|
|
read: (f, t) ->
|
|
me = @
|
|
@onready (() -> me.action "read", t, f)
|
|
|
|
write: (d, f) ->
|
|
me = @
|
|
@action "write", d, (r) ->
|
|
_courrier.ostrigger "VFS", { m: "write", file: me } if r.result
|
|
f r
|
|
|
|
mk: (d, f) ->
|
|
me = @
|
|
@onready (() -> me.action "mk", d, (r) ->
|
|
_courrier.ostrigger "VFS", { m: "mk", file: me } if r.result
|
|
f r)
|
|
|
|
remove: (f) ->
|
|
me = @
|
|
@onready (() -> me.action "remove", null, (r) ->
|
|
_courrier.ostrigger "VFS", { m: "remove", file: me } if r.result
|
|
f r)
|
|
|
|
upload: (f) ->
|
|
me = @
|
|
@onready (() -> me.action "upload", null, (r) ->
|
|
_courrier.ostrigger "VFS", { m: "upload", file: me } if r.result
|
|
f r)
|
|
publish: (f) ->
|
|
me = @
|
|
@onready (() -> me.action "publish", null, (r) ->
|
|
_courrier.ostrigger "VFS", { m: "publish", file: me } if r.result
|
|
f r)
|
|
download: (f) ->
|
|
me = @
|
|
@onready (() -> me.action "download", null, f)
|
|
|
|
move: (d, f) ->
|
|
me = @
|
|
@onready (() -> me.action "move", d, (r) ->
|
|
_courrier.ostrigger "VFS", { m: "move", file: d.asFileHandler() } if r.result
|
|
f r)
|
|
|
|
execute: (f) ->
|
|
me = @
|
|
@onready (() -> me.action "execute", null, f)
|
|
|
|
#mk: (f) ->
|
|
|
|
meta: (f) ->
|
|
|
|
# for main action read, write, remove, execute
|
|
# must be implemented by subclasses
|
|
action: (n, p, f) ->
|
|
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
|
|
|
|
# now export the class
|
|
self.OS.API.VFS.BaseFileHandler = BaseFileHandler
|
|
|
|
# Remote file handle
|
|
class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
|
|
constructor: (path) ->
|
|
super path
|
|
|
|
meta: (f) ->
|
|
_API.handler.fileinfo @path, f
|
|
|
|
action: (n, p, f) ->
|
|
me = @
|
|
switch n
|
|
when "read"
|
|
return _API.handler.scandir @path, f if @info.type is "dir"
|
|
#read the file
|
|
return _API.handler.fileblob @path, f if p is "binary"
|
|
_API.handler.readfile @path, f, if p then p else "text"
|
|
when "mk"
|
|
return f { error: __("{0} is not a directory", @path) } if @info.type is "file"
|
|
_API.handler.mkdir "#{@path}/#{p}", f
|
|
when "write"
|
|
return _API.handler.write me.path, me.cache, f if p is "base64"
|
|
@sendB64 p, (data) ->
|
|
_API.handler.write me.path, data, f
|
|
when "upload"
|
|
return if @info.type is "file"
|
|
_API.handler.upload @path, f
|
|
when "remove"
|
|
_API.handler.delete @path, f
|
|
when "publish"
|
|
_API.handler.sharefile @path, true , f
|
|
when "download"
|
|
return if @info.type is "dir"
|
|
_API.handler.fileblob @path, (d) ->
|
|
blob = new Blob [d], { type: "octet/stream" }
|
|
_API.saveblob me.basename, blob
|
|
when "move"
|
|
_API.handler.move @path, p, f
|
|
else
|
|
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
|
|
|
|
self.OS.API.VFS.register "^(home|desktop|os|Untitled)$", RemoteFileHandler
|
|
|
|
# Application Handler
|
|
class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
|
|
constructor: (path) ->
|
|
super path
|
|
@info = _OS.setting.system.packages[@basename] if @basename
|
|
@ready = true
|
|
|
|
meta: (f) ->
|
|
f()
|
|
|
|
action: (n, p, f) ->
|
|
me = @
|
|
switch n
|
|
when "read"
|
|
return f { result: @info } if @info
|
|
return unless @isRoot()
|
|
f { result: ( v for k, v of _OS.setting.system.packages ) }
|
|
|
|
when "mk"
|
|
return
|
|
|
|
when "write"
|
|
return
|
|
|
|
when "upload"
|
|
# install
|
|
return
|
|
|
|
when "remove"
|
|
#uninstall
|
|
return
|
|
when "publish"
|
|
return
|
|
when "download"
|
|
return
|
|
|
|
when "move"
|
|
return
|
|
else
|
|
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
|
|
|
|
self.OS.API.VFS.register "^app$", ApplicationHandler
|
|
|
|
class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
|
|
constructor: (path, mime, data) ->
|
|
super path
|
|
@cache = data if data
|
|
@info =
|
|
mime: mime
|
|
path: path
|
|
size: if data then data.length else 0
|
|
name: @basename
|
|
type: "file"
|
|
meta: (f) ->
|
|
f()
|
|
|
|
onchange: (f) ->
|
|
@onchange = f
|
|
|
|
action: (n, p, f) ->
|
|
me = @
|
|
switch n
|
|
when "read"
|
|
return f { result: @cache }
|
|
|
|
when "mk"
|
|
return
|
|
|
|
when "write"
|
|
@cache = p
|
|
@onchange @ if @onchange
|
|
f { result: true }
|
|
|
|
when "upload"
|
|
# install
|
|
return
|
|
|
|
when "remove"
|
|
#uninstall
|
|
return
|
|
when "publish"
|
|
return
|
|
when "download"
|
|
blob = new Blob [@cache], { type: "octet/stream" }
|
|
_API.saveblob me.basename, blob
|
|
|
|
when "move"
|
|
return
|
|
else
|
|
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
|
|
|
|
self.OS.API.VFS.register "^mem$", BufferFileHandler
|
|
|
|
class URLFileHandler extends self.OS.API.VFS.BaseFileHandler
|
|
constructor: (path) ->
|
|
super path
|
|
@ready = true
|
|
meta: (f) ->
|
|
f { result: true }
|
|
action: (n, p, f) ->
|
|
me = @
|
|
switch n
|
|
when "read"
|
|
_API.get @path, (d) ->
|
|
f(d)
|
|
, (e, s) ->
|
|
_courrier.oserror __("VFS cannot read : {0}", me.path), e, s
|
|
, if p then p else "text"
|
|
else
|
|
return _courrier.oserror __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
|
|
self.OS.API.VFS.register "^(http|https)$", URLFileHandler
|
|
|
|
class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
|
|
constructor: (path) ->
|
|
super path
|
|
@ready = true if @isRoot()
|
|
meta: (f) ->
|
|
_API.handler.fileinfo @path, f
|
|
|
|
action: (n, p, f) ->
|
|
me = @
|
|
switch n
|
|
when "read"
|
|
return _API.get "#{_API.handler.shared}/all", f, ((e, s)->) if @isRoot()
|
|
#read the file
|
|
return _API.handler.fileblob @path, f if p is "binary"
|
|
_API.handler.readfile @path, f, if p then p else "text"
|
|
when "mk"
|
|
return
|
|
|
|
when "write"
|
|
_API.handler.write @path, p, f
|
|
|
|
when "remove"
|
|
_API.handler.sharefile @basename, false, f
|
|
|
|
when "upload"
|
|
return
|
|
|
|
when "publish"
|
|
return f { result: @basename }
|
|
|
|
when "download"
|
|
return if @info.type is "dir"
|
|
_API.handler.fileblob @path, (d) ->
|
|
blob = new Blob [d], { type: "octet/stream" }
|
|
_API.saveblob me.basename, blob
|
|
when "move"
|
|
return
|
|
else
|
|
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
|
|
|
|
self.OS.API.VFS.register "^shared$", SharedFileHandler |