| 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@1045
 | 
     3 local initiative_id = param.get("initiative_id", atom.number)
 | 
| 
bsw@2
 | 
     4 
 | 
| 
bsw@1045
 | 
     5 if not old_draft_id 
 | 
| 
bsw@1045
 | 
     6   or not new_draft_id 
 | 
| 
bsw@1045
 | 
     7   or old_draft_id == new_draft_id
 | 
| 
bsw@1045
 | 
     8 then
 | 
| 
bsw@1045
 | 
     9   slot.reset_all()
 | 
| 
bsw@1045
 | 
    10   slot.select("error", function()
 | 
| 
bsw@1045
 | 
    11     ui.tag{ content = _"Please choose two different versions of the draft to compare" }
 | 
| 
bsw@1045
 | 
    12   end )
 | 
| 
bsw@1045
 | 
    13   request.redirect{
 | 
| 
bsw@1489
 | 
    14     module = "initiative", view = "history", id = initiative_id
 | 
| 
bsw@1045
 | 
    15   }
 | 
| 
bsw@10
 | 
    16   return
 | 
| 
bsw@10
 | 
    17 end
 | 
| 
bsw@10
 | 
    18 
 | 
| 
bsw@2
 | 
    19 if old_draft_id > new_draft_id then
 | 
| 
jbe@1226
 | 
    20   old_draft_id, new_draft_id = new_draft_id, old_draft_id
 | 
| 
bsw@2
 | 
    21 end
 | 
| 
bsw@2
 | 
    22 
 | 
| 
bsw@2
 | 
    23 local old_draft = Draft:by_id(old_draft_id)
 | 
| 
bsw@2
 | 
    24 local new_draft = Draft:by_id(new_draft_id)
 | 
| 
bsw@2
 | 
    25 
 | 
| 
bsw@1045
 | 
    26 local initiative = new_draft.initiative
 | 
| 
bsw@1045
 | 
    27 
 | 
| 
bsw@1045
 | 
    28 if app.session.member then
 | 
| 
bsw@1045
 | 
    29   initiative:load_everything_for_member_id(app.session.member_id)
 | 
| 
bsw@1045
 | 
    30   initiative.issue:load_everything_for_member_id(app.session.member_id)
 | 
| 
bsw@1045
 | 
    31 end
 | 
| 
bsw@1045
 | 
    32 
 | 
| 
bsw@1045
 | 
    33 
 | 
| 
bsw/jbe@1309
 | 
    34 local old_draft_content = string.gsub(string.gsub(util.html_to_text(old_draft.content), "\n", " ###ENTER###\n"), " ", "\n")
 | 
| 
bsw/jbe@1309
 | 
    35 local new_draft_content = string.gsub(string.gsub(util.html_to_text(new_draft.content), "\n", " ###ENTER###\n"), " ", "\n")
 | 
| 
bsw@95
 | 
    36 
 | 
| 
jbe@1226
 | 
    37 local key = multirand.string(24, "0123456789abcdefghijklmnopqrstuvwxyz")
 | 
| 
bsw@2
 | 
    38 
 | 
| 
bsw@1230
 | 
    39 local old_draft_filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "diff-" .. key .. "-old.tmp")
 | 
| 
bsw@1230
 | 
    40 local new_draft_filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "diff-" .. key .. "-new.tmp")
 | 
| 
bsw@2
 | 
    41 
 | 
| 
bsw@2
 | 
    42 local old_draft_file = assert(io.open(old_draft_filename, "w"))
 | 
| 
bsw@95
 | 
    43 old_draft_file:write(old_draft_content)
 | 
| 
bsw@2
 | 
    44 old_draft_file:write("\n")
 | 
| 
bsw@2
 | 
    45 old_draft_file:close()
 | 
| 
bsw@2
 | 
    46 
 | 
| 
bsw@2
 | 
    47 local new_draft_file = assert(io.open(new_draft_filename, "w"))
 | 
| 
bsw@95
 | 
    48 new_draft_file:write(new_draft_content)
 | 
| 
bsw@2
 | 
    49 new_draft_file:write("\n")
 | 
| 
bsw@2
 | 
    50 new_draft_file:close()
 | 
