require "upath" require "proto" local lua_action = Object:clone() -- set type=lua_action metadata for path function lua_action:register(path) dump("acl_check",path, "lua_action") assert(self.session:acl_check(path, "lua_action"), "EACCESS:May not use lua_action on path") self.session:meta_reset(path, "type", "type", "lua_action") end function lua_action:unregister(path) self.session:meta_delete(path, "type", "type", "lua_action") end -- validate file -- return false or nil will just ignore this type function lua_action:check(path) return true end -- remove all dependency relations which where previously recorded for path function lua_action:abolish(path) end function lua_action:discover(path) -- require ? end -- compile path to destpath function lua_action:compile(path, destpath) end -- figures out what kind of changes are from old to new (maybe with the help of scm) -- intended types (the exact interpretation is open to the type): -- "none" did not changed anything -- "edit" mixed edit -- "prepend" user prepended only -- "append" user appended only -- "add" only content added but nothing removed -- "comment" commented only -- "commentadd" added comment only -- "spam" detected spam -- currentfile the current file -- newfile the new file -- return a string describing the kind (required sub-permission), returning nil will not yield in a acl check and permit anything function lua_action:diffkind(currentfile, newfile) local diff = io.popen("diff -d -C1 %old% %new%" % { old = currentfile:sanitize('shquote'), new = newfile:sanitize('shquote')}) local changestat = { comment = {added = 0, changed = 0}, content = {added = 0, changed = 0}, prepend = 'unknown', append = 'unknown', changes = 0 } for line in diff:lines() do local mode,content = line:match('^(.) (.*)') if mode then -- this pattern is slightly broken as it will detect empty comment lines (//) as content local kind = (content:find('^%s*--')) and "comment" or "content" if mode == '+' then -- TODO rxpd spamcheck here, per kind? changestat[kind].added = changestat[kind].added + 1 changestat.changes = changestat.changes + 1 if changestat.prepend == 'unknown' then changestat.prepend = 'maybe' end if changestat.append == 'unknown' then changestat.append = 'maybe' end elseif mode == '!' then -- TODO rxpd spamcheck here, per kind? changestat[kind].changed = changestat[kind].changed + 1 changestat.changes = changestat.changes + 1 changestat.prepend = false changestat.append = false elseif mode == '-' then changestat[kind].changed = changestat[kind].changed + 1 changestat.changes = changestat.changes + 1 changestat.prepend = false changestat.append = false elseif mode == ' ' then if changestat.prepend == 'unknown' then changestat.prepend = false end if changestat.append == 'maybe' then changestat.append = false end end end end diff:close() -- now analyze the stats local result if changestat.changes == 0 then -- nothing changed result = 'none' else if changestat.content.added == 0 and changestat.content.changed == 0 then if changestat.comment.changed == 0 then -- only comments added result = 'commentadd' else -- edit in comment result = 'comment' end else if changestat.append == 'maybe' then -- only added new content at the end result = 'append' elseif changestat.prepend == 'maybe' then -- only added new content at the begin result = 'prepend' elseif changestat.content.changed == 0 then -- only new content added result = 'add' else -- generic edit result = 'edit' end end end return result end return lua_action -- Local Variables: -- mode: lua -- lua-indent-level: 4 -- indent-tabs-mode: nil -- End: