Merge branch 'master' into openstreetbugs
Conflicts: app/views/browse/_map.html.erb app/views/site/index.html.erb config/initializers/mime_types.rb config/routes.rb lib/map_boundary.rb lib/migrate.rb lib/osm.rb vendor/assets/openlayers/OpenLayers.js
This commit is contained in:
commit
52e5fa6ad7
888 changed files with 23910 additions and 22316 deletions
|
@ -1,5 +1,11 @@
|
|||
class AccessToken<OauthToken
|
||||
validates_presence_of :user
|
||||
class AccessToken < OauthToken
|
||||
belongs_to :user
|
||||
belongs_to :client_application
|
||||
|
||||
scope :valid, where(:invalidated_at => nil)
|
||||
|
||||
validates_presence_of :user, :secret
|
||||
|
||||
before_create :set_authorized_at
|
||||
|
||||
protected
|
||||
|
@ -7,4 +13,4 @@ protected
|
|||
def set_authorized_at
|
||||
self.authorized_at = Time.now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
class Acl < ActiveRecord::Base
|
||||
def self.find_by_address(address, options)
|
||||
self.with_scope(:find => {:conditions => ["#{inet_aton} & netmask = address", address]}) do
|
||||
return self.find(:first, options)
|
||||
end
|
||||
end
|
||||
|
||||
def self.find_all_by_address(address, options)
|
||||
self.with_scope(:find => {:conditions => ["#{inet_aton} & netmask = address", address]}) do
|
||||
return self.find(:all, options)
|
||||
end
|
||||
end
|
||||
scope :address, lambda { |address| where("#{inet_aton} & netmask = address", address) }
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ class Changeset < ActiveRecord::Base
|
|||
|
||||
belongs_to :user
|
||||
|
||||
has_many :changeset_tags, :foreign_key => 'id'
|
||||
has_many :changeset_tags
|
||||
|
||||
has_many :nodes
|
||||
has_many :ways
|
||||
|
@ -20,6 +20,8 @@ class Changeset < ActiveRecord::Base
|
|||
validates_numericality_of :user_id, :integer_only => true
|
||||
validates_numericality_of :num_changes, :integer_only => true, :greater_than_or_equal_to => 0
|
||||
|
||||
before_save :update_closed_at
|
||||
|
||||
# over-expansion factor to use when updating the bounding box
|
||||
EXPAND = 0.1
|
||||
|
||||
|
@ -52,7 +54,7 @@ class Changeset < ActiveRecord::Base
|
|||
|
||||
def self.from_xml(xml, create=false)
|
||||
begin
|
||||
p = XML::Parser.string(xml)
|
||||
p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
|
||||
doc = p.parse
|
||||
|
||||
doc.find('//osm/changeset').each do |pt|
|
||||
|
@ -88,21 +90,11 @@ class Changeset < ActiveRecord::Base
|
|||
# returns the bounding box of the changeset. it is possible that some
|
||||
# or all of the values will be nil, indicating that they are undefined.
|
||||
def bbox
|
||||
@bbox ||= [ min_lon, min_lat, max_lon, max_lat ]
|
||||
@bbox ||= BoundingBox.new(min_lon, min_lat, max_lon, max_lat)
|
||||
end
|
||||
|
||||
def has_valid_bbox?
|
||||
not bbox.include? nil
|
||||
end
|
||||
|
||||
##
|
||||
# returns area of the changset bbox as a rough comparitive quantity for use of changset displays
|
||||
def area
|
||||
if has_valid_bbox?
|
||||
(max_lon - min_lon) * (max_lat - min_lat)
|
||||
else
|
||||
0
|
||||
end
|
||||
bbox.complete?
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -110,26 +102,12 @@ class Changeset < ActiveRecord::Base
|
|||
# expand a little bit more in the direction of the expansion, so that
|
||||
# further expansions may be unnecessary. this is an optimisation
|
||||
# suggested on the wiki page by kleptog.
|
||||
def update_bbox!(array)
|
||||
# ensure that bbox is cached and has no nils in it. if there are any
|
||||
# nils, just use the bounding box update to write over them.
|
||||
@bbox = bbox.zip(array).collect { |a, b| a.nil? ? b : a }
|
||||
|
||||
# only try to update the bbox if there is a value for every coordinate
|
||||
# which there will be from the previous line as long as both array and
|
||||
# bbox are all non-nil.
|
||||
if has_valid_bbox? and array.all?
|
||||
# FIXME - this looks nasty and violates DRY... is there any prettier
|
||||
# way to do this?
|
||||
@bbox[0] = [-180 * GeoRecord::SCALE, array[0] + EXPAND * (@bbox[0] - @bbox[2])].max if array[0] < @bbox[0]
|
||||
@bbox[1] = [ -90 * GeoRecord::SCALE, array[1] + EXPAND * (@bbox[1] - @bbox[3])].max if array[1] < @bbox[1]
|
||||
@bbox[2] = [ 180 * GeoRecord::SCALE, array[2] + EXPAND * (@bbox[2] - @bbox[0])].min if array[2] > @bbox[2]
|
||||
@bbox[3] = [ 90 * GeoRecord::SCALE, array[3] + EXPAND * (@bbox[3] - @bbox[1])].min if array[3] > @bbox[3]
|
||||
def update_bbox!(bbox_update)
|
||||
bbox.expand!(bbox_update, EXPAND)
|
||||
|
||||
# update active record. rails 2.1's dirty handling should take care of
|
||||
# whether this object needs saving or not.
|
||||
self.min_lon, self.min_lat, self.max_lon, self.max_lat = @bbox
|
||||
end
|
||||
# update active record. rails 2.1's dirty handling should take care of
|
||||
# whether this object needs saving or not.
|
||||
self.min_lon, self.min_lat, self.max_lon, self.max_lat = @bbox.to_a if bbox.complete?
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -175,13 +153,13 @@ class Changeset < ActiveRecord::Base
|
|||
self.save!
|
||||
|
||||
tags = self.tags
|
||||
ChangesetTag.delete_all(['id = ?', self.id])
|
||||
ChangesetTag.delete_all(:changeset_id => self.id)
|
||||
|
||||
tags.each do |k,v|
|
||||
tag = ChangesetTag.new
|
||||
tag.changeset_id = self.id
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.save!
|
||||
end
|
||||
end
|
||||
|
@ -191,7 +169,7 @@ class Changeset < ActiveRecord::Base
|
|||
# set the auto-close time to be one hour in the future unless
|
||||
# that would make it more than 24h long, in which case clip to
|
||||
# 24h, as this has been decided is a reasonable time limit.
|
||||
def before_save
|
||||
def update_closed_at
|
||||
if self.is_open?
|
||||
if (closed_at - created_at) > (MAX_TIME_OPEN - IDLE_TIMEOUT)
|
||||
self.closed_at = created_at + MAX_TIME_OPEN
|
||||
|
@ -235,10 +213,9 @@ class Changeset < ActiveRecord::Base
|
|||
el1['closed_at'] = self.closed_at.xmlschema unless is_open?
|
||||
el1['open'] = is_open?.to_s
|
||||
|
||||
el1['min_lon'] = (bbox[0].to_f / GeoRecord::SCALE).to_s unless bbox[0].nil?
|
||||
el1['min_lat'] = (bbox[1].to_f / GeoRecord::SCALE).to_s unless bbox[1].nil?
|
||||
el1['max_lon'] = (bbox[2].to_f / GeoRecord::SCALE).to_s unless bbox[2].nil?
|
||||
el1['max_lat'] = (bbox[3].to_f / GeoRecord::SCALE).to_s unless bbox[3].nil?
|
||||
if bbox.complete?
|
||||
bbox.to_unscaled.add_bounds_to(el1, '_')
|
||||
end
|
||||
|
||||
# NOTE: changesets don't include the XML of the changes within them,
|
||||
# they are just structures for tagging. to get the osmChange of a
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
class ChangesetTag < ActiveRecord::Base
|
||||
belongs_to :changeset, :foreign_key => 'id'
|
||||
set_primary_keys :changeset_id, :k
|
||||
|
||||
validates_presence_of :id
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => :k
|
||||
validates_numericality_of :id, :only_integer => true
|
||||
belongs_to :changeset
|
||||
|
||||
validates_presence_of :changeset
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => :changeset_id
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
require 'oauth'
|
||||
|
||||
class ClientApplication < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
has_many :tokens, :class_name => "OauthToken"
|
||||
has_many :access_tokens
|
||||
has_many :oauth2_verifiers
|
||||
has_many :oauth_tokens
|
||||
|
||||
validates_presence_of :name, :url, :key, :secret
|
||||
validates_uniqueness_of :key
|
||||
before_validation_on_create :generate_keys
|
||||
|
||||
validates_format_of :url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i
|
||||
validates_format_of :support_url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i, :allow_blank=>true
|
||||
validates_format_of :callback_url, :with => /\A[a-z][a-z0-9.+-]*:\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i, :allow_blank=>true
|
||||
|
||||
before_validation :generate_keys, :on => :create
|
||||
|
||||
attr_accessor :token_callback_url
|
||||
|
||||
def self.find_token(token_key)
|
||||
|
@ -25,15 +29,10 @@ class ClientApplication < ActiveRecord::Base
|
|||
def self.verify_request(request, options = {}, &block)
|
||||
begin
|
||||
signature = OAuth::Signature.build(request, options, &block)
|
||||
logger.info "Signature Base String: #{signature.signature_base_string}"
|
||||
logger.info "Consumer: #{signature.send :consumer_key}"
|
||||
logger.info "Token: #{signature.send :token}"
|
||||
return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
|
||||
value = signature.verify
|
||||
logger.info "Signature verification returned: #{value.to_s}"
|
||||
value
|
||||
rescue OAuth::Signature::UnknownSignatureMethod => e
|
||||
logger.info "ERROR"+e.to_s
|
||||
false
|
||||
end
|
||||
end
|
||||
|
@ -50,12 +49,16 @@ class ClientApplication < ActiveRecord::Base
|
|||
@oauth_client ||= OAuth::Consumer.new(key, secret)
|
||||
end
|
||||
|
||||
def create_request_token
|
||||
RequestToken.create :client_application => self, :callback_url => self.token_callback_url
|
||||
def create_request_token(params={})
|
||||
params = { :client_application => self, :callback_url => self.token_callback_url }
|
||||
permissions.each do |p|
|
||||
params[p] = true
|
||||
end
|
||||
RequestToken.create(params)
|
||||
end
|
||||
|
||||
def access_token_for_user(user)
|
||||
unless token = access_tokens.find(:first, :conditions => { :user_id => user.id, :invalidated_at => nil })
|
||||
unless token = access_tokens.valid.where(:user_id => user).first
|
||||
params = { :user => user }
|
||||
|
||||
permissions.each do |p|
|
||||
|
@ -82,8 +85,7 @@ protected
|
|||
:allow_write_api, :allow_read_gpx, :allow_write_gpx ]
|
||||
|
||||
def generate_keys
|
||||
oauth_client = oauth_server.generate_consumer_credentials
|
||||
self.key = oauth_client.key
|
||||
self.secret = oauth_client.secret
|
||||
self.key = OAuth::Helper.generate_key(40)[0,40]
|
||||
self.secret = OAuth::Helper.generate_key(40)[0,40]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,8 @@ class DiaryEntry < ActiveRecord::Base
|
|||
},
|
||||
:order => "diary_comments.id"
|
||||
|
||||
scope :visible, where(:visible => true)
|
||||
|
||||
validates_presence_of :title, :body
|
||||
validates_length_of :title, :within => 1..255
|
||||
#validates_length_of :language, :within => 2..5, :allow_nil => false
|
||||
|
|
|
@ -17,8 +17,8 @@ private
|
|||
|
||||
def expire_cache_for(record)
|
||||
case
|
||||
when record.is_a?(DiaryEntry): entry = record
|
||||
when record.is_a?(DiaryComment): entry = record.diary_entry
|
||||
when record.is_a?(DiaryEntry) then entry = record
|
||||
when record.is_a?(DiaryComment) then entry = record.diary_entry
|
||||
end
|
||||
|
||||
expire_action(:controller => 'diary_entry', :action => 'view', :display_name => entry.user.display_name, :id => entry.id)
|
||||
|
|
|
@ -8,12 +8,12 @@ class Node < ActiveRecord::Base
|
|||
|
||||
belongs_to :changeset
|
||||
|
||||
has_many :old_nodes, :foreign_key => :id, :order => :version
|
||||
has_many :old_nodes, :order => :version
|
||||
|
||||
has_many :way_nodes
|
||||
has_many :ways, :through => :way_nodes
|
||||
|
||||
has_many :node_tags, :foreign_key => :id
|
||||
has_many :node_tags
|
||||
|
||||
has_many :old_way_nodes
|
||||
has_many :ways_via_history, :class_name=> "Way", :through => :old_way_nodes, :source => :way
|
||||
|
@ -30,9 +30,12 @@ class Node < ActiveRecord::Base
|
|||
validate :validate_position
|
||||
validates_associated :changeset
|
||||
|
||||
scope :visible, where(:visible => true)
|
||||
scope :invisible, where(:visible => false)
|
||||
|
||||
# Sanity check the latitude and longitude and add an error if it's broken
|
||||
def validate_position
|
||||
errors.add_to_base("Node is not in the world") unless in_world?
|
||||
errors.add(:base, "Node is not in the world") unless in_world?
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -41,7 +44,6 @@ class Node < ActiveRecord::Base
|
|||
# Also adheres to limitations such as within max_number_of_nodes
|
||||
#
|
||||
def self.search(bounding_box, tags = {})
|
||||
min_lon, min_lat, max_lon, max_lat = *bounding_box
|
||||
# @fixme a bit of a hack to search for only visible nodes
|
||||
# couldn't think of another to add to tags condition
|
||||
#conditions_hash = tags.merge({ 'visible' => 1 })
|
||||
|
@ -56,9 +58,8 @@ class Node < ActiveRecord::Base
|
|||
#end
|
||||
#conditions = keys.join(' AND ')
|
||||
|
||||
find_by_area(min_lat, min_lon, max_lat, max_lon,
|
||||
:conditions => {:visible => true},
|
||||
:limit => MAX_NUMBER_OF_NODES+1)
|
||||
find_by_area(bounding_box, :conditions => {:visible => true},
|
||||
:limit => MAX_NUMBER_OF_NODES+1)
|
||||
end
|
||||
|
||||
# Read in xml as text and return it's Node object representation
|
||||
|
@ -118,7 +119,7 @@ class Node < ActiveRecord::Base
|
|||
# the bounding box around a node, which is used for determining the changeset's
|
||||
# bounding box
|
||||
def bbox
|
||||
[ longitude, latitude, longitude, latitude ]
|
||||
BoundingBox.new(longitude, latitude, longitude, latitude)
|
||||
end
|
||||
|
||||
# Should probably be renamed delete_from to come in line with update
|
||||
|
@ -133,13 +134,11 @@ class Node < ActiveRecord::Base
|
|||
Node.transaction do
|
||||
self.lock!
|
||||
check_consistency(self, new_node, user)
|
||||
way = WayNode.find(:first, :joins => :way,
|
||||
:conditions => [ "current_ways.visible = ? AND current_way_nodes.node_id = ?", true, self.id ])
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by way #{way.way.id}.") unless way.nil?
|
||||
ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id)
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by ways #{ways.collect { |w| w.id }.join(",")}.") unless ways.empty?
|
||||
|
||||
rel = RelationMember.find(:first, :joins => :relation,
|
||||
:conditions => [ "visible = ? AND member_type='Node' and member_id=? ", true, self.id])
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by relation #{rel.relation.id}.") unless rel.nil?
|
||||
rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Node", :member_id => id }).order(:id)
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by relations #{rels.collect { |r| r.id }.join(",")}.") unless rels.empty?
|
||||
|
||||
self.changeset_id = new_node.changeset_id
|
||||
self.tags = {}
|
||||
|
@ -288,12 +287,12 @@ class Node < ActiveRecord::Base
|
|||
|
||||
# Create a NodeTag
|
||||
tags = self.tags
|
||||
NodeTag.delete_all(['id = ?', self.id])
|
||||
NodeTag.delete_all(:node_id => self.id)
|
||||
tags.each do |k,v|
|
||||
tag = NodeTag.new
|
||||
tag.node_id = self.id
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.save!
|
||||
end
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class NodeTag < ActiveRecord::Base
|
||||
set_table_name 'current_node_tags'
|
||||
set_primary_keys :node_id, :k
|
||||
|
||||
belongs_to :node, :foreign_key => 'id'
|
||||
belongs_to :node
|
||||
|
||||
validates_presence_of :id
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => :k
|
||||
validates_numericality_of :id, :only_integer => true
|
||||
validates_presence_of :node
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => :node_id
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
|
@ -1,98 +1,117 @@
|
|||
class Notifier < ActionMailer::Base
|
||||
default :from => EMAIL_FROM,
|
||||
:return_path => EMAIL_RETURN_PATH,
|
||||
:auto_submitted => "auto-generated"
|
||||
helper :application
|
||||
|
||||
def signup_confirm(user, token)
|
||||
common_headers user
|
||||
subject I18n.t('notifier.signup_confirm.subject')
|
||||
body :url => url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "confirm",
|
||||
:display_name => user.display_name,
|
||||
:confirm_string => token.token)
|
||||
@locale = user.preferred_language_from(I18n.available_locales)
|
||||
@url = url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "confirm",
|
||||
:display_name => user.display_name,
|
||||
:confirm_string => token.token)
|
||||
|
||||
mail :to => user.email,
|
||||
:subject => I18n.t('notifier.signup_confirm.subject', :locale => @locale)
|
||||
end
|
||||
|
||||
def email_confirm(user, token)
|
||||
common_headers user
|
||||
recipients user.new_email
|
||||
subject I18n.t('notifier.email_confirm.subject')
|
||||
body :address => user.new_email,
|
||||
:url => url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "confirm_email",
|
||||
:confirm_string => token.token)
|
||||
@locale = user.preferred_language_from(I18n.available_locales)
|
||||
@address = user.new_email
|
||||
@url = url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "confirm_email",
|
||||
:confirm_string => token.token)
|
||||
|
||||
mail :to => user.new_email,
|
||||
:subject => I18n.t('notifier.email_confirm.subject', :locale => @locale)
|
||||
end
|
||||
|
||||
def lost_password(user, token)
|
||||
common_headers user
|
||||
subject I18n.t('notifier.lost_password.subject')
|
||||
body :url => url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "reset_password",
|
||||
:token => token.token)
|
||||
@locale = user.preferred_language_from(I18n.available_locales)
|
||||
@url = url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "reset_password",
|
||||
:token => token.token)
|
||||
|
||||
mail :to => user.email,
|
||||
:subject => I18n.t('notifier.lost_password.subject', :locale => @locale)
|
||||
end
|
||||
|
||||
def gpx_success(trace, possible_points)
|
||||
common_headers trace.user
|
||||
subject I18n.t('notifier.gpx_notification.success.subject')
|
||||
body :trace_name => trace.name,
|
||||
:trace_points => trace.size,
|
||||
:trace_description => trace.description,
|
||||
:trace_tags => trace.tags,
|
||||
:possible_points => possible_points
|
||||
@locale = trace.user.preferred_language_from(I18n.available_locales)
|
||||
@trace_name = trace.name
|
||||
@trace_points = trace.size
|
||||
@trace_description = trace.description
|
||||
@trace_tags = trace.tags
|
||||
@possible_points = possible_points
|
||||
|
||||
mail :to => trace.user.email,
|
||||
:subject => I18n.t('notifier.gpx_notification.success.subject', :locale => @locale)
|
||||
end
|
||||
|
||||
def gpx_failure(trace, error)
|
||||
common_headers trace.user
|
||||
from "webmaster@openstreetmap.org"
|
||||
subject I18n.t('notifier.gpx_notification.failure.subject')
|
||||
body :trace_name => trace.name,
|
||||
:trace_description => trace.description,
|
||||
:trace_tags => trace.tags,
|
||||
:error => error
|
||||
@locale = trace.user.preferred_language_from(I18n.available_locales)
|
||||
@trace_name = trace.name
|
||||
@trace_description = trace.description
|
||||
@trace_tags = trace.tags
|
||||
@error = error
|
||||
|
||||
mail :to => trace.user.email,
|
||||
:subject => I18n.t('notifier.gpx_notification.failure.subject', :locale => @locale)
|
||||
end
|
||||
|
||||
def message_notification(message)
|
||||
common_headers message.recipient
|
||||
from_header message.sender.display_name, "m", message.id, message.digest
|
||||
subject I18n.t('notifier.message_notification.subject_header', :subject => message.title, :locale => locale)
|
||||
body :to_user => message.recipient.display_name,
|
||||
:from_user => message.sender.display_name,
|
||||
:body => message.body,
|
||||
:title => message.title,
|
||||
:readurl => url_for(:host => SERVER_URL,
|
||||
:controller => "message", :action => "read",
|
||||
:message_id => message.id),
|
||||
:replyurl => url_for(:host => SERVER_URL,
|
||||
:controller => "message", :action => "reply",
|
||||
:message_id => message.id)
|
||||
@locale = message.recipient.preferred_language_from(I18n.available_locales)
|
||||
@to_user = message.recipient.display_name
|
||||
@from_user = message.sender.display_name
|
||||
@text = message.body
|
||||
@title = message.title
|
||||
@readurl = url_for(:host => SERVER_URL,
|
||||
:controller => "message", :action => "read",
|
||||
:message_id => message.id)
|
||||
@replyurl = url_for(:host => SERVER_URL,
|
||||
:controller => "message", :action => "reply",
|
||||
:message_id => message.id)
|
||||
|
||||
mail :from => from_address(message.sender.display_name, "m", message.id, message.digest),
|
||||
:to => message.recipient.email,
|
||||
:subject => I18n.t('notifier.message_notification.subject_header', :subject => message.title, :locale => @locale)
|
||||
end
|
||||
|
||||
def diary_comment_notification(comment)
|
||||
common_headers comment.diary_entry.user
|
||||
from_header comment.user.display_name, "c", comment.id, comment.digest
|
||||
subject I18n.t('notifier.diary_comment_notification.subject', :user => comment.user.display_name, :locale => locale)
|
||||
body :to_user => comment.diary_entry.user.display_name,
|
||||
:from_user => comment.user.display_name,
|
||||
:body => comment.body,
|
||||
:title => comment.diary_entry.title,
|
||||
:readurl => url_for(:host => SERVER_URL,
|
||||
:controller => "diary_entry",
|
||||
:action => "view",
|
||||
:display_name => comment.diary_entry.user.display_name,
|
||||
:id => comment.diary_entry.id,
|
||||
:anchor => "comment#{comment.id}"),
|
||||
:commenturl => url_for(:host => SERVER_URL,
|
||||
:controller => "diary_entry",
|
||||
:action => "view",
|
||||
:display_name => comment.diary_entry.user.display_name,
|
||||
:id => comment.diary_entry.id,
|
||||
:anchor => "newcomment"),
|
||||
:replyurl => url_for(:host => SERVER_URL,
|
||||
:controller => "message",
|
||||
:action => "new",
|
||||
:display_name => comment.user.display_name,
|
||||
:title => "Re: #{comment.diary_entry.title}")
|
||||
@locale = comment.diary_entry.user.preferred_language_from(I18n.available_locales)
|
||||
@to_user = comment.diary_entry.user.display_name
|
||||
@from_user = comment.user.display_name
|
||||
@text = comment.body
|
||||
@title = comment.diary_entry.title
|
||||
@readurl = url_for(:host => SERVER_URL,
|
||||
:controller => "diary_entry",
|
||||
:action => "view",
|
||||
:display_name => comment.diary_entry.user.display_name,
|
||||
:id => comment.diary_entry.id,
|
||||
:anchor => "comment#{comment.id}")
|
||||
@commenturl = url_for(:host => SERVER_URL,
|
||||
:controller => "diary_entry",
|
||||
:action => "view",
|
||||
:display_name => comment.diary_entry.user.display_name,
|
||||
:id => comment.diary_entry.id,
|
||||
:anchor => "newcomment")
|
||||
@replyurl = url_for(:host => SERVER_URL,
|
||||
:controller => "message",
|
||||
:action => "new",
|
||||
:display_name => comment.user.display_name,
|
||||
:title => "Re: #{comment.diary_entry.title}")
|
||||
|
||||
mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest),
|
||||
:to => comment.diary_entry.user.email,
|
||||
:subject => I18n.t('notifier.diary_comment_notification.subject', :user => comment.user.display_name, :locale => @locale)
|
||||
end
|
||||
|
||||
def friend_notification(friend)
|
||||
common_headers friend.befriendee
|
||||
subject I18n.t('notifier.friend_notification.subject', :user => friend.befriender.display_name, :locale => locale)
|
||||
body :friend => friend
|
||||
@locale = friend.befriendee.preferred_language_from(I18n.available_locales)
|
||||
@friend = friend
|
||||
|
||||
mail :to => friend.befriendee.email,
|
||||
:subject => I18n.t('notifier.friend_notification.subject', :user => friend.befriender.display_name, :locale => @locale)
|
||||
end
|
||||
|
||||
def note_comment_notification(comment, recipient)
|
||||
|
@ -113,17 +132,11 @@ class Notifier < ActionMailer::Base
|
|||
|
||||
private
|
||||
|
||||
def common_headers(recipient)
|
||||
recipients recipient.email
|
||||
locale recipient.preferred_language_from(I18n.available_locales)
|
||||
from EMAIL_FROM
|
||||
headers "return-path" => EMAIL_RETURN_PATH,
|
||||
"Auto-Submitted" => "auto-generated"
|
||||
end
|
||||
|
||||
def from_header(name, type, id, digest)
|
||||
if domain = MESSAGES_DOMAIN
|
||||
from quote_address_if_necessary("#{name} <#{type}-#{id}-#{digest[0,6]}@#{domain}>", "utf-8")
|
||||
def from_address(name, type, id, digest)
|
||||
if Object.const_defined?(:MESSAGES_DOMAIN) and domain = MESSAGES_DOMAIN
|
||||
"#{name} <#{type}-#{id}-#{digest[0,6]}@#{domain}>"
|
||||
else
|
||||
EMAIL_FROM
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
21
app/models/oauth2_token.rb
Normal file
21
app/models/oauth2_token.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
class Oauth2Token < AccessToken
|
||||
attr_accessor :state
|
||||
|
||||
def as_json(options={})
|
||||
d = {:access_token=>token, :token_type => 'bearer'}
|
||||
d[:expires_in] = expires_in if expires_at
|
||||
d
|
||||
end
|
||||
|
||||
def to_query
|
||||
q = "access_token=#{token}&token_type=bearer"
|
||||
q << "&state=#{URI.escape(state)}" if @state
|
||||
q << "&expires_in=#{expires_in}" if expires_at
|
||||
q << "&scope=#{URI.escape(scope)}" if scope
|
||||
q
|
||||
end
|
||||
|
||||
def expires_in
|
||||
expires_at.to_i - Time.now.to_i
|
||||
end
|
||||
end
|
34
app/models/oauth2_verifier.rb
Normal file
34
app/models/oauth2_verifier.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
class Oauth2Verifier < OauthToken
|
||||
validates_presence_of :user
|
||||
attr_accessor :state
|
||||
|
||||
def exchange!(params={})
|
||||
OauthToken.transaction do
|
||||
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
||||
invalidate!
|
||||
token
|
||||
end
|
||||
end
|
||||
|
||||
def code
|
||||
token
|
||||
end
|
||||
|
||||
def redirect_url
|
||||
callback_url
|
||||
end
|
||||
|
||||
def to_query
|
||||
q = "code=#{token}"
|
||||
q << "&state=#{URI.escape(state)}" if @state
|
||||
q
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def generate_keys
|
||||
self.token = OAuth::Helper.generate_key(20)[0,20]
|
||||
self.expires_at = 10.minutes.from_now
|
||||
self.authorized_at = Time.now
|
||||
end
|
||||
end
|
|
@ -1,19 +1,13 @@
|
|||
class OauthToken < ActiveRecord::Base
|
||||
belongs_to :client_application
|
||||
belongs_to :user
|
||||
|
||||
scope :authorized, where("authorized_at IS NOT NULL and invalidated_at IS NULL")
|
||||
|
||||
validates_uniqueness_of :token
|
||||
validates_presence_of :client_application, :token, :secret
|
||||
before_validation_on_create :generate_keys
|
||||
|
||||
def self.find_token(token_key)
|
||||
token = OauthToken.find_by_token(token_key, :include => :client_application)
|
||||
if token && token.authorized?
|
||||
logger.info "Loaded #{token.token} which was authorized by (user_id=#{token.user_id}) on the #{token.authorized_at}"
|
||||
token
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
validates_presence_of :client_application, :token
|
||||
|
||||
before_validation :generate_keys, :on => :create
|
||||
|
||||
def invalidated?
|
||||
invalidated_at != nil
|
||||
|
@ -34,8 +28,7 @@ class OauthToken < ActiveRecord::Base
|
|||
protected
|
||||
|
||||
def generate_keys
|
||||
@oauth_token = client_application.oauth_server.generate_credentials
|
||||
self.token = @oauth_token[0]
|
||||
self.secret = @oauth_token[1]
|
||||
self.token = OAuth::Helper.generate_key(40)[0,40]
|
||||
self.secret = OAuth::Helper.generate_key(40)[0,40]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,11 +3,8 @@ class OldNode < ActiveRecord::Base
|
|||
include ConsistencyValidations
|
||||
|
||||
set_table_name 'nodes'
|
||||
|
||||
# Should probably have the composite primary key set in the model
|
||||
# however there are some weird bugs happening when you do
|
||||
#set_primary_keys :id, :version
|
||||
|
||||
set_primary_keys :node_id, :version
|
||||
|
||||
validates_presence_of :changeset_id, :timestamp
|
||||
validates_inclusion_of :visible, :in => [ true, false ]
|
||||
validates_numericality_of :latitude, :longitude
|
||||
|
@ -17,7 +14,7 @@ class OldNode < ActiveRecord::Base
|
|||
belongs_to :changeset
|
||||
|
||||
def validate_position
|
||||
errors.add_to_base("Node is not in the world") unless in_world?
|
||||
errors.add(:base, "Node is not in the world") unless in_world?
|
||||
end
|
||||
|
||||
def self.from_node(node)
|
||||
|
@ -28,7 +25,7 @@ class OldNode < ActiveRecord::Base
|
|||
old_node.tags = node.tags
|
||||
old_node.timestamp = node.timestamp
|
||||
old_node.changeset_id = node.changeset_id
|
||||
old_node.id = node.id
|
||||
old_node.node_id = node.id
|
||||
old_node.version = node.version
|
||||
return old_node
|
||||
end
|
||||
|
@ -41,7 +38,7 @@ class OldNode < ActiveRecord::Base
|
|||
|
||||
def to_xml_node
|
||||
el1 = XML::Node.new 'node'
|
||||
el1['id'] = self.id.to_s
|
||||
el1['id'] = self.node_id.to_s
|
||||
el1['lat'] = self.lat.to_s
|
||||
el1['lon'] = self.lon.to_s
|
||||
el1['changeset'] = self.changeset.id.to_s
|
||||
|
@ -69,13 +66,13 @@ class OldNode < ActiveRecord::Base
|
|||
clear_aggregation_cache
|
||||
clear_association_cache
|
||||
#ok from here
|
||||
@attributes.update(OldNode.find(:first, :conditions => ['id = ? AND timestamp = ? AND version = ?', self.id, self.timestamp, self.version]).instance_variable_get('@attributes'))
|
||||
@attributes.update(OldNode.where(:node_id => self.node_id, :timestamp => self.timestamp, :version => self.version).first.instance_variable_get('@attributes'))
|
||||
|
||||
self.tags.each do |k,v|
|
||||
tag = OldNodeTag.new
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.node_id = self.node_id
|
||||
tag.version = self.version
|
||||
tag.save!
|
||||
end
|
||||
|
@ -83,10 +80,10 @@ class OldNode < ActiveRecord::Base
|
|||
|
||||
def tags
|
||||
unless @tags
|
||||
@tags = Hash.new
|
||||
OldNodeTag.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version]).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
@tags = Hash.new
|
||||
OldNodeTag.where(:node_id => self.node_id, :version => self.version).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
end
|
||||
@tags = Hash.new unless @tags
|
||||
@tags
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class OldNodeTag < ActiveRecord::Base
|
||||
set_table_name 'node_tags'
|
||||
set_primary_keys :node_id, :version, :k
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :old_node, :foreign_key => [:node_id, :version]
|
||||
|
||||
validates_presence_of :id, :version
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => [:k, :version]
|
||||
validates_numericality_of :id, :version, :only_integer => true
|
||||
validates_presence_of :old_node
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => [:node_id, :version]
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
|
@ -2,8 +2,12 @@ class OldRelation < ActiveRecord::Base
|
|||
include ConsistencyValidations
|
||||
|
||||
set_table_name 'relations'
|
||||
set_primary_keys :relation_id, :version
|
||||
|
||||
belongs_to :changeset
|
||||
|
||||
has_many :old_members, :class_name => 'OldRelationMember', :foreign_key => [:relation_id, :version], :order => :sequence_id
|
||||
has_many :old_tags, :class_name => 'OldRelationTag', :foreign_key => [:relation_id, :version]
|
||||
|
||||
validates_associated :changeset
|
||||
|
||||
|
@ -12,7 +16,7 @@ class OldRelation < ActiveRecord::Base
|
|||
old_relation.visible = relation.visible
|
||||
old_relation.changeset_id = relation.changeset_id
|
||||
old_relation.timestamp = relation.timestamp
|
||||
old_relation.id = relation.id
|
||||
old_relation.relation_id = relation.id
|
||||
old_relation.version = relation.version
|
||||
old_relation.members = relation.members
|
||||
old_relation.tags = relation.tags
|
||||
|
@ -25,7 +29,7 @@ class OldRelation < ActiveRecord::Base
|
|||
save!
|
||||
clear_aggregation_cache
|
||||
clear_association_cache
|
||||
@attributes.update(OldRelation.find(:first, :conditions => ['id = ? AND timestamp = ?', self.id, self.timestamp], :order => "version desc").instance_variable_get('@attributes'))
|
||||
@attributes.update(OldRelation.where(:relation_id => self.relation_id, :timestamp => self.timestamp).order("version DESC").first.instance_variable_get('@attributes'))
|
||||
|
||||
# ok, you can touch from here on
|
||||
|
||||
|
@ -33,14 +37,14 @@ class OldRelation < ActiveRecord::Base
|
|||
tag = OldRelationTag.new
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.relation_id = self.relation_id
|
||||
tag.version = self.version
|
||||
tag.save!
|
||||
end
|
||||
|
||||
self.members.each_with_index do |m,i|
|
||||
member = OldRelationMember.new
|
||||
member.id = [self.id, self.version, i]
|
||||
member.id = [self.relation_id, self.version, i]
|
||||
member.member_type = m[0].classify
|
||||
member.member_id = m[1]
|
||||
member.member_role = m[2]
|
||||
|
@ -50,20 +54,20 @@ class OldRelation < ActiveRecord::Base
|
|||
|
||||
def members
|
||||
unless @members
|
||||
@members = Array.new
|
||||
OldRelationMember.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version], :order => "sequence_id").each do |m|
|
||||
@members += [[m.type,m.id,m.role]]
|
||||
end
|
||||
@members = Array.new
|
||||
OldRelationMember.where(:relation_id => self.relation_id, :version => self.version).order(:sequence_id).each do |m|
|
||||
@members += [[m.type,m.id,m.role]]
|
||||
end
|
||||
end
|
||||
@members
|
||||
end
|
||||
|
||||
def tags
|
||||
unless @tags
|
||||
@tags = Hash.new
|
||||
OldRelationTag.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version]).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
@tags = Hash.new
|
||||
OldRelationTag.where(:relation_id => self.relation_id, :version => self.version).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
end
|
||||
@tags = Hash.new unless @tags
|
||||
@tags
|
||||
|
@ -77,17 +81,6 @@ class OldRelation < ActiveRecord::Base
|
|||
@tags = t
|
||||
end
|
||||
|
||||
# has_many :relation_segments, :class_name => 'OldRelationSegment', :foreign_key => 'id'
|
||||
# has_many :relation_tags, :class_name => 'OldRelationTag', :foreign_key => 'id'
|
||||
|
||||
def old_members
|
||||
OldRelationMember.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version], :order => "sequence_id")
|
||||
end
|
||||
|
||||
def old_tags
|
||||
OldRelationTag.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])
|
||||
end
|
||||
|
||||
def to_xml
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
doc.root << to_xml_node()
|
||||
|
@ -96,7 +89,7 @@ class OldRelation < ActiveRecord::Base
|
|||
|
||||
def to_xml_node
|
||||
el1 = XML::Node.new 'relation'
|
||||
el1['id'] = self.id.to_s
|
||||
el1['id'] = self.relation_id.to_s
|
||||
el1['visible'] = self.visible.to_s
|
||||
el1['timestamp'] = self.timestamp.xmlschema
|
||||
if self.changeset.user.data_public?
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class OldRelationMember < ActiveRecord::Base
|
||||
set_table_name 'relation_members'
|
||||
set_primary_keys :relation_id, :version, :sequence_id
|
||||
|
||||
set_primary_keys :id, :version, :sequence_id
|
||||
belongs_to :relation, :foreign_key=> :id
|
||||
belongs_to :old_relation, :foreign_key => [:relation_id, :version]
|
||||
# A bit messy, referring to the current tables, should do for the data browser for now
|
||||
belongs_to :member, :polymorphic => true
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class OldRelationTag < ActiveRecord::Base
|
||||
set_table_name 'relation_tags'
|
||||
set_primary_keys :relation_id, :version, :k
|
||||
|
||||
belongs_to :old_relation, :foreign_key => [:relation_id, :version]
|
||||
|
||||
belongs_to :old_relation, :foreign_key => [:id, :version]
|
||||
|
||||
validates_presence_of :id, :version
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => [:k, :version]
|
||||
validates_numericality_of :id, :version, :only_integer => true
|
||||
validates_presence_of :old_relation
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => [:relation_id, :version]
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
|
@ -2,9 +2,13 @@ class OldWay < ActiveRecord::Base
|
|||
include ConsistencyValidations
|
||||
|
||||
set_table_name 'ways'
|
||||
set_primary_keys :way_id, :version
|
||||
|
||||
belongs_to :changeset
|
||||
|
||||
has_many :old_nodes, :class_name => 'OldWayNode', :foreign_key => [:way_id, :version]
|
||||
has_many :old_tags, :class_name => 'OldWayTag', :foreign_key => [:way_id, :version]
|
||||
|
||||
validates_associated :changeset
|
||||
|
||||
def self.from_way(way)
|
||||
|
@ -12,7 +16,7 @@ class OldWay < ActiveRecord::Base
|
|||
old_way.visible = way.visible
|
||||
old_way.changeset_id = way.changeset_id
|
||||
old_way.timestamp = way.timestamp
|
||||
old_way.id = way.id
|
||||
old_way.way_id = way.id
|
||||
old_way.version = way.version
|
||||
old_way.nds = way.nds
|
||||
old_way.tags = way.tags
|
||||
|
@ -30,7 +34,7 @@ class OldWay < ActiveRecord::Base
|
|||
save!
|
||||
clear_aggregation_cache
|
||||
clear_association_cache
|
||||
@attributes.update(OldWay.find(:first, :conditions => ['id = ? AND timestamp = ?', self.id, self.timestamp], :order => "version desc").instance_variable_get('@attributes'))
|
||||
@attributes.update(OldWay.where(:way_id => self.way_id, :timestamp => self.timestamp).order("version DESC").first.instance_variable_get('@attributes'))
|
||||
|
||||
# ok, you can touch from here on
|
||||
|
||||
|
@ -38,7 +42,7 @@ class OldWay < ActiveRecord::Base
|
|||
tag = OldWayTag.new
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.way_id = self.way_id
|
||||
tag.version = self.version
|
||||
tag.save!
|
||||
end
|
||||
|
@ -46,7 +50,7 @@ class OldWay < ActiveRecord::Base
|
|||
sequence = 1
|
||||
self.nds.each do |n|
|
||||
nd = OldWayNode.new
|
||||
nd.id = [self.id, self.version, sequence]
|
||||
nd.id = [self.way_id, self.version, sequence]
|
||||
nd.node_id = n
|
||||
nd.save!
|
||||
sequence += 1
|
||||
|
@ -55,20 +59,20 @@ class OldWay < ActiveRecord::Base
|
|||
|
||||
def nds
|
||||
unless @nds
|
||||
@nds = Array.new
|
||||
OldWayNode.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version], :order => "sequence_id").each do |nd|
|
||||
@nds += [nd.node_id]
|
||||
end
|
||||
@nds = Array.new
|
||||
OldWayNode.where(:way_id => self.way_id, :version => self.version).order(:sequence_id).each do |nd|
|
||||
@nds += [nd.node_id]
|
||||
end
|
||||
end
|
||||
@nds
|
||||
end
|
||||
|
||||
def tags
|
||||
unless @tags
|
||||
@tags = Hash.new
|
||||
OldWayTag.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version]).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
@tags = Hash.new
|
||||
OldWayTag.where(:way_id => self.way_id, :version => self.version).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
end
|
||||
@tags = Hash.new unless @tags
|
||||
@tags
|
||||
|
@ -82,20 +86,9 @@ class OldWay < ActiveRecord::Base
|
|||
@tags = t
|
||||
end
|
||||
|
||||
# has_many :way_nodes, :class_name => 'OldWayNode', :foreign_key => 'id'
|
||||
# has_many :way_tags, :class_name => 'OldWayTag', :foreign_key => 'id'
|
||||
|
||||
def old_nodes
|
||||
OldWayNode.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])
|
||||
end
|
||||
|
||||
def old_tags
|
||||
OldWayTag.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])
|
||||
end
|
||||
|
||||
def to_xml_node
|
||||
el1 = XML::Node.new 'way'
|
||||
el1['id'] = self.id.to_s
|
||||
el1['id'] = self.way_id.to_s
|
||||
el1['visible'] = self.visible.to_s
|
||||
el1['timestamp'] = self.timestamp.xmlschema
|
||||
if self.changeset.user.data_public?
|
||||
|
@ -128,23 +121,23 @@ class OldWay < ActiveRecord::Base
|
|||
# (i.e. is it visible? are we actually reverting to an earlier version?)
|
||||
|
||||
def get_nodes_undelete
|
||||
points = []
|
||||
self.nds.each do |n|
|
||||
node=Node.find(n)
|
||||
points << [node.lon, node.lat, n, node.version, node.tags_as_hash, node.visible]
|
||||
points = []
|
||||
self.nds.each do |n|
|
||||
node = Node.find(n)
|
||||
points << [node.lon, node.lat, n, node.version, node.tags_as_hash, node.visible]
|
||||
end
|
||||
points
|
||||
points
|
||||
end
|
||||
|
||||
def get_nodes_revert(timestamp)
|
||||
points=[]
|
||||
self.nds.each do |n|
|
||||
oldnode=OldNode.find(:first, :conditions=>['id=? AND timestamp<=?',n,timestamp], :order=>"timestamp DESC")
|
||||
curnode=Node.find(n)
|
||||
id=n; reuse=curnode.visible
|
||||
if oldnode.lat!=curnode.lat or oldnode.lon!=curnode.lon or oldnode.tags!=curnode.tags then
|
||||
oldnode = OldNode.where('node_id = ? AND timestamp <= ?', n, timestamp).order("timestamp DESC").first
|
||||
curnode = Node.find(n)
|
||||
id = n; reuse = curnode.visible
|
||||
if oldnode.lat != curnode.lat or oldnode.lon != curnode.lon or oldnode.tags != curnode.tags then
|
||||
# node has changed: if it's in other ways, give it a new id
|
||||
if curnode.ways-[self.id] then id=-1; reuse=false end
|
||||
if curnode.ways-[self.way_id] then id=-1; reuse=false end
|
||||
end
|
||||
points << [oldnode.lon, oldnode.lat, id, curnode.version, oldnode.tags_as_hash, reuse]
|
||||
end
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
class OldWayNode < ActiveRecord::Base
|
||||
set_table_name 'way_nodes'
|
||||
set_primary_keys :way_id, :version, :sequence_id
|
||||
|
||||
set_primary_keys :id, :version, :sequence_id
|
||||
|
||||
belongs_to :way, :foreign_key=> :id
|
||||
|
||||
# A bit messy, referring to current nodes, should do for the data browser for now
|
||||
belongs_to :old_way, :foreign_key => [:way_id, :version]
|
||||
# A bit messy, referring to current nodes and ways, should do for the data browser for now
|
||||
belongs_to :node
|
||||
belongs_to :way
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class OldWayTag < ActiveRecord::Base
|
||||
set_table_name 'way_tags'
|
||||
set_primary_keys :way_id, :version, :k
|
||||
|
||||
belongs_to :old_way, :foreign_key => [:id, :version]
|
||||
belongs_to :old_way, :foreign_key => [:way_id, :version]
|
||||
|
||||
validates_presence_of :id
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => [:k, :version]
|
||||
validates_numericality_of :id, :version, :only_integer => true
|
||||
validates_presence_of :old_way
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => [:way_id, :version]
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ class Relation < ActiveRecord::Base
|
|||
|
||||
belongs_to :changeset
|
||||
|
||||
has_many :old_relations, :foreign_key => 'id', :order => 'version'
|
||||
has_many :old_relations, :order => 'version'
|
||||
|
||||
has_many :relation_members, :foreign_key => 'id', :order => 'sequence_id'
|
||||
has_many :relation_tags, :foreign_key => 'id'
|
||||
has_many :relation_members, :order => 'sequence_id'
|
||||
has_many :relation_tags
|
||||
|
||||
has_many :containing_relation_members, :class_name => "RelationMember", :as => :member
|
||||
has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation, :extend => ObjectFinder
|
||||
|
@ -23,6 +23,12 @@ class Relation < ActiveRecord::Base
|
|||
validates_numericality_of :changeset_id, :version, :integer_only => true
|
||||
validates_associated :changeset
|
||||
|
||||
scope :visible, where(:visible => true)
|
||||
scope :invisible, where(:visible => false)
|
||||
scope :nodes, lambda { |*ids| joins(:relation_members).where(:current_relation_members => { :member_type => "Node", :member_id => ids }) }
|
||||
scope :ways, lambda { |*ids| joins(:relation_members).where(:current_relation_members => { :member_type => "Way", :member_id => ids }) }
|
||||
scope :relations, lambda { |*ids| joins(:relation_members).where(:current_relation_members => { :member_type => "Relation", :member_id => ids }) }
|
||||
|
||||
TYPES = ["node", "way", "relation"]
|
||||
|
||||
def self.from_xml(xml, create=false)
|
||||
|
@ -148,36 +154,6 @@ class Relation < ActiveRecord::Base
|
|||
return el1
|
||||
end
|
||||
|
||||
def self.find_for_nodes(ids, options = {})
|
||||
if ids.empty?
|
||||
return []
|
||||
else
|
||||
self.with_scope(:find => { :joins => "INNER JOIN current_relation_members AS crm ON crm.id = current_relations.id", :conditions => "crm.member_type = 'Node' AND crm.member_id IN (#{ids.join(',')})" }) do
|
||||
return self.find(:all, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.find_for_ways(ids, options = {})
|
||||
if ids.empty?
|
||||
return []
|
||||
else
|
||||
self.with_scope(:find => { :joins => "INNER JOIN current_relation_members AS crm ON crm.id = current_relations.id", :conditions => "crm.member_type = 'Way' AND crm.member_id IN (#{ids.join(',')})" }) do
|
||||
return self.find(:all, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.find_for_relations(ids, options = {})
|
||||
if ids.empty?
|
||||
return []
|
||||
else
|
||||
self.with_scope(:find => { :joins => "INNER JOIN current_relation_members AS crm ON crm.id = current_relations.id", :conditions => "crm.member_type = 'Relation' AND crm.member_id IN (#{ids.join(',')})" }) do
|
||||
return self.find(:all, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# FIXME is this really needed?
|
||||
def members
|
||||
unless @members
|
||||
|
@ -244,8 +220,7 @@ class Relation < ActiveRecord::Base
|
|||
self.lock!
|
||||
check_consistency(self, new_relation, user)
|
||||
# This will check to see if this relation is used by another relation
|
||||
rel = RelationMember.find(:first, :joins => :relation,
|
||||
:conditions => [ "visible = ? AND member_type='Relation' and member_id=? ", true, self.id ])
|
||||
rel = RelationMember.joins(:relation).where("visible = ? AND member_type = 'Relation' and member_id = ? ", true, self.id).first
|
||||
raise OSM::APIPreconditionFailedError.new("The relation #{new_relation.id} is used in relation #{rel.relation.id}.") unless rel.nil?
|
||||
|
||||
self.changeset_id = new_relation.changeset_id
|
||||
|
@ -303,7 +278,7 @@ class Relation < ActiveRecord::Base
|
|||
# use reflection to look up the appropriate class
|
||||
model = Kernel.const_get(m[0].capitalize)
|
||||
# get the element with that ID
|
||||
element = model.find(:first, :conditions =>["id = ?", m[1]])
|
||||
element = model.where(:id => m[1]).first
|
||||
|
||||
# and check that it is OK to use.
|
||||
unless element and element.visible? and element.preconditions_ok?
|
||||
|
@ -373,12 +348,12 @@ class Relation < ActiveRecord::Base
|
|||
# if there are left-over tags then they are new and will have to
|
||||
# be added.
|
||||
tags_changed |= (not tags.empty?)
|
||||
RelationTag.delete_all(:id => self.id)
|
||||
RelationTag.delete_all(:relation_id => self.id)
|
||||
self.tags.each do |k,v|
|
||||
tag = RelationTag.new
|
||||
tag.relation_id = self.id
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.save!
|
||||
end
|
||||
|
||||
|
@ -403,10 +378,11 @@ class Relation < ActiveRecord::Base
|
|||
# members may be in a different order and i don't feel like implementing
|
||||
# a longest common subsequence algorithm to optimise this.
|
||||
members = self.members
|
||||
RelationMember.delete_all(:id => self.id)
|
||||
RelationMember.delete_all(:relation_id => self.id)
|
||||
members.each_with_index do |m,i|
|
||||
mem = RelationMember.new
|
||||
mem.id = [self.id, i]
|
||||
mem.relation_id = self.id
|
||||
mem.sequence_id = i
|
||||
mem.member_type = m[0]
|
||||
mem.member_id = m[1]
|
||||
mem.member_role = m[2]
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
class RelationMember < ActiveRecord::Base
|
||||
set_table_name 'current_relation_members'
|
||||
|
||||
set_primary_keys :id, :sequence_id
|
||||
set_table_name 'current_relation_members'
|
||||
set_primary_keys :relation_id, :sequence_id
|
||||
|
||||
belongs_to :relation
|
||||
belongs_to :member, :polymorphic => true
|
||||
belongs_to :relation, :foreign_key => :id
|
||||
|
||||
def after_find
|
||||
self[:member_class] = self.member_type.classify
|
||||
end
|
||||
|
||||
def after_initialize
|
||||
self[:member_class] = self.member_type.classify unless self.member_type.nil?
|
||||
end
|
||||
|
||||
def before_save
|
||||
self.member_type = self[:member_class].classify
|
||||
end
|
||||
after_find :set_class_from_type
|
||||
after_initialize :set_class_from_type
|
||||
before_save :set_type_from_class
|
||||
|
||||
def member_type=(type)
|
||||
self[:member_type] = type
|
||||
self[:member_class] = type.capitalize
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_class_from_type
|
||||
self[:member_class] = self.member_type.classify unless self.member_type.nil?
|
||||
end
|
||||
|
||||
def set_type_from_class
|
||||
self.member_type = self[:member_class].classify
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class RelationTag < ActiveRecord::Base
|
||||
set_table_name 'current_relation_tags'
|
||||
set_primary_keys :relation_id, :k
|
||||
|
||||
belongs_to :relation, :foreign_key => 'id'
|
||||
belongs_to :relation
|
||||
|
||||
validates_presence_of :id
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => :k
|
||||
validates_numericality_of :id, :only_integer => true
|
||||
validates_presence_of :relation
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => :relation_id
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ class RequestToken < OauthToken
|
|||
return false if authorized?
|
||||
self.user = user
|
||||
self.authorized_at = Time.now
|
||||
self.verifier = OAuth::Helper.generate_key(16)[0,20] unless oauth10?
|
||||
self.verifier = OAuth::Helper.generate_key(20)[0,20] unless oauth10?
|
||||
self.save
|
||||
end
|
||||
|
||||
|
@ -36,7 +36,7 @@ class RequestToken < OauthToken
|
|||
end
|
||||
|
||||
def oob?
|
||||
self.callback_url=='oob'
|
||||
callback_url.nil? || callback_url.downcase == 'oob'
|
||||
end
|
||||
|
||||
def oauth10?
|
||||
|
|
|
@ -3,9 +3,9 @@ class SpamObserver < ActiveRecord::Observer
|
|||
|
||||
def after_save(record)
|
||||
case
|
||||
when record.is_a?(User): user = record
|
||||
when record.is_a?(DiaryEntry): user = record.user
|
||||
when record.is_a?(DiaryComment): user = record.user
|
||||
when record.is_a?(User) then user = record
|
||||
when record.is_a?(DiaryEntry) then user = record.user
|
||||
when record.is_a?(DiaryComment) then user = record.user
|
||||
end
|
||||
|
||||
if user.status == "active" and user.spam_score > SPAM_THRESHOLD
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
class Trace < ActiveRecord::Base
|
||||
set_table_name 'gpx_files'
|
||||
|
||||
belongs_to :user
|
||||
has_many :tags, :class_name => 'Tracetag', :foreign_key => 'gpx_id', :dependent => :delete_all
|
||||
has_many :points, :class_name => 'Tracepoint', :foreign_key => 'gpx_id', :dependent => :delete_all
|
||||
|
||||
scope :visible, where(:visible => true)
|
||||
scope :visible_to, lambda { |u| visible.where("visibility IN ('public', 'identifiable') OR user_id = ?", u) }
|
||||
scope :public, where(:visibility => ["public", "identifiable"])
|
||||
|
||||
validates_presence_of :user_id, :name, :timestamp
|
||||
validates_presence_of :description, :on => :create
|
||||
validates_length_of :name, :maximum => 255
|
||||
|
@ -9,10 +17,6 @@ class Trace < ActiveRecord::Base
|
|||
validates_inclusion_of :inserted, :in => [ true, false ]
|
||||
validates_inclusion_of :visibility, :in => ["private", "public", "trackable", "identifiable"]
|
||||
|
||||
belongs_to :user
|
||||
has_many :tags, :class_name => 'Tracetag', :foreign_key => 'gpx_id', :dependent => :delete_all
|
||||
has_many :points, :class_name => 'Tracepoint', :foreign_key => 'gpx_id', :dependent => :delete_all
|
||||
|
||||
def destroy
|
||||
super
|
||||
FileUtils.rm_f(trace_name)
|
||||
|
@ -262,8 +266,8 @@ class Trace < ActiveRecord::Base
|
|||
# If there are any existing points for this trace then delete
|
||||
# them - we check for existing points first to avoid locking
|
||||
# the table in the common case where there aren't any.
|
||||
if Tracepoint.find(:first, :conditions => ['gpx_id = ?', self.id])
|
||||
Tracepoint.delete_all(['gpx_id = ?', self.id])
|
||||
if Tracepoint.where(:gpx_id => self.id).exists?
|
||||
Tracepoint.delete_all(:gpx_id => self.id)
|
||||
end
|
||||
|
||||
gpx.points do |point|
|
||||
|
|
|
@ -8,6 +8,7 @@ class User < ActiveRecord::Base
|
|||
has_many :new_messages, :class_name => "Message", :foreign_key => :to_user_id, :conditions => { :to_user_visible => true, :message_read => false }, :order => 'sent_on DESC'
|
||||
has_many :sent_messages, :class_name => "Message", :foreign_key => :from_user_id, :conditions => { :from_user_visible => true }, :order => 'sent_on DESC'
|
||||
has_many :friends, :include => :befriendee, :conditions => "users.status IN ('active', 'confirmed')"
|
||||
has_many :friend_users, :through => :friends, :source => :befriendee
|
||||
has_many :tokens, :class_name => "UserToken"
|
||||
has_many :preferences, :class_name => "UserPreference"
|
||||
has_many :changesets, :order => 'created_at DESC'
|
||||
|
@ -15,14 +16,18 @@ class User < ActiveRecord::Base
|
|||
has_many :client_applications
|
||||
has_many :oauth_tokens, :class_name => "OauthToken", :order => "authorized_at desc", :include => [:client_application]
|
||||
|
||||
has_many :active_blocks, :class_name => "UserBlock", :conditions => ['user_blocks.ends_at > \'#{Time.now.getutc.xmlschema(5)}\' or user_blocks.needs_view']
|
||||
has_many :active_blocks, :class_name => "UserBlock", :conditions => proc { [ "user_blocks.ends_at > :ends_at or user_blocks.needs_view", { :ends_at => Time.now.getutc } ] }
|
||||
has_many :roles, :class_name => "UserRole"
|
||||
|
||||
scope :visible, where(:status => ["pending", "active", "confirmed"])
|
||||
scope :active, where(:status => ["active", "confirmed"])
|
||||
scope :public, where(:data_public => true)
|
||||
|
||||
validates_presence_of :email, :display_name
|
||||
validates_confirmation_of :email#, :message => ' addresses must match'
|
||||
validates_confirmation_of :pass_crypt#, :message => ' must match the confirmation password'
|
||||
validates_uniqueness_of :display_name, :allow_nil => true
|
||||
validates_uniqueness_of :email
|
||||
validates_uniqueness_of :display_name, :allow_nil => true, :case_sensitive => false, :if => Proc.new { |u| u.display_name_changed? }
|
||||
validates_uniqueness_of :email, :case_sensitive => false, :if => Proc.new { |u| u.email_changed? }
|
||||
validates_uniqueness_of :openid_url, :allow_nil => true
|
||||
validates_length_of :pass_crypt, :within => 8..255
|
||||
validates_length_of :display_name, :within => 3..255, :allow_nil => true
|
||||
|
@ -36,27 +41,26 @@ class User < ActiveRecord::Base
|
|||
validates_numericality_of :home_zoom, :only_integer => true, :allow_nil => true
|
||||
validates_inclusion_of :preferred_editor, :in => Editors::ALL_EDITORS, :allow_nil => true
|
||||
|
||||
after_initialize :set_creation_time
|
||||
before_save :encrypt_password
|
||||
|
||||
file_column :image, :magick => { :geometry => "100x100>" }
|
||||
|
||||
def after_initialize
|
||||
self.creation_time = Time.now.getutc unless self.attribute_present?(:creation_time)
|
||||
end
|
||||
|
||||
def encrypt_password
|
||||
if pass_crypt_confirmation
|
||||
self.pass_salt = OSM::make_token(8)
|
||||
self.pass_crypt = OSM::encrypt_password(pass_crypt, pass_salt)
|
||||
end
|
||||
end
|
||||
|
||||
def self.authenticate(options)
|
||||
if options[:username] and options[:password]
|
||||
user = find(:first, :conditions => ["email = ? OR display_name = ?", options[:username], options[:username]])
|
||||
user = where("email = ? OR display_name = ?", options[:username], options[:username]).first
|
||||
|
||||
if user.nil?
|
||||
users = where("LOWER(email) = LOWER(?) OR LOWER(display_name) = LOWER(?)", options[:username], options[:username])
|
||||
|
||||
if users.count == 1
|
||||
user = users.first
|
||||
end
|
||||
end
|
||||
|
||||
user = nil if user and user.pass_crypt != OSM::encrypt_password(options[:password], user.pass_salt)
|
||||
elsif options[:token]
|
||||
token = UserToken.find(:first, :include => :user, :conditions => ["user_tokens.token = ?", options[:token]])
|
||||
token = UserToken.find_by_token(options[:token])
|
||||
user = token.user if token
|
||||
end
|
||||
|
||||
|
@ -101,7 +105,7 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def preferred_language
|
||||
languages.find { |l| Language.find(:first, :conditions => { :code => l }) }
|
||||
languages.find { |l| Language.exists?(:code => l) }
|
||||
end
|
||||
|
||||
def preferred_language_from(array)
|
||||
|
@ -113,9 +117,7 @@ class User < ActiveRecord::Base
|
|||
gc = OSM::GreatCircle.new(self.home_lat, self.home_lon)
|
||||
bounds = gc.bounds(radius)
|
||||
sql_for_distance = gc.sql_for_distance("home_lat", "home_lon")
|
||||
nearby = User.find(:all,
|
||||
:conditions => ["id != ? AND status IN (\'active\', \'confirmed\') AND data_public = ? AND #{sql_for_distance} <= ?", id, true, radius],
|
||||
:order => sql_for_distance, :limit => num)
|
||||
nearby = User.where("id != ? AND status IN (\'active\', \'confirmed\') AND data_public = ? AND #{sql_for_distance} <= ?", id, true, radius).order(sql_for_distance).limit(num)
|
||||
else
|
||||
nearby = []
|
||||
end
|
||||
|
@ -191,8 +193,8 @@ class User < ActiveRecord::Base
|
|||
##
|
||||
# return a spam score for a user
|
||||
def spam_score
|
||||
changeset_score = self.changesets.find(:all, :limit => 10).length * 50
|
||||
trace_score = self.traces.find(:all, :limit => 10).length * 50
|
||||
changeset_score = self.changesets.limit(10).length * 50
|
||||
trace_score = self.traces.limit(10).length * 50
|
||||
diary_entry_score = self.diary_entries.inject(0) { |s,e| s += OSM.spam_score(e.body) }
|
||||
diary_comment_score = self.diary_comments.inject(0) { |s,e| s += OSM.spam_score(e.body) }
|
||||
|
||||
|
@ -210,4 +212,17 @@ class User < ActiveRecord::Base
|
|||
def access_token(application_key)
|
||||
return ClientApplication.find_by_key(application_key).access_token_for_user(self)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_creation_time
|
||||
self.creation_time = Time.now.getutc unless self.attribute_present?(:creation_time)
|
||||
end
|
||||
|
||||
def encrypt_password
|
||||
if pass_crypt_confirmation
|
||||
self.pass_salt = OSM::make_token(8)
|
||||
self.pass_crypt = OSM::encrypt_password(pass_crypt, pass_salt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ class UserBlock < ActiveRecord::Base
|
|||
# block. this should be caught and dealt with in the controller,
|
||||
# but i've also included it here just in case.
|
||||
def moderator_permissions
|
||||
errors.add_to_base(I18n.t('user_block.model.non_moderator_update')) if creator_id_changed? and !creator.moderator?
|
||||
errors.add_to_base(I18n.t('user_block.model.non_moderator_revoke')) unless revoker_id.nil? or revoker.moderator?
|
||||
errors.add(:base, I18n.t('user_block.model.non_moderator_update')) if creator_id_changed? and !creator.moderator?
|
||||
errors.add(:base, I18n.t('user_block.model.non_moderator_revoke')) unless revoker_id.nil? or revoker.moderator?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
class UserToken < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
|
||||
def after_initialize
|
||||
after_initialize :set_defaults
|
||||
|
||||
private
|
||||
|
||||
def set_defaults
|
||||
self.token = OSM::make_token() if self.token.blank?
|
||||
self.expiry = 1.week.from_now if self.expiry.blank?
|
||||
end
|
||||
|
|
|
@ -7,12 +7,12 @@ class Way < ActiveRecord::Base
|
|||
|
||||
belongs_to :changeset
|
||||
|
||||
has_many :old_ways, :foreign_key => 'id', :order => 'version'
|
||||
has_many :old_ways, :order => 'version'
|
||||
|
||||
has_many :way_nodes, :foreign_key => 'id', :order => 'sequence_id'
|
||||
has_many :way_nodes, :order => 'sequence_id'
|
||||
has_many :nodes, :through => :way_nodes, :order => 'sequence_id'
|
||||
|
||||
has_many :way_tags, :foreign_key => 'id'
|
||||
has_many :way_tags
|
||||
|
||||
has_many :containing_relation_members, :class_name => "RelationMember", :as => :member
|
||||
has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation, :extend => ObjectFinder
|
||||
|
@ -25,6 +25,9 @@ class Way < ActiveRecord::Base
|
|||
validates_numericality_of :id, :on => :update, :integer_only => true
|
||||
validates_associated :changeset
|
||||
|
||||
scope :visible, where(:visible => true)
|
||||
scope :invisible, where(:visible => false)
|
||||
|
||||
# Read in xml as text and return it's Way object representation
|
||||
def self.from_xml(xml, create=false)
|
||||
begin
|
||||
|
@ -202,7 +205,7 @@ class Way < ActiveRecord::Base
|
|||
def bbox
|
||||
lons = nodes.collect { |n| n.longitude }
|
||||
lats = nodes.collect { |n| n.latitude }
|
||||
[ lons.min, lats.min, lons.max, lats.max ]
|
||||
BoundingBox.new(lons.min, lats.min, lons.max, lats.max)
|
||||
end
|
||||
|
||||
def update_from(new_way, user)
|
||||
|
@ -243,7 +246,7 @@ class Way < ActiveRecord::Base
|
|||
new_nds = (self.nds - old_nodes).sort.uniq
|
||||
|
||||
unless new_nds.empty?
|
||||
db_nds = Node.find(:all, :conditions => { :id => new_nds, :visible => true })
|
||||
db_nds = Node.where(:id => new_nds, :visible => true)
|
||||
|
||||
if db_nds.length < new_nds.length
|
||||
missing = new_nds - db_nds.collect { |n| n.id }
|
||||
|
@ -265,10 +268,9 @@ class Way < ActiveRecord::Base
|
|||
Way.transaction do
|
||||
self.lock!
|
||||
check_consistency(self, new_way, user)
|
||||
rel = RelationMember.find(:first, :joins => :relation,
|
||||
:conditions => [ "visible = ? AND member_type='Way' and member_id=? ", true, self.id])
|
||||
raise OSM::APIPreconditionFailedError.new("Way #{self.id} still used by relation #{rel.relation.id}.") if rel
|
||||
|
||||
rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Way", :member_id => id }).order(:id)
|
||||
raise OSM::APIPreconditionFailedError.new("Way #{self.id} is still used by relations #{rels.collect { |r| r.id }.join(",")}.") unless rels.empty?
|
||||
|
||||
self.changeset_id = new_way.changeset_id
|
||||
self.changeset = new_way.changeset
|
||||
|
||||
|
@ -318,17 +320,17 @@ class Way < ActiveRecord::Base
|
|||
self.save!
|
||||
|
||||
tags = self.tags
|
||||
WayTag.delete_all(['id = ?', self.id])
|
||||
WayTag.delete_all(:way_id => self.id)
|
||||
tags.each do |k,v|
|
||||
tag = WayTag.new
|
||||
tag.way_id = self.id
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.save!
|
||||
end
|
||||
|
||||
nds = self.nds
|
||||
WayNode.delete_all(['id = ?', self.id])
|
||||
WayNode.delete_all(:way_id => self.id)
|
||||
sequence = 1
|
||||
nds.each do |n|
|
||||
nd = WayNode.new
|
||||
|
@ -356,5 +358,4 @@ class Way < ActiveRecord::Base
|
|||
cs.save!
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
class WayNode < ActiveRecord::Base
|
||||
set_table_name 'current_way_nodes'
|
||||
set_primary_keys :way_id, :sequence_id
|
||||
|
||||
set_primary_keys :id, :sequence_id
|
||||
belongs_to :way
|
||||
belongs_to :node
|
||||
|
||||
belongs_to :way, :foreign_key => :id
|
||||
end
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
class WayTag < ActiveRecord::Base
|
||||
set_table_name 'current_way_tags'
|
||||
set_primary_keys :way_id, :k
|
||||
|
||||
# False multipart keys. The following would be a hack:
|
||||
# set_primary_keys :id, :k, :v
|
||||
# FIXME add a real multipart key to waytags so that we can do eager loadin
|
||||
|
||||
belongs_to :way, :foreign_key => 'id'
|
||||
belongs_to :way
|
||||
|
||||
validates_presence_of :id
|
||||
validates_length_of :k, :v, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :id, :scope => :k
|
||||
validates_numericality_of :id, :only_integer => true
|
||||
validates_presence_of :way
|
||||
validates_length_of :k, :maximum => 255, :allow_blank => true
|
||||
validates_uniqueness_of :k, :scope => :way_id
|
||||
validates_length_of :v, :maximum => 255, :allow_blank => true
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue