| rev | 
   line source | 
| 
bsw@2
 | 
     1 local old_draft_id = param.get("old_draft_id", atom.integer)
 | 
| 
bsw@2
 | 
     2 local new_draft_id = param.get("new_draft_id", atom.integer)
 | 
| 
bsw@2
 | 
     3 
 | 
| 
bsw@10
 | 
     4 if not old_draft_id or not new_draft_id then
 | 
| 
bsw@10
 | 
     5   slot.put( _"Please choose two versions of the draft to compare")
 | 
| 
bsw@10
 | 
     6   return
 | 
| 
bsw@10
 | 
     7 end
 | 
| 
bsw@10
 | 
     8 
 | 
| 
bsw@10
 | 
     9 if old_draft_id == new_draft_id then
 | 
| 
bsw@10
 | 
    10   slot.put( _"Please choose two different versions of the draft to compare")
 | 
| 
bsw@10
 | 
    11   return
 | 
| 
bsw@10
 | 
    12 end
 | 
| 
bsw@10
 | 
    13 
 | 
| 
bsw@2
 | 
    14 if old_draft_id > new_draft_id then
 | 
| 
bsw@2
 | 
    15   local tmp = old_draft_id
 | 
| 
bsw@2
 | 
    16   old_draft_id = new_draft_id
 | 
| 
bsw@2
 | 
    17   new_draft_id = tmp
 | 
| 
bsw@2
 | 
    18 end
 | 
| 
bsw@2
 | 
    19 
 | 
| 
bsw@2
 | 
    20 local old_draft = Draft:by_id(old_draft_id)
 | 
| 
bsw@2
 | 
    21 local new_draft = Draft:by_id(new_draft_id)
 | 
| 
bsw@2
 | 
    22 
 | 
| 
poelzi@160
 | 
    23 execute.view{
 | 
| 
poelzi@160
 | 
    24   module = "draft",
 | 
| 
poelzi@160
 | 
    25   view = "_head",
 | 
| 
poelzi@160
 | 
    26   params = { draft = new_draft}
 | 
| 
poelzi@160
 | 
    27 }
 | 
| 
poelzi@159
 | 
    28 
 | 
| 
poelzi@160
 | 
    29 slot.put_into("title", " · " .. _"Diff")
 | 
| 
poelzi@159
 | 
    30 
 | 
| 
poelzi@159
 | 
    31 if app.session.member_id and not new_draft.initiative.revoked then
 | 
| 
poelzi@159
 | 
    32   local supporter = Supporter:new_selector():add_where{"member_id = ?", app.session.member_id}:count()
 | 
| 
poelzi@159
 | 
    33   if supporter then
 | 
| 
poelzi@159
 | 
    34     ui.container{
 | 
| 
poelzi@159
 | 
    35       attr = { class = "draft_updated_info" },
 | 
| 
poelzi@159
 | 
    36       content = function()
 | 
| 
poelzi@159
 | 
    37         slot.put(_"The draft of this initiative has been updated!")
 | 
| 
poelzi@159
 | 
    38         slot.put(" ")
 | 
| 
poelzi@159
 | 
    39         ui.link{
 | 
| 
poelzi@159
 | 
    40           text   = _"Refresh support to current draft",
 | 
| 
poelzi@159
 | 
    41           module = "initiative",
 | 
| 
poelzi@159
 | 
    42           action = "add_support",
 | 
| 
poelzi@159
 | 
    43           id     = new_draft.initiative.id,
 | 
| 
poelzi@159
 | 
    44           routing = {
 | 
| 
poelzi@159
 | 
    45             default = {
 | 
| 
poelzi@159
 | 
    46               mode = "redirect",
 | 
| 
poelzi@159
 | 
    47               module = "initiative",
 | 
| 
poelzi@159
 | 
    48               view = "show",
 | 
| 
poelzi@159
 | 
    49               id = new_draft.initiative.id
 | 
| 
poelzi@159
 | 
    50             }
 | 
| 
poelzi@159
 | 
    51           }
 | 
| 
poelzi@159
 | 
    52         }
 | 
| 
poelzi@159
 | 
    53       end
 | 
| 
poelzi@159
 | 
    54     }
 | 
| 
poelzi@159
 | 
    55   end
 | 
| 
poelzi@159
 | 
    56 end
 | 
| 
poelzi@159
 | 
    57 
 | 
| 
bsw@95
 | 
    58 local old_draft_content = string.gsub(string.gsub(old_draft.content, "\n", " ###ENTER###\n"), " ", "\n")
 | 
| 
bsw@95
 | 
    59 local new_draft_content = string.gsub(string.gsub(new_draft.content, "\n", " ###ENTER###\n"), " ", "\n")
 | 
| 
bsw@95
 | 
    60 
 | 
| 
bsw@2
 | 
    61 local key = multirand.string(26, "123456789bcdfghjklmnpqrstvwxyz");
 | 
| 
bsw@2
 | 
    62 
 | 
