This commit is contained in:
lxsang 2020-02-20 18:28:03 +01:00
parent 80de4fcf5b
commit d50d884733
21 changed files with 578 additions and 584 deletions

View File

@ -14,9 +14,9 @@ endif
coffees= src/core/core.coffee\
src/core/api.coffee\
src/core/settings.coffee\
src/core/handlers/RemoteHandler.coffee\
src/core/handles/RemoteHandle.coffee\
src/core/vfs.coffee\
src/core/vfs/GoogleDriveHandler.coffee\
src/core/vfs/GoogleDriveHandle.coffee\
src/core/db.coffee\
src/core/gui.coffee\
src/core/BaseModel.coffee\
@ -29,7 +29,7 @@ coffees= src/core/core.coffee\
packages = CoreServices NotePad wTerm ActivityMonitor Files MarkOn MarketPlace Preview Setting
packages = CoreServices ActivityMonitor Setting # Files MarkOn MarketPlace Preview NotePad wTerm
main: initd build_coffees build_tags build_themes schemes libs build_packages languages
- cp src/index.html $(BUILDDIR)/

View File

@ -1,4 +1,7 @@
# antOS
**This version 1.0.0a will remove the dependencies on Riot.js by rewriting the major API for GUI and Announcement system**
[![Build Status](https://travis-ci.org/lxsang/antos.svg?branch=master)](https://travis-ci.org/lxsang/antos)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Flxsang%2Fantos.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Flxsang%2Fantos?ref=badge_shield)

View File

@ -15,12 +15,7 @@
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
_GUI = self.OS.GUI
_API = self.OS.API
_PM = self.OS.PM
_OS = self.OS
_courrier = self.OS.courrier
this.onload = () ->
($ document).on 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', ()->
_GUI.fullscreen = not _GUI.fullscreen
self.OS.boot()
Ant.OS.GUI.fullscreen = not Ant.OS.GUI.fullscreen
Ant.OS.boot()

View File

@ -18,9 +18,9 @@
class BaseApplication extends this.OS.GUI.BaseModel
constructor: (name, args) ->
super name, args
if (not _OS.setting.applications[@name]) or (Array.isArray OS.setting.applications[@name])
_OS.setting.applications[@name] = {}
@setting = _OS.setting.applications[@name]
if (not Ant.OS.setting.applications[@name]) or (Array.isArray OS.setting.applications[@name])
Ant.OS.setting.applications[@name] = {}
@setting = Ant.OS.setting.applications[@name]
@keycomb =
ALT: {}
CTRL: {}
@ -97,11 +97,11 @@ class BaseApplication extends this.OS.GUI.BaseModel
if not evt.prevent
@.appmenu.set "items", [] if @.pid == @.appmenu.pid
($ @scheme).remove()
meta: () -> _OS.APP[@name].meta
meta: () -> Ant.OS.APP[@name].meta
baseMenu: ->
mn =
[{
text: _OS.APP[@name].meta.name,
text: Ant.OS.APP[@name].meta.name,
child: [
{ text: "__(About)", dataid: "#{@name}-about" },
{ text: "__(Exit)", dataid: "#{@name}-exit" }

View File

@ -22,7 +22,7 @@ class SubWindow extends this.OS.GUI.BaseModel
@modal = false
quit: () ->
evt = new _GUI.BaseEvent("exit")
evt = new Ant.OS.GUI.BaseEvent("exit")
@onexit(evt)
if not evt.prevent
delete @.observable
@ -44,7 +44,7 @@ this.OS.GUI.SubWindow = SubWindow
class BaseDialog extends SubWindow
constructor: (name) ->
super name
@handler = undefined
@handle = undefined
onexit: (e) ->
@parent.dialog = undefined if @parent
@ -78,7 +78,7 @@ class BasicDialog extends BaseDialog
html += "<afx-button data-id = 'bt#{k}' text = '#{v.label}' style='margin-left:5px;'></afx-button>" for k,v of @conf.buttons
html += "</div><div data-height='5'></div></afx-vbox><div data-width='7'></div></afx-hbox></afx-app-window>"
#render the html
_GUI.htmlToScheme html, @, @host
Ant.OS.GUI.htmlToScheme html, @, @host
main: () ->
@scheme.set "apptitle", @title
@ -109,7 +109,7 @@ class PromptDialog extends BasicDialog
onclick: (d) ->
txt = (d.find "content1").value
return d.quit() if txt is ""
d.handler txt if d.handler
d.handle txt if d.handle
d.quit()
},
{
@ -142,7 +142,7 @@ class CalendarDialog extends BasicDialog
onclick: (d) ->
date = (d.find "content0").get "selectedDate"
if date
d.handler date if d.handler
d.handle date if d.handle
d.quit()
else
d.notify __("Please select a date")
@ -168,7 +168,7 @@ class ColorPickerDialog extends BasicDialog
onclick: (d) ->
c = (d.find "content0").get "selectedColor"
if c
d.handler c if d.handler
d.handle c if d.handle
d.quit()
else
d.notify "Please select a color"
@ -208,12 +208,12 @@ class YesNoDialog extends BasicDialog
buttons: [
{
label: "__(Yes)", onclick: (d) ->
d.handler true if d.handler
d.handle true if d.handle
d.quit()
},
{
label: "__(No)", onclick: (d) ->
d.handler false if d.handler
d.handle false if d.handle
d.quit()
}
],
@ -238,7 +238,7 @@ class SelectionDialog extends BasicDialog
el = d.find "content0"
it = el.get "selected"
return unless it
d.handler it if d.handler
d.handle it if d.handle
d.quit()
},
{ label: "__(Cancel)", onclick: (d) -> d.quit() }
@ -288,11 +288,11 @@ class FileDiaLog extends BaseDialog
@scheme.set "apptitle", @title
fileview.set "fetch", (e, f) ->
return unless e.child
e.child.path.asFileHandler().read (d) ->
e.child.path.asFileHandle().read (d) ->
return me.error __("Resource not found: {0}", e.child.path) if d.error
f d.result
setroot = (path) ->
path.asFileHandler().read (d) ->
path.asFileHandle().read (d) ->
if(d.error)
return me.error __("Resource not found: {0}", path)
fileview.set "path", path
@ -323,10 +323,10 @@ class FileDiaLog extends BaseDialog
break
return me.notify __("Only {0} could be selected", me.data.mimes.join(",")) unless m
d = f.path
d = f.path.asFileHandler().parent() if f.type is "file"
me.handler d, ($ filename).val(), f.path, f if me.handler
d = f.path.asFileHandle().parent() if f.type is "file"
me.handle d, ($ filename).val(), f.path, f if me.handle
#sel = if me.data and me.data.selection then me.data.selection else "file"
#me.handler f, ($ filename).val() if me.handler and ((f.type is sel) or (sel is "*"))
#me.handle f, ($ filename).val() if me.handle and ((f.type is sel) or (sel is "*"))
me.quit()
(@find "bt-cancel").set "onbtclick", (e) ->

View File

@ -20,24 +20,24 @@ class BaseModel
constructor: (@name, @args) ->
me = @
@observable = riot.observable()
@_api = self.OS.API
@_gui = self.OS.GUI
@systemsetting = self.OS.setting
@_api = Ant.OS.API
@_gui = Ant.OS.GUI
@systemsetting = Ant.OS.setting
me = @
@on "exit", () -> me.quit()
@host = "#desktop"
@dialog = undefined
render: (p) ->
_GUI.loadScheme p, @, @host
Ant.OS.GUI.loadScheme p, @, @host
quit: (force) ->
evt = new _GUI.BaseEvent("exit", force)
evt = new Ant.OS.GUI.BaseEvent("exit", force)
@onexit(evt)
if not evt.prevent
@observable.off "*"
delete @.observable
@dialog.quit() if @dialog
_PM.kill @
Ant.OS.PM.kill @
path: () ->
mt = @meta()
@ -65,22 +65,22 @@ class BaseModel
trigger: (e, d) -> @observable.trigger e, d
subscribe: (e, f) ->
_courrier.on e, f, @
Ant.OS.announcer.on e, f, @
openDialog: (d, f, title, data) ->
if @dialog
@dialog.show()
return
if typeof d is "string"
if not _GUI.subwindows[d]
if not Ant.OS.GUI.subwindows[d]
@error __("Dialog {0} not found", d)
return
@dialog = new _GUI.subwindows[d]()
@dialog = new Ant.OS.GUI.subwindows[d]()
else
@dialog = d
#@dialog.observable = riot.observable() unless @dialog
@dialog.parent = @
@dialog.handler = f
@dialog.handle = f
@dialog.pid = @pid
@dialog.data = data
@dialog.title = title
@ -95,7 +95,7 @@ class BaseModel
mt = @meta()
icon = undefined
icon = "#{mt.path}/#{mt.icon}" if mt.icon
_courrier.trigger t, { id: @pid, name: @name, data: { m: m, icon: icon, iconclass: mt.iconclass }, error: e }
Ant.OS.announcer.trigger t, { id: @pid, name: @name, data: { m: m, icon: icon, iconclass: mt.iconclass }, error: e }
notify: (m) ->
@publish "notification", m

View File

@ -30,7 +30,7 @@ class BaseService extends this.OS.GUI.BaseModel
# event registe, etc
# scheme loader
meta: () ->
_OS.APP[@name].meta
Ant.OS.APP[@name].meta
attach: (h) ->
@holder = h

View File

@ -132,13 +132,11 @@ String.prototype.__ = () ->
return match[1].l() if match
return @
String.prototype.l = () ->
_API = window.OS.API
_API.lang[@] = @ unless _API.lang[@]
return _API.lang[@]
Ant.OS.API.lang[@] = @ unless Ant.OS.API.lang[@]
return Ant.OS.API.lang[@]
# language directive
this.__ = () ->
_API = window.OS.API
args = arguments
return "Undefined" unless args.length > 0
d = args[0]
@ -163,20 +161,20 @@ Date.prototype.toString = () ->
Date.prototype.timestamp = () ->
return @getTime() / 1000 | 0
self.OS.API =
# the handler object could be a any remote or local handle to
Ant.OS.API =
# the handle object could be a any remote or local handle to
# fetch user data, used by the API to make requests
# handlers are defined in /src/handlers
handler: {}
# handles are defined in /src/handles
handle: {}
shared: {} # shared libraries
searchHandler:{}
searchHandle:{}
lang:{}
#request a user data
mid: () ->
return _courrier.getMID()
return Ant.OS.announcer.getMID()
post: (p, d, c, f) ->
q = _courrier.getMID()
_API.loading q, p
q = Ant.OS.announcer.getMID()
Ant.OS.API.loading q, p
$.ajax {
type: 'POST',
@ -188,14 +186,14 @@ self.OS.API =
}
#$.getJSON p, d
.done (data) ->
_API.loaded q, p, "OK"
Ant.OS.API.loaded q, p, "OK"
c(data)
.fail (e, s) ->
_API.loaded q, p, "FAIL"
Ant.OS.API.loaded q, p, "FAIL"
f(e, s)
blob: (p, c, f) ->
q = _courrier.getMID()
q = Ant.OS.announcer.getMID()
r = new XMLHttpRequest()
r.open "GET", p, true
r.responseType = "arraybuffer"
@ -203,20 +201,20 @@ self.OS.API =
r.onload = (e) ->
if @status is 200 and @readyState is 4
c @response
_API.loaded q, p, "OK"
Ant.OS.API.loaded q, p, "OK"
else
f e, @
_API.loaded q, p, "FAIL"
Ant.OS.API.loaded q, p, "FAIL"
_API.loading q, p
Ant.OS.API.loading q, p
r.send()
upload: (p, d, c, f) ->
q = _courrier.getMID()
q = Ant.OS.announcer.getMID()
#insert a temporal file selector
o = ($ '<input>').attr('type', 'file').css("display", "none")
o.change () ->
_API.loading q, p
Ant.OS.API.loading q, p
formd = new FormData()
formd.append 'path', d
# TODO: only one file is selected at this time
@ -230,11 +228,11 @@ self.OS.API =
processData: false,
}
.done (data) ->
_API.loaded q, p, "OK"
Ant.OS.API.loaded q, p, "OK"
c(data)
o.remove()
.fail (e, s) ->
_API.loaded q, p, "FAIL"
Ant.OS.API.loaded q, p, "FAIL"
f(e, s)
o.remove()
@ -252,115 +250,115 @@ self.OS.API =
o.remove()
systemConfig: ->
_API.request 'config', (result) ->
Ant.OS.API.request 'config', (result) ->
console.log result
loading: (q, p) ->
_courrier.trigger "loading", { id: q, data: { m: "#{p}", s: true }, name: "OS" }
Ant.OS.announcer.trigger "loading", { id: q, data: { m: "#{p}", s: true }, name: "OS" }
loaded: (q, p, m ) ->
_courrier.trigger "loaded", { id: q, data: { m: "#{m}: #{p}", s: false }, name: "OS" }
Ant.OS.announcer.trigger "loaded", { id: q, data: { m: "#{m}: #{p}", s: false }, name: "OS" }
get: (p, c, f, t) ->
conf =
type: 'GET',
url: p,
conf.dataType = t if t
q = _courrier.getMID()
_API.loading q, p
q = Ant.OS.announcer.getMID()
Ant.OS.API.loading q, p
$.ajax conf
.done (data) ->
_API.loaded q, p, "OK"
Ant.OS.API.loaded q, p, "OK"
c(data)
.fail (e, s) ->
_API.loaded q, p, "FAIL"
Ant.OS.API.loaded q, p, "FAIL"
f(e, s)
script: (p, c, f) ->
q = _courrier.getMID()
_API.loading q, p
q = Ant.OS.announcer.getMID()
Ant.OS.API.loading q, p
$.getScript p
.done (data) ->
_API.loaded q, p, "OK"
Ant.OS.API.loaded q, p, "OK"
c(data)
.fail (e, s) ->
_API.loaded q, p, "FAIL"
Ant.OS.API.loaded q, p, "FAIL"
f(e, s)
resource: (r, c, f) ->
path = "resources/#{r}"
_API.get path, c, f
Ant.OS.API.get path, c, f
libready: (l) ->
return _API.shared[l] || false
return Ant.OS.API.shared[l] || false
require: (l,f) ->
if not _API.shared[l]
if not Ant.OS.API.shared[l]
if l.match /^(https?:\/\/[^\s]+)/g
_API.script l, () ->
_API.shared[l] = true
_courrier.trigger "sharedlibraryloaded", l
Ant.OS.API.script l, () ->
Ant.OS.API.shared[l] = true
Ant.OS.announcer.trigger "sharedlibraryloaded", l
f() if f
, (e, s) ->
_courrier.oserror __("Cannot load 3rd library at: {0}", l), e, r
Ant.OS.announcer.oserror __("Cannot load 3rd library at: {0}", l), e, r
else
path = "os://scripts/"
js = "#{path}#{l}.js"
js.asFileHandler().onready (d) ->
_API.shared[l] = true
el = $ '<script>', { src: "#{_API.handler.get}/#{js}" }
js.asFileHandle().onready (d) ->
Ant.OS.API.shared[l] = true
el = $ '<script>', { src: "#{Ant.OS.API.handle.get}/#{js}" }
.appendTo 'head'
#load css file
css = "#{path}#{l}.css"
css.asFileHandler().onready (d) ->
el = $ '<link>', { rel: 'stylesheet', type: 'text/css', 'href': "#{_API.handler.get}/#{css}" }
css.asFileHandle().onready (d) ->
el = $ '<link>', { rel: 'stylesheet', type: 'text/css', 'href': "#{Ant.OS.API.handle.get}/#{css}" }
.appendTo 'head'
, () ->
console.log "loaded", l
_courrier.trigger "sharedlibraryloaded", l
Ant.OS.announcer.trigger "sharedlibraryloaded", l
f() if f
else
console.log l, "Library exist, no need to load"
f() if f
_courrier.trigger "sharedlibraryloaded", l
Ant.OS.announcer.trigger "sharedlibraryloaded", l
requires:(libs, f) ->
return f() unless libs.length > 0
_courrier.observable.one "sharedlibraryloaded", (l) ->
Ant.OS.announcer.observable.one "sharedlibraryloaded", (l) ->
libs.splice 0, 1
_API.requires libs, f
_API.require libs[0], null
Ant.OS.API.requires libs, f
Ant.OS.API.require libs[0], null
packages:
fetch: (f) ->
_API.handler.packages {
command: "list", args: { paths: (v for k, v of _OS.setting.system.pkgpaths) }
Ant.OS.API.handle.packages {
command: "list", args: { paths: (v for k, v of Ant.OS.setting.system.pkgpaths) }
}, f
cache: (f) ->
_API.handler.packages {
command: "cache", args: { paths: (v for k, v of _OS.setting.system.pkgpaths) }
Ant.OS.API.handle.packages {
command: "cache", args: { paths: (v for k, v of Ant.OS.setting.system.pkgpaths) }
}, f
setting: (f) ->
_API.handler.setting f
Ant.OS.API.handle.setting f
apigateway: (d, ws, c) ->
return _API.handler.apigateway d, ws, c
return Ant.OS.API.handle.apigateway d, ws, c
search: (text) ->
r = []
for k, v of _API.searchHandler
ret = _API.searchHandler[k](text)
for k, v of Ant.OS.API.searchHandle
ret = Ant.OS.API.searchHandle[k](text)
if ret.length > 0
ret.unshift { text: k, class: "search-header", dataid: "header" }
r = r.concat ret
return r
onsearch: (name, fn) ->
self.OS.API.searchHandler[name] = fn unless self.OS.API.searchHandler[name]
Ant.OS.API.searchHandle[name] = fn unless Ant.OS.API.searchHandle[name]
setLocale: (name, f) ->
path = "resources/languages/#{name}.json"
_API.get path, (d) ->
_OS.setting.system.locale = name
_API.lang = d
if f then f() else _courrier.trigger "systemlocalechange", name
Ant.OS.API.get path, (d) ->
Ant.OS.setting.system.locale = name
Ant.OS.API.lang = d
if f then f() else Ant.OS.announcer.trigger "systemlocalechange", name
, (e, s) ->
#_OS.setting.system.locale = "en_GB"
_courrier.oserror __("Language file {0} not found", path), e, s
#Ant.OS.setting.system.locale = "en_GB"
Ant.OS.announcer.oserror __("Language file {0} not found", path), e, s
f() if f
, "json"

View File

@ -18,8 +18,8 @@
'use strict'
#define the OS object
self = this
self.OS or=
Ant = this
Ant.OS or=
API: {}
GUI: {}
@ -31,33 +31,33 @@ self.OS or=
appearance: {}
VFS: {}
system: {}
courrier:
announcer:
observable: riot.observable()
quota: 0
listeners: {}
on: (e, f, a) ->
_courrier.listeners[a.pid] = [] unless _courrier.listeners[a.pid]
_courrier.listeners[a.pid].push { e: e, f: f }
_courrier.observable.on e, f
trigger: (e, d) -> _courrier.observable.trigger e, d
Ant.OS.announcer.listeners[a.pid] = [] unless Ant.OS.announcer.listeners[a.pid]
Ant.OS.announcer.listeners[a.pid].push { e: e, f: f }
Ant.OS.announcer.observable.on e, f
trigger: (e, d) -> Ant.OS.announcer.observable.trigger e, d
osfail: (m, e, s) ->
_courrier.ostrigger "fail", { m: m, e: e, s: s }
Ant.OS.announcer.ostrigger "fail", { m: m, e: e, s: s }
oserror: (m, e, s) ->
_courrier.ostrigger "error", { m: m, e: e, s: s }
Ant.OS.announcer.ostrigger "error", { m: m, e: e, s: s }
osinfo: (m) ->
_courrier.ostrigger "info", { m: m, e: null, s: null }
Ant.OS.announcer.ostrigger "info", { m: m, e: null, s: null }
ostrigger: (e, d) ->
_courrier.trigger e, { id: 0, data: d, name: "OS" }
Ant.OS.announcer.trigger e, { id: 0, data: d, name: "OS" }
unregister: (app) ->
return unless _courrier.listeners[app.pid] and _courrier.listeners[app.pid].length > 0
_courrier.observable.off i.e, i.f for i in _courrier.listeners[app.pid]
delete _courrier.listeners[app.pid]
# _courrier.listeners[app.pid]
return unless Ant.OS.announcer.listeners[app.pid] and Ant.OS.announcer.listeners[app.pid].length > 0
Ant.OS.announcer.observable.off i.e, i.f for i in Ant.OS.announcer.listeners[app.pid]
delete Ant.OS.announcer.listeners[app.pid]
# Ant.OS.announcer.listeners[app.pid]
getMID: () ->
_courrier.quota += 1
_courrier.quota
Ant.OS.announcer.quota += 1
Ant.OS.announcer.quota
register: (name, x) ->
if x.type is 3 then self.OS.GUI.subwindows[name] = x else _OS.APP[name] = x
if x.type is 3 then Ant.OS.GUI.subwindows[name] = x else Ant.OS.APP[name] = x
PM:
pidalloc: 0
@ -67,86 +67,86 @@ self.OS or=
#if it is single ton
# and a process is existing
# just return it
if cls.singleton and _PM.processes[app] and _PM.processes[app].length == 1
_PM.processes[app][0].show()
if cls.singleton and Ant.OS.PM.processes[app] and Ant.OS.PM.processes[app].length == 1
Ant.OS.PM.processes[app][0].show()
else
_PM.processes[app] = [] if not _PM.processes[app]
Ant.OS.PM.processes[app] = [] if not Ant.OS.PM.processes[app]
obj = new cls(args)
obj.birth = (new Date).getTime()
_PM.pidalloc++
obj.pid = _PM.pidalloc
_PM.processes[app].push obj
if cls.type is 1 then _GUI.dock obj, cls.meta else _GUI.attachservice obj
Ant.OS.PM.pidalloc++
obj.pid = Ant.OS.PM.pidalloc
Ant.OS.PM.processes[app].push obj
if cls.type is 1 then Ant.OS.GUI.dock obj, cls.meta else Ant.OS.GUI.attachservice obj
if cls.type is 2
_courrier.trigger "srvroutineready", app
Ant.OS.announcer.trigger "srvroutineready", app
if cls.dependencies
libs = (v for v in cls.dependencies)
_API.requires libs, f
Ant.OS.API.requires libs, f
else
f()
appByPid: (pid) ->
app = undefined
find = (l) ->
return a for a in l when a.pid is pid
for k, v of _PM.processes
for k, v of Ant.OS.PM.processes
app = find v
break if app
app
kill: (app) ->
return if not app.name or not _PM.processes[app.name]
return if not app.name or not Ant.OS.PM.processes[app.name]
i = _PM.processes[app.name].indexOf app
i = Ant.OS.PM.processes[app.name].indexOf app
if i >= 0
if _OS.APP[app.name].type == 1 then _GUI.undock app else _GUI.detachservice app
_courrier.unregister app
delete _PM.processes[app.name][i]
_PM.processes[app.name].splice i, 1
if Ant.OS.APP[app.name].type == 1 then Ant.OS.GUI.undock app else Ant.OS.GUI.detachservice app
Ant.OS.announcer.unregister app
delete Ant.OS.PM.processes[app.name][i]
Ant.OS.PM.processes[app.name].splice i, 1
killAll: (app, force) ->
return unless _PM.processes[app]
a.quit(force) for a in _PM.processes[app]
return unless Ant.OS.PM.processes[app]
a.quit(force) for a in Ant.OS.PM.processes[app]
cleanup: ->
console.log "Clean up system"
_PM.killAll a, true for a, v of _PM.processes
_courrier.observable.off("*") if _courrier.observable
Ant.OS.PM.killAll a, true for a, v of Ant.OS.PM.processes
Ant.OS.announcer.observable.off("*") if Ant.OS.announcer.observable
$(window).off('keydown')
($ "#workspace").off("mouseover")
delete _courrier.observable
delete Ant.OS.announcer.observable
($ "#wrapper").empty()
_GUI.clearTheme()
_courrier.observable = riot.observable()
_courrier.quota = 0
_OS.APP = {}
_OS.setting =
Ant.OS.GUI.clearTheme()
Ant.OS.announcer.observable = riot.observable()
Ant.OS.announcer.quota = 0
Ant.OS.APP = {}
Ant.OS.setting =
user: {}
applications: {}
desktop: {}
appearance: {}
VFS: {}
system: {}
_PM.processes = {}
_PM.pidalloc = 0
Ant.OS.PM.processes = {}
Ant.OS.PM.pidalloc = 0
boot: ->
#first login
console.log "Booting sytem"
_API.handler.auth (d) ->
Ant.OS.API.handle.auth (d) ->
# in case someone call it more than once :)
if d.error
# show login screen
_GUI.login()
Ant.OS.GUI.login()
else
# startX :)
_GUI.startAntOS d.result
Ant.OS.GUI.startAntOS d.result
cleanupHandlers: {}
cleanupHandles: {}
exit: ->
#do clean up first
f() for n, f of _OS.cleanupHandlers
_API.handler.setting (r) ->
_OS.cleanup()
_API.handler.logout()
f() for n, f of Ant.OS.cleanupHandles
Ant.OS.API.handle.setting (r) ->
Ant.OS.cleanup()
Ant.OS.API.handle.logout()
onexit: (n, f) ->
self.OS.cleanupHandlers[n] = f unless self.OS.cleanupHandlers[n]
Ant.OS.cleanupHandles[n] = f unless Ant.OS.cleanupHandles[n]

View File

@ -20,19 +20,19 @@ class DB
constructor: (@table) ->
save: (d, f) ->
_API.handler.dbquery "save", { table: @table, data: d }, f
Ant.OS.API.handle.dbquery "save", { table: @table, data: d }, f
delete: (c, f) ->
rq = { table: @table }
return ( _courrier.oserror __("VDB Unknown condition for delete command"),
(_API.throwe "OS.DB"), c ) unless c and c isnt ""
return ( Ant.OS.announcer.oserror __("VDB Unknown condition for delete command"),
(Ant.OS.API.throwe "OS.DB"), c ) unless c and c isnt ""
if isNaN c
rq.cond = c
else
rq.id = c
_API.handler.dbquery "delete", rq, f
Ant.OS.API.handle.dbquery "delete", rq, f
get: (id, f) ->
_API.handler.dbquery "get", { table: @table, id: id }, f
Ant.OS.API.handle.dbquery "get", { table: @table, id: id }, f
find: (cond, f) ->
_API.handler.dbquery "select", { table: @table, cond: cond }, f
Ant.OS.API.handle.dbquery "select", { table: @table, cond: cond }, f
self.OS.API.DB = DB
Ant.OS.API.DB = DB

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
self.OS.GUI =
Ant.OS.GUI =
subwindows: new Object()
dialog: undefined
fullscreen: false
@ -37,13 +37,13 @@ self.OS.GUI =
dataid: "sys-apps"
iconclass: "fa fa-adn",
onmenuselect: (d) ->
_GUI.launch d.item.data.app
Ant.OS.GUI.launch d.item.data.app
}
],
onmenuselect: (d) ->
return _OS.exit() if d.item.data.dataid is "sys-logout"
return _GUI.toggleFullscreen() if d.item.data.dataid is "os-fullsize"
_GUI.launch d.item.data.app unless d.item.data.dataid
return Ant.OS.exit() if d.item.data.dataid is "sys-logout"
return Ant.OS.GUI.toggleFullscreen() if d.item.data.dataid is "os-fullsize"
Ant.OS.GUI.launch d.item.data.app unless d.item.data.dataid
}
]
htmlToScheme: (html, app, parent) ->
@ -56,58 +56,58 @@ self.OS.GUI =
app.main()
app.show()
loadScheme: (path, app, parent) ->
path.asFileHandler().read (x) ->
path.asFileHandle().read (x) ->
return null unless x
_GUI.htmlToScheme x, app, parent
Ant.OS.GUI.htmlToScheme x, app, parent
#, (e, s) ->
# _courrier.osfail "Cannot load scheme file: #{path} for #{app.name} (#{app.pid})", e, s
# Ant.OS.announcer.osfail "Cannot load scheme file: #{path} for #{app.name} (#{app.pid})", e, s
clearTheme: () ->
$ "head link#ostheme"
.attr "href", ""
loadTheme: (name, force) ->
_GUI.clearTheme() if force
Ant.OS.GUI.clearTheme() if force
path = "resources/themes/#{name}/#{name}.css"
$ "head link#ostheme"
.attr "href", path
pushServices: (srvs) ->
return unless srvs.length > 0
_courrier.observable.one "srvroutineready", () ->
Ant.OS.announcer.observable.one "srvroutineready", () ->
srvs.splice 0, 1
_GUI.pushServices srvs
_GUI.pushService srvs[0]
Ant.OS.GUI.pushServices srvs
Ant.OS.GUI.pushService srvs[0]
openDialog: (d, f, title, data) ->
if _GUI.dialog
_GUI.dialog.show()
if Ant.OS.GUI.dialog
Ant.OS.GUI.dialog.show()
return
if not _GUI.subwindows[d]
ex = _API.throwe "Dialog"
return _courrier.oserror __("Dialog {0} not found", d), ex, null
_GUI.dialog = new _GUI.subwindows[d]()
_GUI.dialog.parent = _GUI
_GUI.dialog.handler = f
_GUI.dialog.pid = -1
_GUI.dialog.data = data
_GUI.dialog.title = title
_GUI.dialog.init()
if not Ant.OS.GUI.subwindows[d]
ex = Ant.OS.API.throwe "Dialog"
return Ant.OS.announcer.oserror __("Dialog {0} not found", d), ex, null
Ant.OS.GUI.dialog = new Ant.OS.GUI.subwindows[d]()
Ant.OS.GUI.dialog.parent = Ant.OS.GUI
Ant.OS.GUI.dialog.handle = f
Ant.OS.GUI.dialog.pid = -1
Ant.OS.GUI.dialog.data = data
Ant.OS.GUI.dialog.title = title
Ant.OS.GUI.dialog.init()
pushService: (ph) ->
arr = ph.split "/"
srv = arr[1]
app = arr[0]
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
_GUI.loadApp app,
return Ant.OS.PM.createProcess srv, Ant.OS.APP[srv] if Ant.OS.APP[srv]
Ant.OS.GUI.loadApp app,
(a) ->
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
return Ant.OS.PM.createProcess srv, Ant.OS.APP[srv] if Ant.OS.APP[srv]
(e, s) ->
_courrier.trigger "srvroutineready", srv
_courrier.osfail __("Cannot read service script: {0}", srv), e, s
Ant.OS.announcer.trigger "srvroutineready", srv
Ant.OS.announcer.osfail __("Cannot read service script: {0}", srv), e, s
appsByMime: (mime) ->
metas = ( v for k, v of _OS.setting.system.packages when v and v.app )
metas = ( v for k, v of Ant.OS.setting.system.packages when v and v.app )
mimes = ( m.mimes for m in metas when m)
apps = []
# search app by mimes
@ -120,56 +120,56 @@ self.OS.GUI =
return false
return false
catch e
_courrier.osfail __("Error find app by mimes {0}", mime), e, mime
Ant.OS.announcer.osfail __("Error find app by mimes {0}", mime), e, mime
( f m, i if m ) for m, i in mimes
return apps
appsWithServices: () ->
o = {}
o[k] = v for k, v of _OS.setting.system.packages when v and v.services and v.services.length > 0
o[k] = v for k, v of Ant.OS.setting.system.packages when v and v.services and v.services.length > 0
o
openWith: (it) ->
return unless it
return _GUI.launch it.app if it.type is "app" and it.app
return _courrier.osinfo __("Application {0} is not executable", it.text) if it.type is "app"
apps = _GUI.appsByMime ( if it.type is "dir" then "dir" else it.mime )
return _courrier.osinfo __("No application available to open {0}", it.filename) if apps.length is 0
return _GUI.launch apps[0].app, [it.path] if apps.length is 1
return Ant.OS.GUI.launch it.app if it.type is "app" and it.app
return Ant.OS.announcer.osinfo __("Application {0} is not executable", it.text) if it.type is "app"
apps = Ant.OS.GUI.appsByMime ( if it.type is "dir" then "dir" else it.mime )
return Ant.OS.announcer.osinfo __("No application available to open {0}", it.filename) if apps.length is 0
return Ant.OS.GUI.launch apps[0].app, [it.path] if apps.length is 1
list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps )
_GUI.openDialog "SelectionDialog", ( d ) ->
_GUI.launch d.text, [it.path]
Ant.OS.GUI.openDialog "SelectionDialog", ( d ) ->
Ant.OS.GUI.launch d.text, [it.path]
, __("Open with"), list
forceLaunch: (app, args) ->
console.warn "This method is used for developing only, please use the launch method instead"
_GUI.unloadApp app
_GUI.launch app, args
Ant.OS.GUI.unloadApp app
Ant.OS.GUI.launch app, args
unloadApp: (app) ->
_PM.killAll app, true
($ _OS.APP[app].style).remove() if _OS.APP[app] and _OS.APP[app].style
delete _OS.APP[app]
Ant.OS.PM.killAll app, true
($ Ant.OS.APP[app].style).remove() if Ant.OS.APP[app] and Ant.OS.APP[app].style
delete Ant.OS.APP[app]
loadApp: (app, ok, err) ->
path = "os://packages/#{app}"
path = _OS.setting.system.packages[app].path if _OS.setting.system.packages[app].path
path = Ant.OS.setting.system.packages[app].path if Ant.OS.setting.system.packages[app].path
js = path + "/main.js"
js.asFileHandler().read (d) ->
js.asFileHandle().read (d) ->
# load app meta data
"#{path}/package.json".asFileHandler().read (data) ->
"#{path}/package.json".asFileHandle().read (data) ->
data.path = path
_OS.APP[app].meta = data if _OS.APP[app]
_OS.APP[v].meta = data for v in data.services if data.services
Ant.OS.APP[app].meta = data if Ant.OS.APP[app]
Ant.OS.APP[v].meta = data for v in data.services if data.services
#load css file
css = "#{path}/main.css"
css.asFileHandler().onready (d) ->
css.asFileHandle().onready (d) ->
stamp = (new Date).timestamp()
el = $ '<link>', { rel: 'stylesheet', type: 'text/css', 'href': "#{_API.handler.get}/#{css}?stamp=#{stamp}" }
el = $ '<link>', { rel: 'stylesheet', type: 'text/css', 'href': "#{Ant.OS.API.handle.get}/#{css}?stamp=#{stamp}" }
.appendTo 'head'
_OS.APP[app].style = el[0] if _OS.APP[app]
Ant.OS.APP[app].style = el[0] if Ant.OS.APP[app]
ok app
, () ->
#launch
@ -178,16 +178,16 @@ self.OS.GUI =
#ok app
, "script"
launch: (app, args) ->
if not _OS.APP[app]
if not Ant.OS.APP[app]
# first load it
_GUI.loadApp app,
Ant.OS.GUI.loadApp app,
(a)->
_PM.createProcess a, _OS.APP[a], args
Ant.OS.PM.createProcess a, Ant.OS.APP[a], args
, (e, s) ->
else
# now launch it
if _OS.APP[app]
_PM.createProcess app, _OS.APP[app], args
if Ant.OS.APP[app]
Ant.OS.PM.createProcess app, Ant.OS.APP[app], args
dock: (app, meta) ->
# dock an application to a dock
@ -214,7 +214,7 @@ self.OS.GUI =
toggleFullscreen: () ->
el = ($ "body")[0]
if _GUI.fullscreen
if Ant.OS.GUI.fullscreen
return document.exitFullscreen() if document.exitFullscreen
return document.mozCancelFullScreen() if document.mozCancelFullScreen
return document.webkitExitFullscreen() if document.webkitExitFullscreen
@ -235,13 +235,13 @@ self.OS.GUI =
detachservice: (srv) ->
($ "#syspanel")[0].detachservice srv
bindContextMenu: (event) ->
handler = (e) ->
if e.contextmenuHandler
e.contextmenuHandler event, ($ "#contextmenu")[0]
handle = (e) ->
if e.contextmenuHandle
e.contextmenuHandle event, ($ "#contextmenu")[0]
else
p = $(e).parent().get(0)
handler p if p isnt ($ "#workspace").get(0)
handler event.target
handle p if p isnt ($ "#workspace").get(0)
handle event.target
event.preventDefault()
bindKey: (k, f) ->
@ -249,14 +249,14 @@ self.OS.GUI =
return unless arr.length is 2
fnk = arr[0].toUpperCase()
c = arr[1].toUpperCase()
return unless _GUI.shortcut[fnk]
_GUI.shortcut[fnk][c] = f
return unless Ant.OS.GUI.shortcut[fnk]
Ant.OS.GUI.shortcut[fnk][c] = f
wallpaper: (obj) ->
if obj
_OS.setting.appearance.wp = obj
wp = _OS.setting.appearance.wp
$("body").css("background-image", "url(#{_API.handler.get}/#{wp.url})" )
Ant.OS.setting.appearance.wp = obj
wp = Ant.OS.setting.appearance.wp
$("body").css("background-image", "url(#{Ant.OS.API.handle.get}/#{wp.url})" )
.css("background-size", wp.size)
.css("background-repeat", wp.repeat)
@ -288,12 +288,12 @@ self.OS.GUI =
initDM: ->
# check login first
_API.resource "schemes/dm.html", (x) ->
Ant.OS.API.resource "schemes/dm.html", (x) ->
return null unless x
scheme = $.parseHTML x
($ "#wrapper").append scheme
_courrier.observable.one "sysdockloaded", () ->
Ant.OS.announcer.observable.one "sysdockloaded", () ->
($ window).bind 'keydown', (event) ->
dock = ($ "#sysdock")[0]
return unless dock
@ -313,9 +313,9 @@ self.OS.GUI =
return unless fnk
r = if app then app.shortcut fnk, c, event else true
return event.preventDefault() if not r
return unless _GUI.shortcut[fnk]
return unless _GUI.shortcut[fnk][c]
_GUI.shortcut[fnk][c](event)
return unless Ant.OS.GUI.shortcut[fnk]
return unless Ant.OS.GUI.shortcut[fnk][c]
Ant.OS.GUI.shortcut[fnk][c](event)
event.preventDefault()
# system menu and dock
riot.mount ($ "#syspanel", $ "#wrapper")
@ -323,24 +323,24 @@ self.OS.GUI =
riot.mount ($ "#systooltip", $ "#wrapper")
# context menu
riot.mount ($ "#contextmenu", $ "#wrapper")
($ "#workspace").contextmenu (e) -> _GUI.bindContextMenu e
($ "#workspace").contextmenu (e) -> Ant.OS.GUI.bindContextMenu e
# tooltip
($ "#workspace").mouseover (e) ->
el = $(e.target).closest "[tooltip]"
return unless el.length > 0
_GUI.showTooltip el, ($(el).attr "tooltip"), e
Ant.OS.GUI.showTooltip el, ($(el).attr "tooltip"), e
# desktop default file manager
desktop = $ "#desktop"
fp = _OS.setting.desktop.path.asFileHandler()
fp = Ant.OS.setting.desktop.path.asFileHandle()
desktop[0].fetch = () ->
fn = () ->
fp = _OS.setting.desktop.path.asFileHandler()
fp = Ant.OS.setting.desktop.path.asFileHandle()
fp.read (d) ->
return _courrier.osfail d.error, (_API.throwe "OS.VFS"), d.error if d.error
return Ant.OS.announcer.osfail d.error, (Ant.OS.API.throwe "OS.VFS"), d.error if d.error
items = []
$.each d.result, (i, v) ->
return if v.filename[0] is '.' and not _OS.setting.desktop.showhidden
return if v.filename[0] is '.' and not Ant.OS.setting.desktop.showhidden
v.text = v.filename
#v.text = v.text.substring(0,9) + "..." ifv.text.length > 10
v.iconclass = v.type
@ -353,14 +353,14 @@ self.OS.GUI =
, ( e ) -> # try to create the path
console.log "#{fp.path} not found"
name = fp.basename
fp.parent().asFileHandler().mk name, (r) ->
ex = _API.throwe "OS.VFS"
if r.error then _courrier.osfail d.error, ex, d.error else fn()
fp.parent().asFileHandle().mk name, (r) ->
ex = Ant.OS.API.throwe "OS.VFS"
if r.error then Ant.OS.announcer.osfail d.error, ex, d.error else fn()
desktop[0].ready = (e) ->
e.observable = _courrier
e.observable = Ant.OS.announcer
window.onresize = () ->
_courrier.trigger "desktopresize"
Ant.OS.announcer.trigger "desktopresize"
e.refresh()
desktop[0].set "onlistselect", (d) ->
@ -369,7 +369,7 @@ self.OS.GUI =
desktop[0].set "onlistdbclick", ( d ) ->
($ "#sysdock").get(0).set "selectedApp", null
it = desktop[0].get "selected"
_GUI.openWith it
Ant.OS.GUI.openWith it
#($ "#workingenv").on "click", (e) ->
# desktop[0].set "selected", -1
@ -380,33 +380,33 @@ self.OS.GUI =
($ "#sysdock").get(0).set "selectedApp", null
#console.log "desktop clicked"
desktop[0].contextmenuHandler = (e, m) ->
desktop[0].contextmenuHandle = (e, m) ->
desktop[0].set "selected", -1 if e.target is desktop[0]
($ "#sysdock").get(0).set "selectedApp", null
menu = [
{ text: __("Open"), dataid: "desktop-open" },
{ text: __("Refresh"), dataid: "desktop-refresh" }
]
menu = menu.concat ( v for k, v of _OS.setting.desktop.menu)
menu = menu.concat ( v for k, v of Ant.OS.setting.desktop.menu)
m.set "items", menu
m.set "onmenuselect", (evt) ->
switch evt.item.data.dataid
when "desktop-open"
it = desktop[0].get "selected"
return _GUI.openWith it if it
it = _OS.setting.desktop.path.asFileHandler()
return Ant.OS.GUI.openWith it if it
it = Ant.OS.setting.desktop.path.asFileHandle()
it.mime = "dir"
_GUI.openWith it
Ant.OS.GUI.openWith it
when "desktop-refresh"
desktop[0].fetch()
else
_GUI.launch evt.item.data.app, evt.item.data.args if evt.item.data.app
Ant.OS.GUI.launch evt.item.data.app, evt.item.data.args if evt.item.data.app
m.show(e)
desktop[0].fetch()
_courrier.observable.on "VFS", (d) ->
Ant.OS.announcer.observable.on "VFS", (d) ->
desktop[0].fetch() if d.data.file.hash() is fp.hash() or d.data.file.parent().hash() is fp.hash()
_courrier.ostrigger "desktoploaded"
Ant.OS.announcer.ostrigger "desktoploaded"
# mount it
riot.mount desktop
, (e, s) ->
@ -416,29 +416,29 @@ self.OS.GUI =
($ "#desktop")[0].fetch()
refreshSystemMenu: () ->
_GUI.SYS_MENU[0].child.length = 1
_GUI.SYS_MENU[0].child[0].child.length = 0
_GUI.SYS_MENU[0].child[0].child.push v for k, v of _OS.setting.system.packages when (v and v.app)
_GUI.SYS_MENU[0].child.push v for k, v of _OS.setting.system.menu
_GUI.SYS_MENU[0].child.push
Ant.OS.GUI.SYS_MENU[0].child.length = 1
Ant.OS.GUI.SYS_MENU[0].child[0].child.length = 0
Ant.OS.GUI.SYS_MENU[0].child[0].child.push v for k, v of Ant.OS.setting.system.packages when (v and v.app)
Ant.OS.GUI.SYS_MENU[0].child.push v for k, v of Ant.OS.setting.system.menu
Ant.OS.GUI.SYS_MENU[0].child.push
text: "__(Toggle Full screen)",
dataid: "os-fullsize",
iconclass: "fa fa-tv"
_GUI.SYS_MENU[0].child.push
Ant.OS.GUI.SYS_MENU[0].child.push
text: "__(Log out)",
dataid: "sys-logout",
iconclass: "fa fa-user-times"
($ "[data-id = 'os_menu']", "#syspanel")[0].update()
buildSystemMenu: () ->
($ "[data-id = 'os_menu']", "#syspanel")[0].set "items", _GUI.SYS_MENU
($ "[data-id = 'os_menu']", "#syspanel")[0].set "items", Ant.OS.GUI.SYS_MENU
#console.log menu
mkdialog: (conf) ->
return new _GUI.BasicDialog conf.name, conf.layout
return new Ant.OS.GUI.BasicDialog conf.name, conf.layout
login: () ->
_API.resource "schemes/login.html", (x) ->
Ant.OS.API.resource "schemes/login.html", (x) ->
return null unless x
scheme = $.parseHTML x
($ "#wrapper").append scheme
@ -446,8 +446,8 @@ self.OS.GUI =
data =
username: ($ "#txtuser").val(),
password: ($ "#txtpass").val()
_API.handler.login data, (d) ->
if d.error then ($ "#login_error").html d.error else _GUI.startAntOS d.result
Ant.OS.API.handle.login data, (d) ->
if d.error then ($ "#login_error").html d.error else Ant.OS.GUI.startAntOS d.result
($ "#txtpass").keyup (e) ->
($ "#btlogin").click() if e.which is 13
, (e, s) ->
@ -455,21 +455,21 @@ self.OS.GUI =
startAntOS: (conf) ->
# clean up things
_OS.cleanup()
Ant.OS.cleanup()
# get setting from conf
_OS.systemSetting conf
#console.log _OS.setting
Ant.OS.systemSetting conf
#console.log Ant.OS.setting
# load theme
_GUI.loadTheme _OS.setting.appearance.theme
_GUI.wallpaper()
_courrier.observable.one "syspanelloaded", () ->
Ant.OS.GUI.loadTheme Ant.OS.setting.appearance.theme
Ant.OS.GUI.wallpaper()
Ant.OS.announcer.observable.one "syspanelloaded", () ->
# TODO load packages list then build system menu
_courrier.observable.on "systemlocalechange", (name) ->
Ant.OS.announcer.observable.on "systemlocalechange", (name) ->
($ "#syspanel")[0].update()
_API.packages.cache (ret) ->
Ant.OS.API.packages.cache (ret) ->
if ret.result
_API.packages.fetch (r) ->
Ant.OS.API.packages.fetch (r) ->
if r.result
for k, v of r.result
v.text = v.name
@ -478,14 +478,14 @@ self.OS.GUI =
v.mime = "antos/app"
v.icon = "#{v.path}/#{v.icon}" if v.icon
v.iconclass = "fa fa-adn" unless v.iconclass or v.icon
_OS.setting.system.packages = if r.result then r.result else
_GUI.refreshSystemMenu()
_GUI.buildSystemMenu()
Ant.OS.setting.system.packages = if r.result then r.result else
Ant.OS.GUI.refreshSystemMenu()
Ant.OS.GUI.buildSystemMenu()
# push startup services
# TODO: get services list from user setting
_GUI.pushServices (v for v in _OS.setting.system.startup.services)
(_GUI.launch a) for a in _OS.setting.system.startup.apps
#_GUI.launch "DummyApp"
Ant.OS.GUI.pushServices (v for v in Ant.OS.setting.system.startup.services)
(Ant.OS.GUI.launch a) for a in Ant.OS.setting.system.startup.apps
#Ant.OS.GUI.launch "DummyApp"
# initDM
_API.setLocale _OS.setting.system.locale, () ->
_GUI.initDM()
Ant.OS.API.setLocale Ant.OS.setting.system.locale, () ->
Ant.OS.GUI.initDM()

View File

@ -1,125 +0,0 @@
# 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/.
self.OS.API.HOST = self.location.hostname+ (if self.location.port then":#{self.location.port}" else "")
self.OS.API.REST = "#{self.location.protocol}//#{self.OS.API.HOST}"
_REST = self.OS.API.REST
_HOST = self.OS.API.HOST
self.OS.API.handler =
# get file, require authentification
get: "#{_REST}/VFS/get"
# get shared file with publish
shared: "#{_REST}/VFS/shared"
scandir: (p, c ) ->
path = "#{_REST}/VFS/scandir"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail __("Fail to scan directory: {0}", p), e, s
mkdir: (p, c ) ->
path = "#{_REST}/VFS/mkdir"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail __("Fail to create directory: {0}", p), e, s
sharefile: (p, pub , c) ->
path = "#{_REST}/VFS/publish"
_API.post path, { path: p , publish: pub }, c, (e, s) ->
_courrier.osfail __("Fail to publish file: {0}", p), e, s
fileinfo: (p, c) ->
path = "#{_REST}/VFS/fileinfo"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail __("Fail to get file meta data: {0}", p), e, s
readfile: (p, c, t) ->
path = "#{_REST}/VFS/get/"
_API.get path + p, c, (e, s) ->
_courrier.osfail __("Fail to read file: {0}", p), e, s
, t
move: (s, d, c) ->
path = "#{_REST}/VFS/move"
_API.post path, { src: s, dest: d }, c, (e, s) ->
_courrier.osfail __("Fail to move file: {0} -> {1}", s, d), e, s
delete: (p , c) ->
path = "#{_REST}/VFS/delete"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail __("Fail to delete: {0}", p), e, s
fileblob: (p, c) ->
path = "#{_REST}/VFS/get/"
_API.blob path + p, c, (e, s) ->
_courrier.osfail "Fail to read file: #{p}", e, s
packages: (d, c) ->
path = "#{_REST}/system/packages"
_API.post path, d, c, (e, s) ->
_courrier.osfail __("Fail to {0} package", d.command), e, s
upload: (d, c) ->
path = "#{_REST}/VFS/upload"
_API.upload path, d, c, (e, s) ->
_courrier.osfail __("Fail to upload file to: {0}", d), e, s
write: (p, d , c) ->
path = "#{_REST}/VFS/write"
_API.post path, { path: p, data: d }, c, (e, s) ->
_courrier.osfail __("Fail to write to file: {0}", p), e, s
scanapp: (p, c ) ->
path = "#{_REST}/system/application"
apigateway: (d, ws, c) ->
if ws
path = "#{_HOST}/system/apigateway?ws=1"
proto = if window.location.protocol is "https:" then "wss://" else "ws://"
socket = new WebSocket proto + path
if c then c(socket)
return socket
else
path = "#{_REST}/system/apigateway?ws=0"
_API.post path, d, c, (e, s) ->
_courrier.osfail __("Fail to invoke gateway api"), e, s
auth: (c) ->
p = "#{_REST}/user/auth"
_API.post p, {}, c, (e, s) ->
console.log e, s
alert __("Resource not found: {0}", p)
login: (d, c) ->
p = "#{_REST}/user/login"
_API.post p, d, c, () ->
alert __("Resource not found: {0}", p)
logout: () ->
p = "#{_REST}/user/logout"
_API.post p, {}, (d) ->
_OS.boot()
, () ->
alert __("Resource not found: {0}", p)
setting: (f) ->
p = "#{_REST}/system/settings"
_API.post p, _OS.setting, (d) ->
_courrier.oserror __("Cannot save system setting"), d.error if d.error
f(d) if f
, (e, s) ->
m = __("Fail to make request: {0}", p)
_courrier.osfail m , e, s
f({ error: m }) if f
dbquery: (cmd, d, c) ->
path = "#{_REST}/VDB/#{cmd}"
_API.post path, d, c, (e, s) ->
_courrier.osfail __("Fail to query data from database: {0}", path), e, s

View File

@ -0,0 +1,123 @@
# 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/.
Ant.OS.API.HOST = Ant.location.hostname+ (if Ant.location.port then":#{Ant.location.port}" else "")
Ant.OS.API.REST = "#{Ant.location.protocol}//#{Ant.OS.API.HOST}"
Ant.OS.API.handle =
# get file, require authentification
get: "#{Ant.OS.API.REST}/VFS/get"
# get shared file with publish
shared: "#{Ant.OS.API.REST}/VFS/shared"
scandir: (p, c ) ->
path = "#{Ant.OS.API.REST}/VFS/scandir"
Ant.OS.API.post path, { path: p }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to scan directory: {0}", p), e, s
mkdir: (p, c ) ->
path = "#{Ant.OS.API.REST}/VFS/mkdir"
Ant.OS.API.post path, { path: p }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to create directory: {0}", p), e, s
sharefile: (p, pub , c) ->
path = "#{Ant.OS.API.REST}/VFS/publish"
Ant.OS.API.post path, { path: p , publish: pub }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to publish file: {0}", p), e, s
fileinfo: (p, c) ->
path = "#{Ant.OS.API.REST}/VFS/fileinfo"
Ant.OS.API.post path, { path: p }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to get file meta data: {0}", p), e, s
readfile: (p, c, t) ->
path = "#{Ant.OS.API.REST}/VFS/get/"
Ant.OS.API.get path + p, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to read file: {0}", p), e, s
, t
move: (s, d, c) ->
path = "#{Ant.OS.API.REST}/VFS/move"
Ant.OS.API.post path, { src: s, dest: d }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to move file: {0} -> {1}", s, d), e, s
delete: (p , c) ->
path = "#{Ant.OS.API.REST}/VFS/delete"
Ant.OS.API.post path, { path: p }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to delete: {0}", p), e, s
fileblob: (p, c) ->
path = "#{Ant.OS.API.REST}/VFS/get/"
Ant.OS.API.blob path + p, c, (e, s) ->
Ant.OS.announcer.osfail "Fail to read file: #{p}", e, s
packages: (d, c) ->
path = "#{Ant.OS.API.REST}/system/packages"
Ant.OS.API.post path, d, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to {0} package", d.command), e, s
upload: (d, c) ->
path = "#{Ant.OS.API.REST}/VFS/upload"
Ant.OS.API.upload path, d, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to upload file to: {0}", d), e, s
write: (p, d , c) ->
path = "#{Ant.OS.API.REST}/VFS/write"
Ant.OS.API.post path, { path: p, data: d }, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to write to file: {0}", p), e, s
scanapp: (p, c ) ->
path = "#{Ant.OS.API.REST}/system/application"
apigateway: (d, ws, c) ->
if ws
path = "#{Ant.OS.API.HOST}/system/apigateway?ws=1"
proto = if window.location.protocol is "https:" then "wss://" else "ws://"
socket = new WebSocket proto + path
if c then c(socket)
return socket
else
path = "#{Ant.OS.API.REST}/system/apigateway?ws=0"
Ant.OS.API.post path, d, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to invoke gateway api"), e, s
auth: (c) ->
p = "#{Ant.OS.API.REST}/user/auth"
Ant.OS.API.post p, {}, c, (e, s) ->
console.log e, s
alert __("Resource not found: {0}", p)
login: (d, c) ->
p = "#{Ant.OS.API.REST}/user/login"
Ant.OS.API.post p, d, c, () ->
alert __("Resource not found: {0}", p)
logout: () ->
p = "#{Ant.OS.API.REST}/user/logout"
Ant.OS.API.post p, {}, (d) ->
Ant.OS.boot()
, () ->
alert __("Resource not found: {0}", p)
setting: (f) ->
p = "#{Ant.OS.API.REST}/system/settings"
Ant.OS.API.post p, Ant.OS.setting, (d) ->
Ant.OS.announcer.oserror __("Cannot save system setting"), d.error if d.error
f(d) if f
, (e, s) ->
m = __("Fail to make request: {0}", p)
Ant.OS.announcer.osfail m , e, s
f({ error: m }) if f
dbquery: (cmd, d, c) ->
path = "#{Ant.OS.API.REST}/VDB/#{cmd}"
Ant.OS.API.post path, d, c, (e, s) ->
Ant.OS.announcer.osfail __("Fail to query data from database: {0}", path), e, s

