2018-09-05 16:56:04 +02:00
|
|
|
BaseController:subclass(
|
|
|
|
"PostController",
|
|
|
|
{
|
|
|
|
registry = {},
|
|
|
|
models = {"blog", "analytical"}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
function PostController:index(...)
|
|
|
|
return self:top(table.unpack({...}))
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:top(limit)
|
|
|
|
limit = limit or POST_LIMIT
|
|
|
|
local data, order = self.blog:fetch(nil, limit)
|
|
|
|
if not data or #order == 0 then
|
|
|
|
return self:notfound("No entry found")
|
|
|
|
end
|
|
|
|
self:list(data, order)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:afterof(id, limit)
|
|
|
|
limit = limit or POST_LIMIT
|
|
|
|
local data, order = self.blog:fetch({[">"] = {id = id}}, limit, {ctime = "ASC"})
|
|
|
|
if not data or #order == 0 then
|
|
|
|
return self:notfound("No entry found")
|
|
|
|
end
|
|
|
|
table.sort(
|
|
|
|
order,
|
|
|
|
function(a, b)
|
|
|
|
return a > b
|
|
|
|
end
|
|
|
|
)
|
|
|
|
self:list(data, order)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:beforeof(id, limit)
|
|
|
|
limit = limit or POST_LIMIT
|
|
|
|
local data, order = self.blog:fetch({["<"] = {id = id}}, limit)
|
|
|
|
if not data or #order == 0 then
|
|
|
|
return self:notfound("No entry found")
|
|
|
|
end
|
|
|
|
self:list(data, order)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
-- this is a private function, should not be called by user
|
|
|
|
function PostController:list(data, order)
|
|
|
|
self.template:setView("posts")
|
|
|
|
self.template:set("posts", data)
|
|
|
|
self.template:set("order", order)
|
|
|
|
self.template:set("title", "Blog Home")
|
|
|
|
self.template:set("minid", self.blog:minid())
|
|
|
|
self.template:set("maxid", self.blog:maxid())
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:bytag(b64tag, limit, action, id)
|
|
|
|
local tag = bytes.__tostring(std.b64decode(b64tag .. "=="))
|
|
|
|
local cond = {["LIKE"] = {tags = "%%" .. tag .. "%%"}}
|
|
|
|
local order = nil
|
|
|
|
limit = limit or POST_LIMIT
|
|
|
|
if action == "before" then
|
|
|
|
cond = {["and"] = {cond, {["<"] = {id = id}}}}
|
|
|
|
elseif action == "after" then
|
|
|
|
cond = {["and"] = {cond, {[">"] = {id = id}}}}
|
|
|
|
order = {ctime = "ASC"}
|
|
|
|
end
|
|
|
|
local data, sort = self.blog:fetch(cond, limit, order)
|
|
|
|
if not data or #sort == 0 then
|
|
|
|
return self:notfound("No entry found")
|
|
|
|
end
|
|
|
|
|
|
|
|
if (action == "after") then
|
|
|
|
table.sort(
|
|
|
|
sort,
|
|
|
|
function(a, b)
|
|
|
|
return a > b
|
|
|
|
end
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
self.template:set("query", b64tag)
|
|
|
|
self.template:set("action", "bytag")
|
|
|
|
self:list(data, sort)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:id(pid)
|
|
|
|
local data, order = self.blog:fetch({["="] = {id = pid}})
|
|
|
|
if not data or #order == 0 then
|
|
|
|
return self:notfound("No post found")
|
|
|
|
end
|
|
|
|
data = data[1]
|
2020-06-18 09:53:15 +02:00
|
|
|
data.rendered = data.rendered:gsub("%%", "%%%%")
|
2018-09-05 16:56:04 +02:00
|
|
|
local a, b = data.rendered:find("<[Hh]1[^>]*>")
|
|
|
|
if a then
|
|
|
|
local c, d = data.rendered:find("</[Hh]1>")
|
|
|
|
if c then
|
|
|
|
self.template:set("title", data.rendered:sub(b + 1, c - 1))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- get similarity post
|
|
|
|
local st_records = self.analytical:similarof(data.id)
|
|
|
|
local similar_posts = {}
|
|
|
|
for k, v in pairs(st_records) do
|
|
|
|
similar_posts[k] = {st = v, post = self.blog:get(v.sid)}
|
|
|
|
end
|
|
|
|
self.template:set("post", data)
|
|
|
|
self.template:set("similar_posts", similar_posts)
|
|
|
|
self.template:set("render", true)
|
|
|
|
self.template:set("tags", data.tags)
|
|
|
|
self.template:set("url", HTTP_ROOT .. "/post/id/" .. pid)
|
|
|
|
self.template:setView("detail")
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:notfound(...)
|
|
|
|
local args = {...}
|
|
|
|
self.template:set("title", "404 not found")
|
|
|
|
self.template:set("error", args[1])
|
|
|
|
self.template:setView("notfound")
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:actionnotfound(...)
|
|
|
|
local args = {...}
|
|
|
|
return self:notfound("Action [" .. args[1] .. "] not found")
|
|
|
|
end
|
|
|
|
|
|
|
|
function PostController:analyse(n)
|
|
|
|
if not n then
|
|
|
|
n = 5
|
|
|
|
end
|
|
|
|
local path = "/home/mrsang/aiws/blog-clustering"
|
|
|
|
local gettext = loadfile(path .. "/gettext.lua")()
|
|
|
|
local cluster = loadfile(path .. "/cluster.lua")()
|
|
|
|
local data = gettext.get({publish = 1})
|
|
|
|
local documents = {}
|
|
|
|
if data then
|
|
|
|
local sw = gettext.stopwords(path .. "/stopwords.txt")
|
|
|
|
for k, v in pairs(data) do
|
|
|
|
local bag = cluster.bow(data[k].content, sw)
|
|
|
|
documents[data[k].id] = bag
|
|
|
|
end
|
|
|
|
cluster.tfidf(documents)
|
|
|
|
--local v = cluster.search("arm", documents)
|
|
|
|
--echo(JSON.encode(v))
|
|
|
|
local vectors, maxv, size = cluster.get_vectors(documents)
|
|
|
|
-- purge the table
|
|
|
|
self.analytical:delete({["="] = {["1"] = 1}})
|
|
|
|
-- get similarity and put to the table
|
|
|
|
for id, v in pairs(vectors) do
|
|
|
|
local top = cluster.top_similarity(id, vectors, n)
|
|
|
|
for a, b in pairs(top) do
|
|
|
|
local record = {pid = id, sid = a, score = b}
|
|
|
|
self.analytical:create(record)
|
|
|
|
end
|
|
|
|
end
|
2018-09-11 10:54:33 +02:00
|
|
|
self.template:set("message", "Analyse complete")
|
2018-09-05 16:56:04 +02:00
|
|
|
else
|
2018-09-11 10:54:33 +02:00
|
|
|
self.template:set("message", "Cannot analyse")
|
2018-09-05 16:56:04 +02:00
|
|
|
end
|
2018-09-11 10:54:33 +02:00
|
|
|
self.template:set("title", "TFIDF-analyse")
|
2018-09-05 16:56:04 +02:00
|
|
|
return true
|
|
|
|
end
|