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\ coffees= src/core/core.coffee\
src/core/api.coffee\ src/core/api.coffee\
src/core/settings.coffee\ src/core/settings.coffee\
src/core/handlers/RemoteHandler.coffee\ src/core/handles/RemoteHandle.coffee\
src/core/vfs.coffee\ src/core/vfs.coffee\
src/core/vfs/GoogleDriveHandler.coffee\ src/core/vfs/GoogleDriveHandle.coffee\
src/core/db.coffee\ src/core/db.coffee\
src/core/gui.coffee\ src/core/gui.coffee\
src/core/BaseModel.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 main: initd build_coffees build_tags build_themes schemes libs build_packages languages
- cp src/index.html $(BUILDDIR)/ - cp src/index.html $(BUILDDIR)/

View File

@ -1,4 +1,7 @@
# antOS # 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) [![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) [![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 # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #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 = () -> this.onload = () ->
($ document).on 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', ()-> ($ document).on 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', ()->
_GUI.fullscreen = not _GUI.fullscreen Ant.OS.GUI.fullscreen = not Ant.OS.GUI.fullscreen
self.OS.boot() Ant.OS.boot()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,8 +18,8 @@
'use strict' 'use strict'
#define the OS object #define the OS object
self = this Ant = this
self.OS or= Ant.OS or=
API: {} API: {}
GUI: {} GUI: {}
@ -31,33 +31,33 @@ self.OS or=
appearance: {} appearance: {}
VFS: {} VFS: {}
system: {} system: {}
courrier: announcer:
observable: riot.observable() observable: riot.observable()
quota: 0 quota: 0
listeners: {} listeners: {}
on: (e, f, a) -> on: (e, f, a) ->
_courrier.listeners[a.pid] = [] unless _courrier.listeners[a.pid] Ant.OS.announcer.listeners[a.pid] = [] unless Ant.OS.announcer.listeners[a.pid]
_courrier.listeners[a.pid].push { e: e, f: f } Ant.OS.announcer.listeners[a.pid].push { e: e, f: f }
_courrier.observable.on e, f Ant.OS.announcer.observable.on e, f
trigger: (e, d) -> _courrier.observable.trigger e, d trigger: (e, d) -> Ant.OS.announcer.observable.trigger e, d
osfail: (m, e, s) -> 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) -> 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) -> 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) -> 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) -> unregister: (app) ->
return unless _courrier.listeners[app.pid] and _courrier.listeners[app.pid].length > 0 return unless Ant.OS.announcer.listeners[app.pid] and Ant.OS.announcer.listeners[app.pid].length > 0
_courrier.observable.off i.e, i.f for i in _courrier.listeners[app.pid] Ant.OS.announcer.observable.off i.e, i.f for i in Ant.OS.announcer.listeners[app.pid]
delete _courrier.listeners[app.pid] delete Ant.OS.announcer.listeners[app.pid]
# _courrier.listeners[app.pid] # Ant.OS.announcer.listeners[app.pid]
getMID: () -> getMID: () ->
_courrier.quota += 1 Ant.OS.announcer.quota += 1
_courrier.quota Ant.OS.announcer.quota
register: (name, x) -> 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: PM:
pidalloc: 0 pidalloc: 0
@ -67,86 +67,86 @@ self.OS or=
#if it is single ton #if it is single ton
# and a process is existing # and a process is existing
# just return it # just return it
if cls.singleton and _PM.processes[app] and _PM.processes[app].length == 1 if cls.singleton and Ant.OS.PM.processes[app] and Ant.OS.PM.processes[app].length == 1
_PM.processes[app][0].show() Ant.OS.PM.processes[app][0].show()
else 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 = new cls(args)
obj.birth = (new Date).getTime() obj.birth = (new Date).getTime()
_PM.pidalloc++ Ant.OS.PM.pidalloc++
obj.pid = _PM.pidalloc obj.pid = Ant.OS.PM.pidalloc
_PM.processes[app].push obj Ant.OS.PM.processes[app].push obj
if cls.type is 1 then _GUI.dock obj, cls.meta else _GUI.attachservice 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 if cls.type is 2
_courrier.trigger "srvroutineready", app Ant.OS.announcer.trigger "srvroutineready", app
if cls.dependencies if cls.dependencies
libs = (v for v in cls.dependencies) libs = (v for v in cls.dependencies)
_API.requires libs, f Ant.OS.API.requires libs, f
else else
f() f()
appByPid: (pid) -> appByPid: (pid) ->
app = undefined app = undefined
find = (l) -> find = (l) ->
return a for a in l when a.pid is pid 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 app = find v
break if app break if app
app app
kill: (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 i >= 0
if _OS.APP[app.name].type == 1 then _GUI.undock app else _GUI.detachservice app if Ant.OS.APP[app.name].type == 1 then Ant.OS.GUI.undock app else Ant.OS.GUI.detachservice app
_courrier.unregister app Ant.OS.announcer.unregister app
delete _PM.processes[app.name][i] delete Ant.OS.PM.processes[app.name][i]
_PM.processes[app.name].splice i, 1 Ant.OS.PM.processes[app.name].splice i, 1
killAll: (app, force) -> killAll: (app, force) ->
return unless _PM.processes[app] return unless Ant.OS.PM.processes[app]
a.quit(force) for a in _PM.processes[app] a.quit(force) for a in Ant.OS.PM.processes[app]
cleanup: -> cleanup: ->
console.log "Clean up system" console.log "Clean up system"
_PM.killAll a, true for a, v of _PM.processes Ant.OS.PM.killAll a, true for a, v of Ant.OS.PM.processes
_courrier.observable.off("*") if _courrier.observable Ant.OS.announcer.observable.off("*") if Ant.OS.announcer.observable
$(window).off('keydown') $(window).off('keydown')
($ "#workspace").off("mouseover") ($ "#workspace").off("mouseover")
delete _courrier.observable delete Ant.OS.announcer.observable
($ "#wrapper").empty() ($ "#wrapper").empty()
_GUI.clearTheme() Ant.OS.GUI.clearTheme()
_courrier.observable = riot.observable() Ant.OS.announcer.observable = riot.observable()
_courrier.quota = 0 Ant.OS.announcer.quota = 0
_OS.APP = {} Ant.OS.APP = {}
_OS.setting = Ant.OS.setting =
user: {} user: {}
applications: {} applications: {}
desktop: {} desktop: {}
appearance: {} appearance: {}
VFS: {} VFS: {}
system: {} system: {}
_PM.processes = {} Ant.OS.PM.processes = {}
_PM.pidalloc = 0 Ant.OS.PM.pidalloc = 0
boot: -> boot: ->
#first login #first login
console.log "Booting sytem" console.log "Booting sytem"
_API.handler.auth (d) -> Ant.OS.API.handle.auth (d) ->
# in case someone call it more than once :) # in case someone call it more than once :)
if d.error if d.error
# show login screen # show login screen
_GUI.login() Ant.OS.GUI.login()
else else
# startX :) # startX :)
_GUI.startAntOS d.result Ant.OS.GUI.startAntOS d.result
cleanupHandlers: {} cleanupHandles: {}
exit: -> exit: ->
#do clean up first #do clean up first
f() for n, f of _OS.cleanupHandlers f() for n, f of Ant.OS.cleanupHandles
_API.handler.setting (r) -> Ant.OS.API.handle.setting (r) ->
_OS.cleanup() Ant.OS.cleanup()
_API.handler.logout() Ant.OS.API.handle.logout()
onexit: (n, f) -> 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) -> constructor: (@table) ->
save: (d, f) -> 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) -> delete: (c, f) ->
rq = { table: @table } rq = { table: @table }
return ( _courrier.oserror __("VDB Unknown condition for delete command"), return ( Ant.OS.announcer.oserror __("VDB Unknown condition for delete command"),
(_API.throwe "OS.DB"), c ) unless c and c isnt "" (Ant.OS.API.throwe "OS.DB"), c ) unless c and c isnt ""
if isNaN c if isNaN c
rq.cond = c rq.cond = c
else else
rq.id = c rq.id = c
_API.handler.dbquery "delete", rq, f Ant.OS.API.handle.dbquery "delete", rq, f
get: (id, 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) -> 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 # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #along with this program. If not, see https://www.gnu.org/licenses/.
self.OS.GUI = Ant.OS.GUI =
subwindows: new Object() subwindows: new Object()
dialog: undefined dialog: undefined
fullscreen: false fullscreen: false
@ -37,13 +37,13 @@ self.OS.GUI =
dataid: "sys-apps" dataid: "sys-apps"
iconclass: "fa fa-adn", iconclass: "fa fa-adn",
onmenuselect: (d) -> onmenuselect: (d) ->
_GUI.launch d.item.data.app Ant.OS.GUI.launch d.item.data.app
} }
], ],
onmenuselect: (d) -> onmenuselect: (d) ->
return _OS.exit() if d.item.data.dataid is "sys-logout" return Ant.OS.exit() if d.item.data.dataid is "sys-logout"
return _GUI.toggleFullscreen() if d.item.data.dataid is "os-fullsize" return Ant.OS.GUI.toggleFullscreen() if d.item.data.dataid is "os-fullsize"
_GUI.launch d.item.data.app unless d.item.data.dataid Ant.OS.GUI.launch d.item.data.app unless d.item.data.dataid
} }
] ]
htmlToScheme: (html, app, parent) -> htmlToScheme: (html, app, parent) ->
@ -56,58 +56,58 @@ self.OS.GUI =
app.main() app.main()
app.show() app.show()
loadScheme: (path, app, parent) -> loadScheme: (path, app, parent) ->
path.asFileHandler().read (x) -> path.asFileHandle().read (x) ->
return null unless x return null unless x
_GUI.htmlToScheme x, app, parent Ant.OS.GUI.htmlToScheme x, app, parent
#, (e, s) -> #, (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: () -> clearTheme: () ->
$ "head link#ostheme" $ "head link#ostheme"
.attr "href", "" .attr "href", ""
loadTheme: (name, force) -> loadTheme: (name, force) ->
_GUI.clearTheme() if force Ant.OS.GUI.clearTheme() if force
path = "resources/themes/#{name}/#{name}.css" path = "resources/themes/#{name}/#{name}.css"
$ "head link#ostheme" $ "head link#ostheme"
.attr "href", path .attr "href", path
pushServices: (srvs) -> pushServices: (srvs) ->
return unless srvs.length > 0 return unless srvs.length > 0
_courrier.observable.one "srvroutineready", () -> Ant.OS.announcer.observable.one "srvroutineready", () ->
srvs.splice 0, 1 srvs.splice 0, 1
_GUI.pushServices srvs Ant.OS.GUI.pushServices srvs
_GUI.pushService srvs[0] Ant.OS.GUI.pushService srvs[0]
openDialog: (d, f, title, data) -> openDialog: (d, f, title, data) ->
if _GUI.dialog if Ant.OS.GUI.dialog
_GUI.dialog.show() Ant.OS.GUI.dialog.show()
return return
if not _GUI.subwindows[d] if not Ant.OS.GUI.subwindows[d]
ex = _API.throwe "Dialog" ex = Ant.OS.API.throwe "Dialog"
return _courrier.oserror __("Dialog {0} not found", d), ex, null return Ant.OS.announcer.oserror __("Dialog {0} not found", d), ex, null
_GUI.dialog = new _GUI.subwindows[d]() Ant.OS.GUI.dialog = new Ant.OS.GUI.subwindows[d]()
_GUI.dialog.parent = _GUI Ant.OS.GUI.dialog.parent = Ant.OS.GUI
_GUI.dialog.handler = f Ant.OS.GUI.dialog.handle = f
_GUI.dialog.pid = -1 Ant.OS.GUI.dialog.pid = -1
_GUI.dialog.data = data Ant.OS.GUI.dialog.data = data
_GUI.dialog.title = title Ant.OS.GUI.dialog.title = title
_GUI.dialog.init() Ant.OS.GUI.dialog.init()
pushService: (ph) -> pushService: (ph) ->
arr = ph.split "/" arr = ph.split "/"
srv = arr[1] srv = arr[1]
app = arr[0] app = arr[0]
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]
_GUI.loadApp app, Ant.OS.GUI.loadApp app,
(a) -> (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) -> (e, s) ->
_courrier.trigger "srvroutineready", srv Ant.OS.announcer.trigger "srvroutineready", srv
_courrier.osfail __("Cannot read service script: {0}", srv), e, s Ant.OS.announcer.osfail __("Cannot read service script: {0}", srv), e, s
appsByMime: (mime) -> 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) mimes = ( m.mimes for m in metas when m)
apps = [] apps = []
# search app by mimes # search app by mimes
@ -120,56 +120,56 @@ self.OS.GUI =
return false return false
return false return false
catch e 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 ( f m, i if m ) for m, i in mimes
return apps return apps
appsWithServices: () -> appsWithServices: () ->
o = {} 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 o
openWith: (it) -> openWith: (it) ->
return unless it return unless it
return _GUI.launch it.app if it.type is "app" and it.app return Ant.OS.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" return Ant.OS.announcer.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 ) apps = Ant.OS.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 Ant.OS.announcer.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 apps[0].app, [it.path] if apps.length is 1
list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps ) list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps )
_GUI.openDialog "SelectionDialog", ( d ) -> Ant.OS.GUI.openDialog "SelectionDialog", ( d ) ->
_GUI.launch d.text, [it.path] Ant.OS.GUI.launch d.text, [it.path]
, __("Open with"), list , __("Open with"), list
forceLaunch: (app, args) -> forceLaunch: (app, args) ->
console.warn "This method is used for developing only, please use the launch method instead" console.warn "This method is used for developing only, please use the launch method instead"
_GUI.unloadApp app Ant.OS.GUI.unloadApp app
_GUI.launch app, args Ant.OS.GUI.launch app, args
unloadApp: (app) -> unloadApp: (app) ->
_PM.killAll app, true Ant.OS.PM.killAll app, true
($ _OS.APP[app].style).remove() if _OS.APP[app] and _OS.APP[app].style ($ Ant.OS.APP[app].style).remove() if Ant.OS.APP[app] and Ant.OS.APP[app].style
delete _OS.APP[app] delete Ant.OS.APP[app]
loadApp: (app, ok, err) -> loadApp: (app, ok, err) ->
path = "os://packages/#{app}" 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 = path + "/main.js"
js.asFileHandler().read (d) -> js.asFileHandle().read (d) ->
# load app meta data # load app meta data
"#{path}/package.json".asFileHandler().read (data) -> "#{path}/package.json".asFileHandle().read (data) ->
data.path = path data.path = path
_OS.APP[app].meta = data if _OS.APP[app] Ant.OS.APP[app].meta = data if Ant.OS.APP[app]
_OS.APP[v].meta = data for v in data.services if data.services Ant.OS.APP[v].meta = data for v in data.services if data.services
#load css file #load css file
css = "#{path}/main.css" css = "#{path}/main.css"
css.asFileHandler().onready (d) -> css.asFileHandle().onready (d) ->
stamp = (new Date).timestamp() 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' .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 ok app
, () -> , () ->
#launch #launch
@ -178,16 +178,16 @@ self.OS.GUI =
#ok app #ok app
, "script" , "script"
launch: (app, args) -> launch: (app, args) ->
if not _OS.APP[app] if not Ant.OS.APP[app]
# first load it # first load it
_GUI.loadApp app, Ant.OS.GUI.loadApp app,
(a)-> (a)->
_PM.createProcess a, _OS.APP[a], args Ant.OS.PM.createProcess a, Ant.OS.APP[a], args
, (e, s) -> , (e, s) ->
else else
# now launch it # now launch it
if _OS.APP[app] if Ant.OS.APP[app]
_PM.createProcess app, _OS.APP[app], args Ant.OS.PM.createProcess app, Ant.OS.APP[app], args
dock: (app, meta) -> dock: (app, meta) ->
# dock an application to a dock # dock an application to a dock
@ -214,7 +214,7 @@ self.OS.GUI =
toggleFullscreen: () -> toggleFullscreen: () ->
el = ($ "body")[0] el = ($ "body")[0]
if _GUI.fullscreen if Ant.OS.GUI.fullscreen
return document.exitFullscreen() if document.exitFullscreen return document.exitFullscreen() if document.exitFullscreen
return document.mozCancelFullScreen() if document.mozCancelFullScreen return document.mozCancelFullScreen() if document.mozCancelFullScreen
return document.webkitExitFullscreen() if document.webkitExitFullscreen return document.webkitExitFullscreen() if document.webkitExitFullscreen
@ -235,13 +235,13 @@ self.OS.GUI =
detachservice: (srv) -> detachservice: (srv) ->
($ "#syspanel")[0].detachservice srv ($ "#syspanel")[0].detachservice srv
bindContextMenu: (event) -> bindContextMenu: (event) ->
handler = (e) -> handle = (e) ->
if e.contextmenuHandler if e.contextmenuHandle
e.contextmenuHandler event, ($ "#contextmenu")[0] e.contextmenuHandle event, ($ "#contextmenu")[0]
else else
p = $(e).parent().get(0) p = $(e).parent().get(0)
handler p if p isnt ($ "#workspace").get(0) handle p if p isnt ($ "#workspace").get(0)
handler event.target handle event.target
event.preventDefault() event.preventDefault()
bindKey: (k, f) -> bindKey: (k, f) ->
@ -249,14 +249,14 @@ self.OS.GUI =
return unless arr.length is 2 return unless arr.length is 2
fnk = arr[0].toUpperCase() fnk = arr[0].toUpperCase()
c = arr[1].toUpperCase() c = arr[1].toUpperCase()
return unless _GUI.shortcut[fnk] return unless Ant.OS.GUI.shortcut[fnk]
_GUI.shortcut[fnk][c] = f Ant.OS.GUI.shortcut[fnk][c] = f
wallpaper: (obj) -> wallpaper: (obj) ->
if obj if obj
_OS.setting.appearance.wp = obj Ant.OS.setting.appearance.wp = obj
wp = _OS.setting.appearance.wp wp = Ant.OS.setting.appearance.wp
$("body").css("background-image", "url(#{_API.handler.get}/#{wp.url})" ) $("body").css("background-image", "url(#{Ant.OS.API.handle.get}/#{wp.url})" )
.css("background-size", wp.size) .css("background-size", wp.size)
.css("background-repeat", wp.repeat) .css("background-repeat", wp.repeat)
@ -288,12 +288,12 @@ self.OS.GUI =
initDM: -> initDM: ->
# check login first # check login first
_API.resource "schemes/dm.html", (x) -> Ant.OS.API.resource "schemes/dm.html", (x) ->
return null unless x return null unless x
scheme = $.parseHTML x scheme = $.parseHTML x
($ "#wrapper").append scheme ($ "#wrapper").append scheme
_courrier.observable.one "sysdockloaded", () -> Ant.OS.announcer.observable.one "sysdockloaded", () ->
($ window).bind 'keydown', (event) -> ($ window).bind 'keydown', (event) ->
dock = ($ "#sysdock")[0] dock = ($ "#sysdock")[0]
return unless dock return unless dock
@ -313,9 +313,9 @@ self.OS.GUI =
return unless fnk return unless fnk
r = if app then app.shortcut fnk, c, event else true r = if app then app.shortcut fnk, c, event else true
return event.preventDefault() if not r return event.preventDefault() if not r
return unless _GUI.shortcut[fnk] return unless Ant.OS.GUI.shortcut[fnk]
return unless _GUI.shortcut[fnk][c] return unless Ant.OS.GUI.shortcut[fnk][c]
_GUI.shortcut[fnk][c](event) Ant.OS.GUI.shortcut[fnk][c](event)
event.preventDefault() event.preventDefault()
# system menu and dock # system menu and dock
riot.mount ($ "#syspanel", $ "#wrapper") riot.mount ($ "#syspanel", $ "#wrapper")
@ -323,24 +323,24 @@ self.OS.GUI =
riot.mount ($ "#systooltip", $ "#wrapper") riot.mount ($ "#systooltip", $ "#wrapper")
# context menu # context menu
riot.mount ($ "#contextmenu", $ "#wrapper") riot.mount ($ "#contextmenu", $ "#wrapper")
($ "#workspace").contextmenu (e) -> _GUI.bindContextMenu e ($ "#workspace").contextmenu (e) -> Ant.OS.GUI.bindContextMenu e
# tooltip # tooltip
($ "#workspace").mouseover (e) -> ($ "#workspace").mouseover (e) ->
el = $(e.target).closest "[tooltip]" el = $(e.target).closest "[tooltip]"
return unless el.length > 0 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 default file manager
desktop = $ "#desktop" desktop = $ "#desktop"
fp = _OS.setting.desktop.path.asFileHandler() fp = Ant.OS.setting.desktop.path.asFileHandle()
desktop[0].fetch = () -> desktop[0].fetch = () ->
fn = () -> fn = () ->
fp = _OS.setting.desktop.path.asFileHandler() fp = Ant.OS.setting.desktop.path.asFileHandle()
fp.read (d) -> 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 = [] items = []
$.each d.result, (i, v) -> $.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.filename
#v.text = v.text.substring(0,9) + "..." ifv.text.length > 10 #v.text = v.text.substring(0,9) + "..." ifv.text.length > 10
v.iconclass = v.type v.iconclass = v.type
@ -353,14 +353,14 @@ self.OS.GUI =
, ( e ) -> # try to create the path , ( e ) -> # try to create the path
console.log "#{fp.path} not found" console.log "#{fp.path} not found"
name = fp.basename name = fp.basename
fp.parent().asFileHandler().mk name, (r) -> fp.parent().asFileHandle().mk name, (r) ->
ex = _API.throwe "OS.VFS" ex = Ant.OS.API.throwe "OS.VFS"
if r.error then _courrier.osfail d.error, ex, d.error else fn() if r.error then Ant.OS.announcer.osfail d.error, ex, d.error else fn()
desktop[0].ready = (e) -> desktop[0].ready = (e) ->
e.observable = _courrier e.observable = Ant.OS.announcer
window.onresize = () -> window.onresize = () ->
_courrier.trigger "desktopresize" Ant.OS.announcer.trigger "desktopresize"
e.refresh() e.refresh()
desktop[0].set "onlistselect", (d) -> desktop[0].set "onlistselect", (d) ->
@ -369,7 +369,7 @@ self.OS.GUI =
desktop[0].set "onlistdbclick", ( d ) -> desktop[0].set "onlistdbclick", ( d ) ->
($ "#sysdock").get(0).set "selectedApp", null ($ "#sysdock").get(0).set "selectedApp", null
it = desktop[0].get "selected" it = desktop[0].get "selected"
_GUI.openWith it Ant.OS.GUI.openWith it
#($ "#workingenv").on "click", (e) -> #($ "#workingenv").on "click", (e) ->
# desktop[0].set "selected", -1 # desktop[0].set "selected", -1
@ -380,33 +380,33 @@ self.OS.GUI =
($ "#sysdock").get(0).set "selectedApp", null ($ "#sysdock").get(0).set "selectedApp", null
#console.log "desktop clicked" #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] desktop[0].set "selected", -1 if e.target is desktop[0]
($ "#sysdock").get(0).set "selectedApp", null ($ "#sysdock").get(0).set "selectedApp", null
menu = [ menu = [
{ text: __("Open"), dataid: "desktop-open" }, { text: __("Open"), dataid: "desktop-open" },
{ text: __("Refresh"), dataid: "desktop-refresh" } { 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 "items", menu
m.set "onmenuselect", (evt) -> m.set "onmenuselect", (evt) ->
switch evt.item.data.dataid switch evt.item.data.dataid
when "desktop-open" when "desktop-open"
it = desktop[0].get "selected" it = desktop[0].get "selected"
return _GUI.openWith it if it return Ant.OS.GUI.openWith it if it
it = _OS.setting.desktop.path.asFileHandler() it = Ant.OS.setting.desktop.path.asFileHandle()
it.mime = "dir" it.mime = "dir"
_GUI.openWith it Ant.OS.GUI.openWith it
when "desktop-refresh" when "desktop-refresh"
desktop[0].fetch() desktop[0].fetch()
else 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) m.show(e)
desktop[0].fetch() 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() 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 # mount it
riot.mount desktop riot.mount desktop
, (e, s) -> , (e, s) ->
@ -416,29 +416,29 @@ self.OS.GUI =
($ "#desktop")[0].fetch() ($ "#desktop")[0].fetch()
refreshSystemMenu: () -> refreshSystemMenu: () ->
_GUI.SYS_MENU[0].child.length = 1 Ant.OS.GUI.SYS_MENU[0].child.length = 1
_GUI.SYS_MENU[0].child[0].child.length = 0 Ant.OS.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) 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)
_GUI.SYS_MENU[0].child.push v for k, v of _OS.setting.system.menu Ant.OS.GUI.SYS_MENU[0].child.push v for k, v of Ant.OS.setting.system.menu
_GUI.SYS_MENU[0].child.push Ant.OS.GUI.SYS_MENU[0].child.push
text: "__(Toggle Full screen)", text: "__(Toggle Full screen)",
dataid: "os-fullsize", dataid: "os-fullsize",
iconclass: "fa fa-tv" iconclass: "fa fa-tv"
_GUI.SYS_MENU[0].child.push Ant.OS.GUI.SYS_MENU[0].child.push
text: "__(Log out)", text: "__(Log out)",
dataid: "sys-logout", dataid: "sys-logout",
iconclass: "fa fa-user-times" iconclass: "fa fa-user-times"
($ "[data-id = 'os_menu']", "#syspanel")[0].update() ($ "[data-id = 'os_menu']", "#syspanel")[0].update()
buildSystemMenu: () -> 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 #console.log menu
mkdialog: (conf) -> mkdialog: (conf) ->
return new _GUI.BasicDialog conf.name, conf.layout return new Ant.OS.GUI.BasicDialog conf.name, conf.layout
login: () -> login: () ->
_API.resource "schemes/login.html", (x) -> Ant.OS.API.resource "schemes/login.html", (x) ->
return null unless x return null unless x
scheme = $.parseHTML x scheme = $.parseHTML x
($ "#wrapper").append scheme ($ "#wrapper").append scheme
@ -446,8 +446,8 @@ self.OS.GUI =
data = data =
username: ($ "#txtuser").val(), username: ($ "#txtuser").val(),
password: ($ "#txtpass").val() password: ($ "#txtpass").val()
_API.handler.login data, (d) -> Ant.OS.API.handle.login data, (d) ->
if d.error then ($ "#login_error").html d.error else _GUI.startAntOS d.result if d.error then ($ "#login_error").html d.error else Ant.OS.GUI.startAntOS d.result
($ "#txtpass").keyup (e) -> ($ "#txtpass").keyup (e) ->
($ "#btlogin").click() if e.which is 13 ($ "#btlogin").click() if e.which is 13
, (e, s) -> , (e, s) ->
@ -455,21 +455,21 @@ self.OS.GUI =
startAntOS: (conf) -> startAntOS: (conf) ->
# clean up things # clean up things
_OS.cleanup() Ant.OS.cleanup()
# get setting from conf # get setting from conf
_OS.systemSetting conf Ant.OS.systemSetting conf
#console.log _OS.setting #console.log Ant.OS.setting
# load theme # load theme
_GUI.loadTheme _OS.setting.appearance.theme Ant.OS.GUI.loadTheme Ant.OS.setting.appearance.theme
_GUI.wallpaper() Ant.OS.GUI.wallpaper()
_courrier.observable.one "syspanelloaded", () -> Ant.OS.announcer.observable.one "syspanelloaded", () ->
# TODO load packages list then build system menu # TODO load packages list then build system menu
_courrier.observable.on "systemlocalechange", (name) -> Ant.OS.announcer.observable.on "systemlocalechange", (name) ->
($ "#syspanel")[0].update() ($ "#syspanel")[0].update()
_API.packages.cache (ret) -> Ant.OS.API.packages.cache (ret) ->
if ret.result if ret.result
_API.packages.fetch (r) -> Ant.OS.API.packages.fetch (r) ->
if r.result if r.result
for k, v of r.result for k, v of r.result
v.text = v.name v.text = v.name
@ -478,14 +478,14 @@ self.OS.GUI =
v.mime = "antos/app" v.mime = "antos/app"
v.icon = "#{v.path}/#{v.icon}" if v.icon v.icon = "#{v.path}/#{v.icon}" if v.icon
v.iconclass = "fa fa-adn" unless v.iconclass or v.icon v.iconclass = "fa fa-adn" unless v.iconclass or v.icon
_OS.setting.system.packages = if r.result then r.result else Ant.OS.setting.system.packages = if r.result then r.result else
_GUI.refreshSystemMenu() Ant.OS.GUI.refreshSystemMenu()
_GUI.buildSystemMenu() Ant.OS.GUI.buildSystemMenu()
# push startup services # push startup services
# TODO: get services list from user setting # TODO: get services list from user setting
_GUI.pushServices (v for v in _OS.setting.system.startup.services) Ant.OS.GUI.pushServices (v for v in Ant.OS.setting.system.startup.services)
(_GUI.launch a) for a in _OS.setting.system.startup.apps (Ant.OS.GUI.launch a) for a in Ant.OS.setting.system.startup.apps
#_GUI.launch "DummyApp" #Ant.OS.GUI.launch "DummyApp"
# initDM # initDM
_API.setLocale _OS.setting.system.locale, () -> Ant.OS.API.setLocale Ant.OS.setting.system.locale, () ->
_GUI.initDM() 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 # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #along with this program. If not, see https://www.gnu.org/licenses/.
self.OS.API.handler = Ant.OS.API.handle =
scandir: (p, c ) -> scandir: (p, c ) ->
path = 'resources/jsons/scandir.json' path = 'resources/jsons/scandir.json'
_API.get path , c, (e, s) -> Ant.OS.API.get path , c, (e, s) ->
_courrier.osfail "System fall: Cannot read #{path}", 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 # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #along with this program. If not, see https://www.gnu.org/licenses/.
self.OS.systemSetting = (conf) -> self.OS.systemSetting = (conf) ->
_OS.setting.desktop = conf.desktop if conf.desktop Ant.OS.setting.desktop = conf.desktop if conf.desktop
_OS.setting.applications = conf.applications if conf.applications Ant.OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance Ant.OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.appearance.wp = { Ant.OS.setting.appearance.wp = {
url: "os://resources/themes/system/wp/wp2.jpg", url: "os://resources/themes/system/wp/wp2.jpg",
size: "cover", size: "cover",
repeat: "repeat" repeat: "repeat"
} unless _OS.setting.appearance.wp } unless Ant.OS.setting.appearance.wp
_OS.setting.appearance.wps = [] unless _OS.setting.appearance.wps Ant.OS.setting.appearance.wps = [] unless Ant.OS.setting.appearance.wps
_OS.setting.applications = {} unless _OS.setting.applications Ant.OS.setting.applications = {} unless Ant.OS.setting.applications
_OS.setting.user = conf.user Ant.OS.setting.user = conf.user
_OS.setting.VFS = conf.VFS if conf.VFS Ant.OS.setting.VFS = conf.VFS if conf.VFS
_OS.setting.desktop.path = "home://.desktop" unless _OS.setting.desktop.path Ant.OS.setting.desktop.path = "home://.desktop" unless Ant.OS.setting.desktop.path
_OS.setting.desktop.menu = {} unless _OS.setting.desktop.menu Ant.OS.setting.desktop.menu = {} unless Ant.OS.setting.desktop.menu
_OS.setting.VFS.mountpoints = [ Ant.OS.setting.VFS.mountpoints = [
#TODO: multi app try to write to this object, it neet to be cloned #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: "__(Applications)", path: 'app://', iconclass: "fa fa-adn", type: "app" },
{ text: "__(Home)", path: 'home://', iconclass: "fa fa-home", type: "fs" }, { 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: "__(OS)", path: 'os://', iconclass: "fa fa-inbox", type: "fs" },
{ text: "__(Google Drive)", path: 'gdv://', 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" } { 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 Ant.OS.setting.system = conf.system if conf.system
_OS.setting.system.startup = { Ant.OS.setting.system.startup = {
services: [ services: [
"CoreServices/PushNotification", "CoreServices/PushNotification",
"CoreServices/UserService", "CoreServices/UserService",
@ -49,30 +49,30 @@
"CoreServices/Spotlight" "CoreServices/Spotlight"
], ],
apps: [] 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", user: "home://.packages",
system: "os://packages" system: "os://packages"
} unless _OS.setting.system.pkgpaths } unless Ant.OS.setting.system.pkgpaths
_OS.setting.system.locale = "en_GB" unless _OS.setting.system.locale Ant.OS.setting.system.locale = "en_GB" unless Ant.OS.setting.system.locale
_OS.setting.system.menu = {} unless _OS.setting.system.menu Ant.OS.setting.system.menu = {} unless Ant.OS.setting.system.menu
_OS.setting.system.repositories = [] unless _OS.setting.system.repositories Ant.OS.setting.system.repositories = [] unless Ant.OS.setting.system.repositories
_OS.setting.appearance.theme = "antos" unless _OS.setting.appearance.theme Ant.OS.setting.appearance.theme = "antos" unless Ant.OS.setting.appearance.theme
_OS.setting.VFS.gdrive = { Ant.OS.setting.VFS.gdrive = {
CLIENT_ID: "" CLIENT_ID: ""
API_KEY: "" API_KEY: ""
apilink: "https://apis.google.com/js/api.js" apilink: "https://apis.google.com/js/api.js"
DISCOVERY_DOCS: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"] DISCOVERY_DOCS: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"]
SCOPES: 'https://www.googleapis.com/auth/drive' SCOPES: 'https://www.googleapis.com/auth/drive'
} unless _OS.setting.VFS.gdrive } unless Ant.OS.setting.VFS.gdrive
#search for app #search for app
_API.onsearch "__(Applications)", (t) -> Ant.OS.API.onsearch "__(Applications)", (t) ->
ar = [] ar = []
term = new RegExp t, "i" 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) if (v.name.match term) or (v.description and v.description.match term)
v1 = {} v1 = {}
v1[k1] = e for k1, e of v when k1 isnt "selected" v1[k1] = e for k1, e of v when k1 isnt "selected"

View File

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

View File

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

View File

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

View File

@ -15,24 +15,24 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #along with this program. If not, see https://www.gnu.org/licenses/.
String.prototype.asFileHandler = () -> String.prototype.asFileHandle = () ->
list = @split "://" list = @split "://"
handlers = _API.VFS.findHandlers list[0] handles = Ant.OS.API.VFS.findHandles list[0]
if not handlers or handlers.length is 0 if not handles or handles.length is 0
_courrier.osfail __("VFS unknown handler: {0}", @), (_API.throwe "OS.VFS"), @ Ant.OS.announcer.osfail __("VFS unknown handle: {0}", @), (Ant.OS.API.throwe "OS.VFS"), @
return null return null
return new handlers[0](@) return new handles[0](@)
this.OS.API.VFS = this.OS.API.VFS =
handlers: { } handles: { }
register: ( protos, cls ) -> register: ( protos, cls ) ->
return self.OS.API.VFS.handlers[protos] = cls # if typeof protos is "string" return Ant.OS.API.VFS.handles[protos] = cls # if typeof protos is "string"
#_API.VFS.handlers[v] = cls for v in protos #Ant.OS.API.VFS.handles[v] = cls for v in protos
findHandlers: (proto) -> findHandles: (proto) ->
l = (v for k, v of _API.VFS.handlers when proto.trim().match (new RegExp k , "g")) l = (v for k, v of Ant.OS.API.VFS.handles when proto.trim().match (new RegExp k , "g"))
return l return l
class BaseFileHandler class BaseFileHandle
constructor: (path) -> constructor: (path) ->
@dirty = false @dirty = false
@cache = undefined @cache = undefined
@ -50,7 +50,7 @@ class BaseFileHandler
@genealogy = re.split("/") @genealogy = re.split("/")
@basename = @genealogy[@genealogy.length - 1] unless @isRoot() @basename = @genealogy[@genealogy.length - 1] unless @isRoot()
@ext = @basename.split( "." ).pop() unless @basename.lastIndexOf(".") is 0 or @basename.indexOf( "." ) is -1 @ext = @basename.split( "." ).pop() unless @basename.lastIndexOf(".") is 0 or @basename.indexOf( "." ) is -1
asFileHandler: () -> asFileHandle: () ->
@ @
isRoot: () -> (not @genealogy) or (@genealogy.size is 0) isRoot: () -> (not @genealogy) or (@genealogy.size is 0)
@ -82,7 +82,7 @@ class BaseFileHandler
reader.onload = () -> reader.onload = () ->
f reader.result f reader.result
reader.onerror = (e) -> 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: () -> parent: () ->
return @ if @isRoot() return @ if @isRoot()
return (@protocol + "://" + (@genealogy.slice 0 , @genealogy.length - 1).join "/") return (@protocol + "://" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
@ -93,7 +93,7 @@ class BaseFileHandler
me = @ me = @
me.meta (d) -> me.meta (d) ->
if d.error 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.info = d.result
me.ready = true me.ready = true
f() f()
@ -105,30 +105,30 @@ class BaseFileHandler
write: (d, f) -> write: (d, f) ->
me = @ me = @
@action "write", d, (r) -> @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 f r
mk: (d, f) -> mk: (d, f) ->
me = @ me = @
@onready (() -> me.action "mk", d, (r) -> @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) f r)
remove: (f) -> remove: (f) ->
me = @ me = @
@onready (() -> me.action "remove", null, (r) -> @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) f r)
upload: (f) -> upload: (f) ->
me = @ me = @
@onready (() -> me.action "upload", null, (r) -> @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) f r)
publish: (f) -> publish: (f) ->
me = @ me = @
@onready (() -> me.action "publish", null, (r) -> @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) f r)
download: (f) -> download: (f) ->
me = @ me = @
@ -137,7 +137,7 @@ class BaseFileHandler
move: (d, f) -> move: (d, f) ->
me = @ me = @
@onready (() -> me.action "move", d, (r) -> @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) f r)
execute: (f) -> execute: (f) ->
@ -152,61 +152,61 @@ class BaseFileHandler
# for main action read, write, remove, execute # for main action read, write, remove, execute
# must be implemented by subclasses # must be implemented by subclasses
action: (n, p, f) -> 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 # now export the class
self.OS.API.VFS.BaseFileHandler = BaseFileHandler Ant.OS.API.VFS.BaseFileHandle = BaseFileHandle
# Remote file handle # Remote file handle
class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler class RemoteFileHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path) -> constructor: (path) ->
super path super path
meta: (f) -> meta: (f) ->
_API.handler.fileinfo @path, f Ant.OS.API.handle.fileinfo @path, f
getlink: () -> getlink: () ->
_API.handler.get + "/" + @path Ant.OS.API.handle.get + "/" + @path
action: (n, p, f) -> action: (n, p, f) ->
me = @ me = @
switch n switch n
when "read" 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 #read the file
return _API.handler.fileblob @path, f if p is "binary" return Ant.OS.API.handle.fileblob @path, f if p is "binary"
_API.handler.readfile @path, f, if p then p else "text" Ant.OS.API.handle.readfile @path, f, if p then p else "text"
when "mk" when "mk"
return f { error: __("{0} is not a directory", @path) } if @info.type is "file" 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" 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) -> @sendB64 p, (data) ->
_API.handler.write me.path, data, f Ant.OS.API.handle.write me.path, data, f
when "upload" when "upload"
return if @info.type is "file" return if @info.type is "file"
_API.handler.upload @path, f Ant.OS.API.handle.upload @path, f
when "remove" when "remove"
_API.handler.delete @path, f Ant.OS.API.handle.delete @path, f
when "publish" when "publish"
_API.handler.sharefile @path, true , f Ant.OS.API.handle.sharefile @path, true , f
when "download" when "download"
return if @info.type is "dir" 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" } blob = new Blob [d], { type: "octet/stream" }
_API.saveblob me.basename, blob Ant.OS.API.saveblob me.basename, blob
when "move" when "move"
_API.handler.move @path, p, f Ant.OS.API.handle.move @path, p, f
else 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 # Application Handle
class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler class ApplicationHandle extends Ant.OS.API.VFS.BaseFileHandle
constructor: (path) -> constructor: (path) ->
super path super path
@info = _OS.setting.system.packages[@basename] if @basename @info = Ant.OS.setting.system.packages[@basename] if @basename
@ready = true @ready = true
meta: (f) -> meta: (f) ->
@ -218,7 +218,7 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "read" when "read"
return f { result: @info } if @info return f { result: @info } if @info
return unless @isRoot() 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" when "mk"
return return
@ -241,11 +241,11 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "move" when "move"
return return
else 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) -> constructor: (path, mime, data) ->
super path super path
@cache = data if data @cache = data if data
@ -286,16 +286,16 @@ class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
return return
when "download" when "download"
blob = new Blob [@cache], { type: "octet/stream" } blob = new Blob [@cache], { type: "octet/stream" }
_API.saveblob me.basename, blob Ant.OS.API.saveblob me.basename, blob
when "move" when "move"
return return
else 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) -> constructor: (path) ->
super path super path
@ready = true @ready = true
@ -305,38 +305,38 @@ class URLFileHandler extends self.OS.API.VFS.BaseFileHandler
me = @ me = @
switch n switch n
when "read" when "read"
_API.get @path, (d) -> Ant.OS.API.get @path, (d) ->
f(d) f(d)
, (e, s) -> , (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" , if p then p else "text"
else else
return _courrier.oserror __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n return Ant.OS.announcer.oserror __("VFS unknown action: {0}", n), (Ant.OS.API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^(http|https)$", URLFileHandler 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) -> constructor: (path) ->
super path super path
@ready = true if @isRoot() @ready = true if @isRoot()
meta: (f) -> meta: (f) ->
_API.handler.fileinfo @path, f Ant.OS.API.handle.fileinfo @path, f
action: (n, p, f) -> action: (n, p, f) ->
me = @ me = @
switch n switch n
when "read" 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 #read the file
return _API.handler.fileblob @path, f if p is "binary" return Ant.OS.API.handle.fileblob @path, f if p is "binary"
_API.handler.readfile @path, f, if p then p else "text" Ant.OS.API.handle.readfile @path, f, if p then p else "text"
when "mk" when "mk"
return return
when "write" when "write"
_API.handler.write @path, p, f Ant.OS.API.handle.write @path, p, f
when "remove" when "remove"
_API.handler.sharefile @basename, false, f Ant.OS.API.handle.sharefile @basename, false, f
when "upload" when "upload"
return return
@ -346,12 +346,12 @@ class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
when "download" when "download"
return if @info.type is "dir" 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" } blob = new Blob [d], { type: "octet/stream" }
_API.saveblob me.basename, blob Ant.OS.API.saveblob me.basename, blob
when "move" when "move"
return return
else 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 # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #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' } } 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) -> constructor: (path) ->
super path super path
me = @ me = @
@setting = _OS.setting.VFS.gdrive @setting = Ant.OS.setting.VFS.gdrive
return _courrier.oserror __("Unknown API setting for {0}", "GAPI"), (_API.throwe "OS.VFS"), null unless @setting return Ant.OS.announcer.oserror __("Unknown API setting for {0}", "GAPI"), (Ant.OS.API.throwe "OS.VFS"), null unless @setting
@gid = 'root' if @isRoot() @gid = 'root' if @isRoot()
@cache = "" @cache = ""
@ -38,16 +38,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
G_CACHE = {"gdv://":{ id: "root", mime: 'dir' } } G_CACHE = {"gdv://":{ id: "root", mime: 'dir' } }
gapi.auth2.getAuthInstance().signIn() gapi.auth2.getAuthInstance().signIn()
if _API.libready @setting.apilink if Ant.OS.API.libready @setting.apilink
gapi.auth2.getAuthInstance().isSignedIn.listen (r) -> gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r) fn(r)
fn(gapi.auth2.getAuthInstance().isSignedIn.get()) fn(gapi.auth2.getAuthInstance().isSignedIn.get())
else else
_API.require @setting.apilink, () -> Ant.OS.API.require @setting.apilink, () ->
# avoid popup block # avoid popup block
q = _courrier.getMID() q = Ant.OS.announcer.getMID()
gapi.load "client:auth2", () -> gapi.load "client:auth2", () ->
_API.loading q, "GAPI" Ant.OS.API.loading q, "GAPI"
gapi.client.init { gapi.client.init {
apiKey: me.setting.API_KEY, apiKey: me.setting.API_KEY,
clientId: me.setting.CLIENT_ID, clientId: me.setting.CLIENT_ID,
@ -55,45 +55,45 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
scope: me.setting.SCOPES scope: me.setting.SCOPES
} }
.then () -> .then () ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
gapi.auth2.getAuthInstance().isSignedIn.listen (r) -> gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r) fn(r)
_GUI.openDialog "YesNoDialog", (d) -> _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()) fn(gapi.auth2.getAuthInstance().isSignedIn.get())
, __("Authentication") , __("Authentication")
, { text: __("Would you like to login to {0}?", "Google Drive") } , { text: __("Would you like to login to {0}?", "Google Drive") }
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot init {0}: {1}", "GAPI",err.error), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot init {0}: {1}", "GAPI",err.error), (Ant.OS.API.throwe "OS.VFS"), err
meta: (f) -> meta: (f) ->
me = @ me = @
@oninit () -> @oninit () ->
q = _courrier.getMID() q = Ant.OS.announcer.getMID()
me.gid = G_CACHE[me.path].id if G_CACHE[me.path] me.gid = G_CACHE[me.path].id if G_CACHE[me.path]
if me.gid if me.gid
#console.log "Gid exists ", me.gid #console.log "Gid exists ", me.gid
_API.loading q, "GAPI" Ant.OS.API.loading q, "GAPI"
gapi.client.drive.files.get { gapi.client.drive.files.get {
fileId: me.gid, fileId: me.gid,
fields: me.fields() fields: me.fields()
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return unless r.result return unless r.result
r.result.mime = r.result.mimeType r.result.mime = r.result.mimeType
f(r) f(r)
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot get meta data for {0}", me.gid), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot get meta data for {0}", me.gid), (Ant.OS.API.throwe "OS.VFS"), err
else else
#console.log "Find file in ", me.parent() #console.log "Find file in ", me.parent()
fp = me.parent().asFileHandler() fp = me.parent().asFileHandle()
fp.meta (d) -> fp.meta (d) ->
file = d.result file = d.result
q1 = _courrier.getMID() q1 = Ant.OS.announcer.getMID()
_API.loading q1, "GAPI" Ant.OS.API.loading q1, "GAPI"
G_CACHE[fp.path] = { id: file.id, mime: file.mimeType } G_CACHE[fp.path] = { id: file.id, mime: file.mimeType }
gapi.client.drive.files.list { gapi.client.drive.files.list {
q: "name = '#{me.basename}' and '#{file.id}' in parents and trashed = false", 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) -> .then (r) ->
#console.log 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 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 } 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 r.result.files[0].mime = r.result.files[0].mimeType
f { result: r.result.files[0] } f { result: r.result.files[0] }
.catch (err) -> .catch (err) ->
_API.loaded q1, "FAIL" Ant.OS.API.loaded q1, "FAIL"
_courrier.oserror __("VFS cannot get meta data for {0}", me.path), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot get meta data for {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
fields: () -> fields: () ->
return "webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size" 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 = @ me = @
user = gapi.auth2.getAuthInstance().currentUser.get() user = gapi.auth2.getAuthInstance().currentUser.get()
oauthToken = user.getAuthResponse().access_token oauthToken = user.getAuthResponse().access_token
q = _courrier.getMID() q = Ant.OS.announcer.getMID()
xhr = new XMLHttpRequest() xhr = new XMLHttpRequest()
url = 'https://www.googleapis.com/upload/drive/v3/files/' + id + '?uploadType=media' url = 'https://www.googleapis.com/upload/drive/v3/files/' + id + '?uploadType=media'
xhr.open('PATCH', url) xhr.open('PATCH', url)
@ -127,14 +127,14 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
xhr.setRequestHeader 'Content-Type', m xhr.setRequestHeader 'Content-Type', m
xhr.setRequestHeader 'Content-Encoding', 'base64' xhr.setRequestHeader 'Content-Encoding', 'base64'
xhr.setRequestHeader 'Content-Transfer-Encoding', 'base64' xhr.setRequestHeader 'Content-Transfer-Encoding', 'base64'
_API.loading q, "GAPI" Ant.OS.API.loading q, "GAPI"
error = (e, s) -> error = (e, s) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot save : {0}", me.path), e, s Ant.OS.announcer.oserror __("VFS cannot save : {0}", me.path), e, s
xhr.onreadystatechange = () -> xhr.onreadystatechange = () ->
if ( xhr.readyState == 4 ) if ( xhr.readyState == 4 )
if ( xhr.status == 200 ) if ( xhr.status == 200 )
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
f { result: JSON.parse(xhr.responseText) } f { result: JSON.parse(xhr.responseText) }
else else
error xhr, xhr.status error xhr, xhr.status
@ -150,8 +150,8 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
action: (n, p, f) -> action: (n, p, f) ->
me = @ me = @
q = _courrier.getMID() q = Ant.OS.announcer.getMID()
_API.loading q, "GAPI" Ant.OS.API.loading q, "GAPI"
switch n switch n
when "read" when "read"
return unless @info.id return unless @info.id
@ -161,7 +161,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: "files(#{me.fields()})" fields: "files(#{me.fields()})"
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return unless r.result.files return unless r.result.files
for file in r.result.files for file in r.result.files
file.path = me.child file.name 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 } G_CACHE[file.path] = { id: file.gid, mime: file.mime }
f { result: r.result.files } f { result: r.result.files }
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot read : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
else else
gapi.client.drive.files.get { gapi.client.drive.files.get {
fileId: me.info.id, fileId: me.info.id,
alt: 'media' alt: 'media'
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return f r.body unless p is "binary" return f r.body unless p is "binary"
f r.body.asUint8Array() f r.body.asUint8Array()
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot read : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "mk" when "mk"
return f { error: __("{0} is not a directory", @path) } unless @isFolder() 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' fields: 'id'
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
#console.log r #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" } G_CACHE[me.child p] = { id: r.result.id, mime: "dir" }
f r f r
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot create : {0}", p), (Ant.OS.API.throwe "OS.VFS"), err
return return
@ -218,10 +218,10 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
gid = undefined gid = undefined
gid = G_CACHE[me.path].id if G_CACHE[me.path] gid = G_CACHE[me.path].id if G_CACHE[me.path]
if gid if gid
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
@save gid, p, f @save gid, p, f
else else
dir = @parent().asFileHandler() dir = @parent().asFileHandle()
dir.onready () -> dir.onready () ->
meta = meta =
name: me.basename, name: me.basename,
@ -233,29 +233,29 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: 'id' fields: 'id'
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return _courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), r unless r and r.result 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 } G_CACHE[me.path] = { id: r.result.id, mime: p }
me.save r.result.id, p, f me.save r.result.id, p, f
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot write : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "upload" when "upload"
return unless @isFolder() return unless @isFolder()
#insert a temporal file selector #insert a temporal file selector
o = ($ '<input>').attr('type', 'file').css("display", "none") o = ($ '<input>').attr('type', 'file').css("display", "none")
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
o.change () -> o.change () ->
#_API.loading q, p #Ant.OS.API.loading q, p
fo = o[0].files[0] fo = o[0].files[0]
file = (me.child fo.name).asFileHandler() file = (me.child fo.name).asFileHandle()
file.cache = fo file.cache = fo
file.write fo.type, f file.write fo.type, f
o.remove() o.remove()
#_API.loaded q, p, "OK" #Ant.OS.API.loaded q, p, "OK"
#_API.loaded q, p, "FAIL" #Ant.OS.API.loaded q, p, "FAIL"
o.click() o.click()
@ -266,16 +266,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
} }
.then (r) -> .then (r) ->
#console.log r #console.log r
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return _courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), r unless r 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 G_CACHE[me.path] = null
f { result: true } f { result: true }
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot delete : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "publish" when "publish"
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return return
when "download" when "download"
@ -284,20 +284,20 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
alt: 'media' alt: 'media'
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return _courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), r unless r.body return Ant.OS.announcer.oserror __("VFS cannot download file : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), r unless r.body
bytes = [] bytes = []
for i in [0..(r.body.length - 1)] for i in [0..(r.body.length - 1)]
bytes.push r.body.charCodeAt i bytes.push r.body.charCodeAt i
bytes = new Uint8Array(bytes) bytes = new Uint8Array(bytes)
blob = new Blob [bytes], { type: "octet/stream" } blob = new Blob [bytes], { type: "octet/stream" }
_API.saveblob me.basename, blob Ant.OS.API.saveblob me.basename, blob
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot download file : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), err
when "move" when "move"
dest = p.asFileHandler().parent().asFileHandler() dest = p.asFileHandle().parent().asFileHandle()
dest.onready () -> dest.onready () ->
previousParents = me.info.parents.join ',' previousParents = me.info.parents.join ','
gapi.client.drive.files.update { gapi.client.drive.files.update {
@ -307,27 +307,27 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fields: "id" fields: "id"
} }
.then (r) -> .then (r) ->
_API.loaded q, "OK" Ant.OS.API.loaded q, "OK"
return _courrier.oserror __("VFS cannot move : {0}", me.path), (_API.throwe "OS.VFS"), r unless r return Ant.OS.announcer.oserror __("VFS cannot move : {0}", me.path), (Ant.OS.API.throwe "OS.VFS"), r unless r
f r f r
.catch (err) -> .catch (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
_courrier.oserror __("VFS cannot move : {0}", me.gid), (_API.throwe "OS.VFS"), err Ant.OS.announcer.oserror __("VFS cannot move : {0}", me.gid), (Ant.OS.API.throwe "OS.VFS"), err
, (err) -> , (err) ->
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
else else
_API.loaded q, "FAIL" Ant.OS.API.loaded q, "FAIL"
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 "^gdv$", GoogleDriveHandler self.OS.API.VFS.register "^gdv$", GoogleDriveHandle
# search the cache for file # search the cache for file
self.OS.API.onsearch "Google Drive", (t) -> self.OS.API.onsearch "Google Drive", (t) ->
arr = [] arr = []
term = new RegExp t, "i" term = new RegExp t, "i"
for k, v of G_CACHE for k, v of G_CACHE
if (k.match term) or (v and v.mime.match term) if (k.match term) or (v and v.mime.match term)
file = k.asFileHandler() file = k.asFileHandle()
file.text = file.basename file.text = file.basename
file.mime = v.mime file.mime = v.mime
file.iconclass = "fa fa-file" file.iconclass = "fa fa-file"
@ -339,7 +339,7 @@ self.OS.API.onsearch "Google Drive", (t) ->
self.OS.onexit "cleanUpGoogleDrive", () -> self.OS.onexit "cleanUpGoogleDrive", () ->
G_CACHE = { "gdv://": { id: "root", mime: 'dir' } } 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() auth2 = gapi.auth2.getAuthInstance()
return unless auth2 return unless auth2
if auth2.isSignedIn.get() if auth2.isSignedIn.get()