From 9cd133194ecae96981d45e17e906ebd90b6edb46 Mon Sep 17 00:00:00 2001 From: lxsang Date: Tue, 12 Oct 2021 12:22:12 +0200 Subject: [PATCH] add vfsx protocol --- Antunnel/build.json | 81 ++++ Antunnel/build/debug/main.js | 2 +- Antunnel/build/release/Antunnel.zip | Bin 7322 -> 2821 bytes Antunnel/coffees/AntunnelService.coffee | 6 +- Antunnel/project.json | 7 - packages.json | 10 + vfsx/README.md | 10 + vfsx/build.json | 83 ++++ vfsx/build/debug/README.md | 10 + vfsx/build/debug/package.json | 39 ++ vfsx/build/debug/vfsx.js | 1 + vfsx/build/release/vfsx.zip | Bin 0 -> 4185 bytes vfsx/gdv.ts | 619 ++++++++++++++++++++++++ vfsx/package.json | 39 ++ 14 files changed, 897 insertions(+), 10 deletions(-) create mode 100644 Antunnel/build.json delete mode 100644 Antunnel/project.json create mode 100644 vfsx/README.md create mode 100644 vfsx/build.json create mode 100644 vfsx/build/debug/README.md create mode 100644 vfsx/build/debug/package.json create mode 100644 vfsx/build/debug/vfsx.js create mode 100644 vfsx/build/release/vfsx.zip create mode 100644 vfsx/gdv.ts create mode 100644 vfsx/package.json diff --git a/Antunnel/build.json b/Antunnel/build.json new file mode 100644 index 0000000..3afc3e6 --- /dev/null +++ b/Antunnel/build.json @@ -0,0 +1,81 @@ +{ + "name": "Antunnel", + "targets": { + "init": { + "jobs": [ + { + "name": "vfs-mkdir", + "data": [ + "build", + "build/debug", + "build/release" + ] + } + ] + }, + "coffee": { + "require": [ + "coffee" + ], + "jobs": [ + { + "name": "coffee-compile", + "data": { + "src": [ + "coffees/Antunnel.coffee", + "coffees/AntunnelService.coffee" + ], + "dest": "build/debug/main.js" + } + } + ] + }, + "uglify": { + "require": [ + "terser" + ], + "jobs": [ + { + "name": "terser-uglify", + "data": [ + "build/debug/main.js" + ] + } + ] + }, + "copy": { + "jobs": [ + { + "name": "vfs-cp", + "data": { + "src": [ + "package.json", + "README.md" + ], + "dest": "build/debug" + } + } + ] + }, + "release": { + "require": [ + "zip" + ], + "depend": [ + "init", + "coffee", + "copy", + "uglify" + ], + "jobs": [ + { + "name": "zip-mk", + "data": { + "src": "build/debug", + "dest": "build/release/Antunnel.zip" + } + } + ] + } + } +} \ No newline at end of file diff --git a/Antunnel/build/debug/main.js b/Antunnel/build/debug/main.js index c337629..e478e97 100644 --- a/Antunnel/build/debug/main.js +++ b/Antunnel/build/debug/main.js @@ -1 +1 @@ -(function(){var e,n,t,s,i;(t=class e{constructor(){this.header={sid:0,cid:0,type:0,size:0},this.data=void 0}as_raw(){var n,t,s;return s=13+this.header.size,(n=new Uint8Array(s)).set(e.MAGIC_START,0),n[2]=this.header.type,t=e.bytes_of(this.header.cid),n.set(t,3),t=e.bytes_of(this.header.sid),n.set(t,5),t=e.bytes_of(this.header.size,4),n.set(t,7),this.data&&n.set(this.data,11),n.set(e.MAGIC_END,this.header.size+11),n.buffer}}).decode=function(e){return new Promise((function(n,s){var i;return i=new t,t.int_from(t.MAGIC_START,0)!==t.int_from(e,0)?s("Unmatch message begin magic number"):(i.header.type=e[2],i.header.cid=t.int_from(e,3),i.header.sid=t.int_from(e,5),i.header.size=t.int_from(e,7,4),i.data=e.slice(11,11+i.header.size),t.int_from(t.MAGIC_END,0)!==t.int_from(e,11+i.header.size)?s("Unmatch message end magic number"):n(i))}))},t.bytes_of=function(e,n){var t;return 4!==n&&(n=2),(t=new Uint8Array(n))[0]=255&e,e>>=8,t[1]=255&e,4!==n||(e>>=8,t[2]=255&e,e>>=8,t[3]=255&e),t},t.int_from=function(e,n,t){return 4!==t?e[n]|e[n+1]<<8:e[n]|e[n+1]<<8|e[n+2]<<16|e[n+3]<<24},t.OK=0,t.ERROR=1,t.DATA=6,t.CLOSE=5,t.SUBSCRIBE=2,t.UNSUBSCRIBE=3,t.CTRL=7,t.PING=8,t.MAGIC_END=[68,84],t.MAGIC_START=[78,65],s=class{constructor(e){this.channel=e,this.id=void 0,this.channel_id=void 0,this.onmessage=void 0,this.onerror=void 0,this.onopen=void 0,this.onclose=void 0,this.tunnel=void 0,this.is_opened=!1}send(e,n){if(this.tunnel){if(this.is_opened)return this.tunnel.send(this.genmsg(e,n));this.onerror&&this.onerror("Channel is not opened yet")}else this.onerror&&this.onerror("Tunnel is not opened")}genmsg(e,n){var s;return(s=new t).header.sid=this.id,s.header.cid=this.channel_id,s.header.type=e,s.header.size=n?n.length:0,s.data=n,s}close(e){if(this.is_opened=!1,this.tunnel)return this.tunnel.unsubscribe(this,e)}},e=class{constructor(e){this.uri=e,this.socket=void 0,this.pending={},this.subscribers={},this.onclose=void 0}ready(){return new Promise((e,n)=>this.uri?void 0!==this.socket?e():(console.log("Connect to "+this.uri),this.socket=new WebSocket(this.uri),this.socket.binaryType="arraybuffer",this.socket.onmessage=e=>this.process(e),this.socket.onclose=e=>{var n,t,s,i;for(n in this.socket=void 0,t=this.pending)(i=t[n]).tunnel=void 0,i.onclose&&i.onclose();for(n in s=this.subscribers)(i=s[n]).tunnel=void 0,i.is_opened=!1,i.onclose&&i.onclose();if(this.pending={},this.subscribe={},this.onclose())return this.onclose()},this.socket.onerror=e=>{var n,t,s,i,r;for(n in t=this.pending)(r=t[n]).onerror&&r.onerror(e.toString());for(n in i=[],s=this.subscribers)(r=s[n]).onerror&&i.push(r.onerror(e.toString()));return i},this.socket.onopen=n=>e()):n())}process(e){return t.decode(new Uint8Array(e.data)).then(e=>{var n,s;switch(n=(e,n)=>{var t;if(!(t=this.pending[e.header.sid]))return(t=this.subscribers[e.header.sid])&&t[n]?t[n](e):void 0;t[n]&&t[n](e)},e.header.type){case t.OK:if(!(s=this.pending[e.header.sid]))return n(e,"onmessage");if(delete this.pending[e.header.sid],s.id=t.int_from(e.data,0),s.channel_id=e.header.cid,this.subscribers[s.id]=s,s.is_opened=!0,s.onopen)return s.onopen();break;case t.DATA:return n(e,"onmessage");case t.CTRL:return n(e,"onctrl");case t.ERROR:return n(e,"onerror");case t.UNSUBSCRIBE:if(!(s=this.subscribers[e.header.sid]))return;return s.close(!0);case t.PING:break;default:return console.error(`Message of type ${e.header.type} is unsupported`,e)}}).catch(e=>{var n,t,s,i;for(n in t=this.pending)(i=t[n]).onerror&&i.onerror(e);for(n in s=this.subscribers)(i=s[n]).onerror&&i.onerror(e);return console.log(e)})}subscribe(e){return this.ready().then(()=>{for(e.tunnel=this,e.id=Math.floor(1e3*Math.random())+1;this.subscribers[e.id]||this.pending[e.id];)e.id=Math.floor(1e3*Math.random())+1;return this.pending[e.id]=e,this.send(e.genmsg(t.SUBSCRIBE,(new TextEncoder).encode(e.channel)))}).catch((function(n){if(e.onerror)return e.onerror(n.toString())}))}unsubscribe(e,n){return this.ready().then(()=>{if(this.subscribers[e.id])return n||this.send(e.genmsg(t.UNSUBSCRIBE,void 0)),e.onclose&&e.onclose(),delete this.subscribers[e.id],e.tunnel=void 0,e.is_opened=!1}).catch((function(n){if(e.onerror)return e.onerror(n.toString())}))}send(e){return this.socket.send(e.as_raw())}close(){if(console.log("Close connection to "+this.uri),this.socket&&this.socket.close(),this.onclose())return this.onclose()}},(i=this).Antunnel||(i.Antunnel={tunnel:void 0,init:function(n){return new Promise((function(t,s){return i.Antunnel.tunnel?t(i.Antunnel.tunnel):(i.Antunnel.tunnel=new e(n),i.Antunnel.tunnel.onclose=function(){return i.Antunnel.tunnel=void 0},i.Antunnel.tunnel.ready().then((function(){return t(i.Antunnel.tunnel)})).catch((function(e){return s(e)})))}))},Subscriber:s,Msg:t}),n=class extends OS.application.BaseService{constructor(e){super("AntunnelService",e),this.text=__("Tunnel"),this.iconclass="fa fa-close",this.is_connect=!1,this.nodes=[{text:__("Connect"),id:1},{text:__("Disconnect"),id:2},{text:__("Enter uri"),id:3},{text:__("Exit"),id:4}],this.onchildselect=e=>this.action(e)}init(){return this.watch(1500,()=>{var e;if(e=!1,void 0!==Antunnel.tunnel&&(e=!0),e!==this.is_connect)return this.is_connect=e,this.iconclass="fa fa-circle",this.is_connect||(this.iconclass="fa fa-close"),this.update()}),OS.onexit("cleanupAntunnel",()=>(Antunnel.tunnel&&Antunnel.tunnel.close(),this.quit()))}action(e){var n;switch(n=()=>this._gui.openDialog("PromptDialog",{title:__("Tunnel uri"),label:__("Please enter tunnel uri"),value:"wss://localhost/tunnel"}).then(e=>{if(e&&""!==e)return this.systemsetting.system.tunnel_uri=e,this.start()}),e.data.item.data.id){case 1:if(this.is_connect)return;return this.systemsetting.system.tunnel_uri?this.start():n();case 2:if(Antunnel.tunnel)return Antunnel.tunnel.close();break;case 3:return Antunnel.tunnel&&Antunnel.tunnel.close(),n();case 4:return Antunnel.tunnel&&Antunnel.tunnel.close(),this.quit()}}start(){if(this.systemsetting.system.tunnel_uri&&!Antunnel.tunnel)return Antunnel.init(this.systemsetting.system.tunnel_uri).then(e=>this.notify(__("Tunnel now connected to the server at: {0}",this.systemsetting.system.tunnel_uri))).catch(e=>(Antunnel.tunnel&&Antunnel.tunnel.close(),this.error(__("Unable to connect to the tunnel: {0}",e.toString()),e)))}awake(){}},this.OS.register("AntunnelService",n)}).call(this); \ No newline at end of file +(function(){var e,n,t,s,i;(t=class e{constructor(){this.header={sid:0,cid:0,type:0,size:0},this.data=void 0}as_raw(){var n,t,s;return s=13+this.header.size,(n=new Uint8Array(s)).set(e.MAGIC_START,0),n[2]=this.header.type,t=e.bytes_of(this.header.cid),n.set(t,3),t=e.bytes_of(this.header.sid),n.set(t,5),t=e.bytes_of(this.header.size,4),n.set(t,7),this.data&&n.set(this.data,11),n.set(e.MAGIC_END,this.header.size+11),n.buffer}}).decode=function(e){return new Promise((function(n,s){var i;return i=new t,t.int_from(t.MAGIC_START,0)!==t.int_from(e,0)?s("Unmatch message begin magic number"):(i.header.type=e[2],i.header.cid=t.int_from(e,3),i.header.sid=t.int_from(e,5),i.header.size=t.int_from(e,7,4),i.data=e.slice(11,11+i.header.size),t.int_from(t.MAGIC_END,0)!==t.int_from(e,11+i.header.size)?s("Unmatch message end magic number"):n(i))}))},t.bytes_of=function(e,n){var t;return 4!==n&&(n=2),(t=new Uint8Array(n))[0]=255&e,e>>=8,t[1]=255&e,4!==n||(e>>=8,t[2]=255&e,e>>=8,t[3]=255&e),t},t.int_from=function(e,n,t){return 4!==t?e[n]|e[n+1]<<8:e[n]|e[n+1]<<8|e[n+2]<<16|e[n+3]<<24},t.OK=0,t.ERROR=1,t.DATA=6,t.CLOSE=5,t.SUBSCRIBE=2,t.UNSUBSCRIBE=3,t.CTRL=7,t.PING=8,t.MAGIC_END=[68,84],t.MAGIC_START=[78,65],s=class{constructor(e){this.channel=e,this.id=void 0,this.channel_id=void 0,this.onmessage=void 0,this.onerror=void 0,this.onopen=void 0,this.onclose=void 0,this.tunnel=void 0,this.is_opened=!1}send(e,n){if(this.tunnel){if(this.is_opened)return this.tunnel.send(this.genmsg(e,n));this.onerror&&this.onerror("Channel is not opened yet")}else this.onerror&&this.onerror("Tunnel is not opened")}genmsg(e,n){var s;return(s=new t).header.sid=this.id,s.header.cid=this.channel_id,s.header.type=e,s.header.size=n?n.length:0,s.data=n,s}close(e){if(this.is_opened=!1,this.tunnel)return this.tunnel.unsubscribe(this,e)}},e=class{constructor(e){this.uri=e,this.socket=void 0,this.pending={},this.subscribers={},this.onclose=void 0}ready(){return new Promise((e,n)=>this.uri?void 0!==this.socket?e():(console.log("Connect to "+this.uri),this.socket=new WebSocket(this.uri),this.socket.binaryType="arraybuffer",this.socket.onmessage=e=>this.process(e),this.socket.onclose=e=>{var n,t,s,i;for(n in this.socket=void 0,t=this.pending)(i=t[n]).tunnel=void 0,i.onclose&&i.onclose();for(n in s=this.subscribers)(i=s[n]).tunnel=void 0,i.is_opened=!1,i.onclose&&i.onclose();if(this.pending={},this.subscribe={},this.onclose())return this.onclose()},this.socket.onerror=e=>{var n,t,s,i,r;for(n in t=this.pending)(r=t[n]).onerror&&r.onerror(e.toString());for(n in i=[],s=this.subscribers)(r=s[n]).onerror&&i.push(r.onerror(e.toString()));return i},this.socket.onopen=n=>e()):n())}process(e){return t.decode(new Uint8Array(e.data)).then(e=>{var n,s;switch(n=(e,n)=>{var t;if(!(t=this.pending[e.header.sid]))return(t=this.subscribers[e.header.sid])&&t[n]?t[n](e):void 0;t[n]&&t[n](e)},e.header.type){case t.OK:if(!(s=this.pending[e.header.sid]))return n(e,"onmessage");if(delete this.pending[e.header.sid],s.id=t.int_from(e.data,0),s.channel_id=e.header.cid,this.subscribers[s.id]=s,s.is_opened=!0,s.onopen)return s.onopen();break;case t.DATA:return n(e,"onmessage");case t.CTRL:return n(e,"onctrl");case t.ERROR:return n(e,"onerror");case t.UNSUBSCRIBE:if(!(s=this.subscribers[e.header.sid]))return;return s.close(!0);case t.PING:break;default:return console.error(`Message of type ${e.header.type} is unsupported`,e)}}).catch(e=>{var n,t,s,i;for(n in t=this.pending)(i=t[n]).onerror&&i.onerror(e);for(n in s=this.subscribers)(i=s[n]).onerror&&i.onerror(e);return console.log(e)})}subscribe(e){return this.ready().then(()=>{for(e.tunnel=this,e.id=Math.floor(1e3*Math.random())+1;this.subscribers[e.id]||this.pending[e.id];)e.id=Math.floor(1e3*Math.random())+1;return this.pending[e.id]=e,this.send(e.genmsg(t.SUBSCRIBE,(new TextEncoder).encode(e.channel)))}).catch((function(n){if(e.onerror)return e.onerror(n.toString())}))}unsubscribe(e,n){return this.ready().then(()=>{if(this.subscribers[e.id])return n||this.send(e.genmsg(t.UNSUBSCRIBE,void 0)),e.onclose&&e.onclose(),delete this.subscribers[e.id],e.tunnel=void 0,e.is_opened=!1}).catch((function(n){if(e.onerror)return e.onerror(n.toString())}))}send(e){return this.socket.send(e.as_raw())}close(){if(console.log("Close connection to "+this.uri),this.socket&&this.socket.close(),this.onclose())return this.onclose()}},(i=this).Antunnel||(i.Antunnel={tunnel:void 0,init:function(n){return new Promise((function(t,s){return i.Antunnel.tunnel?t(i.Antunnel.tunnel):(i.Antunnel.tunnel=new e(n),i.Antunnel.tunnel.onclose=function(){return i.Antunnel.tunnel=void 0},i.Antunnel.tunnel.ready().then((function(){return t(i.Antunnel.tunnel)})).catch((function(e){return s(e)})))}))},Subscriber:s,Msg:t}),n=class extends OS.application.BaseService{constructor(e){super("AntunnelService",e),this.text=__("Tunnel"),this.iconclass="fa fa-close",this.is_connect=!1,this.nodes=[{text:__("Connect"),id:1},{text:__("Disconnect"),id:2},{text:__("Enter uri"),id:3},{text:__("Exit"),id:4}],this.onchildselect=e=>this.action(e)}init(){return this.watch(1500,()=>{var e;if(e=!1,void 0!==Antunnel.tunnel&&(e=!0),e!==this.is_connect)return this.is_connect=e,this.iconclass="fa fa-circle",this.is_connect||(this.iconclass="fa fa-close"),this.update()}),OS.onexit("cleanupAntunnel",()=>new Promise((e,n)=>(Antunnel.tunnel&&Antunnel.tunnel.close(),this.quit(),e(!0))))}action(e){var n;switch(n=()=>this._gui.openDialog("PromptDialog",{title:__("Tunnel uri"),label:__("Please enter tunnel uri"),value:"wss://localhost/tunnel"}).then(e=>{if(e&&""!==e)return this.systemsetting.system.tunnel_uri=e,this.start()}),e.data.item.data.id){case 1:if(this.is_connect)return;return this.systemsetting.system.tunnel_uri?this.start():n();case 2:if(Antunnel.tunnel)return Antunnel.tunnel.close();break;case 3:return Antunnel.tunnel&&Antunnel.tunnel.close(),n();case 4:return Antunnel.tunnel&&Antunnel.tunnel.close(),this.quit()}}start(){if(this.systemsetting.system.tunnel_uri&&!Antunnel.tunnel)return Antunnel.init(this.systemsetting.system.tunnel_uri).then(e=>this.notify(__("Tunnel now connected to the server at: {0}",this.systemsetting.system.tunnel_uri))).catch(e=>(Antunnel.tunnel&&Antunnel.tunnel.close(),this.error(__("Unable to connect to the tunnel: {0}",e.toString()),e)))}awake(){}},this.OS.register("AntunnelService",n)}).call(this); \ No newline at end of file diff --git a/Antunnel/build/release/Antunnel.zip b/Antunnel/build/release/Antunnel.zip index 1038ee94978744bae681591fbc1cf9a55a4febd4..96d012b0d651fd5eeb703c7b8e865ad989fe23b4 100644 GIT binary patch literal 2821 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 literal 7322 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 diff --git a/Antunnel/coffees/AntunnelService.coffee b/Antunnel/coffees/AntunnelService.coffee index f60c287..047ff40 100644 --- a/Antunnel/coffees/AntunnelService.coffee +++ b/Antunnel/coffees/AntunnelService.coffee @@ -24,8 +24,10 @@ class AntunnelService extends OS.application.BaseService @iconclass = "fa fa-close" unless @is_connect @update() OS.onexit "cleanupAntunnel", () => - Antunnel.tunnel.close() if Antunnel.tunnel - @quit() + return new Promise (resolve, reject) => + Antunnel.tunnel.close() if Antunnel.tunnel + @quit() + resolve(true) action: (e) -> diff --git a/Antunnel/project.json b/Antunnel/project.json deleted file mode 100644 index 84cfb1f..0000000 --- a/Antunnel/project.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Antunnel", - "css": [], - "javascripts": [], - "coffees": ["coffees/Antunnel.coffee", "coffees/AntunnelService.coffee"], - "copies": ["package.json", "README.md"] -} \ No newline at end of file diff --git a/packages.json b/packages.json index 4f98cc8..e545460 100644 --- a/packages.json +++ b/packages.json @@ -389,6 +389,16 @@ "dependencies": [], "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/TinyEditor/build/release/TinyEditor.zip" }, + { + "pkgname": "vfsx", + "name": "AntOS VFS handles", + "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/vfsx/README.md", + "category": "Library", + "author": "Dany LE", + "version": "0.1.0-b", + "dependencies": [], + "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/vfsx/build/release/vfsx.zip" + }, { "pkgname": "VizApp", "name": "Viz editor", diff --git a/vfsx/README.md b/vfsx/README.md new file mode 100644 index 0000000..7af9f87 --- /dev/null +++ b/vfsx/README.md @@ -0,0 +1,10 @@ +# vfsx +AntOS VFS handles for various file protocols which are not included by default +int core release, such as: +- GoogleDrive +- Dropbox (TODO) + +This package is used mainly by the File application to communicate with different +file hosting protocols + +## Change logs diff --git a/vfsx/build.json b/vfsx/build.json new file mode 100644 index 0000000..bb66f23 --- /dev/null +++ b/vfsx/build.json @@ -0,0 +1,83 @@ +{ + "name": "vfsx", + "targets":{ + "clean": { + "jobs": [ + { + "name": "vfs-rm", + "data": ["build/debug","build/release"] + } + ] + }, + "build": { + "require": ["ts"], + "jobs":[ + { + "name": "vfs-mkdir", + "data": ["build","build/debug","build/release"] + }, + { + "name": "ts-import", + "data": ["sdk://core/ts/core.d.ts", "sdk://core/ts/jquery.d.ts","sdk://core/ts/antos.d.ts"] + }, + { + "name": "ts-compile", + "data": { + "src": ["gdv.ts"], + "dest": "build/debug/vfsx.js" + } + } + ] + }, + "uglify": { + "require": ["terser"], + "jobs": [ + { + "name":"terser-uglify", + "data": ["build/debug/vfsx.js"] + } + ] + }, + "copy": { + "jobs": [ + { + "name": "vfs-cp", + "data": { + "src": [ + "package.json", + "README.md" + ], + "dest":"build/debug" + } + } + ] + }, + "locale": { + "require": ["locale"], + "jobs": [ + { + "name":"locale-gen", + "data": { + "src": "", + "exclude": ["build/"], + "locale": "en_GB", + "dest": "package.json" + } + } + ] + }, + "release": { + "depend": ["clean","build","uglify", "copy"], + "require": ["zip"], + "jobs": [ + { + "name": "zip-mk", + "data": { + "src":"build/debug", + "dest":"build/release/vfsx.zip" + } + } + ] + } + } +} \ No newline at end of file diff --git a/vfsx/build/debug/README.md b/vfsx/build/debug/README.md new file mode 100644 index 0000000..7af9f87 --- /dev/null +++ b/vfsx/build/debug/README.md @@ -0,0 +1,10 @@ +# vfsx +AntOS VFS handles for various file protocols which are not included by default +int core release, such as: +- GoogleDrive +- Dropbox (TODO) + +This package is used mainly by the File application to communicate with different +file hosting protocols + +## Change logs diff --git a/vfsx/build/debug/package.json b/vfsx/build/debug/package.json new file mode 100644 index 0000000..c1c26c1 --- /dev/null +++ b/vfsx/build/debug/package.json @@ -0,0 +1,39 @@ +{ + "pkgname": "vfsx", + "name": "AntOS VFS handles", + "description": "AntOS VFS handles for various file protocols which are not included by default int core release", + "info": { + "author": "Dany LE", + "email": "mrsang@iohub.dev" + }, + "version": "0.1.0-b", + "category": "Library", + "iconclass": "fa fa-cog", + "mimes": [ + "none" + ], + "dependencies": [], + "locale": {}, + "locales": { + "en_GB": { + "Unknown API setting for GAPI": "Unknown API setting for GAPI", + "VFS cannot download file : {0}": "VFS cannot download file : {0}", + "VFS cannot get meta data for {0}": "VFS cannot get meta data for {0}", + "No GAPI meta found": "No GAPI meta found", + "Authentication": "Authentication", + "Would you like to login to GoogleDrive?": "Would you like to login to GoogleDrive?", + "User abort the authentication": "User abort the authentication", + "File ID is not valid": "File ID is not valid", + "File {0} not found": "File {0} not found", + "Cannot find local copy of file; {0}": "Cannot find local copy of file; {0}", + "VFS cannot save : {0}": "VFS cannot save : {0}", + "VFS cannot write : {0}": "VFS cannot write : {0}", + "{0} is not a directory": "{0} is not a directory", + "VFS cannot create : {0}": "VFS cannot create : {0}", + "Cannot identify file id of {0}": "Cannot identify file id of {0}", + "VFS cannot delete : {0}": "VFS cannot delete : {0}", + "VFS cannot move : {0}": "VFS cannot move : {0}", + "Target file should be a folder": "Target file should be a folder" + } + } +} \ No newline at end of file diff --git a/vfsx/build/debug/vfsx.js b/vfsx/build/debug/vfsx.js new file mode 100644 index 0000000..c34a3e8 --- /dev/null +++ b/vfsx/build/debug/vfsx.js @@ -0,0 +1 @@ +var OS;!function(e){let t;!function(t){let i;!function(i){let a={"gdv://":{id:"root",mime:"dir"}};class r extends i.BaseFileHandle{constructor(t){super(t),r.API_META?(this.isRoot()&&(this.gid="root"),this.cache="",this.local_copy=void 0):e.announcer.oserror(__("Unknown API setting for GAPI"),e.API.throwe("OS.VFS"))}fields(){return"webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size, version"}isFolder(){return"application/vnd.google-apps.folder"===this.info.mimeType}load(e){const i=t.mid();return new Promise(async(a,r)=>{t.loading(i,"GAPI");try{let r=await e;return t.loaded(i,"GAPI","OK"),a(r)}catch(e){return t.loaded(i,"GAPI","FAIL"),r(__e(e))}})}sync(t){return new Promise(async(a,r)=>{try{if(this.info&&this.info.version==t.version||"application/vnd.google-apps.folder"===t.mimeType)a(!0);else{await i.mkdirAll(["home://.gdv_cache","home://.gdv_cache/"+t.id],!0);let e=`home://.gdv_cache/${t.id}/${t.version}.${t.fullFileExtension}`.asFileHandle();try{await e.onready()}catch(a){await("home://.gdv_cache/"+t.id).asFileHandle().remove(),await i.mkdirAll(["home://.gdv_cache/"+t.id]);let r=await this.load(gapi.client.drive.files.get({fileId:t.id,alt:"media"}));if(!r.body)throw new Error(__("VFS cannot download file : {0}",this.path).__());e.cache=new Blob([r.body.asUint8Array()],{type:"octet/stream"}),await e.write(t.mimeType)}this.local_copy=e,a(!0)}}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}meta(){return new Promise(async(t,i)=>{try{if(await this.oninit(),a[this.path]&&(this.gid=a[this.path].id),this.gid){let e=await this.load(gapi.client.drive.files.get({fileId:this.gid,fields:this.fields()}));if(!e.result)throw new Error(__("VFS cannot get meta data for {0}",this.gid).__());e.result.mime=e.result.mimeType,await this.load(this.sync(e.result)),t(e)}else{const e=this.parent().asFileHandle(),i=(await e.meta()).result;a[e.path]={id:i.id,mime:i.mimeType};let r=await this.load(gapi.client.drive.files.list({q:`name = '${this.basename}' and '${i.id}' in parents and trashed = false`,fields:`files(${this.fields()})`}));if(!(r.result.files&&r.result.files.length>0))throw new Error(__("VFS cannot get meta data for {0}",this.path).__());a[this.path]={id:r.result.files[0].id,mime:r.result.files[0].mimeType},r.result.files[0].mime=r.result.files[0].mimeType,this.gid=a[this.path].id,await this.load(this.sync(r.result.files[0])),t({result:r.result.files[0],error:!1})}}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}oninit(){return new Promise(async(i,n)=>{const o=async function(e){if(e)return i(!0);a={"gdv://":{id:"root",mime:"dir"}};try{let e=await gapi.auth2.getAuthInstance().signIn();i(e)}catch(e){n(__e(e))}};try{if(!r.API_META)throw new Error(__("No GAPI meta found").__());if(t.libready(r.API_META.apilink))gapi.auth2.getAuthInstance().isSignedIn.listen(e=>o(e)),o(gapi.auth2.getAuthInstance().isSignedIn.get());else{if(await this.load(t.requires(r.API_META.apilink,!1)),await this.load(new Promise((e,t)=>{gapi.load("client:auth2",e)})),await this.load(gapi.client.init({apiKey:r.API_META.API_KEY,clientId:r.API_META.CLIENT_ID,discoveryDocs:r.API_META.DISCOVERY_DOCS,scope:r.API_META.SCOPES})),gapi.auth2.getAuthInstance().isSignedIn.listen(e=>o(e)),!await e.GUI.openDialog("YesNoDialog",{title:__("Authentication"),text:__("Would you like to login to GoogleDrive?")}))throw new Error(__("User abort the authentication").__());o(gapi.auth2.getAuthInstance().isSignedIn.get())}}catch(t){e.announcer.oserror(t.toString(),t),n(__e(t))}})}getlink(){if(this.local_copy)return this.local_copy.getlink()}child(e){if(this.isFolder())return`${this.path}/${e}`}_rd(t){return new Promise(async(i,r)=>{try{if(!this.info.id)throw new Error(__("File ID is not valid").__());if(this.isFolder()){let e=await this.load(gapi.client.drive.files.list({q:`'${this.info.id}' in parents and trashed = false`,fields:`files(${this.fields()})`}));if(!e.result.files)throw new Error(__("File {0} not found",this.info.id).__());for(let t of e.result.files)t.path=this.child(t.name),t.mime=t.mimeType,t.filename=t.name,t.type="file",t.gid=t.id,"application/vnd.google-apps.folder"===t.mimeType&&(t.mime="dir",t.type="dir",t.size=0),a[t.path]={id:t.gid,mime:t.mime};i({result:e.result.files,error:!1})}else{if(!this.local_copy)throw new Error(__("Cannot find local copy of file; {0}",this.path).__());i(await this.local_copy.read(t))}}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}save(t,i){return new Promise(async(a,n)=>{try{const o=gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token,s=new XMLHttpRequest,l=__(r.API_META.uploadlink,t).__();s.open("PATCH",l),s.setRequestHeader("Authorization","Bearer "+o),s.setRequestHeader("Content-Type",i),s.setRequestHeader("Content-Encoding","base64"),s.setRequestHeader("Content-Transfer-Encoding","base64");let d=t=>(e.announcer.oserror(__("VFS cannot save : {0}",this.path),t),n(t));s.onreadystatechange=()=>{if(4===s.readyState){if(200===s.status)return a({result:JSON.parse(s.responseText),error:!1});d(e.API.throwe("OS.VFS"))}},s.onerror=()=>d(e.API.throwe("OS.VFS"));let c=this.cache;"base64"!==i&&(c=await this.b64(i)),s.send(c.replace(/^data:[^;]+;base64,/g,"")),a(!0)}catch(e){n(__e(e))}})}_wr(t,i){return new Promise(async(i,r)=>{try{var n=void 0;if(a[this.path]&&(n=a[this.path].id),n)i(await this.load(this.save(n,t)));else{const e=this.parent().asFileHandle();await e.onready();const r={name:this.basename,mimeType:t,parents:[e.info.id]};let n=await this.load(gapi.client.drive.files.create({resource:r,fields:"id"}));if(!n||!n.result)throw new Error(__("VFS cannot write : {0}",this.path).__());a[this.path]={id:n.result.id,mime:t},i(this.load(this.save(n.result.id,t)))}}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}_mk(t){return new Promise(async(i,r)=>{try{if(!this.isFolder())throw new Error(__("{0} is not a directory",this.path).__());var n={name:t,parents:[this.info.id],mimeType:"application/vnd.google-apps.folder"};let e=await this.load(gapi.client.drive.files.create({resource:n,fields:"id"}));if(!e||!e.result)throw new Error(__("VFS cannot create : {0}",t).__());a[this.child(t)]={id:e.result.id,mime:"dir"},i(e)}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}_rm(){return new Promise(async(t,i)=>{try{if(!this.info.id)throw new Error(__("Cannot identify file id of {0}",this.path).__());if(!await this.load(gapi.client.drive.files.delete({fileId:this.info.id})))throw new Error(__("VFS cannot delete : {0}",this.path).__());a[this.path]=null,delete a[this.path],t({result:!0,error:!1})}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}_mv(t){return new Promise(async(i,a)=>{try{var r=t.asFileHandle().parent().asFileHandle();await r.onready();const e=this.info.parents.join(",");let a=await this.load(gapi.client.drive.files.update({fileId:this.info.id,addParents:r.info.id,removeParents:e,fields:"id"}));if(!a)throw new Error(__("VFS cannot move : {0}",this.path).__());i(a)}catch(t){e.announcer.oserror(t.toString(),t),a(__e(t))}})}_up(){return new Promise(async(t,i)=>{try{if(!this.isFolder())throw new Error(__("Target file should be a folder").__());var a=$("").attr("type","file").css("display","none");a.on("change",async()=>{const e=a[0].files[0],t=this.child(e.name).asFileHandle();return t.cache=e,await this.load(t.write(e.type)),a.remove()}),a.trigger("click")}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}_down(){return new Promise(async(t,i)=>{try{let i=await this.load(gapi.client.drive.files.get({fileId:this.info.id,alt:"media"}));if(!i.body)throw new Error(__("VFS cannot download file : {0}",this.path).__());let a=[];for(let e=0,t=i.body.length-1,r=0<=t;r?e<=t:e>=t;r?e++:e--)a.push(i.body.charCodeAt(e));let r=new Uint8Array(a);const n=new Blob([r],{type:"octet/stream"});e.API.saveblob(this.basename,n),t(!0)}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}}i.GoogleDriveHandle=r,r.API_META={CLIENT_ID:"1006507170703-l322pfkrhf9cgta4l4jh2p8ughtc14id.apps.googleusercontent.com",API_KEY:"AIzaSyBZhM5KbARvT10acWC8JQKlRn2WbSsmfLc",apilink:"https://apis.google.com/js/api.js",DISCOVERY_DOCS:["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],SCOPES:"https://www.googleapis.com/auth/drive",uploadlink:"https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=media",logout:"https://www.google.com/accounts/Logout"},i.register("^gdv$",r),t.onsearch("Google Drive",(function(e){const t=[],i=new RegExp(e,"i");for(let e in a){const r=a[e];if(e.match(i)||r&&r.mime.match(i)){const i=e.asFileHandle();i.text=i.basename,i.mime=r.mime,i.iconclass="fa fa-file","dir"===i.mime&&(i.iconclass="fa fa-folder"),i.complex=!0,i.detail=[{text:i.path}],t.push(i)}}return t})),e.onexit("cleanUpGoogleDrive",(function(){return new Promise(async(e,t)=>{try{if(await"home://.gdv_cache".asFileHandle().remove(),a={"gdv://":{id:"root",mime:"dir"}},!Ant.OS.API.libready(Ant.OS.setting.VFS.gdrive.apilink))return e(!0);const t=gapi.auth2.getAuthInstance();if(!t)throw new Error(__("Unable to get OATH instance").__());t.isSignedIn.get()&&$("