View File

@ -15,9 +15,9 @@
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
self.OS.API.handler =
Ant.OS.API.handle =
scandir: (p, c ) ->
path = 'resources/jsons/scandir.json'
_API.get path , c, (e, s) ->
_courrier.osfail "System fall: Cannot read #{path}", e, s
Ant.OS.API.get path , c, (e, s) ->
Ant.OS.announcer.osfail "System fall: Cannot read #{path}", e, s

View File

@ -16,32 +16,32 @@
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
self.OS.systemSetting = (conf) ->
_OS.setting.desktop = conf.desktop if conf.desktop
_OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.appearance.wp = {
Ant.OS.setting.desktop = conf.desktop if conf.desktop
Ant.OS.setting.applications = conf.applications if conf.applications
Ant.OS.setting.appearance = conf.appearance if conf.appearance
Ant.OS.setting.appearance.wp = {
url: "os://resources/themes/system/wp/wp2.jpg",
size: "cover",
repeat: "repeat"
} unless _OS.setting.appearance.wp
_OS.setting.appearance.wps = [] unless _OS.setting.appearance.wps
_OS.setting.applications = {} unless _OS.setting.applications
_OS.setting.user = conf.user
_OS.setting.VFS = conf.VFS if conf.VFS
_OS.setting.desktop.path = "home://.desktop" unless _OS.setting.desktop.path
_OS.setting.desktop.menu = {} unless _OS.setting.desktop.menu
_OS.setting.VFS.mountpoints = [
} unless Ant.OS.setting.appearance.wp
Ant.OS.setting.appearance.wps = [] unless Ant.OS.setting.appearance.wps
Ant.OS.setting.applications = {} unless Ant.OS.setting.applications
Ant.OS.setting.user = conf.user
Ant.OS.setting.VFS = conf.VFS if conf.VFS
Ant.OS.setting.desktop.path = "home://.desktop" unless Ant.OS.setting.desktop.path
Ant.OS.setting.desktop.menu = {} unless Ant.OS.setting.desktop.menu
Ant.OS.setting.VFS.mountpoints = [
#TODO: multi app try to write to this object, it neet to be cloned
{ text: "__(Applications)", path: 'app://', iconclass: "fa fa-adn", type: "app" },
{ text: "__(Home)", path: 'home://', iconclass: "fa fa-home", type: "fs" },
{ text: "__(Desktop)", path: _OS.setting.desktop.path , iconclass: "fa fa-desktop", type: "fs" },
{ text: "__(Desktop)", path: Ant.OS.setting.desktop.path , iconclass: "fa fa-desktop", type: "fs" },
{ text: "__(OS)", path: 'os://', iconclass: "fa fa-inbox", type: "fs" },
{ text: "__(Google Drive)", path: 'gdv://', iconclass: "fa fa-inbox", type: "fs" },
{ text: "__(Shared)", path: 'shared://' , iconclass: "fa fa-share-square", type: "fs" }
] if not _OS.setting.VFS.mountpoints
] if not Ant.OS.setting.VFS.mountpoints
_OS.setting.system = conf.system if conf.system
_OS.setting.system.startup = {
Ant.OS.setting.system = conf.system if conf.system
Ant.OS.setting.system.startup = {
services: [
"CoreServices/PushNotification",
"CoreServices/UserService",
@ -49,30 +49,30 @@
"CoreServices/Spotlight"
],
apps: []
} if not _OS.setting.system.startup
} if not Ant.OS.setting.system.startup
_OS.setting.system.pkgpaths = {
Ant.OS.setting.system.pkgpaths = {
user: "home://.packages",
system: "os://packages"
} unless _OS.setting.system.pkgpaths
_OS.setting.system.locale = "en_GB" unless _OS.setting.system.locale
_OS.setting.system.menu = {} unless _OS.setting.system.menu
_OS.setting.system.repositories = [] unless _OS.setting.system.repositories
_OS.setting.appearance.theme = "antos" unless _OS.setting.appearance.theme
} unless Ant.OS.setting.system.pkgpaths
Ant.OS.setting.system.locale = "en_GB" unless Ant.OS.setting.system.locale
Ant.OS.setting.system.menu = {} unless Ant.OS.setting.system.menu
Ant.OS.setting.system.repositories = [] unless Ant.OS.setting.system.repositories
Ant.OS.setting.appearance.theme = "antos" unless Ant.OS.setting.appearance.theme
_OS.setting.VFS.gdrive = {
Ant.OS.setting.VFS.gdrive = {
CLIENT_ID: ""
API_KEY: ""
apilink: "https://apis.google.com/js/api.js"
DISCOVERY_DOCS: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"]
SCOPES: 'https://www.googleapis.com/auth/drive'
} unless _OS.setting.VFS.gdrive
} unless Ant.OS.setting.VFS.gdrive
#search for app
_API.onsearch "__(Applications)", (t) ->
Ant.OS.API.onsearch "__(Applications)", (t) ->
ar = []
term = new RegExp t, "i"
for k, v of _OS.setting.system.packages when v.app
for k, v of Ant.OS.setting.system.packages when v.app
if (v.name.match term) or (v.description and v.description.match term)
v1 = {}
v1[k1] = e for k1, e of v when k1 isnt "selected"

