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