| 
bsw@2
 | 
    63 local old_draft_filename = encode.file_path(request.get_app_basepath(), 'tmp', "diff-" .. key .. "-old.tmp")
 | 
| 
bsw@2
 | 
    64 local new_draft_filename = encode.file_path(request.get_app_basepath(), 'tmp', "diff-" .. key .. "-new.tmp")
 | 
| 
bsw@2
 | 
    65 
 | 
| 
bsw@2
 | 
    66 local old_draft_file = assert(io.open(old_draft_filename, "w"))
 | 
| 
bsw@95
 | 
    67 old_draft_file:write(old_draft_content)
 | 
| 
bsw@2
 | 
    68 old_draft_file:write("\n")
 | 
| 
bsw@2
 | 
    69 old_draft_file:close()
 | 
| 
bsw@2
 | 
    70 
 | 
| 
bsw@2
 | 
    71 local new_draft_file = assert(io.open(new_draft_filename, "w"))
 | 
| 
bsw@95
 | 
    72 new_draft_file:write(new_draft_content)
 | 
| 
bsw@2
 | 
    73 new_draft_file:write("\n")
 | 
| 
bsw@2
 | 
    74 new_draft_file:close()
 | 
| 
bsw@2
 | 
    75 
 | 
| 
bsw@95
 | 
    76 local output, err, status = os.pfilter(nil, "sh", "-c", "diff -U 1000000000 '" .. old_draft_filename .. "' '" .. new_draft_filename .. "' | grep -v ^--- | grep -v ^+++ | grep -v ^@")
 | 
| 
bsw@2
 | 
    77 
 | 
| 
bsw@2
 | 
    78 os.remove(old_draft_filename)
 | 
| 
bsw@2
 | 
    79 os.remove(new_draft_filename)
 | 
| 
bsw@2
 | 
    80 
 | 
| 
bsw@95
 | 
    81 local last_state = "first_run"
 | 
| 
bsw@95
 | 
    82 
 | 
| 
bsw@95
 | 
    83 local function process_line(line)
 | 
| 
bsw@95
 | 
    84   local state_char = string.sub(line, 1, 1)
 | 
| 
bsw@95
 | 
    85   local state
 | 
| 
bsw@95
 | 
    86   if state_char == "+" then
 | 
| 
bsw@95
 | 
    87     state = "added"
 | 
| 
bsw@95
 | 
    88   elseif state_char == "-" then
 | 
| 
bsw@95
 | 
    89     state = "removed"
 | 
| 
bsw@95
 | 
    90   elseif state_char == " " then
 | 
| 
bsw@95
 | 
    91     state = "unchanged"
 | 
| 
bsw@95
 | 
    92   end
 | 
| 
bsw@95
 | 
    93   local state_changed = false
 | 
| 
bsw@95
 | 
    94   if state ~= last_state then
 | 
| 
bsw@95
 | 
    95     if last_state ~= "first_run" then
 | 
| 
bsw@95
 | 
    96       slot.put("</span> ")
 | 
| 
bsw@95
 | 
    97     end
 | 
| 
bsw@95
 | 
    98     last_state = state
 | 
| 
bsw@95
 | 
    99     state_changed = true
 | 
| 
bsw@95
 | 
   100     slot.put("<span class=\"diff_" .. tostring(state) .. "\">")
 | 
| 
bsw@95
 | 
   101   end
 | 
| 
bsw@95
 | 
   102 
 | 
| 
bsw@95
 | 
   103   line = string.sub(line, 2, #line)
 | 
| 
bsw@95
 | 
   104   if line ~= "###ENTER###" then
 | 
| 
bsw@95
 | 
   105     if not state_changed then
 | 
| 
bsw@95
 | 
   106       slot.put(" ")
 | 
| 
bsw@95
 | 
   107     end
 | 
| 
bsw@95
 | 
   108     slot.put(line)
 | 
| 
bsw@95
 | 
   109   else
 | 
| 
bsw@95
 | 
   110     slot.put("<br />")
 | 
| 
bsw@95
 | 
   111   end
 | 
| 
bsw@95
 | 
   112 end
 | 
| 
bsw@95
 | 
   113 
 | 
| 
bsw@2
 | 
   114 if not status then
 | 
| 
bsw@2
 | 
   115   ui.field.text{ value = _"The drafts do not differ" }
 | 
| 
bsw@2
 | 
   116 else
 | 
| 
bsw@95
 | 
   117   ui.container{
 | 
| 
bsw@95
 | 
   118     tag = "div",
 | 
| 
bsw@95
 | 
   119     attr = { class = "diff" },
 | 
| 
bsw@95
 | 
   120     content = function()
 | 
| 
bsw@95
 | 
   121       output = output:gsub("[^\n\r]+", function(line)
 | 
| 
bsw@95
 | 
   122         process_line(line)
 | 
| 
bsw@95
 | 
   123       end)
 | 
| 
bsw@2
 | 
   124     end
 | 
| 
bsw@95
 | 
   125   }
 | 
| 
bsw@2
 | 
   126 end 
 | 
| 
bsw@2
 | 
   127 
 |