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 }
|