From 9afa2f5d1c666ec9467fed1badd27da3ba0ee1ab Mon Sep 17 00:00:00 2001 From: DanyLE Date: Sun, 29 Jan 2023 21:41:28 +0100 Subject: [PATCH] Update LibreOffice and OnlyOffice to latests backend API --- LibreOffice/README.md | 3 + LibreOffice/api/api.lua | 24 ++++---- LibreOffice/build/debug/README.md | 3 + LibreOffice/build/debug/api/api.lua | 24 ++++---- LibreOffice/build/debug/package.json | 2 +- LibreOffice/build/release/LibreOffice.zip | Bin 44173 -> 44185 bytes LibreOffice/package.json | 2 +- OnlyOffice/README.md | 1 + OnlyOffice/api/api.lua | 64 +++++++++++++--------- OnlyOffice/build/release/OnlyOffice.zip | Bin 43553 -> 43704 bytes OnlyOffice/package.json | 2 +- packages.json | 4 +- 12 files changed, 77 insertions(+), 52 deletions(-) diff --git a/LibreOffice/README.md b/LibreOffice/README.md index 16866b6..816814f 100644 --- a/LibreOffice/README.md +++ b/LibreOffice/README.md @@ -9,6 +9,9 @@ It support a wide range of documents. ![https://github.com/lxsang/antosdk-apps/blob/master/LibreOffice/libreoffice.png?raw=true](https://github.com/lxsang/antosdk-apps/blob/master/LibreOffice/libreoffice.png?raw=true) ## Change log +- v 0.1.4-a: + * Update backend script to latest API changes + * use luasocket + luasec to fetch LibreOffice service discovery - v 0.1.3-a: * Minor fix to support AntOS v2.0.x - v 0.1.2-a: diff --git a/LibreOffice/api/api.lua b/LibreOffice/api/api.lua index 230edb4..ec4ebf8 100644 --- a/LibreOffice/api/api.lua +++ b/LibreOffice/api/api.lua @@ -6,7 +6,6 @@ if not args then args = REQUEST end local vfs = require("vfs") -local DLCMD="wget --no-check-certificate -O" local handle = {} --local logger = Logger:new{ levels = {INFO = true, ERROR = true, DEBUG = false}} local result = function(data) @@ -17,12 +16,22 @@ local error = function(msg) return {error = msg, result = false} end +local fetch = function(url) + local https = require('ssl.https') + local body, code, headers = https.request(url) + if code~=200 then + LOG_ERROR("Error: ".. (code or '') ) + return nil + end + return body +end + handle.token = function(data) local file = vfs.ospath(data.file) local stat = ulib.file_stat(file) local ret = { sid = "access_token="..SESSION.sessionid, - key = std.sha1(file..":"..stat.mtime) + key = enc.sha1(file..":"..stat.mtime) } return result(ret) end @@ -43,14 +52,9 @@ handle.duplicate = function(data) end handle.discover = function(data) - local tmpfile = "/tmp/libreoffice_discover.xml" - local cmd = DLCMD.." "..tmpfile..' '..data.uri - os.execute(cmd) + content = fetch(url) -- move file to correct position - if ulib.exists(tmpfile) then - local f = assert(io.open(tmpfile, "rb")) - local content = f:read("*all") - f:close() + if content then return result(content) else return error("Unable to discover data") @@ -74,7 +78,7 @@ handle.file = function(data) elseif REQUEST.method == "POST" then --local clen = tonumber(HEADER['Content-Length']) local barr = REQUEST["application/octet-stream"] - bytes.write(barr, path) + barr:fileout(path) return result(true) else return error("Unknown request method") diff --git a/LibreOffice/build/debug/README.md b/LibreOffice/build/debug/README.md index 16866b6..816814f 100644 --- a/LibreOffice/build/debug/README.md +++ b/LibreOffice/build/debug/README.md @@ -9,6 +9,9 @@ It support a wide range of documents. ![https://github.com/lxsang/antosdk-apps/blob/master/LibreOffice/libreoffice.png?raw=true](https://github.com/lxsang/antosdk-apps/blob/master/LibreOffice/libreoffice.png?raw=true) ## Change log +- v 0.1.4-a: + * Update backend script to latest API changes + * use luasocket + luasec to fetch LibreOffice service discovery - v 0.1.3-a: * Minor fix to support AntOS v2.0.x - v 0.1.2-a: diff --git a/LibreOffice/build/debug/api/api.lua b/LibreOffice/build/debug/api/api.lua index 230edb4..ec4ebf8 100644 --- a/LibreOffice/build/debug/api/api.lua +++ b/LibreOffice/build/debug/api/api.lua @@ -6,7 +6,6 @@ if not args then args = REQUEST end local vfs = require("vfs") -local DLCMD="wget --no-check-certificate -O" local handle = {} --local logger = Logger:new{ levels = {INFO = true, ERROR = true, DEBUG = false}} local result = function(data) @@ -17,12 +16,22 @@ local error = function(msg) return {error = msg, result = false} end +local fetch = function(url) + local https = require('ssl.https') + local body, code, headers = https.request(url) + if code~=200 then + LOG_ERROR("Error: ".. (code or '') ) + return nil + end + return body +end + handle.token = function(data) local file = vfs.ospath(data.file) local stat = ulib.file_stat(file) local ret = { sid = "access_token="..SESSION.sessionid, - key = std.sha1(file..":"..stat.mtime) + key = enc.sha1(file..":"..stat.mtime) } return result(ret) end @@ -43,14 +52,9 @@ handle.duplicate = function(data) end handle.discover = function(data) - local tmpfile = "/tmp/libreoffice_discover.xml" - local cmd = DLCMD.." "..tmpfile..' '..data.uri - os.execute(cmd) + content = fetch(url) -- move file to correct position - if ulib.exists(tmpfile) then - local f = assert(io.open(tmpfile, "rb")) - local content = f:read("*all") - f:close() + if content then return result(content) else return error("Unable to discover data") @@ -74,7 +78,7 @@ handle.file = function(data) elseif REQUEST.method == "POST" then --local clen = tonumber(HEADER['Content-Length']) local barr = REQUEST["application/octet-stream"] - bytes.write(barr, path) + barr:fileout(path) return result(true) else return error("Unknown request method") diff --git a/LibreOffice/build/debug/package.json b/LibreOffice/build/debug/package.json index 6f4ce83..6203ff5 100644 --- a/LibreOffice/build/debug/package.json +++ b/LibreOffice/build/debug/package.json @@ -7,7 +7,7 @@ "author": "Dany LE", "email": "contact@iohub.dev" }, - "version":"0.1.3-a", + "version":"0.1.4-a", "category":"Office", "icon":"icon.png", "mimes":[ diff --git a/LibreOffice/build/release/LibreOffice.zip b/LibreOffice/build/release/LibreOffice.zip index 574299cda34db729559429fe26cefeda90ecaca8..2b1d691dd143230469b281ce10af86363cdb4241 100644 GIT binary patch delta 2633 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