View File

@ -57,7 +57,7 @@
return self[k]
}
this.on("mount", function(){
window.OS.courrier.trigger("sysdockloaded")
window.OS.announcer.trigger("sysdockloaded")
})
self.root.contextmenuHandler = function(e, m)

View File

@ -48,7 +48,7 @@
$(self.refs.aOsmenu.root).css("z-index",1000000)
$(self.refs.aAppmenu.root).css("z-index",1000000)
$(self.refs.aTray.root).css("z-index",1000000)
window.OS.courrier.trigger("syspanelloaded")
window.OS.announcer.trigger("syspanelloaded")
})
</script>
</afx-sys-panel>

View File

@ -64,7 +64,7 @@
self.tabbar.push(el)
if(el.url)
{
el.url.asFileHandler().read(function(d){
el.url.asFileHandle().read(function(d){
el.scheme = d
render(el)
})

View File

@ -15,24 +15,24 @@
# 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 = () ->
String.prototype.asFileHandle = () ->
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"), @
handles = Ant.OS.API.VFS.findHandles list[0]
if not handles or handles.length is 0
Ant.OS.announcer.osfail __("VFS unknown handle: {0}", @), (Ant.OS.API.throwe "OS.VFS"), @
return null
return new handlers[0](@)
return new handles[0](@)
this.OS.API.VFS =
handlers: { }
handles: { }
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 Ant.OS.API.VFS.handles[protos] = cls # if typeof protos is "string"
#Ant.OS.API.VFS.handles[v] = cls for v in protos
findHandles: (proto) ->
l = (v for k, v of Ant.OS.API.VFS.handles when proto.trim().match (new RegExp k , "g"))
return l
class BaseFileHandler
class BaseFileHandle
constructor: (path) ->
@dirty = false
@cache = undefined
@ -50,7 +50,7 @@ class BaseFileHandler
@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: () ->
asFileHandle: () ->
@
isRoot: () -> (not @genealogy) or (@genealogy.size is 0)
@ -82,7 +82,7 @@ class BaseFileHandler
reader.onload = () ->
f reader.result
reader.onerror = (e) ->
return _courrier.osfail __("VFS Cannot encode file: {0}", me.path), (_API.throwe "OS.VFS"), e
return Ant.OS.announcer.osfail __("VFS Cannot encode file: {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), e
parent: () ->
return @ if @isRoot()
return (@protocol + "://" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
@ -93,7 +93,7 @@ class BaseFileHandler
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
return if err then err d else Ant.OS.announcer.osfail "#{me.path}: #{d.error}", (Ant.OS.API.throwe "OS.VFS"), d.error
me.info = d.result
me.ready = true
f()
@ -105,30 +105,30 @@ class BaseFileHandler
write: (d, f) ->
me = @
@action "write", d, (r) ->
_courrier.ostrigger "VFS", { m: "write", file: me } if r.result
Ant.OS.announcer.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
Ant.OS.announcer.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
Ant.OS.announcer.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
Ant.OS.announcer.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
Ant.OS.announcer.ostrigger "VFS", { m: "publish", file: me } if r.result
f r)
download: (f) ->
me = @
@ -137,7 +137,7 @@ class BaseFileHandler
move: (d, f) ->
me = @
@onready (() -> me.action "move", d, (r) ->
_courrier.ostrigger "VFS", { m: "move", file: d.asFileHandler() } if r.result
Ant.OS.announcer.ostrigger "VFS", { m: "move", file: d.asFileHandle() } if r.result
f r)
execute: (f) ->
@ -152,61 +152,61 @@ class BaseFileHandler
# 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
return Ant.OS.announcer.osfail __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
# now export the class
self.OS.API.VFS.BaseFileHandler = BaseFileHandler
Ant.OS.API.VFS.BaseFileHandle = BaseFileHandle
# Remote file handle
class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
class RemoteFileHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path) ->
super path
meta: (f) ->
_API.handler.fileinfo @path, f
Ant.OS.API.handle.fileinfo @path, f
getlink: () ->
_API.handler.get + "/" + @path
Ant.OS.API.handle.get + "/" + @path
action: (n, p, f) ->
me = @
switch n
when "read"
return _API.handler.scandir @path, f if @info.type is "dir"
return Ant.OS.API.handle.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"
return Ant.OS.API.handle.fileblob @path, f if p is "binary"
Ant.OS.API.handle.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
Ant.OS.API.handle.mkdir "#{@path}/#{p}", f
when "write"
return _API.handler.write me.path, me.cache, f if p is "base64"
return Ant.OS.API.handle.write me.path, me.cache, f if p is "base64"
@sendB64 p, (data) ->
_API.handler.write me.path, data, f
Ant.OS.API.handle.write me.path, data, f
when "upload"
return if @info.type is "file"
_API.handler.upload @path, f
Ant.OS.API.handle.upload @path, f
when "remove"
_API.handler.delete @path, f
Ant.OS.API.handle.delete @path, f
when "publish"
_API.handler.sharefile @path, true , f
Ant.OS.API.handle.sharefile @path, true , f
when "download"
return if @info.type is "dir"
_API.handler.fileblob @path, (d) ->
Ant.OS.API.handle.fileblob @path, (d) ->
blob = new Blob [d], { type: "octet/stream" }
_API.saveblob me.basename, blob
Ant.OS.API.saveblob me.basename, blob
when "move"
_API.handler.move @path, p, f
Ant.OS.API.handle.move @path, p, f
else
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
return Ant.OS.announcer.osfail __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^(home|desktop|os|Untitled)$", RemoteFileHandler
Ant.OS.API.VFS.register "^(home|desktop|os|Untitled)$", RemoteFileHandle
# Application Handler
class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
# Application Handle
class ApplicationHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path) ->
super path
@info = _OS.setting.system.packages[@basename] if @basename
@info = Ant.OS.setting.system.packages[@basename] if @basename
@ready = true
meta: (f) ->
@ -218,7 +218,7 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "read"
return f { result: @info } if @info
return unless @isRoot()
f { result: ( v for k, v of _OS.setting.system.packages ) }
f { result: ( v for k, v of Ant.OS.setting.system.packages ) }
when "mk"
return
@ -241,11 +241,11 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
else
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
return Ant.OS.announcer.osfail __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^app$", ApplicationHandler
Ant.OS.API.VFS.register "^app$", ApplicationHandle
class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
class BufferFileHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path, mime, data) ->
super path
@cache = data if data
@ -286,16 +286,16 @@ class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
return
when "download"
blob = new Blob [@cache], { type: "octet/stream" }
_API.saveblob me.basename, blob
Ant.OS.API.saveblob me.basename, blob
when "move"
return
else
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
return Ant.OS.announcer.osfail __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^mem$", BufferFileHandler
Ant.OS.API.VFS.register "^mem$", BufferFileHandle
class URLFileHandler extends self.OS.API.VFS.BaseFileHandler
class URLFileHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path) ->
super path
@ready = true
@ -305,38 +305,38 @@ class URLFileHandler extends self.OS.API.VFS.BaseFileHandler
me = @
switch n
when "read"
_API.get @path, (d) ->
Ant.OS.API.get @path, (d) ->
f(d)
, (e, s) ->
_courrier.oserror __("VFS cannot read : {0}", me.path), e, s
Ant.OS.announcer.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
return Ant.OS.announcer.oserror __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
Ant.OS.API.VFS.register "^(http|https)$", URLFileHandle
class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
class SharedFileHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path) ->
super path
@ready = true if @isRoot()
meta: (f) ->
_API.handler.fileinfo @path, f
Ant.OS.API.handle.fileinfo @path, f
action: (n, p, f) ->
me = @
switch n
when "read"
return _API.get "#{_API.handler.shared}/all", f, ((e, s)->) if @isRoot()
return Ant.OS.API.get "#{Ant.OS.API.handle.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"
return Ant.OS.API.handle.fileblob @path, f if p is "binary"
Ant.OS.API.handle.readfile @path, f, if p then p else "text"
when "mk"
return
when "write"
_API.handler.write @path, p, f
Ant.OS.API.handle.write @path, p, f
when "remove"
_API.handler.sharefile @basename, false, f
Ant.OS.API.handle.sharefile @basename, false, f
when "upload"
return
@ -346,12 +346,12 @@ class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
when "download"
return if @info.type is "dir"
_API.handler.fileblob @path, (d) ->
Ant.OS.API.handle.fileblob @path, (d) ->
blob = new Blob [d], { type: "octet/stream" }
_API.saveblob me.basename, blob
Ant.OS.API.saveblob me.basename, blob
when "move"
return
else
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
return Ant.OS.announcer.osfail __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^shared$", SharedFileHandler
Ant.OS.API.VFS.register "^shared$", SharedFileHandle