| 
bsw@2
 | 
    51 
 | 
| 
bsw/jbe@1309
 | 
    52 local output, err, status = extos.pfilter(nil, "sh", "-c", "diff -a -U 1000000000 '" .. old_draft_filename .. "' '" .. new_draft_filename .. "' | grep --binary-files=text -v ^--- | grep --binary-files=text -v ^+++ | grep --binary-files=text -v ^@")
 | 
| 
bsw@2
 | 
    53 
 | 
| 
bsw@2
 | 
    54 os.remove(old_draft_filename)
 | 
| 
bsw@2
 | 
    55 os.remove(new_draft_filename)
 | 
| 
bsw@2
 | 
    56 
 | 
| 
bsw@95
 | 
    57 local last_state = "first_run"
 | 
| 
bsw@95
 | 
    58 
 | 
| 
bsw@95
 | 
    59 local function process_line(line)
 | 
| 
bsw@95
 | 
    60   local state_char = string.sub(line, 1, 1)
 | 
| 
bsw@95
 | 
    61   local state
 | 
| 
bsw@95
 | 
    62   if state_char == "+" then
 | 
| 
bsw@95
 | 
    63     state = "added"
 | 
| 
bsw@95
 | 
    64   elseif state_char == "-" then
 | 
| 
bsw@95
 | 
    65     state = "removed"
 | 
| 
bsw@95
 | 
    66   elseif state_char == " " then
 | 
| 
bsw@95
 | 
    67     state = "unchanged"
 | 
| 
bsw@95
 | 
    68   end
 | 
| 
bsw@95
 | 
    69   local state_changed = false
 | 
| 
bsw@95
 | 
    70   if state ~= last_state then
 | 
| 
bsw@95
 | 
    71     if last_state ~= "first_run" then
 | 
| 
bsw@95
 | 
    72       slot.put("</span> ")
 | 
| 
bsw@95
 | 
    73     end
 | 
| 
bsw@95
 | 
    74     last_state = state
 | 
| 
bsw@95
 | 
    75     state_changed = true
 | 
| 
bsw@95
 | 
    76     slot.put("<span class=\"diff_" .. tostring(state) .. "\">")
 | 
| 
bsw@95
 | 
    77   end
 | 
| 
bsw@95
 | 
    78 
 | 
