| 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@1045 | 14     module = "draft", view = "list", params = { | 
| bsw@1045 | 15       initiative_id = initiative_id | 
| bsw@1045 | 16     } | 
| bsw@1045 | 17   } | 
| bsw@10 | 18   return | 
| bsw@10 | 19 end | 
| bsw@10 | 20 | 
| bsw@2 | 21 if old_draft_id > new_draft_id then | 
| jbe@1226 | 22   old_draft_id, new_draft_id = new_draft_id, old_draft_id | 
| bsw@2 | 23 end | 
| bsw@2 | 24 | 
| bsw@2 | 25 local old_draft = Draft:by_id(old_draft_id) | 
| bsw@2 | 26 local new_draft = Draft:by_id(new_draft_id) | 
| bsw@2 | 27 | 
| bsw@1045 | 28 local initiative = new_draft.initiative | 
| bsw@1045 | 29 | 
| bsw@1045 | 30 if app.session.member then | 
| bsw@1045 | 31   initiative:load_everything_for_member_id(app.session.member_id) | 
| bsw@1045 | 32   initiative.issue:load_everything_for_member_id(app.session.member_id) | 
| bsw@1045 | 33 end | 
| bsw@1045 | 34 | 
| bsw@1045 | 35 | 
| bsw/jbe@1309 | 36 local old_draft_content = string.gsub(string.gsub(util.html_to_text(old_draft.content), "\n", " ###ENTER###\n"), " ", "\n") | 
| bsw/jbe@1309 | 37 local new_draft_content = string.gsub(string.gsub(util.html_to_text(new_draft.content), "\n", " ###ENTER###\n"), " ", "\n") | 
| bsw@95 | 38 | 
| jbe@1226 | 39 local key = multirand.string(24, "0123456789abcdefghijklmnopqrstuvwxyz") | 
| bsw@2 | 40 | 
| bsw@1230 | 41 local old_draft_filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "diff-" .. key .. "-old.tmp") | 
| bsw@1230 | 42 local new_draft_filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "diff-" .. key .. "-new.tmp") | 
| bsw@2 | 43 | 
| bsw@2 | 44 local old_draft_file = assert(io.open(old_draft_filename, "w")) | 
| bsw@95 | 45 old_draft_file:write(old_draft_content) | 
| bsw@2 | 46 old_draft_file:write("\n") | 
| bsw@2 | 47 old_draft_file:close() | 
| bsw@2 | 48 | 
| bsw@2 | 49 local new_draft_file = assert(io.open(new_draft_filename, "w")) | 
| bsw@95 | 50 new_draft_file:write(new_draft_content) | 
| bsw@2 | 51 new_draft_file:write("\n") | 
| bsw@2 | 52 new_draft_file:close() | 
| bsw@2 | 53 | 
| bsw/jbe@1309 | 54 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 | 55 | 
| bsw@2 | 56 os.remove(old_draft_filename) | 
| bsw@2 | 57 os.remove(new_draft_filename) | 
| bsw@2 | 58 | 
| bsw@95 | 59 local last_state = "first_run" | 
| bsw@95 | 60 | 
| bsw@95 | 61 local function process_line(line) | 
| bsw@95 | 62   local state_char = string.sub(line, 1, 1) | 
| bsw@95 | 63   local state | 
| bsw@95 | 64   if state_char == "+" then | 
| bsw@95 | 65     state = "added" | 
| bsw@95 | 66   elseif state_char == "-" then | 
| bsw@95 | 67     state = "removed" | 
| bsw@95 | 68   elseif state_char == " " then | 
| bsw@95 | 69     state = "unchanged" | 
| bsw@95 | 70   end | 
| bsw@95 | 71   local state_changed = false | 
| bsw@95 | 72   if state ~= last_state then | 
| bsw@95 | 73     if last_state ~= "first_run" then | 
| bsw@95 | 74       slot.put("</span> ") | 
| bsw@95 | 75     end | 
| bsw@95 | 76     last_state = state | 
| bsw@95 | 77     state_changed = true | 
| bsw@95 | 78     slot.put("<span class=\"diff_" .. tostring(state) .. "\">") | 
| bsw@95 | 79   end | 
| bsw@95 | 80 | 
| bsw@95 | 81   line = string.sub(line, 2, #line) | 
| bsw@95 | 82   if line ~= "###ENTER###" then | 
| bsw@95 | 83     if not state_changed then | 
| bsw@95 | 84       slot.put(" ") | 
| bsw@95 | 85     end | 
| bsw/jbe@1309 | 86     --slot.put(encode.html(line)) | 
| bsw/jbe@1309 | 87     slot.put(line) | 
| bsw@95 | 88   else | 
| bsw@95 | 89     slot.put("<br />") | 
| bsw@95 | 90   end | 
| bsw@95 | 91 end | 
| bsw@95 | 92 | 
| bsw/jbe@1309 | 93 execute.view{ module = "issue", view = "_head", params = { issue = initiative.issue } } | 
| bsw/jbe@1309 | 94 | 
| bsw/jbe@1309 | 95 ui.grid{ content = function() | 
| bsw/jbe@1309 | 96   ui.cell_main{ content = function() | 
| bsw/jbe@1309 | 97     ui.container{ attr = { class = "mdl-card mdl-card__fullwidth mdl-shadow--2dp" }, content = function() | 
| bsw/jbe@1309 | 98 | 
| bsw/jbe@1309 | 99       ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function () | 
| bsw@1045 | 100         ui.heading { | 
| bsw/jbe@1309 | 101           attr = { class = "mdl-card__title-text" }, | 
| bsw/jbe@1309 | 102           content = function() | 
| bsw/jbe@1309 | 103             ui.link{ | 
| bsw/jbe@1309 | 104               module = "initiative", view = "show", id = initiative.id, | 
| bsw/jbe@1309 | 105               content = initiative.display_name | 
| bsw/jbe@1309 | 106             } | 
| bsw/jbe@1309 | 107           end | 
| bsw@1045 | 108         } | 
| bsw/jbe@1309 | 109         ui.container{ content = _("Comparision of revisions #{id1} and #{id2}", { | 
| bsw/jbe@1309 | 110           id1 = old_draft.id, | 
| bsw/jbe@1309 | 111           id2 = new_draft.id | 
| bsw/jbe@1309 | 112         } ) } | 
| bsw/jbe@1309 | 113       end } | 
| bsw/jbe@1309 | 114 | 
| bsw/jbe@1309 | 115       if app.session.member_id and not new_draft.initiative.revoked then | 
| bsw/jbe@1309 | 116         local supporter = app.session.member:get_reference_selector("supporters") | 
| bsw/jbe@1309 | 117           :add_where{ "initiative_id = ?", new_draft.initiative_id } | 
| bsw/jbe@1309 | 118           :optional_object_mode() | 
| bsw/jbe@1309 | 119           :exec() | 
| bsw/jbe@1309 | 120         if supporter and supporter.draft_id == old_draft.id and new_draft.id == initiative.current_draft.id then | 
| bsw/jbe@1309 | 121           ui.container { | 
| bsw/jbe@1309 | 122             attr = { class = "mdl-card__content mdl-card--no-bottom-pad mdl-card--notice" }, | 
| bsw/jbe@1309 | 123             content = _"The draft of this initiative has been updated!" | 
| bsw@1045 | 124           } | 
| bsw/jbe@1309 | 125           ui.container { | 
| bsw/jbe@1309 | 126             attr = { class = "mdl-card__actions mdl-card--action-border  mdl-card--notice" }, | 
| bsw/jbe@1309 | 127             content = function () | 
| bsw/jbe@1309 | 128               ui.link{ | 
| bsw/jbe@1309 | 129                 attr = { class = "mdl-button mdl-js-button mdl-button--raised" }, | 
| bsw/jbe@1309 | 130                 text   = _"refresh my support", | 
| bsw/jbe@1309 | 131                 module = "initiative", | 
| bsw/jbe@1309 | 132                 action = "add_support", | 
| bsw/jbe@1309 | 133                 id     = new_draft.initiative.id, | 
| bsw/jbe@1309 | 134                 params = { draft_id = new_draft.id }, | 
| bsw/jbe@1309 | 135                 routing = { | 
| bsw/jbe@1309 | 136                   default = { | 
| bsw/jbe@1309 | 137                     mode = "redirect", | 
| bsw/jbe@1309 | 138                     module = "initiative", | 
| bsw/jbe@1309 | 139                     view = "show", | 
| bsw/jbe@1309 | 140                     id = new_draft.initiative.id | 
| bsw/jbe@1309 | 141                   } | 
| bsw/jbe@1309 | 142                 } | 
| bsw/jbe@1309 | 143               } | 
| bsw@1045 | 144 | 
| bsw/jbe@1309 | 145               slot.put("   ") | 
| bsw/jbe@1309 | 146 | 
| bsw/jbe@1309 | 147               ui.link{ | 
| bsw/jbe@1309 | 148                 attr = { class = "mdl-button mdl-js-button mdl-button--raised" }, | 
| bsw/jbe@1309 | 149                 text   = _"remove my support", | 
| bsw/jbe@1309 | 150                 module = "initiative", | 
| bsw/jbe@1309 | 151                 action = "remove_support", | 
| bsw/jbe@1309 | 152                 id     = new_draft.initiative.id, | 
| bsw/jbe@1309 | 153                 routing = { | 
| bsw/jbe@1309 | 154                   default = { | 
| bsw/jbe@1309 | 155                     mode = "redirect", | 
| bsw/jbe@1309 | 156                     module = "initiative", | 
| bsw/jbe@1309 | 157                     view = "show", | 
| bsw/jbe@1309 | 158                     id = new_draft.initiative.id | 
| bsw/jbe@1309 | 159                   } | 
| bsw/jbe@1309 | 160                 } | 
| bsw/jbe@1309 | 161               } | 
| bsw/jbe@1309 | 162 | 
| bsw/jbe@1309 | 163               slot.put("   ") | 
| bsw/jbe@1309 | 164 | 
| bsw/jbe@1309 | 165               ui.link{ | 
| bsw/jbe@1309 | 166                 attr = { class = "mdl-button mdl-js-button" }, | 
| bsw/jbe@1309 | 167                 text   = _"cancel", | 
| bsw/jbe@1309 | 168                 module = "initiative", | 
| bsw/jbe@1309 | 169                 view   = "show", | 
| bsw/jbe@1309 | 170                 id     = new_draft.initiative.id, | 
| bsw/jbe@1309 | 171               } | 
| bsw/jbe@1309 | 172             end | 
| bsw@1045 | 173           } | 
| bsw/jbe@1309 | 174         end | 
| bsw/jbe@1309 | 175       end | 
| bsw@2 | 176 | 
| bsw/jbe@1309 | 177       ui.container { | 
| bsw/jbe@1309 | 178         attr = { class = "draft mdl-card__content mdl-card--border" }, | 
| bsw/jbe@1309 | 179         content = function () | 
| bsw/jbe@1309 | 180           if not status then | 
| bsw/jbe@1309 | 181             ui.field.text{ value = _"The drafts do not differ" } | 
| bsw/jbe@1309 | 182           else | 
| bsw/jbe@1309 | 183             ui.container{ | 
| bsw/jbe@1309 | 184               tag = "div", | 
| bsw/jbe@1309 | 185               attr = { class = "diff" }, | 
| bsw/jbe@1309 | 186               content = function() | 
| bsw/jbe@1309 | 187                 output = output:gsub("[^\n\r]+", function(line) | 
| bsw/jbe@1309 | 188                   process_line(line) | 
| bsw/jbe@1309 | 189                 end) | 
| bsw/jbe@1309 | 190               end | 
| bsw/jbe@1309 | 191             } | 
| bsw/jbe@1309 | 192           end | 
| bsw@1045 | 193         end | 
| bsw@1045 | 194       } | 
| bsw/jbe@1309 | 195     end } | 
| bsw/jbe@1309 | 196   end } | 
| bsw/jbe@1309 | 197   ui.cell_sidebar{ content = function() | 
| bsw/jbe@1309 | 198 | 
| bsw/jbe@1309 | 199     execute.view{ module = "issue", view = "_sidebar", params = { | 
| bsw/jbe@1309 | 200       initiative = initiative, | 
| bsw/jbe@1309 | 201       issue = initiative.issue | 
| bsw/jbe@1309 | 202     } } | 
| bsw@1045 | 203 | 
| bsw/jbe@1309 | 204     execute.view { | 
| bsw/jbe@1309 | 205       module = "issue", view = "_sidebar_whatcanido", | 
| bsw/jbe@1309 | 206       params = { initiative = initiative } | 
| bsw/jbe@1309 | 207     } | 
| bsw/jbe@1309 | 208 | 
| bsw/jbe@1309 | 209     execute.view { | 
| bsw/jbe@1309 | 210       module = "issue", view = "_sidebar_members", params = { | 
| bsw/jbe@1309 | 211         issue = initiative.issue, initiative = initiative | 
| bsw/jbe@1309 | 212       } | 
| bsw/jbe@1309 | 213     } | 
| bsw/jbe@1309 | 214   end } | 
| bsw/jbe@1309 | 215 end } |