]> git.openstreetmap.org Git - rails.git/blob - app/controllers/api/changesets/downloads_controller.rb
Merge remote-tracking branch 'upstream/pull/5721'
[rails.git] / app / controllers / api / changesets / downloads_controller.rb
1 module Api
2   module Changesets
3     class DownloadsController < ApiController
4       authorize_resource :changeset
5
6       before_action :set_request_formats
7
8       ##
9       # download the changeset as an osmChange document.
10       #
11       # to make it easier to revert diffs it would be better if the osmChange
12       # format were reversible, i.e: contained both old and new versions of
13       # modified elements. but it doesn't at the moment...
14       #
15       # this method cannot order the database changes fully (i.e: timestamp and
16       # version number may be too coarse) so the resulting diff may not apply
17       # to a different database. however since changesets are not atomic this
18       # behaviour cannot be guaranteed anyway and is the result of a design
19       # choice.
20       def show
21         changeset = Changeset.find(params[:changeset_id])
22
23         # get all the elements in the changeset which haven't been redacted
24         # and stick them in a big array.
25         elements = [changeset.old_nodes.unredacted,
26                     changeset.old_ways.unredacted,
27                     changeset.old_relations.unredacted].flatten
28
29         # sort the elements by timestamp and version number, as this is the
30         # almost sensible ordering available. this would be much nicer if
31         # global (SVN-style) versioning were used - then that would be
32         # unambiguous.
33         elements.sort_by! { |e| [e.timestamp, e.version] }
34
35         # generate an output element for each operation. note: we avoid looking
36         # at the history because it is simpler - but it would be more correct to
37         # check these assertions.
38         @created = []
39         @modified = []
40         @deleted = []
41
42         elements.each do |elt|
43           if elt.version == 1
44             # first version, so it must be newly-created.
45             @created << elt
46           elsif elt.visible
47             # must be a modify
48             @modified << elt
49           else
50             # if the element isn't visible then it must have been deleted
51             @deleted << elt
52           end
53         end
54
55         respond_to do |format|
56           format.xml
57         end
58       end
59     end
60   end
61 end