| 
bsw@95
 | 
    79   line = string.sub(line, 2, #line)
 | 
| 
bsw@95
 | 
    80   if line ~= "###ENTER###" then
 | 
| 
bsw@95
 | 
    81     if not state_changed then
 | 
| 
bsw@95
 | 
    82       slot.put(" ")
 | 
| 
bsw@95
 | 
    83     end
 | 
| 
bsw/jbe@1309
 | 
    84     --slot.put(encode.html(line))
 | 
| 
bsw/jbe@1309
 | 
    85     slot.put(line)
 | 
| 
bsw@95
 | 
    86   else
 | 
| 
bsw@95
 | 
    87     slot.put("<br />")
 | 
| 
bsw@95
 | 
    88   end
 | 
| 
bsw@95
 | 
    89 end
 | 
| 
bsw@95
 | 
    90 
 | 
| 
bsw/jbe@1309
 | 
    91 execute.view{ module = "issue", view = "_head", params = { issue = initiative.issue } }
 | 
| 
bsw/jbe@1309
 | 
    92 
 | 
| 
bsw/jbe@1309
 | 
    93 ui.grid{ content = function()
 | 
| 
bsw/jbe@1309
 | 
    94   ui.cell_main{ content = function()
 | 
| 
bsw/jbe@1309
 | 
    95     ui.container{ attr = { class = "mdl-card mdl-card__fullwidth mdl-shadow--2dp" }, content = function()
 | 
| 
bsw/jbe@1309
 | 
    96 
 | 
| 
bsw/jbe@1309
 | 
    97       ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function ()
 | 
| 
bsw@1045
 | 
    98         ui.heading { 
 | 
| 
bsw/jbe@1309
 | 
    99           attr = { class = "mdl-card__title-text" },
 | 
| 
bsw/jbe@1309
 | 
   100           content = function()
 | 
| 
bsw/jbe@1309
 | 
   101             ui.link{
 | 
| 
bsw/jbe@1309
 | 
   102               module = "initiative", view = "show", id = initiative.id,
 | 
| 
bsw/jbe@1309
 | 
   103               content = initiative.display_name
 | 
| 
bsw/jbe@1309
 | 
   104             }
 | 
| 
bsw/jbe@1309
 | 
   105           end
 | 
| 
bsw@1045
 | 
   106         }
 | 
| 
bsw/jbe@1309
 | 
   107         ui.container{ content = _("Comparision of revisions #{id1} and #{id2}", {
 | 
| 
bsw/jbe@1309
 | 
   108           id1 = old_draft.id,
 | 
| 
bsw/jbe@1309
 | 
   109           id2 = new_draft.id 
 | 
| 
bsw/jbe@1309
 | 
   110         } ) }
 | 
| 
bsw/jbe@1309
 | 
   111       end }
 | 
| 
bsw/jbe@1309
 | 
   112 
 | 
| 
bsw/jbe@1309
 | 
   113       if app.session.member_id and not new_draft.initiative.revoked then
 | 
| 
bsw/jbe@1309
 | 
   114         local supporter = app.session.member:get_reference_selector("supporters")
 | 
| 
bsw/jbe@1309
 | 
   115           :add_where{ "initiative_id = ?", new_draft.initiative_id }
 | 
| 
bsw/jbe@1309
 | 
   116           :optional_object_mode()
 | 
| 
bsw/jbe@1309
 | 
   117           :exec()
 | 
| 
bsw/jbe@1309
 | 
   118         if supporter and supporter.draft_id == old_draft.id and new_draft.id == initiative.current_draft.id then
 | 
| 
bsw/jbe@1309
 | 
   119           ui.container {
 | 
| 
bsw/jbe@1309
 | 
   120             attr = { class = "mdl-card__content mdl-card--no-bottom-pad mdl-card--notice" },
 | 
| 
bsw/jbe@1309
 | 
   121             content = _"The draft of this initiative has been updated!"
 | 
| 
bsw@1045
 | 
   122           }
 | 
| 
bsw/jbe@1309
 | 
   123           ui.container {
 | 
| 
bsw/jbe@1309
 | 
   124             attr = { class = "mdl-card__actions mdl-card--action-border  mdl-card--notice" },
 | 
| 
bsw/jbe@1309
 | 
   125             content = function ()
 | 
| 
bsw/jbe@1309
 | 
   126               ui.link{
 | 
| 
bsw/jbe@1309
 | 
   127                 attr = { class = "mdl-button mdl-js-button mdl-button--raised" },
 | 
| 
bsw/jbe@1309
 | 
   128                 text   = _"refresh my support",
 | 
| 
bsw/jbe@1309
 | 
   129                 module = "initiative",
 | 
| 
bsw/jbe@1309
 | 
   130                 action = "add_support",
 | 
| 
bsw/jbe@1309
 | 
   131                 id     = new_draft.initiative.id,
 | 
| 
bsw/jbe@1309
 | 
   132                 params = { draft_id = new_draft.id },
 | 
| 
bsw/jbe@1309
 | 
   133                 routing = {
 | 
| 
bsw/jbe@1309
 | 
   134                   default = {
 | 
| 
bsw/jbe@1309
 | 
   135                     mode = "redirect",
 | 
| 
bsw/jbe@1309
 | 
   136                     module = "initiative",
 | 
| 
bsw/jbe@1309
 | 
   137                     view = "show",
 | 
| 
bsw/jbe@1309
 | 
   138                     id = new_draft.initiative.id
 | 
| 
bsw/jbe@1309
 | 
   139                   }
 | 
| 
bsw/jbe@1309
 | 
   140                 }
 | 
| 
bsw/jbe@1309
 | 
   141               }
 | 
| 
bsw@1045
 | 
   142 
 | 
| 
bsw/jbe@1309
 | 
   143               slot.put("   ")
 | 
| 
bsw/jbe@1309
 | 
   144               
 | 
| 
bsw/jbe@1309
 | 
   145               ui.link{
 | 
| 
bsw/jbe@1309
 | 
   146                 attr = { class = "mdl-button mdl-js-button mdl-button--raised" },
 | 
| 
bsw/jbe@1309
 | 
   147                 text   = _"remove my support",
 | 
| 
bsw/jbe@1309
 | 
   148                 module = "initiative",
 | 
| 
bsw/jbe@1309
 | 
   149                 action = "remove_support",
 | 
| 
bsw/jbe@1309
 | 
   150                 id     = new_draft.initiative.id,
 | 
| 
bsw/jbe@1309
 | 
   151                 routing = {
 | 
| 
bsw/jbe@1309
 | 
   152                   default = {
 | 
| 
bsw/jbe@1309
 | 
   153                     mode = "redirect",
 | 
| 
bsw/jbe@1309
 | 
   154                     module = "initiative",
 | 
| 
bsw/jbe@1309
 | 
   155                     view = "show",
 | 
| 
bsw/jbe@1309
 | 
   156                     id = new_draft.initiative.id
 | 
| 
bsw/jbe@1309
 | 
   157                   }
 | 
| 
bsw/jbe@1309
 | 
   158                 }
 | 
| 
bsw/jbe@1309
 | 
   159               }        
 | 
| 
bsw/jbe@1309
 | 
   160 
 | 
| 
bsw/jbe@1309
 | 
   161               slot.put("   ")
 | 
| 
bsw/jbe@1309
 | 
   162               
 | 
| 
bsw/jbe@1309
 | 
   163               ui.link{
 | 
| 
bsw/jbe@1309
 | 
   164                 attr = { class = "mdl-button mdl-js-button" },
 | 
| 
bsw/jbe@1309
 | 
   165                 text   = _"cancel",
 | 
| 
bsw/jbe@1309
 | 
   166                 module = "initiative",
 | 
| 
bsw/jbe@1309
 | 
   167                 view   = "show",
 | 
| 
bsw/jbe@1309
 | 
   168                 id     = new_draft.initiative.id,
 | 
| 
bsw/jbe@1309
 | 
   169               }        
 | 
| 
bsw/jbe@1309
 | 
   170             end
 | 
| 
bsw@1045
 | 
   171           }
 | 
| 
bsw/jbe@1309
 | 
   172         end
 | 
| 
bsw/jbe@1309
 | 
   173       end
 | 
| 
bsw@2
 | 
   174 
 | 
| 
bsw/jbe@1309
 | 
   175       ui.container {
 | 
| 
bsw/jbe@1309
 | 
   176         attr = { class = "draft mdl-card__content mdl-card--border" },
 | 
| 
bsw/jbe@1309
 | 
   177         content = function ()
 | 
| 
bsw/jbe@1309
 | 
   178           if not status then
 | 
| 
bsw/jbe@1309
 | 
   179             ui.field.text{ value = _"The drafts do not differ" }
 | 
| 
bsw/jbe@1309
 | 
   180           else
 | 
| 
bsw/jbe@1309
 | 
   181             ui.container{
 | 
| 
bsw/jbe@1309
 | 
   182               tag = "div",
 | 
| 
bsw/jbe@1309
 | 
   183               attr = { class = "diff" },
 | 
| 
bsw/jbe@1309
 | 
   184               content = function()
 | 
| 
bsw/jbe@1309
 | 
   185                 output = output:gsub("[^\n\r]+", function(line)
 | 
| 
bsw/jbe@1309
 | 
   186                   process_line(line)
 | 
| 
bsw/jbe@1309
 | 
   187                 end)
 | 
| 
bsw/jbe@1309
 | 
   188               end
 | 
| 
bsw/jbe@1309
 | 
   189             }
 | 
| 
bsw/jbe@1309
 | 
   190           end 
 | 
| 
bsw@1045
 | 
   191         end
 | 
| 
bsw@1045
 | 
   192       }
 | 
| 
bsw@1496
 | 
   193 
 | 
| 
bsw@1496
 | 
   194       local old_files = File:new_selector()
 | 
| 
bsw@1496
 | 
   195         :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id")
 | 
| 
bsw@1496
 | 
   196         :add_where{ "draft_attachment.draft_id = ?", old_draft.id }
 | 
| 
bsw@1496
 | 
   197         :reset_fields()
 | 
| 
bsw@1496
 | 
   198         :add_field("file.id")
 | 
| 
bsw@1496
 | 
   199         :add_field("draft_attachment.title")
 | 
| 
bsw@1496
 | 
   200         :add_field("draft_attachment.description")
 | 
| 
bsw@1496
 | 
   201         :add_order_by("draft_attachment.id")
 | 
| 
bsw@1496
 | 
   202         :exec()
 | 
| 
bsw@1496
 | 
   203 
 | 
| 
bsw@1496
 | 
   204       local new_files = File:new_selector()
 | 
| 
bsw@1496
 | 
   205         :left_join("draft_attachment", nil, "draft_attachment.file_id = file.id")
 | 
| 
bsw@1496
 | 
   206         :add_where{ "draft_attachment.draft_id = ?", new_draft.id }
 | 
| 
bsw@1496
 | 
   207         :reset_fields()
 | 
| 
bsw@1496
 | 
   208         :add_field("file.id")
 | 
| 
bsw@1496
 | 
   209         :add_field("draft_attachment.title")
 | 
| 
bsw@1496
 | 
   210         :add_field("draft_attachment.description")
 | 
| 
bsw@1496
 | 
   211         :add_order_by("draft_attachment.id")
 | 
| 
bsw@1496
 | 
   212         :exec()
 | 
| 
bsw@1496
 | 
   213 
 | 
| 
bsw@1496
 | 
   214       local added_files = {}
 | 
| 
bsw@1496
 | 
   215       for i, new_file in ipairs(new_files) do
 | 
| 
bsw@1496
 | 
   216         local added = true
 | 
| 
bsw@1496
 | 
   217         for j, old_file in ipairs(old_files) do
 | 
| 
bsw@1496
 | 
   218           if 
 | 
| 
bsw@1496
 | 
   219             old_file.file_id == new_file.file_id 
 | 
| 
bsw@1496
 | 
   220             and old_file.title == new_file.title
 | 
| 
bsw@1496
 | 
   221             and old_file.description == new_file.description
 | 
| 
bsw@1496
 | 
   222           then
 | 
| 
bsw@1496
 | 
   223             added = false
 | 
| 
bsw@1496
 | 
   224           end
 | 
| 
bsw@1496
 | 
   225         end
 | 
| 
bsw@1496
 | 
   226         if added then
 | 
| 
bsw@1496
 | 
   227           table.insert(added_files, new_file)
 | 
| 
bsw@1496
 | 
   228         end
 | 
| 
bsw@1496
 | 
   229       end
 | 
| 
bsw@1496
 | 
   230 
 | 
| 
bsw@1496
 | 
   231       if #added_files > 0 then
 | 
| 
bsw@1496
 | 
   232         ui.container {
 | 
| 
bsw@1496
 | 
   233           attr = { class = "mdl-card__content mdl-card--border" },
 | 
| 
bsw@1496
 | 
   234           content = function()
 | 
| 
bsw@1496
 | 
   235             ui.container{ content = _"Added attachments" }
 | 
| 
bsw@1496
 | 
   236             for i, file in ipairs(added_files) do
 | 
| 
bsw@1496
 | 
   237               ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } }
 | 
| 
bsw@1496
 | 
   238               ui.container{ content = file.title or "" }
 | 
| 
bsw@1496
 | 
   239               ui.container{ content = file.description or "" }
 | 
| 
bsw@1496
 | 
   240               slot.put("<br /><br />")
 | 
| 
bsw@1496
 | 
   241             end
 | 
| 
bsw@1496
 | 
   242           end
 | 
| 
bsw@1496
 | 
   243         }
 | 
| 
bsw@1496
 | 
   244       end
 | 
| 
bsw@1496
 | 
   245 
 | 
| 
bsw@1496
 | 
   246       local removed_files = {}      
 | 
| 
bsw@1496
 | 
   247       for i, old_file in ipairs(old_files) do
 | 
| 
bsw@1496
 | 
   248         local removed = true
 | 
| 
bsw@1496
 | 
   249         for j, new_file in ipairs(new_files) do
 | 
| 
bsw@1496
 | 
   250           if 
 | 
| 
bsw@1496
 | 
   251             old_file.file_id == new_file.file_id 
 | 
| 
bsw@1496
 | 
   252             and old_file.title == new_file.title
 | 
| 
bsw@1496
 | 
   253             and old_file.description == new_file.description
 | 
| 
bsw@1496
 | 
   254           then
 | 
| 
bsw@1496
 | 
   255             removed = false
 | 
| 
bsw@1496
 | 
   256           end
 | 
| 
bsw@1496
 | 
   257         end
 | 
| 
bsw@1496
 | 
   258         if removed then
 | 
| 
bsw@1496
 | 
   259           table.insert(removed_files, old_file)
 | 
| 
bsw@1496
 | 
   260         end
 | 
| 
bsw@1496
 | 
   261       end
 | 
| 
bsw@1496
 | 
   262 
 | 
| 
bsw@1496
 | 
   263 
 | 
| 
bsw@1496
 | 
   264       if #removed_files > 0 then
 | 
| 
bsw@1496
 | 
   265         ui.container {
 | 
| 
bsw@1496
 | 
   266           attr = { class = "mdl-card__content mdl-card--border" },
 | 
| 
bsw@1496
 | 
   267           content = function()
 | 
| 
bsw@1496
 | 
   268             ui.container{ content = _"Removed attachments" }
 | 
| 
bsw@1496
 | 
   269             for i, file in ipairs(removed_files) do
 | 
| 
bsw@1496
 | 
   270               ui.image{ module = "file", view = "show.jpg", id = file.id, params = { preview = true } }
 | 
| 
bsw@1496
 | 
   271               ui.container{ content = file.title or "" }
 | 
| 
bsw@1496
 | 
   272               ui.container{ content = file.description or "" }
 | 
| 
bsw@1496
 | 
   273               slot.put("<br /><br />")
 | 
| 
bsw@1496
 | 
   274             end
 | 
| 
bsw@1496
 | 
   275           end
 | 
| 
bsw@1496
 | 
   276         }
 | 
| 
bsw@1496
 | 
   277       end
 | 
| 
bsw@1496
 | 
   278 
 | 
| 
bsw@1496
 | 
   279       ui.container {
 | 
| 
bsw@1496
 | 
   280         attr = { class = "draft mdl-card__content mdl-card--border" },
 | 
| 
bsw@1496
 | 
   281         content = function ()
 | 
| 
bsw@1496
 | 
   282         end
 | 
| 
bsw@1496
 | 
   283       }
 | 
| 
bsw@1496
 | 
   284 
 | 
| 
bsw/jbe@1309
 | 
   285     end }
 | 
