diff --git a/Blogger/dialogs.ts b/Blogger/dialogs.ts index f0167dc..d661ec3 100644 --- a/Blogger/dialogs.ts +++ b/Blogger/dialogs.ts @@ -87,7 +87,7 @@ namespace OS { -\s +\ `; // This dialog is use for cv section editing diff --git a/Docify/README.md b/Docify/README.md index 5dd2277..666b1ca 100644 --- a/Docify/README.md +++ b/Docify/README.md @@ -2,6 +2,7 @@ Simple PDF document manager ## Change logs +- v0.1.0-b: use libsqlite for database handling - v0.0.9-b: Adapt to support AntOS 2.0.x - v0.0.8-b: Allow upload files directly from the app - v0.0.7-a: Change category and icon diff --git a/Docify/api/api.lua b/Docify/api/api.lua index 9fb4241..54c172f 100644 --- a/Docify/api/api.lua +++ b/Docify/api/api.lua @@ -1,12 +1,10 @@ local arg = ... ulib = require("ulib") -sqlite = modules.sqlite() vfs = require("vfs") local handle = {} local docpath = nil -local dbpath = nil local result = function(data) return { @@ -31,7 +29,7 @@ local mkdirp =function(p) return true, nil end -local merge_files = function(data) +handle.merge_files = function(data) local firstfile = data.file[1] local fpath = docpath.."/"..data.cid local r, e = mkdirp(fpath) @@ -57,14 +55,14 @@ local merge_files = function(data) end end -- move the thumb file to the cache folder - local thumb = docpath.."/cache/"..std.sha1(firstfile:gsub(docpath, ""))..".png" - local desthumb = docpath.."/cache/"..std.sha1(fpath:gsub(docpath, ""))..".png" + local thumb = docpath.."/cache/"..enc.sha1(firstfile:gsub(docpath, ""))..".png" + local desthumb = docpath.."/cache/"..enc.sha1(fpath:gsub(docpath, ""))..".png" if vfs.exists(thumb) then vfs.move(thumb, desthumb) end -- remove all other thumb files for i,v in ipairs(data.file) do - thumb = docpath.."/cache/"..std.sha1(v:gsub(docpath, ""))..".png" + thumb = docpath.."/cache/"..enc.sha1(v:gsub(docpath, ""))..".png" if vfs.exists(thumb) then vfs.delete(thumb) end @@ -76,166 +74,15 @@ local merge_files = function(data) return result(fpath) end -handle.init = function(args) - - local r, e = mkdirp(docpath) - if not r then return e end - - r, e = mkdirp(docpath.."/unclassified") - if not r then return e end - - r, e = mkdirp(docpath.."/cache") - if not r then return e end - - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to initialized database "..dbpath) - end - local sql - -- check if table exists - if sqlite.hasTable(db, "categories") == 0 then - -- create the table - sql = [[ - CREATE TABLE "categories" ( - "id" INTEGER, - "name" TEXT NOT NULL, - PRIMARY KEY("id" AUTOINCREMENT) - ); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create table categories") - end - -- insert unknown category - sql = [[ - INSERT INTO categories("id","name") VALUES (0,'Uncategoried'); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create default category") - end - end - - if sqlite.hasTable(db, "owners") == 0 then - -- create the table - sql = [[ - CREATE TABLE "owners" ( - "id" INTEGER, - "name" TEXT NOT NULL, - PRIMARY KEY("id" AUTOINCREMENT) - ); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create table owners") - end - -- insert unknown category - sql = [[ - INSERT INTO owners("id","name") VALUES (0,'None'); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create default None owner") - end - end - - if sqlite.hasTable(db, "docs") == 0 then - -- create the table - sql = [[ - CREATE TABLE "docs" ( - "id" INTEGER, - "name" TEXT NOT NULL, - "ctime" INTEGER, - "day" INTEGER, - "month" INTEGER, - "year" INTEGER, - "cid" INTEGER DEFAULT 0, - "oid" INTEGER DEFAULT 0, - "file" TEXT NOT NULL, - "tags" TEXT, - "note" TEXT, - "mtime" INTEGER, - FOREIGN KEY("oid") REFERENCES "owners"("id") ON DELETE SET DEFAULT ON UPDATE NO ACTION, - FOREIGN KEY("cid") REFERENCES "categories"("id") ON DELETE SET DEFAULT ON UPDATE NO ACTION, - PRIMARY KEY("id" AUTOINCREMENT) - ); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create table docs") - end - end - sqlite.dbclose(db) - return result("Docify initialized") -end - -handle.select = function(param) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local r = sqlite.select(db, param.table, "*", param.cond) - sqlite.dbclose(db) - if r == nil then - return error("Unable to select data from "..param.table) - else - return result(r) - end -end - -handle.fetch = function(table) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local r = sqlite.select(db, table, "*", "1=1") - sqlite.dbclose(db) - if r == nil then - return error("Unable to fetch data from "..table) - else - return result(r) - end -end - -handle.insert = function(param) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local keys = {} - local values = {} - for k,v in pairs(param.data) do - if k ~= "id" then - table.insert(keys,k) - if type(v) == "number" then - table.insert(values, v) - elseif type(v) == "boolean" then - table.insert( values, v and 1 or 0 ) - else - local t = "\""..v:gsub('"', '""').."\"" - table.insert(values,t) - end - end - end - local sql = "INSERT INTO "..param.table.." ("..table.concat(keys,',')..') VALUES (' - sql = sql..table.concat(values,',')..');' - local r = sqlite.query(db, sql) - sqlite.dbclose(db) - if r == nil then - return error("Unable to insert data to "..param.table) - else - return result("Data inserted") - end -end - handle.preview = function(path) -- convert -resize 300x500 noel.pdf[0] thumb.png - local name = std.sha1(path:gsub(docpath,""))..".png" + local name = enc.sha1(path:gsub(docpath,""))..".png" -- try to find the thumb local tpath = docpath.."/cache/"..name if not vfs.exists(tpath) then -- regenerate thumb local cmd = "convert -resize 250x500 \""..vfs.ospath(path).."\"[0] "..vfs.ospath(tpath) + LOG_ERROR(cmd) os.execute(cmd) end @@ -248,57 +95,12 @@ handle.preview = function(path) end end -handle.get_doc = function(id) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local r = sqlite.select(db, "docs", "*", "id = "..id) - if r == nil or #r == 0 then - sqlite.dbclose(db) - return error("Unable to select data from "..param.table) - else - r = r[1] - local ret, meta = vfs.fileinfo(r.file) - if ret then - r.fileinfo = meta - end - local o = sqlite.select(db, "owners", "*", "id = "..r.oid) - sqlite.dbclose(db) - if o == nil or #o == 0 then - return result(r) - else - o = o[1] - r.owner = o.name - if r.ctime then - r.ctime = os.date("%d/%m/%Y %H:%M:%S", r.ctime) - end - - if r.mtime then - r.mtime = os.date("%d/%m/%Y %H:%M:%S", r.mtime) - end - local edate = "" - return result(r) - end - end -end - handle.deletedoc = function(param) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local sql = "DELETE FROM docs WHERE id="..param.id..";" - local ret = sqlite.query(db, sql) == 1 - sqlite.dbclose(db) - if not ret then - return error("Unable to delete doc meta-data from database") - end -- move file to unclassified - local newfile = docpath.."/unclassified/"..std.basename(param.file) + local newfile = docpath.."/unclassified/"..utils.basename(param.file) vfs.move(param.file, newfile) -- delete thumb file - local thumb = docpath.."/cache/"..std.sha1(param.file:gsub(docpath,""))..".png" + local thumb = docpath.."/cache/"..enc.sha1(param.file:gsub(docpath,""))..".png" if vfs.exists(thumb) then vfs.delete(thumb) end @@ -306,20 +108,20 @@ handle.deletedoc = function(param) end handle.updatedoc = function(param) - local r = merge_files(param.data) + local r = handle.merge_files(param.data) if r.error then return r end if param.rm then -- move ve the old file to unclassified - local newfile = docpath.."/unclassified/"..std.basename(param.rm) + local newfile = docpath.."/unclassified/"..utils.basename(param.rm) local cmd = "rm -f "..vfs.ospath(param.rm) os.execute(cmd) --if vfs.exists(param.rm) then -- vfs.move(param.rm, newfile) --end -- move the thumb file if needed - local thumb = docpath.."/cache/"..std.sha1(param.rm:gsub(docpath,""))..".png" - local newwthumb = docpath.."/cache/"..std.sha1(newfile:gsub(docpath, ""))..".png" + local thumb = docpath.."/cache/"..enc.sha1(param.rm:gsub(docpath,""))..".png" + local newwthumb = docpath.."/cache/"..enc.sha1(newfile:gsub(docpath, ""))..".png" if vfs.exists(thumb) then vfs.move(thumb, newwthumb) end @@ -327,107 +129,16 @@ handle.updatedoc = function(param) param.data.file = r.result print(r.result) param.data.mtime = os.time(os.date("!*t")) - return handle.update({ - table = "docs", - data = param.data - }) + return result(param.data) + --return handle.update({ + -- table = "docs", + -- data = param.data + --}) end - -handle.insertdoc = function(data) - local r = merge_files(data) - if r.error then return r end - -- save data - data.file = r.result - data.ctime = os.time(os.date("!*t")) - data.mtime = os.time(os.date("!*t")) - local ret = handle.insert({ - table = "docs", - data = data - }) - return ret -end - -handle.update = function(param) - if not param.data.id or param.data.id == 0 then - return error("Record id is 0 or not found") - end - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local lst = {} - for k,v in pairs(param.data) do - if(type(v)== "number") then - table.insert(lst,k.."="..v) - elseif type(v) == "boolean" then - table.insert( lst, k.."="..(v and 1 or 0) ) - else - table.insert(lst,k.."=\""..v:gsub('"', '""').."\"") - end - end - - local sql = "UPDATE "..param.table.." SET "..table.concat(lst,",").." WHERE id="..param.data.id..";" - local r = sqlite.query(db, sql) - sqlite.dbclose(db) - if r == nil then - return error("Unable to update data to "..param.table) - else - return result("Data Updated") - end -end - -handle.delete = function(param) - if param.id == 0 then - return error("Record with id = 0 cannot be deleted") - end - - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local sql = "DELETE FROM "..param.table.." WHERE id="..param.id..";" - local r = sqlite.query(db, sql) - sqlite.dbclose(db) - if r == nil then - return error("Unable to delete data from "..param.table) - else - return result("Data deleted") - end -end - -handle.printdoc = function(opt) - local cmd = "lp " - if opt.printer and opt.printer ~= "" then - cmd = cmd .. " -d "..opt.printer - end - if opt.side == 0 then - cmd = cmd.. " -o sides=one-sided" - elseif opt.side == 1 then - cmd = cmd.. " -o sides=two-sided-long-edge" - elseif opt.side == 2 then - cmd = cmd .. " -o sides=two-sided-short-edge" - end - -- orientation landscape - if opt.orientation == 1 then - cmd = cmd.." -o orientation-requested=5" - end - - if opt.range == 1 then - cmd = cmd.." -P "..opt.pages - end - - cmd = cmd.. " "..vfs.ospath(opt.file) - print(cmd) - os.execute(cmd) - return result("A print job has been posted on server. Check if it successes") -end - - if arg.action and handle[arg.action] then -- check if the database exits docpath = arg.docpath - dbpath = docpath.."/docify.db" return handle[arg.action](arg.args) else diff --git a/Docify/assets/scheme.html b/Docify/assets/scheme.html index 6b98f30..f3e98cd 100644 --- a/Docify/assets/scheme.html +++ b/Docify/assets/scheme.html @@ -25,7 +25,6 @@
-
diff --git a/Docify/build.json b/Docify/build.json index 27525e2..ae3e803 100644 --- a/Docify/build.json +++ b/Docify/build.json @@ -13,17 +13,35 @@ } ] }, - "coffee": { + "locale": { + "require": ["locale"], + "jobs": [ + { + "name":"locale-gen", + "data": { + "src": "", + "exclude": ["build/", "api/", "css/", "coffees/"], + "locale": "en_GB", + "dest": "package.json" + } + } + ] + }, + "ts": { "require": [ - "coffee" + "ts" ], "jobs": [ { - "name": "coffee-compile", + "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": [ - "coffees/dialogs.coffee", - "coffees/main.coffee" + "ts/dialogs.ts", + "ts/main.ts" ], "dest": "build/debug/main.js" } @@ -65,7 +83,7 @@ ], "depend": [ "init", - "coffee", + "ts", "uglify", "copy" ], @@ -78,6 +96,14 @@ } } ] + }, + + "debug": { + "depend": [ + "init", + "ts", + "copy" + ] } } } \ No newline at end of file diff --git a/Docify/build/debug/README.md b/Docify/build/debug/README.md index 5dd2277..666b1ca 100644 --- a/Docify/build/debug/README.md +++ b/Docify/build/debug/README.md @@ -2,6 +2,7 @@ Simple PDF document manager ## Change logs +- v0.1.0-b: use libsqlite for database handling - v0.0.9-b: Adapt to support AntOS 2.0.x - v0.0.8-b: Allow upload files directly from the app - v0.0.7-a: Change category and icon diff --git a/Docify/build/debug/api.lua b/Docify/build/debug/api.lua index 9fb4241..54c172f 100644 --- a/Docify/build/debug/api.lua +++ b/Docify/build/debug/api.lua @@ -1,12 +1,10 @@ local arg = ... ulib = require("ulib") -sqlite = modules.sqlite() vfs = require("vfs") local handle = {} local docpath = nil -local dbpath = nil local result = function(data) return { @@ -31,7 +29,7 @@ local mkdirp =function(p) return true, nil end -local merge_files = function(data) +handle.merge_files = function(data) local firstfile = data.file[1] local fpath = docpath.."/"..data.cid local r, e = mkdirp(fpath) @@ -57,14 +55,14 @@ local merge_files = function(data) end end -- move the thumb file to the cache folder - local thumb = docpath.."/cache/"..std.sha1(firstfile:gsub(docpath, ""))..".png" - local desthumb = docpath.."/cache/"..std.sha1(fpath:gsub(docpath, ""))..".png" + local thumb = docpath.."/cache/"..enc.sha1(firstfile:gsub(docpath, ""))..".png" + local desthumb = docpath.."/cache/"..enc.sha1(fpath:gsub(docpath, ""))..".png" if vfs.exists(thumb) then vfs.move(thumb, desthumb) end -- remove all other thumb files for i,v in ipairs(data.file) do - thumb = docpath.."/cache/"..std.sha1(v:gsub(docpath, ""))..".png" + thumb = docpath.."/cache/"..enc.sha1(v:gsub(docpath, ""))..".png" if vfs.exists(thumb) then vfs.delete(thumb) end @@ -76,166 +74,15 @@ local merge_files = function(data) return result(fpath) end -handle.init = function(args) - - local r, e = mkdirp(docpath) - if not r then return e end - - r, e = mkdirp(docpath.."/unclassified") - if not r then return e end - - r, e = mkdirp(docpath.."/cache") - if not r then return e end - - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to initialized database "..dbpath) - end - local sql - -- check if table exists - if sqlite.hasTable(db, "categories") == 0 then - -- create the table - sql = [[ - CREATE TABLE "categories" ( - "id" INTEGER, - "name" TEXT NOT NULL, - PRIMARY KEY("id" AUTOINCREMENT) - ); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create table categories") - end - -- insert unknown category - sql = [[ - INSERT INTO categories("id","name") VALUES (0,'Uncategoried'); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create default category") - end - end - - if sqlite.hasTable(db, "owners") == 0 then - -- create the table - sql = [[ - CREATE TABLE "owners" ( - "id" INTEGER, - "name" TEXT NOT NULL, - PRIMARY KEY("id" AUTOINCREMENT) - ); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create table owners") - end - -- insert unknown category - sql = [[ - INSERT INTO owners("id","name") VALUES (0,'None'); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create default None owner") - end - end - - if sqlite.hasTable(db, "docs") == 0 then - -- create the table - sql = [[ - CREATE TABLE "docs" ( - "id" INTEGER, - "name" TEXT NOT NULL, - "ctime" INTEGER, - "day" INTEGER, - "month" INTEGER, - "year" INTEGER, - "cid" INTEGER DEFAULT 0, - "oid" INTEGER DEFAULT 0, - "file" TEXT NOT NULL, - "tags" TEXT, - "note" TEXT, - "mtime" INTEGER, - FOREIGN KEY("oid") REFERENCES "owners"("id") ON DELETE SET DEFAULT ON UPDATE NO ACTION, - FOREIGN KEY("cid") REFERENCES "categories"("id") ON DELETE SET DEFAULT ON UPDATE NO ACTION, - PRIMARY KEY("id" AUTOINCREMENT) - ); - ]] - if sqlite.query(db, sql) ~= 1 then - sqlite.dbclose(db) - return error("Unable to create table docs") - end - end - sqlite.dbclose(db) - return result("Docify initialized") -end - -handle.select = function(param) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local r = sqlite.select(db, param.table, "*", param.cond) - sqlite.dbclose(db) - if r == nil then - return error("Unable to select data from "..param.table) - else - return result(r) - end -end - -handle.fetch = function(table) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local r = sqlite.select(db, table, "*", "1=1") - sqlite.dbclose(db) - if r == nil then - return error("Unable to fetch data from "..table) - else - return result(r) - end -end - -handle.insert = function(param) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local keys = {} - local values = {} - for k,v in pairs(param.data) do - if k ~= "id" then - table.insert(keys,k) - if type(v) == "number" then - table.insert(values, v) - elseif type(v) == "boolean" then - table.insert( values, v and 1 or 0 ) - else - local t = "\""..v:gsub('"', '""').."\"" - table.insert(values,t) - end - end - end - local sql = "INSERT INTO "..param.table.." ("..table.concat(keys,',')..') VALUES (' - sql = sql..table.concat(values,',')..');' - local r = sqlite.query(db, sql) - sqlite.dbclose(db) - if r == nil then - return error("Unable to insert data to "..param.table) - else - return result("Data inserted") - end -end - handle.preview = function(path) -- convert -resize 300x500 noel.pdf[0] thumb.png - local name = std.sha1(path:gsub(docpath,""))..".png" + local name = enc.sha1(path:gsub(docpath,""))..".png" -- try to find the thumb local tpath = docpath.."/cache/"..name if not vfs.exists(tpath) then -- regenerate thumb local cmd = "convert -resize 250x500 \""..vfs.ospath(path).."\"[0] "..vfs.ospath(tpath) + LOG_ERROR(cmd) os.execute(cmd) end @@ -248,57 +95,12 @@ handle.preview = function(path) end end -handle.get_doc = function(id) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local r = sqlite.select(db, "docs", "*", "id = "..id) - if r == nil or #r == 0 then - sqlite.dbclose(db) - return error("Unable to select data from "..param.table) - else - r = r[1] - local ret, meta = vfs.fileinfo(r.file) - if ret then - r.fileinfo = meta - end - local o = sqlite.select(db, "owners", "*", "id = "..r.oid) - sqlite.dbclose(db) - if o == nil or #o == 0 then - return result(r) - else - o = o[1] - r.owner = o.name - if r.ctime then - r.ctime = os.date("%d/%m/%Y %H:%M:%S", r.ctime) - end - - if r.mtime then - r.mtime = os.date("%d/%m/%Y %H:%M:%S", r.mtime) - end - local edate = "" - return result(r) - end - end -end - handle.deletedoc = function(param) - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local sql = "DELETE FROM docs WHERE id="..param.id..";" - local ret = sqlite.query(db, sql) == 1 - sqlite.dbclose(db) - if not ret then - return error("Unable to delete doc meta-data from database") - end -- move file to unclassified - local newfile = docpath.."/unclassified/"..std.basename(param.file) + local newfile = docpath.."/unclassified/"..utils.basename(param.file) vfs.move(param.file, newfile) -- delete thumb file - local thumb = docpath.."/cache/"..std.sha1(param.file:gsub(docpath,""))..".png" + local thumb = docpath.."/cache/"..enc.sha1(param.file:gsub(docpath,""))..".png" if vfs.exists(thumb) then vfs.delete(thumb) end @@ -306,20 +108,20 @@ handle.deletedoc = function(param) end handle.updatedoc = function(param) - local r = merge_files(param.data) + local r = handle.merge_files(param.data) if r.error then return r end if param.rm then -- move ve the old file to unclassified - local newfile = docpath.."/unclassified/"..std.basename(param.rm) + local newfile = docpath.."/unclassified/"..utils.basename(param.rm) local cmd = "rm -f "..vfs.ospath(param.rm) os.execute(cmd) --if vfs.exists(param.rm) then -- vfs.move(param.rm, newfile) --end -- move the thumb file if needed - local thumb = docpath.."/cache/"..std.sha1(param.rm:gsub(docpath,""))..".png" - local newwthumb = docpath.."/cache/"..std.sha1(newfile:gsub(docpath, ""))..".png" + local thumb = docpath.."/cache/"..enc.sha1(param.rm:gsub(docpath,""))..".png" + local newwthumb = docpath.."/cache/"..enc.sha1(newfile:gsub(docpath, ""))..".png" if vfs.exists(thumb) then vfs.move(thumb, newwthumb) end @@ -327,107 +129,16 @@ handle.updatedoc = function(param) param.data.file = r.result print(r.result) param.data.mtime = os.time(os.date("!*t")) - return handle.update({ - table = "docs", - data = param.data - }) + return result(param.data) + --return handle.update({ + -- table = "docs", + -- data = param.data + --}) end - -handle.insertdoc = function(data) - local r = merge_files(data) - if r.error then return r end - -- save data - data.file = r.result - data.ctime = os.time(os.date("!*t")) - data.mtime = os.time(os.date("!*t")) - local ret = handle.insert({ - table = "docs", - data = data - }) - return ret -end - -handle.update = function(param) - if not param.data.id or param.data.id == 0 then - return error("Record id is 0 or not found") - end - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local lst = {} - for k,v in pairs(param.data) do - if(type(v)== "number") then - table.insert(lst,k.."="..v) - elseif type(v) == "boolean" then - table.insert( lst, k.."="..(v and 1 or 0) ) - else - table.insert(lst,k.."=\""..v:gsub('"', '""').."\"") - end - end - - local sql = "UPDATE "..param.table.." SET "..table.concat(lst,",").." WHERE id="..param.data.id..";" - local r = sqlite.query(db, sql) - sqlite.dbclose(db) - if r == nil then - return error("Unable to update data to "..param.table) - else - return result("Data Updated") - end -end - -handle.delete = function(param) - if param.id == 0 then - return error("Record with id = 0 cannot be deleted") - end - - local db = sqlite._getdb(vfs.ospath(dbpath)) - if not db then - return error("Unable to get database "..dbpath) - end - local sql = "DELETE FROM "..param.table.." WHERE id="..param.id..";" - local r = sqlite.query(db, sql) - sqlite.dbclose(db) - if r == nil then - return error("Unable to delete data from "..param.table) - else - return result("Data deleted") - end -end - -handle.printdoc = function(opt) - local cmd = "lp " - if opt.printer and opt.printer ~= "" then - cmd = cmd .. " -d "..opt.printer - end - if opt.side == 0 then - cmd = cmd.. " -o sides=one-sided" - elseif opt.side == 1 then - cmd = cmd.. " -o sides=two-sided-long-edge" - elseif opt.side == 2 then - cmd = cmd .. " -o sides=two-sided-short-edge" - end - -- orientation landscape - if opt.orientation == 1 then - cmd = cmd.." -o orientation-requested=5" - end - - if opt.range == 1 then - cmd = cmd.." -P "..opt.pages - end - - cmd = cmd.. " "..vfs.ospath(opt.file) - print(cmd) - os.execute(cmd) - return result("A print job has been posted on server. Check if it successes") -end - - if arg.action and handle[arg.action] then -- check if the database exits docpath = arg.docpath - dbpath = docpath.."/docify.db" return handle[arg.action](arg.args) else diff --git a/Docify/build/debug/main.js b/Docify/build/debug/main.js index a43d741..b34f59c 100644 --- a/Docify/build/debug/main.js +++ b/Docify/build/debug/main.js @@ -1 +1 @@ -(function(){var t,i,a,r,n;(r=class t extends this.OS.GUI.BasicDialog{constructor(){super("OwnerDialog",t.scheme)}main(){return super.main(),this.oview=this.find("ownview"),this.oview.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:t=>this.openDialog("PromptDialog",{title:__("Owner"),label:__("Name")}).then(t=>this.parent.exec("insert",{table:"owners",data:{name:t}}).then(t=>t.error?this.error(t.error):this.owner_refresh()).catch(t=>this.error(__("Unable to insert owner: {0}",t.toString()),t))).catch(t=>this.error(t.toString(),t))},{text:"",iconclass:"fa fa-minus-circle",onbtclick:t=>{var e;if(e=this.oview.selectedItem)return this.ask({text:__("Do you realy want to delete: `{0}`",e.data.text)}).then(t=>{if(t)return this.parent.exec("delete",{table:"owners",id:parseInt(e.data.id)}).then(t=>t.error?this.error(t.error):this.owner_refresh()).catch(t=>this.error(__("Unable delete category: {0}",t.toString()),t))})}},{text:"",iconclass:"fa fa-pencil-square-o",onbtclick:t=>{var e;if(e=this.oview.selectedItem)return this.openDialog("PromptDialog",{title:__("Owner"),label:__("Name"),value:e.data.name}).then(t=>this.parent.exec("update",{table:"owners",data:{id:parseInt(e.data.id),name:t}}).then(t=>t.error?this.error(t.error):this.owner_refresh()).catch(t=>this.error(__("Unable to update owner: {0}",t.toString()),t))).catch(t=>this.error(t.toString()))}}],this.owner_refresh()}owner_refresh(){return this.parent.exec("fetch","owners").then(t=>{var e,i,a,r;for(e=0,i=(a=t.result).length;ethis.error(__("Unable to fetch owners: {0}",t.toString()),e))}}).scheme="\n \n \n \n",(t=class t extends this.OS.GUI.BasicDialog{constructor(){super("DocDialog",t.scheme)}main(){var t,e,i,r,n,s,h,l;for(super.main(),this.flist=this.find("file-list"),this.dlist=this.find("dlist"),this.mlist=this.find("mlist"),this.ylist=this.find("ylist"),this.olist=this.find("olist"),this.setting=this.parent.setting,this.exec=this.parent.exec,this.preview=this.parent.preview,this.exec("fetch","owners").then(t=>{var e,i,a,r,n,s,h;if(t.error)return this.error(t.error);for(e=0,a=(n=t.result).length;ethis.error(__("Unable to fetch owner list: {0}",t.toString()),t)),this.dlist.push({text:"None",value:0}),h=0,t=i=1;i<=31;t=++i)this.dlist.push({text:""+t,value:t}),this.data&&parseInt(this.data.day)===t&&(h=t);for(this.dlist.selected=h,this.mlist.push({text:"None",value:0}),h=0,t=r=1;r<=12;t=++r)this.mlist.push({text:""+t,value:t}),this.data&&parseInt(this.data.month)===t&&(h=t);for(this.mlist.selected=h,this.ylist.push({text:"None",value:0}),this.ylist.selected=0,l=n=1960,s=(new Date).getFullYear();1960<=s?n<=s:n>=s;l=1960<=s?++n:--n)this.ylist.push({text:""+l,value:l,selected:this.data&&parseInt(this.data.year)===l});if(this.flist.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:t=>this.openDialog(new a).then(t=>(t.text=t.filename,this.flist.push(t)))},{text:"",iconclass:"fa fa-minus-circle",onbtclick:t=>{var e;if(e=this.flist.selectedItem)return this.flist.delete(e)}}],this.flist.onlistselect=t=>this.parent.preview(t.data.item.data.path,this.find("preview-canvas")),this.find("btsave").onbtclick=t=>{var e,i;return(e={name:this.find("title").value.trim(),day:this.dlist.selectedItem.data.value,month:this.mlist.selectedItem.data.value,year:this.ylist.selectedItem.data.value,file:function(){var t,e,a,r;for(r=[],t=0,e=(a=this.flist.data).length;t0?(this.handle&&this.handle(e),this.quit()):this.notify(__("Please attach files to the entry")):this.notify(__("Please enter title"))},this.data)return this.find("title").value=this.data.name,this.find("note").value=this.data.note,this.find("tag").value=this.data.tags,(e=this.data.file.asFileHandle()).text=e.filename,this.flist.data=[e]}}).scheme='\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n \n
\n
\n
\n
',(a=class t extends this.OS.GUI.BasicDialog{constructor(){super("FilePreviewDialog",t.scheme)}main(){return super.main(),this.flist=this.find("file-list"),this.flist.buttons=[{text:"",iconclass:"fa fa-refresh",onbtclick:t=>this.refresh()}],this.flist.onlistselect=t=>this.parent.preview(t.data.item.data.path,this.find("preview-canvas")),this.find("btok").onbtclick=t=>{var e;return(e=this.flist.selectedItem)?(this.handle&&this.handle(e.data),this.quit()):this.quit()},this.refresh()}refresh(){return(this.parent.setting.docpath+"/unclassified").asFileHandle().read().then(t=>{var e,i,a,r;if(t.error)return this.error(t.error);for(e=0,i=(a=t.result).length;ethis.error(__("Unable to fetch unclassified file list: {0}",t.toString()),t))}}).scheme='\n \n \n \n \n \n \n
\n \n
\n
\n \n
\n \n
\n
\n
',(n=class t extends this.OS.GUI.BasicDialog{constructor(){super("PrintDialog",t.scheme)}main(){return super.main(),this.find("printerName").value=this.parent.setting.printer,this.find("btnprint").onbtclick=t=>{var e;return(e={}).range=parseInt($("input[name=range]:checked",this.scheme).val()),e.pages=this.find("txtPageRange").value,e.printer=this.find("printerName").value,e.orientation=parseInt($("input[name=orientation]:checked",this.scheme).val()),e.side=parseInt($("input[name=side]:checked",this.scheme).val()),this.handle&&this.handle(e),this.quit()}}}).scheme='\n \n \n \n \n
\n \n
\n \n \n \n
\n \n
\n \n
\n \n \n
\n \n
\n \n
\n \n
\n \n \n
\n
\n \n
\n
\n
',i=class extends this.OS.application.BaseApplication{constructor(t){super("Docify",t)}main(){return this.setting.printer||(this.setting.printer=""),this.catview=this.find("catview"),this.docview=this.find("docview"),this.docpreview=this.find("preview-canvas"),this.docgrid=this.find("docgrid"),this.docgrid.header=[{text:"",width:100},{text:""}],this.find("btdld").onbtclick=t=>{var e;if(e=this.docview.selectedItem)return e.data.file.asFileHandle().download().catch(t=>this.error(__("Unable to download: {}",t.toString()),t))},this.find("btopen").onbtclick=t=>{var e;if(e=this.docview.selectedItem)return e.data.file.asFileHandle().meta().then(t=>t.error?this.error(t.error):this._gui.openWith(t.result)).catch(t=>this.error(t.toString(),t))},this.find("btprint").onbtclick=t=>{var e;if(e=this.docview.selectedItem)return this.openDialog(new n,{}).then(t=>{if(t)return t.file=e.data.file,this.exec("printdoc",t).then(t=>t.error?this.error(t.error):this.notify(t.result)).catch(t=>this.error(__("Unable to insert category: {0}",t.toString()),t))})},this.catview.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:t=>this.openDialog("PromptDialog",{title:__("Category"),label:__("Name")}).then(t=>this.exec("insert",{table:"categories",data:{name:t}}).then(t=>t.error?this.error(t.error):this.cat_refresh()).catch(t=>this.error(__("Unable to insert category: {0}",t.toString()),t))).catch(t=>this.error(t.toString(),t))},{text:"",iconclass:"fa fa-minus-circle",onbtclick:t=>{var e;if(e=this.catview.selectedItem)return this.ask({text:__("Do you realy want to delete: `{0}`",e.data.text)}).then(t=>{if(t)return this.exec("delete",{table:"categories",id:parseInt(e.data.id)}).then(t=>t.error?this.error(t.error):this.cat_refresh()).catch(t=>this.error(__("Unable delete category: {0}",t.toString()),t))})}},{text:"",iconclass:"fa fa-pencil-square-o",onbtclick:t=>{var e;if(e=this.catview.selectedItem)return this.openDialog("PromptDialog",{title:__("Category"),label:__("Name"),value:e.data.name}).then(t=>this.exec("update",{table:"categories",data:{id:parseInt(e.data.id),name:t}}).then(t=>t.error?this.error(t.error):this.cat_refresh()).catch(t=>this.error(__("Unable to update category: {0}",t.toString()),t))).catch(t=>this.error(t.toString(),t))}}],this.docview.onlistselect=t=>{var e;if(this.clear_preview(),e=t.data.item)return this.exec("get_doc",e.data.id).then(t=>{var e,i,a,r,n,s;if(t.error)return this.error(t.error);for(i in this.preview(t.result.file,this.docpreview),n=[],t.result.fileinfo&&(t.result.size=(t.result.fileinfo.size/1024).toFixed(2)+" Kb"),a={ctime:"Created on",mtime:"Modified on",note:"Note",tags:"Tags",name:"Title",owner:"Owner",edate:"Effective date",file:"File",size:"Size"},t.result.edate=`${t.result.day}/${t.result.month}/${t.result.year}`,r=t.result)s=r[i],(e=a[i])&&n.push([{text:e},{text:s}]);return this.docgrid.rows=n}).catch(t=>this.error(t.toString(),t))},this.catview.onlistselect=t=>{var e;if(this.clear_preview(),e=t.data.item)return this.update_doclist(e.data.id)},this.find("bt-add-doc").onbtclick=e=>{var i;return(i=this.catview.selectedItem)?this.openDialog(new t).then(t=>(t.cid=parseInt(i.data.id),this.exec("insertdoc",t).then(t=>t.error?this.error(t.error):(t.result&&this.notify(t.result),this.update_doclist(i.data.id),this.clear_preview())).catch(t=>this.error(t.toString(),t)))):this.notify(__("Please select a category"))},this.find("bt-del-doc").onbtclick=t=>{var e;if(e=this.docview.selectedItem)return this.ask({text:__("Do you really want to delete: `{0}`",e.data.name)}).then(t=>{if(t)return this.exec("deletedoc",{id:e.data.id,file:e.data.file}).then(t=>t.error?this.error(t.error):(this.notify(t.result),this.update_doclist(e.data.cid),this.clear_preview())).catch(t=>this.error(t.toString(),t))})},this.find("bt-upload-doc").onbtclick=t=>(this.setting.docpath+"/unclassified").asFileHandle().upload().then(t=>this.notify(__("File uploaded"))).catch(t=>this.error(t.toString(),t)),this.find("bt-edit-doc").onbtclick=e=>{var i,a;if(a=this.docview.selectedItem,i=this.catview.selectedItem,a)return this.openDialog(new t,a.data).then(t=>(t.cid=parseInt(i.data.id),t.id=a.data.id,this.exec("updatedoc",{data:t,rm:!t.file.includes(a.data.file)&&a.data.file}).then(t=>t.error?this.error(t.error):(t.result&&this.notify(t.result),this.update_doclist(i.data.id),this.clear_preview())).catch(t=>this.error(t.toString(),t))))},this.initialize()}update_doclist(t){return this.exec("select",{table:"docs",cond:`cid = ${t} ORDER BY year DESC, month DESC, day DESC`}).then(t=>{var e,i,a,r;if(t.error)return this.error(t.error);for(e=0,i=(a=t.result).length;ethis.error(t.toString(),t))}clear_preview(){return this.docpreview.getContext("2d").clearRect(0,0,this.docpreview.width,this.docpreview.height),this.docgrid.rows=[]}preview(t,e){return this.exec("preview",t).then(t=>{var i;return t.error?this.error(t.error):(i=t.result.asFileHandle()).read("binary").then(t=>{var a,r;return(r=new Image).onload=()=>{var t;return t=e.getContext("2d"),e.height=r.height,e.width=r.width,t.drawImage(r,0,0)},a=new Blob([t],{type:i.info.mime}),r.src=URL.createObjectURL(a)}).catch(t=>this.error(t.toString(),t))}).catch(t=>this.error(t.toString(),t))}cat_refresh(){return this.docview.data=[],this.clear_preview(),this.exec("fetch","categories").then(t=>{var e,i,a,r;for(e=0,i=(a=t.result).length;ethis.error(__("Unable to fetch categories: {0}",t.toString()),t))}initialize(){return this.setting.docpath?this.initdb():this.openDialog("FileDialog",{title:__("Please select a doc path"),mimes:["dir"]}).then(t=>(this.setting.docpath=t.file.path,this._api.setting(),this.initdb())).catch(t=>this.error(t.toString(),t))}exec(t,e){var i;return i={path:this.path()+"/api.lua",parameters:{action:t,docpath:this.setting.docpath,args:e}},this.call(i)}initdb(){return this.setting.docpath?this.exec("init").then(t=>t.error?this.error(t.error):(this.notify(t.result),this.cat_refresh())).catch(t=>this.error(__("Unable to init database: {0}",t.toString()),t)):this.error(__("No configured docpath"))}menu(){return[{text:"__(Options)",nodes:[{text:"__(Owners)",id:"owners"},{text:"__(Preview)",id:"preview"},{text:"__(Change doc path)",id:"setdocp"},{text:"__(Set default printer)",id:"setprinter"}],onchildselect:t=>this.fileMenuHandle(t.data.item.data.id)}]}fileMenuHandle(t){switch(t){case"owners":return this.openDialog(new r,{title:__("Owners")});case"preview":return this.openDialog(new a).then(t=>this.notify(t.path));case"setdocp":return this.setting.docpath=void 0,this.initialize();case"setprinter":return this.openDialog("PromptDialog",{title:__("Default Printer"),label:__("Enter printer name")}).then(t=>this.setting.printer=t)}}},this.OS.register("Docify",i)}).call(this); \ No newline at end of file +var OS;!function(t){let e;!function(e){let i;!function(e){class i extends t.GUI.BasicDialog{constructor(){super("OwnerDialog",i.scheme)}main(){if(super.main(),this.oview=this.find("ownview"),!this.data.dbhandle)throw new Error(__("Unable to get owner data handle").__());return this.oview.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:async t=>{try{const t=await this.openDialog("PromptDialog",{title:__("Owner"),label:__("Name")});this.data.dbhandle.cache={name:t};const e=await this.data.dbhandle.write(void 0);if(e.error)throw new Error(e.error);await this.owner_refresh()}catch(t){this.error(t.toString(),t)}}},{text:"",iconclass:"fa fa-minus-circle",onbtclick:async t=>{try{const t=this.oview.selectedItem;if(!t)return;if(!await this.ask({text:__("Do you realy want to delete: `{0}`",t.data.text)}))return;const e=t.data.$vfs;let i=await e.remove();if(i.error)throw new Error(i.error.toString());await this.owner_refresh()}catch(t){this.error(t.toString(),t)}}},{text:"",iconclass:"fa fa-pencil-square-o",onbtclick:async t=>{try{const t=this.oview.selectedItem;if(!t)return;const e=await this.openDialog("PromptDialog",{title:__("Owner"),label:__("Name"),value:t.data.name}),i=t.data.$vfs;i.cache={name:e};const a=await i.write(void 0);if(a.error)throw new Error(a.error.toString());await this.owner_refresh()}catch(t){this.error(t.toString(),t)}}}],this.owner_refresh()}async owner_refresh(){const t=await this.data.dbhandle.read();for(let e of t)e.text=e.name;this.oview.data=t}}e.OwnerDialog=i,i.scheme="\n \n \n \n ";class a extends t.GUI.BasicDialog{constructor(){super("DocDialog",a.scheme)}main(){let t;super.main(),this.flist=this.find("file-list"),this.dlist=this.find("dlist"),this.mlist=this.find("mlist"),this.ylist=this.find("ylist"),this.olist=this.find("olist");const e=this.parent;`sqlite://${e.setting.docpath.asFileHandle().genealogy.join("/")}/docify.db@owners`.asFileHandle().read().then(t=>{if(t.error)return this.error(t.error);for(let e of t)e.text=e.name,e.selected=this.data&&this.data.oid===e.id;return this.olist.data=t,this.olist.selectedItem?void 0:this.olist.selected=0}).catch(t=>this.error(__("Unable to fetch owner list: {0}",t.toString()),t)),this.dlist.push({text:"None",value:0});let i=0;for(t=1;t<=31;t++)this.dlist.push({text:""+t,value:t}),this.data&&parseInt(this.data.day)===t&&(i=t);for(this.dlist.selected=i,this.mlist.push({text:"None",value:0}),i=0,t=1;t<=12;t++)this.mlist.push({text:""+t,value:t}),this.data&&parseInt(this.data.month)===t&&(i=t);this.mlist.selected=i,this.ylist.push({text:"None",value:0}),this.ylist.selected=0;for(let t=1960,e=(new Date).getFullYear(),i=1960<=e;i?t<=e:t>=e;i?t++:t--)this.ylist.push({text:""+t,value:t,selected:this.data&&parseInt(this.data.year)===t});if(this.flist.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:t=>this.openDialog(new r,{app:e}).then(t=>(t.text=t.filename,this.flist.push(t)))},{text:"",iconclass:"fa fa-minus-circle",onbtclick:t=>{const e=this.flist.selectedItem;if(e)return this.flist.delete(e)}}],this.flist.onlistselect=async t=>await e.preview(t.data.item.data.path,this.find("preview-canvas")),this.find("btsave").onbtclick=t=>{const e={name:this.find("title").value.trim(),day:this.dlist.selectedItem.data.value,month:this.mlist.selectedItem.data.value,year:this.ylist.selectedItem.data.value,file:Array.from(this.flist.data).map(t=>t.path),note:this.find("note").value.trim(),tags:this.find("tag").value.trim(),oid:parseInt(this.olist.selectedItem.data.id)};return e.name&&""!==e.title?e.file.length>0?(this.handle&&this.handle(e),this.quit()):this.notify(__("Please attach files to the entry")):this.notify(__("Please enter title"))},!this.data)return;this.find("title").value=this.data.name,this.find("note").value=this.data.note,this.find("tag").value=this.data.tags;const a=this.data.file.asFileHandle();return a.text=a.filename,this.flist.data=[a]}}e.DocDialog=a,a.scheme='\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n \n
\n
\n
\n
';class r extends t.GUI.BasicDialog{constructor(){super("FilePreviewDialog",r.scheme)}main(){super.main(),this.flist=this.find("file-list"),this.flist.buttons=[{text:"",iconclass:"fa fa-refresh",onbtclick:t=>this.refresh()}];const t=this.data.app;return this.flist.onlistselect=async e=>await t.preview(e.data.item.data.path,this.find("preview-canvas")),this.find("btok").onbtclick=t=>{const e=this.flist.selectedItem;return e?(this.handle&&this.handle(e.data),this.quit()):this.quit()},this.refresh()}async refresh(){try{const t=this.data.app,e=await(t.setting.docpath+"/unclassified").asFileHandle().read();if(e.error)return this.error(e.error);for(let t of e.result)t.text=t.filename;return this.flist.data=e.result.filter(t=>"."!==t.filename[0])}catch(t){return this.error(__("Unable to fetch unclassified file list: {0}",t.toString()),t)}}}e.FilePreviewDialog=r,r.scheme='\n \n \n \n \n \n \n
\n \n
\n
\n \n
\n \n
\n
\n
'}(i=e.docify||(e.docify={}))}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(t){class e extends t.BaseApplication{constructor(t){super("Docify",t)}async init_db(){try{if(!this.setting.docpath)return this.error(__("No configured docpath"));const t=this.setting.docpath.asFileHandle();this.dbhandle=`sqlite://${t.genealogy.join("/")}/docify.db`.asFileHandle();const e=await this.dbhandle.read();await(""+this.setting.docpath).asFileHandle().mk("unclassified"),await(""+this.setting.docpath).asFileHandle().mk("cache");let i=void 0;if(this.catdb=(this.dbhandle.path+"@categories").asFileHandle(),!e.categories){if(this.dbhandle.cache={name:"TEXT"},i=await this.dbhandle.write("categories"),i.error)throw new Error(i.error);if(this.catdb.cache={name:"Uncategoried"},i=await this.catdb.write(void 0),i.error)throw new Error(i.error)}if(this.ownerdb=(this.dbhandle.path+"@owners").asFileHandle(),!e.owners){if(this.dbhandle.cache={name:"TEXT"},i=await this.dbhandle.write("owners"),i.error)throw new Error(i.error);if(this.ownerdb.cache={name:"None"},i=await this.ownerdb.write(void 0),i.error)throw new Error(i.error)}if(this.docdb=(this.dbhandle.path+"@docs").asFileHandle(),!e.docs&&(this.dbhandle.cache={name:"TEXT NOT NULL",ctime:"INTEGER",day:"INTEGER",month:"INTEGER",year:"INTEGER",cid:"INTEGER DEFAULT 0",oid:"INTEGER DEFAULT 0",file:"TEXT NOT NULL",tags:"TEXT",note:"TEXT",mtime:"INTEGER"},i=await this.dbhandle.write("docs"),i.error))throw new Error(i.error);return await this.cat_refresh()}catch(t){this.error(__("Unable to init database file: {0}",t.toString()),t),this.dbhandle=void 0}}main(){return this.setting.printer||(this.setting.printer=""),this.catview=this.find("catview"),this.docview=this.find("docview"),this.docpreview=this.find("preview-canvas"),this.docgrid=this.find("docgrid"),this.docgrid.header=[{text:"",width:100},{text:""}],this.find("btdld").onbtclick=async t=>{try{const t=this.docview.selectedItem;if(!t)return;await t.data.file.asFileHandle().download()}catch(t){this.error(__("Unable to download: {0}",t.toString()),t)}},this.find("btopen").onbtclick=async t=>{try{const t=this.docview.selectedItem;if(!t)return;const e=await t.data.file.asFileHandle().meta();if(e.error)throw new Error(e.error);return this._gui.openWith(e.result)}catch(t){this.error(__("Unable to open file: {0}",t.toString()),t)}},this.catview.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:async t=>{try{const t=await this.openDialog("PromptDialog",{title:__("Category"),label:__("Name")});this.catdb.cache={name:t};const e=await this.catdb.write(void 0);if(e.error)throw new Error(e.error.toString());return await this.cat_refresh()}catch(t){this.error(__("Unable to insert category: {0}",t.toString()),t)}}},{text:"",iconclass:"fa fa-minus-circle",onbtclick:async t=>{try{const t=this.catview.selectedItem;if(!t)return;if(!await this.ask({text:__("Do you realy want to delete: `{0}`",t.data.text)}))return;const e=await this.catdb.remove({where:{id:t.data.id}});if(e.error)throw new Error(e.error.toString());await this.cat_refresh()}catch(t){this.error(__("Unable delete category: {0}",t.toString()),t)}}},{text:"",iconclass:"fa fa-pencil-square-o",onbtclick:async t=>{try{const t=this.catview.selectedItem;if(!t)return;const e=t.data;if(!e)return;const i=await this.openDialog("PromptDialog",{title:__("Category"),label:__("Name"),value:t.data.name}),a=e.$vfs;a.cache={id:parseInt(t.data.id),name:i};const r=await a.write(void 0);if(r.error)throw new Error(r.error.toString());await this.cat_refresh()}catch(t){this.error(__("Unable to update category: {0}",t.toString()),t)}}}],this.docview.onlistselect=async t=>{try{this.clear_preview();const e=t.data.item;if(!e)return;const i=e.data.$vfs,a=await i.read();await this.preview(a.file,this.docpreview);const r=[],s={ctime:"Created on",mtime:"Modified on",note:"Note",tags:"Tags",name:"Title",owner:"Owner",edate:"Effective date",file:"File",size:"Size"};a.edate=`${a.day}/${a.month}/${a.year}`;for(let t in a){let e=a[t];const i=s[t];"ctime"!==t&&"mtime"!=t||(e=new Date(1e3*e).toDateString()),i&&r.push([{text:i},{text:e}])}return this.docgrid.rows=r}catch(t){this.error(__("Unable to fetch document detail: {0}",t.toString()),t)}},this.catview.onlistselect=t=>{this.clear_preview();const e=t.data.item;if(e)return this.update_doclist(e.data.id)},this.find("bt-add-doc").onbtclick=async e=>{try{const e=this.catview.selectedItem;if(!e)return this.notify(__("Please select a category"));const i=await this.openDialog(new t.docify.DocDialog);i.cid=parseInt(e.data.id);const a=Math.floor(Date.now()/1e3);i.ctime=a,i.mtime=a;const r=await this.exec("merge_files",i);if(r.error)throw new Error(r.error.toString());i.file=r.result,this.docdb.cache=i;const s=await this.docdb.write(void 0);if(s.error)throw new Error(s.error.toString());s.result&&this.toast(s.result),this.update_doclist(e.data.id),this.clear_preview()}catch(t){this.error(__("Unable to add document: {0}",t.toString()),t)}},this.find("bt-del-doc").onbtclick=async t=>{try{const t=this.docview.selectedItem;if(!t)return;if(!await this.ask({text:__("Do you really want to delete: `{0}`",t.data.name)}))return;let e=await this.docdb.remove({where:{id:t.data.id}});if(e.error)throw new Error(e.error.toString());if(e=await this.exec("deletedoc",{file:t.data.file}),e.error)throw new Error(e.error.toString());return this.notify(e.result.toString()),this.update_doclist(t.data.cid),this.clear_preview()}catch(t){this.error(__("Unable to delete document: {0}",t.tostring()),t)}},this.find("bt-upload-doc").onbtclick=async t=>{try{await(this.setting.docpath+"/unclassified").asFileHandle().upload(),this.toast(__("File uploaded"))}catch(t){this.error(__("Unable to upload document: {0}",t.toString()),t)}},this.find("bt-edit-doc").onbtclick=async e=>{try{const e=this.docview.selectedItem,i=this.catview.selectedItem;if(!e)return;const a=await this.openDialog(new t.docify.DocDialog,e.data);a.cid=parseInt(i.data.id),a.id=e.data.id;const r=Math.floor(Date.now()/1e3);a.mtime=r;let s=await this.exec("updatedoc",{data:a,rm:!a.file.includes(e.data.file)&&e.data.file});if(s.error)throw new Error(s.error);const n=e.data.$vfs;if(n.cache=s.result,s=await n.write(void 0),s.error)throw new Error(s.error);return s.result&&this.toast(s.result),this.update_doclist(i.data.id),this.clear_preview()}catch(t){this.error(__("Unable to edit document metadata: {0}",t.toString()))}},this.initialize()}async update_doclist(t){try{const e=await this.docdb.read({where:{cid:t},order:["year$desc","month$desc","day$desc"]});if(e.error)throw new Error(e.error);for(let t of e)t.text=t.name;return this.docview.data=e}catch(t){this.error(__("Unable to update document list: {0}",t.toString()),t)}}clear_preview(){return this.docpreview.getContext("2d").clearRect(0,0,this.docpreview.width,this.docpreview.height),this.docgrid.rows=[]}async preview(t,e){try{const i=await this.exec("preview",t);if(i.error)throw new Error(i.error);const a=i.result.asFileHandle(),r=await a.read("binary"),s=new Image;s.onload=()=>{const t=e.getContext("2d");return e.height=s.height,e.width=s.width,t.drawImage(s,0,0)};const n=new Blob([r],{type:a.info.mime});return s.src=URL.createObjectURL(n)}catch(t){this.error(__("Unable to generate document thumbnail: {0}",t.toString()),t)}}cat_refresh(){return new Promise(async(t,e)=>{try{this.docview.data=[],this.clear_preview();const t=await this.catdb.read();for(let e of t)e.text=e.name;return this.catview.data=t}catch(t){e(__e(t))}})}async initialize(){try{if(this.setting.docpath)return await this.init_db();{const t=await this.openDialog("FileDialog",{title:__("Please select a doc path"),type:"dir"});return this.setting.docpath=t.file.path,await this.init_db()}}catch(t){this.error(__("Error initialize database: {0}",t.toString()),t)}}exec(t,e){const i={path:this.path()+"/api.lua",parameters:{action:t,docpath:this.setting.docpath,args:e}};return this.call(i)}menu(){return[{text:"__(Options)",nodes:[{text:"__(Owners)",id:"owners"},{text:"__(Preview)",id:"preview"},{text:"__(Change doc path)",id:"setdocp"}],onchildselect:t=>this.fileMenuHandle(t.data.item.data.id)}]}fileMenuHandle(e){switch(e){case"owners":return this.openDialog(new t.docify.OwnerDialog,{title:__("Owners"),dbhandle:this.ownerdb});case"preview":return this.openDialog(new t.docify.FilePreviewDialog,{app:this}).then(t=>this.notify(t.path));case"setdocp":return this.setting.docpath=void 0,this.initialize()}}}t.Docify=e,e.dependencies=["pkg://SQLiteDB/libsqlite.js"]}(e=t.application||(t.application={}))}(OS||(OS={})); \ No newline at end of file diff --git a/Docify/build/debug/package.json b/Docify/build/debug/package.json index a237c69..3f09d19 100644 --- a/Docify/build/debug/package.json +++ b/Docify/build/debug/package.json @@ -1,15 +1,68 @@ { "pkgname": "Docify", - "app":"Docify", - "name":"Docify", - "description":"Docify", - "info":{ - "author": "", - "email": "" + "app": "Docify", + "name": "Docify", + "description": "Simple document manager", + "info": { + "author": "Dany LE", + "email": "mrsang@iohub.dev" }, - "version":"0.0.9-b", - "category":"Office", - "iconclass":"bi bi-collection-fill", - "mimes":["none"], - "locale": {} + "version": "0.1.0-b", + "category": "Office", + "iconclass": "bi bi-collection-fill", + "mimes": [ + "none" + ], + "dependencies": [ + "SQLiteDB@0.1.0-a" + ], + "locale": {}, + "locales": { + "en_GB": { + "title": "title", + "Day": "Day", + "Month": "Month", + "Year": "Year", + "Files": "Files", + "Note": "Note", + "Owner": "Owner", + "Tags": "Tags", + "Save": "Save", + "Document preview": "Document preview", + "Ok": "Ok", + "Unable to get owner data handle": "Unable to get owner data handle", + "Name": "Name", + "Do you realy want to delete: `{0}`": "Do you realy want to delete: `{0}`", + "Unable to fetch owner list: {0}": "Unable to fetch owner list: {0}", + "Please enter title": "Please enter title", + "Please attach files to the entry": "Please attach files to the entry", + "Unable to fetch unclassified file list: {0}": "Unable to fetch unclassified file list: {0}", + "Options": "Options", + "Owners": "Owners", + "Preview": "Preview", + "Change doc path": "Change doc path", + "No configured docpath": "No configured docpath", + "Unable to init database file: {0}": "Unable to init database file: {0}", + "Unable to download: {0}": "Unable to download: {0}", + "Unable to open file: {0}": "Unable to open file: {0}", + "Category": "Category", + "Unable to insert category: {0}": "Unable to insert category: {0}", + "Unable delete category: {0}": "Unable delete category: {0}", + "Unable to update category: {0}": "Unable to update category: {0}", + "Unable to fetch document detail: {0}": "Unable to fetch document detail: {0}", + "Please select a category": "Please select a category", + "Unable to add document: {0}": "Unable to add document: {0}", + "Do you really want to delete: `{0}`": "Do you really want to delete: `{0}`", + "Unable to delete document: {0}": "Unable to delete document: {0}", + "File uploaded": "File uploaded", + "Unable to upload document: {0}": "Unable to upload document: {0}", + "Unable to edit document metadata: {0}": "Unable to edit document metadata: {0}", + "Unable to update document list: {0}": "Unable to update document list: {0}", + "Unable to generate document thumbnail: {0}": "Unable to generate document thumbnail: {0}", + "Please select a doc path": "Please select a doc path", + "Error initialize database: {0}": "Error initialize database: {0}", + "Categories": "Categories", + "Documents": "Documents" + } + } } \ No newline at end of file diff --git a/Docify/build/debug/scheme.html b/Docify/build/debug/scheme.html index 6b98f30..f3e98cd 100644 --- a/Docify/build/debug/scheme.html +++ b/Docify/build/debug/scheme.html @@ -25,7 +25,6 @@
-
diff --git a/Docify/build/release/Docify.zip b/Docify/build/release/Docify.zip index 5b3f32a..d47517e 100644 Binary files a/Docify/build/release/Docify.zip and b/Docify/build/release/Docify.zip differ diff --git a/Docify/coffees/dialogs.coffee b/Docify/coffees/dialogs.coffee deleted file mode 100644 index 3a75055..0000000 --- a/Docify/coffees/dialogs.coffee +++ /dev/null @@ -1,329 +0,0 @@ -class OwnerDialog extends this.OS.GUI.BasicDialog - constructor: () -> - super "OwnerDialog", OwnerDialog.scheme - - main: () -> - super.main() - @oview = @find("ownview") - @oview.buttons = [ - { - text: "", - iconclass: "fa fa-plus-circle", - onbtclick: (e) => - @openDialog("PromptDialog", { title: __("Owner"), label: __("Name")}) - .then (d) => - @parent.exec("insert", { table: "owners", data: { name: d } }) - .then (r) => - return @error r.error if r.error - @owner_refresh() - .catch (e) => @error __("Unable to insert owner: {0}", e.toString()),e - .catch (e) => @error e.toString(),e - }, - { - text: "", - iconclass: "fa fa-minus-circle", - onbtclick: (e) => - item = @oview.selectedItem - return unless item - @ask({ text:__("Do you realy want to delete: `{0}`", item.data.text)}) - .then (d) => - return unless d - @parent.exec("delete", {table:"owners", id: parseInt(item.data.id)}) - .then (d) => - return @error d.error if d.error - @owner_refresh() - .catch (e) => - @error __("Unable delete category: {0}", e.toString()), e - }, - { - text: "", - iconclass: "fa fa-pencil-square-o", - onbtclick: (e) => - item = @oview.selectedItem - return unless item - @openDialog("PromptDialog", { title: __("Owner"), label: __("Name"), value: item.data.name }) - .then (d) => - @parent.exec("update", { table: "owners", data: { id: parseInt(item.data.id), name: d } }) - .then (r) => - return @error r.error if r.error - @owner_refresh() - .catch (e) => @error __("Unable to update owner: {0}", e.toString()), e - .catch (e) => @error e.toString() - } - ] - @owner_refresh() - - owner_refresh: () -> - @parent.exec("fetch", "owners") - .then (d) => - v.text = v.name for v in d.result - @oview.data = d.result - .catch (err) => @error __("Unable to fetch owners: {0}", err.toString()), e - -OwnerDialog.scheme = """ - - - - - -""" - -class DocDialog extends this.OS.GUI.BasicDialog - constructor: () -> - super "DocDialog", DocDialog.scheme - - main: () -> - super.main() - @flist = @find("file-list") - @dlist = @find("dlist") - @mlist = @find("mlist") - @ylist = @find("ylist") - @olist = @find("olist") - - @setting = @parent.setting - @exec = @parent.exec - @preview = @parent.preview - - @exec("fetch", "owners") - .then (d) => - return @error d.error if d.error - v.text = v.name for v in d.result - v.selected = (@data and @data.oid is v.id) for v in d.result - @olist.data = d.result - @olist.selected = 0 if not @olist.selectedItem - .catch (e) => - @error __("Unable to fetch owner list: {0}", e.toString()), e - - @dlist.push { - text:"None", - value: 0 - } - selected = 0 - for d in [1..31] - @dlist.push { - text:"#{d}", - value: d - } - selected = d if @data and parseInt(@data.day) is d - @dlist.selected = selected - - @mlist.push { - text:"None", - value: 0 - } - selected = 0 - for d in [1..12] - @mlist.push { - text:"#{d}", - value: d - } - selected = d if @data and parseInt(@data.month) is d - @mlist.selected = selected - - @ylist.push { - text:"None", - value: 0 - } - @ylist.selected = 0 - for y in [1960..new Date().getFullYear()] - @ylist.push { - text:"#{y}", - value: y, - selected: @data and parseInt(@data.year) is y - } - - @flist.buttons = [ - { - text: "", - iconclass: "fa fa-plus-circle", - onbtclick: (e) => - @openDialog(new FilePreviewDialog()) - .then (d) => - d.text = d.filename - @flist.push d - }, - { - text: "", - iconclass: "fa fa-minus-circle", - onbtclick: (e) => - item = @flist.selectedItem - return unless item - @flist.delete item - } - ] - @flist.onlistselect = (e) => - @parent.preview(e.data.item.data.path, @find("preview-canvas")) - - @find("btsave").onbtclick = (e) => - data = { - name: @find("title").value.trim(), - day: @dlist.selectedItem.data.value, - month: @mlist.selectedItem.data.value, - year: @ylist.selectedItem.data.value, - file: (v.path for v in @flist.data), - note: @find("note").value.trim(), - tags: @find("tag").value.trim(), - oid: parseInt(@olist.selectedItem.data.id) - } - return @notify __("Please enter title") unless data.name and data.title != "" - return @notify __("Please attach files to the entry") unless data.file.length > 0 - - @handle data if @handle - @quit() - - return unless @data - @find("title").value = @data.name - @find("note").value = @data.note - @find("tag").value = @data.tags - file = @data.file.asFileHandle() - file.text = file.filename - @flist.data = [ file ] - # owner - - -DocDialog.scheme = """ - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- -
-
-
-
-""" - -class FilePreviewDialog extends this.OS.GUI.BasicDialog - constructor: () -> - super "FilePreviewDialog", FilePreviewDialog.scheme - - main: () -> - super.main() - @flist = @find("file-list") - @flist.buttons = [ - { - text: "", - iconclass: "fa fa-refresh", - onbtclick: (e) => @refresh() - } - ] - - @flist.onlistselect = (e) => - # console.log e.data.item.data - @parent.preview(e.data.item.data.path, @find("preview-canvas")) - @find("btok").onbtclick = (e) => - item = @flist.selectedItem - return @quit() unless item - @handle(item.data) if @handle - @quit() - - @refresh() - - refresh: () -> - "#{@parent.setting.docpath}/unclassified".asFileHandle().read() - .then (d) => - return @error d.error if d.error - v.text = v.filename for v in d.result - @flist.data = (v for v in d.result when v.filename[0] isnt '.') - .catch (e) => - @error __("Unable to fetch unclassified file list: {0}", e.toString()), e - -FilePreviewDialog.scheme = """ - - - - - - - -
- -
-
- -
- -
-
-
-""" - -class PrintDialog extends this.OS.GUI.BasicDialog - constructor: () -> - super "PrintDialog", PrintDialog.scheme - - main: () -> - super.main() - @find("printerName").value = @parent.setting.printer - @find("btnprint").onbtclick = (e) => - data = {} - data.range = parseInt($('input[name=range]:checked', @scheme).val()) - data.pages = @find("txtPageRange").value - data.printer = @find("printerName").value - data.orientation = parseInt($('input[name=orientation]:checked', @scheme).val()) - data.side = parseInt($('input[name=side]:checked', @scheme).val()) - @handle data if @handle - @quit() - -PrintDialog.scheme = """ - - - - - -
- -
- - - -
- -
- -
- - -
- -
- -
- -
- - -
-
- -
-
-
-""" \ No newline at end of file diff --git a/Docify/coffees/main.coffee b/Docify/coffees/main.coffee deleted file mode 100644 index f4de028..0000000 --- a/Docify/coffees/main.coffee +++ /dev/null @@ -1,290 +0,0 @@ -class Docify extends this.OS.application.BaseApplication - constructor: ( args ) -> - super "Docify", args - - main: () -> - - @setting.printer = "" unless @setting.printer - - @catview = @find "catview" - @docview = @find "docview" - @docpreview = @find "preview-canvas" - @docgrid = @find "docgrid" - @docgrid.header = [ - { text: "", width: 100 }, - { text: "" }, - ] - @find("btdld").onbtclick = (e) => - item = @docview.selectedItem - return unless item - item.data.file.asFileHandle() - .download() - .catch (e) => @error __("Unable to download: {}", e.toString()), e - @find("btopen").onbtclick = (e) => - item = @docview.selectedItem - return unless item - item.data.file.asFileHandle().meta() - .then (m) => - return @error m.error if m.error - @_gui.openWith m.result - .catch (e) => @error e.toString(), e - @find("btprint").onbtclick = (e) => - item = @docview.selectedItem - return unless item - @openDialog new PrintDialog(), {} - .then (d) => - return unless d - d.file = item.data.file - @exec("printdoc", d) - .then (r) => - return @error r.error if r.error - @notify r.result - .catch (e) => @error __("Unable to insert category: {0}", e.toString()), e - @catview.buttons = [ - { - text: "", - iconclass: "fa fa-plus-circle", - onbtclick: (e) => - @openDialog("PromptDialog", { title: __("Category"), label: __("Name")}) - .then (d) => - @exec("insert", { table: "categories", data: { name: d } }) - .then (r) => - return @error r.error if r.error - @cat_refresh() - .catch (e) => @error __("Unable to insert category: {0}", e.toString()), e - .catch (e) => @error e.toString(), e - }, - { - text: "", - iconclass: "fa fa-minus-circle", - onbtclick: (e) => - item = @catview.selectedItem - return unless item - @ask({ text:__("Do you realy want to delete: `{0}`", item.data.text)}) - .then (d) => - return unless d - @exec("delete", {table:"categories", id: parseInt(item.data.id)}) - .then (d) => - return @error d.error if d.error - @cat_refresh() - .catch (e) => - @error __("Unable delete category: {0}", e.toString()), e - }, - { - text: "", - iconclass: "fa fa-pencil-square-o", - onbtclick: (e) => - item = @catview.selectedItem - return unless item - @openDialog("PromptDialog", { title: __("Category"), label: __("Name"), value: item.data.name }) - .then (d) => - @exec("update", { table: "categories", data: { id: parseInt(item.data.id), name: d } }) - .then (r) => - return @error r.error if r.error - @cat_refresh() - .catch (e) => @error __("Unable to update category: {0}", e.toString()), e - .catch (e) => @error e.toString(), e - } - ] - - @docview.onlistselect = (e) => - @clear_preview() - item = e.data.item - return unless item - @exec("get_doc", item.data.id) - .then (d) => - return @error d.error if d.error - @preview d.result.file, @docpreview - rows = [] - d.result.size = (d.result.fileinfo.size / 1024.0).toFixed(2) + " Kb" if d.result.fileinfo - map = { - ctime: "Created on", - mtime: "Modified on", - note: "Note", - tags: "Tags", - name: "Title", - owner: "Owner", - edate: "Effective date", - file: "File", - size: "Size" - } - d.result.edate = "#{d.result.day}/#{d.result.month}/#{d.result.year}" - for key, value of d.result - field = map[key] - rows.push [{text: field}, {text: value}] if field - @docgrid.rows = rows - .catch (e) => @error e.toString(), e - - @catview.onlistselect = (e) => - @clear_preview() - item = e.data.item - return unless item - @update_doclist(item.data.id) - - @find("bt-add-doc").onbtclick = (e) => - catiem = @catview.selectedItem - return @notify __("Please select a category") unless catiem - - @openDialog(new DocDialog()) - .then (data) => - data.cid = parseInt(catiem.data.id) - @exec("insertdoc", data) - .then (d) => - return @error d.error if d.error - @notify d.result if d.result - @update_doclist(catiem.data.id) - @clear_preview() - .catch (e) => @error e.toString(), e - - @find("bt-del-doc").onbtclick = (e) => - item = @docview.selectedItem - return unless item - @ask({ text: __("Do you really want to delete: `{0}`", item.data.name) }) - .then (d) => - return unless d - @exec("deletedoc", {id: item.data.id, file: item.data.file}) - .then (r) => - return @error r.error if r.error - @notify r.result - @update_doclist(item.data.cid) - @clear_preview() - .catch (e) => - @error e.toString(), e - @find("bt-upload-doc").onbtclick = (e) => - "#{@setting.docpath}/unclassified".asFileHandle().upload() - .then (r) => - @notify __("File uploaded") - .catch (e) => - @error e.toString(), e - @find("bt-edit-doc").onbtclick = (e) => - item = @docview.selectedItem - catiem = @catview.selectedItem - return unless item - @openDialog(new DocDialog(), item.data) - .then (data) => - data.cid = parseInt(catiem.data.id) - data.id = item.data.id - @exec("updatedoc", { - data:data, - rm: if not data.file.includes(item.data.file) then item.data.file else false - }) - .then (d) => - return @error d.error if d.error - @notify d.result if d.result - @update_doclist(catiem.data.id) - @clear_preview() - .catch (e) => @error e.toString(), e - - @initialize() - - update_doclist: (cid) -> - @exec("select",{table: "docs", cond:"cid = #{cid} ORDER BY year DESC, month DESC, day DESC"}) - .then (d) => - return @error d.error if d.error - v.text = v.name for v in d.result - @docview.data = d.result - .catch (e) => - @error e.toString(), e - - clear_preview: () -> - @docpreview.getContext('2d').clearRect(0,0,@docpreview.width,@docpreview.height) - @docgrid.rows = [] - - preview: (path, canvas) -> - @exec("preview", path) - .then (d) => - return @error d.error if d.error - file = d.result.asFileHandle() - file.read("binary") - .then (d) => - img = new Image() - #($ me.view).append img - img.onload = () => - context = canvas.getContext '2d' - canvas.height = img.height - canvas.width = img.width - #console.log canvas.width, canvas.height - context.drawImage img, 0, 0 - - blob = new Blob [d], { type: file.info.mime } - img.src = URL.createObjectURL blob - - .catch (e) => @error e.toString(), e - .catch (e) => - @error e.toString(), e - - cat_refresh: () -> - @docview.data = [] - @clear_preview() - @exec("fetch", "categories") - .then (d) => - v.text = v.name for v in d.result - @catview.data = d.result - .catch (err) => @error __("Unable to fetch categories: {0}", err.toString()), err - - initialize: () -> - # Check if we have configured docpath - if @setting.docpath - # check data base - @initdb() - else - # ask user to choose a docpath - @openDialog "FileDialog", { title:__("Please select a doc path"), mimes: ['dir'] } - .then (d) => - @setting.docpath = d.file.path - @_api.setting() - @initdb() - .catch (msg) => @error msg.toString(), msg - - exec: (action, args) -> - cmd = - path: "#{@path()}/api.lua", - parameters: - action: action, - docpath: @setting.docpath, - args: args - return @call(cmd) - - initdb: () -> - return @error __("No configured docpath") unless @setting.docpath - # fetch the categories from the database - @exec("init") - .then (d) => - return @error d.error if d.error - @notify d.result - # load categories - @cat_refresh() - .catch (e) => - @error __("Unable to init database: {0}", e.toString()), e - - menu: () -> - [ - { - text: "__(Options)", - nodes: [ - { text: "__(Owners)", id:"owners"}, - { text: "__(Preview)", id:"preview"}, - { text: "__(Change doc path)", id:"setdocp"}, - { text: "__(Set default printer)", id:"setprinter"} - ], - onchildselect: (e) => @fileMenuHandle e.data.item.data.id - } - ] - - fileMenuHandle:(id) -> - switch id - when "owners" - @openDialog new OwnerDialog(), { title: __("Owners")} - when "preview" - @openDialog(new FilePreviewDialog()) - .then (d) => - @notify d.path - when "setdocp" - @setting.docpath = undefined - @initialize() - when "setprinter" - @openDialog "PromptDialog", {title: __("Default Printer"), label: __("Enter printer name")} - .then (n) => - @setting.printer = n - -this.OS.register "Docify", Docify \ No newline at end of file diff --git a/Docify/package.json b/Docify/package.json index a237c69..3f09d19 100644 --- a/Docify/package.json +++ b/Docify/package.json @@ -1,15 +1,68 @@ { "pkgname": "Docify", - "app":"Docify", - "name":"Docify", - "description":"Docify", - "info":{ - "author": "", - "email": "" + "app": "Docify", + "name": "Docify", + "description": "Simple document manager", + "info": { + "author": "Dany LE", + "email": "mrsang@iohub.dev" }, - "version":"0.0.9-b", - "category":"Office", - "iconclass":"bi bi-collection-fill", - "mimes":["none"], - "locale": {} + "version": "0.1.0-b", + "category": "Office", + "iconclass": "bi bi-collection-fill", + "mimes": [ + "none" + ], + "dependencies": [ + "SQLiteDB@0.1.0-a" + ], + "locale": {}, + "locales": { + "en_GB": { + "title": "title", + "Day": "Day", + "Month": "Month", + "Year": "Year", + "Files": "Files", + "Note": "Note", + "Owner": "Owner", + "Tags": "Tags", + "Save": "Save", + "Document preview": "Document preview", + "Ok": "Ok", + "Unable to get owner data handle": "Unable to get owner data handle", + "Name": "Name", + "Do you realy want to delete: `{0}`": "Do you realy want to delete: `{0}`", + "Unable to fetch owner list: {0}": "Unable to fetch owner list: {0}", + "Please enter title": "Please enter title", + "Please attach files to the entry": "Please attach files to the entry", + "Unable to fetch unclassified file list: {0}": "Unable to fetch unclassified file list: {0}", + "Options": "Options", + "Owners": "Owners", + "Preview": "Preview", + "Change doc path": "Change doc path", + "No configured docpath": "No configured docpath", + "Unable to init database file: {0}": "Unable to init database file: {0}", + "Unable to download: {0}": "Unable to download: {0}", + "Unable to open file: {0}": "Unable to open file: {0}", + "Category": "Category", + "Unable to insert category: {0}": "Unable to insert category: {0}", + "Unable delete category: {0}": "Unable delete category: {0}", + "Unable to update category: {0}": "Unable to update category: {0}", + "Unable to fetch document detail: {0}": "Unable to fetch document detail: {0}", + "Please select a category": "Please select a category", + "Unable to add document: {0}": "Unable to add document: {0}", + "Do you really want to delete: `{0}`": "Do you really want to delete: `{0}`", + "Unable to delete document: {0}": "Unable to delete document: {0}", + "File uploaded": "File uploaded", + "Unable to upload document: {0}": "Unable to upload document: {0}", + "Unable to edit document metadata: {0}": "Unable to edit document metadata: {0}", + "Unable to update document list: {0}": "Unable to update document list: {0}", + "Unable to generate document thumbnail: {0}": "Unable to generate document thumbnail: {0}", + "Please select a doc path": "Please select a doc path", + "Error initialize database: {0}": "Error initialize database: {0}", + "Categories": "Categories", + "Documents": "Documents" + } + } } \ No newline at end of file diff --git a/Docify/project.json b/Docify/project.json deleted file mode 100644 index ec2e84e..0000000 --- a/Docify/project.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Docify", - "css": ["css/main.css"], - "javascripts": [], - "coffees": ["coffees/dialogs.coffee", "coffees/main.coffee"], - "copies": ["assets/scheme.html", "api/api.lua", "package.json", "README.md"] -} \ No newline at end of file diff --git a/Docify/ts/dialogs.ts b/Docify/ts/dialogs.ts new file mode 100644 index 0000000..ed0b5ea --- /dev/null +++ b/Docify/ts/dialogs.ts @@ -0,0 +1,354 @@ +namespace OS { + export namespace application { + export namespace docify { + export class OwnerDialog extends OS.GUI.BasicDialog { + private oview: GUI.tag.ListViewTag; + constructor() { + super("OwnerDialog", OwnerDialog.scheme); + } + + main() { + super.main(); + this.oview = this.find("ownview") as GUI.tag.ListViewTag; + if(!this.data.dbhandle) + { + throw new Error(__("Unable to get owner data handle").__()); + } + + this.oview.buttons = [ + { + text: "", + iconclass: "fa fa-plus-circle", + onbtclick: async (e: any) => { + try + { + const d = await this.openDialog("PromptDialog", { + title: __("Owner"), + label: __("Name") + }); + this.data.dbhandle.cache = { name: d }; + const r = await this.data.dbhandle.write(undefined); + if(r.error) + { + throw new Error(r.error); + } + await this.owner_refresh(); + } + catch(e) + { + this.error(e.toString(), e); + } + } + }, + { + text: "", + iconclass: "fa fa-minus-circle", + onbtclick: async (e: any) => { + try{ + const item = this.oview.selectedItem; + if (!item) { return; } + let d = await this.ask({ text:__("Do you realy want to delete: `{0}`", item.data.text)}); + if (!d) { return; } + const handle = item.data.$vfs as API.VFS.BaseFileHandle; + let r = await handle.remove(); + if(r.error) + { + throw new Error(r.error.toString()); + } + await this.owner_refresh(); + } + catch(e) + { + this.error(e.toString(), e); + } + } + }, + { + text: "", + iconclass: "fa fa-pencil-square-o", + onbtclick: async (e: any) => { + try + { + const item = this.oview.selectedItem; + if (!item) { return; } + const d = await this.openDialog("PromptDialog", { + title: __("Owner"), + label: __("Name"), + value: item.data.name + }); + const handle = item.data.$vfs as API.VFS.BaseFileHandle; + handle.cache = { name: d }; + const r = await handle.write(undefined); + if(r.error) + { + throw new Error(r.error.toString()); + } + await this.owner_refresh(); + } + catch(e) + { + this.error(e.toString(), e); + } + } + } + ]; + return this.owner_refresh(); + } + + private async owner_refresh() { + + const d = await this.data.dbhandle.read(); + for (let v of d) { v.text = v.name; } + this.oview.data = d; + } + } + + OwnerDialog.scheme = `\ + + + + +\ + `; + + export class DocDialog extends OS.GUI.BasicDialog { + private flist: GUI.tag.ListViewTag; + private dlist: GUI.tag.ListViewTag; + private mlist: GUI.tag.ListViewTag; + private ylist: GUI.tag.ListViewTag; + private olist: GUI.tag.ListViewTag; + constructor() { + super("DocDialog", DocDialog.scheme); + } + + main() { + let d: number; + super.main(); + this.flist = this.find("file-list") as GUI.tag.ListViewTag; + this.dlist = this.find("dlist") as GUI.tag.ListViewTag; + this.mlist = this.find("mlist") as GUI.tag.ListViewTag; + this.ylist = this.find("ylist") as GUI.tag.ListViewTag; + this.olist = this.find("olist") as GUI.tag.ListViewTag; + const app = this.parent as Docify; + const target=app.setting.docpath.asFileHandle(); + const dbhandle=`sqlite://${target.genealogy.join("/")}/docify.db@owners`.asFileHandle(); + dbhandle.read() + .then((d) => { + if (d.error) { return this.error(d.error); } + for (let v of d) { + v.text = v.name; + v.selected = this.data && (this.data.oid === v.id); + } + this.olist.data = d; + if (!this.olist.selectedItem) { return this.olist.selected = 0; } + }).catch((e) => { + return this.error(__("Unable to fetch owner list: {0}", e.toString()), e); + }); + + this.dlist.push({ + text:"None", + value: 0 + }); + let selected = 0; + for (d = 1; d <= 31; d++) { + this.dlist.push({ + text:`${d}`, + value: d + }); + if (this.data && (parseInt(this.data.day) === d)) { selected = d; } + } + this.dlist.selected = selected; + + this.mlist.push({ + text:"None", + value: 0 + }); + selected = 0; + for (d = 1; d <= 12; d++) { + this.mlist.push({ + text:`${d}`, + value: d + }); + if (this.data && (parseInt(this.data.month) === d)) { selected = d; } + } + this.mlist.selected = selected; + + this.ylist.push({ + text:"None", + value: 0 + }); + this.ylist.selected = 0; + for (let y = 1960, end = new Date().getFullYear(), asc = 1960 <= end; asc ? y <= end : y >= end; asc ? y++ : y--) { + this.ylist.push({ + text:`${y}`, + value: y, + selected: this.data && (parseInt(this.data.year) === y) + }); + } + + this.flist.buttons = [ + { + text: "", + iconclass: "fa fa-plus-circle", + onbtclick: (e: any) => { + return this.openDialog(new FilePreviewDialog(), { + app: app + }) + .then((d: { text: any; filename: any; }) => { + d.text = d.filename; + return this.flist.push(d); + }); + } + }, + { + text: "", + iconclass: "fa fa-minus-circle", + onbtclick: (e: any) => { + const item = this.flist.selectedItem; + if (!item) { return; } + return this.flist.delete(item); + } + } + ]; + this.flist.onlistselect = async (e) => { + return await app.preview(e.data.item.data.path, this.find("preview-canvas") as HTMLCanvasElement); + }; + + (this.find("btsave") as GUI.tag.ButtonTag).onbtclick = (e: any) => { + const data: GenericObject = { + name: (this.find("title") as HTMLInputElement).value.trim(), + day: this.dlist.selectedItem.data.value, + month: this.mlist.selectedItem.data.value, + year: this.ylist.selectedItem.data.value, + file: (Array.from(this.flist.data).map((v: { path: any; }) => v.path)), + note: (this.find("note") as HTMLTextAreaElement).value.trim(), + tags: (this.find("tag") as HTMLInputElement).value.trim(), + oid: parseInt(this.olist.selectedItem.data.id) + }; + if (!data.name || (data.title === "")) { return this.notify(__("Please enter title")); } + if (!(data.file.length > 0)) { return this.notify(__("Please attach files to the entry")); } + + if (this.handle) { this.handle(data); } + return this.quit(); + }; + + if (!this.data) { return; } + (this.find("title") as HTMLInputElement).value = this.data.name; + (this.find("note") as HTMLTextAreaElement).value = this.data.note; + (this.find("tag") as HTMLInputElement).value = this.data.tags; + const file = this.data.file.asFileHandle(); + file.text = file.filename; + return this.flist.data = [ file ]; + } + } + + + DocDialog.scheme = `\ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+
\ + `; + + export class FilePreviewDialog extends OS.GUI.BasicDialog { + private flist: GUI.tag.ListViewTag; + constructor() { + super("FilePreviewDialog", FilePreviewDialog.scheme); + } + + main() { + super.main(); + this.flist = this.find("file-list") as GUI.tag.ListViewTag; + this.flist.buttons = [ + { + text: "", + iconclass: "fa fa-refresh", + onbtclick: (e: any) => this.refresh() + } + ]; + const app = this.data.app as Docify; + + this.flist.onlistselect = async (e) => { + // console.log e.data.item.data + return await app.preview(e.data.item.data.path, this.find("preview-canvas") as HTMLCanvasElement); + }; + (this.find("btok") as GUI.tag.ButtonTag).onbtclick = (e: any) => { + const item = this.flist.selectedItem; + if (!item) { return this.quit(); } + if (this.handle) { this.handle(item.data); } + return this.quit(); + }; + + return this.refresh(); + } + + async refresh() { + try + { + const app = this.data.app as Docify; + const d = await `${app.setting.docpath}/unclassified`.asFileHandle().read(); + if (d.error) { return this.error(d.error); } + for (let v of d.result) { v.text = v.filename; } + return this.flist.data = d.result.filter((e) => e.filename[0] !== '.'); + } + catch(e) + { + return this.error(__("Unable to fetch unclassified file list: {0}", e.toString()), e); + } + } + } + + FilePreviewDialog.scheme = `\ + + + + + + + +
+ +
+
+ +
+ +
+
+
\ + `; + } + } +} \ No newline at end of file diff --git a/Docify/ts/main.ts b/Docify/ts/main.ts new file mode 100644 index 0000000..d468020 --- /dev/null +++ b/Docify/ts/main.ts @@ -0,0 +1,543 @@ +namespace OS { + export namespace application { + + export class Docify extends BaseApplication { + private catview: GUI.tag.ListViewTag; + private docview: GUI.tag.ListViewTag; + private docpreview: HTMLCanvasElement; + private docgrid: GUI.tag.GridViewTag; + + private dbhandle: API.VFS.BaseFileHandle; + private catdb: API.VFS.BaseFileHandle; + private ownerdb: API.VFS.BaseFileHandle; + private docdb: API.VFS.BaseFileHandle; + + constructor( args: any ) { + super("Docify", args); + } + + private async init_db() { + try { + if (!this.setting.docpath) { return this.error(__("No configured docpath")); } + + const target=this.setting.docpath.asFileHandle(); + this.dbhandle=`sqlite://${target.genealogy.join("/")}/docify.db`.asFileHandle(); + const tables = await this.dbhandle.read(); + /** + * Init following tables if not exist: + * - categories + * - owners + * - docs + */ + await `${this.setting.docpath}`.asFileHandle().mk("unclassified"); + await `${this.setting.docpath}`.asFileHandle().mk("cache"); + let r = undefined; + this.catdb = `${this.dbhandle.path}@categories`.asFileHandle(); + if(!tables.categories) + { + this.dbhandle.cache = { + name: "TEXT" + } + r = await this.dbhandle.write("categories"); + if(r.error) + { + throw new Error(r.error as string); + } + this.catdb.cache = { + name: "Uncategoried" + }; + r = await this.catdb.write(undefined); + if(r.error) + { + throw new Error(r.error as string); + } + } + this.ownerdb = `${this.dbhandle.path}@owners`.asFileHandle(); + if(!tables.owners) + { + this.dbhandle.cache = { + name: "TEXT", + } + r = await this.dbhandle.write("owners"); + if(r.error) + { + throw new Error(r.error as string); + } + this.ownerdb.cache = { + name: "None" + }; + r = await this.ownerdb.write(undefined); + if(r.error) + { + throw new Error(r.error as string); + } + } + this.docdb = `${this.dbhandle.path}@docs`.asFileHandle(); + if(!tables.docs) + { + this.dbhandle.cache = { + name: "TEXT NOT NULL", + ctime: "INTEGER", + day: "INTEGER", + month: "INTEGER", + year: "INTEGER", + cid: "INTEGER DEFAULT 0", + oid: "INTEGER DEFAULT 0", + file: "TEXT NOT NULL", + tags: "TEXT", + note: "TEXT", + mtime: "INTEGER", + //'FOREIGN KEY("oid")': 'REFERENCES "owners"("id") ON DELETE SET DEFAULT ON UPDATE NO ACTION', + //'FOREIGN KEY("cid")': 'REFERENCES "categories"("id") ON DELETE SET DEFAULT ON UPDATE NO ACTION', + } + r = await this.dbhandle.write("docs"); + if(r.error) + { + throw new Error(r.error as string); + } + } + return await this.cat_refresh(); + + } + catch(e) { + this.error(__("Unable to init database file: {0}",e.toString()),e); + this.dbhandle = undefined; + } + } + + main() { + + if (!this.setting.printer) { this.setting.printer = ""; } + + this.catview = this.find("catview") as GUI.tag.ListViewTag; + this.docview = this.find("docview") as GUI.tag.ListViewTag; + this.docpreview = this.find("preview-canvas") as HTMLCanvasElement; + this.docgrid = this.find("docgrid") as GUI.tag.GridViewTag; + this.docgrid.header = [ + { text: "", width: 100 }, + { text: "" }, + ]; + (this.find("btdld") as GUI.tag.ButtonTag).onbtclick = async (e) => { + try { + const item = this.docview.selectedItem; + if (!item) { return; } + await item.data.file.asFileHandle().download(); + } + catch(e) + { + this.error(__("Unable to download: {0}", e.toString()), e); + } + }; + (this.find("btopen") as GUI.tag.ButtonTag).onbtclick = async (e) => { + try { + const item = this.docview.selectedItem; + if (!item) { return; } + const m = await item.data.file.asFileHandle().meta(); + if (m.error) + { + throw new Error(m.error); + } + return this._gui.openWith(m.result); + } + catch(e) + { + this.error(__("Unable to open file: {0}", e.toString()), e); + } + }; + this.catview.buttons = [ + { + text: "", + iconclass: "fa fa-plus-circle", + onbtclick:async (e) => { + try + { + const d = await this.openDialog("PromptDialog", { + title: __("Category"), + label: __("Name") + }); + this.catdb.cache = { name: d }; + const r = await this.catdb.write(undefined); + if (r.error) + { + throw new Error(r.error.toString()); + } + return await this.cat_refresh(); + } + catch(e) + { + this.error(__("Unable to insert category: {0}", e.toString()), e); + } + } + }, + { + text: "", + iconclass: "fa fa-minus-circle", + onbtclick: async (e) => + { + try + { + const item = this.catview.selectedItem; + if (!item) { return; } + const d = await this.ask({ text:__("Do you realy want to delete: `{0}`", item.data.text)}); + if (!d) { return; } + + const r = await this.catdb.remove({ + where: { + id: item.data.id + } + }); + if(r.error) + { + throw new Error(r.error.toString()); + } + await this.cat_refresh(); + } + catch(e) + { + this.error(__("Unable delete category: {0}", e.toString()), e); + } + } + }, + { + text: "", + iconclass: "fa fa-pencil-square-o", + onbtclick: async (_) => { + try + { + const item = this.catview.selectedItem; + if (!item) { return; }; + const cat = item.data; + if (!cat) { return; } + const d = await this.openDialog("PromptDialog", { + title: __("Category"), + label: __("Name"), + value: item.data.name + }); + const handle: API.VFS.BaseFileHandle = cat.$vfs; + handle.cache = { id: parseInt(item.data.id), name: d }; + const r = await handle.write(undefined); + if(r.error) + { + throw new Error(r.error.toString()); + } + await this.cat_refresh(); + } + catch(e) + { + this.error(__("Unable to update category: {0}", e.toString()), e); + } + } + } + ]; + + this.docview.onlistselect = async (evt) => { + try + { + this.clear_preview(); + const item = evt.data.item; + if(!item) return; + const handle = item.data.$vfs as API.VFS.BaseFileHandle; + // TODO join owner here + const d = await handle.read(); + await this.preview(d.file, this.docpreview); + const rows = []; + // TODO: if (d.result.fileinfo) { d.result.size = (d.result.fileinfo.size / 1024.0).toFixed(2) + " Kb"; } + const map = { + ctime: "Created on", + mtime: "Modified on", + note: "Note", + tags: "Tags", + name: "Title", + owner: "Owner", + edate: "Effective date", + file: "File", + size: "Size" + }; + d.edate = `${d.day}/${d.month}/${d.year}`; + for (let key in d) { + let value = d[key]; + const field = map[key]; + if(key === "ctime" || key == "mtime") + { + value = (new Date(value*1000)).toDateString(); + } + if (field) { rows.push([{text: field}, {text: value}]); } + } + return this.docgrid.rows = rows; + } + catch(e) + { + this.error(__("Unable to fetch document detail: {0}", e.toString()), e); + } + }; + + this.catview.onlistselect = (e) => { + this.clear_preview(); + const item = e.data.item; + if (!item) { return; } + return this.update_doclist(item.data.id); + }; + + (this.find("bt-add-doc") as GUI.tag.ButtonTag).onbtclick = async (evt) => { + try + { + const catiem = this.catview.selectedItem; + if (!catiem) { return this.notify(__("Please select a category")); } + const data = await this.openDialog(new docify.DocDialog()); + data.cid = parseInt(catiem.data.id); + const timestamp = Math.floor(Date.now() / 1000); + data.ctime = timestamp; + data.mtime = timestamp; + const r = await this.exec("merge_files", data); + if(r.error) + { + throw new Error(r.error.toString()); + } + data.file = r.result; + this.docdb.cache = data; + const d = await this.docdb.write(undefined); + if(d.error) + { + throw new Error(d.error.toString()); + } + if (d.result) { this.toast(d.result); } + this.update_doclist(catiem.data.id); + this.clear_preview(); + } + catch(e) + { + this.error(__("Unable to add document: {0}", e.toString()), e); + } + }; + + (this.find("bt-del-doc") as GUI.tag.ButtonTag).onbtclick = async (evt) => { + try + { + const item = this.docview.selectedItem; + if (!item) { return; } + const d = await this.ask({ text: __("Do you really want to delete: `{0}`", item.data.name) }); + if (!d) { return; } + let r = await this.docdb.remove({ + where: { + id: item.data.id + } + }); + if(r.error) + { + throw new Error(r.error.toString()); + } + r = await this.exec("deletedoc", {file: item.data.file}); + if(r.error) + { + throw new Error(r.error.toString()); + } + this.notify(r.result.toString()); + this.update_doclist(item.data.cid); + return this.clear_preview(); + } + catch(e) + { + this.error(__("Unable to delete document: {0}", e.tostring()), e); + } + }; + (this.find("bt-upload-doc") as GUI.tag.ButtonTag).onbtclick = async (evt) => { + try + { + await `${this.setting.docpath}/unclassified`.asFileHandle().upload(); + this.toast(__("File uploaded")); + } + catch(e) + { + this.error(__("Unable to upload document: {0}", e.toString()), e); + } + } + (this.find("bt-edit-doc") as GUI.tag.ButtonTag).onbtclick = async (evt) => { + try + { + const item = this.docview.selectedItem; + const catiem = this.catview.selectedItem; + if (!item) { return; } + const data = await this.openDialog(new docify.DocDialog(), item.data); + data.cid = parseInt(catiem.data.id); + data.id = item.data.id; + const timestamp = Math.floor(Date.now() / 1000); + data.mtime = timestamp; + let d = await this.exec("updatedoc", { + data, + rm: !data.file.includes(item.data.file) ? item.data.file : false + }); + if(d.error) + { + throw new Error(d.error); + } + const handle = item.data.$vfs; + handle.cache = d.result; + d = await handle.write(undefined); + if(d.error) + { + throw new Error(d.error); + } + if (d.result) { this.toast(d.result); } + this.update_doclist(catiem.data.id); + return this.clear_preview(); + } + catch(e) + { + this.error(__("Unable to edit document metadata: {0}", e.toString())); + } + }; + return this.initialize(); + } + + private async update_doclist(cid: any) { + try + { + const d = await this.docdb.read({ + where: { + cid: cid + }, + order: ["year$desc", "month$desc", "day$desc"] + }); + + // this.exec("select",{table: "docs", cond:`cid = ${cid} ORDER BY year DESC, month DESC, day DESC`}); + if(d.error) + { + throw new Error(d.error); + } + for (let v of d) + { + v.text = v.name; + } + return this.docview.data = d; + } + catch(e) + { + this.error(__("Unable to update document list: {0}", e.toString()), e); + } + } + + private clear_preview() { + this.docpreview.getContext('2d').clearRect(0,0,this.docpreview.width,this.docpreview.height); + return this.docgrid.rows = []; + } + + async preview(path: any, canvas: HTMLCanvasElement) { + try { + const d = await this.exec("preview", path); + if (d.error) { + throw new Error(d.error); + } + const file = d.result.asFileHandle(); + const data = await file.read("binary"); + const img = new Image(); + //($ me.view).append img + img.onload = () => { + const context = canvas.getContext('2d'); + canvas.height = img.height; + canvas.width = img.width; + //console.log canvas.width, canvas.height + return context.drawImage(img, 0, 0); + }; + + const blob = new Blob([data], { type: file.info.mime }); + return img.src = URL.createObjectURL(blob); + } + catch(e) + { + this.error(__("Unable to generate document thumbnail: {0}", e.toString()), e); + } + } + + private cat_refresh(): Promise { + return new Promise(async (resolve, reject) => { + try { + this.docview.data = []; + this.clear_preview(); + const d = await this.catdb.read(); + for (let v of d) { + v.text = v.name; + } + return this.catview.data = d; + } + catch(e) + { + reject(__e(e)); + } + }); + } + + private async initialize() { + try + { + // Check if we have configured docpath + if (this.setting.docpath) { + // check data base + return await this.init_db(); + } else + { + // ask user to choose a docpath + const d = await this.openDialog("FileDialog", { + title:__("Please select a doc path"), + type: 'dir' + }); + this.setting.docpath = d.file.path; + // save the doc path to local setting + //await this._api.setting(); + return await this.init_db(); + } + } + catch(e) + { + this.error(__("Error initialize database: {0}", e.toString()), e); + } + } + + exec(action: string, args?: GenericObject) { + const cmd = { + path: `${this.path()}/api.lua`, + parameters: { + action, + docpath: this.setting.docpath, + args + } + }; + return this.call(cmd); + } + + menu() { + return [ + { + text: "__(Options)", + nodes: [ + { text: "__(Owners)", id:"owners"}, + { text: "__(Preview)", id:"preview"}, + { text: "__(Change doc path)", id:"setdocp"} + ], + onchildselect: (e) => this.fileMenuHandle(e.data.item.data.id) + } + ]; + } + + private fileMenuHandle(id: any) { + switch (id) { + case "owners": + return this.openDialog(new docify.OwnerDialog(), { + title: __("Owners"), + dbhandle: this.ownerdb + }); + case "preview": + return this.openDialog(new docify.FilePreviewDialog(), { + app: this + }) + .then((d: { path: any; }) => { + return this.notify(d.path); + }); + case "setdocp": + this.setting.docpath = undefined; + return this.initialize(); + } + } + } + Docify.dependencies = ["pkg://SQLiteDB/libsqlite.js"]; + } +} \ No newline at end of file diff --git a/packages.json b/packages.json index f3fa40d..06f0ccf 100644 --- a/packages.json +++ b/packages.json @@ -154,9 +154,9 @@ "name": "Docify", "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/Docify/README.md", "category": "Office", - "author": "", - "version": "0.0.9-b", - "dependencies": [], + "author": "Dany LE", + "version": "0.1.0-b", + "dependencies": ["SQLiteDB@0.1.0-a"], "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/Docify/build/release/Docify.zip" }, {