Merge branch 'master' into moderation
2
.mailmap
|
@ -5,4 +5,6 @@ Grant Slater <openstreetmap@firefishy.com> <github@firefishy.com>
|
|||
Harry Wood <git@harrywood.co.uk> <mail@harrywood.co.uk> <github@onlineanimals.co.uk>
|
||||
Kai Krueger <kakrueger@gmail.com> <kai@aiputerlx.(none)>
|
||||
Michael Glanznig <nebulon42@yandex.com>
|
||||
Petr Kadlec <mormegil@centrum.cz>
|
||||
Richard Fairhurst <richard@systemeD.net> <richard@systemed.net>
|
||||
Simon Poole <simon@poole.ch> <simon@rails-dev.poole.ch>
|
||||
|
|
49
.rubocop.yml
|
@ -1,20 +1,44 @@
|
|||
inherit_from: .rubocop_todo.yml
|
||||
|
||||
AllCops:
|
||||
Include:
|
||||
- '**/*.gemspec'
|
||||
- '**/*.podspec'
|
||||
- '**/*.jbuilder'
|
||||
- '**/*.rake'
|
||||
- '**/*.opal'
|
||||
- '**/config.ru'
|
||||
- '**/Gemfile'
|
||||
- '**/Rakefile'
|
||||
- '**/Capfile'
|
||||
- '**/Guardfile'
|
||||
- '**/Podfile'
|
||||
- '**/Thorfile'
|
||||
- '**/Vagrantfile'
|
||||
- '**/Berksfile'
|
||||
- '**/Cheffile'
|
||||
- '**/Vagabondfile'
|
||||
- '**/Fastfile'
|
||||
- '**/*.builder'
|
||||
|
||||
Rails:
|
||||
Enabled: true
|
||||
|
||||
Layout/ExtraSpacing:
|
||||
AllowForAlignment: true
|
||||
|
||||
Style/BracesAroundHashParameters:
|
||||
EnforcedStyle: context_dependent
|
||||
|
||||
Style/ExtraSpacing:
|
||||
AllowForAlignment: true
|
||||
|
||||
Style/FileName:
|
||||
Exclude:
|
||||
- 'script/deliver-message'
|
||||
- 'script/locale/reload-languages'
|
||||
- 'script/update-spam-blocks'
|
||||
|
||||
Style/FormatStringToken:
|
||||
EnforcedStyle: template
|
||||
|
||||
Style/IfInsideElse:
|
||||
Enabled: false
|
||||
|
||||
|
@ -33,3 +57,22 @@ Style/HashSyntax:
|
|||
|
||||
Style/StringLiterals:
|
||||
EnforcedStyle: double_quotes
|
||||
|
||||
Style/SymbolArray:
|
||||
EnforcedStyle: brackets
|
||||
|
||||
Rails/ApplicationRecord:
|
||||
Enabled: false
|
||||
|
||||
Rails/HttpPositionalArguments:
|
||||
Enabled: false
|
||||
|
||||
Rails/SkipsModelValidations:
|
||||
Exclude:
|
||||
- 'db/migrate/*.rb'
|
||||
- 'app/controllers/user_controller.rb'
|
||||
|
||||
Lint/PercentStringArray:
|
||||
Exclude:
|
||||
- 'config/initializers/secure_headers.rb'
|
||||
- 'app/controllers/site_controller.rb'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2016-07-13 09:47:52 +0100 using RuboCop version 0.41.2.
|
||||
# on 2016-10-20 21:45:27 +0100 using RuboCop version 0.44.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
|
@ -14,11 +14,11 @@ Lint/AmbiguousOperator:
|
|||
- 'test/lib/bounding_box_test.rb'
|
||||
- 'test/lib/country_test.rb'
|
||||
|
||||
# Offense count: 115
|
||||
# Offense count: 117
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 29
|
||||
# Offense count: 30
|
||||
# Configuration parameters: AllowSafeAssignment.
|
||||
Lint/AssignmentInCondition:
|
||||
Exclude:
|
||||
|
@ -43,30 +43,40 @@ Lint/HandleExceptions:
|
|||
- 'app/controllers/user_controller.rb'
|
||||
- 'config/initializers/session.rb'
|
||||
|
||||
# Offense count: 616
|
||||
Metrics/AbcSize:
|
||||
Max: 277
|
||||
# Offense count: 2
|
||||
Lint/ShadowingOuterLocalVariable:
|
||||
Exclude:
|
||||
- 'app/views/changeset/list.atom.builder'
|
||||
|
||||
# Offense count: 11
|
||||
# Offense count: 630
|
||||
Metrics/AbcSize:
|
||||
Max: 280
|
||||
|
||||
# Offense count: 35
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/BlockLength:
|
||||
Max: 295
|
||||
|
||||
# Offense count: 12
|
||||
Metrics/BlockNesting:
|
||||
Max: 5
|
||||
|
||||
# Offense count: 62
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 1650
|
||||
Max: 1790
|
||||
|
||||
# Offense count: 67
|
||||
# Offense count: 69
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 20
|
||||
|
||||
# Offense count: 2485
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
|
||||
# Offense count: 2826
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
Max: 962
|
||||
Max: 1072
|
||||
|
||||
# Offense count: 596
|
||||
# Offense count: 612
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 179
|
||||
|
@ -74,14 +84,14 @@ Metrics/MethodLength:
|
|||
# Offense count: 1
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ModuleLength:
|
||||
Max: 139
|
||||
Max: 147
|
||||
|
||||
# Offense count: 4
|
||||
# Configuration parameters: CountKeywordArgs.
|
||||
Metrics/ParameterLists:
|
||||
Max: 9
|
||||
|
||||
# Offense count: 70
|
||||
# Offense count: 71
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 23
|
||||
|
||||
|
@ -101,6 +111,17 @@ Rails/HasAndBelongsToMany:
|
|||
- 'app/models/changeset.rb'
|
||||
- 'app/models/user.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Configuration parameters: Include.
|
||||
# Include: db/migrate/*.rb
|
||||
Rails/NotNullColumn:
|
||||
Exclude:
|
||||
- 'db/migrate/002_cleanup_osm_db.rb'
|
||||
- 'db/migrate/020_populate_node_tags_and_remove.rb'
|
||||
- 'db/migrate/021_move_to_innodb.rb'
|
||||
- 'db/migrate/025_add_end_time_to_changesets.rb'
|
||||
- 'db/migrate/20120404205604_add_user_and_description_to_redaction.rb'
|
||||
|
||||
# Offense count: 17
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
|
@ -115,7 +136,7 @@ Rails/OutputSafety:
|
|||
- 'lib/rich_text.rb'
|
||||
- 'test/helpers/application_helper_test.rb'
|
||||
|
||||
# Offense count: 65
|
||||
# Offense count: 74
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: strict, flexible
|
||||
Rails/TimeZone:
|
||||
|
@ -135,10 +156,17 @@ Style/AsciiComments:
|
|||
Exclude:
|
||||
- 'test/models/message_test.rb'
|
||||
|
||||
# Offense count: 217
|
||||
# Offense count: 220
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: MaxLineLength.
|
||||
Style/IfUnlessModifier:
|
||||
Exclude:
|
||||
- 'app/controllers/way_controller.rb'
|
||||
|
||||
# Offense count: 60
|
||||
# Cop supports --auto-correct.
|
||||
Style/LineEndConcatenation:
|
||||
|
@ -154,22 +182,11 @@ Style/LineEndConcatenation:
|
|||
- 'test/controllers/relation_controller_test.rb'
|
||||
- 'test/controllers/way_controller_test.rb'
|
||||
|
||||
# Offense count: 69
|
||||
# Offense count: 71
|
||||
# Cop supports --auto-correct.
|
||||
Style/NumericLiterals:
|
||||
MinDigits: 11
|
||||
|
||||
# Offense count: 38
|
||||
# Cop supports --auto-correct.
|
||||
Style/PerlBackrefs:
|
||||
Exclude:
|
||||
- 'app/controllers/amf_controller.rb'
|
||||
- 'app/helpers/browse_helper.rb'
|
||||
- 'config/initializers/paperclip.rb'
|
||||
- 'lib/id.rb'
|
||||
- 'lib/potlatch.rb'
|
||||
- 'test/lib/i18n_test.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
|
||||
# NamePrefix: is_, has_, have_
|
||||
|
@ -197,15 +214,3 @@ Style/RaiseArgs:
|
|||
Style/RescueModifier:
|
||||
Exclude:
|
||||
- 'app/helpers/browse_helper.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: single_quotes, double_quotes
|
||||
Style/StringLiteralsInInterpolation:
|
||||
Exclude:
|
||||
- 'app/controllers/amf_controller.rb'
|
||||
- 'app/models/node.rb'
|
||||
- 'app/models/way.rb'
|
||||
- 'lib/migrate.rb'
|
||||
- 'test/controllers/changeset_controller_test.rb'
|
||||
|
|
|
@ -26,4 +26,4 @@ before_script:
|
|||
script:
|
||||
- bundle exec rubocop -f fuubar
|
||||
- bundle exec rake jshint
|
||||
- bundle exec rake test
|
||||
- bundle exec rake test:db
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
When writing code it is generally a good idea to try and match your
|
||||
formatting to that of any existing code in the same file, or to other
|
||||
similar files if you are writing new code. Consistency of layout is
|
||||
far more important that the layout itself as it makes reading code
|
||||
far more important than the layout itself as it makes reading code
|
||||
much easier.
|
||||
|
||||
One golden rule of formatting -- please don't use tabs in your code
|
||||
|
|
65
Gemfile
|
@ -1,7 +1,7 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
# Require rails
|
||||
gem "rails", "4.2.7"
|
||||
gem "rails", "5.0.4"
|
||||
|
||||
# Require things which have moved to gems in ruby 1.9
|
||||
gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19
|
||||
|
@ -22,7 +22,7 @@ gem "sass-rails", "~> 5.0"
|
|||
gem "uglifier", ">= 1.3.0"
|
||||
|
||||
# Use CoffeeScript for .js.coffee assets and views
|
||||
gem "coffee-rails", "~> 4.1.0"
|
||||
gem "coffee-rails", "~> 4.2"
|
||||
|
||||
# Use jquery as the JavaScript library
|
||||
gem "jquery-rails"
|
||||
|
@ -38,32 +38,34 @@ gem "r2"
|
|||
gem "autoprefixer-rails"
|
||||
|
||||
# Use image_optim to optimise images
|
||||
gem "image_optim", ">= 0.22.0"
|
||||
gem "image_optim_rails"
|
||||
|
||||
# Load rails plugins
|
||||
gem "rails-i18n", "~> 4.0.0"
|
||||
gem "dynamic_form"
|
||||
gem "rinku", ">= 1.2.2", :require => "rails_rinku"
|
||||
gem "oauth-plugin", ">= 0.5.1"
|
||||
gem "validates_email_format_of", ">= 1.5.1"
|
||||
gem "composite_primary_keys", "~> 8.1.0"
|
||||
gem "http_accept_language", "~> 2.0.0"
|
||||
gem "paperclip", "~> 4.0"
|
||||
gem "deadlock_retry", ">= 1.2.0"
|
||||
gem "i18n-js", ">= 3.0.0.rc10"
|
||||
gem "rack-cors"
|
||||
gem "actionpack-page_caching"
|
||||
gem "composite_primary_keys", "~> 9.0.7"
|
||||
gem "deadlock_retry", ">= 1.2.0"
|
||||
gem "dynamic_form"
|
||||
gem "http_accept_language", "~> 2.0.0"
|
||||
gem "i18n-js", ">= 3.0.0"
|
||||
gem "oauth-plugin", ">= 0.5.1"
|
||||
gem "paperclip", "~> 4.0"
|
||||
gem "rack-cors"
|
||||
gem "rails-i18n", "~> 4.0.0"
|
||||
gem "record_tag_helper"
|
||||
gem "rinku", ">= 1.2.2", :require => "rails_rinku"
|
||||
gem "validates_email_format_of", ">= 1.5.1"
|
||||
|
||||
# Sanitise URIs
|
||||
gem "rack-uri_sanitizer"
|
||||
|
||||
# Omniauth for authentication
|
||||
gem "omniauth"
|
||||
gem "omniauth-openid"
|
||||
gem "omniauth-google-oauth2", ">= 0.2.7"
|
||||
gem "omniauth-facebook"
|
||||
gem "omniauth-windowslive"
|
||||
gem "omniauth-github"
|
||||
gem "omniauth-google-oauth2", ">= 0.2.7"
|
||||
gem "omniauth-mediawiki", ">= 0.0.3"
|
||||
gem "omniauth-openid"
|
||||
gem "omniauth-windowslive"
|
||||
|
||||
# Markdown formatting support
|
||||
gem "redcarpet"
|
||||
|
@ -75,8 +77,8 @@ gem "aasm"
|
|||
gem "libxml-ruby", ">= 2.0.5", :require => "libxml"
|
||||
|
||||
# Use for HTML sanitisation
|
||||
gem "sanitize"
|
||||
gem "htmlentities"
|
||||
gem "sanitize"
|
||||
|
||||
# Load SystemTimer for implementing request timeouts
|
||||
gem "SystemTimer", ">= 1.1.3", :require => "system_timer", :platforms => :ruby_18
|
||||
|
@ -84,33 +86,44 @@ gem "SystemTimer", ">= 1.1.3", :require => "system_timer", :platforms => :ruby_1
|
|||
# Load faraday for mockable HTTP client
|
||||
gem "faraday"
|
||||
|
||||
# Load httpclient and soap4r for SOAP support for Quova GeoIP queries
|
||||
gem "httpclient"
|
||||
gem "soap4r-ruby1.9"
|
||||
# Load geoip for querying Maxmind GeoIP database
|
||||
gem "geoip"
|
||||
|
||||
# Load rotp to generate TOTP tokens
|
||||
gem "rotp"
|
||||
|
||||
# Load memcache client in case we are using it
|
||||
gem "dalli"
|
||||
gem "kgio"
|
||||
|
||||
# Load secure_headers for Content-Security-Policy support
|
||||
gem "secure_headers"
|
||||
|
||||
# Load canonical-rails to generate canonical URLs
|
||||
gem "canonical-rails"
|
||||
|
||||
# Used to generate logstash friendly log files
|
||||
gem "logstasher"
|
||||
|
||||
# Gems useful for development
|
||||
group :development do
|
||||
gem "listen"
|
||||
gem "vendorer"
|
||||
end
|
||||
|
||||
# Gems needed for running tests
|
||||
group :test do
|
||||
gem "rubocop"
|
||||
gem "timecop"
|
||||
gem "minitest", "~> 5.1", :platforms => [:ruby_19, :ruby_20]
|
||||
gem "rails-controller-testing"
|
||||
gem "rubocop"
|
||||
gem "webmock"
|
||||
end
|
||||
|
||||
# Needed in development as well so rake can see konacha tasks
|
||||
group :development, :test do
|
||||
gem "jshint"
|
||||
gem "konacha"
|
||||
gem "poltergeist"
|
||||
gem "coveralls", :require => false
|
||||
gem "factory_girl_rails"
|
||||
gem "jshint"
|
||||
# gem "konacha"
|
||||
gem "poltergeist"
|
||||
end
|
||||
|
|
381
Gemfile.lock
|
@ -3,79 +3,84 @@ GEM
|
|||
specs:
|
||||
SystemTimer (1.2.3)
|
||||
aasm (4.1.0)
|
||||
actionmailer (4.2.7)
|
||||
actionpack (= 4.2.7)
|
||||
actionview (= 4.2.7)
|
||||
activejob (= 4.2.7)
|
||||
actioncable (5.0.4)
|
||||
actionpack (= 5.0.4)
|
||||
nio4r (>= 1.2, < 3.0)
|
||||
websocket-driver (~> 0.6.1)
|
||||
actionmailer (5.0.4)
|
||||
actionpack (= 5.0.4)
|
||||
actionview (= 5.0.4)
|
||||
activejob (= 5.0.4)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
actionpack (4.2.7)
|
||||
actionview (= 4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.0.4)
|
||||
actionview (= 5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
rack (~> 2.0)
|
||||
rack-test (~> 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionpack-page_caching (1.0.2)
|
||||
actionpack (>= 4.0.0, < 5)
|
||||
actionview (4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
actionpack-page_caching (1.1.0)
|
||||
actionpack (>= 4.0.0, < 6)
|
||||
actionview (5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
activejob (4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
globalid (>= 0.3.0)
|
||||
activemodel (4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.7)
|
||||
activemodel (= 4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.7)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activejob (5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
activerecord (5.0.4)
|
||||
activemodel (= 5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
arel (~> 7.0)
|
||||
activesupport (5.0.4)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (~> 0.7)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.4.0)
|
||||
arel (6.0.3)
|
||||
addressable (2.5.1)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
arel (7.1.4)
|
||||
ast (2.3.0)
|
||||
autoprefixer-rails (6.3.7)
|
||||
autoprefixer-rails (7.1.1.2)
|
||||
execjs
|
||||
bigdecimal (1.1.0)
|
||||
builder (3.2.2)
|
||||
capybara (2.7.1)
|
||||
builder (3.2.3)
|
||||
canonical-rails (0.2.0)
|
||||
rails (>= 4.1, < 5.2)
|
||||
capybara (2.14.3)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
climate_control (0.2.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coffee-rails (4.1.1)
|
||||
coffee-rails (4.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 4.0.0, < 5.1.x)
|
||||
railties (>= 4.0.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.10.0)
|
||||
colorize (0.8.1)
|
||||
composite_primary_keys (8.1.3)
|
||||
activerecord (~> 4.2.0)
|
||||
concurrent-ruby (1.0.2)
|
||||
coveralls (0.8.14)
|
||||
coffee-script-source (1.12.2)
|
||||
composite_primary_keys (9.0.7)
|
||||
activerecord (~> 5.0.0)
|
||||
concurrent-ruby (1.0.5)
|
||||
coveralls (0.8.21)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov (~> 0.12.0)
|
||||
simplecov (~> 0.14.1)
|
||||
term-ansicolor (~> 1.3)
|
||||
thor (~> 0.19.1)
|
||||
tins (~> 1.6.0)
|
||||
thor (~> 0.19.4)
|
||||
tins (~> 1.6)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
crass (1.0.2)
|
||||
dalli (2.7.6)
|
||||
deadlock_retry (1.2.0)
|
||||
|
@ -83,76 +88,83 @@ GEM
|
|||
dynamic_form (1.1.4)
|
||||
erubis (2.7.0)
|
||||
execjs (2.7.0)
|
||||
exifr (1.2.4)
|
||||
faraday (0.9.2)
|
||||
exifr (1.2.5)
|
||||
factory_girl (4.8.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.8.0)
|
||||
factory_girl (~> 4.8.0)
|
||||
railties (>= 3.0.0)
|
||||
faraday (0.12.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
fspath (2.1.1)
|
||||
globalid (0.3.6)
|
||||
activesupport (>= 4.1.0)
|
||||
hashie (3.4.4)
|
||||
ffi (1.9.18)
|
||||
fspath (3.1.0)
|
||||
geoip (1.6.3)
|
||||
globalid (0.4.0)
|
||||
activesupport (>= 4.2.0)
|
||||
hashdiff (0.3.4)
|
||||
hashie (3.5.5)
|
||||
htmlentities (4.3.4)
|
||||
http_accept_language (2.0.5)
|
||||
httpclient (2.8.0)
|
||||
i18n (0.7.0)
|
||||
i18n-js (3.0.0.rc13)
|
||||
i18n (0.8.4)
|
||||
i18n-js (3.0.0)
|
||||
i18n (~> 0.6, >= 0.6.6)
|
||||
image_optim (0.22.1)
|
||||
image_optim (0.24.3)
|
||||
exifr (~> 1.2, >= 1.2.2)
|
||||
fspath (~> 2.1)
|
||||
image_size (~> 1.3)
|
||||
fspath (~> 3.0)
|
||||
image_size (~> 1.5)
|
||||
in_threads (~> 1.3)
|
||||
progress (~> 3.0, >= 3.0.1)
|
||||
image_size (1.4.2)
|
||||
in_threads (1.3.1)
|
||||
jquery-rails (4.1.1)
|
||||
image_optim_rails (0.4.0)
|
||||
image_optim (~> 0.24.0)
|
||||
rails
|
||||
sprockets
|
||||
image_size (1.5.0)
|
||||
in_threads (1.4.0)
|
||||
jquery-rails (4.3.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jshint (1.4.0)
|
||||
jshint (1.5.0)
|
||||
execjs (>= 1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
therubyracer (~> 0.12.1)
|
||||
json (1.8.3)
|
||||
json (2.1.0)
|
||||
jsonify (0.3.1)
|
||||
multi_json (~> 1.0)
|
||||
jsonify-rails (0.3.2)
|
||||
actionpack
|
||||
jsonify (< 0.4.0)
|
||||
jwt (1.5.4)
|
||||
kgio (2.10.0)
|
||||
konacha (4.0.0)
|
||||
actionpack (>= 4.1, < 5)
|
||||
capybara
|
||||
colorize
|
||||
railties (>= 4.1, < 5)
|
||||
sprockets (>= 2, < 4)
|
||||
sprockets-rails (>= 2, < 4)
|
||||
tilt
|
||||
libv8 (3.16.14.15)
|
||||
libxml-ruby (2.9.0)
|
||||
jwt (1.5.6)
|
||||
kgio (2.11.0)
|
||||
libv8 (3.16.14.19)
|
||||
libxml-ruby (3.0.0)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
ruby_dep (~> 1.2)
|
||||
logstash-event (1.2.02)
|
||||
logstasher (1.0.0)
|
||||
activerecord (>= 4.0)
|
||||
logstasher (1.2.1)
|
||||
activesupport (>= 4.0)
|
||||
logstash-event (~> 1.2.0)
|
||||
request_store
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.6.4)
|
||||
mail (2.6.6)
|
||||
mime-types (>= 1.16, < 4)
|
||||
method_source (0.8.2)
|
||||
mime-types (3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.0)
|
||||
mini_portile2 (2.1.0)
|
||||
minitest (5.9.0)
|
||||
mini_portile2 (2.2.0)
|
||||
minitest (5.10.2)
|
||||
multi_json (1.12.1)
|
||||
multi_xml (0.5.5)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
nokogiri (1.6.8)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
pkg-config (~> 1.1.7)
|
||||
nokogumbo (1.4.7)
|
||||
nio4r (2.1.0)
|
||||
nokogiri (1.8.0)
|
||||
mini_portile2 (~> 2.2.0)
|
||||
nokogumbo (1.4.13)
|
||||
nokogiri
|
||||
oauth (0.4.7)
|
||||
oauth-plugin (0.5.1)
|
||||
|
@ -160,147 +172,172 @@ GEM
|
|||
oauth (~> 0.4.4)
|
||||
oauth2 (>= 0.5.0)
|
||||
rack
|
||||
oauth2 (1.2.0)
|
||||
faraday (>= 0.8, < 0.10)
|
||||
oauth2 (1.4.0)
|
||||
faraday (>= 0.8, < 0.13)
|
||||
jwt (~> 1.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
omniauth (1.3.1)
|
||||
hashie (>= 1.2, < 4)
|
||||
rack (>= 1.0, < 3)
|
||||
omniauth-facebook (3.0.0)
|
||||
omniauth (1.6.1)
|
||||
hashie (>= 3.4.6, < 3.6.0)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-facebook (4.0.0)
|
||||
omniauth-oauth2 (~> 1.2)
|
||||
omniauth-github (1.1.2)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (~> 1.1)
|
||||
omniauth-google-oauth2 (0.4.1)
|
||||
jwt (~> 1.5.2)
|
||||
omniauth-github (1.3.0)
|
||||
omniauth (~> 1.5)
|
||||
omniauth-oauth2 (>= 1.4.0, < 2.0)
|
||||
omniauth-google-oauth2 (0.5.0)
|
||||
jwt (~> 1.5)
|
||||
multi_json (~> 1.3)
|
||||
omniauth (>= 1.1.1)
|
||||
omniauth-oauth2 (>= 1.3.1)
|
||||
omniauth-mediawiki (0.0.3)
|
||||
jwt (~> 1.0)
|
||||
omniauth-oauth (~> 1.0)
|
||||
omniauth-oauth (1.1.0)
|
||||
oauth
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (1.4.0)
|
||||
oauth2 (~> 1.0)
|
||||
omniauth (~> 1.2)
|
||||
omniauth-openid (1.0.1)
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
omniauth-windowslive (0.0.9.1)
|
||||
multi_json (>= 1.0.3)
|
||||
omniauth-oauth2 (~> 1.0)
|
||||
omniauth-windowslive (0.0.12)
|
||||
multi_json (~> 1.12)
|
||||
omniauth-oauth2 (~> 1.4)
|
||||
paperclip (4.3.7)
|
||||
activemodel (>= 3.2.0)
|
||||
activesupport (>= 3.2.0)
|
||||
cocaine (~> 0.5.5)
|
||||
mime-types
|
||||
mimemagic (= 0.3.0)
|
||||
parser (2.3.1.2)
|
||||
parallel (1.11.2)
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
pg (0.18.4)
|
||||
pkg-config (1.1.7)
|
||||
poltergeist (1.10.0)
|
||||
pg (0.21.0)
|
||||
poltergeist (1.15.0)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
websocket-driver (>= 0.2.0)
|
||||
powerpack (0.1.1)
|
||||
progress (3.1.1)
|
||||
psych (2.1.0)
|
||||
progress (3.3.1)
|
||||
psych (2.2.4)
|
||||
public_suffix (2.0.5)
|
||||
r2 (0.2.6)
|
||||
rack (1.6.4)
|
||||
rack-cors (0.4.0)
|
||||
rack (2.0.3)
|
||||
rack-cors (0.4.1)
|
||||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rack-uri_sanitizer (0.0.2)
|
||||
rails (4.2.7)
|
||||
actionmailer (= 4.2.7)
|
||||
actionpack (= 4.2.7)
|
||||
actionview (= 4.2.7)
|
||||
activejob (= 4.2.7)
|
||||
activemodel (= 4.2.7)
|
||||
activerecord (= 4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
rails (5.0.4)
|
||||
actioncable (= 5.0.4)
|
||||
actionmailer (= 5.0.4)
|
||||
actionpack (= 5.0.4)
|
||||
actionview (= 5.0.4)
|
||||
activejob (= 5.0.4)
|
||||
activemodel (= 5.0.4)
|
||||
activerecord (= 5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.2.7)
|
||||
sprockets-rails
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
activesupport (>= 4.2.0.alpha)
|
||||
rails-dom-testing (1.0.7)
|
||||
activesupport (>= 4.2.0.beta, < 5.0)
|
||||
nokogiri (~> 1.6.0)
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
railties (= 5.0.4)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.2)
|
||||
actionpack (~> 5.x, >= 5.0.1)
|
||||
actionview (~> 5.x, >= 5.0.1)
|
||||
activesupport (~> 5.x)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.0.3)
|
||||
loofah (~> 2.0)
|
||||
rails-i18n (4.0.9)
|
||||
i18n (~> 0.7)
|
||||
railties (~> 4.0)
|
||||
railties (4.2.7)
|
||||
actionpack (= 4.2.7)
|
||||
activesupport (= 4.2.7)
|
||||
rails-i18n (4.0.2)
|
||||
i18n (~> 0.6)
|
||||
rails (>= 4.0)
|
||||
railties (5.0.4)
|
||||
actionpack (= 5.0.4)
|
||||
activesupport (= 5.0.4)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.1.0)
|
||||
rake (11.2.2)
|
||||
redcarpet (3.3.4)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
rake (12.0.0)
|
||||
rb-fsevent (0.9.8)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
record_tag_helper (1.0.0)
|
||||
actionview (~> 5.x)
|
||||
redcarpet (3.4.0)
|
||||
ref (2.0.0)
|
||||
request_store (1.3.1)
|
||||
rinku (2.0.0)
|
||||
rubocop (0.41.2)
|
||||
parser (>= 2.3.1.1, < 3.0)
|
||||
request_store (1.3.2)
|
||||
rinku (2.0.2)
|
||||
rotp (3.3.0)
|
||||
rubocop (0.49.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 1.99.1, < 3.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-openid (2.7.0)
|
||||
ruby-progressbar (1.8.1)
|
||||
sanitize (4.0.1)
|
||||
ruby_dep (1.5.0)
|
||||
safe_yaml (1.0.4)
|
||||
sanitize (4.5.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.4.4)
|
||||
nokogumbo (~> 1.4.1)
|
||||
sass (3.4.22)
|
||||
sass-rails (5.0.5)
|
||||
sass (3.4.24)
|
||||
sass-rails (5.0.6)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
simplecov (0.12.0)
|
||||
secure_headers (3.6.5)
|
||||
useragent
|
||||
simplecov (0.14.1)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.0)
|
||||
soap4r-ruby1.9 (2.0.5)
|
||||
sprockets (3.6.3)
|
||||
simplecov-html (0.10.1)
|
||||
sprockets (3.7.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.1.1)
|
||||
sprockets-rails (3.2.0)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
term-ansicolor (1.3.2)
|
||||
term-ansicolor (1.6.0)
|
||||
tins (~> 1.0)
|
||||
therubyracer (0.12.2)
|
||||
libv8 (~> 3.16.14.0)
|
||||
therubyracer (0.12.3)
|
||||
libv8 (~> 3.16.14.15)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
thread_safe (0.3.5)
|
||||
tilt (2.0.5)
|
||||
timecop (0.8.1)
|
||||
tins (1.6.0)
|
||||
tzinfo (1.2.2)
|
||||
thor (0.19.4)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.7)
|
||||
tins (1.14.0)
|
||||
tzinfo (1.2.3)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.0.0)
|
||||
uglifier (3.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.1.0)
|
||||
unicode-display_width (1.3.0)
|
||||
useragent (0.16.8)
|
||||
validates_email_format_of (1.6.3)
|
||||
i18n
|
||||
vendorer (0.1.16)
|
||||
websocket-driver (0.6.4)
|
||||
webmock (3.0.1)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
websocket-driver (0.6.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
xpath (2.0.0)
|
||||
xpath (2.1.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -312,25 +349,27 @@ DEPENDENCIES
|
|||
actionpack-page_caching
|
||||
autoprefixer-rails
|
||||
bigdecimal (~> 1.1.0)
|
||||
coffee-rails (~> 4.1.0)
|
||||
composite_primary_keys (~> 8.1.0)
|
||||
canonical-rails
|
||||
coffee-rails (~> 4.2)
|
||||
composite_primary_keys (~> 9.0.7)
|
||||
coveralls
|
||||
dalli
|
||||
deadlock_retry (>= 1.2.0)
|
||||
dynamic_form
|
||||
factory_girl_rails
|
||||
faraday
|
||||
geoip
|
||||
htmlentities
|
||||
http_accept_language (~> 2.0.0)
|
||||
httpclient
|
||||
i18n-js (>= 3.0.0.rc10)
|
||||
image_optim (>= 0.22.0)
|
||||
i18n-js (>= 3.0.0)
|
||||
image_optim_rails
|
||||
jquery-rails
|
||||
jshint
|
||||
json
|
||||
jsonify-rails
|
||||
kgio
|
||||
konacha
|
||||
libxml-ruby (>= 2.0.5)
|
||||
listen
|
||||
logstasher
|
||||
minitest (~> 5.1)
|
||||
oauth-plugin (>= 0.5.1)
|
||||
|
@ -338,6 +377,7 @@ DEPENDENCIES
|
|||
omniauth-facebook
|
||||
omniauth-github
|
||||
omniauth-google-oauth2 (>= 0.2.7)
|
||||
omniauth-mediawiki (>= 0.0.3)
|
||||
omniauth-openid
|
||||
omniauth-windowslive
|
||||
paperclip (~> 4.0)
|
||||
|
@ -347,18 +387,21 @@ DEPENDENCIES
|
|||
r2
|
||||
rack-cors
|
||||
rack-uri_sanitizer
|
||||
rails (= 4.2.7)
|
||||
rails (= 5.0.4)
|
||||
rails-controller-testing
|
||||
rails-i18n (~> 4.0.0)
|
||||
record_tag_helper
|
||||
redcarpet
|
||||
rinku (>= 1.2.2)
|
||||
rotp
|
||||
rubocop
|
||||
sanitize
|
||||
sass-rails (~> 5.0)
|
||||
soap4r-ruby1.9
|
||||
timecop
|
||||
secure_headers
|
||||
uglifier (>= 1.3.0)
|
||||
validates_email_format_of (>= 1.5.1)
|
||||
vendorer
|
||||
webmock
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.6
|
||||
1.13.7
|
||||
|
|
12
INSTALL.md
|
@ -18,22 +18,22 @@ of packages required before you can get the various gems installed.
|
|||
|
||||
## Minimum requirements
|
||||
|
||||
* Ruby 2.0
|
||||
* Ruby 2.3
|
||||
* RubyGems 1.3.1+
|
||||
* PostgreSQL 9.1+
|
||||
* ImageMagick
|
||||
* Bundler
|
||||
* Javascript Runtime
|
||||
|
||||
These can be installed on Ubuntu 14.04 or later with:
|
||||
These can be installed on Ubuntu 16.04 or later with:
|
||||
|
||||
```
|
||||
sudo apt-get install ruby2.0 libruby2.0 ruby2.0-dev \
|
||||
sudo apt-get install ruby2.3 libruby2.3 ruby2.3-dev \
|
||||
libmagickwand-dev libxml2-dev libxslt1-dev nodejs \
|
||||
apache2 apache2-threaded-dev build-essential git-core \
|
||||
apache2 apache2-dev build-essential git-core \
|
||||
postgresql postgresql-contrib libpq-dev postgresql-server-dev-all \
|
||||
libsasl2-dev imagemagick
|
||||
sudo gem2.0 install bundler
|
||||
sudo gem2.3 install bundler
|
||||
```
|
||||
|
||||
### Alternative platforms
|
||||
|
@ -138,7 +138,7 @@ instructions below as appropriate.
|
|||
|
||||
### PostgreSQL account setup
|
||||
|
||||
We need to create a PostgreSQL role (i.e. user account) for your current user, and it needs to be a superuser so that we can create more database.
|
||||
We need to create a PostgreSQL role (i.e. user account) for your current user, and it needs to be a superuser so that we can create more databases.
|
||||
|
||||
```
|
||||
sudo -u postgres -i
|
||||
|
|
4
Rakefile
|
@ -1,6 +1,6 @@
|
|||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require File.expand_path("../config/application", __FILE__)
|
||||
require_relative "config/application"
|
||||
|
||||
OpenStreetMap::Application.load_tasks
|
||||
Rails.application.load_tasks
|
||||
|
|
|
@ -6,10 +6,13 @@ On Ubuntu, it should be as simple as:
|
|||
sudo apt-get install vagrant
|
||||
```
|
||||
|
||||
Other Linux distributions should have similar installation instructions using `yum` or similar.
|
||||
Other Linux distributions should have similar installation instructions using `dnf`, `pacman`, or similar.
|
||||
|
||||
Installers are available for Mac OS X and Windows, please see the [Vagrant project download page](http://www.vagrantup.com/downloads.html) for more information.
|
||||
|
||||
Note than until there are suitable _xenial64_ [vagrant boxes](https://atlas.hashicorp.com/boxes/search?utf8=%E2%9C%93&sort=&provider=&q=xenial64) for other providers,
|
||||
the only virtualization provider supported is virtualbox. You might need to install it and specify `--provider virtualbox` when setting up your environment.
|
||||
|
||||
# Setting up openstreetmap-website
|
||||
|
||||
Once Vagrant has been installed, you can start an environment by checking out the openstreetmap-website code if you haven't already, then changing to the directory which contains the Vagrantfile by typing:
|
||||
|
|
2
Vagrantfile
vendored
|
@ -4,7 +4,7 @@
|
|||
Vagrant.configure("2") do |config|
|
||||
# use official ubuntu image for virtualbox
|
||||
config.vm.provider "virtualbox" do |vb, override|
|
||||
override.vm.box = "ubuntu/trusty64"
|
||||
override.vm.box = "ubuntu/xenial64"
|
||||
override.vm.synced_folder ".", "/srv/openstreetmap-website"
|
||||
vb.customize ["modifyvm", :id, "--memory", "1024"]
|
||||
vb.customize ["modifyvm", :id, "--cpus", "2"]
|
||||
|
|
27
Vendorfile
|
@ -11,13 +11,18 @@ folder 'vendor/assets' do
|
|||
end
|
||||
|
||||
folder 'leaflet' do
|
||||
file 'leaflet.js', 'http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet-src.js'
|
||||
file 'leaflet.css', 'http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css'
|
||||
file 'leaflet.js', 'https://unpkg.com/leaflet@1.1.0/dist/leaflet-src.js'
|
||||
file 'leaflet.css', 'https://unpkg.com/leaflet@1.1.0/dist/leaflet.css'
|
||||
|
||||
[ 'layers.png', 'layers-2x.png',
|
||||
'marker-icon.png', 'marker-icon-2x.png',
|
||||
'marker-shadow.png' ].each do |image|
|
||||
file "images/#{image}", "http://cdn.leafletjs.com/leaflet/v0.7.7/images/#{image}"
|
||||
file "images/#{image}", "https://unpkg.com/leaflet@1.1.0/dist/images/#{image}"
|
||||
end
|
||||
|
||||
from 'git://github.com/aratcliffe/Leaflet.contextmenu.git', :tag => 'v1.2.1' do
|
||||
file 'leaflet.contextmenu.js', 'dist/leaflet.contextmenu.js'
|
||||
file 'leaflet.contextmenu.css', 'dist/leaflet.contextmenu.css'
|
||||
end
|
||||
|
||||
from 'git://github.com/kajic/leaflet-locationfilter.git' do
|
||||
|
@ -26,7 +31,7 @@ folder 'vendor/assets' do
|
|||
folder 'img', 'src/img'
|
||||
end
|
||||
|
||||
from 'git://github.com/domoritz/leaflet-locatecontrol.git' do
|
||||
from 'git://github.com/domoritz/leaflet-locatecontrol.git', :tag => 'v0.54.0' do
|
||||
file 'leaflet.locate.js', 'src/L.Control.Locate.js'
|
||||
end
|
||||
|
||||
|
@ -34,7 +39,7 @@ folder 'vendor/assets' do
|
|||
file 'leaflet.osm.js', 'leaflet-osm.js'
|
||||
end
|
||||
|
||||
from 'git://github.com/jieter/Leaflet.encoded.git' do
|
||||
from 'git://github.com/jieter/Leaflet.encoded.git', :tag => '0.0.8' do
|
||||
file 'leaflet.polyline.js', 'Polyline.encoded.js'
|
||||
end
|
||||
end
|
||||
|
@ -49,7 +54,7 @@ folder 'vendor/assets' do
|
|||
from 'git://github.com/openstreetmap/iD', :branch => 'release' do
|
||||
folder 'iD/img', 'dist/img'
|
||||
folder 'iD/locales', 'dist/locales'
|
||||
folder 'iD/traffico', 'dist/traffico'
|
||||
folder 'iD/mapillary-js', 'dist/mapillary-js'
|
||||
|
||||
file 'iD.css.erb', 'dist/iD.css' do |path|
|
||||
rewrite(path) do |content|
|
||||
|
@ -57,17 +62,7 @@ folder 'vendor/assets' do
|
|||
end
|
||||
end
|
||||
|
||||
file 'iD/traffico/stylesheets/traffico.css.erb', 'dist/traffico/stylesheets/traffico.css' do |path|
|
||||
rewrite(path) do |content|
|
||||
content.gsub(/url\("?\.\.\/([^#?")]+)([^"]*)"?\)/, 'url(<%= asset_path("iD/traffico/\1") %>\2)')
|
||||
end
|
||||
end
|
||||
|
||||
File.delete('vendor/assets/iD/iD/traffico/stylesheets/traffico.css')
|
||||
|
||||
file 'iD.js', 'dist/iD.js'
|
||||
file 'presets.js', 'dist/presets.js'
|
||||
file 'imagery.js', 'dist/imagery.js'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
BIN
app/assets/images/banners/donate-2016.jpg
Normal file
After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 79 KiB |
BIN
app/assets/images/banners/sotmlatam-2016.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
app/assets/images/osm_logo_30.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
8
app/assets/images/tab-icon.svg
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
app/assets/images/wikipedia.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
@ -115,4 +115,24 @@ $(document).ready(function () {
|
|||
$("nav.primary li a").on("click", function() {
|
||||
$("header").toggleClass("closed");
|
||||
});
|
||||
|
||||
var application_data = $("head").data();
|
||||
|
||||
I18n.default_locale = OSM.DEFAULT_LOCALE;
|
||||
I18n.locale = application_data.locale;
|
||||
I18n.fallbacks = true;
|
||||
|
||||
OSM.preferred_editor = application_data.preferredEditor;
|
||||
|
||||
if (application_data.user) {
|
||||
OSM.user = application_data.user;
|
||||
|
||||
if (application_data.userHome) {
|
||||
OSM.home = application_data.userHome;
|
||||
}
|
||||
}
|
||||
|
||||
if (application_data.location) {
|
||||
OSM.location = application_data.location;
|
||||
}
|
||||
});
|
||||
|
|
36
app/assets/javascripts/edit/id.js.erb
Normal file
|
@ -0,0 +1,36 @@
|
|||
$(document).ready(function () {
|
||||
var id = $("#id-embed");
|
||||
|
||||
if (id.data("key")) {
|
||||
var hashParams = OSM.params(location.hash.substring(1)),
|
||||
mapParams = OSM.mapParams(),
|
||||
params = {};
|
||||
|
||||
if (mapParams.object) {
|
||||
params.id = mapParams.object.type[0] + mapParams.object.id;
|
||||
mapParams = OSM.parseHash(location.hash);
|
||||
if (mapParams.center) {
|
||||
params.map = mapParams.zoom + '/' + mapParams.center.lat + '/' + mapParams.center.lng;
|
||||
}
|
||||
} else if (id.data("lat") && id.data("lon")) {
|
||||
params.map = "16/" + id.data("lat") + "/" + id.data("lon");
|
||||
} else {
|
||||
params.map = (mapParams.zoom || 17) + '/' + mapParams.lat + '/' + mapParams.lon;
|
||||
}
|
||||
|
||||
if (hashParams.background) params.background = hashParams.background;
|
||||
if (hashParams.comment) params.comment = hashParams.comment;
|
||||
if (hashParams.offset) params.offset = hashParams.offset;
|
||||
if (hashParams.walkthrough) params.walkthrough = hashParams.walkthrough;
|
||||
|
||||
if (id.data("gpx")) {
|
||||
params.gpx = id.data("gpx");
|
||||
} else if (hashParams.gpx) {
|
||||
params.gpx = hashParams.gpx;
|
||||
}
|
||||
|
||||
id.attr("src", id.data("url") + "#" + querystring.stringify(params));
|
||||
} else {
|
||||
alert(I18n.t("site.edit.id_not_configured"));
|
||||
}
|
||||
});
|
61
app/assets/javascripts/edit/potlatch.js.erb
Normal file
|
@ -0,0 +1,61 @@
|
|||
//= require swfobject
|
||||
|
||||
$(document).ready(function () {
|
||||
window.changesaved = true;
|
||||
|
||||
window.markChanged = function (saved) {
|
||||
window.changesaved = saved;
|
||||
}
|
||||
|
||||
$(window).on("beforeunload", function() {
|
||||
if (!window.changesaved) {
|
||||
return I18n.t("site.edit.potlatch_unsaved_changes");
|
||||
}
|
||||
});
|
||||
|
||||
window.updatelinks = function (lon, lat, zoom, layers, minlon, minlat, maxlon, maxlat, object) {
|
||||
var hash = OSM.formatHash({ lon: lon, lat: lat, zoom: zoom });
|
||||
|
||||
if (hash !== location.hash) {
|
||||
location.replace(hash);
|
||||
}
|
||||
|
||||
updateLinks({ lon: lon, lat: lat }, zoom);
|
||||
}
|
||||
|
||||
var potlatch = $("#potlatch"),
|
||||
urlparams = OSM.params(),
|
||||
potlatch_swf = <%= asset_path("potlatch/potlatch.swf").to_json %>,
|
||||
install_swf = <%= asset_path("expressInstall.swf").to_json %>,
|
||||
flashvars = {},
|
||||
params = {},
|
||||
attributes = {};
|
||||
|
||||
flashvars.winie = document.all && window.print ? true : false;
|
||||
flashvars.token = potlatch.data("token");
|
||||
|
||||
if (potlatch.data("lat") && potlatch.data("lon")) {
|
||||
flashvars.lat = potlatch.data("lat");
|
||||
flashvars.long = potlatch.data("lon");
|
||||
flashvars.scale = potlatch.data("zoom");
|
||||
} else {
|
||||
var mapParams = OSM.mapParams();
|
||||
|
||||
flashvars.lat = mapParams.lat;
|
||||
flashvars.long = mapParams.lon;
|
||||
flashvars.scale = mapParams.zoom || 17;
|
||||
}
|
||||
|
||||
if (flashvars.scale < 11) flashvars.scale = 11;
|
||||
|
||||
if (urlparams.gpx) flashvars.gpx = urlparams.gpx;
|
||||
if (urlparams.way) flashvars.way = urlparams.way;
|
||||
if (urlparams.node) flashvars.node = urlparams.node;
|
||||
if (urlparams.custombg) flashvars.custombg = urlparams.custombg;
|
||||
|
||||
attributes.id = "potlatch";
|
||||
attributes.bgcolor = "#FFFFFF";
|
||||
|
||||
swfobject.embedSWF(potlatch_swf, "potlatch", "100%", "100%", "6",
|
||||
install_swf, flashvars, params, attributes);
|
||||
});
|
83
app/assets/javascripts/edit/potlatch2.js.erb
Normal file
|
@ -0,0 +1,83 @@
|
|||
//= require swfobject
|
||||
|
||||
$(document).ready(function () {
|
||||
window.changesaved = true;
|
||||
|
||||
window.markChanged = function (saved) {
|
||||
window.changesaved = saved;
|
||||
}
|
||||
|
||||
$(window).on("beforeunload", function() {
|
||||
if (!window.changesaved) {
|
||||
return I18n.t("site.edit.potlatch2_unsaved_changes");
|
||||
}
|
||||
});
|
||||
|
||||
window.mapMoved = $.throttle(250, function(lon, lat, zoom) {
|
||||
var hash = OSM.formatHash({ lon: lon, lat: lat, zoom: zoom });
|
||||
|
||||
if (hash !== location.hash) {
|
||||
location.replace(hash);
|
||||
}
|
||||
|
||||
updateLinks({ lon: lon, lat: lat }, zoom);
|
||||
});
|
||||
|
||||
var potlatch = $("#potlatch"),
|
||||
urlparams = OSM.params(),
|
||||
potlatch_swf = <%= asset_path("potlatch2.swf").to_json %>,
|
||||
install_swf = <%= asset_path("expressInstall.swf").to_json %>,
|
||||
flashvars = {},
|
||||
params = {};
|
||||
attributes = {};
|
||||
|
||||
if (potlatch.data("lat") && potlatch.data("lon")) {
|
||||
flashvars.lat = potlatch.data("lat");
|
||||
flashvars.lon = potlatch.data("lon");
|
||||
flashvars.zoom = potlatch.data("zoom");
|
||||
} else {
|
||||
var mapParams = OSM.mapParams();
|
||||
|
||||
flashvars.lat = mapParams.lat;
|
||||
flashvars.lon = mapParams.lon;
|
||||
flashvars.zoom = mapParams.zoom || 17;
|
||||
}
|
||||
|
||||
if (potlatch.data("token")) {
|
||||
flashvars.oauth_token = potlatch.data("token");
|
||||
flashvars.oauth_token_secret = potlatch.data("token-secret");
|
||||
flashvars.oauth_consumer_key = potlatch.data("consumer-key");
|
||||
flashvars.oauth_consumer_secret = potlatch.data("consumer-secret");
|
||||
} else {
|
||||
alert(I18n.t("site.edit.potlatch2_not_configured"));
|
||||
}
|
||||
|
||||
flashvars.assets = <%= asset_path("potlatch2/assets.zip").to_json %>;
|
||||
flashvars.font_library = <%= asset_path("potlatch2/FontLibrary.swf").to_json %>;
|
||||
flashvars.locale = potlatch.data("locale");
|
||||
flashvars.locale_paths = potlatch.data("locale") + "=" + potlatch.data("locale-path");
|
||||
flashvars.intro_image = <%= asset_path("help/introduction.jpg").to_json %>;
|
||||
flashvars.intro_video = <%= asset_path("help/introduction.mp4").to_json %>;
|
||||
if (urlparams.gpx) flashvars.gpx = urlparams.gpx;
|
||||
if (urlparams.tileurl) flashvars.tileurl = urlparams.tileurl;
|
||||
flashvars.api = location.protocol + "//" + location.host + "/api/" + OSM.API_VERSION + "/";
|
||||
flashvars.policy = location.protocol + "//" + location.host + "/api/crossdomain.xml";
|
||||
flashvars.connection = "XML";
|
||||
flashvars.show_help = "once";
|
||||
flashvars.user_check = "warn";
|
||||
flashvars.maximise_function = "maximiseMap";
|
||||
flashvars.minimise_function = "minimiseMap";
|
||||
flashvars.move_function = "mapMoved";
|
||||
|
||||
params.base = "/potlatch2";
|
||||
|
||||
attributes.id = "potlatch";
|
||||
attributes.bgcolor = "#FFFFFF";
|
||||
|
||||
swfobject.embedSWF(potlatch_swf, "potlatch", "100%", "100%", "10.1.102",
|
||||
install_swf, flashvars, params, attributes);
|
||||
|
||||
if (flashvars.lat && flashvars.lon) {
|
||||
updateLinks({ lon: flashvars.lon, lat: flashvars.lat }, flashvars.scale);
|
||||
}
|
||||
});
|
|
@ -18,6 +18,12 @@ window.onload = function () {
|
|||
args[parts[0]] = decodeURIComponent(parts[1] || '');
|
||||
}
|
||||
|
||||
var thunderforestOptions = {
|
||||
<% if defined?(THUNDERFOREST_KEY) %>
|
||||
apikey: <%= THUNDERFOREST_KEY.to_json %>
|
||||
<% end %>
|
||||
};
|
||||
|
||||
var map = L.map("map");
|
||||
map.attributionControl.setPrefix('');
|
||||
map.removeControl(map.attributionControl);
|
||||
|
@ -25,9 +31,9 @@ window.onload = function () {
|
|||
if (!args.layer || args.layer === "mapnik" || args.layer === "osmarender" || args.layer === "mapquest") {
|
||||
new L.OSM.Mapnik().addTo(map);
|
||||
} else if (args.layer === "cyclemap" || args.layer === "cycle map") {
|
||||
new L.OSM.CycleMap().addTo(map);
|
||||
new L.OSM.CycleMap(thunderforestOptions).addTo(map);
|
||||
} else if (args.layer === "transportmap") {
|
||||
new L.OSM.TransportMap().addTo(map);
|
||||
new L.OSM.TransportMap(thunderforestOptions).addTo(map);
|
||||
} else if (args.layer === "hot") {
|
||||
new L.OSM.HOT().addTo(map);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,58 @@
|
|||
//= require iD
|
||||
//= require presets
|
||||
//= require imagery
|
||||
|
||||
/* globals iD */
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var container = document.getElementById("id-container");
|
||||
|
||||
if (typeof iD === 'undefined' || !iD.Detect().support) {
|
||||
container.innerHTML = 'This editor is supported ' +
|
||||
'in Firefox, Chrome, Safari, Opera, Edge, and Internet Explorer 11. ' +
|
||||
'Please upgrade your browser or use Potlatch 2 to edit the map.';
|
||||
container.className = 'unsupported';
|
||||
} else {
|
||||
var id = iD.Context()
|
||||
.embed(true)
|
||||
.assetPath("iD/")
|
||||
.assetMap(JSON.parse(container.dataset.assetMap))
|
||||
.locale(container.dataset.locale, container.dataset.localePath)
|
||||
.preauth({
|
||||
urlroot: location.protocol + "//" + location.host,
|
||||
oauth_consumer_key: container.dataset.consumerKey,
|
||||
oauth_secret: container.dataset.consumerSecret,
|
||||
oauth_token: container.dataset.token,
|
||||
oauth_token_secret: container.dataset.tokenSecret
|
||||
});
|
||||
|
||||
id.map().on('move.embed', parent.$.throttle(250, function() {
|
||||
if (id.inIntro()) return;
|
||||
var zoom = ~~id.map().zoom(),
|
||||
center = id.map().center(),
|
||||
llz = { lon: center[0], lat: center[1], zoom: zoom };
|
||||
|
||||
parent.updateLinks(llz, zoom);
|
||||
|
||||
// Manually resolve URL to avoid iframe JS context weirdness.
|
||||
// http://bl.ocks.org/jfirebaugh/5439412
|
||||
var hash = parent.OSM.formatHash(llz);
|
||||
if (hash !== parent.location.hash) {
|
||||
parent.location.replace(parent.location.href.replace(/(#.*|$)/, hash));
|
||||
}
|
||||
}));
|
||||
|
||||
parent.$("body").on("click", "a.set_position", function (e) {
|
||||
e.preventDefault();
|
||||
var data = parent.$(this).data();
|
||||
|
||||
// 0ms timeout to avoid iframe JS context weirdness.
|
||||
// http://bl.ocks.org/jfirebaugh/5439412
|
||||
setTimeout(function() {
|
||||
id.map().centerZoom(
|
||||
[data.lon, data.lat],
|
||||
Math.max(data.zoom || 15, 13));
|
||||
}, 0);
|
||||
});
|
||||
|
||||
id.ui()(container);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
//= require leaflet.share
|
||||
//= require leaflet.polyline
|
||||
//= require leaflet.query
|
||||
//= require leaflet.contextmenu
|
||||
//= require index/contextmenu
|
||||
//= require index/search
|
||||
//= require index/browse
|
||||
//= require index/export
|
||||
|
@ -77,7 +79,8 @@ $(document).ready(function () {
|
|||
|
||||
var map = new L.OSM.Map("map", {
|
||||
zoomControl: false,
|
||||
layerControl: false
|
||||
layerControl: false,
|
||||
contextmenu: true
|
||||
});
|
||||
|
||||
map.attributionControl.setPrefix('');
|
||||
|
@ -95,14 +98,25 @@ $(document).ready(function () {
|
|||
L.OSM.zoom({position: position})
|
||||
.addTo(map);
|
||||
|
||||
L.control.locate({
|
||||
var locate = L.control.locate({
|
||||
position: position,
|
||||
icon: 'icon geolocate',
|
||||
iconLoading: 'icon geolocate',
|
||||
strings: {
|
||||
title: I18n.t('javascripts.map.locate.title'),
|
||||
popup: I18n.t('javascripts.map.locate.popup')
|
||||
}
|
||||
}).addTo(map);
|
||||
|
||||
var locateContainer = locate.getContainer();
|
||||
|
||||
$(locateContainer)
|
||||
.removeClass('leaflet-control-locate leaflet-bar')
|
||||
.addClass('control-locate')
|
||||
.children("a")
|
||||
.removeClass('leaflet-bar-part leaflet-bar-part-single')
|
||||
.addClass('control-button');
|
||||
|
||||
var sidebar = L.OSM.sidebar('#map-ui')
|
||||
.addTo(map);
|
||||
|
||||
|
@ -136,6 +150,8 @@ $(document).ready(function () {
|
|||
L.control.scale()
|
||||
.addTo(map);
|
||||
|
||||
OSM.initializeContextMenu(map);
|
||||
|
||||
if (OSM.STATUS !== 'api_offline' && OSM.STATUS !== 'database_offline') {
|
||||
OSM.initializeNotes(map);
|
||||
if (params.layers.indexOf(map.noteLayer.options.code) >= 0) {
|
||||
|
@ -146,6 +162,10 @@ $(document).ready(function () {
|
|||
if (params.layers.indexOf(map.dataLayer.options.code) >= 0) {
|
||||
map.addLayer(map.dataLayer);
|
||||
}
|
||||
|
||||
if (params.layers.indexOf(map.gpsLayer.options.code) >= 0) {
|
||||
map.addLayer(map.gpsLayer);
|
||||
}
|
||||
}
|
||||
|
||||
var placement = $('html').attr('dir') === 'rtl' ? 'right' : 'left';
|
||||
|
@ -175,7 +195,7 @@ $(document).ready(function () {
|
|||
});
|
||||
|
||||
var bannerExpiry = new Date();
|
||||
expiry.setYear(expiry.getFullYear() + 1);
|
||||
bannerExpiry.setYear(bannerExpiry.getFullYear() + 1);
|
||||
|
||||
$('#banner .close-wrap').on('click', function(e) {
|
||||
var cookieId = e.target.id;
|
||||
|
|
85
app/assets/javascripts/index/contextmenu.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
OSM.initializeContextMenu = function (map) {
|
||||
map.contextmenu.addItem({
|
||||
text: I18n.t("javascripts.context.directions_from"),
|
||||
callback: function directionsFromHere(e) {
|
||||
var precision = OSM.zoomPrecision(map.getZoom()),
|
||||
latlng = e.latlng.wrap(),
|
||||
lat = latlng.lat.toFixed(precision),
|
||||
lng = latlng.lng.toFixed(precision);
|
||||
|
||||
OSM.router.route("/directions?" + querystring.stringify({
|
||||
route: lat + "," + lng + ";" + $("#route_to").val()
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: I18n.t("javascripts.context.directions_to"),
|
||||
callback: function directionsToHere(e) {
|
||||
var precision = OSM.zoomPrecision(map.getZoom()),
|
||||
latlng = e.latlng.wrap(),
|
||||
lat = latlng.lat.toFixed(precision),
|
||||
lng = latlng.lng.toFixed(precision);
|
||||
|
||||
OSM.router.route("/directions?" + querystring.stringify({
|
||||
route: $("#route_from").val() + ";" + lat + "," + lng
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: I18n.t("javascripts.context.add_note"),
|
||||
callback: function addNoteHere(e) {
|
||||
var precision = OSM.zoomPrecision(map.getZoom()),
|
||||
latlng = e.latlng.wrap(),
|
||||
lat = latlng.lat.toFixed(precision),
|
||||
lng = latlng.lng.toFixed(precision);
|
||||
|
||||
OSM.router.route("/note/new?lat=" + lat + "&lon=" + lng);
|
||||
}
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: I18n.t("javascripts.context.show_address"),
|
||||
callback: function describeLocation(e) {
|
||||
var precision = OSM.zoomPrecision(map.getZoom()),
|
||||
latlng = e.latlng.wrap(),
|
||||
lat = latlng.lat.toFixed(precision),
|
||||
lng = latlng.lng.toFixed(precision);
|
||||
|
||||
OSM.router.route("/search?query=" + encodeURIComponent(lat + "," + lng));
|
||||
}
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: I18n.t("javascripts.context.query_features"),
|
||||
callback: function queryFeatures(e) {
|
||||
var precision = OSM.zoomPrecision(map.getZoom()),
|
||||
latlng = e.latlng.wrap(),
|
||||
lat = latlng.lat.toFixed(precision),
|
||||
lng = latlng.lng.toFixed(precision);
|
||||
|
||||
OSM.router.route("/query?lat=" + lat + "&lon=" + lng);
|
||||
}
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: I18n.t("javascripts.context.centre_map"),
|
||||
callback: function centreMap(e) {
|
||||
map.panTo(e.latlng);
|
||||
}
|
||||
});
|
||||
|
||||
map.on("mousedown", function (e) {
|
||||
if (e.originalEvent.shiftKey) map.contextmenu.disable();
|
||||
else map.contextmenu.enable();
|
||||
});
|
||||
|
||||
var updateMenu = function updateMenu () {
|
||||
map.contextmenu.setDisabled(2, map.getZoom() < 12);
|
||||
map.contextmenu.setDisabled(4, map.getZoom() < 14);
|
||||
};
|
||||
|
||||
map.on("zoomend", updateMenu);
|
||||
updateMenu();
|
||||
};
|
|
@ -26,6 +26,9 @@ OSM.Directions = function (map) {
|
|||
Endpoint($("input[name='route_to']"), OSM.MARKER_RED)
|
||||
];
|
||||
|
||||
var expiry = new Date();
|
||||
expiry.setYear(expiry.getFullYear() + 10);
|
||||
|
||||
function Endpoint(input, iconUrl) {
|
||||
var endpoint = {};
|
||||
|
||||
|
@ -207,8 +210,13 @@ OSM.Directions = function (map) {
|
|||
'<span class="icon close"></span></a>' + I18n.t('javascripts.directions.directions') +
|
||||
'</h2><p id="routing_summary">' +
|
||||
I18n.t('javascripts.directions.distance') + ': ' + formatDistance(route.distance) + '. ' +
|
||||
I18n.t('javascripts.directions.time') + ': ' + formatTime(route.time) + '.</p>' +
|
||||
'<table id="turnbyturn" />';
|
||||
I18n.t('javascripts.directions.time') + ': ' + formatTime(route.time) + '.';
|
||||
if (typeof route.ascend !== 'undefined' && typeof route.descend !== 'undefined') {
|
||||
html += '<br />' +
|
||||
I18n.t('javascripts.directions.ascend') + ': ' + Math.round(route.ascend) + 'm. ' +
|
||||
I18n.t('javascripts.directions.descend') + ': ' + Math.round(route.descend) +'m.';
|
||||
}
|
||||
html += '</p><table id="turnbyturn" />';
|
||||
|
||||
$('#sidebar_content')
|
||||
.html(html);
|
||||
|
@ -287,10 +295,15 @@ OSM.Directions = function (map) {
|
|||
select.append("<option value='" + i + "'>" + I18n.t('javascripts.directions.engines.' + engine.id) + "</option>");
|
||||
});
|
||||
|
||||
setEngine('osrm_car');
|
||||
var chosenEngineId = $.cookie('_osm_directions_engine');
|
||||
if(!chosenEngineId) {
|
||||
chosenEngineId = 'osrm_car';
|
||||
}
|
||||
setEngine(chosenEngineId);
|
||||
|
||||
select.on("change", function (e) {
|
||||
chosenEngine = engines[e.target.selectedIndex];
|
||||
$.cookie('_osm_directions_engine', chosenEngine.id, { expires: expiry, path: '/' });
|
||||
if (map.hasLayer(polyline)) {
|
||||
getRoute();
|
||||
}
|
||||
|
@ -302,10 +315,14 @@ OSM.Directions = function (map) {
|
|||
});
|
||||
|
||||
$(".routing_marker").on('dragstart', function (e) {
|
||||
e.originalEvent.dataTransfer.effectAllowed = 'move';
|
||||
e.originalEvent.dataTransfer.setData('type', $(this).data('type'));
|
||||
var img = $("<img>").attr("src", $(e.originalEvent.target).attr("src"));
|
||||
e.originalEvent.dataTransfer.setDragImage(img.get(0), 12, 21);
|
||||
var dt = e.originalEvent.dataTransfer;
|
||||
dt.effectAllowed = 'move';
|
||||
var dragData = { type: $(this).data('type') };
|
||||
dt.setData('text', JSON.stringify(dragData));
|
||||
if (dt.setDragImage) {
|
||||
var img = $("<img>").attr("src", $(e.originalEvent.target).attr("src"));
|
||||
dt.setDragImage(img.get(0), 12, 21);
|
||||
}
|
||||
});
|
||||
|
||||
var page = {};
|
||||
|
@ -321,7 +338,8 @@ OSM.Directions = function (map) {
|
|||
$("#map").on('drop', function (e) {
|
||||
e.preventDefault();
|
||||
var oe = e.originalEvent;
|
||||
var type = oe.dataTransfer.getData('type');
|
||||
var dragData = JSON.parse(oe.dataTransfer.getData('text'));
|
||||
var type = dragData.type;
|
||||
var pt = L.DomEvent.getMousePosition(oe, map.getContainer()); // co-ordinates of the mouse pointer at present
|
||||
pt.y += 20;
|
||||
var ll = map.containerPointToLatLng(pt);
|
||||
|
|
|
@ -14,18 +14,19 @@ function GraphHopperEngine(id, vehicleType) {
|
|||
|
||||
return {
|
||||
id: id,
|
||||
creditline: '<a href="https://graphhopper.com/" target="_blank">Graphhopper</a>',
|
||||
creditline: '<a href="https://www.graphhopper.com/" target="_blank">Graphhopper</a>',
|
||||
draggable: false,
|
||||
|
||||
getRoute: function (points, callback) {
|
||||
// GraphHopper Directions API documentation
|
||||
// https://github.com/graphhopper/directions-api/blob/master/docs-routing.md
|
||||
// https://graphhopper.com/api/1/docs/routing/
|
||||
return $.ajax({
|
||||
url: document.location.protocol + OSM.GRAPHHOPPER_URL,
|
||||
data: {
|
||||
vehicle: vehicleType,
|
||||
locale: I18n.currentLocale(),
|
||||
key: "LijBPDQGfu7Iiq80w3HzwB4RUDJbMbhs6BU0dEnn",
|
||||
"ch.disable": vehicleType === "car",
|
||||
type: "jsonp",
|
||||
elevation: false,
|
||||
instructions: true,
|
||||
|
@ -49,12 +50,16 @@ function GraphHopperEngine(id, vehicleType) {
|
|||
instrText += instr.text;
|
||||
var latLng = line[instr.interval[0]];
|
||||
var distInMeter = instr.distance;
|
||||
var lineseg = [];
|
||||
for (var j = instr.interval[0]; j <= instr.interval[1]; j++) {
|
||||
lineseg.push({lat: line[j][0], lng: line[j][1]});
|
||||
}
|
||||
steps.push([
|
||||
{lat: latLng.lat, lng: latLng.lng},
|
||||
{lat: latLng[0], lng: latLng[1]},
|
||||
instrCode,
|
||||
instrText,
|
||||
distInMeter,
|
||||
[]
|
||||
lineseg
|
||||
]); // TODO does graphhopper map instructions onto line indices?
|
||||
}
|
||||
|
||||
|
@ -62,7 +67,9 @@ function GraphHopperEngine(id, vehicleType) {
|
|||
line: line,
|
||||
steps: steps,
|
||||
distance: path.distance,
|
||||
time: path.time / 1000
|
||||
time: path.time / 1000,
|
||||
ascend: path.ascend,
|
||||
descend: path.descend
|
||||
});
|
||||
},
|
||||
error: function () {
|
||||
|
@ -73,5 +80,6 @@ function GraphHopperEngine(id, vehicleType) {
|
|||
};
|
||||
}
|
||||
|
||||
OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_car", "car"), true);
|
||||
OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_bicycle", "bike"), true);
|
||||
OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_foot", "foot"), true);
|
||||
|
|
|
@ -34,7 +34,7 @@ function MapzenEngine(id, costing) {
|
|||
|
||||
return {
|
||||
id: id,
|
||||
creditline: "<a href='https://mapzen.com/projects/valhalla' target='_blank'>Mapzen</a>",
|
||||
creditline: "<a href='https://mapzen.com/products/turn-by-turn/' target='_blank'>Mapzen</a>",
|
||||
draggable: false,
|
||||
|
||||
getRoute: function (points, callback) {
|
||||
|
|
|
@ -30,7 +30,6 @@ function OSRMEngine() {
|
|||
'turn sharp left': 'javascripts.directions.instructions.sharp_left',
|
||||
'turn left': 'javascripts.directions.instructions.turn_left',
|
||||
'turn slight left': 'javascripts.directions.instructions.slight_left',
|
||||
'trun straight': 'javascripts.directions.instructions.follow',
|
||||
'roundabout': 'javascripts.directions.instructions.roundabout',
|
||||
'rotary': 'javascripts.directions.instructions.roundabout',
|
||||
'depart': 'javascripts.directions.instructions.start',
|
||||
|
@ -56,7 +55,6 @@ function OSRMEngine() {
|
|||
'turn slight left': 5,
|
||||
'turn left': 6,
|
||||
'turn sharp left': 7,
|
||||
'trun straight': 0,
|
||||
'roundabout': 10,
|
||||
'rotary': 10,
|
||||
'depart': 8,
|
||||
|
|
|
@ -69,7 +69,7 @@ OSM.NewNote = function(map) {
|
|||
var marker = L.marker(feature.geometry.coordinates.reverse(), {
|
||||
icon: noteIcons[feature.properties.status],
|
||||
opacity: 0.9,
|
||||
clickable: true
|
||||
interactive: true
|
||||
});
|
||||
marker.id = feature.properties.id;
|
||||
marker.addTo(noteLayer);
|
||||
|
@ -77,7 +77,9 @@ OSM.NewNote = function(map) {
|
|||
}
|
||||
|
||||
page.pushstate = page.popstate = function (path) {
|
||||
OSM.loadSidebarContent(path, page.load);
|
||||
OSM.loadSidebarContent(path, function () {
|
||||
page.load(path);
|
||||
});
|
||||
};
|
||||
|
||||
function newHalo(loc, a) {
|
||||
|
@ -97,7 +99,7 @@ OSM.NewNote = function(map) {
|
|||
}
|
||||
}
|
||||
|
||||
page.load = function () {
|
||||
page.load = function (path) {
|
||||
if (addNoteButton.hasClass("disabled")) return;
|
||||
if (addNoteButton.hasClass("active")) return;
|
||||
|
||||
|
@ -105,12 +107,34 @@ OSM.NewNote = function(map) {
|
|||
|
||||
map.addLayer(noteLayer);
|
||||
|
||||
var mapSize = map.getSize();
|
||||
var markerPosition;
|
||||
var params = querystring.parse(path.substring(path.indexOf('?') + 1));
|
||||
var markerLatlng;
|
||||
|
||||
markerPosition = [mapSize.x / 2, mapSize.y / 2];
|
||||
if (params.lat && params.lon) {
|
||||
markerLatlng = L.latLng(params.lat, params.lon);
|
||||
|
||||
newNote = L.marker(map.containerPointToLatLng(markerPosition), {
|
||||
var markerPosition = map.latLngToContainerPoint(markerLatlng),
|
||||
mapSize = map.getSize(),
|
||||
panBy = L.point(0, 0);
|
||||
|
||||
if (markerPosition.x < 50) {
|
||||
panBy.x = markerPosition.x - 50;
|
||||
} else if (markerPosition.x > mapSize.x - 50) {
|
||||
panBy.x = 50 - mapSize.x + markerPosition.x;
|
||||
}
|
||||
|
||||
if (markerPosition.y < 50) {
|
||||
panBy.y = markerPosition.y - 50;
|
||||
} else if (markerPosition.y > mapSize.y - 50) {
|
||||
panBy.y = 50 - mapSize.y + markerPosition.y;
|
||||
}
|
||||
|
||||
map.panBy(panBy);
|
||||
} else {
|
||||
markerLatlng = map.getCenter();
|
||||
}
|
||||
|
||||
newNote = L.marker(markerLatlng, {
|
||||
icon: noteIcons["new"],
|
||||
opacity: 0.9,
|
||||
draggable: true
|
||||
|
|
|
@ -87,7 +87,7 @@ OSM.Note = function (map) {
|
|||
currentNote = L.marker(latLng, {
|
||||
icon: noteIcons[data.status],
|
||||
opacity: 1,
|
||||
clickable: true
|
||||
interactive: true
|
||||
});
|
||||
|
||||
map.addLayer(currentNote);
|
||||
|
|
|
@ -47,7 +47,7 @@ OSM.initializeNotes = function (map) {
|
|||
icon: noteIcons[feature.properties.status],
|
||||
title: feature.properties.comments[0].text,
|
||||
opacity: 0.8,
|
||||
clickable: true
|
||||
interactive: true
|
||||
});
|
||||
marker.id = feature.properties.id;
|
||||
marker.addTo(noteLayer);
|
||||
|
|
|
@ -12,7 +12,7 @@ OSM.Query = function(map) {
|
|||
weight: 4,
|
||||
opacity: 1,
|
||||
fillOpacity: 0.5,
|
||||
clickable: false
|
||||
interactive: false
|
||||
};
|
||||
|
||||
queryButton.on("click", function (e) {
|
||||
|
|
|
@ -50,7 +50,7 @@ L.OSM.layers = function(options) {
|
|||
|
||||
map.whenReady(function() {
|
||||
var miniMap = L.map(div[0], {attributionControl: false, zoomControl: false})
|
||||
.addLayer(new layer.constructor());
|
||||
.addLayer(new layer.constructor({ apikey: layer.options.apikey }));
|
||||
|
||||
miniMap.dragging.disable();
|
||||
miniMap.touchZoom.disable();
|
||||
|
@ -176,6 +176,7 @@ L.OSM.layers = function(options) {
|
|||
|
||||
addOverlay(map.noteLayer, 'notes', OSM.MAX_NOTE_REQUEST_AREA);
|
||||
addOverlay(map.dataLayer, 'data', OSM.MAX_REQUEST_AREA);
|
||||
addOverlay(map.gpsLayer, 'gps', Number.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
options.sidebar.addPane($ui);
|
||||
|
|
|
@ -16,38 +16,51 @@ L.OSM.Map = L.Map.extend({
|
|||
var copyright = I18n.t('javascripts.map.copyright', {copyright_url: '/copyright'});
|
||||
var donate = I18n.t('javascripts.map.donate_link_text', {donate_url: 'http://donate.openstreetmap.org'});
|
||||
|
||||
this.baseLayers = [
|
||||
new L.OSM.Mapnik({
|
||||
attribution: copyright + " ♥ " + donate,
|
||||
code: "M",
|
||||
keyid: "mapnik",
|
||||
name: I18n.t("javascripts.map.base.standard")
|
||||
}),
|
||||
new L.OSM.CycleMap({
|
||||
this.baseLayers = [];
|
||||
|
||||
this.baseLayers.push(new L.OSM.Mapnik({
|
||||
attribution: copyright + " ♥ " + donate,
|
||||
code: "M",
|
||||
keyid: "mapnik",
|
||||
name: I18n.t("javascripts.map.base.standard")
|
||||
}));
|
||||
|
||||
if (OSM.THUNDERFOREST_KEY) {
|
||||
this.baseLayers.push(new L.OSM.CycleMap({
|
||||
attribution: copyright + ". Tiles courtesy of <a href='http://www.thunderforest.com/' target='_blank'>Andy Allan</a>",
|
||||
apikey: OSM.THUNDERFOREST_KEY,
|
||||
code: "C",
|
||||
keyid: "cyclemap",
|
||||
name: I18n.t("javascripts.map.base.cycle_map")
|
||||
}),
|
||||
new L.OSM.TransportMap({
|
||||
}));
|
||||
|
||||
this.baseLayers.push(new L.OSM.TransportMap({
|
||||
attribution: copyright + ". Tiles courtesy of <a href='http://www.thunderforest.com/' target='_blank'>Andy Allan</a>",
|
||||
apikey: OSM.THUNDERFOREST_KEY,
|
||||
code: "T",
|
||||
keyid: "transportmap",
|
||||
name: I18n.t("javascripts.map.base.transport_map")
|
||||
}),
|
||||
new L.OSM.HOT({
|
||||
attribution: copyright + ". Tiles courtesy of <a href='http://hot.openstreetmap.org/' target='_blank'>Humanitarian OpenStreetMap Team</a>",
|
||||
code: "H",
|
||||
keyid: "hot",
|
||||
name: I18n.t("javascripts.map.base.hot")
|
||||
})
|
||||
];
|
||||
}));
|
||||
}
|
||||
|
||||
this.baseLayers.push(new L.OSM.HOT({
|
||||
attribution: copyright + ". Tiles courtesy of <a href='http://hot.openstreetmap.org/' target='_blank'>Humanitarian OpenStreetMap Team</a>",
|
||||
code: "H",
|
||||
keyid: "hot",
|
||||
name: I18n.t("javascripts.map.base.hot")
|
||||
}));
|
||||
|
||||
this.noteLayer = new L.FeatureGroup();
|
||||
this.noteLayer.options = {code: 'N'};
|
||||
|
||||
this.dataLayer = new L.OSM.DataLayer(null);
|
||||
this.dataLayer.options.code = 'D';
|
||||
|
||||
this.gpsLayer = new L.OSM.GPS({
|
||||
pane: "overlayPane",
|
||||
code: "G",
|
||||
name: I18n.t("javascripts.map.base.gps")
|
||||
});
|
||||
},
|
||||
|
||||
updateLayers: function(layerParam) {
|
||||
|
@ -94,7 +107,7 @@ L.OSM.Map = L.Map.extend({
|
|||
params.mlon = latLng.lng.toFixed(precision);
|
||||
}
|
||||
|
||||
var url = 'http://' + OSM.SERVER_URL + '/',
|
||||
var url = window.location.protocol + '//' + OSM.SERVER_URL + '/',
|
||||
query = querystring.stringify(params),
|
||||
hash = OSM.formatHash(this);
|
||||
|
||||
|
@ -108,7 +121,8 @@ L.OSM.Map = L.Map.extend({
|
|||
var zoom = this.getZoom(),
|
||||
latLng = marker && this.hasLayer(marker) ? marker.getLatLng().wrap() : this.getCenter().wrap(),
|
||||
str = window.location.hostname.match(/^www\.openstreetmap\.org/i) ?
|
||||
'http://osm.org/go/' : 'http://' + window.location.hostname + '/go/',
|
||||
window.location.protocol + '//osm.org/go/' :
|
||||
window.location.protocol + '//' + window.location.hostname + '/go/',
|
||||
char_array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_~",
|
||||
x = Math.round((latLng.lng + 180.0) * ((1 << 30) / 90.0)),
|
||||
y = Math.round((latLng.lat + 90.0) * ((1 << 30) / 45.0)),
|
||||
|
@ -195,19 +209,18 @@ L.OSM.Map = L.Map.extend({
|
|||
color: '#FF9500',
|
||||
opacity: 1,
|
||||
fillOpacity: 0,
|
||||
clickable: false
|
||||
interactive: false
|
||||
};
|
||||
|
||||
this._object = object;
|
||||
|
||||
if (this._objectLoader) this._objectLoader.abort();
|
||||
if (this._objectLayer) this.removeLayer(this._objectLayer);
|
||||
this.removeObject();
|
||||
|
||||
var map = this;
|
||||
this._objectLoader = $.ajax({
|
||||
url: OSM.apiUrl(object),
|
||||
dataType: "xml",
|
||||
success: function (xml) {
|
||||
map._object = object;
|
||||
|
||||
map._objectLayer = new L.OSM.DataLayer(null, {
|
||||
styles: {
|
||||
node: objectStyle,
|
||||
|
@ -270,7 +283,7 @@ L.OSM.Map = L.Map.extend({
|
|||
}
|
||||
});
|
||||
|
||||
L.Icon.Default.imagePath = "/images";
|
||||
L.Icon.Default.imagePath = "/images/";
|
||||
|
||||
L.Icon.Default.imageUrls = {
|
||||
"/images/marker-icon.png": OSM.MARKER_ICON,
|
||||
|
|
|
@ -213,6 +213,15 @@ L.OSM.share = function (options) {
|
|||
.attr('type', 'hidden')
|
||||
.appendTo($form);
|
||||
|
||||
var csrf_param = $("meta[name=csrf-param]").attr("content"),
|
||||
csrf_token = $("meta[name=csrf-token]").attr("content");
|
||||
|
||||
$('<input>')
|
||||
.attr('name', csrf_param)
|
||||
.attr('value', csrf_token)
|
||||
.attr('type', 'hidden')
|
||||
.appendTo($form);
|
||||
|
||||
$('<p>')
|
||||
.attr('class', 'deemphasize')
|
||||
.html(I18n.t('javascripts.share.image_size') + ' <span id="mapnik_image_width"></span> x <span id="mapnik_image_height"></span>')
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
//= require ohauth
|
||||
|
||||
$(document).ready(function () {
|
||||
var application_data = $("head").data();
|
||||
|
||||
function makeAbsolute(url) {
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
return a.href;
|
||||
}
|
||||
|
||||
if (OSM.oauth_token) {
|
||||
if (application_data.token) {
|
||||
var headerGenerator = window.ohauth.headerGenerator({
|
||||
consumer_key: OSM.oauth_consumer_key,
|
||||
consumer_secret: OSM.oauth_consumer_secret,
|
||||
token: OSM.oauth_token,
|
||||
token_secret: OSM.oauth_token_secret
|
||||
consumer_key: application_data.consumerKey,
|
||||
consumer_secret: application_data.consumerSecret,
|
||||
token: application_data.token,
|
||||
token_secret: application_data.tokenSecret
|
||||
});
|
||||
|
||||
$.ajaxPrefilter(function(options, jqxhr) {
|
||||
|
|
|
@ -16,6 +16,7 @@ OSM = {
|
|||
MAPQUEST_DIRECTIONS_URL: <%= MAPQUEST_DIRECTIONS_URL.to_json %>,
|
||||
MAPZEN_VALHALLA_URL: <%= MAPZEN_VALHALLA_URL.to_json %>,
|
||||
OSRM_URL: <%= OSRM_URL.to_json %>,
|
||||
DEFAULT_LOCALE: <%= I18n.default_locale.to_json %>,
|
||||
|
||||
<% if defined?(MAPQUEST_KEY) %>
|
||||
MAPQUEST_KEY: <%= MAPQUEST_KEY.to_json %>,
|
||||
|
@ -23,6 +24,9 @@ OSM = {
|
|||
<% if defined?(MAPZEN_VALHALLA_KEY) %>
|
||||
MAPZEN_VALHALLA_KEY: <%= MAPZEN_VALHALLA_KEY.to_json %>,
|
||||
<% end %>
|
||||
<% if defined?(THUNDERFOREST_KEY) %>
|
||||
THUNDERFOREST_KEY: <%= THUNDERFOREST_KEY.to_json %>,
|
||||
<% end %>
|
||||
|
||||
MARKER_GREEN: <%= image_path("marker-green.png").to_json %>,
|
||||
MARKER_RED: <%= image_path("marker-red.png").to_json %>,
|
||||
|
@ -35,6 +39,8 @@ OSM = {
|
|||
OPEN_NOTE_MARKER: <%= image_path("open_note_marker.png").to_json %>,
|
||||
CLOSED_NOTE_MARKER: <%= image_path("closed_note_marker.png").to_json %>,
|
||||
|
||||
SEARCHING: <%= image_path("searching.gif").to_json %>,
|
||||
|
||||
apiUrl: function (object) {
|
||||
var url = "/api/" + OSM.API_VERSION + "/" + object.type + "/" + object.id;
|
||||
|
||||
|
|
|
@ -12,14 +12,25 @@ $(document).ready(function () {
|
|||
L.OSM.zoom({position: position})
|
||||
.addTo(map);
|
||||
|
||||
L.control.locate({
|
||||
var locate = L.control.locate({
|
||||
position: position,
|
||||
icon: 'icon geolocate',
|
||||
iconLoading: 'icon geolocate',
|
||||
strings: {
|
||||
title: I18n.t('javascripts.map.locate.title'),
|
||||
popup: I18n.t('javascripts.map.locate.popup')
|
||||
}
|
||||
}).addTo(map);
|
||||
|
||||
var locateContainer = locate.getContainer();
|
||||
|
||||
$(locateContainer)
|
||||
.removeClass('leaflet-control-locate leaflet-bar')
|
||||
.addClass('control-locate')
|
||||
.children("a")
|
||||
.removeClass('leaflet-bar-part leaflet-bar-part-single')
|
||||
.addClass('control-button');
|
||||
|
||||
if (OSM.home) {
|
||||
map.setView([OSM.home.lat, OSM.home.lon], 12);
|
||||
} else {
|
||||
|
@ -92,4 +103,20 @@ $(document).ready(function () {
|
|||
} else {
|
||||
enableAuth();
|
||||
}
|
||||
|
||||
$("#user_all").change(function () {
|
||||
$("#user_list input[type=checkbox]").prop("checked", $("#user_all").prop("checked"));
|
||||
});
|
||||
|
||||
$("#content.user_confirm").each(function () {
|
||||
$(this).hide();
|
||||
$(this).find("#confirm").submit();
|
||||
});
|
||||
|
||||
$("input[name=legale]").change(function () {
|
||||
var url = $(this).data("url");
|
||||
|
||||
$("#contributorTerms").html("<img src='" + OSM.SEARCHING + "' />");
|
||||
$("#contributorTerms").load(url);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<OutputEncoding>UTF-8</OutputEncoding>
|
||||
<Image width="16" height="16">data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%06%00%00%00%1F%F3%FFa%00%00%00%19tEXtSoftware%00www.inkscape.org%9B%EE%3C%1A%00%00%01'IDATx%9C%9D%93%B1q%C30%0CE%1F%5Dd%80l%90I%C4*%A7%22%95%CF%85J%97%AE%B2%82%3DC%CE%03%A0%B3%9B%B8f%95%A3%17H%93%05%5C%A7%C8%0A%3F%05E%8A%92l%E7.%D0%E9N%02%81%07%E0Cr%FCaf%A6%FC%BC%5E%AF%DD%F4%3C%3Bt%C5%87%99)%84P%0E%DA%B6%BD%0AI%00%A1%A8%A8%1E%263S%D7u%C9'F%FE%9B%80%0C%C9%C9%22%BD'%B0%0A%AC%86%2CJ%DB%0E%22%11%8F%2F%D4%B3%22%8D%F34%CE%13u%06R%0C%40%D7u%AA%01%C5r%40%0Dq%88%C6%F9i%E8%7C%8CX%5D%A9M%95%D6%A3%A2Ti%C3Xx%CA%9C%F5mf3h%11%B6%07%B8%0APh%97%DD%1E%9E%5E%08!%D0%B6m%F1%87%108%1E%8EY5%007%03%5Cv%7B%00%3E%BF%3E%F8~x%1E%CD%B89l%00%F0I%0FWw%00%20%DB%AEJr%B6%E5%FB%09%80%C6y%CE%7D%91%1AP%B6p%2B%D9%BB%06%18V%3A%B5E%9F%AC%5B%95%AFY%3F%EE%20%A2mW%AA%93%DFN%3F%A0%E1%9B%F0u%E5%BC%BC%89%88%BC.%1F%D5'%DF%FD%C1%EE%F8%FFg%BFp%96%DF%E2%DCw%25%2B%00%00%00%00IEND%AEB%60%82</Image>
|
||||
<Url type="text/html" method="get" template="http://www.openstreetmap.org/search">
|
||||
<Url type="text/html" method="get" template="https://www.openstreetmap.org/search">
|
||||
<Param name="query" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Query role="example" searchTerms="Reigate" />
|
||||
|
|
|
@ -148,6 +148,8 @@ small, aside {
|
|||
|
||||
.red { color: $red; }
|
||||
|
||||
.piwik { border: 0; }
|
||||
|
||||
/* Rules for icons */
|
||||
|
||||
.icon {
|
||||
|
@ -491,7 +493,8 @@ body.compact {
|
|||
background-color: black;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
&.disabled,
|
||||
&.leaflet-disabled {
|
||||
background-color: #333;
|
||||
background-color: rgba(0,0,0,.5);
|
||||
cursor: default;
|
||||
|
@ -547,6 +550,10 @@ body.compact {
|
|||
background: #fff;
|
||||
font-size: 12px;
|
||||
|
||||
#sidebar_loader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> div {
|
||||
position: relative;
|
||||
float: left;
|
||||
|
@ -582,12 +589,19 @@ body.compact {
|
|||
|
||||
.icon.close {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p.error {
|
||||
background-color: #ff7070;
|
||||
padding: 10px;
|
||||
font-weight: bold;
|
||||
.flash {
|
||||
padding: 15px;
|
||||
|
||||
picture {
|
||||
margin-right: -25px;
|
||||
}
|
||||
|
||||
div.message {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -724,7 +738,7 @@ body.compact {
|
|||
font-size: 16px;
|
||||
text-stroke: 2px #fff;
|
||||
background: rgba(255,255,255,.9);
|
||||
z-index: 2; // For IE9
|
||||
z-index: 1000;
|
||||
input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
@ -869,10 +883,15 @@ body.compact {
|
|||
|
||||
#sidebar {
|
||||
#sidebar_loader,
|
||||
.search_more {
|
||||
width: 100%;
|
||||
margin: $lineheight auto;
|
||||
}
|
||||
|
||||
.loader,
|
||||
.load_more {
|
||||
text-align: center;
|
||||
margin: $lineheight auto;
|
||||
margin: auto;
|
||||
width: 40px;
|
||||
display: block;
|
||||
}
|
||||
|
@ -1175,6 +1194,7 @@ tr.turn:hover {
|
|||
width: 50%;
|
||||
padding: 6px 10px;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.browse-tag-k {
|
||||
|
@ -1469,6 +1489,18 @@ tr.turn:hover {
|
|||
}
|
||||
}
|
||||
|
||||
/* Rules for the trace view */
|
||||
|
||||
.trace-view {
|
||||
.trace_pending {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.geo {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rules for the new trace form */
|
||||
|
||||
#new_trace {
|
||||
|
@ -1674,6 +1706,13 @@ tr.turn:hover {
|
|||
float: left;
|
||||
}
|
||||
|
||||
|
||||
.diary-subscribe-buttons {
|
||||
position:relative;
|
||||
top: -30px;
|
||||
left: 130px;
|
||||
}
|
||||
|
||||
/* Rules for the log in page */
|
||||
|
||||
#login_auth_buttons {
|
||||
|
@ -1694,6 +1733,14 @@ tr.turn:hover {
|
|||
margin-bottom: $lineheight;
|
||||
overflow: auto;
|
||||
height: 20em;
|
||||
|
||||
li {
|
||||
list-style: inherit;
|
||||
}
|
||||
|
||||
ol ol {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
}
|
||||
|
||||
#decline {
|
||||
|
@ -1752,6 +1799,12 @@ tr.turn:hover {
|
|||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
/* Rules for the oauth authorization page */
|
||||
|
||||
.oauth-authorize ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Rules for messages pages */
|
||||
|
||||
.messages {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
*= require leaflet
|
||||
*= require leaflet.locationfilter
|
||||
*= require leaflet.contextmenu
|
||||
*/
|
||||
|
||||
/* Override to serve images through the asset pipeline. */
|
||||
|
|
|
@ -133,7 +133,6 @@ body.small {
|
|||
|
||||
.leaflet-top.leaflet-right {
|
||||
top: 10px !important;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.content_map {
|
||||
|
|
|
@ -46,7 +46,7 @@ class AmfController < ApplicationController
|
|||
|
||||
def amf_read
|
||||
self.status = :ok
|
||||
self.content_type = Mime::AMF
|
||||
self.content_type = Mime[:amf]
|
||||
self.response_body = Dispatcher.new(request.raw_post) do |message, *args|
|
||||
logger.info("Executing AMF #{message}(#{args.join(',')})")
|
||||
|
||||
|
@ -74,7 +74,7 @@ class AmfController < ApplicationController
|
|||
err = false # Abort batch on error
|
||||
|
||||
self.status = :ok
|
||||
self.content_type = Mime::AMF
|
||||
self.content_type = Mime[:amf]
|
||||
self.response_body = Dispatcher.new(request.raw_post) do |message, *args|
|
||||
logger.info("Executing AMF #{message}")
|
||||
|
||||
|
@ -86,14 +86,14 @@ class AmfController < ApplicationController
|
|||
orn = renumberednodes.dup
|
||||
result = putway(renumberednodes, *args)
|
||||
result[4] = renumberednodes.reject { |k, _v| orn.key?(k) }
|
||||
renumberedways[result[2]] = result[3] if result[0] == 0 && result[2] != result[3]
|
||||
renumberedways[result[2]] = result[3] if result[0].zero? && result[2] != result[3]
|
||||
when "putrelation" then
|
||||
result = putrelation(renumberednodes, renumberedways, *args)
|
||||
when "deleteway" then
|
||||
result = deleteway(*args)
|
||||
when "putpoi" then
|
||||
result = putpoi(*args)
|
||||
renumberednodes[result[2]] = result[3] if result[0] == 0 && result[2] != result[3]
|
||||
renumberednodes[result[2]] = result[3] if result[0].zero? && result[2] != result[3]
|
||||
when "startchangeset" then
|
||||
result = startchangeset(*args)
|
||||
end
|
||||
|
@ -163,7 +163,7 @@ class AmfController < ApplicationController
|
|||
end
|
||||
|
||||
# open a new changeset
|
||||
if opennew != 0
|
||||
if opennew.nonzero?
|
||||
cs = Changeset.new
|
||||
cs.tags = cstags
|
||||
cs.user_id = user.id
|
||||
|
@ -220,14 +220,14 @@ class AmfController < ApplicationController
|
|||
loaded_lang = "en"
|
||||
|
||||
# Load English defaults
|
||||
en = YAML.load(File.open("#{Rails.root}/config/potlatch/locales/en.yml"))["en"]
|
||||
en = YAML.safe_load(File.open(Rails.root.join("config", "potlatch", "locales", "en.yml")))["en"]
|
||||
|
||||
if lang == "en"
|
||||
return [loaded_lang, en]
|
||||
else
|
||||
# Use English as a fallback
|
||||
begin
|
||||
other = YAML.load(File.open("#{Rails.root}/config/potlatch/locales/#{lang}.yml"))[lang]
|
||||
other = YAML.safe_load(File.open(Rails.root.join("config", "potlatch", "locales", "#{lang}.yml")))[lang]
|
||||
loaded_lang = lang
|
||||
rescue
|
||||
other = en
|
||||
|
@ -540,7 +540,7 @@ class AmfController < ApplicationController
|
|||
tags = strip_non_xml_chars tags
|
||||
|
||||
relid = relid.to_i
|
||||
visible = (visible.to_i != 0)
|
||||
visible = visible.to_i.nonzero?
|
||||
|
||||
new_relation = nil
|
||||
relation = nil
|
||||
|
@ -644,7 +644,7 @@ class AmfController < ApplicationController
|
|||
id = a[2].to_i
|
||||
version = a[3].to_i
|
||||
|
||||
return -2, "Server error - node with id 0 found in way #{originalway}." if id == 0
|
||||
return -2, "Server error - node with id 0 found in way #{originalway}." if id.zero?
|
||||
return -2, "Server error - node with latitude -90 found in way #{originalway}." if lat == 90
|
||||
|
||||
id = renumberednodes[id] if renumberednodes[id]
|
||||
|
@ -868,14 +868,14 @@ class AmfController < ApplicationController
|
|||
|
||||
def getuser(token) #:doc:
|
||||
if token =~ /^(.+)\:(.+)$/
|
||||
User.authenticate(:username => $1, :password => $2)
|
||||
User.authenticate(:username => Regexp.last_match(1), :password => Regexp.last_match(2))
|
||||
else
|
||||
User.authenticate(:token => token)
|
||||
end
|
||||
end
|
||||
|
||||
def getlocales
|
||||
@locales ||= Locale.list(Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") })
|
||||
@locales ||= Locale.list(Dir.glob(Rails.root.join("config", "potlatch", "locales", "*")).collect { |f| File.basename(f, ".yml") })
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -914,7 +914,7 @@ class AmfController < ApplicationController
|
|||
INNER JOIN current_ways ON current_ways.id =current_way_nodes.id
|
||||
WHERE current_nodes.visible=TRUE
|
||||
AND current_ways.visible=TRUE
|
||||
AND #{OSM.sql_for_area(bbox, "current_nodes.")}
|
||||
AND #{OSM.sql_for_area(bbox, 'current_nodes.')}
|
||||
EOF
|
||||
ActiveRecord::Base.connection.select_all(sql).collect { |a| [a["wayid"].to_i, a["version"].to_i] }
|
||||
end
|
||||
|
@ -927,7 +927,7 @@ class AmfController < ApplicationController
|
|||
LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id
|
||||
WHERE current_nodes.visible=TRUE
|
||||
AND cwn.id IS NULL
|
||||
AND #{OSM.sql_for_area(bbox, "current_nodes.")}
|
||||
AND #{OSM.sql_for_area(bbox, 'current_nodes.')}
|
||||
EOF
|
||||
ActiveRecord::Base.connection.select_all(sql).each do |row|
|
||||
poitags = {}
|
||||
|
@ -947,7 +947,7 @@ class AmfController < ApplicationController
|
|||
FROM current_relations cr
|
||||
INNER JOIN current_relation_members crm ON crm.id=cr.id
|
||||
INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node'
|
||||
WHERE #{OSM.sql_for_area(bbox, "cn.")}
|
||||
WHERE #{OSM.sql_for_area(bbox, 'cn.')}
|
||||
EOF
|
||||
unless way_ids.empty?
|
||||
sql += <<-EOF
|
||||
|
|
|
@ -100,7 +100,7 @@ class ApiController < ApplicationController
|
|||
|
||||
response.headers["Content-Disposition"] = "attachment; filename=\"tracks.gpx\""
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
# This is probably the most common call of all. It is used for getting the
|
||||
|
@ -198,7 +198,7 @@ class ApiController < ApplicationController
|
|||
|
||||
response.headers["Content-Disposition"] = "attachment; filename=\"map.osm\""
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
# Get a list of the tiles that have changed within a specified time
|
||||
|
@ -241,9 +241,9 @@ class ApiController < ApplicationController
|
|||
|
||||
doc.root << changes
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
else
|
||||
render :text => "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours", :status => :bad_request
|
||||
render :plain => "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours", :status => :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -263,6 +263,9 @@ class ApiController < ApplicationController
|
|||
area = XML::Node.new "area"
|
||||
area["maximum"] = MAX_REQUEST_AREA.to_s
|
||||
api << area
|
||||
notearea = XML::Node.new "note_area"
|
||||
notearea["maximum"] = MAX_NOTE_REQUEST_AREA.to_s
|
||||
api << notearea
|
||||
tracepoints = XML::Node.new "tracepoints"
|
||||
tracepoints["per_page"] = TRACEPOINTS_PER_PAGE.to_s
|
||||
api << tracepoints
|
||||
|
@ -291,7 +294,7 @@ class ApiController < ApplicationController
|
|||
policy << blacklist
|
||||
doc.root << policy
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
# External apps that use the api are able to query which permissions
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
include SessionPersistence
|
||||
|
||||
protect_from_forgery
|
||||
protect_from_forgery :with => :exception
|
||||
|
||||
before_action :fetch_body
|
||||
|
||||
|
@ -41,7 +41,7 @@ class ApplicationController < ActionController::Base
|
|||
if request.get?
|
||||
redirect_to :controller => "user", :action => "login", :referer => request.fullpath
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -61,8 +61,9 @@ class ApplicationController < ActionController::Base
|
|||
# method, otherwise an OAuth token was used, which has to be checked.
|
||||
unless current_token.nil?
|
||||
unless current_token.read_attribute(cap)
|
||||
report_error "OAuth token doesn't have that capability.", :forbidden
|
||||
return false
|
||||
set_locale
|
||||
report_error t("oauth.permissions.missing"), :forbidden
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -73,8 +74,8 @@ class ApplicationController < ActionController::Base
|
|||
if request.cookies["_osm_session"].to_s == ""
|
||||
if params[:cookie_test].nil?
|
||||
session[:cookie_test] = true
|
||||
redirect_to Hash[params].merge(:cookie_test => "true")
|
||||
return false
|
||||
redirect_to params.to_unsafe_h.merge(:cookie_test => "true")
|
||||
false
|
||||
else
|
||||
flash.now[:warning] = t "application.require_cookies.cookies_needed"
|
||||
end
|
||||
|
@ -126,7 +127,7 @@ class ApplicationController < ActionController::Base
|
|||
flash[:error] = t("application.require_moderator.not_a_moderator")
|
||||
redirect_to :action => "index"
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -152,9 +153,14 @@ class ApplicationController < ActionController::Base
|
|||
# have we identified the user?
|
||||
if @user
|
||||
# check if the user has been banned
|
||||
if @user.blocks.active.exists?
|
||||
# NOTE: need slightly more helpful message than this.
|
||||
report_error t("application.setup_user_auth.blocked"), :forbidden
|
||||
user_block = @user.blocks.active.take
|
||||
unless user_block.nil?
|
||||
set_locale
|
||||
if user_block.zero_hour?
|
||||
report_error t("application.setup_user_auth.blocked_zero_hour"), :forbidden
|
||||
else
|
||||
report_error t("application.setup_user_auth.blocked"), :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
# if the user hasn't seen the contributor terms then don't
|
||||
|
@ -175,7 +181,7 @@ class ApplicationController < ActionController::Base
|
|||
unless @user
|
||||
# no auth, the user does not exist or the password was wrong
|
||||
response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
|
||||
render :text => errormessage, :status => :unauthorized
|
||||
render :plain => errormessage, :status => :unauthorized
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -191,8 +197,8 @@ class ApplicationController < ActionController::Base
|
|||
def authorize_moderator(errormessage = "Access restricted to moderators")
|
||||
# check user is a moderator
|
||||
unless @user.moderator?
|
||||
render :text => errormessage, :status => :forbidden
|
||||
return false
|
||||
render :plain => errormessage, :status => :forbidden
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -220,14 +226,14 @@ class ApplicationController < ActionController::Base
|
|||
def check_api_readable
|
||||
if api_status == :offline
|
||||
report_error "Database offline for maintenance", :service_unavailable
|
||||
return false
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def check_api_writable
|
||||
unless api_status == :online
|
||||
report_error "Database offline for maintenance", :service_unavailable
|
||||
return false
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -262,7 +268,7 @@ class ApplicationController < ActionController::Base
|
|||
def require_public_data
|
||||
unless @user.data_public?
|
||||
report_error "You must make your edits public to upload new data", :forbidden
|
||||
return false
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -282,9 +288,9 @@ class ApplicationController < ActionController::Base
|
|||
result.root << (XML::Node.new("status") << "#{Rack::Utils.status_code(status)} #{Rack::Utils::HTTP_STATUS_CODES[status]}")
|
||||
result.root << (XML::Node.new("message") << message)
|
||||
|
||||
render :text => result.to_s, :content_type => "text/xml"
|
||||
render :xml => result.to_s
|
||||
else
|
||||
render :text => message, :status => status, :content_type => "text/plain"
|
||||
render :plain => message, :status => status
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -315,7 +321,7 @@ class ApplicationController < ActionController::Base
|
|||
def api_call_handle_error
|
||||
yield
|
||||
rescue ActiveRecord::RecordNotFound => ex
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
rescue LibXML::XML::Error, ArgumentError => ex
|
||||
report_error ex.message, :bad_request
|
||||
rescue ActiveRecord::RecordInvalid => ex
|
||||
|
@ -343,7 +349,7 @@ class ApplicationController < ActionController::Base
|
|||
##
|
||||
# wrap an api call in a timeout
|
||||
def api_call_timeout
|
||||
OSM::Timer.timeout(API_TIMEOUT) do
|
||||
OSM::Timer.timeout(API_TIMEOUT, Timeout::Error) do
|
||||
yield
|
||||
end
|
||||
rescue Timeout::Error
|
||||
|
@ -353,17 +359,14 @@ class ApplicationController < ActionController::Base
|
|||
##
|
||||
# wrap a web page in a timeout
|
||||
def web_timeout
|
||||
OSM::Timer.timeout(WEB_TIMEOUT) do
|
||||
OSM::Timer.timeout(WEB_TIMEOUT, Timeout::Error) do
|
||||
yield
|
||||
end
|
||||
rescue ActionView::Template::Error => ex
|
||||
ex = ex.original_exception
|
||||
|
||||
if ex.is_a?(ActiveRecord::StatementInvalid) && ex.message =~ /execution expired/
|
||||
ex = Timeout::Error.new
|
||||
end
|
||||
|
||||
if ex.is_a?(Timeout::Error)
|
||||
if ex.is_a?(Timeout::Error) ||
|
||||
(ex.is_a?(ActiveRecord::StatementInvalid) && ex.message =~ /execution expired/)
|
||||
render :action => "timeout"
|
||||
else
|
||||
raise
|
||||
|
@ -375,7 +378,7 @@ class ApplicationController < ActionController::Base
|
|||
##
|
||||
# ensure that there is a "this_user" instance variable
|
||||
def lookup_this_user
|
||||
unless @this_user = User.active.find_by_display_name(params[:display_name])
|
||||
unless @this_user = User.active.find_by(:display_name => params[:display_name])
|
||||
render_unknown_user params[:display_name]
|
||||
end
|
||||
end
|
||||
|
@ -388,7 +391,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
respond_to do |format|
|
||||
format.html { render :template => "user/no_such_user", :status => :not_found }
|
||||
format.all { render :text => "", :status => :not_found }
|
||||
format.all { head :not_found }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -406,6 +409,18 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def map_layout
|
||||
append_content_security_policy_directives(
|
||||
:connect_src => %w[nominatim.openstreetmap.org overpass-api.de router.project-osrm.org valhalla.mapzen.com],
|
||||
:script_src => %w[graphhopper.com open.mapquestapi.com],
|
||||
:img_src => %w[developer.mapquest.com]
|
||||
)
|
||||
|
||||
if STATUS == :database_offline || STATUS == :api_offline
|
||||
flash.now[:warning] = t("layouts.osm_offline")
|
||||
elsif STATUS == :database_readonly || STATUS == :api_readonly
|
||||
flash.now[:warning] = t("layouts.osm_read_only")
|
||||
end
|
||||
|
||||
request.xhr? ? "xhr" : "map"
|
||||
end
|
||||
|
||||
|
@ -423,6 +438,16 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
helper_method :preferred_editor
|
||||
|
||||
def update_totp
|
||||
if defined?(TOTP_KEY)
|
||||
cookies["_osm_totp_token"] = {
|
||||
:value => ROTP::TOTP.new(TOTP_KEY, :interval => 3600).now,
|
||||
:domain => "openstreetmap.org",
|
||||
:expires => 1.hour.from_now
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# extract authorisation credentials from headers, returns user = nil if none
|
||||
|
@ -452,6 +477,5 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
# override to stop oauth plugin sending errors
|
||||
def invalid_oauth_response
|
||||
end
|
||||
def invalid_oauth_response; end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class BrowseController < ApplicationController
|
|||
|
||||
def relation
|
||||
@type = "relation"
|
||||
@feature = Relation.find(params[:id])
|
||||
@feature = Relation.preload(:relation_tags, :containing_relation_members, :changeset => [:changeset_tags, :user], :relation_members => :member).find(params[:id])
|
||||
render "feature"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "not_found", :status => :not_found
|
||||
|
@ -17,7 +17,7 @@ class BrowseController < ApplicationController
|
|||
|
||||
def relation_history
|
||||
@type = "relation"
|
||||
@feature = Relation.find(params[:id])
|
||||
@feature = Relation.preload(:relation_tags, :old_relations => [:old_tags, :changeset => [:changeset_tags, :user], :old_members => :member]).find(params[:id])
|
||||
render "history"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "not_found", :status => :not_found
|
||||
|
@ -25,7 +25,7 @@ class BrowseController < ApplicationController
|
|||
|
||||
def way
|
||||
@type = "way"
|
||||
@feature = Way.preload(:way_tags, :containing_relation_members, :changeset => :user, :nodes => [:node_tags, :ways => :way_tags]).find(params[:id])
|
||||
@feature = Way.preload(:way_tags, :containing_relation_members, :changeset => [:changeset_tags, :user], :nodes => [:node_tags, :ways => :way_tags]).find(params[:id])
|
||||
render "feature"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "not_found", :status => :not_found
|
||||
|
@ -33,7 +33,7 @@ class BrowseController < ApplicationController
|
|||
|
||||
def way_history
|
||||
@type = "way"
|
||||
@feature = Way.preload(:way_tags, :old_ways => { :changeset => :user }).find(params[:id])
|
||||
@feature = Way.preload(:way_tags, :old_ways => [:old_tags, :changeset => [:changeset_tags, :user], :old_nodes => { :node => [:node_tags, :ways] }]).find(params[:id])
|
||||
render "history"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "not_found", :status => :not_found
|
||||
|
@ -41,7 +41,7 @@ class BrowseController < ApplicationController
|
|||
|
||||
def node
|
||||
@type = "node"
|
||||
@feature = Node.find(params[:id])
|
||||
@feature = Node.preload(:node_tags, :containing_relation_members, :changeset => [:changeset_tags, :user], :ways => :way_tags).find(params[:id])
|
||||
render "feature"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "not_found", :status => :not_found
|
||||
|
@ -49,7 +49,7 @@ class BrowseController < ApplicationController
|
|||
|
||||
def node_history
|
||||
@type = "node"
|
||||
@feature = Node.find(params[:id])
|
||||
@feature = Node.preload(:node_tags, :old_nodes => [:old_tags, :changeset => [:changeset_tags, :user]]).find(params[:id])
|
||||
render "history"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "not_found", :status => :not_found
|
||||
|
|
|
@ -34,7 +34,7 @@ class ChangesetController < ApplicationController
|
|||
# Subscribe user to changeset comments
|
||||
cs.subscribers << @user
|
||||
|
||||
render :text => cs.id.to_s, :content_type => "text/plain"
|
||||
render :plain => cs.id.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -43,7 +43,7 @@ class ChangesetController < ApplicationController
|
|||
def read
|
||||
changeset = Changeset.find(params[:id])
|
||||
|
||||
render :text => changeset.to_xml(params[:include_discussion].presence).to_s, :content_type => "text/xml"
|
||||
render :xml => changeset.to_xml(params[:include_discussion].presence).to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -61,7 +61,7 @@ class ChangesetController < ApplicationController
|
|||
changeset.set_closed_time_now
|
||||
|
||||
changeset.save!
|
||||
render :text => ""
|
||||
head :ok
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -83,7 +83,7 @@ class ChangesetController < ApplicationController
|
|||
|
||||
# the request is in pseudo-osm format... this is kind-of an
|
||||
# abuse, maybe should change to some other format?
|
||||
doc = XML::Parser.string(request.raw_post).parse
|
||||
doc = XML::Parser.string(request.raw_post, :options => XML::Parser::Options::NOERROR).parse
|
||||
doc.find("//osm/node").each do |n|
|
||||
lon << n["lon"].to_f * GeoRecord::SCALE
|
||||
lat << n["lat"].to_f * GeoRecord::SCALE
|
||||
|
@ -104,7 +104,7 @@ class ChangesetController < ApplicationController
|
|||
# save the larger bounding box and return the changeset, which
|
||||
# will include the bigger bounding box.
|
||||
cs.save!
|
||||
render :text => cs.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => cs.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -132,7 +132,7 @@ class ChangesetController < ApplicationController
|
|||
diff_reader = DiffReader.new(request.raw_post, changeset)
|
||||
Changeset.transaction do
|
||||
result = diff_reader.commit
|
||||
render :text => result.to_s, :content_type => "text/xml"
|
||||
render :xml => result.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -197,7 +197,7 @@ class ChangesetController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
render :text => result.to_s, :content_type => "text/xml"
|
||||
render :xml => result.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -224,7 +224,7 @@ class ChangesetController < ApplicationController
|
|||
results.root << cs.to_xml_node
|
||||
end
|
||||
|
||||
render :text => results.to_s, :content_type => "text/xml"
|
||||
render :xml => results.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -244,52 +244,54 @@ class ChangesetController < ApplicationController
|
|||
|
||||
check_changeset_consistency(changeset, @user)
|
||||
changeset.update_from(new_changeset, @user)
|
||||
render :text => changeset.to_xml, :mime_type => "text/xml"
|
||||
render :xml => changeset.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
# list edits (open changesets) in reverse chronological order
|
||||
# list non-empty changesets in reverse chronological order
|
||||
def list
|
||||
if request.format == :atom && params[:max_id]
|
||||
redirect_to url_for(params.merge(:max_id => nil)), :status => :moved_permanently
|
||||
@params = params.permit(:display_name, :bbox, :friends, :nearby, :max_id, :list)
|
||||
|
||||
if request.format == :atom && @params[:max_id]
|
||||
redirect_to url_for(@params.merge(:max_id => nil)), :status => :moved_permanently
|
||||
return
|
||||
end
|
||||
|
||||
if params[:display_name]
|
||||
user = User.find_by_display_name(params[:display_name])
|
||||
if @params[:display_name]
|
||||
user = User.find_by(:display_name => @params[:display_name])
|
||||
if !user || !user.active?
|
||||
render_unknown_user params[:display_name]
|
||||
render_unknown_user @params[:display_name]
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if (params[:friends] || params[:nearby]) && !@user
|
||||
if (@params[:friends] || @params[:nearby]) && !@user
|
||||
require_user
|
||||
return
|
||||
end
|
||||
|
||||
if request.format == :html && !params[:list]
|
||||
if request.format == :html && !@params[:list]
|
||||
require_oauth
|
||||
render :action => :history, :layout => map_layout
|
||||
else
|
||||
changesets = conditions_nonempty(Changeset.all)
|
||||
|
||||
if params[:display_name]
|
||||
if @params[:display_name]
|
||||
changesets = if user.data_public? || user == @user
|
||||
changesets.where(:user_id => user.id)
|
||||
else
|
||||
changesets.where("false")
|
||||
end
|
||||
elsif params[:bbox]
|
||||
elsif @params[:bbox]
|
||||
changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params))
|
||||
elsif params[:friends] && @user
|
||||
elsif @params[:friends] && @user
|
||||
changesets = changesets.where(:user_id => @user.friend_users.identifiable)
|
||||
elsif params[:nearby] && @user
|
||||
elsif @params[:nearby] && @user
|
||||
changesets = changesets.where(:user_id => @user.nearby)
|
||||
end
|
||||
|
||||
if params[:max_id]
|
||||
changesets = changesets.where("changesets.id <= ?", params[:max_id])
|
||||
if @params[:max_id]
|
||||
changesets = changesets.where("changesets.id <= ?", @params[:max_id])
|
||||
end
|
||||
|
||||
@edits = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments)
|
||||
|
@ -335,7 +337,7 @@ class ChangesetController < ApplicationController
|
|||
changeset.subscribers << @user unless changeset.subscribers.exists?(@user.id)
|
||||
|
||||
# Return a copy of the updated changeset
|
||||
render :text => changeset.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => changeset.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -356,7 +358,7 @@ class ChangesetController < ApplicationController
|
|||
changeset.subscribers << @user
|
||||
|
||||
# Return a copy of the updated changeset
|
||||
render :text => changeset.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => changeset.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -377,7 +379,7 @@ class ChangesetController < ApplicationController
|
|||
changeset.subscribers.delete(@user)
|
||||
|
||||
# Return a copy of the updated changeset
|
||||
render :text => changeset.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => changeset.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -396,7 +398,7 @@ class ChangesetController < ApplicationController
|
|||
comment.update(:visible => false)
|
||||
|
||||
# Return a copy of the updated changeset
|
||||
render :text => comment.changeset.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => comment.changeset.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -415,7 +417,7 @@ class ChangesetController < ApplicationController
|
|||
comment.update(:visible => true)
|
||||
|
||||
# Return a copy of the updated changeset
|
||||
render :text => comment.changeset.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => comment.changeset.to_xml.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -440,7 +442,7 @@ class ChangesetController < ApplicationController
|
|||
format.rss
|
||||
end
|
||||
rescue OSM::APIBadUserInput
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -481,7 +483,7 @@ class ChangesetController < ApplicationController
|
|||
raise OSM::APIBadUserInput.new("invalid user ID") if user.to_i < 1
|
||||
u = User.find(user.to_i)
|
||||
else
|
||||
u = User.find_by_display_name(name)
|
||||
u = User.find_by(:display_name => name)
|
||||
end
|
||||
|
||||
# make sure we found a user
|
||||
|
@ -535,10 +537,10 @@ class ChangesetController < ApplicationController
|
|||
# if parameter 'open' is nill then open and closed changesets are returned
|
||||
def conditions_open(changesets, open)
|
||||
if open.nil?
|
||||
return changesets
|
||||
changesets
|
||||
else
|
||||
return changesets.where("closed_at >= ? and num_changes <= ?",
|
||||
Time.now.getutc, Changeset::MAX_ELEMENTS)
|
||||
changesets.where("closed_at >= ? and num_changes <= ?",
|
||||
Time.now.getutc, Changeset::MAX_ELEMENTS)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -547,10 +549,10 @@ class ChangesetController < ApplicationController
|
|||
# ('closed at' time has passed or changes limit is hit)
|
||||
def conditions_closed(changesets, closed)
|
||||
if closed.nil?
|
||||
return changesets
|
||||
changesets
|
||||
else
|
||||
return changesets.where("closed_at < ? or num_changes > ?",
|
||||
Time.now.getutc, Changeset::MAX_ELEMENTS)
|
||||
changesets.where("closed_at < ? or num_changes > ?",
|
||||
Time.now.getutc, Changeset::MAX_ELEMENTS)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -559,12 +561,12 @@ class ChangesetController < ApplicationController
|
|||
# (either specified as array or comma-separated string)
|
||||
def conditions_ids(changesets, ids)
|
||||
if ids.nil?
|
||||
return changesets
|
||||
changesets
|
||||
elsif ids.empty?
|
||||
raise OSM::APIBadUserInput.new("No changesets were given to search for")
|
||||
else
|
||||
ids = ids.split(",").collect(&:to_i)
|
||||
return changesets.where(:id => ids)
|
||||
changesets.where(:id => ids)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,16 +3,16 @@ class DiaryEntryController < ApplicationController
|
|||
|
||||
before_action :authorize_web
|
||||
before_action :set_locale
|
||||
before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment]
|
||||
before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
|
||||
before_action :lookup_this_user, :only => [:view, :comments]
|
||||
before_action :check_database_readable
|
||||
before_action :check_database_writable, :only => [:new, :edit]
|
||||
before_action :check_database_writable, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
|
||||
before_action :require_administrator, :only => [:hide, :hidecomment]
|
||||
|
||||
def new
|
||||
@title = t "diary_entry.new.title"
|
||||
|
||||
if params[:diary_entry]
|
||||
if request.post?
|
||||
@diary_entry = DiaryEntry.new(entry_params)
|
||||
@diary_entry.user = @user
|
||||
|
||||
|
@ -24,14 +24,18 @@ class DiaryEntryController < ApplicationController
|
|||
else
|
||||
@user.preferences.create(:k => "diary.default_language", :v => @diary_entry.language_code)
|
||||
end
|
||||
redirect_to :controller => "diary_entry", :action => "list", :display_name => @user.display_name
|
||||
|
||||
# Subscribe user to diary comments
|
||||
@diary_entry.subscriptions.create(:user => @user)
|
||||
|
||||
redirect_to :action => "list", :display_name => @user.display_name
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
else
|
||||
default_lang = @user.preferences.where(:k => "diary.default_language").first
|
||||
lang_code = default_lang ? default_lang.v : @user.preferred_language
|
||||
@diary_entry = DiaryEntry.new(:language_code => lang_code)
|
||||
@diary_entry = DiaryEntry.new(entry_params.merge(:language_code => lang_code))
|
||||
set_map_location
|
||||
render :action => "edit"
|
||||
end
|
||||
|
@ -42,9 +46,9 @@ class DiaryEntryController < ApplicationController
|
|||
@diary_entry = DiaryEntry.find(params[:id])
|
||||
|
||||
if @user != @diary_entry.user
|
||||
redirect_to :controller => "diary_entry", :action => "view", :id => params[:id]
|
||||
redirect_to :action => "view", :id => params[:id]
|
||||
elsif params[:diary_entry] && @diary_entry.update_attributes(entry_params)
|
||||
redirect_to :controller => "diary_entry", :action => "view", :id => params[:id]
|
||||
redirect_to :action => "view", :id => params[:id]
|
||||
end
|
||||
|
||||
set_map_location
|
||||
|
@ -57,11 +61,18 @@ class DiaryEntryController < ApplicationController
|
|||
@diary_comment = @entry.comments.build(comment_params)
|
||||
@diary_comment.user = @user
|
||||
if @diary_comment.save
|
||||
if @diary_comment.user != @entry.user
|
||||
Notifier.diary_comment_notification(@diary_comment).deliver_now
|
||||
|
||||
# Notify current subscribers of the new comment
|
||||
@entry.subscribers.visible.each do |user|
|
||||
if @user != user
|
||||
Notifier.diary_comment_notification(@diary_comment, user).deliver_now
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to :controller => "diary_entry", :action => "view", :display_name => @entry.user.display_name, :id => @entry.id
|
||||
# Add the commenter to the subscribers if necessary
|
||||
@entry.subscriptions.create(:user => @user) unless @entry.subscribers.exists?(@user.id)
|
||||
|
||||
redirect_to :action => "view", :display_name => @entry.user.display_name, :id => @entry.id
|
||||
else
|
||||
render :action => "view"
|
||||
end
|
||||
|
@ -69,9 +80,29 @@ class DiaryEntryController < ApplicationController
|
|||
render :action => "no_such_entry", :status => :not_found
|
||||
end
|
||||
|
||||
def subscribe
|
||||
diary_entry = DiaryEntry.find(params[:id])
|
||||
|
||||
diary_entry.subscriptions.create(:user => @user) unless diary_entry.subscribers.exists?(@user.id)
|
||||
|
||||
redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "no_such_entry", :status => :not_found
|
||||
end
|
||||
|
||||
def unsubscribe
|
||||
diary_entry = DiaryEntry.find(params[:id])
|
||||
|
||||
diary_entry.subscriptions.where(:user => @user).delete_all if diary_entry.subscribers.exists?(@user.id)
|
||||
|
||||
redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :action => "no_such_entry", :status => :not_found
|
||||
end
|
||||
|
||||
def list
|
||||
if params[:display_name]
|
||||
@this_user = User.active.find_by_display_name(params[:display_name])
|
||||
@this_user = User.active.find_by(:display_name => params[:display_name])
|
||||
|
||||
if @this_user
|
||||
@title = t "diary_entry.list.user_title", :user => @this_user.display_name
|
||||
|
@ -97,7 +128,7 @@ class DiaryEntryController < ApplicationController
|
|||
return
|
||||
end
|
||||
else
|
||||
@entries = DiaryEntry.joins(:user).where(:users => { :status => %w(active confirmed) })
|
||||
@entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
|
||||
|
||||
if params[:language]
|
||||
@title = t "diary_entry.list.in_language_title", :language => Language.find(params[:language]).english_name
|
||||
|
@ -107,6 +138,8 @@ class DiaryEntryController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
@params = params.permit(:display_name, :friends, :nearby, :language)
|
||||
|
||||
@page = (params[:page] || 1).to_i
|
||||
@page_size = 20
|
||||
|
||||
|
@ -119,7 +152,7 @@ class DiaryEntryController < ApplicationController
|
|||
|
||||
def rss
|
||||
if params[:display_name]
|
||||
user = User.active.find_by_display_name(params[:display_name])
|
||||
user = User.active.find_by(:display_name => params[:display_name])
|
||||
|
||||
if user
|
||||
@entries = user.diary_entries
|
||||
|
@ -127,11 +160,11 @@ class DiaryEntryController < ApplicationController
|
|||
@description = I18n.t("diary_entry.feed.user.description", :user => user.display_name)
|
||||
@link = "http://#{SERVER_URL}/user/#{user.display_name}/diary"
|
||||
else
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
return
|
||||
end
|
||||
else
|
||||
@entries = DiaryEntry.joins(:user).where(:users => { :status => %w(active confirmed) })
|
||||
@entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
|
||||
|
||||
if params[:language]
|
||||
@entries = @entries.where(:language_code => params[:language])
|
||||
|
@ -190,6 +223,8 @@ class DiaryEntryController < ApplicationController
|
|||
# return permitted diary entry parameters
|
||||
def entry_params
|
||||
params.require(:diary_entry).permit(:title, :body, :language_code, :latitude, :longitude)
|
||||
rescue ActionController::ParameterMissing
|
||||
ActionController::Parameters.new.permit(:title, :body, :language_code, :latitude, :longitude)
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -204,7 +239,7 @@ class DiaryEntryController < ApplicationController
|
|||
def require_administrator
|
||||
unless @user.administrator?
|
||||
flash[:error] = t("user.filter.not_an_administrator")
|
||||
redirect_to :controller => "diary_entry", :action => "view"
|
||||
redirect_to :action => "view"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class ExportController < ApplicationController
|
||||
before_action :authorize_web
|
||||
before_action :set_locale
|
||||
before_action :update_totp, :only => [:finish]
|
||||
|
||||
caches_page :embed
|
||||
|
||||
|
@ -11,7 +12,7 @@ class ExportController < ApplicationController
|
|||
|
||||
if format == "osm"
|
||||
# redirect to API map get
|
||||
redirect_to "http://api.openstreetmap.org/api/#{API_VERSION}/map?bbox=#{bbox}"
|
||||
redirect_to :controller => "api", :action => "map", :bbox => bbox
|
||||
|
||||
elsif format == "mapnik"
|
||||
# redirect to a special 'export' cgi script
|
||||
|
@ -22,6 +23,5 @@ class ExportController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def embed
|
||||
end
|
||||
def embed; end
|
||||
end
|
||||
|
|
|
@ -10,22 +10,21 @@ class GeocoderController < ApplicationController
|
|||
before_action :require_oauth, :only => [:search]
|
||||
|
||||
def search
|
||||
normalize_params
|
||||
|
||||
@params = normalize_params
|
||||
@sources = []
|
||||
|
||||
if params[:lat] && params[:lon]
|
||||
if @params[:lat] && @params[:lon]
|
||||
@sources.push "latlon"
|
||||
@sources.push "osm_nominatim_reverse"
|
||||
@sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME)
|
||||
elsif params[:query]
|
||||
if params[:query] =~ /^\d{5}(-\d{4})?$/
|
||||
elsif @params[:query]
|
||||
if @params[:query] =~ /^\d{5}(-\d{4})?$/
|
||||
@sources.push "us_postcode"
|
||||
@sources.push "osm_nominatim"
|
||||
elsif params[:query] =~ /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i
|
||||
elsif @params[:query] =~ /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i
|
||||
@sources.push "uk_postcode"
|
||||
@sources.push "osm_nominatim"
|
||||
elsif params[:query] =~ /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i
|
||||
elsif @params[:query] =~ /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i
|
||||
@sources.push "ca_postcode"
|
||||
@sources.push "osm_nominatim"
|
||||
else
|
||||
|
@ -35,7 +34,7 @@ class GeocoderController < ApplicationController
|
|||
end
|
||||
|
||||
if @sources.empty?
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
else
|
||||
render :layout => map_layout
|
||||
end
|
||||
|
@ -149,7 +148,7 @@ class GeocoderController < ApplicationController
|
|||
exclude = "&exclude_place_ids=#{params[:exclude]}" if params[:exclude]
|
||||
|
||||
# ask nominatim
|
||||
response = fetch_xml("http:#{NOMINATIM_URL}search?format=xml&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}")
|
||||
response = fetch_xml("http:#{NOMINATIM_URL}search?format=xml&extratags=1&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}")
|
||||
|
||||
# extract the results from the response
|
||||
results = response.elements["searchresults"]
|
||||
|
@ -161,7 +160,9 @@ class GeocoderController < ApplicationController
|
|||
@results = []
|
||||
|
||||
# create parameter hash for "more results" link
|
||||
@more_params = params.merge(:exclude => more_url_params["exclude_place_ids"].first)
|
||||
@more_params = params
|
||||
.permit(:query, :minlon, :minlat, :maxlon, :maxlat, :exclude)
|
||||
.merge(:exclude => more_url_params["exclude_place_ids"].first)
|
||||
|
||||
# parse the response
|
||||
results.elements.each("place") do |place|
|
||||
|
@ -179,6 +180,11 @@ class GeocoderController < ApplicationController
|
|||
if klass == "boundary" && type == "administrative"
|
||||
rank = (place.attributes["place_rank"].to_i + 1) / 2
|
||||
prefix_name = t "geocoder.search_osm_nominatim.admin_levels.level#{rank}", :default => prefix_name
|
||||
place.elements["extratags"].elements.each("tag") do |extratag|
|
||||
if extratag.attributes["key"] == "place"
|
||||
prefix_name = t "geocoder.search_osm_nominatim.prefix.place.#{extratag.attributes['value']}", :default => prefix_name
|
||||
end
|
||||
end
|
||||
end
|
||||
prefix = t "geocoder.search_osm_nominatim.prefix_format", :name => prefix_name
|
||||
object_type = place.attributes["osm_type"]
|
||||
|
@ -311,29 +317,30 @@ class GeocoderController < ApplicationController
|
|||
end
|
||||
|
||||
def normalize_params
|
||||
query = params[:query]
|
||||
return unless query
|
||||
if query = params[:query]
|
||||
query.strip!
|
||||
|
||||
query.strip!
|
||||
if latlon = query.match(/^([NS])\s*(\d{1,3}(\.\d*)?)\W*([EW])\s*(\d{1,3}(\.\d*)?)$/).try(:captures) # [NSEW] decimal degrees
|
||||
params.merge!(nsew_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^(\d{1,3}(\.\d*)?)\s*([NS])\W*(\d{1,3}(\.\d*)?)\s*([EW])$/).try(:captures) # decimal degrees [NSEW]
|
||||
params.merge!(nsew_to_decdeg(latlon)).delete(:query)
|
||||
|
||||
if latlon = query.match(/^([NS])\s*(\d{1,3}(\.\d*)?)\W*([EW])\s*(\d{1,3}(\.\d*)?)$/).try(:captures) # [NSEW] decimal degrees
|
||||
params.merge!(nsew_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^(\d{1,3}(\.\d*)?)\s*([NS])\W*(\d{1,3}(\.\d*)?)\s*([EW])$/).try(:captures) # decimal degrees [NSEW]
|
||||
params.merge!(nsew_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?$/).try(:captures) # [NSEW] degrees, decimal minutes
|
||||
params.merge!(ddm_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?\s*([NS])\W*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?\s*([EW])$/).try(:captures) # degrees, decimal minutes [NSEW]
|
||||
params.merge!(ddm_to_decdeg(latlon)).delete(:query)
|
||||
|
||||
elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?$/).try(:captures) # [NSEW] degrees, decimal minutes
|
||||
params.merge!(ddm_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?\s*([NS])\W*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?['′]?\s*([EW])$/).try(:captures) # degrees, decimal minutes [NSEW]
|
||||
params.merge!(ddm_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]?$/).try(:captures) # [NSEW] degrees, minutes, decimal seconds
|
||||
params.merge!(dms_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]\s*([NS])\W*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]?\s*([EW])$/).try(:captures) # degrees, minutes, decimal seconds [NSEW]
|
||||
params.merge!(dms_to_decdeg(latlon)).delete(:query)
|
||||
|
||||
elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]?$/).try(:captures) # [NSEW] degrees, minutes, decimal seconds
|
||||
params.merge!(dms_to_decdeg(latlon)).delete(:query)
|
||||
elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]\s*([NS])\W*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(\.\d*)?)?["″]?\s*([EW])$/).try(:captures) # degrees, minutes, decimal seconds [NSEW]
|
||||
params.merge!(dms_to_decdeg(latlon)).delete(:query)
|
||||
|
||||
elsif latlon = query.match(/^\s*([+-]?\d+(\.\d*)?)\s*[\s,]\s*([+-]?\d+(\.\d*)?)\s*$/)
|
||||
params.merge!(:lat => latlon[1].to_f, :lon => latlon[3].to_f).delete(:query)
|
||||
elsif latlon = query.match(/^\s*([+-]?\d+(\.\d*)?)\s*[\s,]\s*([+-]?\d+(\.\d*)?)\s*$/)
|
||||
params.merge!(:lat => latlon[1].to_f, :lon => latlon[3].to_f).delete(:query)
|
||||
end
|
||||
end
|
||||
|
||||
params.permit(:query, :lat, :lon, :zoom, :minlat, :minlon, :maxlat, :maxlon)
|
||||
end
|
||||
|
||||
def nsew_to_decdeg(captures)
|
||||
|
|
|
@ -13,7 +13,7 @@ class MessageController < ApplicationController
|
|||
# clicks send.
|
||||
# The display_name param is the display name of the user that the message is being sent to.
|
||||
def new
|
||||
if params[:message]
|
||||
if request.post?
|
||||
if @user.sent_messages.where("sent_on >= ?", Time.now.getutc - 1.hour).count >= MAX_MESSAGES_PER_HOUR
|
||||
flash[:error] = t "message.new.limit_exceeded"
|
||||
else
|
||||
|
@ -25,12 +25,12 @@ class MessageController < ApplicationController
|
|||
if @message.save
|
||||
flash[:notice] = t "message.new.message_sent"
|
||||
Notifier.message_notification(@message).deliver_now
|
||||
redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
|
||||
redirect_to :action => "inbox", :display_name => @user.display_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@message ||= Message.new(:recipient => @this_user)
|
||||
@message ||= Message.new(message_params.merge(:recipient => @this_user))
|
||||
@title = t "message.new.title"
|
||||
end
|
||||
|
||||
|
@ -39,7 +39,7 @@ class MessageController < ApplicationController
|
|||
message = Message.find(params[:message_id])
|
||||
|
||||
if message.to_user_id == @user.id
|
||||
message.update_attribute(:message_read, true)
|
||||
message.update(:message_read => true)
|
||||
|
||||
@message = Message.new(
|
||||
:recipient => message.sender,
|
||||
|
@ -81,7 +81,7 @@ class MessageController < ApplicationController
|
|||
@title = t "message.inbox.title"
|
||||
if @user && params[:display_name] == @user.display_name
|
||||
else
|
||||
redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
|
||||
redirect_to :action => "inbox", :display_name => @user.display_name
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -90,7 +90,7 @@ class MessageController < ApplicationController
|
|||
@title = t "message.outbox.title"
|
||||
if @user && params[:display_name] == @user.display_name
|
||||
else
|
||||
redirect_to :controller => "message", :action => "outbox", :display_name => @user.display_name
|
||||
redirect_to :action => "outbox", :display_name => @user.display_name
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -107,7 +107,7 @@ class MessageController < ApplicationController
|
|||
@message.message_read = message_read
|
||||
if @message.save && !request.xhr?
|
||||
flash[:notice] = notice
|
||||
redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
|
||||
redirect_to :action => "inbox", :display_name => @user.display_name
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
@title = t "message.no_such_message.title"
|
||||
|
@ -125,7 +125,7 @@ class MessageController < ApplicationController
|
|||
if params[:referer]
|
||||
redirect_to params[:referer]
|
||||
else
|
||||
redirect_to :controller => "message", :action => "inbox", :display_name => @user.display_name
|
||||
redirect_to :action => "inbox", :display_name => @user.display_name
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
|
@ -139,5 +139,7 @@ class MessageController < ApplicationController
|
|||
# return permitted message parameters
|
||||
def message_params
|
||||
params.require(:message).permit(:title, :body)
|
||||
rescue ActionController::ParameterMissing
|
||||
ActionController::Parameters.new.permit(:title, :body)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,7 @@ class NodeController < ApplicationController
|
|||
|
||||
# Assume that Node.from_xml has thrown an exception if there is an error parsing the xml
|
||||
node.create_with_history @user
|
||||
render :text => node.id.to_s, :content_type => "text/plain"
|
||||
render :plain => node.id.to_s
|
||||
end
|
||||
|
||||
# Dump the details on a node given in params[:id]
|
||||
|
@ -29,9 +29,9 @@ class NodeController < ApplicationController
|
|||
response.last_modified = node.timestamp
|
||||
|
||||
if node.visible
|
||||
render :text => node.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => node.to_xml.to_s
|
||||
else
|
||||
render :text => "", :status => :gone
|
||||
head :gone
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -45,7 +45,7 @@ class NodeController < ApplicationController
|
|||
end
|
||||
|
||||
node.update_from(new_node, @user)
|
||||
render :text => node.version.to_s, :content_type => "text/plain"
|
||||
render :plain => node.version.to_s
|
||||
end
|
||||
|
||||
# Delete a node. Doesn't actually delete it, but retains its history
|
||||
|
@ -59,7 +59,7 @@ class NodeController < ApplicationController
|
|||
raise OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})")
|
||||
end
|
||||
node.delete_with_history!(new_node, @user)
|
||||
render :text => node.version.to_s, :content_type => "text/plain"
|
||||
render :plain => node.version.to_s
|
||||
end
|
||||
|
||||
# Dump the details on many nodes whose ids are given in the "nodes" parameter.
|
||||
|
@ -79,6 +79,6 @@ class NodeController < ApplicationController
|
|||
doc.root << node.to_xml_node
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class NotesController < ApplicationController
|
||||
layout "site", :only => [:mine]
|
||||
|
||||
skip_before_action :verify_authenticity_token, :except => [:mine]
|
||||
before_action :check_api_readable
|
||||
before_action :authorize_web, :only => [:mine]
|
||||
before_action :setup_user_auth, :only => [:create, :comment]
|
||||
|
@ -127,7 +128,7 @@ class NotesController < ApplicationController
|
|||
comment = params[:text]
|
||||
|
||||
# Find the note and check it is valid
|
||||
@note = Note.find_by_id(id)
|
||||
@note = Note.find_by(:id => id)
|
||||
raise OSM::APINotFoundError unless @note
|
||||
raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
|
||||
raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
|
||||
|
@ -157,7 +158,7 @@ class NotesController < ApplicationController
|
|||
comment = params[:text]
|
||||
|
||||
# Find the note and check it is valid
|
||||
@note = Note.find_by_id(id)
|
||||
@note = Note.find_by(:id => id)
|
||||
raise OSM::APINotFoundError unless @note
|
||||
raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? || @user.moderator?
|
||||
raise OSM::APINoteAlreadyOpenError.new(@note) unless @note.closed? || !@note.visible?
|
||||
|
@ -277,7 +278,8 @@ class NotesController < ApplicationController
|
|||
# Display a list of notes by a specified user
|
||||
def mine
|
||||
if params[:display_name]
|
||||
if @this_user = User.active.find_by_display_name(params[:display_name])
|
||||
if @this_user = User.active.find_by(:display_name => params[:display_name])
|
||||
@params = params.permit(:display_name)
|
||||
@title = t "note.mine.title", :user => @this_user.display_name
|
||||
@heading = t "note.mine.heading", :user => @this_user.display_name
|
||||
@description = t "note.mine.subheading", :user => render_to_string(:partial => "user", :object => @this_user)
|
||||
|
@ -285,7 +287,7 @@ class NotesController < ApplicationController
|
|||
@page_size = 10
|
||||
@notes = @this_user.notes
|
||||
@notes = @notes.visible unless @user && @user.moderator?
|
||||
@notes = @notes.order("updated_at DESC, id").uniq.offset((@page - 1) * @page_size).limit(@page_size).preload(:comments => :author).to_a
|
||||
@notes = @notes.order("updated_at DESC, id").distinct.offset((@page - 1) * @page_size).limit(@page_size).preload(:comments => :author).to_a
|
||||
else
|
||||
@title = t "user.no_such_user.title"
|
||||
@not_found_user = params[:display_name]
|
||||
|
@ -316,7 +318,7 @@ class NotesController < ApplicationController
|
|||
end
|
||||
|
||||
##
|
||||
# Generate a condition to choose which bugs we want based
|
||||
# Generate a condition to choose which notes we want based
|
||||
# on their status and the user's request parameters
|
||||
def closed_condition(notes)
|
||||
closed_since = if params[:closed]
|
||||
|
@ -345,7 +347,7 @@ class NotesController < ApplicationController
|
|||
attributes[:author_ip] = request.remote_ip
|
||||
end
|
||||
|
||||
comment = note.comments.create(attributes)
|
||||
comment = note.comments.create!(attributes)
|
||||
|
||||
note.comments.map(&:author).uniq.each do |user|
|
||||
if notify && user && user != @user && user.visible?
|
||||
|
|
|
@ -27,7 +27,7 @@ class OauthController < ApplicationController
|
|||
end
|
||||
|
||||
def revoke
|
||||
@token = current_user.oauth_tokens.find_by_token params[:token]
|
||||
@token = current_user.oauth_tokens.find_by :token => params[:token]
|
||||
if @token
|
||||
@token.invalidate!
|
||||
flash[:notice] = t("oauth.revoke.flash", :application => @token.client_application.name)
|
||||
|
@ -49,7 +49,7 @@ class OauthController < ApplicationController
|
|||
else
|
||||
@token.oob? ? @token.client_application.callback_url : @token.callback_url
|
||||
end
|
||||
@redirect_url = URI.parse(callback_url) unless callback_url.blank?
|
||||
@redirect_url = URI.parse(callback_url) if callback_url.present?
|
||||
|
||||
if @redirect_url.to_s.blank?
|
||||
render :action => "authorize_success"
|
||||
|
|
|
@ -33,12 +33,12 @@ class OldController < ApplicationController
|
|||
doc.root << element.to_xml_node
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
def version
|
||||
if @old_element.redacted? && !show_redactions?
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
|
||||
else
|
||||
response.last_modified = @old_element.timestamp
|
||||
|
@ -46,7 +46,7 @@ class OldController < ApplicationController
|
|||
doc = OSM::API.new.get_xml_doc
|
||||
doc.root << @old_element.to_xml_node
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,7 +64,7 @@ class OldController < ApplicationController
|
|||
end
|
||||
|
||||
# just return an empty 200 OK for success
|
||||
render :text => ""
|
||||
head :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -32,11 +32,9 @@ class RedactionsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
def show; end
|
||||
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
# note - don't update the user ID
|
||||
|
|
|
@ -16,16 +16,16 @@ class RelationController < ApplicationController
|
|||
|
||||
# Assume that Relation.from_xml has thrown an exception if there is an error parsing the xml
|
||||
relation.create_with_history @user
|
||||
render :text => relation.id.to_s, :content_type => "text/plain"
|
||||
render :plain => relation.id.to_s
|
||||
end
|
||||
|
||||
def read
|
||||
relation = Relation.find(params[:id])
|
||||
response.last_modified = relation.timestamp
|
||||
if relation.visible
|
||||
render :text => relation.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => relation.to_xml.to_s
|
||||
else
|
||||
render :text => "", :status => :gone
|
||||
head :gone
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -40,7 +40,7 @@ class RelationController < ApplicationController
|
|||
end
|
||||
|
||||
relation.update_from new_relation, @user
|
||||
render :text => relation.version.to_s, :content_type => "text/plain"
|
||||
render :plain => relation.version.to_s
|
||||
end
|
||||
|
||||
def delete
|
||||
|
@ -48,9 +48,9 @@ class RelationController < ApplicationController
|
|||
new_relation = Relation.from_xml(request.raw_post)
|
||||
if new_relation && new_relation.id == relation.id
|
||||
relation.delete_with_history!(new_relation, @user)
|
||||
render :text => relation.version.to_s, :content_type => "text/plain"
|
||||
render :plain => relation.version.to_s
|
||||
else
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -119,10 +119,10 @@ class RelationController < ApplicationController
|
|||
|
||||
# finally add self and output
|
||||
doc.root << relation.to_xml_node(visible_members, changeset_cache, user_display_name_cache)
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
|
||||
else
|
||||
render :text => "", :status => :gone
|
||||
head :gone
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -143,7 +143,7 @@ class RelationController < ApplicationController
|
|||
doc.root << relation.to_xml_node
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
def relations_for_way
|
||||
|
@ -167,6 +167,6 @@ class RelationController < ApplicationController
|
|||
doc.root << relation.to_xml_node if relation.visible
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,13 +33,13 @@ class SearchController < ApplicationController
|
|||
|
||||
if do_nodes
|
||||
response.headers["Error"] = "Searching of nodes is currently unavailable"
|
||||
render :text => "", :status => :service_unavailable
|
||||
head :service_unavailable
|
||||
return false
|
||||
end
|
||||
|
||||
unless value
|
||||
response.headers["Error"] = "Searching for a key without value is currently unavailable"
|
||||
render :text => "", :status => :service_unavailable
|
||||
head :service_unavailable
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -94,6 +94,6 @@ class SearchController < ApplicationController
|
|||
doc.root << rel.to_xml_node(nil, changeset_cache, user_display_name_cache)
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ class SiteController < ApplicationController
|
|||
before_action :redirect_map_params, :only => [:index, :edit, :export]
|
||||
before_action :require_user, :only => [:welcome]
|
||||
before_action :require_oauth, :only => [:index]
|
||||
before_action :update_totp, :only => [:index]
|
||||
|
||||
def index
|
||||
unless STATUS == :database_readonly || STATUS == :database_offline
|
||||
|
@ -49,7 +50,7 @@ class SiteController < ApplicationController
|
|||
new_params[:anchor] = "map=#{zoom}/#{lat}/#{lon}"
|
||||
new_params[:anchor] += "&layers=#{params[:layers]}" if params.key? :layers
|
||||
|
||||
redirect_to Hash[new_params]
|
||||
redirect_to new_params.to_unsafe_h
|
||||
end
|
||||
|
||||
def key
|
||||
|
@ -68,6 +69,14 @@ class SiteController < ApplicationController
|
|||
require_user
|
||||
end
|
||||
|
||||
if %w[potlatch potlatch2].include?(editor)
|
||||
append_content_security_policy_directives(
|
||||
:object_src => %w[*],
|
||||
:plugin_types => %w[application/x-shockwave-flash],
|
||||
:script_src => %w['unsafe-inline']
|
||||
)
|
||||
end
|
||||
|
||||
if params[:node]
|
||||
bbox = Node.find(params[:node]).bbox.to_unscaled
|
||||
@lat = bbox.centre_lat
|
||||
|
@ -83,7 +92,7 @@ class SiteController < ApplicationController
|
|||
@lat = note.lat
|
||||
@lon = note.lon
|
||||
@zoom = 17
|
||||
elsif params[:gpx]
|
||||
elsif params[:gpx] && @user
|
||||
trace = Trace.visible_to(@user).find(params[:gpx])
|
||||
@lat = trace.latitude
|
||||
@lon = trace.longitude
|
||||
|
@ -95,26 +104,27 @@ class SiteController < ApplicationController
|
|||
@locale = params[:copyright_locale] || I18n.locale
|
||||
end
|
||||
|
||||
def welcome
|
||||
end
|
||||
def welcome; end
|
||||
|
||||
def help
|
||||
end
|
||||
def help; end
|
||||
|
||||
def about
|
||||
end
|
||||
def about; end
|
||||
|
||||
def export
|
||||
end
|
||||
def export; end
|
||||
|
||||
def offline
|
||||
end
|
||||
def offline; end
|
||||
|
||||
def preview
|
||||
render :text => RichText.new(params[:format], params[:text]).to_html
|
||||
render :html => RichText.new(params[:type], params[:text]).to_html
|
||||
end
|
||||
|
||||
def id
|
||||
append_content_security_policy_directives(
|
||||
:connect_src => %w[taginfo.openstreetmap.org *.mapillary.com],
|
||||
:img_src => %w[*],
|
||||
:script_src => %w[dev.virtualearth.net]
|
||||
)
|
||||
|
||||
render "id", :layout => false
|
||||
end
|
||||
|
||||
|
@ -148,7 +158,7 @@ class SiteController < ApplicationController
|
|||
end
|
||||
|
||||
if anchor.present?
|
||||
redirect_to Hash[params].merge(:anchor => anchor.join("&"))
|
||||
redirect_to params.to_unsafe_h.merge(:anchor => anchor.join("&"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -92,7 +92,7 @@ class SwfController < ApplicationController
|
|||
m = pack_rect(bounds_left, bounds_right, bounds_bottom, bounds_top) + 0.chr + 12.chr + pack_u16(1) + m
|
||||
m = "FWS" + 6.chr + pack_u32(m.length + 8) + m
|
||||
|
||||
render :text => m, :content_type => "application/x-shockwave-flash"
|
||||
render :body => m, :content_type => "application/x-shockwave-flash"
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -161,10 +161,10 @@ class SwfController < ApplicationController
|
|||
def swf_record(id, r)
|
||||
if r.length > 62
|
||||
# Long header: tag id, 0x3F, length
|
||||
return pack_u16((id << 6) + 0x3F) + pack_u32(r.length) + r
|
||||
pack_u16((id << 6) + 0x3F) + pack_u32(r.length) + r
|
||||
else
|
||||
# Short header: tag id, length
|
||||
return pack_u16((id << 6) + r.length) + r
|
||||
pack_u16((id << 6) + r.length) + r
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -195,7 +195,7 @@ class SwfController < ApplicationController
|
|||
# Find number of bits required to store arbitrary-length binary
|
||||
|
||||
def length_sb(n)
|
||||
Math.frexp(n + (n == 0 ? 1 : 0))[1] + 1
|
||||
Math.frexp(n + (n.zero? ? 1 : 0))[1] + 1
|
||||
end
|
||||
|
||||
# ====================================================================
|
||||
|
|
|
@ -21,7 +21,7 @@ class TraceController < ApplicationController
|
|||
def list
|
||||
# from display name, pick up user id if one user's traces only
|
||||
display_name = params[:display_name]
|
||||
unless display_name.blank?
|
||||
if display_name.present?
|
||||
target_user = User.active.where(:display_name => display_name).first
|
||||
if target_user.nil?
|
||||
render_unknown_user display_name
|
||||
|
@ -59,11 +59,13 @@ class TraceController < ApplicationController
|
|||
|
||||
@traces = @traces.tagged(params[:tag]) if params[:tag]
|
||||
|
||||
@params = params.permit(:display_name, :tag)
|
||||
|
||||
@page = (params[:page] || 1).to_i
|
||||
@page_size = 20
|
||||
|
||||
@traces = @traces.visible
|
||||
@traces = @traces.order("timestamp DESC")
|
||||
@traces = @traces.order(:id => :desc)
|
||||
@traces = @traces.offset((@page - 1) * @page_size)
|
||||
@traces = @traces.limit(@page_size)
|
||||
@traces = @traces.includes(:user, :tags)
|
||||
|
@ -95,15 +97,15 @@ class TraceController < ApplicationController
|
|||
@title = t "trace.view.title", :name => @trace.name
|
||||
else
|
||||
flash[:error] = t "trace.view.trace_not_found"
|
||||
redirect_to :controller => "trace", :action => "list"
|
||||
redirect_to :action => "list"
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
flash[:error] = t "trace.view.trace_not_found"
|
||||
redirect_to :controller => "trace", :action => "list"
|
||||
redirect_to :action => "list"
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:trace]
|
||||
if request.post?
|
||||
logger.info(params[:trace][:gpx_file].class.name)
|
||||
|
||||
if params[:trace][:gpx_file].respond_to?(:read)
|
||||
|
@ -145,32 +147,32 @@ class TraceController < ApplicationController
|
|||
|
||||
if trace.visible? && (trace.public? || (@user && @user == trace.user))
|
||||
if Acl.no_trace_download(request.remote_ip)
|
||||
render :text => "", :status => :forbidden
|
||||
elsif request.format == Mime::XML
|
||||
head :forbidden
|
||||
elsif request.format == Mime[:xml]
|
||||
send_file(trace.xml_file, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment")
|
||||
elsif request.format == Mime::GPX
|
||||
elsif request.format == Mime[:gpx]
|
||||
send_file(trace.xml_file, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment")
|
||||
else
|
||||
send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => "attachment")
|
||||
end
|
||||
else
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def edit
|
||||
@trace = Trace.find(params[:id])
|
||||
|
||||
if !@trace.visible?
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
elsif @user.nil? || @trace.user != @user
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
else
|
||||
@title = t "trace.edit.title", :name => @trace.name
|
||||
|
||||
if params[:trace]
|
||||
if request.post? && params[:trace]
|
||||
@trace.description = params[:trace][:description]
|
||||
@trace.tagstring = params[:trace][:tagstring]
|
||||
@trace.visibility = params[:trace][:visibility]
|
||||
|
@ -180,16 +182,16 @@ class TraceController < ApplicationController
|
|||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def delete
|
||||
trace = Trace.find(params[:id])
|
||||
|
||||
if !trace.visible?
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
elsif @user.nil? || trace.user != @user
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
else
|
||||
trace.visible = false
|
||||
trace.save
|
||||
|
@ -197,7 +199,7 @@ class TraceController < ApplicationController
|
|||
redirect_to :action => :list, :display_name => @user.display_name
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def georss
|
||||
|
@ -221,13 +223,13 @@ class TraceController < ApplicationController
|
|||
expires_in 7.days, :private => !trace.public?, :public => trace.public?
|
||||
send_file(trace.large_picture_name, :filename => "#{trace.id}.gif", :type => "image/gif", :disposition => "inline")
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
else
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def icon
|
||||
|
@ -238,22 +240,22 @@ class TraceController < ApplicationController
|
|||
expires_in 7.days, :private => !trace.public?, :public => trace.public?
|
||||
send_file(trace.icon_picture_name, :filename => "#{trace.id}_icon.gif", :type => "image/gif", :disposition => "inline")
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
else
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :text => "", :status => :not_found
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def api_read
|
||||
trace = Trace.visible.find(params[:id])
|
||||
|
||||
if trace.public? || trace.user == @user
|
||||
render :text => trace.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => trace.to_xml.to_s
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -272,9 +274,9 @@ class TraceController < ApplicationController
|
|||
trace.visibility = new_trace.visibility
|
||||
trace.save!
|
||||
|
||||
render :text => "", :status => :ok
|
||||
head :ok
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -285,9 +287,9 @@ class TraceController < ApplicationController
|
|||
trace.visible = false
|
||||
trace.save!
|
||||
|
||||
render :text => "", :status => :ok
|
||||
head :ok
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -295,15 +297,15 @@ class TraceController < ApplicationController
|
|||
trace = Trace.visible.find(params[:id])
|
||||
|
||||
if trace.public? || trace.user == @user
|
||||
if request.format == Mime::XML
|
||||
if request.format == Mime[:xml]
|
||||
send_file(trace.xml_file, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment")
|
||||
elsif request.format == Mime::GPX
|
||||
elsif request.format == Mime[:gpx]
|
||||
send_file(trace.xml_file, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment")
|
||||
else
|
||||
send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => "attachment")
|
||||
end
|
||||
else
|
||||
render :text => "", :status => :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -324,14 +326,14 @@ class TraceController < ApplicationController
|
|||
do_create(params[:file], tags, description, visibility)
|
||||
|
||||
if @trace.id
|
||||
render :text => @trace.id.to_s, :content_type => "text/plain"
|
||||
render :plain => @trace.id.to_s
|
||||
elsif @trace.valid?
|
||||
render :text => "", :status => :internal_server_error
|
||||
head :internal_server_error
|
||||
else
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
end
|
||||
else
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ class UserBlocksController < ApplicationController
|
|||
before_action :check_database_writable, :only => [:create, :update, :revoke]
|
||||
|
||||
def index
|
||||
@params = params.permit
|
||||
@user_blocks_pages, @user_blocks = paginate(:user_blocks,
|
||||
:include => [:user, :creator, :revoker],
|
||||
:order => "user_blocks.ends_at DESC",
|
||||
|
@ -88,6 +89,7 @@ class UserBlocksController < ApplicationController
|
|||
##
|
||||
# shows a list of all the blocks on the given user
|
||||
def blocks_on
|
||||
@params = params.permit(:display_name)
|
||||
@user_blocks_pages, @user_blocks = paginate(:user_blocks,
|
||||
:include => [:user, :creator, :revoker],
|
||||
:conditions => { :user_id => @this_user.id },
|
||||
|
@ -98,6 +100,7 @@ class UserBlocksController < ApplicationController
|
|||
##
|
||||
# shows a list of all the blocks by the given user.
|
||||
def blocks_by
|
||||
@params = params.permit(:display_name)
|
||||
@user_blocks_pages, @user_blocks = paginate(:user_blocks,
|
||||
:include => [:user, :creator, :revoker],
|
||||
:conditions => { :creator_id => @this_user.id },
|
||||
|
|
|
@ -81,7 +81,7 @@ class UserController < ApplicationController
|
|||
@user.terms_agreed = Time.now.getutc
|
||||
@user.terms_seen = true
|
||||
|
||||
if @user.auth_uid.nil? || @user.auth_uid.empty?
|
||||
if @user.auth_uid.blank?
|
||||
@user.auth_provider = nil
|
||||
@user.auth_uid = nil
|
||||
end
|
||||
|
@ -142,14 +142,14 @@ class UserController < ApplicationController
|
|||
@user.data_public = true
|
||||
@user.save
|
||||
flash[:notice] = t "user.go_public.flash success"
|
||||
redirect_to :controller => "user", :action => "account", :display_name => @user.display_name
|
||||
redirect_to :action => "account", :display_name => @user.display_name
|
||||
end
|
||||
|
||||
def lost_password
|
||||
@title = t "user.lost_password.title"
|
||||
|
||||
if params[:user] && params[:user][:email]
|
||||
user = User.visible.find_by_email(params[:user][:email])
|
||||
user = User.visible.find_by(:email => params[:user][:email])
|
||||
|
||||
if user.nil?
|
||||
users = User.visible.where("LOWER(email) = LOWER(?)", params[:user][:email])
|
||||
|
@ -172,7 +172,7 @@ class UserController < ApplicationController
|
|||
@title = t "user.reset_password.title"
|
||||
|
||||
if params[:token]
|
||||
token = UserToken.find_by_token(params[:token])
|
||||
token = UserToken.find_by(:token => params[:token])
|
||||
|
||||
if token
|
||||
@user = token.user
|
||||
|
@ -194,7 +194,7 @@ class UserController < ApplicationController
|
|||
redirect_to :action => "lost_password"
|
||||
end
|
||||
else
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -268,9 +268,9 @@ class UserController < ApplicationController
|
|||
def logout
|
||||
@title = t "user.logout.title"
|
||||
|
||||
if params[:session] == request.session_options[:id]
|
||||
if params[:session] == session.id
|
||||
if session[:token]
|
||||
token = UserToken.find_by_token(session[:token])
|
||||
token = UserToken.find_by(:token => session[:token])
|
||||
token.destroy if token
|
||||
session.delete(:token)
|
||||
end
|
||||
|
@ -286,7 +286,7 @@ class UserController < ApplicationController
|
|||
|
||||
def confirm
|
||||
if request.post?
|
||||
token = UserToken.find_by_token(params[:confirm_string])
|
||||
token = UserToken.find_by(:token => params[:confirm_string])
|
||||
if token && token.user.active?
|
||||
flash[:error] = t("user.confirm.already active")
|
||||
redirect_to :action => "login"
|
||||
|
@ -303,7 +303,7 @@ class UserController < ApplicationController
|
|||
token.destroy
|
||||
|
||||
if session[:token]
|
||||
token = UserToken.find_by_token(session[:token])
|
||||
token = UserToken.find_by(:token => session[:token])
|
||||
session.delete(:token)
|
||||
else
|
||||
token = nil
|
||||
|
@ -321,15 +321,15 @@ class UserController < ApplicationController
|
|||
end
|
||||
end
|
||||
else
|
||||
user = User.find_by_display_name(params[:display_name])
|
||||
user = User.find_by(:display_name => params[:display_name])
|
||||
|
||||
redirect_to root_path if user.nil? || user.active?
|
||||
end
|
||||
end
|
||||
|
||||
def confirm_resend
|
||||
user = User.find_by_display_name(params[:display_name])
|
||||
token = UserToken.find_by_token(session[:token])
|
||||
user = User.find_by(:display_name => params[:display_name])
|
||||
token = UserToken.find_by(:token => session[:token])
|
||||
|
||||
if user.nil? || token.nil? || token.user != user
|
||||
flash[:error] = t "user.confirm_resend.failure", :name => params[:display_name]
|
||||
|
@ -343,7 +343,7 @@ class UserController < ApplicationController
|
|||
|
||||
def confirm_email
|
||||
if request.post?
|
||||
token = UserToken.find_by_token(params[:confirm_string])
|
||||
token = UserToken.find_by(:token => params[:confirm_string])
|
||||
if token && token.user.new_email?
|
||||
@user = token.user
|
||||
@user.email = @user.new_email
|
||||
|
@ -375,7 +375,7 @@ class UserController < ApplicationController
|
|||
if @this_user.visible?
|
||||
render :action => :api_read, :content_type => "text/xml"
|
||||
else
|
||||
render :text => "", :status => :gone
|
||||
head :gone
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -389,11 +389,11 @@ class UserController < ApplicationController
|
|||
@user.traces.reload.each do |trace|
|
||||
doc.root << trace.to_xml_node
|
||||
end
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
def view
|
||||
@this_user = User.find_by_display_name(params[:display_name])
|
||||
@this_user = User.find_by(:display_name => params[:display_name])
|
||||
|
||||
if @this_user &&
|
||||
(@this_user.visible? || (@user && @user.administrator?))
|
||||
|
@ -404,7 +404,7 @@ class UserController < ApplicationController
|
|||
end
|
||||
|
||||
def make_friend
|
||||
@new_friend = User.find_by_display_name(params[:display_name])
|
||||
@new_friend = User.find_by(:display_name => params[:display_name])
|
||||
|
||||
if @new_friend
|
||||
if request.post?
|
||||
|
@ -423,7 +423,7 @@ class UserController < ApplicationController
|
|||
if params[:referer]
|
||||
redirect_to params[:referer]
|
||||
else
|
||||
redirect_to :controller => "user", :action => "view"
|
||||
redirect_to :action => "view"
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -432,12 +432,12 @@ class UserController < ApplicationController
|
|||
end
|
||||
|
||||
def remove_friend
|
||||
@friend = User.find_by_display_name(params[:display_name])
|
||||
@friend = User.find_by(:display_name => params[:display_name])
|
||||
|
||||
if @friend
|
||||
if request.post?
|
||||
if @user.is_friends_with?(@friend)
|
||||
Friend.delete_all "user_id = #{@user.id} AND friend_user_id = #{@friend.id}"
|
||||
Friend.where(:user_id => @user.id, :friend_user_id => @friend.id).delete_all
|
||||
flash[:notice] = t "user.remove_friend.success", :name => @friend.display_name
|
||||
else
|
||||
flash[:error] = t "user.remove_friend.not_a_friend", :name => @friend.display_name
|
||||
|
@ -446,7 +446,7 @@ class UserController < ApplicationController
|
|||
if params[:referer]
|
||||
redirect_to params[:referer]
|
||||
else
|
||||
redirect_to :controller => "user", :action => "view"
|
||||
redirect_to :action => "view"
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -459,14 +459,14 @@ class UserController < ApplicationController
|
|||
def set_status
|
||||
@this_user.status = params[:status]
|
||||
@this_user.save
|
||||
redirect_to :controller => "user", :action => "view", :display_name => params[:display_name]
|
||||
redirect_to :action => "view", :display_name => params[:display_name]
|
||||
end
|
||||
|
||||
##
|
||||
# delete a user, marking them as deleted and removing personal data
|
||||
def delete
|
||||
@this_user.delete
|
||||
redirect_to :controller => "user", :action => "view", :display_name => params[:display_name]
|
||||
redirect_to :action => "view", :display_name => params[:display_name]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -480,9 +480,11 @@ class UserController < ApplicationController
|
|||
|
||||
redirect_to url_for(:status => params[:status], :ip => params[:ip], :page => params[:page])
|
||||
else
|
||||
@params = params.permit(:status, :ip)
|
||||
|
||||
conditions = {}
|
||||
conditions[:status] = params[:status] if params[:status]
|
||||
conditions[:creation_ip] = params[:ip] if params[:ip]
|
||||
conditions[:status] = @params[:status] if @params[:status]
|
||||
conditions[:creation_ip] = @params[:ip] if @params[:ip]
|
||||
|
||||
@user_pages, @users = paginate(:users,
|
||||
:conditions => conditions,
|
||||
|
@ -494,7 +496,7 @@ class UserController < ApplicationController
|
|||
##
|
||||
# omniauth success callback
|
||||
def auth_success
|
||||
auth_info = env["omniauth.auth"]
|
||||
auth_info = request.env["omniauth.auth"]
|
||||
|
||||
provider = auth_info[:provider]
|
||||
uid = auth_info[:uid]
|
||||
|
@ -530,11 +532,11 @@ class UserController < ApplicationController
|
|||
|
||||
redirect_to :action => "terms"
|
||||
else
|
||||
user = User.find_by_auth_provider_and_auth_uid(provider, uid)
|
||||
user = User.find_by(:auth_provider => provider, :auth_uid => uid)
|
||||
|
||||
if user.nil? && provider == "google"
|
||||
openid_url = auth_info[:extra][:id_info]["openid_id"]
|
||||
user = User.find_by_auth_provider_and_auth_uid("openid", openid_url) if openid_url
|
||||
user = User.find_by(:auth_provider => "openid", :auth_uid => openid_url) if openid_url
|
||||
user.update(:auth_provider => provider, :auth_uid => uid) if user
|
||||
end
|
||||
|
||||
|
@ -543,7 +545,7 @@ class UserController < ApplicationController
|
|||
when "pending" then
|
||||
unconfirmed_login(user)
|
||||
when "active", "confirmed" then
|
||||
successful_login(user, env["omniauth.params"]["referer"])
|
||||
successful_login(user, request.env["omniauth.params"]["referer"])
|
||||
when "suspended" then
|
||||
failed_login t("user.login.account is suspended", :webmaster => "mailto:#{SUPPORT_EMAIL}")
|
||||
else
|
||||
|
@ -601,15 +603,15 @@ class UserController < ApplicationController
|
|||
# try and come up with the correct URL based on what the user entered
|
||||
def openid_expand_url(openid_url)
|
||||
if openid_url.nil?
|
||||
return nil
|
||||
nil
|
||||
elsif openid_url.match(%r{(.*)gmail.com(/?)$}) || openid_url.match(%r{(.*)googlemail.com(/?)$})
|
||||
# Special case gmail.com as it is potentially a popular OpenID
|
||||
# provider and, unlike yahoo.com, where it works automatically, Google
|
||||
# have hidden their OpenID endpoint somewhere obscure this making it
|
||||
# somewhat less user friendly.
|
||||
return "https://www.google.com/accounts/o8/id"
|
||||
"https://www.google.com/accounts/o8/id"
|
||||
else
|
||||
return openid_url
|
||||
openid_url
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -628,7 +630,7 @@ class UserController < ApplicationController
|
|||
# - If they were referred to the login, send them back there.
|
||||
# - Otherwise, send them to the home page.
|
||||
if REQUIRE_TERMS_SEEN && !user.terms_seen
|
||||
redirect_to :controller => :user, :action => :terms, :referer => target
|
||||
redirect_to :action => :terms, :referer => target
|
||||
elsif user.blocked_on_view
|
||||
redirect_to user.blocked_on_view, :referer => target
|
||||
else
|
||||
|
@ -723,8 +725,8 @@ class UserController < ApplicationController
|
|||
# Ignore errors sending email
|
||||
end
|
||||
else
|
||||
@user.errors.set(:new_email, @user.errors.get(:email))
|
||||
@user.errors.set(:email, [])
|
||||
@user.errors.add(:new_email, @user.errors[:email])
|
||||
@user.errors.add(:email, [])
|
||||
end
|
||||
|
||||
user.restore_email!
|
||||
|
@ -740,21 +742,19 @@ class UserController < ApplicationController
|
|||
flash[:error] = t("user.filter.not_an_administrator")
|
||||
|
||||
if params[:display_name]
|
||||
redirect_to :controller => "user", :action => "view", :display_name => params[:display_name]
|
||||
redirect_to :action => "view", :display_name => params[:display_name]
|
||||
else
|
||||
redirect_to :controller => "user", :action => "login", :referer => request.fullpath
|
||||
redirect_to :action => "login", :referer => request.fullpath
|
||||
end
|
||||
elsif !@user
|
||||
redirect_to :controller => "user", :action => "login", :referer => request.fullpath
|
||||
redirect_to :action => "login", :referer => request.fullpath
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# require that the user in the URL is the logged in user
|
||||
def require_self
|
||||
if params[:display_name] != @user.display_name
|
||||
render :text => "", :status => :forbidden
|
||||
end
|
||||
head :forbidden if params[:display_name] != @user.display_name
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -766,9 +766,9 @@ class UserController < ApplicationController
|
|||
##
|
||||
# ensure that there is a "this_user" instance variable
|
||||
def lookup_user_by_name
|
||||
@this_user = User.find_by_display_name(params[:display_name])
|
||||
@this_user = User.find_by(:display_name => params[:display_name])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
redirect_to :controller => "user", :action => "view", :display_name => params[:display_name] unless @this_user
|
||||
redirect_to :action => "view", :display_name => params[:display_name] unless @this_user
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -823,9 +823,9 @@ class UserController < ApplicationController
|
|||
# display a message about th current status of the gravatar setting
|
||||
def gravatar_status_message(user)
|
||||
if user.image_use_gravatar
|
||||
return t "user.account.gravatar.enabled"
|
||||
t "user.account.gravatar.enabled"
|
||||
else
|
||||
return t "user.account.gravatar.disabled"
|
||||
t "user.account.gravatar.disabled"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ class UserPreferenceController < ApplicationController
|
|||
end
|
||||
|
||||
doc.root << el1
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -28,7 +28,7 @@ class UserPreferenceController < ApplicationController
|
|||
def read_one
|
||||
pref = UserPreference.find([@user.id, params[:preference_key]])
|
||||
|
||||
render :text => pref.v.to_s, :content_type => "text/plain"
|
||||
render :plain => pref.v.to_s
|
||||
end
|
||||
|
||||
# update the entire set of preferences
|
||||
|
@ -39,7 +39,7 @@ class UserPreferenceController < ApplicationController
|
|||
|
||||
new_preferences = {}
|
||||
|
||||
doc = XML::Parser.string(request.raw_post).parse
|
||||
doc = XML::Parser.string(request.raw_post, :options => XML::Parser::Options::NOERROR).parse
|
||||
|
||||
doc.find("//preferences/preference").each do |pt|
|
||||
if preference = old_preferences.delete(pt["k"])
|
||||
|
@ -57,7 +57,7 @@ class UserPreferenceController < ApplicationController
|
|||
|
||||
new_preferences.each_value(&:save!)
|
||||
|
||||
render :text => "", :content_type => "text/plain"
|
||||
render :plain => ""
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -74,7 +74,7 @@ class UserPreferenceController < ApplicationController
|
|||
pref.v = request.raw_post.chomp
|
||||
pref.save!
|
||||
|
||||
render :text => "", :content_type => "text/plain"
|
||||
render :plain => ""
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -82,6 +82,6 @@ class UserPreferenceController < ApplicationController
|
|||
def delete_one
|
||||
UserPreference.find([@user.id, params[:preference_key]]).delete
|
||||
|
||||
render :text => "", :content_type => "text/plain"
|
||||
render :plain => ""
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ class UserRolesController < ApplicationController
|
|||
end
|
||||
|
||||
def revoke
|
||||
UserRole.delete_all(:user_id => @this_user.id, :role => @role)
|
||||
UserRole.where(:user_id => @this_user.id, :role => @role).delete_all
|
||||
redirect_to :controller => "user", :action => "view", :display_name => @this_user.display_name
|
||||
end
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class WayController < ApplicationController
|
|||
|
||||
# Assume that Way.from_xml has thrown an exception if there is an error parsing the xml
|
||||
way.create_with_history @user
|
||||
render :text => way.id.to_s, :content_type => "text/plain"
|
||||
render :plain => way.id.to_s
|
||||
end
|
||||
|
||||
def read
|
||||
|
@ -25,9 +25,9 @@ class WayController < ApplicationController
|
|||
response.last_modified = way.timestamp
|
||||
|
||||
if way.visible
|
||||
render :text => way.to_xml.to_s, :content_type => "text/xml"
|
||||
render :xml => way.to_xml.to_s
|
||||
else
|
||||
render :text => "", :status => :gone
|
||||
head :gone
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -40,7 +40,7 @@ class WayController < ApplicationController
|
|||
end
|
||||
|
||||
way.update_from(new_way, @user)
|
||||
render :text => way.version.to_s, :content_type => "text/plain"
|
||||
render :plain => way.version.to_s
|
||||
end
|
||||
|
||||
# This is the API call to delete a way
|
||||
|
@ -50,9 +50,9 @@ class WayController < ApplicationController
|
|||
|
||||
if new_way && new_way.id == way.id
|
||||
way.delete_with_history!(new_way, @user)
|
||||
render :text => way.version.to_s, :content_type => "text/plain"
|
||||
render :plain => way.version.to_s
|
||||
else
|
||||
render :text => "", :status => :bad_request
|
||||
head :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -73,9 +73,9 @@ class WayController < ApplicationController
|
|||
end
|
||||
doc.root << way.to_xml_node(visible_nodes, changeset_cache, user_display_name_cache)
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
else
|
||||
render :text => "", :status => :gone
|
||||
head :gone
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -96,7 +96,7 @@ class WayController < ApplicationController
|
|||
doc.root << way.to_xml_node
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -112,6 +112,6 @@ class WayController < ApplicationController
|
|||
doc.root << way.to_xml_node if way.visible
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
render :xml => doc.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -59,16 +59,16 @@ module ApplicationHelper
|
|||
|
||||
def richtext_area(object_name, method, options = {})
|
||||
id = "#{object_name}_#{method}"
|
||||
format = options.delete(:format) || "markdown"
|
||||
type = options.delete(:format) || "markdown"
|
||||
|
||||
content_tag(:div, :id => "#{id}_container", :class => "richtext_container") do
|
||||
output_buffer << content_tag(:div, :id => "#{id}_content", :class => "richtext_content") do
|
||||
output_buffer << text_area(object_name, method, options.merge("data-preview-url" => preview_url(:format => format)))
|
||||
output_buffer << text_area(object_name, method, options.merge("data-preview-url" => preview_url(:type => type)))
|
||||
output_buffer << content_tag(:div, "", :id => "#{id}_preview", :class => "richtext_preview richtext")
|
||||
end
|
||||
|
||||
output_buffer << content_tag(:div, :id => "#{id}_help", :class => "richtext_help") do
|
||||
output_buffer << render("site/#{format}_help")
|
||||
output_buffer << render("site/#{type}_help")
|
||||
output_buffer << content_tag(:div, :class => "buttons") do
|
||||
output_buffer << submit_tag(I18n.t("site.richtext_area.edit"), :id => "#{id}_doedit", :class => "richtext_doedit deemphasize", :disabled => true)
|
||||
output_buffer << submit_tag(I18n.t("site.richtext_area.preview"), :id => "#{id}_dopreview", :class => "richtext_dopreview deemphasize")
|
||||
|
@ -100,4 +100,30 @@ module ApplicationHelper
|
|||
def current_page_class(path)
|
||||
:current if current_page?(path)
|
||||
end
|
||||
|
||||
def application_data
|
||||
data = {
|
||||
:locale => I18n.locale,
|
||||
:preferred_editor => preferred_editor
|
||||
}
|
||||
|
||||
if @user
|
||||
data[:user] = @user.id.to_json
|
||||
|
||||
unless @user.home_lon.nil? || @user.home_lat.nil?
|
||||
data[:user_home] = { :lat => @user.home_lat, :lon => @user.home_lon }
|
||||
end
|
||||
end
|
||||
|
||||
data[:location] = session[:location] if session[:location]
|
||||
|
||||
if @oauth
|
||||
data[:token] = @oauth.token
|
||||
data[:token_secret] = @oauth.secret
|
||||
data[:consumer_key] = @oauth.client_application.key
|
||||
data[:consumer_secret] = @oauth.client_application.secret
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module BannerHelper
|
|||
rescue
|
||||
parsed = nil
|
||||
end
|
||||
parsed.is_a?(Date) && parsed.past?
|
||||
!parsed.is_a?(Date) || (parsed.is_a?(Date) && parsed.past?)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -17,6 +17,7 @@ module BannerHelper
|
|||
banner_key = nil
|
||||
cookie_key = nil
|
||||
min_index = 9999
|
||||
min_date = Date.new(9999, 1, 1)
|
||||
|
||||
banners.each do |k, v|
|
||||
ckey = banner_cookie(v[:id]).to_sym
|
||||
|
@ -30,9 +31,14 @@ module BannerHelper
|
|||
# pick banner with mininum queue position
|
||||
next if index > min_index
|
||||
|
||||
# or if equal queue position, pick banner with soonest end date (i.e. next expiring)
|
||||
end_date = Date.parse(v[:enddate])
|
||||
next if index == min_index && end_date > min_date
|
||||
|
||||
banner_key = k
|
||||
cookie_key = ckey
|
||||
min_index = index
|
||||
min_date = end_date
|
||||
end
|
||||
|
||||
unless banner_key.nil?
|
||||
|
|
|
@ -99,7 +99,7 @@ module BrowseHelper
|
|||
|
||||
private
|
||||
|
||||
ICON_TAGS = %w(aeroway amenity barrier building highway historic landuse leisure man_made natural railway shop tourism waterway).freeze
|
||||
ICON_TAGS = %w[aeroway amenity barrier building highway historic landuse leisure man_made natural railway shop tourism waterway].freeze
|
||||
|
||||
def icon_tags(object)
|
||||
object.tags.find_all { |k, _v| ICON_TAGS.include? k }.sort
|
||||
|
@ -133,14 +133,14 @@ module BrowseHelper
|
|||
lang = if value =~ /^([a-z-]{2,12}):(.+)$/i
|
||||
# Value is <lang>:<title> so split it up
|
||||
# Note that value is always left as-is, see: https://trac.openstreetmap.org/ticket/4315
|
||||
$1
|
||||
Regexp.last_match(1)
|
||||
else
|
||||
# Value is <title> so default to English Wikipedia
|
||||
"en"
|
||||
end
|
||||
elsif key =~ /^wikipedia:(\S+)$/
|
||||
# Language is in the key, so assume value is the title
|
||||
lang = $1
|
||||
lang = Regexp.last_match(1)
|
||||
else
|
||||
# Not a wikipedia key!
|
||||
return nil
|
||||
|
@ -149,9 +149,9 @@ module BrowseHelper
|
|||
if value =~ /^([^#]*)#(.*)/
|
||||
# Contains a reference to a section of the wikipedia article
|
||||
# Must break it up to correctly build the url
|
||||
value = $1
|
||||
section = "#" + $2
|
||||
encoded_section = "#" + URI.encode($2.gsub(/ +/, "_"), /[^A-Za-z0-9:_]/).tr("%", ".")
|
||||
value = Regexp.last_match(1)
|
||||
section = "#" + Regexp.last_match(2)
|
||||
encoded_section = "#" + URI.encode(Regexp.last_match(2).gsub(/ +/, "_"), /[^A-Za-z0-9:_]/).tr("%", ".")
|
||||
else
|
||||
section = ""
|
||||
encoded_section = ""
|
||||
|
|
|
@ -2,4 +2,33 @@ module NotifierHelper
|
|||
def fp(text)
|
||||
format_paragraph(text, 72, 0)
|
||||
end
|
||||
|
||||
def link_to_user(display_name)
|
||||
link_to(
|
||||
content_tag(
|
||||
"strong",
|
||||
display_name,
|
||||
# NB we need "text-decoration: none" twice: GMail only honours it on
|
||||
# the <a> but Outlook only on the <strong>
|
||||
:style => "text-decoration: none"
|
||||
),
|
||||
user_url(display_name, :host => SERVER_URL),
|
||||
:target => "_blank",
|
||||
:style => "text-decoration: none; color: #222"
|
||||
)
|
||||
end
|
||||
|
||||
def message_body(&block)
|
||||
render(
|
||||
:partial => "message_body",
|
||||
:locals => { :body => capture(&block) }
|
||||
)
|
||||
end
|
||||
|
||||
def style_message(html)
|
||||
# Because we can't use stylesheets in HTML emails, we need to inline the
|
||||
# styles. Rather than copy-paste the same string of CSS into every message,
|
||||
# we apply it once here, after the message has been composed.
|
||||
html.gsub /<p>/, '<p style="color: black; margin: 0.75em 0; font-family: \'Helvetica Neue\', Arial, Sans-Serif">'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,9 +4,9 @@ module OpenGraphHelper
|
|||
"og:site_name" => t("layouts.project_name.title"),
|
||||
"og:title" => [t("layouts.project_name.title"), title].compact.join(" | "),
|
||||
"og:type" => "website",
|
||||
"og:image" => image_path("osm_logo_256.png", :host => SERVER_URL, :protocol => "http"),
|
||||
"og:image:secure_url" => image_path("osm_logo_256.png", :host => SERVER_URL, :protocol => "https"),
|
||||
"og:url" => url_for(:host => SERVER_URL),
|
||||
"og:image" => image_url("osm_logo_256.png", :protocol => "http"),
|
||||
"og:image:secure_url" => image_url("osm_logo_256.png", :protocol => "https"),
|
||||
"og:url" => url_for(:only_path => false),
|
||||
"og:description" => t("layouts.intro_text")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module TraceHelper
|
||||
def link_to_tag(tag)
|
||||
if @action == "mine"
|
||||
return link_to(tag, :tag => tag, :page => nil)
|
||||
link_to(tag, :tag => tag, :page => nil)
|
||||
else
|
||||
return link_to(tag, :tag => tag, :display_name => @display_name, :page => nil)
|
||||
link_to(tag, :tag => tag, :display_name => @display_name, :page => nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,8 +4,13 @@ module UserBlocksHelper
|
|||
# user block (i.e: whether it's active, what the expiry time is)
|
||||
def block_status(block)
|
||||
if block.active?
|
||||
# if the block hasn't expired yet show the date, if the user just needs to login show that
|
||||
if block.needs_view?
|
||||
I18n.t("user_block.helper.until_login")
|
||||
if block.ends_at > Time.now.getutc
|
||||
I18n.t("user_block.helper.time_future_and_until_login", :time => friendly_date(block.ends_at)).html_safe
|
||||
else
|
||||
I18n.t("user_block.helper.until_login")
|
||||
end
|
||||
else
|
||||
I18n.t("user_block.helper.time_future", :time => friendly_date(block.ends_at)).html_safe
|
||||
end
|
||||
|
|
|
@ -57,6 +57,8 @@ module UserHelper
|
|||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Gravatar support
|
||||
|
||||
# See http://en.gravatar.com/site/implement/images/ for details.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
module UserRolesHelper
|
||||
def role_icons(user)
|
||||
UserRole::ALL_ROLES.reduce("".html_safe) { |a, e| a + " " + role_icon(user, e) }
|
||||
UserRole::ALL_ROLES.reduce("".html_safe) do |acc, elem|
|
||||
acc + " " + role_icon(user, elem)
|
||||
end
|
||||
end
|
||||
|
||||
def role_icon(user, role)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Acl < ActiveRecord::Base
|
||||
validates :k, :presence => true
|
||||
|
||||
def self.match(address, domain = nil)
|
||||
if domain
|
||||
Acl.where("address >>= ? OR domain = ?", address, domain)
|
||||
|
|
|
@ -32,7 +32,7 @@ class Changeset < ActiveRecord::Base
|
|||
EXPAND = 0.1
|
||||
|
||||
# maximum number of elements allowed in a changeset
|
||||
MAX_ELEMENTS = 50000
|
||||
MAX_ELEMENTS = 10000
|
||||
|
||||
# maximum time a changeset is allowed to be open for.
|
||||
MAX_TIME_OPEN = 1.day
|
||||
|
@ -149,7 +149,7 @@ class Changeset < ActiveRecord::Base
|
|||
save!
|
||||
|
||||
tags = self.tags
|
||||
ChangesetTag.delete_all(:changeset_id => id)
|
||||
ChangesetTag.where(:changeset_id => id).delete_all
|
||||
|
||||
tags.each do |k, v|
|
||||
tag = ChangesetTag.new
|
||||
|
|
|
@ -18,7 +18,7 @@ class ClientApplication < ActiveRecord::Base
|
|||
attr_accessor :token_callback_url
|
||||
|
||||
def self.find_token(token_key)
|
||||
token = OauthToken.find_by_token(token_key, :include => :client_application)
|
||||
token = OauthToken.includes(:client_application).find_by(:token => token_key)
|
||||
token if token && token.authorized?
|
||||
end
|
||||
|
||||
|
@ -75,9 +75,7 @@ class ClientApplication < ActiveRecord::Base
|
|||
# this is the set of permissions that the client can ask for. clients
|
||||
# have to say up-front what permissions they want and when users sign up they
|
||||
# can agree or not agree to each of them.
|
||||
PERMISSIONS = [:allow_read_prefs, :allow_write_prefs, :allow_write_diary,
|
||||
:allow_write_api, :allow_read_gpx, :allow_write_gpx,
|
||||
:allow_write_notes].freeze
|
||||
PERMISSIONS = [:allow_read_prefs, :allow_write_prefs, :allow_write_diary, :allow_write_api, :allow_read_gpx, :allow_write_gpx, :allow_write_notes].freeze
|
||||
|
||||
def generate_keys
|
||||
self.key = OAuth::Helper.generate_key(40)[0, 40]
|
||||
|
|
|
@ -3,7 +3,9 @@ class DiaryEntry < ActiveRecord::Base
|
|||
belongs_to :language, :foreign_key => "language_code"
|
||||
|
||||
has_many :comments, -> { order(:id).preload(:user) }, :class_name => "DiaryComment"
|
||||
has_many :visible_comments, -> { joins(:user).where(:visible => true, :users => { :status => %w(active confirmed) }).order(:id) }, :class_name => "DiaryComment"
|
||||
has_many :visible_comments, -> { joins(:user).where(:visible => true, :users => { :status => %w[active confirmed] }).order(:id) }, :class_name => "DiaryComment"
|
||||
has_many :subscriptions, :class_name => "DiaryEntrySubscription"
|
||||
has_many :subscribers, :through => :subscriptions, :source => :user
|
||||
|
||||
scope :visible, -> { where(:visible => true) }
|
||||
|
||||
|
|
6
app/models/diary_entry_subscription.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class DiaryEntrySubscription < ActiveRecord::Base
|
||||
self.primary_keys = "user_id", "diary_entry_id"
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :diary_entry
|
||||
end
|
|
@ -5,7 +5,7 @@ class Language < ActiveRecord::Base
|
|||
|
||||
def self.load(file)
|
||||
Language.transaction do
|
||||
YAML.load(File.read(file)).each do |k, v|
|
||||
YAML.safe_load(File.read(file)).each do |k, v|
|
||||
begin
|
||||
Language.update(k, :english_name => v["english"], :native_name => v["native"])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
|
|
|
@ -49,7 +49,7 @@ class Node < ActiveRecord::Base
|
|||
|
||||
# Read in xml as text and return it's Node object representation
|
||||
def self.from_xml(xml, create = false)
|
||||
p = XML::Parser.string(xml)
|
||||
p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
|
||||
doc = p.parse
|
||||
|
||||
doc.find("//osm/node").each do |pt|
|
||||
|
@ -81,7 +81,7 @@ class Node < ActiveRecord::Base
|
|||
node.id = pt["id"].to_i
|
||||
# .to_i will return 0 if there is no number that can be parsed.
|
||||
# We want to make sure that there is no id with zero anyway
|
||||
raise OSM::APIBadUserInput.new("ID of node cannot be zero when updating.") if node.id == 0
|
||||
raise OSM::APIBadUserInput.new("ID of node cannot be zero when updating.") if node.id.zero?
|
||||
end
|
||||
|
||||
# We don't care about the time, as it is explicitly set on create/update/delete
|
||||
|
@ -120,10 +120,10 @@ class Node < ActiveRecord::Base
|
|||
lock!
|
||||
check_consistency(self, new_node, user)
|
||||
ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id)
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by ways #{ways.collect(&:id).join(",")}.") unless ways.empty?
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by ways #{ways.collect(&:id).join(',')}.") unless ways.empty?
|
||||
|
||||
rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Node", :member_id => id }).order(:id)
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by relations #{rels.collect(&:id).join(",")}.") unless rels.empty?
|
||||
raise OSM::APIPreconditionFailedError.new("Node #{id} is still used by relations #{rels.collect(&:id).join(',')}.") unless rels.empty?
|
||||
|
||||
self.changeset_id = new_node.changeset_id
|
||||
self.tags = {}
|
||||
|
@ -232,14 +232,18 @@ class Node < ActiveRecord::Base
|
|||
|
||||
def save_with_history!
|
||||
t = Time.now.getutc
|
||||
|
||||
self.version += 1
|
||||
self.timestamp = t
|
||||
|
||||
Node.transaction do
|
||||
self.version += 1
|
||||
self.timestamp = t
|
||||
save!
|
||||
# clone the object before saving it so that the original is
|
||||
# still marked as dirty if we retry the transaction
|
||||
clone.save!
|
||||
|
||||
# Create a NodeTag
|
||||
tags = self.tags
|
||||
NodeTag.delete_all(:node_id => id)
|
||||
NodeTag.where(:node_id => id).delete_all
|
||||
tags.each do |k, v|
|
||||
tag = NodeTag.new
|
||||
tag.node_id = id
|
||||
|
|
|
@ -7,7 +7,7 @@ class Note < ActiveRecord::Base
|
|||
:numericality => { :on => :update, :integer_only => true }
|
||||
validates :latitude, :longitude, :numericality => { :only_integer => true }
|
||||
validates :closed_at, :presence => true, :if => proc { :status == "closed" }
|
||||
validates :status, :inclusion => %w(open closed hidden)
|
||||
validates :status, :inclusion => %w[open closed hidden]
|
||||
|
||||
validate :validate_position
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ class NoteComment < ActiveRecord::Base
|
|||
validates :note, :presence => true, :associated => true
|
||||
validates :visible, :inclusion => [true, false]
|
||||
validates :author, :associated => true
|
||||
validates :event, :inclusion => %w(opened closed reopened commented hidden)
|
||||
validates :event, :inclusion => %w[opened closed reopened commented hidden]
|
||||
validates :body, :format => /\A[^\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff]*\z/
|
||||
|
||||
# Return the comment text
|
||||
|
|
|
@ -3,6 +3,8 @@ class Notifier < ActionMailer::Base
|
|||
:return_path => EMAIL_RETURN_PATH,
|
||||
:auto_submitted => "auto-generated"
|
||||
helper :application
|
||||
before_action :set_shared_template_vars
|
||||
before_action :attach_project_logo
|
||||
|
||||
def signup_confirm(user, token)
|
||||
with_recipient_locale user do
|
||||
|
@ -76,6 +78,9 @@ class Notifier < ActionMailer::Base
|
|||
@replyurl = url_for(:host => SERVER_URL,
|
||||
:controller => "message", :action => "reply",
|
||||
:message_id => message.id)
|
||||
@author = @from_user
|
||||
|
||||
attach_user_avatar(message.sender)
|
||||
|
||||
mail :from => from_address(message.sender.display_name, "m", message.id, message.digest),
|
||||
:to => message.recipient.email,
|
||||
|
@ -83,9 +88,9 @@ class Notifier < ActionMailer::Base
|
|||
end
|
||||
end
|
||||
|
||||
def diary_comment_notification(comment)
|
||||
with_recipient_locale comment.diary_entry.user do
|
||||
@to_user = comment.diary_entry.user.display_name
|
||||
def diary_comment_notification(comment, recipient)
|
||||
with_recipient_locale recipient do
|
||||
@to_user = recipient.display_name
|
||||
@from_user = comment.user.display_name
|
||||
@text = comment.body
|
||||
@title = comment.diary_entry.title
|
||||
|
@ -106,9 +111,12 @@ class Notifier < ActionMailer::Base
|
|||
:action => "new",
|
||||
:display_name => comment.user.display_name,
|
||||
:title => "Re: #{comment.diary_entry.title}")
|
||||
@author = @from_user
|
||||
|
||||
mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest),
|
||||
:to => comment.diary_entry.user.email,
|
||||
attach_user_avatar(comment.user)
|
||||
|
||||
mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest, recipient.id),
|
||||
:to => recipient.email,
|
||||
:subject => I18n.t("notifier.diary_comment_notification.subject", :user => comment.user.display_name)
|
||||
end
|
||||
end
|
||||
|
@ -122,7 +130,9 @@ class Notifier < ActionMailer::Base
|
|||
@friendurl = url_for(:host => SERVER_URL,
|
||||
:controller => "user", :action => "make_friend",
|
||||
:display_name => @friend.befriender.display_name)
|
||||
@author = @friend.befriender.display_name
|
||||
|
||||
attach_user_avatar(@friend.befriender)
|
||||
mail :to => friend.befriendee.email,
|
||||
:subject => I18n.t("notifier.friend_notification.subject", :user => friend.befriender.display_name)
|
||||
end
|
||||
|
@ -142,6 +152,9 @@ class Notifier < ActionMailer::Base
|
|||
I18n.t("notifier.note_comment_notification.anonymous")
|
||||
end
|
||||
|
||||
@author = @commenter
|
||||
attach_user_avatar(comment.author)
|
||||
|
||||
subject = if @owner
|
||||
I18n.t("notifier.note_comment_notification.#{@event}.subject_own", :commenter => @commenter)
|
||||
else
|
||||
|
@ -154,6 +167,7 @@ class Notifier < ActionMailer::Base
|
|||
|
||||
def changeset_comment_notification(comment, recipient)
|
||||
with_recipient_locale recipient do
|
||||
@to_user = recipient.display_name
|
||||
@changeset_url = changeset_url(comment.changeset, :host => SERVER_URL)
|
||||
@comment = comment.body
|
||||
@owner = recipient == comment.changeset.user
|
||||
|
@ -161,6 +175,7 @@ class Notifier < ActionMailer::Base
|
|||
@changeset_comment = comment.changeset.tags["comment"].presence
|
||||
@time = comment.created_at
|
||||
@changeset_author = comment.changeset.user.display_name
|
||||
@author = @commenter
|
||||
|
||||
subject = if @owner
|
||||
I18n.t("notifier.changeset_comment_notification.commented.subject_own", :commenter => @commenter)
|
||||
|
@ -168,6 +183,8 @@ class Notifier < ActionMailer::Base
|
|||
I18n.t("notifier.changeset_comment_notification.commented.subject_other", :commenter => @commenter)
|
||||
end
|
||||
|
||||
attach_user_avatar(comment.author)
|
||||
|
||||
mail :to => recipient.email, :subject => subject
|
||||
end
|
||||
end
|
||||
|
@ -185,15 +202,40 @@ class Notifier < ActionMailer::Base
|
|||
|
||||
private
|
||||
|
||||
def set_shared_template_vars
|
||||
@root_url = root_url(:host => SERVER_URL)
|
||||
end
|
||||
|
||||
def attach_project_logo
|
||||
attachments.inline["logo.png"] = File.read(Rails.root.join("app", "assets", "images", "osm_logo_30.png"))
|
||||
end
|
||||
|
||||
def attach_user_avatar(user)
|
||||
attachments.inline["avatar.png"] = File.read(user_avatar_file_path(user))
|
||||
end
|
||||
|
||||
def user_avatar_file_path(user)
|
||||
image = user && user.image
|
||||
if image && image.file?
|
||||
return image.path(:small)
|
||||
else
|
||||
return Rails.root.join("app", "assets", "images", "users", "images", "small.png")
|
||||
end
|
||||
end
|
||||
|
||||
def with_recipient_locale(recipient)
|
||||
I18n.with_locale Locale.available.preferred(recipient.preferred_languages) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def from_address(name, type, id, digest)
|
||||
def from_address(name, type, id, digest, user_id = nil)
|
||||
if Object.const_defined?(:MESSAGES_DOMAIN) && domain = MESSAGES_DOMAIN
|
||||
"#{name} <#{type}-#{id}-#{digest[0, 6]}@#{domain}>"
|
||||
if user_id
|
||||
"#{name} <#{type}-#{id}-#{user_id}-#{digest[0, 6]}@#{domain}>"
|
||||
else
|
||||
"#{name} <#{type}-#{id}-#{digest[0, 6]}@#{domain}>"
|
||||
end
|
||||
else
|
||||
EMAIL_FROM
|
||||
end
|
||||
|
|
|
@ -6,7 +6,8 @@ class OauthNonce < ActiveRecord::Base
|
|||
|
||||
# Remembers a nonce and it's associated timestamp. It returns false if it has already been used
|
||||
def self.remember(nonce, timestamp)
|
||||
oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp)
|
||||
return false if Time.now.to_i - timestamp.to_i > 86400
|
||||
oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp.to_i)
|
||||
return false if oauth_nonce.new_record?
|
||||
oauth_nonce
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ class Redaction < ActiveRecord::Base
|
|||
has_many :old_relations
|
||||
|
||||
validates :description, :presence => true
|
||||
validates :description_format, :inclusion => { :in => %w(text html markdown) }
|
||||
validates :description_format, :inclusion => { :in => %w[text html markdown] }
|
||||
|
||||
# this method overrides the AR default to provide the rich
|
||||
# text object for the description field.
|
||||
|
|
|
@ -33,10 +33,10 @@ class Relation < ActiveRecord::Base
|
|||
scope :ways, ->(*ids) { joins(:relation_members).where(:current_relation_members => { :member_type => "Way", :member_id => ids.flatten }) }
|
||||
scope :relations, ->(*ids) { joins(:relation_members).where(:current_relation_members => { :member_type => "Relation", :member_id => ids.flatten }) }
|
||||
|
||||
TYPES = %w(node way relation).freeze
|
||||
TYPES = %w[node way relation].freeze
|
||||
|
||||
def self.from_xml(xml, create = false)
|
||||
p = XML::Parser.string(xml)
|
||||
p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
|
||||
doc = p.parse
|
||||
|
||||
doc.find("//osm/relation").each do |pt|
|
||||
|
@ -60,7 +60,7 @@ class Relation < ActiveRecord::Base
|
|||
relation.id = pt["id"].to_i
|
||||
# .to_i will return 0 if there is no number that can be parsed.
|
||||
# We want to make sure that there is no id with zero anyway
|
||||
raise OSM::APIBadUserInput.new("ID of relation cannot be zero when updating.") if relation.id == 0
|
||||
raise OSM::APIBadUserInput.new("ID of relation cannot be zero when updating.") if relation.id.zero?
|
||||
end
|
||||
|
||||
# We don't care about the timestamp nor the visibility as these are either
|
||||
|
@ -281,15 +281,19 @@ class Relation < ActiveRecord::Base
|
|||
private
|
||||
|
||||
def save_with_history!
|
||||
t = Time.now.getutc
|
||||
|
||||
self.version += 1
|
||||
self.timestamp = t
|
||||
|
||||
Relation.transaction do
|
||||
# have to be a little bit clever here - to detect if any tags
|
||||
# changed then we have to monitor their before and after state.
|
||||
tags_changed = false
|
||||
|
||||
t = Time.now.getutc
|
||||
self.version += 1
|
||||
self.timestamp = t
|
||||
save!
|
||||
# clone the object before saving it so that the original is
|
||||
# still marked as dirty if we retry the transaction
|
||||
clone.save!
|
||||
|
||||
tags = self.tags.clone
|
||||
relation_tags.each do |old_tag|
|
||||
|
@ -313,7 +317,7 @@ class Relation < ActiveRecord::Base
|
|||
# if there are left-over tags then they are new and will have to
|
||||
# be added.
|
||||
tags_changed |= !tags.empty?
|
||||
RelationTag.delete_all(:relation_id => id)
|
||||
RelationTag.where(:relation_id => id).delete_all
|
||||
self.tags.each do |k, v|
|
||||
tag = RelationTag.new
|
||||
tag.relation_id = id
|
||||
|
@ -343,7 +347,7 @@ 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(:relation_id => id)
|
||||
RelationMember.where(:relation_id => id).delete_all
|
||||
members.each_with_index do |m, i|
|
||||
mem = RelationMember.new
|
||||
mem.relation_id = id
|
||||
|
@ -370,7 +374,7 @@ class Relation < ActiveRecord::Base
|
|||
# materially change the rest of the relation.
|
||||
any_relations =
|
||||
changed_members.collect { |_id, type| type == "relation" }
|
||||
.inject(false) { |a, e| a || e }
|
||||
.inject(false) { |acc, elem| acc || elem }
|
||||
|
||||
update_members = if tags_changed || any_relations
|
||||
# add all non-relation bounding boxes to the changeset
|
||||
|
|
|
@ -7,14 +7,14 @@ class Trace < ActiveRecord::Base
|
|||
|
||||
scope :visible, -> { where(:visible => true) }
|
||||
scope :visible_to, ->(u) { visible.where("visibility IN ('public', 'identifiable') OR user_id = ?", u) }
|
||||
scope :visible_to_all, -> { where(:visibility => %w(public identifiable)) }
|
||||
scope :visible_to_all, -> { where(:visibility => %w[public identifiable]) }
|
||||
scope :tagged, ->(t) { joins(:tags).where(:gpx_file_tags => { :tag => t }) }
|
||||
|
||||
validates :user, :presence => true, :associated => true
|
||||
validates :name, :presence => true, :length => 1..255
|
||||
validates :description, :presence => { :on => :create }, :length => 1..255
|
||||
validates :timestamp, :presence => true
|
||||
validates :visibility, :inclusion => %w(private public trackable identifiable)
|
||||
validates :visibility, :inclusion => %w[private public trackable identifiable]
|
||||
|
||||
def destroy
|
||||
super
|
||||
|
@ -29,7 +29,7 @@ class Trace < ActiveRecord::Base
|
|||
|
||||
def tagstring=(s)
|
||||
self.tags = if s.include? ","
|
||||
s.split(/\s*,\s*/).select { |tag| tag !~ /^\s*$/ }.collect do |tag|
|
||||
s.split(/\s*,\s*/).reject { |tag| tag =~ /^\s*$/ }.collect do |tag|
|
||||
tt = Tracetag.new
|
||||
tt.tag = tag
|
||||
tt
|
||||
|
@ -95,7 +95,7 @@ class Trace < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def mime_type
|
||||
filetype = `/usr/bin/file -bz #{trace_name}`.chomp
|
||||
filetype = `/usr/bin/file -Lbz #{trace_name}`.chomp
|
||||
gzipped = filetype =~ /gzip compressed/
|
||||
bzipped = filetype =~ /bzip2 compressed/
|
||||
zipped = filetype =~ /Zip archive/
|
||||
|
@ -117,7 +117,7 @@ class Trace < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def extension_name
|
||||
filetype = `/usr/bin/file -bz #{trace_name}`.chomp
|
||||
filetype = `/usr/bin/file -Lbz #{trace_name}`.chomp
|
||||
gzipped = filetype =~ /gzip compressed/
|
||||
bzipped = filetype =~ /bzip2 compressed/
|
||||
zipped = filetype =~ /Zip archive/
|
||||
|
@ -174,7 +174,7 @@ class Trace < ActiveRecord::Base
|
|||
|
||||
# Read in xml as text and return it's Node object representation
|
||||
def self.from_xml(xml, create = false)
|
||||
p = XML::Parser.string(xml)
|
||||
p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
|
||||
doc = p.parse
|
||||
|
||||
doc.find("//osm/gpx_file").each do |pt|
|
||||
|
@ -197,7 +197,7 @@ class Trace < ActiveRecord::Base
|
|||
trace.id = pt["id"].to_i
|
||||
# .to_i will return 0 if there is no number that can be parsed.
|
||||
# We want to make sure that there is no id with zero anyway
|
||||
raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id == 0
|
||||
raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id.zero?
|
||||
end
|
||||
|
||||
# We don't care about the time, as it is explicitly set on create/update/delete
|
||||
|
@ -218,7 +218,7 @@ class Trace < ActiveRecord::Base
|
|||
|
||||
def xml_file
|
||||
# TODO: *nix specific, could do to work on windows... would be functionally inferior though - check for '.gz'
|
||||
filetype = `/usr/bin/file -bz #{trace_name}`.chomp
|
||||
filetype = `/usr/bin/file -Lbz #{trace_name}`.chomp
|
||||
gzipped = filetype =~ /gzip compressed/
|
||||
bzipped = filetype =~ /bzip2 compressed/
|
||||
zipped = filetype =~ /Zip archive/
|
||||
|
@ -261,7 +261,7 @@ class Trace < ActiveRecord::Base
|
|||
first = true
|
||||
|
||||
# If there are any existing points for this trace then delete them
|
||||
Tracepoint.delete_all(:gpx_id => id)
|
||||
Tracepoint.where(:gpx_id => id).delete_all
|
||||
|
||||
gpx.points do |point|
|
||||
if first
|
||||
|
|
|
@ -4,10 +4,12 @@ class User < ActiveRecord::Base
|
|||
has_many :traces, -> { where(:visible => true) }
|
||||
has_many :diary_entries, -> { order(:created_at => :desc) }
|
||||
has_many :diary_comments, -> { order(:created_at => :desc) }
|
||||
has_many :diary_entry_subscriptions, :class_name => "DiaryEntrySubscription"
|
||||
has_many :diary_subscriptions, :through => :diary_entry_subscriptions, :source => :diary_entry
|
||||
has_many :messages, -> { where(:to_user_visible => true).order(:sent_on => :desc).preload(:sender, :recipient) }, :foreign_key => :to_user_id
|
||||
has_many :new_messages, -> { where(:to_user_visible => true, :message_read => false).order(:sent_on => :desc) }, :class_name => "Message", :foreign_key => :to_user_id
|
||||
has_many :sent_messages, -> { where(:from_user_visible => true).order(:sent_on => :desc).preload(:sender, :recipient) }, :class_name => "Message", :foreign_key => :from_user_id
|
||||
has_many :friends, -> { joins(:befriendee).where(:users => { :status => %w(active confirmed) }) }
|
||||
has_many :friends, -> { joins(:befriendee).where(:users => { :status => %w[active confirmed] }) }
|
||||
has_many :friend_users, :through => :friends, :source => :befriendee
|
||||
has_many :tokens, :class_name => "UserToken"
|
||||
has_many :preferences, :class_name => "UserPreference"
|
||||
|
@ -32,8 +34,8 @@ class User < ActiveRecord::Base
|
|||
|
||||
has_many :reports
|
||||
|
||||
scope :visible, -> { where(:status => %w(pending active confirmed)) }
|
||||
scope :active, -> { where(:status => %w(active confirmed)) }
|
||||
scope :visible, -> { where(:status => %w[pending active confirmed]) }
|
||||
scope :active, -> { where(:status => %w[active confirmed]) }
|
||||
scope :identifiable, -> { where(:data_public => true) }
|
||||
|
||||
has_attached_file :image,
|
||||
|
@ -41,7 +43,7 @@ class User < ActiveRecord::Base
|
|||
:styles => { :large => "100x100>", :small => "50x50>" }
|
||||
|
||||
validates :display_name, :presence => true, :allow_nil => true, :length => 3..255,
|
||||
:exclusion => %w(new terms save confirm confirm-email go_public reset-password forgot-password suspended)
|
||||
:exclusion => %w[new terms save confirm confirm-email go_public reset-password forgot-password suspended]
|
||||
validates :display_name, :if => proc { |u| u.display_name_changed? },
|
||||
:uniqueness => { :case_sensitive => false }
|
||||
validates :display_name, :if => proc { |u| u.display_name_changed? },
|
||||
|
@ -87,7 +89,7 @@ class User < ActiveRecord::Base
|
|||
user = nil
|
||||
end
|
||||
elsif options[:token]
|
||||
token = UserToken.find_by_token(options[:token])
|
||||
token = UserToken.find_by(:token => options[:token])
|
||||
user = token.user if token
|
||||
end
|
||||
|
||||
|
@ -98,7 +100,7 @@ class User < ActiveRecord::Base
|
|||
user = nil
|
||||
end
|
||||
|
||||
token.update_column(:expiry, 1.week.from_now) if token && user
|
||||
token.update(:expiry => 1.week.from_now) if token && user
|
||||
|
||||
user
|
||||
end
|
||||
|
@ -165,13 +167,13 @@ class User < ActiveRecord::Base
|
|||
##
|
||||
# returns true if a user is visible
|
||||
def visible?
|
||||
%w(pending active confirmed).include? status
|
||||
%w[pending active confirmed].include? status
|
||||
end
|
||||
|
||||
##
|
||||
# returns true if a user is active
|
||||
def active?
|
||||
%w(active confirmed).include? status
|
||||
%w[active confirmed].include? status
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -220,8 +222,8 @@ class User < ActiveRecord::Base
|
|||
def spam_score
|
||||
changeset_score = changesets.size * 50
|
||||
trace_score = traces.size * 50
|
||||
diary_entry_score = diary_entries.inject(0) { |a, e| a + e.body.spam_score }
|
||||
diary_comment_score = diary_comments.inject(0) { |a, e| a + e.body.spam_score }
|
||||
diary_entry_score = diary_entries.inject(0) { |acc, elem| acc + elem.body.spam_score }
|
||||
diary_comment_score = diary_comments.inject(0) { |acc, elem| acc + elem.body.spam_score }
|
||||
|
||||
score = description.spam_score / 4.0
|
||||
score += diary_entries.where("created_at > ?", 1.day.ago).count * 10
|
||||
|
@ -237,14 +239,14 @@ class User < ActiveRecord::Base
|
|||
# perform a spam check on a user
|
||||
def spam_check
|
||||
if status == "active" && spam_score > SPAM_THRESHOLD
|
||||
update_column(:status, "suspended")
|
||||
update(:status => "suspended")
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# return an oauth access token for a specified application
|
||||
def access_token(application_key)
|
||||
ClientApplication.find_by_key(application_key).access_token_for_user(self)
|
||||
ClientApplication.find_by(:key => application_key).access_token_for_user(self)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -26,6 +26,13 @@ class UserBlock < ActiveRecord::Base
|
|||
needs_view || ends_at > Time.now.getutc
|
||||
end
|
||||
|
||||
##
|
||||
# returns true if the block is a "zero hour" block
|
||||
def zero_hour?
|
||||
# if the times differ more than 1 minute we probably have more important issues
|
||||
needs_view && (ends_at.to_i - updated_at.to_i) < 60
|
||||
end
|
||||
|
||||
##
|
||||
# revokes the block, allowing the user to use the API again. the argument
|
||||
# is the user object who is revoking the ban.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
class UserRole < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :granter, :class_name => "User"
|
||||
|
||||
ALL_ROLES = %w(administrator moderator).freeze
|
||||
ALL_ROLES = %w[administrator moderator].freeze
|
||||
|
||||
validates :role, :inclusion => ALL_ROLES, :uniqueness => { :scope => :user_id }
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ class Way < ActiveRecord::Base
|
|||
|
||||
# Read in xml as text and return it's Way object representation
|
||||
def self.from_xml(xml, create = false)
|
||||
p = XML::Parser.string(xml)
|
||||
p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
|
||||
doc = p.parse
|
||||
|
||||
doc.find("//osm/way").each do |pt|
|
||||
|
@ -58,7 +58,7 @@ class Way < ActiveRecord::Base
|
|||
way.id = pt["id"].to_i
|
||||
# .to_i will return 0 if there is no number that can be parsed.
|
||||
# We want to make sure that there is no id with zero anyway
|
||||
raise OSM::APIBadUserInput.new("ID of way cannot be zero when updating.") if way.id == 0
|
||||
raise OSM::APIBadUserInput.new("ID of way cannot be zero when updating.") if way.id.zero?
|
||||
end
|
||||
|
||||
# We don't care about the timestamp nor the visibility as these are either
|
||||
|
@ -222,7 +222,7 @@ class Way < ActiveRecord::Base
|
|||
lock!
|
||||
check_consistency(self, new_way, user)
|
||||
rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Way", :member_id => id }).order(:id)
|
||||
raise OSM::APIPreconditionFailedError.new("Way #{id} is still used by relations #{rels.collect(&:id).join(",")}.") unless rels.empty?
|
||||
raise OSM::APIPreconditionFailedError.new("Way #{id} is still used by relations #{rels.collect(&:id).join(',')}.") unless rels.empty?
|
||||
|
||||
self.changeset_id = new_way.changeset_id
|
||||
self.changeset = new_way.changeset
|
||||
|
@ -255,6 +255,9 @@ class Way < ActiveRecord::Base
|
|||
def save_with_history!
|
||||
t = Time.now.getutc
|
||||
|
||||
self.version += 1
|
||||
self.timestamp = t
|
||||
|
||||
# update the bounding box, note that this has to be done both before
|
||||
# and after the save, so that nodes from both versions are included in the
|
||||
# bbox. we use a copy of the changeset so that it isn't reloaded
|
||||
|
@ -263,12 +266,12 @@ class Way < ActiveRecord::Base
|
|||
cs.update_bbox!(bbox) unless nodes.empty?
|
||||
|
||||
Way.transaction do
|
||||
self.version += 1
|
||||
self.timestamp = t
|
||||
save!
|
||||
# clone the object before saving it so that the original is
|
||||
# still marked as dirty if we retry the transaction
|
||||
clone.save!
|
||||
|
||||
tags = self.tags
|
||||
WayTag.delete_all(:way_id => id)
|
||||
WayTag.where(:way_id => id).delete_all
|
||||
tags.each do |k, v|
|
||||
tag = WayTag.new
|
||||
tag.way_id = id
|
||||
|
@ -278,7 +281,7 @@ class Way < ActiveRecord::Base
|
|||
end
|
||||
|
||||
nds = self.nds
|
||||
WayNode.delete_all(:way_id => id)
|
||||
WayNode.where(:way_id => id).delete_all
|
||||
sequence = 1
|
||||
nds.each do |n|
|
||||
nd = WayNode.new
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# create list of permissions
|
||||
xml.instruct! :xml, :version=>"1.0"
|
||||
xml.osm("version" => "#{API_VERSION}", "generator" => "OpenStreetMap Server") do
|
||||
xml.instruct! :xml, :version => "1.0"
|
||||
xml.osm("version" => API_VERSION.to_s, "generator" => "OpenStreetMap Server") do
|
||||
xml.permissions do
|
||||
@permissions.each do |permission|
|
||||
xml.permission :name => permission
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
<div class='browse-section browse-relation'>
|
||||
<%= render :partial => "common_details", :object => relation %>
|
||||
|
||||
<% unless relation.relation_members.empty? %>
|
||||
<h4><%= t'browse.relation.members' %></h4>
|
||||
<ul><%= render :partial => "relation_member", :collection => relation.relation_members %></ul>
|
||||
<% end %>
|
||||
|
||||
<% unless relation.containing_relation_members.empty? %>
|
||||
<h4><%= t'browse.part_of' %></h4>
|
||||
<ul><%= render :partial => "containing_relation", :collection => relation.containing_relation_members.uniq %></ul>
|
||||
<% end %>
|
||||
|
||||
<% unless relation.relation_members.empty? %>
|
||||
<h4><%= t'browse.relation.members' %></h4>
|
||||
<ul><%= render :partial => "relation_member", :collection => relation.relation_members %></ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
<div class='browse-section browse-way'>
|
||||
<%= render :partial => "common_details", :object => way %>
|
||||
|
||||
<% unless way.containing_relation_members.empty? %>
|
||||
<h4><%= t'browse.part_of' %></h4>
|
||||
<ul>
|
||||
<%= render :partial => "containing_relation", :collection => way.containing_relation_members.uniq %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<% unless way.way_nodes.empty? %>
|
||||
<h4><%= t'browse.way.nodes' %></h4>
|
||||
<ul>
|
||||
|
@ -24,12 +31,5 @@
|
|||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<% unless way.containing_relation_members.empty? %>
|
||||
<h4><%= t'browse.part_of' %></h4>
|
||||
<ul>
|
||||
<%= render :partial => "containing_relation", :collection => way.containing_relation_members.uniq %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|