View File

@ -17,15 +17,15 @@
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
# GoogleDrive File Handler
# GoogleDrive File Handle
G_CACHE = {"gdv://":{ id: "root", mime: 'dir' } }
class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
class GoogleDriveHandle extends this.OS.API.VFS.BaseFileHandle
constructor: (path) ->
super path
me = @
@setting = _OS.setting.VFS.gdrive
return _courrier.oserror __("Unknown API setting for {0}", "GAPI"), (_API.throwe "OS.VFS"), null unless @setting
@setting = Ant.OS.setting.VFS.gdrive
return Ant.OS.announcer.oserror __("Unknown API setting for {0}", "GAPI"), (Ant.OS.API.throwe "OS.VFS"), null unless @setting
@gid = 'root' if @isRoot()
@cache = ""
@ -38,16 +38,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
G_CACHE = {"gdv://":{ id: "root", mime: 'dir' } }
gapi.auth2.getAuthInstance().signIn()
if _API.libready @setting.apilink
if Ant.OS.API.libready @setting.apilink
gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r)
fn(gapi.auth2.getAuthInstance().isSignedIn.get())
else
_API.require @setting.apilink, () ->
Ant.OS.API.require @setting.apilink, () ->
# avoid popup block
q = _courrier.getMID()
q = Ant.OS.announcer.getMID()
gapi.load "client:auth2", () ->
_API.loading q, "GAPI"
Ant.OS.API.loading q, "GAPI"
gapi.client.init {
apiKey: me.setting.API_KEY,
clientId: me.setting.CLIENT_ID,
@ -55,45 +55,45 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
scope: me.setting.SCOPES
}
.then () ->
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r)
_GUI.openDialog "YesNoDialog", (d) ->
return _courrier.osinfo __("User abort the authentication") unless d
return Ant.OS.announcer.osinfo __("User abort the authentication") unless d
fn(gapi.auth2.getAuthInstance().isSignedIn.get())
, __("Authentication")
, { text: __("Would you like to login to {0}?", "Google Drive") }
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot init {0}: {1}", "GAPI",err.error), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot init {0}: {1}", "GAPI",err.error), (Ant.OS.API.throwe "OS.VFS"), err
meta: (f) ->
me = @
@oninit () ->
q = _courrier.getMID()
q = Ant.OS.announcer.getMID()
me.gid = G_CACHE[me.path].id if G_CACHE[me.path]
if me.gid
#console.log "Gid exists ", me.gid
_API.loading q, "GAPI"
Ant.OS.API.loading q, "GAPI"
gapi.client.drive.files.get {
fileId: me.gid,
fields: me.fields()
}
.then (r) ->
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
return unless r.result
r.result.mime = r.result.mimeType
f(r)
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot get meta data for {0}", me.gid), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot get meta data for {0}", me.gid), (Ant.OS.API.throwe "OS.VFS"), err
else
#console.log "Find file in ", me.parent()
fp = me.parent().asFileHandler()
fp = me.parent().asFileHandle()
fp.meta (d) ->
file = d.result
q1 = _courrier.getMID()
_API.loading q1, "GAPI"
q1 = Ant.OS.announcer.getMID()
Ant.OS.API.loading q1, "GAPI"
G_CACHE[fp.path] = { id: file.id, mime: file.mimeType }
gapi.client.drive.files.list {
q: "name = '#{me.basename}' and '#{file.id}' in parents and trashed = false",
@ -101,14 +101,14 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
#console.log r
_API.loaded q1, "OK"
Ant.OS.API.loaded q1, "OK"
return unless r.result.files and r.result.files.length > 0
G_CACHE[me.path] = { id: r.result.files[0].id, mime: r.result.files[0].mimeType }
r.result.files[0].mime = r.result.files[0].mimeType
f { result: r.result.files[0] }
.catch (err) ->
_API.loaded q1, "FAIL"
_courrier.oserror __("VFS cannot get meta data for {0}", me.path), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q1, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot get meta data for {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
fields: () ->
return "webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size"
@ -119,7 +119,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
me = @
user = gapi.auth2.getAuthInstance().currentUser.get()
oauthToken = user.getAuthResponse().access_token
q = _courrier.getMID()
q = Ant.OS.announcer.getMID()
xhr = new XMLHttpRequest()
url = 'https://www.googleapis.com/upload/drive/v3/files/' + id + '?uploadType=media'
xhr.open('PATCH', url)
@ -127,14 +127,14 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
xhr.setRequestHeader 'Content-Type', m
xhr.setRequestHeader 'Content-Encoding', 'base64'
xhr.setRequestHeader 'Content-Transfer-Encoding', 'base64'
_API.loading q, "GAPI"
Ant.OS.API.loading q, "GAPI"
error = (e, s) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot save : {0}", me.path), e, s
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot save : {0}", me.path), e, s
xhr.onreadystatechange = () ->
if ( xhr.readyState == 4 )
if ( xhr.status == 200 )
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
f { result: JSON.parse(xhr.responseText) }
else
error xhr, xhr.status
@ -150,8 +150,8 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
action: (n, p, f) ->
me = @
q = _courrier.getMID()
_API.loading q, "GAPI"
q = Ant.OS.announcer.getMID()
Ant.OS.API.loading q, "GAPI"
switch n
when "read"
return unless @info.id
@ -161,7 +161,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: "files(#{me.fields()})"
}
.then (r) ->
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
return unless r.result.files
for file in r.result.files
file.path = me.child file.name
@ -176,20 +176,20 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
G_CACHE[file.path] = { id: file.gid, mime: file.mime }
f { result: r.result.files }
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot read : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
else
gapi.client.drive.files.get {
fileId: me.info.id,
alt: 'media'
}
.then (r) ->
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
return f r.body unless p is "binary"
f r.body.asUint8Array()
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot read : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "mk"
return f { error: __("{0} is not a directory", @path) } unless @isFolder()
@ -203,14 +203,14 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: 'id'
}
.then (r) ->
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
#console.log r
return _courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), r unless r and r.result
return Ant.OS.announcer.oserror __("VFS cannot create : {0}", p), (Ant.OS.API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.child p] = { id: r.result.id, mime: "dir" }
f r
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot create : {0}", p), (Ant.OS.API.throwe "OS.VFS"), err
return
@ -218,10 +218,10 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
gid = undefined
gid = G_CACHE[me.path].id if G_CACHE[me.path]
if gid
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
@save gid, p, f
else
dir = @parent().asFileHandler()
dir = @parent().asFileHandle()
dir.onready () ->
meta =
name: me.basename,
@ -233,29 +233,29 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: 'id'
}
.then (r) ->
_API.loaded q, "OK"
return _courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), r unless r and r.result
Ant.OS.API.loaded q, "OK"
return Ant.OS.announcer.oserror __("VFS cannot write : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.path] = { id: r.result.id, mime: p }
me.save r.result.id, p, f
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot write : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "upload"
return unless @isFolder()
#insert a temporal file selector
o = ($ '<input>').attr('type', 'file').css("display", "none")
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
o.change () ->
#_API.loading q, p
#Ant.OS.API.loading q, p
fo = o[0].files[0]
file = (me.child fo.name).asFileHandler()
file = (me.child fo.name).asFileHandle()
file.cache = fo
file.write fo.type, f
o.remove()
#_API.loaded q, p, "OK"
#_API.loaded q, p, "FAIL"
#Ant.OS.API.loaded q, p, "OK"
#Ant.OS.API.loaded q, p, "FAIL"
o.click()
@ -266,16 +266,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
#console.log r
_API.loaded q, "OK"
return _courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), r unless r
Ant.OS.API.loaded q, "OK"
return Ant.OS.announcer.oserror __("VFS cannot delete : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), r unless r
G_CACHE[me.path] = null
f { result: true }
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot delete : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "publish"
_API.loaded q, "OK"
Ant.OS.API.loaded q, "OK"
return
when "download"
@ -284,20 +284,20 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
alt: 'media'
}
.then (r) ->
_API.loaded q, "OK"
return _courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), r unless r.body
Ant.OS.API.loaded q, "OK"
return Ant.OS.announcer.oserror __("VFS cannot download file : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), r unless r.body
bytes = []
for i in [0..(r.body.length - 1)]
bytes.push r.body.charCodeAt i
bytes = new Uint8Array(bytes)
blob = new Blob [bytes], { type: "octet/stream" }
_API.saveblob me.basename, blob
Ant.OS.API.saveblob me.basename, blob
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot download file : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "move"
dest = p.asFileHandler().parent().asFileHandler()
dest = p.asFileHandle().parent().asFileHandle()
dest.onready () ->
previousParents = me.info.parents.join ','
gapi.client.drive.files.update {
@ -307,27 +307,27 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: "id"
}
.then (r) ->
_API.loaded q, "OK"
return _courrier.oserror __("VFS cannot move : {0}", me.path), (_API.throwe "OS.VFS"), r unless r
Ant.OS.API.loaded q, "OK"
return Ant.OS.announcer.oserror __("VFS cannot move : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), r unless r
f r
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot move : {0}", me.gid), (_API.throwe "OS.VFS"), err
Ant.OS.API.loaded q, "FAIL"
Ant.OS.announcer.oserror __("VFS cannot move : {0}", me.gid), (Ant.OS.API.throwe "OS.VFS"), err
, (err) ->
_API.loaded q, "FAIL"
Ant.OS.API.loaded q, "FAIL"
else
_API.loaded q, "FAIL"
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
Ant.OS.API.loaded q, "FAIL"
return Ant.OS.announcer.osfail __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^gdv$", GoogleDriveHandler
self.OS.API.VFS.register "^gdv$", GoogleDriveHandle
# search the cache for file
self.OS.API.onsearch "Google Drive", (t) ->
arr = []
term = new RegExp t, "i"
for k, v of G_CACHE
if (k.match term) or (v and v.mime.match term)
file = k.asFileHandler()
file = k.asFileHandle()
file.text = file.basename
file.mime = v.mime
file.iconclass = "fa fa-file"
@ -339,7 +339,7 @@ self.OS.API.onsearch "Google Drive", (t) ->
self.OS.onexit "cleanUpGoogleDrive", () ->
G_CACHE = { "gdv://": { id: "root", mime: 'dir' } }
return unless _OS.setting.VFS.gdrive and _API.libready _OS.setting.VFS.gdrive.apilink
return unless Ant.OS.setting.VFS.gdrive and Ant.OS.API.libready Ant.OS.setting.VFS.gdrive.apilink
auth2 = gapi.auth2.getAuthInstance()
return unless auth2
if auth2.isSignedIn.get()