| 
bsw/jbe@1309
 | 
   286   end }
 | 
| 
bsw/jbe@1309
 | 
   287   ui.cell_sidebar{ content = function()
 | 
| 
bsw/jbe@1309
 | 
   288 
 | 
| 
bsw/jbe@1309
 | 
   289     execute.view{ module = "issue", view = "_sidebar", params = {
 | 
| 
bsw/jbe@1309
 | 
   290       initiative = initiative,
 | 
| 
bsw/jbe@1309
 | 
   291       issue = initiative.issue
 | 
| 
bsw/jbe@1309
 | 
   292     } }
 | 
| 
bsw@1045
 | 
   293 
 | 
| 
bsw/jbe@1309
 | 
   294     execute.view {
 | 
| 
bsw/jbe@1309
 | 
   295       module = "issue", view = "_sidebar_whatcanido",
 | 
| 
bsw/jbe@1309
 | 
   296       params = { initiative = initiative }
 | 
| 
bsw/jbe@1309
 | 
   297     }
 | 
| 
bsw/jbe@1309
 | 
   298 
 | 
| 
bsw/jbe@1309
 | 
   299     execute.view { 
 | 
| 
bsw/jbe@1309
 | 
   300       module = "issue", view = "_sidebar_members", params = {
 | 
| 
bsw/jbe@1309
 | 
   301         issue = initiative.issue, initiative = initiative
 | 
| 
bsw/jbe@1309
 | 
   302       }
 | 
| 
bsw/jbe@1309
 | 
   303     }
 | 
| 
bsw/jbe@1309
 | 
   304   end }
 | 
| 
bsw/jbe@1309
 | 
   305 end }
 |