diff --git a/Blogger/README.md b/Blogger/README.md
deleted file mode 100644
index 2c958fe..0000000
--- a/Blogger/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Blogger
-
-Blackend for my blog at https://blog.iohub.dev
-
-
-## Change logs
-
-### v0.2.x-a
-* Patch 7: Fix sendmail API security bug
-* Patch 6: Chage libraries load order
-* Patch 5: Add user photo to portfolio
-* Patch 4: Add package dependencies
-* Patch 3: Correct JSON text decoding
-* Patch 2: Bug fix rendering content
-* Patch 0-1 Important change: Store raw post content to the database instead of base64 string as before
-
-### v0.1.x-a
-* Patch 3-4: Enhance youtube video embedding feature in markdown
-* Patch 2: CV Category now can be created when database is not created yet
-* Patch 1: Fix package archive broken
-* Patch 0: Change default email of the sender
\ No newline at end of file
diff --git a/Blogger/api/sendmail.lua b/Blogger/api/sendmail.lua
deleted file mode 100644
index 6e8aab4..0000000
--- a/Blogger/api/sendmail.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-
-local data = ...
--- print(data.content)
-local error_msg = {}
-local iserror = false
-local tmp_name = "/tmp/"..os.time(os.date("!*t"))
-local file = io.open (tmp_name , "w")
-if file then
- file:write("From: mrsang@lxsang.me\n")
- file:write("Subject: " .. data.title .. "\n")
- file:write( data.content.."\n")
- file:close()
- for k,v in pairs(data.to) do
- print("sent to:"..v)
- local to = v
- local cmd = 'cat ' ..tmp_name .. '| sendmail ' .. to
- --print(cmd)
- local r = os.execute(cmd)
- if not r then
- iserror = true
- table.insert(error_msg, v)
- print("Unable to send mail to: "..v)
- end
- end
-else
- iserror = true
- table.insert(error_msg, "Cannot create mail file")
-end
-local result = {}
-result.error = iserror
-result.result = error_msg
-return result
\ No newline at end of file
diff --git a/Blogger/build/release/Blogger.zip b/Blogger/build/release/Blogger.zip
deleted file mode 100644
index 5571e96..0000000
Binary files a/Blogger/build/release/Blogger.zip and /dev/null differ
diff --git a/Blogger/cvsection.html b/Blogger/cvsection.html
deleted file mode 100644
index eb7eeaf..0000000
--- a/Blogger/cvsection.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Blogger/dialogs.coffee b/Blogger/dialogs.coffee
deleted file mode 100644
index efe94b8..0000000
--- a/Blogger/dialogs.coffee
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright 2017-2018 Xuan Sang LE
-
-# AnTOS Web desktop is is licensed under the GNU General Public
-# License v3.0, see the LICENCE file for more information
-
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-#along with this program. If not, see https://www.gnu.org/licenses/.
-class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
- constructor: () ->
- super "BloggerCategoryDialog", BloggerCategoryDialog.scheme
-
- main: () ->
- super.main()
- @tree = @find "tree"
- @txtinput = @find "txtinput"
-
- (@find "bt-ok").onbtclick = (e) =>
- sel = @tree.selectedItem
- return @notify __("Please select a parent category") unless sel
- seldata = sel.data
- val = @txtinput.value
- return @notify __("Please enter category name") if val is "" and not @data.selonly
- return @notify __("Parent can not be the category itself") if @data.cat and @data.cat.id is seldata.id
- @handle { p: seldata, value: val } if @handle
- @quit()
-
- (@find "bt-cancel").onbtclick = (e) =>
- @quit()
- if @data and @data.tree
- if @data and @data.cat
- @txtinput.value = @data.cat.name
- if @data.cat.pid is "0"
- seldata = @data.tree
- else
- seldata = @findDataByID @data.cat.pid, @data.tree.nodes
- seldata.selected = true if seldata
- @tree.data = @data.tree
- @tree.expandAll()
- # TODO set selected category name
-
- findDataByID: (id, list) ->
- for data in list
- return data if data.id is id
- if data.nodes
- @findDataByID id, data.nodes
- return undefined
-
-BloggerCategoryDialog.scheme = """
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-"""
-
-# This dialog is use for cv section editing
-
-class BloggerCVSectionDiaglog extends this.OS.GUI.BasicDialog
- constructor: (parent) ->
- file = "#{parent.meta().path}/cvsection.html".asFileHandle()
- super "BloggerCVSectionDiaglog", file
-
- main: () ->
- super.main()
- @editor = new SimpleMDE
- autoDownloadFontAwesome: false
- element: @find "contentarea"
- status: false
- toolbar: false
- ($ (@select '[class = "CodeMirror-scroll"]')[0]).css "min-height", "50px"
- ($ (@select '[class="CodeMirror cm-s-paper CodeMirror-wrap"]')[0]).css "min-height", "50px"
- inputs = @select "[input-class='user-input']"
- (($ v).val @data.section[v.name] for v in inputs ) if @data and @data.section
- @editor.value @data.section.content if @data and @data.section
- (@find "section-publish").swon = (if @data and @data.section and Number(@data.section.publish) then true else false)
- (@find "bt-cv-sec-save").onbtclick = (e) =>
- data = {}
- data[v.name] = ($ v).val() for v in inputs
- data.content = @editor.value()
- return @notify __("Title or content must not be blank") if data.title is "" and data.content is ""
- #return @notify "Content must not be blank" if data.content is ""
- data.id = @data.section.id if @data and @data.section
- val = (@find "section-publish").swon
- if val is true
- data.publish = 1
- else
- data.publish = 0
- @handle data if @handle
- @quit()
-
- @on "vboxchange", () => @resizeContent()
- @resizeContent()
-
- resizeContent: () ->
- container = @find "editor-container"
- children = ($ container).children()
- cheight = ($ container).height() - 30
- ($ children[1]).css("height", cheight + "px")
-
-
-# this dialog is for send mail
-class BloggerSendmailDiaglog extends this.OS.GUI.BasicDialog
- constructor: (parent) ->
- file = "#{parent.meta().path}/sendmail.html".asFileHandle()
- super "BloggerSendmailDiaglog", file
-
- main: () ->
- super.main()
- @subdb = new @.parent._api.DB("subscribers")
- @maillinglist = @find "email-list"
- title = (new RegExp "^#+(.*)\n", "g").exec @data.content
- (@find "mail-title").value = title[1]
- content = (@data.content.substring 0, 500) + "..."
- (@find "contentarea").value = BloggerSendmailDiaglog.template.format @data.id, content
-
- @subdb.find {}
- .then (d) =>
- for v in d
- v.text = v.name
- v.switch = true
- v.checked = true
- @maillinglist. items = d
- .catch (e) =>
- @error __("Cannot fetch subscribers data: {0}", e.toString()), e
-
- (@find "bt-sendmail").onbtclick = (e) =>
- items = @maillinglist.items
- emails = []
- for v in items
- if v.checked is true
- console.log v.email
- emails.push v.email
-
- return @notify __("No email selected") if emails.length is 0
- # send the email
- data =
- path: "#{@parent.path()}/sendmail.lua",
- parameters:
- to: emails,
- title: (@find "mail-title").value,
- content: (@find "contentarea").value
- @_api.apigateway data, false
- .then (d) =>
- return @notify __("Unable to send mail to: {0}", d.result.join(", ")) if d.error
- @quit()
- .catch (e) =>
- console.log e
- @error __("Error sending mail: {0}", e.toString()), e
-
-
-
-BloggerSendmailDiaglog.template = """
-Hello,
-
-Xuan Sang LE has just published a new post on his blog: https://blog.lxsang.me/post/id/{0}
-
-==========
-{1}
-==========
-
-
-Read the full article via:
-https://blog.lxsang.me/post/id/{0}
-
-You receive this email because you have been subscribed to his blog.
-
-Have a nice day,
-
-Sent from Blogger, an AntOS application
-"""
\ No newline at end of file
diff --git a/Blogger/main.coffee b/Blogger/main.coffee
deleted file mode 100644
index e601d2b..0000000
--- a/Blogger/main.coffee
+++ /dev/null
@@ -1,506 +0,0 @@
-# Copyright 2017-2018 Xuan Sang LE
-
-# AnTOS Web desktop is is licensed under the GNU General Public
-# License v3.0, see the LICENCE file for more information
-
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-#along with this program. If not, see https://www.gnu.org/licenses/.
-class Blogger extends this.OS.application.BaseApplication
- constructor: (args) ->
- super "Blogger", args
-
-
- main: () ->
- @user = {}
- @cvlist = @find "cv-list"
- @cvlist.ontreeselect = (d) =>
- return unless d
- data = d.data.item.data
- @CVSectionByCID Number(data.id)
-
- @inputtags = @.find "input-tags"
- @bloglist = @find "blog-list"
- @seclist = @find "cv-sec-list"
-
- el = @find("photo")
- $(el)
- .click (e) =>
- @openDialog("FileDialog", {
- title: __("Select image file"),
- mimes: ["image/.*"]
- })
- .then (d) =>
- el.value = d.file.path
- .catch (e) => @error __("Unable to get file"), e
-
- @userdb = new @_api.DB("user")
- @cvcatdb = new @_api.DB("cv_cat")
- @cvsecdb = new @_api.DB("cv_sections")
- @blogdb = new @_api.DB("blogs")
-
-
- @tabcontainer = @find "tabcontainer"
- @tabcontainer.ontabselect = (e) =>
- @fetchData e.data.container.aid
-
- (@find "bt-user-save").onbtclick = (e) =>
- @saveUser()
-
- (@find "cv-cat-add").onbtclick = (e) =>
- fn = (tree) =>
- @openDialog(new BloggerCategoryDialog(), {
- title: __("Add category"),
- tree: tree
- }).then (d) =>
- c =
- name: d.value,
- pid: d.p.id,
- publish: 1
- @cvcatdb.save c
- .then (r) =>
- @refreshCVCat()
- .catch (e) => @error __("Cannot add new category"), e
- .catch (e) => @error e.toString(), e
- @fetchCVCat()
- .then (tree) => fn(tree)
- .catch (e) =>
- data =
- text: "Porfolio",
- id:"0",
- nodes: []
- fn(data)
- @error __("Unable to fetch categories"), e
-
- (@find "cv-cat-edit").onbtclick = (e) =>
- sel = @cvlist.selectedItem
- return unless sel
- cat = sel.data
- return unless cat
- @fetchCVCat().then (tree) =>
- @openDialog(new BloggerCategoryDialog(), {
- title: __("Edit category"),
- tree: tree, cat: cat
- }).then (d) =>
- c =
- id: cat.id,
- publish: cat.publish,
- pid: d.p.id,
- name: d.value
-
- @cvcatdb.save c
- .then (r) =>
- @refreshCVCat()
- .catch (e) =>
- @error __("Cannot Edit category"), e
- .catch (e) => @error __("Unable to fetch categories"), e
-
- (@find "cv-cat-del").onbtclick = (e) =>
- sel = @cvlist.selectedItem
- return unless sel
- cat = sel.data
- return unless cat
- @openDialog("YesNoDialog", {
- title: __("Delete category") ,
- iconclass: "fa fa-question-circle",
- text: __("Do you really want to delete: {0}?", cat.name)
- }).then (d) =>
- return unless d
- @deleteCVCat cat
- .catch (e) => @error e.toString(), e
-
- (@find "cv-sec-add").onbtclick = (e) =>
- sel = @cvlist.selectedItem
- return unless sel
- cat = sel.data
- return @notify __("Please select a category") unless cat and cat.id isnt "0"
- @openDialog(new BloggerCVSectionDiaglog(@), {
- title: __("New section entry for {0}", cat.name)
- }).then (d) =>
- d.cid = Number cat.id
- d.start = Number d.start
- d.end = Number d.end
- # d.publish = 1
- @cvsecdb.save d
- .then (r) =>
- @CVSectionByCID Number(cat.id)
- .catch (e) => @error __("Cannot save section: {0}", e.toString()), e
-
- (@find "cv-sec-move").onbtclick = (e) =>
- sel = (@find "cv-sec-list").selectedItem
- return @notify __("Please select a section to move") unless sel
- sec = sel.data
-
- @fetchCVCat().then (tree) =>
- @openDialog(new BloggerCategoryDialog(),{
- title: __("Move to"),
- tree: tree,
- selonly: true
- }).then (d) =>
- c =
- id: sec.id,
- cid: d.p.id
-
- @cvsecdb.save c
- .then (r) =>
- @CVSectionByCID(sec.cid)
- (@find "cv-sec-list").unselect()
- .catch (e) => @error __("Cannot move section"), e
-
- (@find "cv-sec-edit").onbtclick = (e) =>
- sel = (@find "cv-sec-list").selectedItem
- return @notify __("Please select a section to edit") unless sel
- sec = sel.data
- @openDialog(new BloggerCVSectionDiaglog(@), {
- title: __("Modify section entry"),
- section: sec
- }).then (d) =>
- d.cid = Number sec.cid
- d.start = Number d.start
- d.end = Number d.end
- #d.publish = Number sec.publish
- @cvsecdb.save d
- .then (r) =>
- @CVSectionByCID Number(sec.cid)
- .catch (e) => return @error __("Cannot save section: {0}", e.toString()), e
-
- @seclist.onitemclose = (e) =>
- return unless e
- data = e.data.item.data
- @openDialog("YesNoDialog", {
- iconclass: "fa fa-question-circle",
- text: __("Do you really want to delete: {0}?", data.title)
- }).then (b) =>
- return unless b
- @cvsecdb.delete data.id
- .then (r) =>
- @seclist.delete e.data.item
- .catch (e) => @error __("Cannot delete the section: {0}", e.toString()), e
- return false
-
- @editor = new SimpleMDE
- element: @find "markarea"
- autoDownloadFontAwesome: false
- autofocus: true
- tabSize: 4
- indentWithTabs: true
- toolbar: [
- {
- name: __("New"),
- className: "fa fa-file",
- action: (e) =>
- @bloglist.unselect()
- @clearEditor()
- },
- {
- name: __("Save"),
- className: "fa fa-save",
- action: (e) =>
- @saveBlog()
- }
- , "|", "bold", "italic", "heading", "|", "quote", "code",
- "unordered-list", "ordered-list", "|", "link",
- "image", "table", "horizontal-rule",
- {
- name: "image",
- className: "fa fa-file-image-o",
- action: (e) =>
- @openDialog("FileDialog", {
- title: __("Select image file"),
- mimes: ["image/.*"]
- }).then (d) =>
- d.file.path.asFileHandle().publish()
- .then (r) =>
- doc = @editor.codemirror.getDoc()
- doc.replaceSelection "![](#{@_api.handle.shared}/#{r.result})"
- .catch (e) => @error __("Cannot export file for embedding to text"), e
- },
- {
- name:"Youtube",
- className: "fa fa-youtube",
- action: (e) =>
- doc = @editor.codemirror.getDoc()
- doc.replaceSelection "[[youtube:]]"
- }
- "|",
- {
- name: __("Preview"),
- className: "fa fa-eye no-disable",
- action: (e) =>
- @previewOn = !@previewOn
- SimpleMDE.togglePreview e
- #/console.log @select ".editor-preview editor-preview-active"
- renderMathInElement @find "editor-container"
- },
- "|",
- {
- name: __("Send mail"),
- className: "fa fa-paper-plane",
- action: (e) =>
- sel = @bloglist.selectedItem
- return @error __("No post selected") unless sel
- data = sel.data
- @openDialog(new BloggerSendmailDiaglog(@), {
- title: __("Send mail"),
- content: @editor.value(),
- id: data.id
- })
- .then (d) ->
- console.log "Email sent"
- }
- ],
-
- @bloglist.onlistselect = (e) =>
- el = @bloglist.selectedItem
- return unless el
- sel = el.data
- return unless sel
- @blogdb.get Number(sel.id)
- .then (r) =>
- @editor.value r.content
- @inputtags.value = r.tags
- (@find "blog-publish").swon = if Number(r.publish) then true else false
- .catch (e) =>
- @error __("Cannot fetch the entry content"), e
-
- @bloglist.onitemclose = (e) =>
- return unless e
- el = e.data.item
- data = el.data
- @openDialog("YesNoDialog", {
- title: __("Delete a post"),
- iconclass: "fa fa-question-circle",
- text: __("Do you really want to delete this post ?")
- }).then (b) =>
- return unless b
- @blogdb.delete data.id
- .then (r) =>
- @bloglist.delete el
- @bloglist.unselect()
- @clearEditor()
- return false
-
-
- @bindKey "CTRL-S", () =>
- sel = @tabcontainer.selectedTab
- return unless sel and sel.container.aid is "blog-container"
- @saveBlog()
- @on "vboxchange", () =>
- @resizeContent()
-
- @resizeContent()
- @loadBlogs()
- # @fetchData 0
- # USER TAB
- fetchData: (idx) ->
- switch idx
- when "user-container" #user info
-
- @userdb.get null
- .then (d) =>
- @user = d[0]
- inputs = @select "[input-class='user-input']"
- ($ v).val @user[v.name] for v in inputs
- .catch (e) => @error __("Cannot fetch user data"), e
- when "cv-container" # category
- @refreshCVCat()
- else
- @loadBlogs()
-
- saveUser:() ->
- inputs = @select "[input-class='user-input']"
- @user[v.name] = ($ v).val() for v in inputs
- return @notify __("Full name must be entered") if not @user.fullname or @user.fullname is ""
- #console.log @user
- @userdb.save @user
- .then (r) =>
- return @notify __("User data updated")
- .catch (e) => return @error __("Cannot save user data"), e
-
-
- # PORFOLIO TAB
- refreshCVCat: () ->
- @fetchCVCat().then (data) =>
- @cvlist.data = data
- @cvlist.expandAll()
- .catch (e) => @error __("Unable to load categories"), e
-
- fetchCVCat: () ->
- new Promise (resolve, reject) =>
- data =
- text: "Porfolio",
- id:"0",
- nodes: []
- cnd =
- order:
- name: "ASC"
- @cvcatdb.find cnd
- .then (d) =>
- @catListToTree d, data, "0"
- resolve data
- .catch (e) -> reject __e e
- #it = (@cvlist.find "pid", "2")[0]
- #@cvlist.set "selectedItem", it
-
- catListToTree: (table, data, id) ->
- result = (v for v in table when v.pid is id)
- return data.nodes = null if result.length is 0
- for v in result
- v.nodes = []
- v.text = v.name
- @catListToTree table, v, v.id
- #v.nodes = null if v.nodes.length is 0
- data.nodes.push v
-
- deleteCVCat: (cat) ->
- me = @
- ids = []
- func = (c) ->
- ids.push c.id
- func(v) for v in c.nodes if c.nodes
- func(cat)
-
- cond = ({ "=": { cid: v } } for v in ids)
- # delete all content
- @cvsecdb.delete({ "or": cond }).then (r) =>
- cond = ({ "=": { id: v } } for v in ids)
- @cvcatdb.delete({ "or": cond }).then (re) =>
- @refreshCVCat()
- @seclist.data=[]
- .catch (e) =>
- @error __("Cannot delete the category: {0} [{1}]", cat.name, e.toString()), e
- .catch (e) =>
- @error __("Cannot delete all content of: {0} [{1}]", cat.name, e.toString()), e
-
- CVSectionByCID: (cid) ->
- cond =
- exp:
- "=":
- cid: cid
- order:
- start: "DESC"
- @cvsecdb.find(cond).then (d) =>
- items = []
- (@find "cv-sec-status").text = __("Found {0} sections", d.length)
- for v in d
- v.closable = true
- v.tag = "afx-blogger-cvsection-item"
- v.start = Number(v.start)
- v.end = Number(v.end)
- v.start = undefined if v.start < 1000
- v.end = undefined if v.end < 1000
- items.push v
- @seclist.data = items
- .catch (e) => @error e.toString(), e
-
- # blog
- saveBlog: () ->
- sel = undefined
- selel = @bloglist.selectedItem
- sel = selel.data if selel
- tags = @inputtags.value
- content = @editor.value()
- title = (new RegExp "^#+(.*)\n", "g").exec content
- return @notify __("Please insert a title in the text: beginning with heading") unless title and title.length is 2
- return @notify __("Please enter tags") if tags is ""
- d = new Date()
- data =
- content: content
- title: title[1].trim()
- tags: tags
- ctime: if sel then sel.ctime else d.timestamp()
- ctimestr: if sel then sel.ctimestr else d.toString()
- utime: d.timestamp()
- utimestr: d.toString()
- rendered: @process(@editor.options.previewRender(content))
- publish: if (@find "blog-publish").swon then 1 else 0
- data.id = sel.id if sel
- #save the data
- @blogdb.save data
- .then (r) =>
- @loadBlogs()
- .catch (e) => @error __("Cannot save blog: {0}", e.toString()), e
-
- process: (text) ->
- # find video tag and rendered it
- embed = (id) ->
- return """
-
- """
- re = /\[\[youtube:([^\]]*)\]\]/g
- replace = []
- while (found = re.exec text) isnt null
- replace.push found
- return text unless replace.length > 0
- ret = ""
- begin = 0
- for it in replace
- ret += text.substring begin, it.index
- ret += embed(it[1])
- begin = it.index + it[0].length
- ret += text.substring begin, text.length
- #console.log ret
- return ret
-
- clearEditor:() ->
- @.editor.value ""
- @.inputtags.value = ""
- (@.find "blog-publish").swon = false
- # load blog
- loadBlogs: () ->
- selidx = -1
- el = @bloglist.selectedItem
- selidx = $(el).index()
- cond =
- order:
- ctime: "DESC"
- fields: [
- "id",
- "title",
- "ctimestr",
- "ctime",
- "utime",
- "utimestr"
- ]
- @blogdb.find cond
- .then (r) =>
- v.tag = "afx-blogger-post-item" for v in r
- @bloglist.data = r
- if selidx isnt -1
- @bloglist.selected = selidx
- else
- @clearEditor()
- @bloglist.selected = -1
- .catch (e) => @error __("No post found: {0}", e.toString()), e
-
- resizeContent: () ->
- container = @find "editor-container"
- children = ($ container).children()
- titlebar = (($ @scheme).find ".afx-window-top")[0]
- toolbar = children[1]
- statusbar = children[4]
- cheight = ($ @scheme).height() - ($ titlebar).height() - ($ toolbar).height() - ($ statusbar).height() - 90
- ($ children[2]).css("height", cheight + "px")
-
-Blogger.singleton = true
-Blogger.dependencies = [
- "pkg://SimpleMDE/main.js",
- "pkg://SimpleMDE/main.css"
- "pkg://Katex/main.js",
- "pkg://Katex/main.css",
-]
-this.OS.register "Blogger", Blogger
\ No newline at end of file
diff --git a/Blogger/main.css b/Blogger/main.css
deleted file mode 100644
index 780d5fc..0000000
--- a/Blogger/main.css
+++ /dev/null
@@ -1,92 +0,0 @@
-afx-app-window[data-id="blogger-win"] afx-tab-container[data-id="tabcontainer"] afx-tab-bar afx-list-view > div.list-container {
- padding: 0;
- margin: 0;
- border-right: 1px solid #292929;
-}
-
-afx-app-window[data-id="blogger-win"] afx-tab-container[data-id="tabcontainer"] afx-tab-bar afx-list-view > div.list-container > ul li{
- font-size: 15px;
- padding:0;
- width: 100%;
- border-radius: 0;
- border:0;
- margin: 0;
- text-align: center;
-}
-afx-app-window[data-id="blogger-win"] afx-tab-container[data-id="tabcontainer"] afx-tab-bar afx-list-view > div.list-container > ul li.selected {
- background-color: #116cd6;
- color:white;
-}
-
-afx-app-window[data-id="blogger-win"] afx-hbox[data-id="user-container"] afx-label i.label-text{
- font-weight: bold;
-}
-
-afx-app-window .lbl-header i.label-text{
- font-weight: bold;
-}
-afx-app-window[data-id="blogger-win"] afx-hbox[data-id="cv-container"] .cat-header{
- border-bottom: 1px solid #cbcbcb;
- text-align: center;
-}
-
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] > .list-container > ul .afx-cv-sec-title .label-text{
- font-weight: bold;
-
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] afx-blogger-cvsection-item afx-label {
- display: block;
-
-}
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] afx-blogger-cvsection-item p {
- padding: 0;
- margin: 0;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] afx-blogger-cvsection-item .afx-cv-sec-period,
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] afx-blogger-cvsection-item .afx-cv-sec-loc {
- text-align: right;
-}
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] afx-blogger-cvsection-item afx-cv-sec-content{
- text-align: justify;
- overflow-wrap: break-word;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] > div.list-container > ul li.selected {
- border: 1px solid #116cd6;
- background-color: transparent;
- border-radius: 5px;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] .closable::before{
- content: "\f014";
- font-size: 14px;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "cv-sec-list"] .period-end::before{
- content: "-";
-}
-
-afx-app-window[data-id ='blogger-win'] .editor-toolbar{
- background-color: white;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "blog-list"] > div.list-container > ul li afx-label {
- display: block;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "blog-list"] > div.list-container > ul .afx-blogpost-title .label-text{
- font-weight: bold;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "blog-list"] > div.list-container > ul .blog-dates .label-text{
- font-size: 10px;
- font-weight: normal;
-}
-
-afx-app-window[data-id="blogger-win"] afx-list-view[ data-id = "blog-list"] > div.list-container > ul li.selected {
- background-color: #116cd6;
- color:white;
-}
diff --git a/Blogger/package.json b/Blogger/package.json
deleted file mode 100644
index 0531786..0000000
--- a/Blogger/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "app":"Blogger",
- "name":"Blogging application",
- "description":"Backend manager for blogging",
- "info":{
- "author": "Xuan Sang LE",
- "email": "xsang.le@gmail.com"
- },
- "version":"0.2.7-a",
- "category":"Internet",
- "iconclass":"fa fa-book",
- "dependencies": ["SimpleMDE@1.11.2-r","Katex@0.11.1-r"],
- "mimes":["none"]
-}
\ No newline at end of file
diff --git a/Blogger/project.json b/Blogger/project.json
deleted file mode 100644
index e2c2d72..0000000
--- a/Blogger/project.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "Blogger",
- "css": ["main.css"],
- "javascripts": [],
- "coffees": ["main.coffee", "dialogs.coffee", "tags.coffee"],
- "copies": [
- "scheme.html",
- "cvsection.html",
- "api/sendmail.lua",
- "sendmail.html",
- "package.json",
- "README.md"
- ]
-}
\ No newline at end of file
diff --git a/Blogger/scheme.html b/Blogger/scheme.html
deleted file mode 100644
index 36d7082..0000000
--- a/Blogger/scheme.html
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Blogger/sendmail.html b/Blogger/sendmail.html
deleted file mode 100644
index 799709a..0000000
--- a/Blogger/sendmail.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Blogger/tags.coffee b/Blogger/tags.coffee
deleted file mode 100644
index b751498..0000000
--- a/Blogger/tags.coffee
+++ /dev/null
@@ -1,63 +0,0 @@
-Ant = this
-
-class CVSectionListItemTag extends this.OS.GUI.tag.ListViewItemTag
- constructor: () ->
- super()
-
- ondatachange: () ->
- return unless @data
- v = @data
- nativel = ["content", "start", "end" ]
- @closable = v.closable
- for k, el of @refs
- if v[k] and v[k] isnt ""
- if nativel.includes k
- $(el).text v[k]
- else
- el.text = v[k]
-
- reload: () ->
-
- init:() ->
-
-
- itemlayout: () ->
- { el: "div", children: [
- { el: "afx-label", ref: "title", class: "afx-cv-sec-title" },
- { el: "afx-label", ref: "subtitle", class: "afx-cv-sec-subtitle" },
- { el: "p", ref: "content", class: "afx-cv-sec-content" },
- { el: "p", class: "afx-cv-sec-period", children: [
- { el: "i", ref: "start" },
- { el: "i", ref: "end", class: "period-end" }
- ] },
- { el: "afx-label", ref: "location", class: "afx-cv-sec-loc" }
- ] }
-
-this.OS.GUI.tag.define "afx-blogger-cvsection-item", CVSectionListItemTag
-
-
-class BlogPostListItemTag extends this.OS.GUI.tag.ListViewItemTag
- constructor: () ->
- super()
-
- ondatachange: (v) ->
- return unless @data
- v = @data
- v.closable = true
- @closable = v.closable
- @refs.title.text = v.title
- @refs.ctimestr.text = __("Created: {0}", v.ctimestr)
- @refs.utimestr.text = __("Updated: {0}", v.utimestr)
-
- reload: () ->
-
- init:() ->
-
- itemlayout: () ->
- { el: "div", children: [
- { el: "afx-label", ref: "title", class: "afx-blogpost-title" },
- { el: "afx-label", ref: "ctimestr", class: "blog-dates" },
- { el: "afx-label", ref: "utimestr", class: "blog-dates" },
- ] }
-
-this.OS.GUI.tag.define "afx-blogger-post-item", BlogPostListItemTag
\ No newline at end of file
diff --git a/DBDecoder/README.md b/DBDecoder/README.md
deleted file mode 100644
index 4b364cd..0000000
--- a/DBDecoder/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# DBDecoder
-This is an example project, generated by AntOS Development Kit
-
-## Howto
-Use the CodePad command palette to access to the SDK functionalities:
-
-1. Create new project
-2. Init the project from the current folder located in side bar
-3. Build and run the project
-4. Release the project in zip package
-
-## Set up build target
-
-Open the `project.json` file from the current project tree and add/remove
-build target entries. Save the file
\ No newline at end of file
diff --git a/DBDecoder/assets/scheme.html b/DBDecoder/assets/scheme.html
deleted file mode 100644
index cb58be5..0000000
--- a/DBDecoder/assets/scheme.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/DBDecoder/build/debug/README.md b/DBDecoder/build/debug/README.md
deleted file mode 100644
index 4b364cd..0000000
--- a/DBDecoder/build/debug/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# DBDecoder
-This is an example project, generated by AntOS Development Kit
-
-## Howto
-Use the CodePad command palette to access to the SDK functionalities:
-
-1. Create new project
-2. Init the project from the current folder located in side bar
-3. Build and run the project
-4. Release the project in zip package
-
-## Set up build target
-
-Open the `project.json` file from the current project tree and add/remove
-build target entries. Save the file
\ No newline at end of file
diff --git a/DBDecoder/build/debug/main.js b/DBDecoder/build/debug/main.js
deleted file mode 100644
index 08b71ff..0000000
--- a/DBDecoder/build/debug/main.js
+++ /dev/null
@@ -1,54 +0,0 @@
-(function() {
- var DBDecoder;
-
- DBDecoder = class DBDecoder extends this.OS.application.BaseApplication {
- constructor(args) {
- super("DBDecoder", args);
- }
-
- main() {
- var bt;
- bt = this.find("decoder");
- this.db = new this._api.DB("blogs");
- return bt.onbtclick = (e) => {
- // decode the database
- return this.db.find("1=1").then((data) => {
- var i, len, v;
- for (i = 0, len = data.length; i < len; i++) {
- v = data[i];
- v.content = atob(v.content);
- v.rendered = atob(v.rendered);
- }
- return this.saveDB(data).then(() => {
- return this.notify("Data base saved");
- }).catch((e) => {
- return this.error(e.toString(), e);
- });
- });
- };
- }
-
- saveDB(list) {
- return new Promise((resolve, reject) => {
- var record;
- if (list.length === 0) {
- return resolve();
- }
- record = list.shift();
- return this.db.save(record).then(() => {
- return this.saveDB(list).then(() => {
- return resolve();
- }).catch((e) => {
- return reject(__e(e));
- });
- }).catch((e) => {
- return reject(__e(e));
- });
- });
- }
-
- };
-
- this.OS.register("DBDecoder", DBDecoder);
-
-}).call(this);
diff --git a/DBDecoder/build/debug/package.json b/DBDecoder/build/debug/package.json
deleted file mode 100644
index 3075358..0000000
--- a/DBDecoder/build/debug/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "app":"DBDecoder",
- "name":"DBDecoder",
- "description":"DBDecoder",
- "info":{
- "author": "",
- "email": ""
- },
- "version":"0.0.2-a",
- "category":"Other",
- "iconclass":"fa fa-adn",
- "mimes":["none"],
- "locale": {}
-}
\ No newline at end of file
diff --git a/DBDecoder/build/debug/scheme.html b/DBDecoder/build/debug/scheme.html
deleted file mode 100644
index cb58be5..0000000
--- a/DBDecoder/build/debug/scheme.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/DBDecoder/build/release/DBDecoder.zip b/DBDecoder/build/release/DBDecoder.zip
deleted file mode 100644
index ad0e7f0..0000000
Binary files a/DBDecoder/build/release/DBDecoder.zip and /dev/null differ
diff --git a/DBDecoder/coffees/main.coffee b/DBDecoder/coffees/main.coffee
deleted file mode 100644
index a1a75e7..0000000
--- a/DBDecoder/coffees/main.coffee
+++ /dev/null
@@ -1,29 +0,0 @@
-class DBDecoder extends this.OS.application.BaseApplication
- constructor: ( args ) ->
- super "DBDecoder", args
-
- main: () ->
- bt = @find "decoder"
- @db = new @_api.DB("blogs")
- bt.onbtclick = (e) =>
- # decode the database
- @db.find("1=1").then (data) =>
- for v in data
- v.content = atob(v.content)
- v.rendered = atob(v.rendered)
- @saveDB(data).then () =>
- @notify "Data base saved"
- .catch (e) => @error e.toString(), e
-
- saveDB: (list) ->
- new Promise (resolve, reject) =>
- return resolve() if list.length is 0
- record = list.shift()
- @db.save(record).then () =>
- @saveDB(list)
- .then () => resolve()
- .catch (e) => reject __e e
- .catch (e) => reject __e e
-
-
-this.OS.register "DBDecoder", DBDecoder
\ No newline at end of file
diff --git a/DBDecoder/package.json b/DBDecoder/package.json
deleted file mode 100644
index 3075358..0000000
--- a/DBDecoder/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "app":"DBDecoder",
- "name":"DBDecoder",
- "description":"DBDecoder",
- "info":{
- "author": "",
- "email": ""
- },
- "version":"0.0.2-a",
- "category":"Other",
- "iconclass":"fa fa-adn",
- "mimes":["none"],
- "locale": {}
-}
\ No newline at end of file
diff --git a/DBDecoder/project.json b/DBDecoder/project.json
deleted file mode 100644
index a0454bc..0000000
--- a/DBDecoder/project.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "DBDecoder",
- "css": [],
- "javascripts": [],
- "coffees": ["coffees/main.coffee"],
- "copies": ["assets/scheme.html", "package.json", "README.md"]
-}
\ No newline at end of file
diff --git a/Docify/README.md b/Docify/README.md
deleted file mode 100644
index 662978c..0000000
--- a/Docify/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Docify
-Simple PDF document manager
-
-## Change logs
-- v0.0.8-b: Allow upload files directly from the app
-- v0.0.7-a: Change category and icon
-- v0.0.6-a: Add print dialog (support server side printing)
-- v0.0.5-a: Fix delete file bug
-- v0.0.4-a: Display file size in entry meta-data
-- v0.0.3-a: Fix document moved bug, sort entries by year, month, day
\ No newline at end of file
diff --git a/Docify/api/api.lua b/Docify/api/api.lua
deleted file mode 100644
index 9fb4241..0000000
--- a/Docify/api/api.lua
+++ /dev/null
@@ -1,435 +0,0 @@
-local arg = ...
-
-ulib = require("ulib")
-sqlite = modules.sqlite()
-vfs = require("vfs")
-
-local handle = {}
-local docpath = nil
-local dbpath = nil
-
-local result = function(data)
- return {
- error = false,
- result = data
- }
-end
-
-local error = function(data)
- return {
- error = data,
- result = false
- }
-end
-
-local mkdirp =function(p)
- if not vfs.exists(p) then
- if not vfs.mkdir(p) then
- return false, error("Unable to create directory: "..p)
- end
- end
- return true, nil
-end
-
-local merge_files = function(data)
- local firstfile = data.file[1]
- local fpath = docpath.."/"..data.cid
- local r, e = mkdirp(fpath)
- if not r then return e end
- fpath = fpath.."/"..os.date("%d-%m-%Y_%H_%M_%S")..".pdf"
- -- concat the files
- if #data.file > 1 then
- local cmd = "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="..vfs.ospath(fpath)
- for i,v in ipairs(data.file) do
- cmd = cmd.." \""..vfs.ospath(v).."\""
- end
- os.execute(cmd)
- if not vfs.exists(fpath) then
- return error("Unable to merge PDF files")
- end
- cmd = "chmod 777 "..vfs.ospath(fpath)
- os.execute(cmd)
- else
- local cmd = "mv \""..vfs.ospath(firstfile).."\" \""..vfs.ospath(fpath).."\""
- os.execute(cmd)
- if not vfs.exists(fpath) then
- return error("Unable to move PDF file")
- 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"
- 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"
- if vfs.exists(thumb) then
- vfs.delete(thumb)
- end
- -- delete all files
- if vfs.exists(v) then
- vfs.delete(v)
- end
- end
- 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"
- -- 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)
- os.execute(cmd)
- end
-
- if vfs.exists(tpath) then
- local cmd = "chmod 777 "..vfs.ospath(tpath)
- os.execute(cmd)
- return result(tpath)
- else
- return error("do not exist")
- 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)
- vfs.move(param.file, newfile)
- -- delete thumb file
- local thumb = docpath.."/cache/"..std.sha1(param.file:gsub(docpath,""))..".png"
- if vfs.exists(thumb) then
- vfs.delete(thumb)
- end
- return result("Document entry deleted")
-end
-
-handle.updatedoc = function(param)
- local r = 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 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"
- if vfs.exists(thumb) then
- vfs.move(thumb, newwthumb)
- end
- end
- param.data.file = r.result
- print(r.result)
- param.data.mtime = os.time(os.date("!*t"))
- 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
- return error("Invalid action parameter")
-end
\ No newline at end of file
diff --git a/Docify/assets/scheme.html b/Docify/assets/scheme.html
deleted file mode 100644
index 1d5c67e..0000000
--- a/Docify/assets/scheme.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Docify/build.json b/Docify/build.json
deleted file mode 100644
index 27525e2..0000000
--- a/Docify/build.json
+++ /dev/null
@@ -1,83 +0,0 @@
-{
- "name": "Docify",
- "targets": {
- "init": {
- "jobs": [
- {
- "name": "vfs-mkdir",
- "data": [
- "build",
- "build/debug",
- "build/release"
- ]
- }
- ]
- },
- "coffee": {
- "require": [
- "coffee"
- ],
- "jobs": [
- {
- "name": "coffee-compile",
- "data": {
- "src": [
- "coffees/dialogs.coffee",
- "coffees/main.coffee"
- ],
- "dest": "build/debug/main.js"
- }
- }
- ]
- },
- "uglify": {
- "require": [
- "terser"
- ],
- "jobs": [
- {
- "name": "terser-uglify",
- "data": [
- "build/debug/main.js"
- ]
- }
- ]
- },
- "copy": {
- "jobs": [
- {
- "name": "vfs-cp",
- "data": {
- "src": [
- "assets/scheme.html",
- "api/api.lua",
- "package.json",
- "README.md"
- ],
- "dest": "build/debug"
- }
- }
- ]
- },
- "release": {
- "require": [
- "zip"
- ],
- "depend": [
- "init",
- "coffee",
- "uglify",
- "copy"
- ],
- "jobs": [
- {
- "name": "zip-mk",
- "data": {
- "src": "build/debug",
- "dest": "build/release/Docify.zip"
- }
- }
- ]
- }
- }
-}
\ No newline at end of file
diff --git a/Docify/build/debug/README.md b/Docify/build/debug/README.md
deleted file mode 100644
index 662978c..0000000
--- a/Docify/build/debug/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Docify
-Simple PDF document manager
-
-## Change logs
-- v0.0.8-b: Allow upload files directly from the app
-- v0.0.7-a: Change category and icon
-- v0.0.6-a: Add print dialog (support server side printing)
-- v0.0.5-a: Fix delete file bug
-- v0.0.4-a: Display file size in entry meta-data
-- v0.0.3-a: Fix document moved bug, sort entries by year, month, day
\ No newline at end of file
diff --git a/Docify/build/debug/api.lua b/Docify/build/debug/api.lua
deleted file mode 100644
index 9fb4241..0000000
--- a/Docify/build/debug/api.lua
+++ /dev/null
@@ -1,435 +0,0 @@
-local arg = ...
-
-ulib = require("ulib")
-sqlite = modules.sqlite()
-vfs = require("vfs")
-
-local handle = {}
-local docpath = nil
-local dbpath = nil
-
-local result = function(data)
- return {
- error = false,
- result = data
- }
-end
-
-local error = function(data)
- return {
- error = data,
- result = false
- }
-end
-
-local mkdirp =function(p)
- if not vfs.exists(p) then
- if not vfs.mkdir(p) then
- return false, error("Unable to create directory: "..p)
- end
- end
- return true, nil
-end
-
-local merge_files = function(data)
- local firstfile = data.file[1]
- local fpath = docpath.."/"..data.cid
- local r, e = mkdirp(fpath)
- if not r then return e end
- fpath = fpath.."/"..os.date("%d-%m-%Y_%H_%M_%S")..".pdf"
- -- concat the files
- if #data.file > 1 then
- local cmd = "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="..vfs.ospath(fpath)
- for i,v in ipairs(data.file) do
- cmd = cmd.." \""..vfs.ospath(v).."\""
- end
- os.execute(cmd)
- if not vfs.exists(fpath) then
- return error("Unable to merge PDF files")
- end
- cmd = "chmod 777 "..vfs.ospath(fpath)
- os.execute(cmd)
- else
- local cmd = "mv \""..vfs.ospath(firstfile).."\" \""..vfs.ospath(fpath).."\""
- os.execute(cmd)
- if not vfs.exists(fpath) then
- return error("Unable to move PDF file")
- 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"
- 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"
- if vfs.exists(thumb) then
- vfs.delete(thumb)
- end
- -- delete all files
- if vfs.exists(v) then
- vfs.delete(v)
- end
- end
- 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"
- -- 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)
- os.execute(cmd)
- end
-
- if vfs.exists(tpath) then
- local cmd = "chmod 777 "..vfs.ospath(tpath)
- os.execute(cmd)
- return result(tpath)
- else
- return error("do not exist")
- 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)
- vfs.move(param.file, newfile)
- -- delete thumb file
- local thumb = docpath.."/cache/"..std.sha1(param.file:gsub(docpath,""))..".png"
- if vfs.exists(thumb) then
- vfs.delete(thumb)
- end
- return result("Document entry deleted")
-end
-
-handle.updatedoc = function(param)
- local r = 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 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"
- if vfs.exists(thumb) then
- vfs.move(thumb, newwthumb)
- end
- end
- param.data.file = r.result
- print(r.result)
- param.data.mtime = os.time(os.date("!*t"))
- 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
- return error("Invalid action parameter")
-end
\ No newline at end of file
diff --git a/Docify/build/debug/main.css b/Docify/build/debug/main.css
deleted file mode 100644
index 6b0de1d..0000000
--- a/Docify/build/debug/main.css
+++ /dev/null
@@ -1,25 +0,0 @@
-
-afx-app-window[data-id = "Docify"] .header .label-text
-{
- font-weight: bold;
-}
-div[data-id = "preview-container"]
-{
- overflow: auto;
- display: block;
-}
-
-canvas[data-id = "preview-canvas"]
-{
- display: block;
- margin:0 auto;
-}
-afx-app-window[data-id = "DocifyPrintDialog"] i.label-text {
- font-weight: bold;
-}
-
-afx-app-window[data-id = "DocifyPrintDialog"] input[type="radio"] {
- margin: 0;
- height: 12px;
- margin-left: 10px;
-}
\ No newline at end of file
diff --git a/Docify/build/debug/main.js b/Docify/build/debug/main.js
deleted file mode 100644
index 25cd55f..0000000
--- a/Docify/build/debug/main.js
+++ /dev/null
@@ -1 +0,0 @@
-(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