]> git.openstreetmap.org Git - rails.git/blob - app/models/changeset.rb
some useful notes in code for ideas that require implementing.
[rails.git] / app / models / changeset.rb
1 class Changeset < ActiveRecord::Base
2   require 'xml/libxml'
3
4   belongs_to :user
5
6   has_many :changeset_tags, :foreign_key => 'id'
7   
8   has_many :nodes
9   has_many :ways
10   has_many :relations
11   has_many :old_nodes
12   has_many :old_ways
13   has_many :old_relations
14   
15   validates_presence_of :user_id, :created_at, :open
16   
17   # Use a method like this, so that we can easily change how we
18   # determine whether a changeset is open, without breaking code in at 
19   # least 6 controllers
20   def is_open?
21     return open
22   end
23
24   def self.from_xml(xml, create=false)
25     begin
26       p = XML::Parser.new
27       p.string = xml
28       doc = p.parse
29
30       cs = Changeset.new
31
32       doc.find('//osm/changeset').each do |pt|
33         if create
34           cs.created_at = Time.now
35         end
36
37         pt.find('tag').each do |tag|
38           cs.add_tag_keyval(tag['k'], tag['v'])
39         end
40       end
41     rescue Exception => ex
42     print "noes "+ ex.to_s + "\n"
43       cs = nil
44     end
45
46     return cs
47   end
48
49   def tags
50     unless @tags
51       @tags = {}
52       self.changeset_tags.each do |tag|
53         @tags[tag.k] = tag.v
54       end
55     end
56     @tags
57   end
58
59   def tags=(t)
60     @tags = t
61   end
62
63   def add_tag_keyval(k, v)
64     @tags = Hash.new unless @tags
65     @tags[k] = v
66   end
67
68   def save_with_tags!
69     t = Time.now
70
71     Changeset.transaction do
72       # fixme update modified_at time?
73       self.save!
74     end
75
76     ChangesetTag.transaction do
77       tags = self.tags
78       ChangesetTag.delete_all(['id = ?', self.id])
79
80       tags.each do |k,v|
81         tag = ChangesetTag.new
82         tag.k = k
83         tag.v = v
84         tag.id = self.id
85         tag.save!
86       end
87     end
88   end
89   
90   def to_xml
91     doc = OSM::API.new.get_xml_doc
92     doc.root << to_xml_node()
93     return doc
94   end
95   
96   def to_xml_node(user_display_name_cache = nil)
97     el1 = XML::Node.new 'changeset'
98     el1['id'] = self.id.to_s
99
100     user_display_name_cache = {} if user_display_name_cache.nil?
101
102     if user_display_name_cache and user_display_name_cache.key?(self.user_id)
103       # use the cache if available
104     elsif self.user.data_public?
105       user_display_name_cache[self.user_id] = self.user.display_name
106     else
107       user_display_name_cache[self.user_id] = nil
108     end
109
110     el1['user'] = user_display_name_cache[self.user_id] unless user_display_name_cache[self.user_id].nil?
111
112     self.tags.each do |k,v|
113       el2 = XML::Node.new('tag')
114       el2['k'] = k.to_s
115       el2['v'] = v.to_s
116       el1 << el2
117     end
118     
119     el1['created_at'] = self.created_at.xmlschema
120     el1['open'] = self.open.to_s
121
122     # FIXME FIXME FIXME: This does not include changes yet! There is 
123     # currently no changeset_id column in the tables as far as I can tell,
124     # so this is just a scaffold to build on, not a complete to_xml
125
126     return el1
127   end
128 end