Merge remote-tracking branch 'openstreetmap/pull/954'
authorTom Hughes <tom@compton.nu>
Mon, 14 Mar 2016 22:11:23 +0000 (22:11 +0000)
committerTom Hughes <tom@compton.nu>
Mon, 14 Mar 2016 22:11:23 +0000 (22:11 +0000)
418 files changed:
.rubocop.yml
.rubocop_todo.yml
.travis.yml
Gemfile
Gemfile.lock
INSTALL.md
Vagrantfile
Vendorfile
app/assets/images/browse/motorway.20.png
app/assets/images/browse/primary.20.png
app/assets/images/browse/secondary.20.png
app/assets/images/browse/shop_car_parts.16.png [new file with mode: 0644]
app/assets/images/browse/tertiary.20.png
app/assets/images/browse/trunk.20.png
app/assets/images/key/mapnik/construction.png
app/assets/images/key/mapnik/mainroad.png [new file with mode: 0644]
app/assets/images/key/mapnik/mainroad12.png [new file with mode: 0644]
app/assets/images/key/mapnik/mainroad7.png [new file with mode: 0644]
app/assets/images/key/mapnik/mainroad9.png [new file with mode: 0644]
app/assets/images/key/mapnik/motorway.png
app/assets/images/key/mapnik/primary.png [deleted file]
app/assets/images/key/mapnik/primary12.png [deleted file]
app/assets/images/key/mapnik/secondary.png [deleted file]
app/assets/images/key/mapnik/secondary12.png [deleted file]
app/assets/images/key/mapnik/trunk.png [deleted file]
app/assets/images/key/mapnik/trunk12.png [deleted file]
app/assets/images/osm_logo_256.png [new file with mode: 0644]
app/assets/images/osm_logo_512.png [new file with mode: 0644]
app/assets/images/routing-sprite.png
app/assets/images/sprite.png
app/assets/images/sprite.svg
app/assets/javascripts/embed.js.erb
app/assets/javascripts/index.js
app/assets/javascripts/index/directions.js
app/assets/javascripts/index/directions/graphhopper.js
app/assets/javascripts/index/directions/mapquest.js
app/assets/javascripts/index/directions/mapzen.js [new file with mode: 0644]
app/assets/javascripts/index/directions/osrm.js
app/assets/javascripts/index/query.js
app/assets/javascripts/index/search.js
app/assets/javascripts/leaflet.layers.js
app/assets/javascripts/leaflet.share.js
app/assets/javascripts/login.js [new file with mode: 0644]
app/assets/javascripts/osm.js.erb
app/assets/stylesheets/browse.scss
app/assets/stylesheets/common.scss
app/controllers/amf_controller.rb
app/controllers/api_controller.rb
app/controllers/application_controller.rb
app/controllers/browse_controller.rb
app/controllers/changeset_controller.rb
app/controllers/geocoder_controller.rb
app/controllers/node_controller.rb
app/controllers/notes_controller.rb
app/controllers/oauth_controller.rb
app/controllers/old_controller.rb
app/controllers/relation_controller.rb
app/controllers/trace_controller.rb
app/controllers/user_controller.rb
app/controllers/user_preference_controller.rb
app/controllers/way_controller.rb
app/helpers/asset_helper.rb
app/helpers/browse_helper.rb
app/helpers/changeset_helper.rb
app/helpers/geocoder_helper.rb
app/helpers/note_helper.rb
app/helpers/open_graph_helper.rb [new file with mode: 0644]
app/helpers/title_helper.rb
app/helpers/user_roles_helper.rb
app/models/changeset.rb
app/models/changeset_comment.rb
app/models/client_application.rb
app/models/node.rb
app/models/note.rb
app/models/notifier.rb
app/models/old_node.rb
app/models/relation.rb
app/models/request_token.rb
app/models/trace.rb
app/models/user.rb
app/models/user_role.rb
app/models/way.rb
app/views/browse/_relation_member.html.erb
app/views/browse/_way.html.erb
app/views/browse/changeset.html.erb
app/views/browse/timeout.html.erb
app/views/changeset/_changeset.html.erb
app/views/changeset/history.html.erb
app/views/changeset/list.atom.builder
app/views/diary_entry/edit.html.erb
app/views/diary_entry/rss.rss.builder
app/views/layouts/_flash.html.erb
app/views/layouts/_head.html.erb
app/views/layouts/_header.html.erb
app/views/site/_id.html.erb
app/views/site/_potlatch2.html.erb
app/views/site/export.html.erb
app/views/site/id.html.erb
app/views/user/_auth_association.html.erb [new file with mode: 0644]
app/views/user/blocked.html.erb
app/views/user/login.html.erb
config/application.rb
config/example.application.yml
config/image_optim.yml [new file with mode: 0644]
config/initializers/abstract_adapter.rb
config/initializers/assets.rb
config/initializers/http_accept_language.rb [deleted file]
config/initializers/i18n.rb
config/initializers/libxml.rb
config/initializers/omniauth.rb
config/initializers/r2.rb
config/initializers/streaming.rb
config/initializers/uri_sanitizer.rb [new file with mode: 0644]
config/key.yml
config/locales/af.yml
config/locales/aln.yml
config/locales/ar.yml
config/locales/arz.yml
config/locales/ast.yml
config/locales/az.yml
config/locales/be-Tarask.yml
config/locales/be.yml
config/locales/br.yml
config/locales/bs.yml
config/locales/ca.yml
config/locales/cs.yml
config/locales/cy.yml
config/locales/da.yml
config/locales/de.yml
config/locales/diq.yml
config/locales/dsb.yml
config/locales/el.yml
config/locales/en-GB.yml
config/locales/en.yml
config/locales/es.yml
config/locales/et.yml
config/locales/eu.yml
config/locales/fa.yml
config/locales/fi.yml
config/locales/fr.yml
config/locales/fur.yml
config/locales/gd.yml
config/locales/gl.yml
config/locales/he.yml
config/locales/hr.yml
config/locales/hsb.yml
config/locales/hu.yml
config/locales/ia.yml
config/locales/id.yml
config/locales/is.yml
config/locales/it.yml
config/locales/ja.yml
config/locales/ka.yml
config/locales/ko.yml
config/locales/lb.yml
config/locales/lt.yml
config/locales/lv.yml
config/locales/mk.yml
config/locales/mr.yml
config/locales/ms.yml
config/locales/nb.yml
config/locales/nl.yml
config/locales/nn.yml
config/locales/oc.yml
config/locales/pa.yml
config/locales/pl.yml
config/locales/pt-BR.yml
config/locales/pt-PT.yml
config/locales/ro.yml
config/locales/ru.yml
config/locales/scn.yml
config/locales/sk.yml
config/locales/sl.yml
config/locales/sq.yml
config/locales/sr-Latn.yml
config/locales/sr.yml
config/locales/sv.yml
config/locales/te.yml
config/locales/tl.yml
config/locales/tr.yml
config/locales/uk.yml
config/locales/vi.yml
config/locales/zh-CN.yml
config/locales/zh-TW.yml
config/preinitializer.rb
db/migrate/008_remove_segments.rb
db/migrate/020_populate_node_tags_and_remove.rb
db/migrate/021_move_to_innodb.rb
db/migrate/022_key_constraints.rb
db/migrate/023_add_changesets.rb
db/migrate/030_add_foreign_keys.rb
db/migrate/040_create_oauth_tables.rb
db/migrate/041_add_fine_o_auth_permissions.rb
db/migrate/044_create_user_roles.rb
db/migrate/045_create_user_blocks.rb
db/migrate/20120318201948_create_redactions.rb
lib/auth.rb
lib/bounding_box.rb
lib/classic_pagination/pagination.rb
lib/classic_pagination/pagination_helper.rb
lib/consistency_validations.rb
lib/diff_reader.rb
lib/editors.rb
lib/gpx.rb
lib/id.rb
lib/locale.rb [new file with mode: 0644]
lib/not_redactable.rb
lib/password_hash.rb
lib/potlatch.rb
lib/potlatch2.rb
lib/quad_tile.rb
lib/quova.rb
lib/redactable.rb
lib/rich_text.rb
lib/session_persistence.rb
lib/short_link.rb
lib/tasks/add_version_to_nodes.rake
public/robots.txt
script/vagrant/setup/provision.sh
test/controllers/changeset_controller_test.rb
test/controllers/diary_entry_controller_test.rb
test/controllers/node_controller_test.rb
test/controllers/notes_controller_test.rb
test/controllers/relation_controller_test.rb
test/controllers/site_controller_test.rb
test/controllers/trace_controller_test.rb
test/controllers/user_blocks_controller_test.rb
test/controllers/user_controller_test.rb
test/controllers/way_controller_test.rb
test/fixtures/changesets.yml
test/fixtures/changesets_subscribers.yml
test/fixtures/current_node_tags.yml
test/fixtures/current_nodes.yml
test/fixtures/note_comments.yml
test/helpers/browse_helper_test.rb
test/helpers/changeset_helper_test.rb
test/helpers/note_helper_test.rb
test/helpers/title_helper_test.rb
test/helpers/user_roles_helper_test.rb
test/integration/oauth_test.rb
test/integration/page_locale_test.rb [moved from test/integration/locale_test.rb with 94% similarity]
test/integration/user_creation_test.rb
test/integration/user_login_test.rb
test/lib/locale_test.rb [new file with mode: 0644]
test/models/changeset_comment_test.rb
test/models/changeset_test.rb
test/models/message_test.rb
test/models/node_tag_test.rb
test/models/node_test.rb
test/models/note_comment_test.rb
test/models/request_token_test.rb [new file with mode: 0644]
test/models/trace_test.rb
test/models/user_preference_test.rb
test/models/user_test.rb
test/models/way_test.rb
vendor/assets/iD/iD.css.erb
vendor/assets/iD/iD.js
vendor/assets/iD/iD/img/iD-sprite.svg [new file with mode: 0644]
vendor/assets/iD/iD/img/line-presets.png [deleted file]
vendor/assets/iD/iD/img/maki-sprite.png [deleted file]
vendor/assets/iD/iD/img/maki-sprite.svg [new file with mode: 0644]
vendor/assets/iD/iD/img/relation-presets.png [deleted file]
vendor/assets/iD/iD/img/sprite.svg [deleted file]
vendor/assets/iD/iD/locales/af.json
vendor/assets/iD/iD/locales/ar-AA.json
vendor/assets/iD/iD/locales/ar.json
vendor/assets/iD/iD/locales/ast.json
vendor/assets/iD/iD/locales/bg-BG.json
vendor/assets/iD/iD/locales/bn.json
vendor/assets/iD/iD/locales/bs.json
vendor/assets/iD/iD/locales/ca.json
vendor/assets/iD/iD/locales/cs.json
vendor/assets/iD/iD/locales/da.json
vendor/assets/iD/iD/locales/de.json
vendor/assets/iD/iD/locales/el.json
vendor/assets/iD/iD/locales/en-GB.json
vendor/assets/iD/iD/locales/en.json
vendor/assets/iD/iD/locales/eo.json
vendor/assets/iD/iD/locales/es.json
vendor/assets/iD/iD/locales/et.json
vendor/assets/iD/iD/locales/fa.json
vendor/assets/iD/iD/locales/fi.json
vendor/assets/iD/iD/locales/fr.json
vendor/assets/iD/iD/locales/gl.json
vendor/assets/iD/iD/locales/hi-IN.json [deleted file]
vendor/assets/iD/iD/locales/hi.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/hr.json
vendor/assets/iD/iD/locales/hu.json
vendor/assets/iD/iD/locales/hy.json
vendor/assets/iD/iD/locales/id.json
vendor/assets/iD/iD/locales/is.json
vendor/assets/iD/iD/locales/it.json
vendor/assets/iD/iD/locales/ja.json
vendor/assets/iD/iD/locales/kn.json
vendor/assets/iD/iD/locales/ko-KR.json
vendor/assets/iD/iD/locales/ko.json
vendor/assets/iD/iD/locales/lij.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/lt.json
vendor/assets/iD/iD/locales/lv.json
vendor/assets/iD/iD/locales/nl.json
vendor/assets/iD/iD/locales/no.json
vendor/assets/iD/iD/locales/pl.json
vendor/assets/iD/iD/locales/pt-BR.json
vendor/assets/iD/iD/locales/pt.json
vendor/assets/iD/iD/locales/ro.json [moved from vendor/assets/iD/iD/locales/ro-RO.json with 86% similarity]
vendor/assets/iD/iD/locales/ru.json
vendor/assets/iD/iD/locales/si.json
vendor/assets/iD/iD/locales/sk.json
vendor/assets/iD/iD/locales/sl.json
vendor/assets/iD/iD/locales/sq.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/sr.json
vendor/assets/iD/iD/locales/sv.json
vendor/assets/iD/iD/locales/ta.json
vendor/assets/iD/iD/locales/te.json
vendor/assets/iD/iD/locales/th.json [new file with mode: 0644]
vendor/assets/iD/iD/locales/tl.json
vendor/assets/iD/iD/locales/tr.json
vendor/assets/iD/iD/locales/uk.json
vendor/assets/iD/iD/locales/vi.json
vendor/assets/iD/iD/locales/yue.json
vendor/assets/iD/iD/locales/zh-CN.json
vendor/assets/iD/iD/locales/zh-HK.json
vendor/assets/iD/iD/locales/zh-TW.json
vendor/assets/iD/iD/locales/zh.json
vendor/assets/iD/iD/traffico/LICENSE [new file with mode: 0644]
vendor/assets/iD/iD/traffico/README.md [new file with mode: 0644]
vendor/assets/iD/iD/traffico/bower.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/fonts/traffico-preview.html [new file with mode: 0644]
vendor/assets/iD/iD/traffico/fonts/traffico_d596ae6150aa5c55ac14b1e060efc523.eot [new file with mode: 0644]
vendor/assets/iD/iD/traffico/fonts/traffico_d596ae6150aa5c55ac14b1e060efc523.svg [new file with mode: 0644]
vendor/assets/iD/iD/traffico/fonts/traffico_d596ae6150aa5c55ac14b1e060efc523.ttf [new file with mode: 0644]
vendor/assets/iD/iD/traffico/fonts/traffico_d596ae6150aa5c55ac14b1e060efc523.woff [new file with mode: 0644]
vendor/assets/iD/iD/traffico/global.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/glyphs.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/mapillary-mappings/au.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/mapillary-mappings/br.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/mapillary-mappings/ca.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/mapillary-mappings/eu.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/mapillary-mappings/us.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/at.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/au.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/be.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/br.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/ca.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/ch.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/cz.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/de.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/dk.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/ee.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/es.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/fi.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/fr.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/gr.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/hu.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/it.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/lt.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/lu.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/lv.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/nl.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/no.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/pl.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/se.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/si.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/sk.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/uk.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/signs/us.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/at-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/au-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/be-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/br-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/ca-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/ch-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/cz-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/de-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/dk-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/ee-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/es-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/fi-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/fr-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/gr-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/hu-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/it-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/lt-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/lu-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/lv-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/nl-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/no-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/pl-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/se-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/si-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/sk-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/uk-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/string-maps/us-map.json [new file with mode: 0644]
vendor/assets/iD/iD/traffico/stylesheets/examples.css [new file with mode: 0644]
vendor/assets/iD/iD/traffico/stylesheets/traffico.css.erb [new file with mode: 0644]
vendor/assets/iD/iD/traffico/transformations.json [new file with mode: 0644]
vendor/assets/iD/imagery.js
vendor/assets/iD/presets.js
vendor/assets/leaflet/leaflet.css
vendor/assets/leaflet/leaflet.js
vendor/assets/leaflet/leaflet.osm.js
vendor/assets/potlatch2/potlatch2.swf
vendor/assets/potlatch2/potlatch2/assets.zip
vendor/assets/potlatch2/potlatch2/locales/be.swf
vendor/assets/potlatch2/potlatch2/locales/bn.swf
vendor/assets/potlatch2/potlatch2/locales/bs.swf
vendor/assets/potlatch2/potlatch2/locales/el.swf
vendor/assets/potlatch2/potlatch2/locales/en_GB.swf
vendor/assets/potlatch2/potlatch2/locales/es_ES.swf
vendor/assets/potlatch2/potlatch2/locales/id.swf
vendor/assets/potlatch2/potlatch2/locales/ko.swf
vendor/assets/potlatch2/potlatch2/locales/ksh.swf
vendor/assets/potlatch2/potlatch2/locales/ky.swf
vendor/assets/potlatch2/potlatch2/locales/ro.swf
vendor/assets/potlatch2/potlatch2/locales/scn.swf [new file with mode: 0644]
vendor/assets/potlatch2/potlatch2/locales/sq.swf
vendor/assets/potlatch2/potlatch2/locales/te.swf
vendor/assets/potlatch2/potlatch2/locales/zh_TW.swf

index 213eb27aae9a6d490cf78e0b8f9f9401ae2c060f..f12f24a9f4c0b4a6215032efadfed4a27845042d 100644 (file)
@@ -1,7 +1,7 @@
 inherit_from: .rubocop_todo.yml
 
-AllCops:
-   RunRailsCops: true
+Rails:
+  Enabled: true
 
 Style/BracesAroundHashParameters:
   EnforcedStyle: context_dependent
@@ -15,10 +15,16 @@ Style/FileName:
     - 'script/locale/reload-languages'
     - 'script/update-spam-blocks'
 
+Style/IfInsideElse:
+  Enabled: false
+
 Style/GlobalVars:
   Exclude:
     - 'lib/quad_tile/extconf.rb'
-    
+
+Style/GuardClause:
+  Enabled: false
+
 Style/HashSyntax:
   EnforcedStyle: hash_rockets
   Exclude:
index 71d949daee69c30e6f4217e86e4e267374ca4fa8..191e82b39b4389e0a115941fdc52a6a2de7ec639 100644 (file)
@@ -66,7 +66,7 @@ Metrics/BlockNesting:
 # Offense count: 62
 # Configuration parameters: CountComments.
 Metrics/ClassLength:
-  Max: 1653
+  Max: 1654
 
 # Offense count: 67
 Metrics/CyclomaticComplexity:
@@ -75,7 +75,7 @@ Metrics/CyclomaticComplexity:
 # Offense count: 2535
 # Configuration parameters: AllowURI, URISchemes.
 Metrics/LineLength:
-  Max: 694
+  Max: 962
 
 # Offense count: 628
 # Configuration parameters: CountComments.
@@ -85,7 +85,7 @@ Metrics/MethodLength:
 # Offense count: 1
 # Configuration parameters: CountComments.
 Metrics/ModuleLength:
-  Max: 126
+  Max: 131
 
 # Offense count: 4
 # Configuration parameters: CountKeywordArgs.
index e4f7390936762ad0c41a3abd09aa2350f2d6393f..6c41bc8b82521802dc6ec577ea93e38b2ceff9f0 100644 (file)
@@ -1,7 +1,7 @@
 sudo: false
 language: ruby
 rvm:
-  - 1.9.3
+  - 2.1.8
 cache: bundler
 addons:
   postgresql: 9.1
@@ -14,6 +14,7 @@ env:
   global:
     - OSM_MEMCACHE_SERVERS="127.0.0.1"
 before_script:
+  - cp config/example.application.yml config/application.yml
   - psql -U postgres -c "CREATE DATABASE openstreetmap"
   - psql -U postgres -c "CREATE EXTENSION btree_gist" openstreetmap
   - make -C db/functions libpgosm.so
diff --git a/Gemfile b/Gemfile
index 3c8c3548b31e352fe4752bce950bb6d06a5c08a9..dfd87eb849ff2490b495e62669fa3cf8e7e8cb0c 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,10 +1,7 @@
 source "https://rubygems.org"
 
 # Require rails
-gem "rails", "4.2.4"
-
-# Sprockets 3 seems to be buggy, so stick with 2 for now
-gem "sprockets", "~> 2.12.3"
+gem "rails", "4.2.6"
 
 # Require things which have moved to gems in ruby 1.9
 gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19
@@ -40,6 +37,9 @@ gem "r2"
 # Use autoprefixer to generate CSS prefixes
 gem "autoprefixer-rails"
 
+# Use image_optim to optimise images
+gem "image_optim", ">= 0.22.0"
+
 # Load rails plugins
 gem "rails-i18n", "~> 4.0.0"
 gem "dynamic_form"
@@ -54,10 +54,13 @@ gem "i18n-js", ">= 3.0.0.rc10"
 gem "rack-cors"
 gem "actionpack-page_caching"
 
+# Sanitise URIs
+gem "rack-uri_sanitizer"
+
 # Omniauth for authentication
 gem "omniauth"
 gem "omniauth-openid"
-gem "openstreetmap-omniauth-google-oauth2", ">= 0.2.6.1", :require => "omniauth-google-oauth2"
+gem "omniauth-google-oauth2", ">= 0.2.7"
 gem "omniauth-facebook"
 gem "omniauth-windowslive"
 
index b65ba33a603342796b4587c64b5695cc2cdc74b9..ca4df4670432f810343c2394fbaa99739c9fadf8 100644 (file)
@@ -2,53 +2,52 @@ GEM
   remote: https://rubygems.org/
   specs:
     SystemTimer (1.2.3)
-    actionmailer (4.2.4)
-      actionpack (= 4.2.4)
-      actionview (= 4.2.4)
-      activejob (= 4.2.4)
+    actionmailer (4.2.6)
+      actionpack (= 4.2.6)
+      actionview (= 4.2.6)
+      activejob (= 4.2.6)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 1.0, >= 1.0.5)
-    actionpack (4.2.4)
-      actionview (= 4.2.4)
-      activesupport (= 4.2.4)
+    actionpack (4.2.6)
+      actionview (= 4.2.6)
+      activesupport (= 4.2.6)
       rack (~> 1.6)
       rack-test (~> 0.6.2)
       rails-dom-testing (~> 1.0, >= 1.0.5)
       rails-html-sanitizer (~> 1.0, >= 1.0.2)
     actionpack-page_caching (1.0.2)
       actionpack (>= 4.0.0, < 5)
-    actionview (4.2.4)
-      activesupport (= 4.2.4)
+    actionview (4.2.6)
+      activesupport (= 4.2.6)
       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.4)
-      activesupport (= 4.2.4)
+    activejob (4.2.6)
+      activesupport (= 4.2.6)
       globalid (>= 0.3.0)
-    activemodel (4.2.4)
-      activesupport (= 4.2.4)
+    activemodel (4.2.6)
+      activesupport (= 4.2.6)
       builder (~> 3.1)
-    activerecord (4.2.4)
-      activemodel (= 4.2.4)
-      activesupport (= 4.2.4)
+    activerecord (4.2.6)
+      activemodel (= 4.2.6)
+      activesupport (= 4.2.6)
       arel (~> 6.0)
-    activesupport (4.2.4)
+    activesupport (4.2.6)
       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)
-    ast (2.1.0)
-    astrolabe (1.3.1)
-      parser (~> 2.2)
-    autoprefixer-rails (5.2.1.2)
+    ast (2.2.0)
+    autoprefixer-rails (6.3.3.1)
       execjs
-      json
     bigdecimal (1.1.0)
     builder (3.2.2)
-    capybara (2.4.4)
+    capybara (2.6.2)
+      addressable
       mime-types (>= 1.16)
       nokogiri (>= 1.3.3)
       rack (>= 1.0.0)
@@ -57,48 +56,54 @@ GEM
     climate_control (0.0.3)
       activesupport (>= 3.0)
     cliver (0.3.2)
-    cocaine (0.5.7)
+    cocaine (0.5.8)
       climate_control (>= 0.0.3, < 1.0)
-    coffee-rails (4.1.0)
+    coffee-rails (4.1.1)
       coffee-script (>= 2.2.0)
-      railties (>= 4.0.0, < 5.0)
+      railties (>= 4.0.0, < 5.1.x)
     coffee-script (2.4.1)
       coffee-script-source
       execjs
-    coffee-script-source (1.9.1.1)
+    coffee-script-source (1.10.0)
     colorize (0.7.7)
-    composite_primary_keys (8.1.1)
+    composite_primary_keys (8.1.2)
       activerecord (~> 4.2.0)
-    coveralls (0.8.2)
+    concurrent-ruby (1.0.1)
+    coveralls (0.8.13)
       json (~> 1.8)
-      rest-client (>= 1.6.8, < 2)
-      simplecov (~> 0.10.0)
+      simplecov (~> 0.11.0)
       term-ansicolor (~> 1.3)
       thor (~> 0.19.1)
+      tins (~> 1.6.0)
     crass (1.0.2)
-    dalli (2.7.4)
+    dalli (2.7.6)
     deadlock_retry (1.2.0)
     docile (1.1.5)
-    domain_name (0.5.24)
-      unf (>= 0.0.5, < 1.0.0)
     dynamic_form (1.1.4)
     erubis (2.7.0)
     execjs (2.6.0)
-    faraday (0.9.1)
+    exifr (1.2.4)
+    faraday (0.9.2)
       multipart-post (>= 1.2, < 3)
+    fspath (2.1.1)
     globalid (0.3.6)
       activesupport (>= 4.1.0)
-    hashie (3.4.2)
-    hike (1.2.3)
+    hashie (3.4.3)
     htmlentities (4.3.4)
-    http-cookie (1.0.2)
-      domain_name (~> 0.5)
     http_accept_language (2.0.5)
-    httpclient (2.6.0.1)
+    httpclient (2.7.1)
     i18n (0.7.0)
-    i18n-js (3.0.0.rc11)
-      i18n (~> 0.6)
-    jquery-rails (4.0.4)
+    i18n-js (3.0.0.rc12)
+      i18n (~> 0.6, >= 0.6.6)
+    image_optim (0.22.1)
+      exifr (~> 1.2, >= 1.2.2)
+      fspath (~> 2.1)
+      image_size (~> 1.3)
+      in_threads (~> 1.3)
+      progress (~> 3.0, >= 3.0.1)
+    image_size (1.4.2)
+    in_threads (1.3.1)
+    jquery-rails (4.1.0)
       rails-dom-testing (~> 1.0)
       railties (>= 4.2.0)
       thor (>= 0.14, < 2.0)
@@ -113,35 +118,37 @@ GEM
       actionpack
       jsonify (< 0.4.0)
     jwt (1.5.1)
-    kgio (2.9.3)
-    konacha (3.5.1)
-      actionpack (>= 3.1, < 5)
+    kgio (2.10.0)
+    konacha (4.0.0)
+      actionpack (>= 4.1, < 5)
       capybara
       colorize
-      railties (>= 3.1, < 5)
+      railties (>= 4.1, < 5)
       sprockets (>= 2, < 4)
+      sprockets-rails (>= 2, < 4)
       tilt
-    libv8 (3.16.14.11)
+    libv8 (3.16.14.13)
     libxml-ruby (2.8.0)
     logstash-event (1.2.02)
-    logstasher (0.6.5)
+    logstasher (0.9.0)
+      activerecord (>= 3.0)
+      activesupport (>= 3.0)
       logstash-event (~> 1.2.0)
       request_store
     loofah (2.0.3)
       nokogiri (>= 1.5.9)
     mail (2.6.3)
       mime-types (>= 1.16, < 3)
-    mime-types (2.6.1)
+    mime-types (2.99.1)
     mimemagic (0.3.0)
-    mini_portile (0.6.2)
-    minitest (5.8.0)
+    mini_portile2 (2.0.0)
+    minitest (5.8.4)
     multi_json (1.11.2)
     multi_xml (0.5.5)
     multipart-post (2.0.0)
-    netrc (0.10.3)
-    nokogiri (1.6.6.2)
-      mini_portile (~> 0.6.0)
-    nokogumbo (1.4.1)
+    nokogiri (1.6.7.2)
+      mini_portile2 (~> 2.0.0.rc2)
+    nokogumbo (1.4.7)
       nokogiri
     oauth (0.4.7)
     oauth-plugin (0.5.1)
@@ -149,18 +156,23 @@ GEM
       oauth (~> 0.4.4)
       oauth2 (>= 0.5.0)
       rack
-    oauth2 (1.0.0)
+    oauth2 (1.1.0)
       faraday (>= 0.8, < 0.10)
-      jwt (~> 1.0)
+      jwt (~> 1.0, < 1.5.2)
       multi_json (~> 1.3)
       multi_xml (~> 0.5)
-      rack (~> 1.2)
-    omniauth (1.2.2)
+      rack (>= 1.2, < 3)
+    omniauth (1.3.1)
       hashie (>= 1.2, < 4)
-      rack (~> 1.0)
-    omniauth-facebook (2.0.1)
+      rack (>= 1.0, < 3)
+    omniauth-facebook (3.0.0)
       omniauth-oauth2 (~> 1.2)
-    omniauth-oauth2 (1.3.1)
+    omniauth-google-oauth2 (0.3.1)
+      jwt (~> 1.0)
+      multi_json (~> 1.3)
+      omniauth (>= 1.1.1)
+      omniauth-oauth2 (>= 1.3.1)
+    omniauth-oauth2 (1.4.0)
       oauth2 (~> 1.0)
       omniauth (~> 1.2)
     omniauth-openid (1.0.1)
@@ -169,28 +181,24 @@ GEM
     omniauth-windowslive (0.0.9.1)
       multi_json (>= 1.0.3)
       omniauth-oauth2 (~> 1.0)
-    openstreetmap-omniauth-google-oauth2 (0.2.6.1)
-      jwt (~> 1.0)
-      multi_json (~> 1.3)
-      omniauth (>= 1.1.1)
-      omniauth-oauth2 (>= 1.1.1)
-    paperclip (4.3.0)
+    paperclip (4.3.5)
       activemodel (>= 3.2.0)
       activesupport (>= 3.2.0)
       cocaine (~> 0.5.5)
       mime-types
       mimemagic (= 0.3.0)
-    parser (2.2.2.6)
-      ast (>= 1.1, < 3.0)
-    pg (0.18.2)
-    poltergeist (1.6.0)
+    parser (2.3.0.6)
+      ast (~> 2.2)
+    pg (0.18.4)
+    poltergeist (1.9.0)
       capybara (~> 2.1)
       cliver (~> 0.3.1)
       multi_json (~> 1.0)
       websocket-driver (>= 0.2.0)
     powerpack (0.1.1)
-    psych (2.0.15)
-    r2 (0.2.5)
+    progress (3.1.1)
+    psych (2.0.17)
+    r2 (0.2.6)
     rack (1.6.4)
     rack-cors (0.4.0)
     rack-openid (1.3.1)
@@ -198,16 +206,17 @@ GEM
       ruby-openid (>= 2.1.8)
     rack-test (0.6.3)
       rack (>= 1.0)
-    rails (4.2.4)
-      actionmailer (= 4.2.4)
-      actionpack (= 4.2.4)
-      actionview (= 4.2.4)
-      activejob (= 4.2.4)
-      activemodel (= 4.2.4)
-      activerecord (= 4.2.4)
-      activesupport (= 4.2.4)
+    rack-uri_sanitizer (0.0.2)
+    rails (4.2.6)
+      actionmailer (= 4.2.6)
+      actionpack (= 4.2.6)
+      actionview (= 4.2.6)
+      activejob (= 4.2.6)
+      activemodel (= 4.2.6)
+      activerecord (= 4.2.6)
+      activesupport (= 4.2.6)
       bundler (>= 1.3.0, < 2.0)
-      railties (= 4.2.4)
+      railties (= 4.2.6)
       sprockets-rails
     rails-deprecated_sanitizer (1.0.3)
       activesupport (>= 4.2.0.alpha)
@@ -215,60 +224,54 @@ GEM
       activesupport (>= 4.2.0.beta, < 5.0)
       nokogiri (~> 1.6.0)
       rails-deprecated_sanitizer (>= 1.0.1)
-    rails-html-sanitizer (1.0.2)
+    rails-html-sanitizer (1.0.3)
       loofah (~> 2.0)
-    rails-i18n (4.0.4)
-      i18n (~> 0.6)
+    rails-i18n (4.0.8)
+      i18n (~> 0.7)
       railties (~> 4.0)
-    railties (4.2.4)
-      actionpack (= 4.2.4)
-      activesupport (= 4.2.4)
+    railties (4.2.6)
+      actionpack (= 4.2.6)
+      activesupport (= 4.2.6)
       rake (>= 0.8.7)
       thor (>= 0.18.1, < 2.0)
-    rainbow (2.0.0)
-    rake (10.4.2)
-    redcarpet (3.3.2)
+    rainbow (2.1.0)
+    rake (10.5.0)
+    redcarpet (3.3.4)
     ref (2.0.0)
-    request_store (1.2.0)
-    rest-client (1.8.0)
-      http-cookie (>= 1.0.2, < 2.0)
-      mime-types (>= 1.16, < 3.0)
-      netrc (~> 0.7)
+    request_store (1.3.0)
     rinku (1.7.3)
-    rubocop (0.33.0)
-      astrolabe (~> 1.3)
-      parser (>= 2.2.2.5, < 3.0)
+    rubocop (0.37.2)
+      parser (>= 2.3.0.4, < 3.0)
       powerpack (~> 0.1)
       rainbow (>= 1.99.1, < 3.0)
-      ruby-progressbar (~> 1.4)
+      ruby-progressbar (~> 1.7)
+      unicode-display_width (~> 0.3)
     ruby-openid (2.7.0)
     ruby-progressbar (1.7.5)
-    sanitize (4.0.0)
+    sanitize (4.0.1)
       crass (~> 1.0.2)
       nokogiri (>= 1.4.4)
-      nokogumbo (= 1.4.1)
-    sass (3.4.17)
-    sass-rails (5.0.3)
+      nokogumbo (~> 1.4.1)
+    sass (3.4.21)
+    sass-rails (5.0.4)
       railties (>= 4.0.0, < 5.0)
       sass (~> 3.1)
       sprockets (>= 2.8, < 4.0)
       sprockets-rails (>= 2.0, < 4.0)
-      tilt (~> 1.1)
-    simplecov (0.10.0)
+      tilt (>= 1.1, < 3)
+    simplecov (0.11.2)
       docile (~> 1.1.0)
       json (~> 1.8)
       simplecov-html (~> 0.10.0)
     simplecov-html (0.10.0)
     soap4r-ruby1.9 (2.0.5)
-    sprockets (2.12.4)
-      hike (~> 1.2)
-      multi_json (~> 1.0)
-      rack (~> 1.0)
-      tilt (~> 1.1, != 1.3.0)
-    sprockets-rails (2.3.2)
-      actionpack (>= 3.0)
-      activesupport (>= 3.0)
-      sprockets (>= 2.8, < 4.0)
+    sprockets (3.5.2)
+      concurrent-ruby (~> 1.0)
+      rack (> 1, < 3)
+    sprockets-rails (3.0.4)
+      actionpack (>= 4.0)
+      activesupport (>= 4.0)
+      sprockets (>= 3.0.0)
     term-ansicolor (1.3.2)
       tins (~> 1.0)
     therubyracer (0.12.2)
@@ -276,21 +279,19 @@ GEM
       ref
     thor (0.19.1)
     thread_safe (0.3.5)
-    tilt (1.4.1)
+    tilt (2.0.2)
     timecop (0.8.0)
     tins (1.6.0)
     tzinfo (1.2.2)
       thread_safe (~> 0.1)
-    uglifier (2.7.1)
+    uglifier (2.7.2)
       execjs (>= 0.3.0)
       json (>= 1.8.0)
-    unf (0.1.4)
-      unf_ext
-    unf_ext (0.0.7.1)
+    unicode-display_width (0.3.1)
     validates_email_format_of (1.6.3)
       i18n
     vendorer (0.1.16)
-    websocket-driver (0.6.2)
+    websocket-driver (0.6.3)
       websocket-extensions (>= 0.1.0)
     websocket-extensions (0.1.2)
     xpath (2.0.0)
@@ -315,6 +316,7 @@ DEPENDENCIES
   http_accept_language (~> 2.0.0)
   httpclient
   i18n-js (>= 3.0.0.rc10)
+  image_optim (>= 0.22.0)
   jquery-rails
   jshint
   json
@@ -327,16 +329,17 @@ DEPENDENCIES
   oauth-plugin (>= 0.5.1)
   omniauth
   omniauth-facebook
+  omniauth-google-oauth2 (>= 0.2.7)
   omniauth-openid
   omniauth-windowslive
-  openstreetmap-omniauth-google-oauth2 (>= 0.2.6.1)
   paperclip (~> 4.0)
   pg
   poltergeist
   psych
   r2
   rack-cors
-  rails (= 4.2.4)
+  rack-uri_sanitizer
+  rails (= 4.2.6)
   rails-i18n (~> 4.0.0)
   redcarpet
   rinku (>= 1.2.2)
@@ -344,7 +347,6 @@ DEPENDENCIES
   sanitize
   sass-rails (~> 5.0)
   soap4r-ruby1.9
-  sprockets (~> 2.12.3)
   timecop
   uglifier (>= 1.3.0)
   validates_email_format_of (>= 1.5.1)
index 09e3b12f7827a92971c129dd4ef49dd6aa4449a5..055702a4c1cb6820e5f2528fc1d965512e86cce7 100644 (file)
@@ -8,7 +8,7 @@ You can install the software directly on your machine, which is the traditional
 These instructions are based on Ubuntu 12.04 LTS, which is the platform used by the OSMF servers.
 The instructions also work, with only minor amendments, for all other current Ubuntu releases, Fedora and MacOSX
 
-We don't recommend attempting to develop or deploy this software on Windows. If you need to use Windows, then try developing this sofware using Ubuntu in a virtual machine, or use [Vagrant](VAGRANT.md).
+We don't recommend attempting to develop or deploy this software on Windows. If you need to use Windows, then try developing this software using Ubuntu in a virtual machine, or use [Vagrant](VAGRANT.md).
 
 ## Dependencies
 
@@ -18,26 +18,24 @@ of packages required before you can get the various gems installed.
 
 ## Minimum requirements
 
-* Ruby 1.9.3
+* Ruby 2.0
 * RubyGems 1.3.1+
-* Postgres 8.3+
+* PostgreSQL 9.1+
 * ImageMagick
 * Bundler
 * Javascript Runtime
 
-These can be installed on Ubuntu 10.10 or later with:
+These can be installed on Ubuntu 14.04 or later with:
 
 ```
-sudo apt-get install ruby1.9.1 libruby1.9.1 ruby1.9.1-dev ri1.9.1 \
+sudo apt-get install ruby2.0 libruby2.0 ruby2.0-dev \
                      libmagickwand-dev libxml2-dev libxslt1-dev nodejs \
                      apache2 apache2-threaded-dev build-essential git-core \
                      postgresql postgresql-contrib libpq-dev postgresql-server-dev-all \
-                     libsasl2-dev
-sudo gem1.9.1 install bundler
+                     libsasl2-dev imagemagick
+sudo gem2.0 install bundler
 ```
 
-Note that the "1.9.1" Ubuntu packages do in fact contain ruby 1.9.3.
-
 ### Alternative platforms
 
 #### Fedora
@@ -49,17 +47,17 @@ sudo yum install ruby ruby-devel rubygem-rdoc rubygem-bundler rubygems \
                  libxml2-devel js \
                  gcc gcc-c++ git \
                  postgresql postgresql-server postgresql-contrib postgresql-devel \
-                 perl-podlators
+                 perl-podlators ImageMagick
 ```
 
-If you didn't already have Postgres installed then create a Postgres instance and start the server:
+If you didn't already have PostgreSQL installed then create a PostgreSQL instance and start the server:
 
 ```
 sudo postgresql-setup initdb
 sudo systemctl start postgresql.service
 ```
 
-Optionally set Postgres to start on boot:
+Optionally set PostgreSQL to start on boot:
 
 ```
 sudo systemctl enable postgresql.service
@@ -69,10 +67,10 @@ sudo systemctl enable postgresql.service
 
 For MacOSX, you will need XCode installed from the Mac App Store; OS X 10.7 (Lion) or later; and some familiarity with Unix development via the Terminal.
 
-Installing Postgres:
+Installing PostgreSQL:
 
 * Install Postgres.app from http://postgresapp.com/
-* Add Postgres to your path, by editing your profile:
+* Add PostgreSQL to your path, by editing your profile:
 
 `nano ~/.profile`
 
@@ -158,15 +156,7 @@ bundle exec rake db:create
 
 ### PostgreSQL Btree-gist Extension
 
-We need to load the btree-gist extension, which is needed for showing changesets on the history tab.
-
-For PostgreSQL < 9.1 (change the version number in the path as necessary):
-
-```
-psql -d openstreetmap < /usr/share/postgresql/9.0/contrib/btree_gist.sql
-```
-
-For PostgreSQL >= 9.1:
+We need to load the `btree-gist` extension, which is needed for showing changesets on the history tab.
 
 ```
 psql -d openstreetmap -c "CREATE EXTENSION btree_gist"
@@ -174,7 +164,7 @@ psql -d openstreetmap -c "CREATE EXTENSION btree_gist"
 
 ### PostgreSQL Functions
 
-We need to install special functions into the postgresql databases, and these are provided by a library that needs compiling first.
+We need to install special functions into the PostgreSQL databases, and these are provided by a library that needs compiling first.
 
 ```
 cd db/functions
@@ -203,7 +193,7 @@ bundle exec rake db:migrate
 To ensure that everything is set up properly, you should now run:
 
 ```
-bundle exec rake test
+bundle exec rake test:db
 ```
 
 This test will take a few minutes, reporting tests run, assertions, and any errors. If you receive no errors, then your installation is successful.
index 24d62bb7a4a95e56a4d2ad01526c6cce533061d2..0cd5ac72aa760553b8fdbada019af56c46cd19b4 100644 (file)
@@ -3,9 +3,11 @@
 
 Vagrant.configure("2") do |config|
   # use official ubuntu image for virtualbox
-  config.vm.provider "virtualbox" do |_, override|
+  config.vm.provider "virtualbox" do |vb, override|
     override.vm.box = "ubuntu/trusty64"
     override.vm.synced_folder ".", "/srv/openstreetmap-website"
+    vb.customize ["modifyvm", :id, "--memory", "1024"]
+    vb.customize ["modifyvm", :id, "--cpus", "2"]
   end
 
   # use third party image and NFS sharing for lxc
index 097f557aadd317993c677458e3f2d7231bf72ae4..30ccee4415add9f9f51dab32f119aa70f8f9ebb5 100644 (file)
@@ -11,13 +11,13 @@ folder 'vendor/assets' do
   end
 
   folder 'leaflet' do
-    file 'leaflet.js', 'http://cdn.leafletjs.com/leaflet-0.7.3/leaflet-src.js'
-    file 'leaflet.css', 'http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css'
+    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'
 
     [ '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-0.7.3/images/#{image}"
+      file "images/#{image}", "http://cdn.leafletjs.com/leaflet/v0.7.7/images/#{image}"
     end
 
     from 'git://github.com/kajic/leaflet-locationfilter.git' do
@@ -49,9 +49,22 @@ 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'
+
       file 'iD.css.erb', 'dist/iD.css' do |path|
-        rewrite(path) { |content| content.gsub(/url\('?(img\/[^')]+)'?\)/, 'url(<%= asset_path("iD/\1") %>)') }
+        rewrite(path) do |content|
+          content.gsub(/url\('?(img\/[^')]+)'?\)/, 'url(<%= asset_path("iD/\1") %>)')
+        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'
index 183c7941167501914e2335c029ef69480483ca01..4528ad560f5e4adf647776b19ec3bcfb5eec0cb9 100644 (file)
Binary files a/app/assets/images/browse/motorway.20.png and b/app/assets/images/browse/motorway.20.png differ
index 7a6efb4c8ea66dceb637509a373b6ea31df6334e..91204ac6afede772a4af9f7c6963735e02e3122e 100644 (file)
Binary files a/app/assets/images/browse/primary.20.png and b/app/assets/images/browse/primary.20.png differ
index dfdfd1bfbee16226013df291ee95ec5294a1eb77..13e0aa6a40fa60e15f1bba4ffdb9071132b7bf4a 100644 (file)
Binary files a/app/assets/images/browse/secondary.20.png and b/app/assets/images/browse/secondary.20.png differ
diff --git a/app/assets/images/browse/shop_car_parts.16.png b/app/assets/images/browse/shop_car_parts.16.png
new file mode 100644 (file)
index 0000000..6c07e4d
Binary files /dev/null and b/app/assets/images/browse/shop_car_parts.16.png differ
index 49a51f113e405755c9689dbe271dc49fe2a52141..bccaa7e0e6f00ad2822870d6d30becd79e9f6b2b 100644 (file)
Binary files a/app/assets/images/browse/tertiary.20.png and b/app/assets/images/browse/tertiary.20.png differ
index 930de64e7724883bac5f4cc3c8a24cd93c35ee5c..c753a3189416d1f7a62f698626cf8b5bbb120503 100644 (file)
Binary files a/app/assets/images/browse/trunk.20.png and b/app/assets/images/browse/trunk.20.png differ
index bec836d7e4c367e42fa0baf3f21ebd0eca9998ce..5ce63ded239eed97cb60ac2a4dda43a146fe5964 100644 (file)
Binary files a/app/assets/images/key/mapnik/construction.png and b/app/assets/images/key/mapnik/construction.png differ
diff --git a/app/assets/images/key/mapnik/mainroad.png b/app/assets/images/key/mapnik/mainroad.png
new file mode 100644 (file)
index 0000000..269959b
Binary files /dev/null and b/app/assets/images/key/mapnik/mainroad.png differ
diff --git a/app/assets/images/key/mapnik/mainroad12.png b/app/assets/images/key/mapnik/mainroad12.png
new file mode 100644 (file)
index 0000000..c289a3f
Binary files /dev/null and b/app/assets/images/key/mapnik/mainroad12.png differ
diff --git a/app/assets/images/key/mapnik/mainroad7.png b/app/assets/images/key/mapnik/mainroad7.png
new file mode 100644 (file)
index 0000000..05b4dac
Binary files /dev/null and b/app/assets/images/key/mapnik/mainroad7.png differ
diff --git a/app/assets/images/key/mapnik/mainroad9.png b/app/assets/images/key/mapnik/mainroad9.png
new file mode 100644 (file)
index 0000000..334f8fc
Binary files /dev/null and b/app/assets/images/key/mapnik/mainroad9.png differ
index 3940c83d2da2b40f304d136c3ecd5ac47bb99a3d..484fc9daa3bbae3d126a4810ac83de738a462ac9 100644 (file)
Binary files a/app/assets/images/key/mapnik/motorway.png and b/app/assets/images/key/mapnik/motorway.png differ
diff --git a/app/assets/images/key/mapnik/primary.png b/app/assets/images/key/mapnik/primary.png
deleted file mode 100644 (file)
index a51703c..0000000
Binary files a/app/assets/images/key/mapnik/primary.png and /dev/null differ
diff --git a/app/assets/images/key/mapnik/primary12.png b/app/assets/images/key/mapnik/primary12.png
deleted file mode 100644 (file)
index 741b138..0000000
Binary files a/app/assets/images/key/mapnik/primary12.png and /dev/null differ
diff --git a/app/assets/images/key/mapnik/secondary.png b/app/assets/images/key/mapnik/secondary.png
deleted file mode 100644 (file)
index cbd4578..0000000
Binary files a/app/assets/images/key/mapnik/secondary.png and /dev/null differ
diff --git a/app/assets/images/key/mapnik/secondary12.png b/app/assets/images/key/mapnik/secondary12.png
deleted file mode 100644 (file)
index b95b188..0000000
Binary files a/app/assets/images/key/mapnik/secondary12.png and /dev/null differ
diff --git a/app/assets/images/key/mapnik/trunk.png b/app/assets/images/key/mapnik/trunk.png
deleted file mode 100644 (file)
index 93611ef..0000000
Binary files a/app/assets/images/key/mapnik/trunk.png and /dev/null differ
diff --git a/app/assets/images/key/mapnik/trunk12.png b/app/assets/images/key/mapnik/trunk12.png
deleted file mode 100644 (file)
index d8becf0..0000000
Binary files a/app/assets/images/key/mapnik/trunk12.png and /dev/null differ
diff --git a/app/assets/images/osm_logo_256.png b/app/assets/images/osm_logo_256.png
new file mode 100644 (file)
index 0000000..5388bc5
Binary files /dev/null and b/app/assets/images/osm_logo_256.png differ
diff --git a/app/assets/images/osm_logo_512.png b/app/assets/images/osm_logo_512.png
new file mode 100644 (file)
index 0000000..c54f416
Binary files /dev/null and b/app/assets/images/osm_logo_512.png differ
index 37d94886ddf07ea4074f92c01584394761984983..42ec7b4cdf94c3098160e40542d81ca645bc3b32 100644 (file)
Binary files a/app/assets/images/routing-sprite.png and b/app/assets/images/routing-sprite.png differ
index d5577d4b7121a50486799d697e50f189dcfc835f..c511bd90fbc7db6e940d6abce045033eca31df44 100644 (file)
Binary files a/app/assets/images/sprite.png and b/app/assets/images/sprite.png differ
index b50b969e909620ce71400c28d5c54c4dc409e1f4..df8e3e3d58c9cf6342bfb0f1f9e2071f57bc513e 100644 (file)
@@ -13,7 +13,7 @@
    height="200"
    id="svg2"
    version="1.1"
-   inkscape:version="0.48.4 r9939"
+   inkscape:version="0.91 r13725"
    inkscape:export-filename="/home/tom/rails/app/assets/images/sprite.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90"
        sodipodi:nodetypes="cccccccccccccccccc"
        d="m 129,855.3622 -1.00001,1 0,2 1.00001,1 2.00002,0 1,-1 0,-2 -1.00002,-1 z m 2e-5,6 -1.00001,1 0,6 1.00001,1 1.99998,0 1.00004,-1 -3e-5,-6 -1,-1 z"
        id="path6912"
-       style="font-size:16.71258354000000068px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:0px;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate;font-family:Helvetica Neue"
+       style="font-size:16.71258354000000068px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:0px;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica Neue"
        inkscape:connector-curvature="0" />
     <path
        inkscape:export-ydpi="90"
        inkscape:connector-curvature="0"
        id="path6914"
        d="m 57,861.36216 -1,-1 -4,0 0,-4 -1,-0.99999 -1,0 -1,1 0,4 -4,0 -1,0.99999 0,1 1,1 4,0 0,3.99999 1,1.00002 1,0 1,-1.00001 0,-3.99999 4,-10e-6 1,-0.99998 0,-1.00002 z"
-       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate" />
+       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <path
-       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate"
+       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        d="m 65,860.36216 11,-2e-5 1,1.00002 0,1.00002 -1,0.99997 -11,3e-5 -1,-1.00003 0,-1 z"
        id="path6916"
        inkscape:connector-curvature="0"
        inkscape:connector-curvature="0"
        id="path6918"
        d="m 84,862.36218 0,-2.00001 10,-3.99999 2,1e-5 0,1.99998 -4,10 -2,10e-6 0,-6 z"
-       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate" />
+       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <path
        inkscape:export-ydpi="90"
        inkscape:export-xdpi="90"
        inkscape:export-filename="/Users/saman/work_repos/osm-redesign/renders/share-1.png"
        id="path6920"
        d="m 155,854.3622 -1,1 0,2 -2,0 c -6,0 -6,7 -6,7 0,0 2,-4 6,-4 0.66667,0 1.33333,0 2,0 l 0,2 1,1 4,-4.5 -4,-4.5 z m -13,4 -1,1 0,9 1,1 10,0 1,-1 0,-2 0,-3 0,-1 -1,0 c -0.3202,-10e-5 -0.6603,0.073 -1,0.1875 l 0,2.8125 0,2 -5.5625,0 a 2.0002,2.0002 0 0 1 -0.90625,0 l -1.53125,0 0,-1.625 a 2.0002,2.0002 0 0 1 0,-0.625 l 0,-2.75 0,-2 1.53125,0 c 0.3433,-0.6691 0.79175,-1.3477 1.34375,-2 l -0.875,0 -3,0 z"
-       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate"
+       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        inkscape:connector-curvature="0" />
     <path
        inkscape:export-ydpi="90"
        inkscape:export-xdpi="90"
        inkscape:export-filename="/Users/saman/work_repos/osm-redesign/renders/share-1.png"
-       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate"
+       style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        d="m 109.50003,855.3622 -6.50002,3 1e-5,1 6.49998,3 1.00002,0 6.49999,-3 1e-5,-1 -6.50001,-3 -0.99998,0 z m -5.40621,6.5 -1.09377,0.5 -3e-5,1 6.49999,3 1,0 6.50001,-3 0,-1 -1.0937,-0.5 -5.40631,2.5 -0.99998,0 -5.40621,-2.5 z m 0,4 -1.09379,0.5 -2e-5,1 6.50001,3 1.00001,0 6.5,-3 -10e-6,-1 -1.0937,-0.5 -5.40631,2.5 -0.99999,0 -5.4062,-2.5 z"
        id="path6922"
        inkscape:connector-curvature="0" />
        inkscape:connector-curvature="0"
        id="path10739"
        d="m 11.5,855.36218 c 3.0376,0 5.5,2.46243 5.5,5.5 0,3.03757 -2.4624,5.5 -5.5,5.5 -1.0061,0 -1.9387,-0.27827 -2.75,-0.75 l -3.75,3.75 -1,0 -1,-1 0,-1 3.75,-3.75 C 6.2783,862.80084 6,861.86831 6,860.86218 c 0,-3.03757 2.4624,-5.5 5.5,-5.5 z m 0.5,2 -1,0 -2,1 -1,2 0,1 1,2 2,1 1,0 2,-1 1,-2 0,-1 -1,-2 -2,-1 z"
-       style="color:#000000;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate" />
+       style="color:#000000;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <path
        inkscape:export-ydpi="90"
        inkscape:export-xdpi="90"
        inkscape:connector-curvature="0"
        id="path6918-2"
        d="m 84,882.36218 0,-2.00001 10,-3.99999 2,1e-5 0,1.99998 -4,10 -2,10e-6 0,-6 z"
-       style="color:#000000;fill:#70cd8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6591-2);enable-background:accumulate" />
+       style="color:#000000;fill:#70cd8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
     <path
        style="color:#000000;fill:#0000ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
        d="M 185 6 L 183 8 L 183 12 L 185 14 L 187 14 L 185 12 L 185 8 L 190 8 L 190 11 L 192 11 L 192 8 L 190 6 L 187 6 L 185 6 z M 192 6 L 194 8 L 194 12 L 189 12 L 189 9 L 187 9 L 187 12 L 189 14 L 194 14 L 196 12 L 196 8 L 194 6 L 192 6 z "
        inkscape:export-ydpi="90" />
     <text
        xml:space="preserve"
-       style="font-size:20px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+       style="font-size:20px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:'DejaVu Sans', Sans, sans-serif"
        x="264.8125"
        y="869.62622"
        id="text3021"
          id="tspan3023"
          x="264.8125"
          y="869.62622">?</tspan></text>
+    <path
+       sodipodi:nodetypes="cccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path3386"
+       d="m 244,884.36218 0,-7 1,-1 10,0 1,1 0,7 -1,1 -3,0 -2,3 -2,-3 -3,0 z"
+       style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;enable-background:accumulate" />
   </g>
 </svg>
index ca5594459101720b3e95d297c40411e9a21ba1b8..a8fe29fce9d96cc75902762f8ab63b3954430ea6 100644 (file)
@@ -1,7 +1,14 @@
 //= require leaflet
 //= require leaflet.osm
+//= require i18n/translations
 
 window.onload = function () {
+  if (navigator.languages) {
+    I18n.locale = navigator.languages[0];
+  } else if (navigator.language) {
+    I18n.locale = navigator.language;
+  }
+
   var query = (window.location.search || '?').substr(1),
       args  = {};
 
@@ -51,7 +58,7 @@ window.onload = function () {
 L.Control.OSMReportAProblem = L.Control.Attribution.extend({
   options: {
     position: 'bottomright',
-    prefix: '<a href="http://www.openstreetmap.org/fixthemap?lat={x}&lon={y}&zoom={z}">Report a problem</a>'
+    prefix: '<a href="http://www.openstreetmap.org/fixthemap?lat={x}&lon={y}&zoom={z}" target="_blank">'+I18n.t('javascripts.embed.report_problem')+'</a>'
   },
 
   onAdd: function (map) {
index 085b615c7244f66214f2cddee69f89400c28d3d0..fdbeaba22fbc0bf50b96133405cc62c93d52d0c5 100644 (file)
@@ -192,10 +192,8 @@ $(document).ready(function () {
     map.setView([params.lat, params.lon], params.zoom);
   }
 
-  var marker = L.marker([0, 0], {icon: OSM.getUserIcon()});
-
   if (params.marker) {
-    marker.setLatLng([params.mlat, params.mlon]).addTo(map);
+    L.marker([params.mlat, params.mlon]).addTo(map);
   }
 
   $("#homeanchor").on("click", function(e) {
@@ -205,7 +203,7 @@ $(document).ready(function () {
       center = L.latLng(data.lat, data.lon);
 
     map.setView(center, data.zoom);
-    marker.setLatLng(center).addTo(map);
+    L.marker(center, {icon: OSM.getUserIcon()}).addTo(map);
   });
 
   function remoteEditHandler(bbox, object) {
index a8615d3eb11339f3cc7c35a39a9f06d28f00fdb5..a141045a3da13141d0b075f09303f654ee2a3f77 100644 (file)
@@ -189,7 +189,7 @@ OSM.Directions = function (map) {
         map.removeLayer(polyline);
 
         if (!dragging) {
-          alert(I18n.t('javascripts.directions.errors.no_route'));
+          $('#sidebar_content').html('<p class="search_results_error">' + I18n.t('javascripts.directions.errors.no_route') + '</p>');
         }
 
         return;
@@ -336,13 +336,8 @@ OSM.Directions = function (map) {
       setEngine(params.engine);
     }
 
-    if (params.from) {
-      endpoints[0].setValue(params.from);
-      endpoints[1].setValue("");
-    } else {
-      endpoints[0].setValue("");
-      endpoints[1].setValue("");
-    }
+    endpoints[0].setValue(params.from || "");
+    endpoints[1].setValue(params.to || "");
 
     var o = route[0] && L.latLng(route[0].split(',')),
         d = route[1] && L.latLng(route[1].split(','));
index 95cb29ab813c0ac61eb265281caf4a49c777b65b..c35085b35482fcbf336a7dd76c96522675affbb2 100644 (file)
@@ -1,4 +1,4 @@
-function GraphHopperEngine(id, vehicleParam) {
+function GraphHopperEngine(id, vehicleType) {
   var GH_INSTR_MAP = {
     "-3": 6, // sharp left
     "-2": 7, // left
@@ -20,21 +20,19 @@ function GraphHopperEngine(id, vehicleParam) {
     getRoute: function (points, callback) {
       // GraphHopper Directions API documentation
       // https://github.com/graphhopper/directions-api/blob/master/docs-routing.md
-      var url = document.location.protocol + "//graphhopper.com/api/1/route?" +
-          vehicleParam +
-          "&locale=" + I18n.currentLocale() +
-          "&key=LijBPDQGfu7Iiq80w3HzwB4RUDJbMbhs6BU0dEnn" +
-          "&type=jsonp" +
-          "&elevation=false" +
-          "&instructions=true";
-
-      for (var i = 0; i < points.length; i++) {
-        url += "&point=" + points[i].lat + ',' + points[i].lng;
-      }
-
       return $.ajax({
-        url: url,
-        dataType: 'jsonp',
+        url: document.location.protocol + OSM.GRAPHHOPPER_URL,
+        data: {
+          vehicle: vehicleType,
+          locale: I18n.currentLocale(),
+          key: "LijBPDQGfu7Iiq80w3HzwB4RUDJbMbhs6BU0dEnn",
+          type: "jsonp",
+          elevation: false,
+          instructions: true,
+          point: points.map(function (p) { return p.lat + "," + p.lng; })
+        },
+        traditional: true,
+        dataType: "jsonp",
         success: function (data) {
           if (!data.paths || data.paths.length === 0)
             return callback(true);
@@ -60,17 +58,20 @@ function GraphHopperEngine(id, vehicleParam) {
             ]); // TODO does graphhopper map instructions onto line indices?
           }
 
-          callback(null, {
+          callback(false, {
             line: line,
             steps: steps,
             distance: path.distance,
             time: path.time / 1000
           });
+        },
+        error: function () {
+          callback(true);
         }
       });
     }
   };
 }
 
-OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_bicycle", "vehicle=bike"), true);
-OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_foot", "vehicle=foot"), true);
+OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_bicycle", "bike"), true);
+OSM.Directions.addEngine(new GraphHopperEngine("graphhopper_foot", "foot"), true);
index fbbc55a5f660f2c2e89721a4fcaf4b8c85b23725..0f645ceeb7f35e621369d080517887f82154595d 100644 (file)
@@ -3,7 +3,7 @@
 // http://open.mapquestapi.com/directions/
 // https://github.com/apmon/openstreetmap-website/blob/21edc353a4558006f0ce23f5ec3930be6a7d4c8b/app/controllers/routing_controller.rb#L153
 
-function MapQuestEngine(id, vehicleParam) {
+function MapQuestEngine(id, routeType) {
   var MQ_SPRITE_MAP = {
     0: 1, // straight
     1: 2, // slight right
@@ -32,18 +32,23 @@ function MapQuestEngine(id, vehicleParam) {
     draggable: false,
 
     getRoute: function (points, callback) {
-      var url = document.location.protocol + "//open.mapquestapi.com/directions/v2/route?key=Fmjtd%7Cluur290anu%2Crl%3Do5-908a0y";
       var from = points[0];
       var to = points[points.length - 1];
-      url += "&from=" + from.lat + ',' + from.lng;
-      url += "&to=" + to.lat + ',' + to.lng;
-      url += "&" + vehicleParam;
-      //url+="&locale=" + I18n.currentLocale(); //Doesn't actually work. MapQuest requires full locale e.g. "de_DE", but I18n may only provides language, e.g. "de"
-      url += "&manMaps=false";
-      url += "&shapeFormat=raw&generalize=0&unit=k";
 
       return $.ajax({
-        url: url,
+        url: document.location.protocol + OSM.MAPQUEST_DIRECTIONS_URL,
+        data: {
+          key: OSM.MAPQUEST_KEY,
+          from: from.lat + "," + from.lng,
+          to: to.lat + "," + to.lng,
+          routeType: routeType,
+          // locale: I18n.currentLocale(), //Doesn't actually work. MapQuest requires full locale e.g. "de_DE", but I18n may only provides language, e.g. "de"
+          manMaps: false,
+          shapeFormat: "raw",
+          generalize: 0,
+          unit: "k"
+        },
+        dataType: "jsonp",
         success: function (data) {
           if (data.info.statuscode !== 0)
             return callback(true);
@@ -78,18 +83,23 @@ function MapQuestEngine(id, vehicleParam) {
             steps.push([L.latLng(s.startPoint.lat, s.startPoint.lng), d, s.narrative, s.distance * 1000, lineseg]);
           }
 
-          callback(null, {
+          callback(false, {
             line: line,
             steps: steps,
             distance: data.route.distance * 1000,
             time: data.route.time
           });
+        },
+        error: function () {
+          callback(true);
         }
       });
     }
   };
 }
 
-OSM.Directions.addEngine(new MapQuestEngine("mapquest_bicycle", "routeType=bicycle"), true);
-OSM.Directions.addEngine(new MapQuestEngine("mapquest_foot", "routeType=pedestrian"), true);
-OSM.Directions.addEngine(new MapQuestEngine("mapquest_car", "routeType=fastest"), true);
+if (OSM.MAPQUEST_KEY) {
+  OSM.Directions.addEngine(new MapQuestEngine("mapquest_bicycle", "bicycle"), true);
+  OSM.Directions.addEngine(new MapQuestEngine("mapquest_foot", "pedestrian"), true);
+  OSM.Directions.addEngine(new MapQuestEngine("mapquest_car", "fastest"), true);
+}
diff --git a/app/assets/javascripts/index/directions/mapzen.js b/app/assets/javascripts/index/directions/mapzen.js
new file mode 100644 (file)
index 0000000..348cb99
--- /dev/null
@@ -0,0 +1,109 @@
+function MapzenEngine(id, costing) {
+  var MZ_INSTR_MAP = [
+    1,  // kNone = 0;
+    14, // kStart = 1;
+    14, // kStartRight = 2;
+    14, // kStartLeft = 3;
+    15, // kDestination = 4;
+    15, // kDestinationRight = 5;
+    15, // kDestinationLeft = 6;
+    1,  // kBecomes = 7;
+    1,  // kContinue = 8;
+    2,  // kSlightRight = 9;
+    3,  // kRight = 10;
+    4,  // kSharpRight = 11;
+    5,  // kUturnRight = 12;
+    5,  // kUturnLeft = 13;
+    6,  // kSharpLeft = 14;
+    7,  // kLeft = 15;
+    8,  // kSlightLeft = 16;
+    1,  // kRampStraight = 17;
+    2,  // kRampRight = 18;
+    8,  // kRampLeft = 19;
+    2,  // kExitRight = 20;
+    8,  // kExitLeft = 21;
+    1,  // kStayStraight = 22;
+    2,  // kStayRight = 23;
+    8,  // kStayLeft = 24;
+    1,  // kMerge = 25;
+    11, // kRoundaboutEnter = 26;
+    12, // kRoundaboutExit = 27;
+    18, // kFerryEnter = 28;
+    1   // kFerryExit = 29;
+  ];
+
+  return {
+    id: id,
+    creditline: "<a href='https://mapzen.com/projects/valhalla' target='_blank'>Mapzen</a>",
+    draggable: false,
+
+    getRoute: function (points, callback) {
+      return $.ajax({
+        url: document.location.protocol + OSM.MAPZEN_VALHALLA_URL,
+        data: {
+          api_key: OSM.MAPZEN_VALHALLA_KEY,
+          json: JSON.stringify({
+            locations: points.map(function (p) { return { lat: p.lat, lon: p.lng }; }),
+            costing: costing,
+            directions_options: {
+              units: "km",
+              language: I18n.currentLocale()
+            }
+          })
+        },
+        dataType: "json",
+        success: function (data) {
+          var trip = data.trip;
+
+          if (trip.status === 0) {
+            var line = [];
+            var steps = [];
+            var distance = 0;
+            var time = 0;
+
+            trip.legs.forEach(function (leg) {
+              var legLine = L.PolylineUtil.decode(leg.shape, {
+                precision: 6
+              });
+
+              line = line.concat(legLine);
+
+              leg.maneuvers.forEach(function (manoeuvre) {
+                var point = legLine[manoeuvre.begin_shape_index];
+
+                steps.push([
+                  { lat: point[0], lng: point[1] },
+                  MZ_INSTR_MAP[manoeuvre.type],
+                  manoeuvre.instruction,
+                  manoeuvre.length * 1000,
+                  []
+                ]);
+              });
+
+              distance = distance + leg.summary.length;
+              time = time + leg.summary.time;
+            });
+
+            callback(false, {
+              line: line,
+              steps: steps,
+              distance: distance * 1000,
+              time: time
+            });
+          } else {
+            callback(true);
+          }
+        },
+        error: function () {
+          callback(true);
+        }
+      });
+    }
+  };
+}
+
+if (OSM.MAPZEN_VALHALLA_KEY) {
+  OSM.Directions.addEngine(new MapzenEngine("mapzen_car", "auto"), true);
+  OSM.Directions.addEngine(new MapzenEngine("mapzen_bicycle", "bicycle"), true);
+  OSM.Directions.addEngine(new MapzenEngine("mapzen_foot", "pedestrian"), true);
+}
index b53fecb81921131aac57a0d6e908393425682521..2ee9da12b1d78dbce1f057d9f706e5d4fa374692 100644 (file)
@@ -28,25 +28,32 @@ function OSRMEngine() {
         'javascripts.directions.instructions.start',            // 14
         'javascripts.directions.instructions.destination',      // 15
         'javascripts.directions.instructions.against_oneway',   // 16
-        'javascripts.directions.instructions.end_oneway'        // 17
+        'javascripts.directions.instructions.end_oneway',       // 17
+        'javascripts.directions.instructions.ferry'             // 18
       ];
 
-      var url = document.location.protocol + "//router.project-osrm.org/viaroute?z=14&output=json&instructions=true";
+      var params = [
+        { name: "z", value: "14" },
+        { name: "output", value: "json" },
+        { name: "instructions", value: true }
+      ];
 
       for (var i = 0; i < points.length; i++) {
-        url += "&loc=" + points[i].lat + ',' + points[i].lng;
+        params.push({ name: "loc", value: points[i].lat + "," + points[i].lng });
+
         if (hintData && previousPoints && previousPoints[i].equals(points[i])) {
-          url += "&hint=" + hintData.locations[i];
+          params.push({ name: "hint", value: hintData.locations[i] });
         }
       }
 
       if (hintData && hintData.checksum) {
-        url += "&checksum=" + hintData.checksum;
+        params.push({ name: "checksum", value: hintData.checksum });
       }
 
       return $.ajax({
-        url: url,
-        dataType: 'json',
+        url: document.location.protocol + OSM.OSRM_URL,
+        data: params,
+        dataType: "json",
         success: function (data) {
           if (data.status === 207)
             return callback(true);
@@ -63,6 +70,10 @@ function OSRMEngine() {
             var s = data.route_instructions[i];
             var linesegend;
             var instCodes = s[0].split('-');
+            if (s[8] === 2) {
+              /* indicates a ferry in car routing mode, see https://github.com/Project-OSRM/osrm-backend/blob/6cbbd1e5a1b441eb27055f56956e1bac14832a58/profiles/car.lua#L151 */
+              instCodes = ["18"];
+            }
             var instText = "<b>" + (i + 1) + ".</b> ";
             var name = s[1] ? "<b>" + s[1] + "</b>" : I18n.t('javascripts.directions.instructions.unnamed');
             if (instCodes[0] === "11" && instCodes[1]) {
@@ -75,15 +86,18 @@ function OSRMEngine() {
             } else {
               linesegend = s[3] + 1;
             }
-            steps.push([line[s[3]], s[0].split('-')[0], instText, s[2], line.slice(s[3], linesegend)]);
+            steps.push([line[s[3]], instCodes[0], instText, s[2], line.slice(s[3], linesegend)]);
           }
 
-          callback(null, {
+          callback(false, {
             line: line,
             steps: steps,
             distance: data.route_summary.total_distance,
             time: data.route_summary.total_time
           });
+        },
+        error: function () {
+          callback(true);
         }
       });
     }
index 333fce5494866c9c9ff4503a61288b658ede9641..86f24e0469603751af413aadf02e64be547960aa 100644 (file)
@@ -161,7 +161,7 @@ OSM.Query = function(map) {
     return geometry;
   }
 
-  function runQuery(latlng, radius, query, $section, compare) {
+  function runQuery(latlng, radius, query, $section, merge, compare) {
     var $ul = $section.find("ul");
 
     $ul.empty();
@@ -186,12 +186,27 @@ OSM.Query = function(map) {
 
         $section.find(".loader").stopTime("loading").hide();
 
-        if (compare) {
-          elements = results.elements.sort(compare);
+        if (merge) {
+          elements = results.elements.reduce(function (hash, element) {
+            var key = element.type + element.id;
+            if ("geometry" in element) {
+              delete element.bounds;
+            }
+            hash[key] = $.extend({}, hash[key], element);
+            return hash;
+          }, {});
+
+          elements = Object.keys(elements).map(function (key) {
+            return elements[key];
+          });
         } else {
           elements = results.elements;
         }
 
+        if (compare) {
+          elements = elements.sort(compare);
+        }
+
         for (var i = 0; i < elements.length; i++) {
           var element = elements[i];
 
@@ -268,7 +283,7 @@ OSM.Query = function(map) {
       ways = "way(" + around + ")",
       relations = "relation(" + around + ")",
       nearby = "(" + nodes + ";" + ways + ");out tags geom(" + bbox + ");" + relations + ";out geom(" + bbox + ");",
-      isin = "is_in(" + lat + "," + lng + ")->.a;way(pivot.a);out tags geom(" + bbox + ");relation(pivot.a);out tags bb;";
+      isin = "is_in(" + lat + "," + lng + ")->.a;way(pivot.a);out tags bb;out ids geom(" + bbox + ");relation(pivot.a);out tags bb;";
 
     $("#sidebar_content .query-intro")
       .hide();
@@ -287,8 +302,8 @@ OSM.Query = function(map) {
       }
     }, 10);
 
-    runQuery(latlng, radius, nearby, $("#query-nearby"));
-    runQuery(latlng, radius, isin, $("#query-isin"), compareSize);
+    runQuery(latlng, radius, nearby, $("#query-nearby"), false);
+    runQuery(latlng, radius, isin, $("#query-isin"), true, compareSize);
   }
 
   function clickHandler(e) {
index 485920c8e1f901f93c1a04b1e29bdcdac4ba0146..9481e271e9565446c9e1abee595f531a0ec1a3c5 100644 (file)
@@ -119,6 +119,7 @@ OSM.Search = function(map) {
   page.pushstate = page.popstate = function(path) {
     var params = querystring.parse(path.substring(path.indexOf('?') + 1));
     $(".search_form input[name=query]").val(params.query);
+    $(".describe_location").hide();
     OSM.loadSidebarContent(path, page.load);
   };
 
index d2928068d4d6a1ec1a754e0a081f75b90f4cf356..9f2e50a6f4afaa928cb6c1611b24843708cabd09 100644 (file)
@@ -101,6 +101,8 @@ L.OSM.layers = function(options) {
         map.fire('baselayerchange', {layer: layer});
       });
 
+      item.on('dblclick', toggle);
+
       map.on('layeradd layerremove', function() {
         item.toggleClass('active', map.hasLayer(layer));
         input.prop('checked', map.hasLayer(layer));
index b991210dfad5a063fcc48d76181c0deb5e72a2c6..a6b10821e868bc603da0b1d4e0bff296cf945818 100644 (file)
@@ -145,7 +145,14 @@ L.OSM.share = function (options) {
       .text(I18n.t('javascripts.share.image'))
       .appendTo($imageSection);
 
+    $('<div>')
+      .attr('id', 'export-warning')
+      .attr('class', 'deemphasize')
+      .text(I18n.t('javascripts.share.only_standard_layer'))
+      .appendTo($imageSection);
+
     $form = $('<form>')
+      .attr('id', 'export-image')
       .attr('class', 'standard-form')
       .attr('action', '/export/finish')
       .attr('method', 'post')
@@ -364,6 +371,14 @@ L.OSM.share = function (options) {
 
       $("#mapnik_image_width").text(Math.round(size.x / scale / 0.00028));
       $("#mapnik_image_height").text(Math.round(size.y / scale / 0.00028));
+
+      if (map.getMapBaseLayerId() === 'mapnik') {
+        $('#export-image').show();
+        $('#export-warning').hide();
+      } else {
+        $('#export-image').hide();
+        $('#export-warning').show();
+      }
     }
 
     function select() {
diff --git a/app/assets/javascripts/login.js b/app/assets/javascripts/login.js
new file mode 100644 (file)
index 0000000..b7a540f
--- /dev/null
@@ -0,0 +1,25 @@
+$(document).ready(function() {
+  // Preserve location hash in referer
+  if (window.location.hash) {
+    $("#referer").val($("#referer").val() + window.location.hash);
+  }
+
+  // Attach referer to authentication buttons
+  $(".auth_button").each(function () {
+    var params = querystring.parse(this.search.substring(1));
+    params.referer = $("#referer").val();
+    this.search = querystring.stringify(params);
+  });
+
+  // Add click handler to show OpenID field
+  $("#openid_open_url").click(function() {
+    $("#openid_url").val("http://");
+    $("#login_auth_buttons").hide();
+    $("#login_openid_url").show();
+    $("#login_openid_submit").show();
+  });
+
+  // Hide OpenID field for now
+  $("#login_openid_url").hide();
+  $("#login_openid_submit").hide();
+});
index 6afebf8e5dc0db61730a2feaa253a7fe7fcd3e0b..138416be12525fa1fb1480c3e5151f69ffb76daa 100644 (file)
@@ -1,26 +1,39 @@
+//= depend_on application.yml
+
 OSM = {
 <% if defined?(PIWIK) %>
-  PIWIK:                 <%= PIWIK.to_json %>,
+  PIWIK:                   <%= PIWIK.to_json %>,
 <% end %>
 
-  MAX_REQUEST_AREA:      <%= MAX_REQUEST_AREA.to_json %>,
-  SERVER_URL:            <%= SERVER_URL.to_json %>,
-  API_VERSION:           <%= API_VERSION.to_json %>,
-  STATUS:                <%= STATUS.to_json %>,
-  MAX_NOTE_REQUEST_AREA: <%= MAX_NOTE_REQUEST_AREA.to_json %>,
-  OVERPASS_URL:          <%= OVERPASS_URL.to_json %>,
-  NOMINATIM_URL:         <%= NOMINATIM_URL.to_json %>,
+  MAX_REQUEST_AREA:        <%= MAX_REQUEST_AREA.to_json %>,
+  SERVER_URL:              <%= SERVER_URL.to_json %>,
+  API_VERSION:             <%= API_VERSION.to_json %>,
+  STATUS:                  <%= STATUS.to_json %>,
+  MAX_NOTE_REQUEST_AREA:   <%= MAX_NOTE_REQUEST_AREA.to_json %>,
+  OVERPASS_URL:            <%= OVERPASS_URL.to_json %>,
+  NOMINATIM_URL:           <%= NOMINATIM_URL.to_json %>,
+  GRAPHHOPPER_URL:         <%= GRAPHHOPPER_URL.to_json %>,
+  MAPQUEST_DIRECTIONS_URL: <%= MAPQUEST_DIRECTIONS_URL.to_json %>,
+  MAPZEN_VALHALLA_URL:     <%= MAPZEN_VALHALLA_URL.to_json %>,
+  OSRM_URL:                <%= OSRM_URL.to_json %>,
+
+<% if defined?(MAPQUEST_KEY) %>
+  MAPQUEST_KEY:            <%= MAPQUEST_KEY.to_json %>,
+<% end %>
+<% if defined?(MAPZEN_VALHALLA_KEY) %>
+  MAPZEN_VALHALLA_KEY:     <%= MAPZEN_VALHALLA_KEY.to_json %>,
+<% end %>
 
-  MARKER_GREEN:          <%= image_path("marker-green.png").to_json %>,
-  MARKER_RED:            <%= image_path("marker-red.png").to_json %>,
+  MARKER_GREEN:            <%= image_path("marker-green.png").to_json %>,
+  MARKER_RED:              <%= image_path("marker-red.png").to_json %>,
 
-  MARKER_ICON:           <%= image_path("images/marker-icon.png").to_json %>,
-  MARKER_ICON_2X:        <%= image_path("images/marker-icon-2x.png").to_json %>,
-  MARKER_SHADOW:         <%= image_path("images/marker-shadow.png").to_json %>,
+  MARKER_ICON:             <%= image_path("images/marker-icon.png").to_json %>,
+  MARKER_ICON_2X:          <%= image_path("images/marker-icon-2x.png").to_json %>,
+  MARKER_SHADOW:           <%= image_path("images/marker-shadow.png").to_json %>,
 
-  NEW_NOTE_MARKER:       <%= image_path("new_note_marker.png").to_json %>,
-  OPEN_NOTE_MARKER:      <%= image_path("open_note_marker.png").to_json %>,
-  CLOSED_NOTE_MARKER:    <%= image_path("closed_note_marker.png").to_json %>,
+  NEW_NOTE_MARKER:         <%= image_path("new_note_marker.png").to_json %>,
+  OPEN_NOTE_MARKER:        <%= image_path("open_note_marker.png").to_json %>,
+  CLOSED_NOTE_MARKER:      <%= image_path("closed_note_marker.png").to_json %>,
 
   apiUrl: function (object) {
     var url = "/api/" + OSM.API_VERSION + "/" + object.type + "/" + object.id;
@@ -44,7 +57,12 @@ OSM = {
         j = pair.indexOf('='),
         key = pair.slice(0, j),
         val = pair.slice(++j);
-      params[key] = decodeURIComponent(val);
+
+      try {
+        params[key] = decodeURIComponent(val);
+      } catch (e) {
+        // Ignore parse exceptions
+      }
     }
 
     return params;
index f2241b4cf12e5a894c464f71b83369b0136c510e..f497a22d86db7eb994ada531fbc07dc26110ed18 100644 (file)
@@ -98,6 +98,7 @@
   .shop.books::before { content: image-url('browse/shop_books.16.png'); }
   .shop.butcher::before { content: image-url('browse/shop_butcher.p.16.png'); }
   .shop.clothes::before { content: image-url('browse/shop_clothes.16.png'); }
+  .shop.car_parts::before { content: image-url('browse/shop_car_parts.16.png'); }
   .shop.car_repair::before { content: image-url('browse/shop_car_repair.16.png'); }
   .shop.convenience::before { content: image-url('browse/shop_convenience.p.16.png'); }
   .shop.diy::before { content: image-url('browse/shop_doityourself.16.png'); }
index 6706aa6ed9321b5e5c6ce5b14003a046ba91d3f3..cf687653e1efa19bd18fd82ddf7ad20d4aec8055 100644 (file)
@@ -151,13 +151,14 @@ small, aside {
 /* Rules for icons */
 
 .icon {
-  display:inline-block;
-  vertical-align:top;
-  width:20px;
-  height:20px;
-  background:transparent image-url("sprite.png") no-repeat 0 0;
-  text-indent:-9999px;
-  overflow:hidden;
+  display: inline-block;
+  vertical-align: top;
+  width: 20px;
+  height: 20px;
+  background: transparent image-url("sprite.png") no-repeat 0 0;
+  background-image: image-url("sprite.svg");
+  text-indent: -9999px;
+  overflow: hidden;
 }
 
 .icon.search      { background-position: 0 0; }
@@ -175,6 +176,7 @@ small, aside {
 .icon.close:hover { background-position: -200px -20px; }
 .icon.check       { background-position: -220px 0; }
 .icon.note        { background-position: -240px 0; }
+.icon.note.grey   { background-position: -240px -20px; }
 .icon.query       { background-position: -260px 0; }
 
 /* Rules for links */
@@ -1001,7 +1003,7 @@ div.direction {
   height: 20px;
   background-repeat: no-repeat;
 }
-@for $i from 1 through 17 {
+@for $i from 1 through 18 {
 div.direction.i#{$i} { background-position: #{($i)*-20+20}px 0px; }
 }
 
@@ -1059,6 +1061,15 @@ tr.turn:hover {
       color: #000;
     }
   }
+
+  .comments {
+    float: right;
+    color: #999;
+  }
+
+  .comments-0 {
+    opacity: 0.5;
+  }
 }
 
 /* Rules for the browse sidebar */
@@ -1324,6 +1335,11 @@ tr.turn:hover {
 .user-terms {
   .content-body .content-inner {
     padding: 0;
+
+    .message {
+      margin-top: 80px;
+      padding: 20px;
+    }
   }
 }
 
@@ -1577,10 +1593,6 @@ tr.turn:hover {
     float: left;
     display: block;
   }
-
-  ul.secondary-actions {
-    display: inline-block;
-  }
 }
 
 .content-heading .hide_unless_logged_in { // hacky selector, better to just add a new class to this div
@@ -1813,6 +1825,19 @@ tr.turn:hover {
     display: inline-block;
     margin-left: $lineheight / 2;
     vertical-align: middle;
+
+    p {
+      margin-top: $lineheight * 0.5;
+      margin-bottom: $lineheight * 0.5;
+
+      &:first-child {
+        margin-top: 0px;
+      }
+
+      &:last-child {
+        margin-bottom: 0px;
+      }
+    }
   }
 }
 
index f6ae7f231443228d4a349f98b318d832d6b4aa26..9cd6857483982e89cb8c5feec0098ee774a540d2 100644 (file)
@@ -151,7 +151,7 @@ class AmfController < ApplicationController
         cs = Changeset.find(closeid.to_i)
         cs.set_closed_time_now
         if cs.user_id != user.id
-          fail OSM::APIUserChangesetMismatchError.new
+          raise OSM::APIUserChangesetMismatchError.new
         elsif closecomment.empty?
           cs.save!
         else
@@ -189,12 +189,14 @@ class AmfController < ApplicationController
   def getpresets(usertoken, lang) #:doc:
     user = getuser(usertoken)
 
-    if user && !user.languages.empty?
-      http_accept_language.user_preferred_languages = user.languages
-    end
+    langs = if user && !user.languages.empty?
+              Locale.list(user.languages)
+            else
+              Locale.list(http_accept_language.user_preferred_languages)
+            end
 
-    lang = http_accept_language.compatible_language_from(getlocales)
-    (real_lang, localised) = getlocalized(lang)
+    lang = getlocales.preferred(langs)
+    (real_lang, localised) = getlocalized(lang.to_s)
 
     # Tell Potlatch what language it's using
     localised["__potlatch_locale"] = real_lang
@@ -469,11 +471,11 @@ class AmfController < ApplicationController
       return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
 
       query = Trace.visible_to(user)
-      if searchterm.to_i > 0
-        query = query.where(:id => searchterm.to_i)
-      else
-        query = query.where("MATCH(name) AGAINST (?)", searchterm).limit(21)
-      end
+      query = if searchterm.to_i > 0
+                query.where(:id => searchterm.to_i)
+              else
+                query.where("MATCH(name) AGAINST (?)", searchterm).limit(21)
+              end
       gpxs = query.collect do |gpx|
         [gpx.id, gpx.name, gpx.description]
       end
@@ -675,7 +677,7 @@ class AmfController < ApplicationController
 
         # -- Save revised way
 
-        pointlist.collect! do|a|
+        pointlist.collect! do |a|
           renumberednodes[a] ? renumberednodes[a] : a
         end # renumber nodes
         new_way = Way.new
@@ -866,15 +868,14 @@ class AmfController < ApplicationController
 
   def getuser(token) #:doc:
     if token =~ /^(.+)\:(.+)$/
-      user = User.authenticate(:username => $1, :password => $2)
+      User.authenticate(:username => $1, :password => $2)
     else
-      user = User.authenticate(:token => token)
+      User.authenticate(:token => token)
     end
-    user
   end
 
   def getlocales
-    Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") }
+    @locales ||= Locale.list(Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") })
   end
 
   ##
index 379bb7e8650c3577588e4954d8a731c721425b99..25e1e3b95cc9edebaff056d1ea9fdbcf5ca22f98 100644 (file)
@@ -136,12 +136,14 @@ class ApiController < ApplicationController
     doc = OSM::API.new.get_xml_doc
 
     # add bounds
-    doc.root << bbox.add_bounds_to(XML::Node.new "bounds")
+    doc.root << bbox.add_bounds_to(XML::Node.new("bounds"))
 
     # get ways
     # find which ways are needed
     ways = []
-    if node_ids.length > 0
+    if node_ids.empty?
+      list_of_way_nodes = []
+    else
       way_nodes = WayNode.where(:node_id => node_ids)
       way_ids = way_nodes.collect { |way_node| way_node.id[0] }
       ways = Way.preload(:way_nodes, :way_tags).find(way_ids)
@@ -150,15 +152,12 @@ class ApiController < ApplicationController
         way.way_nodes.collect(&:node_id)
       end
       list_of_way_nodes.flatten!
-
-    else
-      list_of_way_nodes = []
     end
 
     # - [0] in case some thing links to node 0 which doesn't exist. Shouldn't actually ever happen but it does. FIXME: file a ticket for this
     nodes_to_fetch = (list_of_way_nodes.uniq - node_ids) - [0]
 
-    if nodes_to_fetch.length > 0
+    unless nodes_to_fetch.empty?
       nodes += Node.includes(:node_tags).find(nodes_to_fetch)
     end
 
@@ -258,8 +257,8 @@ class ApiController < ApplicationController
 
     api = XML::Node.new "api"
     version = XML::Node.new "version"
-    version["minimum"] = "#{API_VERSION}"
-    version["maximum"] = "#{API_VERSION}"
+    version["minimum"] = API_VERSION.to_s
+    version["maximum"] = API_VERSION.to_s
     api << version
     area = XML::Node.new "area"
     area["maximum"] = MAX_REQUEST_AREA.to_s
index 3470db86c0774d43db7fda4dd234690257ae5d91..f3b77f8108acade06c00f70a367a3f6f606cd2f1 100644 (file)
@@ -140,13 +140,13 @@ class ApplicationController < ActionController::Base
     unless Authenticator.new(self, [:token]).allow?
       username, passwd = get_auth_data # parse from headers
       # authenticate per-scheme
-      if username.nil?
-        @user = nil # no authentication provided - perhaps first connect (client should retry after 401)
-      elsif username == "token"
-        @user = User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth
-      else
-        @user = User.authenticate(:username => username, :password => passwd) # basic auth
-      end
+      @user = if username.nil?
+                nil # no authentication provided - perhaps first connect (client should retry after 401)
+              elsif username == "token"
+                User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth
+              else
+                User.authenticate(:username => username, :password => passwd) # basic auth
+              end
     end
 
     # have we identified the user?
@@ -276,7 +276,7 @@ class ApplicationController < ActionController::Base
     response.headers["Error"] = message
 
     if request.headers["X-Error-Format"] &&
-       request.headers["X-Error-Format"].downcase == "xml"
+       request.headers["X-Error-Format"].casecmp("xml").zero?
       result = OSM::API.new.get_xml_doc
       result.root.name = "osmError"
       result.root << (XML::Node.new("status") << "#{Rack::Utils.status_code(status)} #{Rack::Utils::HTTP_STATUS_CODES[status]}")
@@ -288,47 +288,30 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  def set_locale
-    response.header["Vary"] = "Accept-Language"
-
-    if @user && !@user.languages.empty?
-      http_accept_language.user_preferred_languages = @user.languages
-      response.header["Vary"] = "*"
-    end
+  def preferred_languages
+    @languages ||= if params[:locale]
+                     Locale.list(params[:locale])
+                   elsif @user
+                     @user.preferred_languages
+                   else
+                     Locale.list(http_accept_language.user_preferred_languages)
+                   end
+  end
 
-    I18n.locale = select_locale
+  helper_method :preferred_languages
 
+  def set_locale
     if @user && @user.languages.empty? && !http_accept_language.user_preferred_languages.empty?
       @user.languages = http_accept_language.user_preferred_languages
       @user.save
     end
 
-    response.headers["Content-Language"] = I18n.locale.to_s
-  end
-
-  def select_locale(locales = I18n.available_locales)
-    if params[:locale]
-      http_accept_language.user_preferred_languages = [params[:locale]]
-    end
-
-    if http_accept_language.compatible_language_from(locales).nil?
-      http_accept_language.user_preferred_languages = http_accept_language.user_preferred_languages.collect do |pl|
-        pls = [pl]
-
-        while pl.match(/^(.*)-[^-]+$/)
-          pls.push($1) if locales.include?($1) || locales.include?($1.to_sym)
-          pl = $1
-        end
-
-        pls
-      end.flatten
-    end
+    I18n.locale = Locale.available.preferred(preferred_languages)
 
-    http_accept_language.compatible_language_from(locales) || I18n.default_locale
+    response.headers["Vary"] = "Accept-Language"
+    response.headers["Content-Language"] = I18n.locale.to_s
   end
 
-  helper_method :select_locale
-
   def api_call_handle_error
     yield
   rescue ActiveRecord::RecordNotFound => ex
@@ -354,7 +337,7 @@ class ApplicationController < ActionController::Base
   # or raises a suitable error. +method+ should be a symbol, e.g: :put or :get.
   def assert_method(method)
     ok = request.send((method.to_s.downcase + "?").to_sym)
-    fail OSM::APIBadMethodError.new(method) unless ok
+    raise OSM::APIBadMethodError.new(method) unless ok
   end
 
   ##
@@ -435,10 +418,6 @@ class ApplicationController < ActionController::Base
                DEFAULT_EDITOR
              end
 
-    if request.env["HTTP_USER_AGENT"] =~ /MSIE|Trident/ && editor == "id"
-      editor = "potlatch2"
-    end
-
     editor
   end
 
index 0ac45b9261d1a4dcc1a1d6135747ca6489fd5f40..7d2f80eb90a4c6dde5f35876dfac24bc6235a890 100644 (file)
@@ -58,11 +58,11 @@ class BrowseController < ApplicationController
   def changeset
     @type = "changeset"
     @changeset = Changeset.find(params[:id])
-    if @user && @user.moderator?
-      @comments = @changeset.comments.unscope(:where => :visible).includes(:author)
-    else
-      @comments = @changeset.comments.includes(:author)
-    end
+    @comments = if @user && @user.moderator?
+                  @changeset.comments.unscope(:where => :visible).includes(:author)
+                else
+                  @changeset.comments.includes(:author)
+                end
     @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "node_page")
     @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "way_page")
     @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "relation_page")
index 2ce024c76476d4332550f7e99fed2c8b7a83c261..89ba5d1313efabfda84b5e9a89132e0412a4364e 100644 (file)
@@ -162,7 +162,7 @@ class ChangesetController < ApplicationController
     # global (SVN-style) versioning were used - then that would be
     # unambiguous.
     elements.sort! do |a, b|
-      if (a.timestamp == b.timestamp)
+      if a.timestamp == b.timestamp
         a.version <=> b.version
       else
         a.timestamp <=> b.timestamp
@@ -182,20 +182,18 @@ class ChangesetController < ApplicationController
     # check these assertions.
     elements.each do |elt|
       result.root <<
-        if (elt.version == 1)
+        if elt.version == 1
           # first version, so it must be newly-created.
           created = XML::Node.new "create"
           created << elt.to_xml_node(changeset_cache, user_display_name_cache)
+        elsif elt.visible
+          # must be a modify
+          modified = XML::Node.new "modify"
+          modified << elt.to_xml_node(changeset_cache, user_display_name_cache)
         else
-          if elt.visible
-            # must be a modify
-            modified = XML::Node.new "modify"
-            modified << elt.to_xml_node(changeset_cache, user_display_name_cache)
-          else
-            # if the element isn't visible then it must have been deleted
-            deleted = XML::Node.new "delete"
-            deleted << elt.to_xml_node(changeset_cache, user_display_name_cache)
-          end
+          # if the element isn't visible then it must have been deleted
+          deleted = XML::Node.new "delete"
+          deleted << elt.to_xml_node(changeset_cache, user_display_name_cache)
         end
     end
 
@@ -277,11 +275,11 @@ class ChangesetController < ApplicationController
       changesets = conditions_nonempty(Changeset.all)
 
       if params[:display_name]
-        if user.data_public? || user == @user
-          changesets = changesets.where(:user_id => user.id)
-        else
-          changesets = changesets.where("false")
-        end
+        changesets = if user.data_public? || user == @user
+                       changesets.where(:user_id => user.id)
+                     else
+                       changesets.where("false")
+                     end
       elsif params[:bbox]
         changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params))
       elsif params[:friends] && @user
@@ -294,7 +292,7 @@ class ChangesetController < ApplicationController
         changesets = changesets.where("changesets.id <= ?", params[:max_id])
       end
 
-      @edits = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags)
+      @edits = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments)
 
       render :action => :list, :layout => false
     end
@@ -310,8 +308,8 @@ class ChangesetController < ApplicationController
   # Add a comment to a changeset
   def comment
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
-    fail OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
 
     # Extract the arguments
     id = params[:id].to_i
@@ -319,7 +317,7 @@ class ChangesetController < ApplicationController
 
     # Find the changeset and check it is valid
     changeset = Changeset.find(id)
-    fail OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open?
+    raise OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open?
 
     # Add a comment to the changeset
     comment = changeset.comments.create(:changeset => changeset,
@@ -327,7 +325,7 @@ class ChangesetController < ApplicationController
                                         :author => @user)
 
     # Notify current subscribers of the new comment
-    changeset.subscribers.each do |user|
+    changeset.subscribers.visible.each do |user|
       if @user != user
         Notifier.changeset_comment_notification(comment, user).deliver_now
       end
@@ -344,15 +342,15 @@ class ChangesetController < ApplicationController
   # Adds a subscriber to the changeset
   def subscribe
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
 
     # Find the changeset and check it is valid
     changeset = Changeset.find(id)
-    fail OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open?
-    fail OSM::APIChangesetAlreadySubscribedError.new(changeset) if changeset.subscribers.exists?(@user.id)
+    raise OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open?
+    raise OSM::APIChangesetAlreadySubscribedError.new(changeset) if changeset.subscribers.exists?(@user.id)
 
     # Add the subscriber
     changeset.subscribers << @user
@@ -365,15 +363,15 @@ class ChangesetController < ApplicationController
   # Removes a subscriber from the changeset
   def unsubscribe
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
 
     # Find the changeset and check it is valid
     changeset = Changeset.find(id)
-    fail OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open?
-    fail OSM::APIChangesetNotSubscribedError.new(changeset) unless changeset.subscribers.exists?(@user.id)
+    raise OSM::APIChangesetNotYetClosedError.new(changeset) if changeset.is_open?
+    raise OSM::APIChangesetNotSubscribedError.new(changeset) unless changeset.subscribers.exists?(@user.id)
 
     # Remove the subscriber
     changeset.subscribers.delete(@user)
@@ -386,7 +384,7 @@ class ChangesetController < ApplicationController
   # Sets visible flag on comment to false
   def hide_comment
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
@@ -405,7 +403,7 @@ class ChangesetController < ApplicationController
   # Sets visible flag on comment to true
   def unhide_comment
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
@@ -459,11 +457,12 @@ class ChangesetController < ApplicationController
     if bbox
       bbox.check_boundaries
       bbox = bbox.to_scaled
-      return changesets.where("min_lon < ? and max_lon > ? and min_lat < ? and max_lat > ?",
-                              bbox.max_lon.to_i, bbox.min_lon.to_i,
-                              bbox.max_lat.to_i, bbox.min_lat.to_i)
+
+      changesets.where("min_lon < ? and max_lon > ? and min_lat < ? and max_lat > ?",
+                       bbox.max_lon.to_i, bbox.min_lon.to_i,
+                       bbox.max_lat.to_i, bbox.min_lat.to_i)
     else
-      return changesets
+      changesets
     end
   end
 
@@ -471,22 +470,22 @@ class ChangesetController < ApplicationController
   # restrict changesets to those by a particular user
   def conditions_user(changesets, user, name)
     if user.nil? && name.nil?
-      return changesets
+      changesets
     else
       # shouldn't provide both name and UID
-      fail OSM::APIBadUserInput.new("provide either the user ID or display name, but not both") if user && name
+      raise OSM::APIBadUserInput.new("provide either the user ID or display name, but not both") if user && name
 
       # use either the name or the UID to find the user which we're selecting on.
       u = if name.nil?
             # user input checking, we don't have any UIDs < 1
-            fail OSM::APIBadUserInput.new("invalid user ID") if user.to_i < 1
+            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)
           end
 
       # make sure we found a user
-      fail OSM::APINotFoundError.new if u.nil?
+      raise OSM::APINotFoundError.new if u.nil?
 
       # should be able to get changesets of public users only, or
       # our own changesets regardless of public-ness.
@@ -495,9 +494,10 @@ class ChangesetController < ApplicationController
         # changesets if they're non-public
         setup_user_auth
 
-        fail OSM::APINotFoundError if @user.nil? || @user.id != u.id
+        raise OSM::APINotFoundError if @user.nil? || @user.id != u.id
       end
-      return changesets.where(:user_id => u.id)
+
+      changesets.where(:user_id => u.id)
     end
   end
 
@@ -506,20 +506,19 @@ class ChangesetController < ApplicationController
   def conditions_time(changesets, time)
     if time.nil?
       return changesets
-    else
+    elsif time.count(",") == 1
       # if there is a range, i.e: comma separated, then the first is
       # low, second is high - same as with bounding boxes.
-      if time.count(",") == 1
-        # check that we actually have 2 elements in the array
-        times = time.split(/,/)
-        fail OSM::APIBadUserInput.new("bad time range") if times.size != 2
 
-        from, to = times.collect { |t| DateTime.parse(t) }
-        return changesets.where("closed_at >= ? and created_at <= ?", from, to)
-      else
-        # if there is no comma, assume its a lower limit on time
-        return changesets.where("closed_at >= ?", DateTime.parse(time))
-      end
+      # check that we actually have 2 elements in the array
+      times = time.split(/,/)
+      raise OSM::APIBadUserInput.new("bad time range") if times.size != 2
+
+      from, to = times.collect { |t| DateTime.parse(t) }
+      return changesets.where("closed_at >= ? and created_at <= ?", from, to)
+    else
+      # if there is no comma, assume its a lower limit on time
+      return changesets.where("closed_at >= ?", DateTime.parse(time))
     end
     # stupid DateTime seems to throw both of these for bad parsing, so
     # we have to catch both and ensure the correct code path is taken.
@@ -562,7 +561,7 @@ class ChangesetController < ApplicationController
     if ids.nil?
       return changesets
     elsif ids.empty?
-      fail OSM::APIBadUserInput.new("No changesets were given to search for")
+      raise OSM::APIBadUserInput.new("No changesets were given to search for")
     else
       ids = ids.split(",").collect(&:to_i)
       return changesets.where(:id => ids)
@@ -583,7 +582,7 @@ class ChangesetController < ApplicationController
       if params[:limit].to_i > 0 && params[:limit].to_i <= 10000
         params[:limit].to_i
       else
-        fail OSM::APIBadUserInput.new("Comments limit must be between 1 and 10000")
+        raise OSM::APIBadUserInput.new("Comments limit must be between 1 and 10000")
       end
     else
       100
index b6fb455eee3b6631e39f0be605ee3fe7fc2c6ccf..8afa80d7fbe593820b0f87ef7f6b92cf780f3e2b 100644 (file)
@@ -19,13 +19,13 @@ class GeocoderController < ApplicationController
       @sources.push "osm_nominatim_reverse"
       @sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME)
     elsif params[:query]
-      if params[:query].match(/^\d{5}(-\d{4})?$/)
+      if params[:query] =~ /^\d{5}(-\d{4})?$/
         @sources.push "us_postcode"
         @sources.push "osm_nominatim"
-      elsif params[:query].match(/^(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].match(/^[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
@@ -70,7 +70,7 @@ class GeocoderController < ApplicationController
     response = fetch_text("http://rpc.geocoder.us/service/csv?zip=#{escape_query(query)}")
 
     # parse the response
-    unless response.match(/couldn't find this zip/)
+    unless response =~ /couldn't find this zip/
       data = response.split(/\s*,\s+/) # lat,long,town,state,zip
       @results.push(:lat => data[0], :lon => data[1],
                     :zoom => POSTCODE_ZOOM,
@@ -95,7 +95,7 @@ class GeocoderController < ApplicationController
     response = fetch_text("http://www.npemap.org.uk/cgi/geocoder.fcgi?format=text&postcode=#{escape_query(query)}")
 
     # parse the response
-    unless response.match(/Error/)
+    unless response =~ /Error/
       dataline = response.split(/\n/)[1]
       data = dataline.split(/,/) # easting,northing,postcode,lat,long
       postcode = data[2].delete("'")
@@ -171,11 +171,11 @@ class GeocoderController < ApplicationController
       type = place.attributes["type"].to_s
       name = place.attributes["display_name"].to_s
       min_lat, max_lat, min_lon, max_lon = place.attributes["boundingbox"].to_s.split(",")
-      if type.empty?
-        prefix_name = ""
-      else
-        prefix_name = t "geocoder.search_osm_nominatim.prefix.#{klass}.#{type}", :default => type.tr("_", " ").capitalize
-      end
+      prefix_name = if type.empty?
+                      ""
+                    else
+                      t "geocoder.search_osm_nominatim.prefix.#{klass}.#{type}", :default => type.tr("_", " ").capitalize
+                    end
       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
@@ -298,7 +298,7 @@ class GeocoderController < ApplicationController
     if response.success?
       response.body
     else
-      fail response.status.to_s
+      raise response.status.to_s
     end
   end
 
@@ -339,11 +339,11 @@ class GeocoderController < ApplicationController
   def nsew_to_decdeg(captures)
     begin
       Float(captures[0])
-      captures[2].downcase != "s" ? lat = captures[0].to_f : lat = -(captures[0].to_f)
-      captures[5].downcase != "w" ? lon = captures[3].to_f : lon = -(captures[3].to_f)
+      lat = !captures[2].casecmp("s").zero? ? captures[0].to_f : -captures[0].to_f
+      lon = !captures[5].casecmp("w").zero? ? captures[3].to_f : -captures[3].to_f
     rescue
-      captures[0].downcase != "s" ? lat = captures[1].to_f : lat = -(captures[1].to_f)
-      captures[3].downcase != "w" ? lon = captures[4].to_f : lon = -(captures[4].to_f)
+      lat = !captures[0].casecmp("s").zero? ? captures[1].to_f : -captures[1].to_f
+      lon = !captures[3].casecmp("w").zero? ? captures[4].to_f : -captures[4].to_f
     end
     { :lat => lat, :lon => lon }
   end
@@ -351,11 +351,11 @@ class GeocoderController < ApplicationController
   def ddm_to_decdeg(captures)
     begin
       Float(captures[0])
-      captures[3].downcase != "s" ? lat = captures[0].to_f + captures[1].to_f / 60 : lat = -(captures[0].to_f + captures[1].to_f / 60)
-      captures[7].downcase != "w" ? lon = captures[4].to_f + captures[5].to_f / 60 : lon = -(captures[4].to_f + captures[5].to_f / 60)
+      lat = !captures[3].casecmp("s").zero? ? captures[0].to_f + captures[1].to_f / 60 : -(captures[0].to_f + captures[1].to_f / 60)
+      lon = !captures[7].casecmp("w").zero? ? captures[4].to_f + captures[5].to_f / 60 : -(captures[4].to_f + captures[5].to_f / 60)
     rescue
-      captures[0].downcase != "s" ? lat = captures[1].to_f + captures[2].to_f / 60 : lat = -(captures[1].to_f + captures[2].to_f / 60)
-      captures[4].downcase != "w" ? lon = captures[5].to_f + captures[6].to_f / 60 : lon = -(captures[5].to_f + captures[6].to_f / 60)
+      lat = !captures[0].casecmp("s").zero? ? captures[1].to_f + captures[2].to_f / 60 : -(captures[1].to_f + captures[2].to_f / 60)
+      lon = !captures[4].casecmp("w").zero? ? captures[5].to_f + captures[6].to_f / 60 : -(captures[5].to_f + captures[6].to_f / 60)
     end
     { :lat => lat, :lon => lon }
   end
@@ -363,11 +363,11 @@ class GeocoderController < ApplicationController
   def dms_to_decdeg(captures)
     begin
       Float(captures[0])
-      captures[4].downcase != "s" ? lat = captures[0].to_f + (captures[1].to_f + captures[2].to_f / 60) / 60 : lat = -(captures[0].to_f + (captures[1].to_f + captures[2].to_f / 60) / 60)
-      captures[9].downcase != "w" ? lon = captures[5].to_f + (captures[6].to_f + captures[7].to_f / 60) / 60 : lon = -(captures[5].to_f + (captures[6].to_f + captures[7].to_f / 60) / 60)
+      lat = !captures[4].casecmp("s").zero? ? captures[0].to_f + (captures[1].to_f + captures[2].to_f / 60) / 60 : -(captures[0].to_f + (captures[1].to_f + captures[2].to_f / 60) / 60)
+      lon = !captures[9].casecmp("w").zero? ? captures[5].to_f + (captures[6].to_f + captures[7].to_f / 60) / 60 : -(captures[5].to_f + (captures[6].to_f + captures[7].to_f / 60) / 60)
     rescue
-      captures[0].downcase != "s" ? lat = captures[1].to_f + (captures[2].to_f + captures[3].to_f / 60) / 60 : lat = -(captures[1].to_f + (captures[2].to_f + captures[3].to_f / 60) / 60)
-      captures[5].downcase != "w" ? lon = captures[6].to_f + (captures[7].to_f + captures[8].to_f / 60) / 60 : lon = -(captures[6].to_f + (captures[7].to_f + captures[8].to_f / 60) / 60)
+      lat = !captures[0].casecmp("s").zero? ? captures[1].to_f + (captures[2].to_f + captures[3].to_f / 60) / 60 : -(captures[1].to_f + (captures[2].to_f + captures[3].to_f / 60) / 60)
+      lon = !captures[5].casecmp("w").zero? ? captures[6].to_f + (captures[7].to_f + captures[8].to_f / 60) / 60 : -(captures[6].to_f + (captures[7].to_f + captures[8].to_f / 60) / 60)
     end
     { :lat => lat, :lon => lon }
   end
index a077916ea1dc666edd90f6a56ab5897a19ede487..8d29fd0726b21ff8d286f59d899ccc2d5ca355c6 100644 (file)
@@ -41,7 +41,7 @@ class NodeController < ApplicationController
     new_node = Node.from_xml(request.raw_post)
 
     unless new_node && new_node.id == node.id
-      fail OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})")
+      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.update_from(new_node, @user)
@@ -56,7 +56,7 @@ class NodeController < ApplicationController
     new_node = Node.from_xml(request.raw_post)
 
     unless new_node && new_node.id == node.id
-      fail OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})")
+      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"
@@ -65,13 +65,13 @@ class NodeController < ApplicationController
   # Dump the details on many nodes whose ids are given in the "nodes" parameter.
   def nodes
     unless params["nodes"]
-      fail OSM::APIBadUserInput.new("The parameter nodes is required, and must be of the form nodes=id[,id[,id...]]")
+      raise OSM::APIBadUserInput.new("The parameter nodes is required, and must be of the form nodes=id[,id[,id...]]")
     end
 
     ids = params["nodes"].split(",").collect(&:to_i)
 
-    if ids.length == 0
-      fail OSM::APIBadUserInput.new("No nodes were given to search for")
+    if ids.empty?
+      raise OSM::APIBadUserInput.new("No nodes were given to search for")
     end
     doc = OSM::API.new.get_xml_doc
 
index 59dd025e8280f7a60b0668fb57e8fa222457815c..51ef4491d35363be75437919e9089537f1eeff9a 100644 (file)
@@ -19,10 +19,10 @@ class NotesController < ApplicationController
     if params[:bbox]
       bbox = BoundingBox.from_bbox_params(params)
     else
-      fail OSM::APIBadUserInput.new("No l was given") unless params[:l]
-      fail OSM::APIBadUserInput.new("No r was given") unless params[:r]
-      fail OSM::APIBadUserInput.new("No b was given") unless params[:b]
-      fail OSM::APIBadUserInput.new("No t was given") unless params[:t]
+      raise OSM::APIBadUserInput.new("No l was given") unless params[:l]
+      raise OSM::APIBadUserInput.new("No r was given") unless params[:r]
+      raise OSM::APIBadUserInput.new("No b was given") unless params[:b]
+      raise OSM::APIBadUserInput.new("No t was given") unless params[:t]
 
       bbox = BoundingBox.from_lrbt_params(params)
     end
@@ -52,12 +52,12 @@ class NotesController < ApplicationController
   # Create a new note
   def create
     # Check the ACLs
-    fail OSM::APIAccessDenied if Acl.no_note_comment(request.remote_ip)
+    raise OSM::APIAccessDenied if Acl.no_note_comment(request.remote_ip)
 
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No lat was given") unless params[:lat]
-    fail OSM::APIBadUserInput.new("No lon was given") unless params[:lon]
-    fail OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
+    raise OSM::APIBadUserInput.new("No lat was given") unless params[:lat]
+    raise OSM::APIBadUserInput.new("No lon was given") unless params[:lon]
+    raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
 
     # Extract the arguments
     lon = OSM.parse_float(params[:lon], OSM::APIBadUserInput, "lon was not a number")
@@ -68,7 +68,7 @@ class NotesController < ApplicationController
     Note.transaction do
       # Create the note
       @note = Note.create(:lat => lat, :lon => lon)
-      fail OSM::APIBadUserInput.new("The note is outside this world") unless @note.in_world?
+      raise OSM::APIBadUserInput.new("The note is outside this world") unless @note.in_world?
 
       # Save the note
       @note.save!
@@ -88,11 +88,11 @@ class NotesController < ApplicationController
   # Add a comment to an existing note
   def comment
     # Check the ACLs
-    fail OSM::APIAccessDenied if Acl.no_note_comment(request.remote_ip)
+    raise OSM::APIAccessDenied if Acl.no_note_comment(request.remote_ip)
 
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
-    fail OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
 
     # Extract the arguments
     id = params[:id].to_i
@@ -100,9 +100,9 @@ class NotesController < ApplicationController
 
     # Find the note and check it is valid
     @note = Note.find(id)
-    fail OSM::APINotFoundError unless @note
-    fail OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
-    fail OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
+    raise OSM::APINotFoundError unless @note
+    raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
+    raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
 
     # Add a comment to the note
     Note.transaction do
@@ -120,7 +120,7 @@ class NotesController < ApplicationController
   # Close a note
   def close
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
@@ -128,9 +128,9 @@ class NotesController < ApplicationController
 
     # Find the note and check it is valid
     @note = Note.find_by_id(id)
-    fail OSM::APINotFoundError unless @note
-    fail OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
-    fail OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
+    raise OSM::APINotFoundError unless @note
+    raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
+    raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
 
     # Close the note and add a comment
     Note.transaction do
@@ -150,7 +150,7 @@ class NotesController < ApplicationController
   # Reopen a note
   def reopen
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
@@ -158,9 +158,9 @@ class NotesController < ApplicationController
 
     # Find the note and check it is valid
     @note = Note.find_by_id(id)
-    fail OSM::APINotFoundError unless @note
-    fail OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? || @user.moderator?
-    fail OSM::APINoteAlreadyOpenError.new(@note) unless @note.closed? || !@note.visible?
+    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?
 
     # Reopen the note and add a comment
     Note.transaction do
@@ -205,12 +205,12 @@ class NotesController < ApplicationController
   # Read a note
   def show
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Find the note and check it is valid
     @note = Note.find(params[:id])
-    fail OSM::APINotFoundError unless @note
-    fail OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
+    raise OSM::APINotFoundError unless @note
+    raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
 
     # Render the result
     respond_to do |format|
@@ -225,7 +225,7 @@ class NotesController < ApplicationController
   # Delete (hide) a note
   def destroy
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No id was given") unless params[:id]
+    raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
 
     # Extract the arguments
     id = params[:id].to_i
@@ -233,8 +233,8 @@ class NotesController < ApplicationController
 
     # Find the note and check it is valid
     @note = Note.find(id)
-    fail OSM::APINotFoundError unless @note
-    fail OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
+    raise OSM::APINotFoundError unless @note
+    raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
 
     # Mark the note as hidden
     Note.transaction do
@@ -255,7 +255,7 @@ class NotesController < ApplicationController
   # Return a list of notes matching a given string
   def search
     # Check the arguments are sane
-    fail OSM::APIBadUserInput.new("No query string was given") unless params[:q]
+    raise OSM::APIBadUserInput.new("No query string was given") unless params[:q]
 
     # Get any conditions that need to be applied
     @notes = closed_condition(Note.all)
@@ -308,7 +308,7 @@ class NotesController < ApplicationController
       if params[:limit].to_i > 0 && params[:limit].to_i <= 10000
         params[:limit].to_i
       else
-        fail OSM::APIBadUserInput.new("Note limit must be between 1 and 10000")
+        raise OSM::APIBadUserInput.new("Note limit must be between 1 and 10000")
       end
     else
       100
@@ -319,21 +319,19 @@ class NotesController < ApplicationController
   # Generate a condition to choose which bugs we want based
   # on their status and the user's request parameters
   def closed_condition(notes)
-    if params[:closed]
-      closed_since = params[:closed].to_i
-    else
-      closed_since = 7
-    end
+    closed_since = if params[:closed]
+                     params[:closed].to_i
+                   else
+                     7
+                   end
 
     if closed_since < 0
-      notes = notes.where("status != 'hidden'")
+      notes.where("status != 'hidden'")
     elsif closed_since > 0
-      notes = notes.where("(status = 'open' OR (status = 'closed' AND closed_at > '#{Time.now - closed_since.days}'))")
+      notes.where("(status = 'open' OR (status = 'closed' AND closed_at > '#{Time.now - closed_since.days}'))")
     else
-      notes = notes.where("status = 'open'")
+      notes.where("status = 'open'")
     end
-
-    notes
   end
 
   ##
@@ -350,7 +348,7 @@ class NotesController < ApplicationController
     comment = note.comments.create(attributes)
 
     note.comments.map(&:author).uniq.each do |user|
-      if notify && user && user != @user
+      if notify && user && user != @user && user.visible?
         Notifier.note_comment_notification(comment, user).deliver_now
       end
     end
index 8ce53739fdff427bd656f9b9aba7b7c90aec273c..59ebfd631b0075d1279a6738bf55a9278713602c 100644 (file)
@@ -41,38 +41,36 @@ class OauthController < ApplicationController
     if @token.invalidated?
       @message = t "oauth.oauthorize_failure.invalid"
       render :action => "authorize_failure"
-    else
-      if request.post?
-        if user_authorizes_token?
-          @token.authorize!(current_user)
-          if @token.oauth10?
-            callback_url = params[:oauth_callback] || @token.client_application.callback_url
-          else
-            callback_url = @token.oob? ? @token.client_application.callback_url : @token.callback_url
-          end
-          @redirect_url = URI.parse(callback_url) unless callback_url.blank?
-
-          if @redirect_url.to_s.blank?
-            render :action => "authorize_success"
-          else
-            @redirect_url.query = if @redirect_url.query.blank?
-                                    "oauth_token=#{@token.token}"
-                                  else
-                                    @redirect_url.query +
-                                      "&oauth_token=#{@token.token}"
-                                  end
+    elsif request.post?
+      if user_authorizes_token?
+        @token.authorize!(current_user)
+        callback_url = if @token.oauth10?
+                         params[:oauth_callback] || @token.client_application.callback_url
+                       else
+                         @token.oob? ? @token.client_application.callback_url : @token.callback_url
+                       end
+        @redirect_url = URI.parse(callback_url) unless callback_url.blank?
 
-            unless @token.oauth10?
-              @redirect_url.query += "&oauth_verifier=#{@token.verifier}"
-            end
+        if @redirect_url.to_s.blank?
+          render :action => "authorize_success"
+        else
+          @redirect_url.query = if @redirect_url.query.blank?
+                                  "oauth_token=#{@token.token}"
+                                else
+                                  @redirect_url.query +
+                                    "&oauth_token=#{@token.token}"
+                                end
 
-            redirect_to @redirect_url.to_s
+          unless @token.oauth10?
+            @redirect_url.query += "&oauth_verifier=#{@token.verifier}"
           end
-        else
-          @token.invalidate!
-          @message = t("oauth.oauthorize_failure.denied", :app_name => @token.client_application.name)
-          render :action => "authorize_failure"
+
+          redirect_to @redirect_url.to_s
         end
+      else
+        @token.invalidate!
+        @message = t("oauth.oauthorize_failure.denied", :app_name => @token.client_application.name)
+        render :action => "authorize_failure"
       end
     end
   end
index 9e1137f8d6e635cd7d1b001167701689fc9a1de9..4869ae3e15da873b14df8e709d1c4243ffec682b 100644 (file)
@@ -19,7 +19,7 @@ class OldController < ApplicationController
     # the .where() method used in the lookup_old_element_versions
     # call won't throw an error if no records are found, so we have
     # to do that ourselves.
-    fail OSM::APINotFoundError.new if @elements.empty?
+    raise OSM::APINotFoundError.new if @elements.empty?
 
     doc = OSM::API.new.get_xml_doc
 
index 2f8a477d9e4da06030d2a835b5ccb9318fa2651b..587cfce8292b6e962d3362d2eac8f18b425bbdb8 100644 (file)
@@ -36,7 +36,7 @@ class RelationController < ApplicationController
     new_relation = Relation.from_xml(request.raw_post)
 
     unless new_relation && new_relation.id == relation.id
-      fail OSM::APIBadUserInput.new("The id in the url (#{relation.id}) is not the same as provided in the xml (#{new_relation.id})")
+      raise OSM::APIBadUserInput.new("The id in the url (#{relation.id}) is not the same as provided in the xml (#{new_relation.id})")
     end
 
     relation.update_from new_relation, @user
@@ -128,13 +128,13 @@ class RelationController < ApplicationController
 
   def relations
     unless params["relations"]
-      fail OSM::APIBadUserInput.new("The parameter relations is required, and must be of the form relations=id[,id[,id...]]")
+      raise OSM::APIBadUserInput.new("The parameter relations is required, and must be of the form relations=id[,id[,id...]]")
     end
 
     ids = params["relations"].split(",").collect(&:to_i)
 
-    if ids.length == 0
-      fail OSM::APIBadUserInput.new("No relations were given to search for")
+    if ids.empty?
+      raise OSM::APIBadUserInput.new("No relations were given to search for")
     end
 
     doc = OSM::API.new.get_xml_doc
index bda0a7942044421827ddfa18244d4c5a556cf4de..60b5a4585330309f5c7aa1bf873ae6e5fe220dea 100644 (file)
@@ -30,13 +30,13 @@ class TraceController < ApplicationController
     end
 
     # set title
-    if target_user.nil?
-      @title = t "trace.list.public_traces"
-    elsif @user && @user == target_user
-      @title = t "trace.list.your_traces"
-    else
-      @title = t "trace.list.public_traces_from", :user => target_user.display_name
-    end
+    @title = if target_user.nil?
+               t "trace.list.public_traces"
+             elsif @user && @user == target_user
+               t "trace.list.your_traces"
+             else
+               t "trace.list.public_traces_from", :user => target_user.display_name
+             end
 
     @title += t "trace.list.tagged_with", :tags => params[:tag] if params[:tag]
 
@@ -45,19 +45,17 @@ class TraceController < ApplicationController
     # 2 - all traces, not logged in = all public traces
     # 3 - user's traces, logged in as same user = all user's traces
     # 4 - user's traces, not logged in as that user = all user's public traces
-    if target_user.nil? # all traces
-      if @user
-        @traces = Trace.visible_to(@user) # 1
-      else
-        @traces = Trace.visible_to_all # 2
-      end
-    else
-      if @user && @user == target_user
-        @traces = @user.traces # 3 (check vs user id, so no join + can't pick up non-public traces by changing name)
-      else
-        @traces = target_user.traces.visible_to_all # 4
-      end
-    end
+    @traces = if target_user.nil? # all traces
+                if @user
+                  Trace.visible_to(@user) # 1
+                else
+                  Trace.visible_to_all # 2
+                end
+              elsif @user && @user == target_user
+                @user.traces # 3 (check vs user id, so no join + can't pick up non-public traces by changing name)
+              else
+                target_user.traces.visible_to_all # 4
+              end
 
     @traces = @traces.tagged(params[:tag]) if params[:tag]
 
@@ -266,7 +264,7 @@ class TraceController < ApplicationController
       new_trace = Trace.from_xml(request.raw_post)
 
       unless new_trace && new_trace.id == trace.id
-        fail OSM::APIBadUserInput.new("The id in the url (#{trace.id}) is not the same as provided in the xml (#{new_trace.id})")
+        raise OSM::APIBadUserInput.new("The id in the url (#{trace.id}) is not the same as provided in the xml (#{new_trace.id})")
       end
 
       trace.description = new_trace.description
@@ -315,11 +313,11 @@ class TraceController < ApplicationController
     visibility = params[:visibility]
 
     if visibility.nil?
-      if params[:public] && params[:public].to_i.nonzero?
-        visibility = "public"
-      else
-        visibility = "private"
-      end
+      visibility = if params[:public] && params[:public].to_i.nonzero?
+                     "public"
+                   else
+                     "private"
+                   end
     end
 
     if params[:file].respond_to?(:read)
index 0f77c87a0966dcf4dab318bbc8cabb6f64e5eb97..766ab37d1396e437c4826b8d02b78b8e923c9fe8 100644 (file)
@@ -45,7 +45,7 @@ class UserController < ApplicationController
         @user.terms_seen = true
 
         if @user.save
-          flash[:notice] = t "user.new.terms declined", :url => t("user.new.terms declined url")
+          flash[:notice] = t("user.new.terms declined", :url => t("user.new.terms declined url")).html_safe
         end
 
         if params[:referer]
@@ -182,7 +182,7 @@ class UserController < ApplicationController
           if @user.save
             token.destroy
             flash[:notice] = t "user.reset_password.flash changed"
-            redirect_to :action => "login"
+            successful_login(@user)
           end
         end
       else
@@ -213,7 +213,7 @@ class UserController < ApplicationController
                        :auth_provider => params[:auth_provider],
                        :auth_uid => params[:auth_uid])
 
-      flash.now[:notice] = t "user.new.auth association"
+      flash.now[:notice] = render_to_string :partial => "auth_association"
     else
       check_signup_allowed
     end
@@ -257,7 +257,7 @@ class UserController < ApplicationController
       password_authentication(params[:username], params[:password])
     elsif params[:openid_url].present?
       session[:remember_me] ||= params[:remember_me_openid]
-      redirect_to auth_url("openid", params[:openid_url])
+      redirect_to auth_url("openid", params[:openid_url], params[:referer])
     end
   end
 
@@ -330,7 +330,7 @@ class UserController < ApplicationController
       flash[:error] = t "user.confirm_resend.failure", :name => params[:display_name]
     else
       Notifier.signup_confirm(user, user.tokens.create).deliver_now
-      flash[:notice] = t "user.confirm_resend.success", :email => user.email
+      flash[:notice] = t("user.confirm_resend.success", :email => user.email).html_safe
     end
 
     redirect_to :action => "login"
@@ -403,13 +403,11 @@ class UserController < ApplicationController
         friend.friend_user_id = @new_friend.id
         if @user.is_friends_with?(@new_friend)
           flash[:warning] = t "user.make_friend.already_a_friend", :name => @new_friend.display_name
+        elsif friend.save
+          flash[:notice] = t "user.make_friend.success", :name => @new_friend.display_name
+          Notifier.friend_notification(friend).deliver_now
         else
-          if friend.save
-            flash[:notice] = t "user.make_friend.success", :name => @new_friend.display_name
-            Notifier.friend_notification(friend).deliver_now
-          else
-            friend.add_error(t("user.make_friend.failed", :name => @new_friend.display_name))
-          end
+          friend.add_error(t("user.make_friend.failed", :name => @new_friend.display_name))
         end
 
         if params[:referer]
@@ -497,7 +495,7 @@ class UserController < ApplicationController
     when "openid"
       email_verified = uid.match(%r{https://www.google.com/accounts/o8/id?(.*)}) ||
                        uid.match(%r{https://me.yahoo.com/(.*)})
-    when "google"
+    when "google", "facebook"
       email_verified = true
     else
       email_verified = false
@@ -516,7 +514,7 @@ class UserController < ApplicationController
       when "pending" then
         unconfirmed_login(user)
       when "active", "confirmed" then
-        successful_login(user)
+        successful_login(user, env["omniauth.params"]["referer"])
       when "suspended" then
         failed_login t("user.login.account is suspended", :webmaster => "mailto:webmaster@openstreetmap.org")
       else
@@ -561,20 +559,27 @@ class UserController < ApplicationController
     elsif user = User.authenticate(:username => username, :password => password, :pending => true)
       unconfirmed_login(user)
     elsif User.authenticate(:username => username, :password => password, :suspended => true)
-      failed_login t("user.login.account is suspended", :webmaster => "mailto:webmaster@openstreetmap.org")
+      failed_login t("user.login.account is suspended", :webmaster => "mailto:webmaster@openstreetmap.org"), username
     else
-      failed_login t("user.login.auth failure")
+      failed_login t("user.login.auth failure"), username
     end
   end
 
   ##
   # return the URL to use for authentication
-  def auth_url(provider, uid)
-    if provider == "openid"
-      auth_path(:provider => "openid", :openid_url => openid_expand_url(uid), :origin => request.path)
+  def auth_url(provider, uid, referer = nil)
+    params = { :provider => provider }
+
+    params[:openid_url] = openid_expand_url(uid) if provider == "openid"
+
+    if referer.nil?
+      params[:origin] = request.path
     else
-      auth_path(:provider => provider, :origin => request.path)
+      params[:origin] = request.path + "?referer=" + CGI.escape(referer)
+      params[:referer] = referer
     end
+
+    auth_path(params)
   end
 
   ##
@@ -596,11 +601,11 @@ class UserController < ApplicationController
 
   ##
   # process a successful login
-  def successful_login(user)
+  def successful_login(user, referer = nil)
     session[:user] = user.id
     session_expires_after 28.days if session[:remember_me]
 
-    target = session[:referer] || url_for(:controller => :site, :action => :index)
+    target = referer || session[:referer] || url_for(:controller => :site, :action => :index)
 
     # The user is logged in, so decide where to send them:
     #
@@ -622,10 +627,11 @@ class UserController < ApplicationController
 
   ##
   # process a failed login
-  def failed_login(message)
+  def failed_login(message, username = nil)
     flash[:error] = message
 
-    redirect_to :action => "login", :referer => session[:referer]
+    redirect_to :action => "login", :referer => session[:referer],
+                :username => username, :remember_me => session[:remember_me]
 
     session.delete(:remember_me)
     session.delete(:referer)
@@ -648,7 +654,7 @@ class UserController < ApplicationController
     user.display_name = params[:user][:display_name]
     user.new_email = params[:user][:new_email]
 
-    if params[:user][:pass_crypt].length > 0 || params[:user][:pass_crypt_confirmation].length > 0
+    unless params[:user][:pass_crypt].empty? && params[:user][:pass_crypt_confirmation].empty?
       user.pass_crypt = params[:user][:pass_crypt]
       user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
     end
@@ -675,11 +681,11 @@ class UserController < ApplicationController
     user.home_lat = params[:user][:home_lat]
     user.home_lon = params[:user][:home_lon]
 
-    if params[:user][:preferred_editor] == "default"
-      user.preferred_editor = nil
-    else
-      user.preferred_editor = params[:user][:preferred_editor]
-    end
+    user.preferred_editor = if params[:user][:preferred_editor] == "default"
+                              nil
+                            else
+                              params[:user][:preferred_editor]
+                            end
 
     if params[:user][:auth_provider].nil? || params[:user][:auth_provider].blank?
       user.auth_provider = nil
@@ -771,11 +777,11 @@ class UserController < ApplicationController
   ##
   # check signup acls
   def check_signup_allowed(email = nil)
-    if email.nil?
-      domain = nil
-    else
-      domain = email.split("@").last
-    end
+    domain = if email.nil?
+               nil
+             else
+               email.split("@").last
+             end
 
     if blocked = Acl.no_account_creation(request.remote_ip, domain)
       logger.info "Blocked signup from #{request.remote_ip} for #{email}"
index 2b6df65e6f39a0933c5594ab4e90663f5ca07041..78ab45308e874a9d7e56cad7efab1c6d63ca32c4 100644 (file)
@@ -45,7 +45,7 @@ class UserPreferenceController < ApplicationController
       if preference = old_preferences.delete(pt["k"])
         preference.v = pt["v"]
       elsif new_preferences.include?(pt["k"])
-        fail OSM::APIDuplicatePreferenceError.new(pt["k"])
+        raise OSM::APIDuplicatePreferenceError.new(pt["k"])
       else
         preference = @user.preferences.build(:k => pt["k"], :v => pt["v"])
       end
index e7a968a09449408b3d61d79a9bf9bfd3bdff6aa0..c988545c717a00c7258a06c049f6e14ad83379b9 100644 (file)
@@ -36,7 +36,7 @@ class WayController < ApplicationController
     new_way = Way.from_xml(request.raw_post)
 
     unless new_way && new_way.id == way.id
-      fail OSM::APIBadUserInput.new("The id in the url (#{way.id}) is not the same as provided in the xml (#{new_way.id})")
+      raise OSM::APIBadUserInput.new("The id in the url (#{way.id}) is not the same as provided in the xml (#{new_way.id})")
     end
 
     way.update_from(new_way, @user)
@@ -81,13 +81,13 @@ class WayController < ApplicationController
 
   def ways
     unless params["ways"]
-      fail OSM::APIBadUserInput.new("The parameter ways is required, and must be of the form ways=id[,id[,id...]]")
+      raise OSM::APIBadUserInput.new("The parameter ways is required, and must be of the form ways=id[,id[,id...]]")
     end
 
     ids = params["ways"].split(",").collect(&:to_i)
 
-    if ids.length == 0
-      fail OSM::APIBadUserInput.new("No ways were given to search for")
+    if ids.empty?
+      raise OSM::APIBadUserInput.new("No ways were given to search for")
     end
 
     doc = OSM::API.new.get_xml_doc
index 5b07407353c3e8a9276a9635d54e01b74f55ab67..40782fbcfad5676e6c59eb900610aef25d27ab22 100644 (file)
@@ -1,11 +1,7 @@
 module AssetHelper
   def assets(directory)
-    assets = {}
-
-    Rails.application.assets.index.each_logical_path("#{directory}/*") do |path|
-      assets[path.sub(%r{^#{directory}/}, "")] = asset_path(path)
+    Rails.application.assets_manifest.assets.keys.each_with_object({}) do |asset, assets|
+      assets[asset] = asset_path(asset) if asset.start_with?("#{directory}/")
     end
-
-    assets
   end
 end
index 3723186b89d7f568cad2966c927672f87e601421..494232744e3447feb079e31dd256db66fdf81413 100644 (file)
@@ -2,11 +2,11 @@ require "uri"
 
 module BrowseHelper
   def printable_name(object, version = false)
-    if object.id.is_a?(Array)
-      id = object.id[0]
-    else
-      id = object.id
-    end
+    id = if object.id.is_a?(Array)
+           object.id[0]
+         else
+           object.id
+         end
     name = t "printable_name.with_id", :id => id.to_s
     if version
       name = t "printable_name.with_version", :id => name, :version => object.version.to_s
@@ -25,6 +25,8 @@ module BrowseHelper
         name = t "printable_name.with_name_html", :name => content_tag(:bdi, object.tags["name:#{locale}"].to_s), :id => content_tag(:bdi, name)
       elsif object.tags.include? "name"
         name = t "printable_name.with_name_html", :name => content_tag(:bdi, object.tags["name"].to_s), :id => content_tag(:bdi, name)
+      elsif object.tags.include? "ref"
+        name = t "printable_name.with_name_html", :name => content_tag(:bdi, object.tags["ref"].to_s), :id => content_tag(:bdi, name)
       end
     end
 
@@ -52,6 +54,10 @@ module BrowseHelper
     end
   end
 
+  def link_follow(object)
+    "nofollow" if object.tags.empty?
+  end
+
   def format_key(key)
     if url = wiki_link("key", key)
       link_to h(key), url, :title => t("browse.tag_details.wiki_link.key", :key => key)
@@ -88,7 +94,7 @@ module BrowseHelper
 
   private
 
-  ICON_TAGS = %w(aeroway amenity barrier building highway historic landuse leisure man_made natural railway shop tourism waterway)
+  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
@@ -119,14 +125,14 @@ module BrowseHelper
     if key == "wikipedia"
       # This regex should match Wikipedia language codes, everything
       # from de to zh-classical
-      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
-        lang = $1
-      else
-        # Value is <title> so default to English Wikipedia
-        lang = "en"
-      end
+      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
+             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
index c3141297ce537c5ebcdfd2fecfd42af928313b21..cc008aab758ff568ba970a19e55b03e78cebdc3f 100644 (file)
@@ -1,6 +1,8 @@
 module ChangesetHelper
   def changeset_user_link(changeset)
-    if changeset.user.data_public?
+    if changeset.user.status == "deleted"
+      t("user.no_such_user.deleted")
+    elsif changeset.user.data_public?
       link_to(changeset.user.display_name, user_path(changeset.user.display_name))
     else
       t("browse.anonymous")
@@ -29,4 +31,16 @@ module ChangesetHelper
         :user => changeset_user_link(changeset)
     end
   end
+
+  def changeset_list_title(params, user)
+    if params[:friends] && user
+      t "changeset.list.title_friend"
+    elsif params[:nearby] && user
+      t "changeset.list.title_nearby"
+    elsif params[:display_name]
+      t "changeset.list.title_user", :user => params[:display_name]
+    else
+      t "changeset.list.title"
+    end
+  end
 end
index e135917a9240886c22c5dbca7417ab272bd348ac..161bb2d6de57369c322c0e30ba5d50dc37c14850 100644 (file)
@@ -2,13 +2,13 @@ module GeocoderHelper
   def result_to_html(result)
     html_options = { :class => "set_position", :data => {} }
 
-    if result[:type] && result[:id]
-      url = url_for(:controller => :browse, :action => result[:type], :id => result[:id])
-    elsif result[:min_lon] && result[:min_lat] && result[:max_lon] && result[:max_lat]
-      url = "/?bbox=#{result[:min_lon]},#{result[:min_lat]},#{result[:max_lon]},#{result[:max_lat]}"
-    else
-      url = "/#map=#{result[:zoom]}/#{result[:lat]}/#{result[:lon]}"
-    end
+    url = if result[:type] && result[:id]
+            url_for(:controller => :browse, :action => result[:type], :id => result[:id])
+          elsif result[:min_lon] && result[:min_lat] && result[:max_lon] && result[:max_lat]
+            "/?bbox=#{result[:min_lon]},#{result[:min_lat]},#{result[:max_lon]},#{result[:max_lat]}"
+          else
+            "/#map=#{result[:zoom]}/#{result[:lat]}/#{result[:lon]}"
+          end
 
     result.each do |key, value|
       html_options[:data][key.to_s.tr("_", "-")] = value
index 87bd86f428e4edd7e1e821d84a9840694c8758c7..2a101612928db938e68d3ccb51ce946cc467776a 100644 (file)
@@ -17,6 +17,8 @@ module NoteHelper
   def note_author(author, link_options = {})
     if author.nil?
       ""
+    elsif author.status == "deleted"
+      t("user.no_such_user.deleted")
     else
       link_to h(author.display_name), link_options.merge(:controller => "user", :action => "view", :display_name => author.display_name)
     end
diff --git a/app/helpers/open_graph_helper.rb b/app/helpers/open_graph_helper.rb
new file mode 100644 (file)
index 0000000..e21a564
--- /dev/null
@@ -0,0 +1,17 @@
+module OpenGraphHelper
+  def opengraph_tags(title = nil)
+    tags = {
+      "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:description" => t("layouts.intro_text")
+    }
+
+    tags.map do |property, content|
+      tag(:meta, :property => property, :content => content)
+    end.join("").html_safe
+  end
+end
index eb1724d93aac343ae23a559111b7317a3b4785fd..8b1eb53b6dfdcae08ea8291a4c2d393ed1b7bad0 100644 (file)
@@ -5,7 +5,7 @@ module TitleHelper
     @coder ||= HTMLEntities.new
   end
 
-  def set_title(title = false)
+  def set_title(title = nil)
     if title
       @title = TitleHelper.coder.decode(title.gsub("<bdi>", "\u202a").gsub("</bdi>", "\u202c"))
       response.headers["X-Page-Title"] = URI.escape(t("layouts.project_name.title") + " | " + @title)
index 690cccdca2ad7e15a46ba5f9c2f45791187a5eb4..b6961cd8b02021715b6f8436bbf293dbf4b28f03 100644 (file)
@@ -6,26 +6,28 @@ module UserRolesHelper
   def role_icon(user, role)
     if @user && @user.administrator?
       if user.has_role?(role)
-        image = "roles/#{role}.png"
+        image = "roles/#{role}"
         alt = t("user.view.role.revoke.#{role}")
         title = t("user.view.role.revoke.#{role}")
         url = revoke_role_path(:display_name => user.display_name, :role => role)
         confirm = t("user_role.revoke.are_you_sure", :name => user.display_name, :role => role)
       else
-        image = "roles/blank_#{role}.png"
+        image = "roles/blank_#{role}"
         alt = t("user.view.role.grant.#{role}")
         title = t("user.view.role.grant.#{role}")
         url = grant_role_path(:display_name => user.display_name, :role => role)
         confirm = t("user_role.grant.are_you_sure", :name => user.display_name, :role => role)
       end
     elsif user.has_role?(role)
-      image = "roles/#{role}.png"
+      image = "roles/#{role}"
       alt = t("user.view.role.#{role}")
       title = t("user.view.role.#{role}")
     end
 
     if image
-      icon = image_tag(image, :size => "20x20", :border => 0, :alt => alt, :title => title)
+      svg_icon = tag("source", :srcset => image_path("#{image}.svg"), :type => "image/svg+xml")
+      png_icon = image_tag("#{image}.png", :srcset => image_path("#{image}.svg"), :size => "20x20", :border => 0, :alt => alt, :title => title)
+      icon = content_tag("picture", svg_icon + png_icon)
       icon = link_to(icon, url, :method => :post, :confirm => confirm) if url
     end
 
index bf939e425e5c5f0b08577c95678c37c2d89a39f8..6909ba948bc4c33fb1079f90e963a82e9e515ae3 100644 (file)
@@ -63,7 +63,7 @@ class Changeset < ActiveRecord::Base
     doc.find("//osm/changeset").each do |pt|
       return Changeset.from_xml_node(pt, create)
     end
-    fail OSM::APIBadXMLError.new("changeset", xml, "XML doesn't contain an osm/changeset element.")
+    raise OSM::APIBadXMLError.new("changeset", xml, "XML doesn't contain an osm/changeset element.")
   rescue LibXML::XML::Error, ArgumentError => ex
     raise OSM::APIBadXMLError.new("changeset", xml, ex.message)
   end
@@ -80,8 +80,8 @@ class Changeset < ActiveRecord::Base
     end
 
     pt.find("tag").each do |tag|
-      fail OSM::APIBadXMLError.new("changeset", pt, "tag is missing key") if tag["k"].nil?
-      fail OSM::APIBadXMLError.new("changeset", pt, "tag is missing value") if tag["v"].nil?
+      raise OSM::APIBadXMLError.new("changeset", pt, "tag is missing key") if tag["k"].nil?
+      raise OSM::APIBadXMLError.new("changeset", pt, "tag is missing value") if tag["v"].nil?
       cs.add_tag_keyval(tag["k"], tag["v"])
     end
 
@@ -137,7 +137,7 @@ class Changeset < ActiveRecord::Base
 
     # duplicate tags are now forbidden, so we can't allow values
     # in the hash to be overwritten.
-    fail OSM::APIDuplicateTagsError.new("changeset", id, k) if @tags.include? k
+    raise OSM::APIDuplicateTagsError.new("changeset", id, k) if @tags.include? k
 
     @tags[k] = v
   end
@@ -146,7 +146,7 @@ class Changeset < ActiveRecord::Base
     # do the changeset update and the changeset tags update in the
     # same transaction to ensure consistency.
     Changeset.transaction do
-      self.save!
+      save!
 
       tags = self.tags
       ChangesetTag.delete_all(:changeset_id => id)
@@ -166,12 +166,12 @@ class Changeset < ActiveRecord::Base
   # that would make it more than 24h long, in which case clip to
   # 24h, as this has been decided is a reasonable time limit.
   def update_closed_at
-    if self.is_open?
-      if (closed_at - created_at) > (MAX_TIME_OPEN - IDLE_TIMEOUT)
-        self.closed_at = created_at + MAX_TIME_OPEN
-      else
-        self.closed_at = Time.now.getutc + IDLE_TIMEOUT
-      end
+    if is_open?
+      self.closed_at = if (closed_at - created_at) > (MAX_TIME_OPEN - IDLE_TIMEOUT)
+                         created_at + MAX_TIME_OPEN
+                       else
+                         Time.now.getutc + IDLE_TIMEOUT
+                       end
     end
   end
 
@@ -241,10 +241,10 @@ class Changeset < ActiveRecord::Base
   # bounding box, only the tags of the changeset.
   def update_from(other, user)
     # ensure that only the user who opened the changeset may modify it.
-    fail OSM::APIUserChangesetMismatchError.new unless user.id == user_id
+    raise OSM::APIUserChangesetMismatchError.new unless user.id == user_id
 
     # can't change a closed changeset
-    fail OSM::APIChangesetAlreadyClosedError.new(self) unless is_open?
+    raise OSM::APIChangesetAlreadyClosedError.new(self) unless is_open?
 
     # copy the other's tags
     self.tags = other.tags
index ec563d6c773ea50bd36adb1798adece578542085..2fedadff04129e72e0d5eaee741309246c485d28 100644 (file)
@@ -7,6 +7,7 @@ class ChangesetComment < ActiveRecord::Base
   validates :changeset, :presence => true, :associated => true
   validates :author, :presence => true, :associated => true
   validates :visible, :inclusion => [true, false]
+  validates :body, :format => /\A[^\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff]*\z/
 
   # Return the comment text
   def body
index aa7cb1c343e8cd9794bfc0cfc530b5d08557be31..156eeafc7989cc15a6d03d504bef6477aa0604e8 100644 (file)
@@ -77,7 +77,7 @@ class ClientApplication < ActiveRecord::Base
   # 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]
+                 :allow_write_notes].freeze
 
   def generate_keys
     self.key = OAuth::Helper.generate_key(40)[0, 40]
index f1a89e0e2d4656ccc4480fbf88a8cb69002288ee..a6814405c731195442304ee1f08d90107061d2cc 100644 (file)
@@ -55,7 +55,7 @@ class Node < ActiveRecord::Base
     doc.find("//osm/node").each do |pt|
       return Node.from_xml_node(pt, create)
     end
-    fail OSM::APIBadXMLError.new("node", xml, "XML doesn't contain an osm/node element.")
+    raise OSM::APIBadXMLError.new("node", xml, "XML doesn't contain an osm/node element.")
   rescue LibXML::XML::Error, ArgumentError => ex
     raise OSM::APIBadXMLError.new("node", xml, ex.message)
   end
@@ -63,25 +63,25 @@ class Node < ActiveRecord::Base
   def self.from_xml_node(pt, create = false)
     node = Node.new
 
-    fail OSM::APIBadXMLError.new("node", pt, "lat missing") if pt["lat"].nil?
-    fail OSM::APIBadXMLError.new("node", pt, "lon missing") if pt["lon"].nil?
+    raise OSM::APIBadXMLError.new("node", pt, "lat missing") if pt["lat"].nil?
+    raise OSM::APIBadXMLError.new("node", pt, "lon missing") if pt["lon"].nil?
     node.lat = OSM.parse_float(pt["lat"], OSM::APIBadXMLError, "node", pt, "lat not a number")
     node.lon = OSM.parse_float(pt["lon"], OSM::APIBadXMLError, "node", pt, "lon not a number")
-    fail OSM::APIBadXMLError.new("node", pt, "Changeset id is missing") if pt["changeset"].nil?
+    raise OSM::APIBadXMLError.new("node", pt, "Changeset id is missing") if pt["changeset"].nil?
     node.changeset_id = pt["changeset"].to_i
 
-    fail OSM::APIBadUserInput.new("The node is outside this world") unless node.in_world?
+    raise OSM::APIBadUserInput.new("The node is outside this world") unless node.in_world?
 
     # version must be present unless creating
-    fail OSM::APIBadXMLError.new("node", pt, "Version is required when updating") unless create || !pt["version"].nil?
+    raise OSM::APIBadXMLError.new("node", pt, "Version is required when updating") unless create || !pt["version"].nil?
     node.version = create ? 0 : pt["version"].to_i
 
     unless create
-      fail OSM::APIBadXMLError.new("node", pt, "ID is required when updating.") if pt["id"].nil?
+      raise OSM::APIBadXMLError.new("node", pt, "ID is required when updating.") if pt["id"].nil?
       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
-      fail 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 == 0
     end
 
     # We don't care about the time, as it is explicitly set on create/update/delete
@@ -94,8 +94,8 @@ class Node < ActiveRecord::Base
 
     # Add in any tags from the XML
     pt.find("tag").each do |tag|
-      fail OSM::APIBadXMLError.new("node", pt, "tag is missing key") if tag["k"].nil?
-      fail OSM::APIBadXMLError.new("node", pt, "tag is missing value") if tag["v"].nil?
+      raise OSM::APIBadXMLError.new("node", pt, "tag is missing key") if tag["k"].nil?
+      raise OSM::APIBadXMLError.new("node", pt, "tag is missing value") if tag["v"].nil?
       node.add_tag_key_val(tag["k"], tag["v"])
     end
 
@@ -111,19 +111,19 @@ class Node < ActiveRecord::Base
 
   # Should probably be renamed delete_from to come in line with update
   def delete_with_history!(new_node, user)
-    fail OSM::APIAlreadyDeletedError.new("node", new_node.id) unless visible
+    raise OSM::APIAlreadyDeletedError.new("node", new_node.id) unless visible
 
     # need to start the transaction here, so that the database can
     # provide repeatable reads for the used-by checks. this means it
     # shouldn't be possible to get race conditions.
     Node.transaction do
-      self.lock!
+      lock!
       check_consistency(self, new_node, user)
       ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id)
-      fail 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)
-      fail 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 = {}
@@ -138,7 +138,7 @@ class Node < ActiveRecord::Base
 
   def update_from(new_node, user)
     Node.transaction do
-      self.lock!
+      lock!
       check_consistency(self, new_node, user)
 
       # update changeset first
@@ -184,7 +184,7 @@ class Node < ActiveRecord::Base
 
     add_metadata_to_xml_node(el, self, changeset_cache, user_display_name_cache)
 
-    if self.visible?
+    if visible?
       el["lat"] = lat.to_s
       el["lon"] = lon.to_s
     end
@@ -209,7 +209,7 @@ class Node < ActiveRecord::Base
 
     # duplicate tags are now forbidden, so we can't allow values
     # in the hash to be overwritten.
-    fail OSM::APIDuplicateTagsError.new("node", id, k) if @tags.include? k
+    raise OSM::APIDuplicateTagsError.new("node", id, k) if @tags.include? k
 
     @tags[k] = v
   end
@@ -235,7 +235,7 @@ class Node < ActiveRecord::Base
     Node.transaction do
       self.version += 1
       self.timestamp = t
-      self.save!
+      save!
 
       # Create a NodeTag
       tags = self.tags
index 31056be49ca090733b483a09ddeb1ac0f4ecb805..73207af0ff22f4e0a16d26f2b8cfdc3a95df0208 100644 (file)
@@ -59,6 +59,6 @@ class Note < ActiveRecord::Base
 
   # Fill in default values for new notes
   def set_defaults
-    self.status = "open" unless self.attribute_present?(:status)
+    self.status = "open" unless attribute_present?(:status)
   end
 end
index 01822656609cc58f710011be937492979b2bb210..23f7b990781049948036d08842bcec877b0250ad 100644 (file)
@@ -136,17 +136,17 @@ class Notifier < ActionMailer::Base
       @owner = recipient == comment.note.author
       @event = comment.event
 
-      if comment.author
-        @commenter = comment.author.display_name
-      else
-        @commenter = I18n.t("notifier.note_comment_notification.anonymous")
-      end
-
-      if @owner
-        subject = I18n.t("notifier.note_comment_notification.#{@event}.subject_own", :commenter => @commenter)
-      else
-        subject = I18n.t("notifier.note_comment_notification.#{@event}.subject_other", :commenter => @commenter)
-      end
+      @commenter = if comment.author
+                     comment.author.display_name
+                   else
+                     I18n.t("notifier.note_comment_notification.anonymous")
+                   end
+
+      subject = if @owner
+                  I18n.t("notifier.note_comment_notification.#{@event}.subject_own", :commenter => @commenter)
+                else
+                  I18n.t("notifier.note_comment_notification.#{@event}.subject_other", :commenter => @commenter)
+                end
 
       mail :to => recipient.email, :subject => subject
     end
@@ -162,11 +162,11 @@ class Notifier < ActionMailer::Base
       @time = comment.created_at
       @changeset_author = comment.changeset.user.display_name
 
-      if @owner
-        subject = I18n.t("notifier.changeset_comment_notification.commented.subject_own", :commenter => @commenter)
-      else
-        subject = I18n.t("notifier.changeset_comment_notification.commented.subject_other", :commenter => @commenter)
-      end
+      subject = if @owner
+                  I18n.t("notifier.changeset_comment_notification.commented.subject_own", :commenter => @commenter)
+                else
+                  I18n.t("notifier.changeset_comment_notification.commented.subject_other", :commenter => @commenter)
+                end
 
       mail :to => recipient.email, :subject => subject
     end
@@ -175,14 +175,8 @@ class Notifier < ActionMailer::Base
   private
 
   def with_recipient_locale(recipient)
-    old_locale = I18n.locale
-
-    begin
-      I18n.locale = recipient.preferred_language_from(I18n.available_locales)
-
+    I18n.with_locale Locale.available.preferred(recipient.preferred_languages) do
       yield
-    ensure
-      I18n.locale = old_locale
     end
   end
 
index 84899d7fb4a8e7b609c0d3dd03d01271b145789f..b103e5c7310160033f1d733029b26f5a29da50d7 100644 (file)
@@ -55,7 +55,7 @@ class OldNode < ActiveRecord::Base
 
     add_metadata_to_xml_node(el, self, changeset_cache, user_display_name_cache)
 
-    if self.visible?
+    if visible?
       el["lat"] = lat.to_s
       el["lon"] = lon.to_s
     end
index cb9621822ba63cefd1349318f28c8947765ec829..062f0ed04ec073a869ecabfd3f5414e95e940c6d 100644 (file)
@@ -33,7 +33,7 @@ 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)
+  TYPES = %w(node way relation).freeze
 
   def self.from_xml(xml, create = false)
     p = XML::Parser.string(xml)
@@ -42,7 +42,7 @@ class Relation < ActiveRecord::Base
     doc.find("//osm/relation").each do |pt|
       return Relation.from_xml_node(pt, create)
     end
-    fail OSM::APIBadXMLError.new("node", xml, "XML doesn't contain an osm/relation element.")
+    raise OSM::APIBadXMLError.new("node", xml, "XML doesn't contain an osm/relation element.")
   rescue LibXML::XML::Error, ArgumentError => ex
     raise OSM::APIBadXMLError.new("relation", xml, ex.message)
   end
@@ -50,17 +50,17 @@ class Relation < ActiveRecord::Base
   def self.from_xml_node(pt, create = false)
     relation = Relation.new
 
-    fail OSM::APIBadXMLError.new("relation", pt, "Version is required when updating") unless create || !pt["version"].nil?
+    raise OSM::APIBadXMLError.new("relation", pt, "Version is required when updating") unless create || !pt["version"].nil?
     relation.version = pt["version"]
-    fail OSM::APIBadXMLError.new("relation", pt, "Changeset id is missing") if pt["changeset"].nil?
+    raise OSM::APIBadXMLError.new("relation", pt, "Changeset id is missing") if pt["changeset"].nil?
     relation.changeset_id = pt["changeset"]
 
     unless create
-      fail OSM::APIBadXMLError.new("relation", pt, "ID is required when updating") if pt["id"].nil?
+      raise OSM::APIBadXMLError.new("relation", pt, "ID is required when updating") if pt["id"].nil?
       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
-      fail 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 == 0
     end
 
     # We don't care about the timestamp nor the visibility as these are either
@@ -73,8 +73,8 @@ class Relation < ActiveRecord::Base
 
     # Add in any tags from the XML
     pt.find("tag").each do |tag|
-      fail OSM::APIBadXMLError.new("relation", pt, "tag is missing key") if tag["k"].nil?
-      fail OSM::APIBadXMLError.new("relation", pt, "tag is missing value") if tag["v"].nil?
+      raise OSM::APIBadXMLError.new("relation", pt, "tag is missing key") if tag["k"].nil?
+      raise OSM::APIBadXMLError.new("relation", pt, "tag is missing value") if tag["v"].nil?
       relation.add_tag_keyval(tag["k"], tag["v"])
     end
 
@@ -86,13 +86,13 @@ class Relation < ActiveRecord::Base
 
     pt.find("member").each do |member|
       # member_type =
-      fail OSM::APIBadXMLError.new("relation", pt, "The #{member['type']} is not allowed only, #{TYPES.inspect} allowed") unless TYPES.include? member["type"]
+      raise OSM::APIBadXMLError.new("relation", pt, "The #{member['type']} is not allowed only, #{TYPES.inspect} allowed") unless TYPES.include? member["type"]
       # member_ref = member['ref']
       # member_role
       member["role"] ||= "" # Allow  the upload to not include this, in which case we default to an empty string.
       relation.add_member(member["type"].classify, member["ref"], member["role"])
     end
-    fail OSM::APIBadUserInput.new("Some bad xml in relation") if relation.nil?
+    raise OSM::APIBadUserInput.new("Some bad xml in relation") if relation.nil?
 
     relation
   end
@@ -159,7 +159,7 @@ class Relation < ActiveRecord::Base
 
     # duplicate tags are now forbidden, so we can't allow values
     # in the hash to be overwritten.
-    fail OSM::APIDuplicateTagsError.new("relation", id, k) if @tags.include? k
+    raise OSM::APIDuplicateTagsError.new("relation", id, k) if @tags.include? k
 
     @tags[k] = v
   end
@@ -176,18 +176,18 @@ class Relation < ActiveRecord::Base
 
   def delete_with_history!(new_relation, user)
     unless visible
-      fail OSM::APIAlreadyDeletedError.new("relation", new_relation.id)
+      raise OSM::APIAlreadyDeletedError.new("relation", new_relation.id)
     end
 
     # need to start the transaction here, so that the database can
     # provide repeatable reads for the used-by checks. this means it
     # shouldn't be possible to get race conditions.
     Relation.transaction do
-      self.lock!
+      lock!
       check_consistency(self, new_relation, user)
       # This will check to see if this relation is used by another relation
       rel = RelationMember.joins(:relation).find_by("visible = ? AND member_type = 'Relation' and member_id = ? ", true, id)
-      fail OSM::APIPreconditionFailedError.new("The relation #{new_relation.id} is used in relation #{rel.relation.id}.") unless rel.nil?
+      raise OSM::APIPreconditionFailedError.new("The relation #{new_relation.id} is used in relation #{rel.relation.id}.") unless rel.nil?
 
       self.changeset_id = new_relation.changeset_id
       self.tags = {}
@@ -199,10 +199,10 @@ class Relation < ActiveRecord::Base
 
   def update_from(new_relation, user)
     Relation.transaction do
-      self.lock!
+      lock!
       check_consistency(self, new_relation, user)
       unless new_relation.preconditions_ok?(members)
-        fail OSM::APIPreconditionFailedError.new("Cannot update relation #{id}: data or member data is invalid.")
+        raise OSM::APIPreconditionFailedError.new("Cannot update relation #{id}: data or member data is invalid.")
       end
       self.changeset_id = new_relation.changeset_id
       self.changeset = new_relation.changeset
@@ -215,8 +215,8 @@ class Relation < ActiveRecord::Base
 
   def create_with_history(user)
     check_create_consistency(self, user)
-    unless self.preconditions_ok?
-      fail OSM::APIPreconditionFailedError.new("Cannot create relation: data or member data is invalid.")
+    unless preconditions_ok?
+      raise OSM::APIPreconditionFailedError.new("Cannot create relation: data or member data is invalid.")
     end
     self.version = 0
     self.visible = true
@@ -253,7 +253,7 @@ class Relation < ActiveRecord::Base
 
       # and check that it is OK to use.
       unless element && element.visible? && element.preconditions_ok?
-        fail OSM::APIPreconditionFailedError.new("Relation with id #{id} cannot be saved due to #{m[0]} with id #{m[1]}")
+        raise OSM::APIPreconditionFailedError.new("Relation with id #{id} cannot be saved due to #{m[0]} with id #{m[1]}")
       end
       hash[m[1]] = true
     end
@@ -270,7 +270,7 @@ class Relation < ActiveRecord::Base
       old_id = id.to_i
       if old_id < 0
         new_id = id_map[type.downcase.to_sym][old_id]
-        fail OSM::APIBadUserInput.new("Placeholder #{type} not found for reference #{old_id} in relation #{self.id.nil? ? placeholder_id : self.id}.") if new_id.nil?
+        raise OSM::APIBadUserInput.new("Placeholder #{type} not found for reference #{old_id} in relation #{self.id.nil? ? placeholder_id : self.id}.") if new_id.nil?
         [type, new_id, role]
       else
         [type, id, role]
@@ -289,7 +289,7 @@ class Relation < ActiveRecord::Base
       t = Time.now.getutc
       self.version += 1
       self.timestamp = t
-      self.save!
+      save!
 
       tags = self.tags.clone
       relation_tags.each do |old_tag|
@@ -312,7 +312,7 @@ class Relation < ActiveRecord::Base
       end
       # if there are left-over tags then they are new and will have to
       # be added.
-      tags_changed |= (!tags.empty?)
+      tags_changed |= !tags.empty?
       RelationTag.delete_all(:relation_id => id)
       self.tags.each do |k, v|
         tag = RelationTag.new
@@ -370,7 +370,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) { |a, e| a || e }
 
       update_members = if tags_changed || any_relations
                          # add all non-relation bounding boxes to the changeset
index a1b30abb30d76c9a51c01b1083bbb0ad12335d1b..c0f0194860f0117fcf71181301bfb2c53385a849 100644 (file)
@@ -35,7 +35,7 @@ class RequestToken < OauthToken
   end
 
   def oob?
-    callback_url.nil? || callback_url.downcase == "oob"
+    callback_url.nil? || callback_url.casecmp("oob").zero?
   end
 
   def oauth10?
index b13ce84d23b5addf216a9f363fb06f1d1905dc63..a1e98467648507fef371d1c827a03a67526696ca 100644 (file)
@@ -28,20 +28,20 @@ class Trace < ActiveRecord::Base
   end
 
   def tagstring=(s)
-    if s.include? ","
-      self.tags = s.split(/\s*,\s*/).select { |tag| tag !~ /^\s*$/ }.collect {|tag|
-        tt = Tracetag.new
-        tt.tag = tag
-        tt
-      }
-    else
-      # do as before for backwards compatibility:
-      self.tags = s.split.collect {|tag|
-        tt = Tracetag.new
-        tt.tag = tag
-        tt
-      }
-    end
+    self.tags = if s.include? ","
+                  s.split(/\s*,\s*/).select { |tag| tag !~ /^\s*$/ }.collect do |tag|
+                    tt = Tracetag.new
+                    tt.tag = tag
+                    tt
+                  end
+                else
+                  # do as before for backwards compatibility:
+                  s.split.collect do |tag|
+                    tt = Tracetag.new
+                    tt.tag = tag
+                    tt
+                  end
+                end
   end
 
   def public?
@@ -101,17 +101,17 @@ class Trace < ActiveRecord::Base
     zipped = filetype =~ /Zip archive/
     tarred = filetype =~ /tar archive/
 
-    if gzipped
-      mimetype = "application/x-gzip"
-    elsif bzipped
-      mimetype = "application/x-bzip2"
-    elsif zipped
-      mimetype = "application/x-zip"
-    elsif tarred
-      mimetype = "application/x-tar"
-    else
-      mimetype = "application/gpx+xml"
-    end
+    mimetype = if gzipped
+                 "application/x-gzip"
+               elsif bzipped
+                 "application/x-bzip2"
+               elsif zipped
+                 "application/x-zip"
+               elsif tarred
+                 "application/x-tar"
+               else
+                 "application/gpx+xml"
+               end
 
     mimetype
   end
@@ -123,21 +123,21 @@ class Trace < ActiveRecord::Base
     zipped = filetype =~ /Zip archive/
     tarred = filetype =~ /tar archive/
 
-    if tarred && gzipped
-      extension = ".tar.gz"
-    elsif tarred && bzipped
-      extension = ".tar.bz2"
-    elsif tarred
-      extension = ".tar"
-    elsif gzipped
-      extension = ".gpx.gz"
-    elsif bzipped
-      extension = ".gpx.bz2"
-    elsif zipped
-      extension = ".zip"
-    else
-      extension = ".gpx"
-    end
+    extension = if tarred && gzipped
+                  ".tar.gz"
+                elsif tarred && bzipped
+                  ".tar.bz2"
+                elsif tarred
+                  ".tar"
+                elsif gzipped
+                  ".gpx.gz"
+                elsif bzipped
+                  ".gpx.bz2"
+                elsif zipped
+                  ".zip"
+                else
+                  ".gpx"
+                end
 
     extension
   end
@@ -156,7 +156,7 @@ class Trace < ActiveRecord::Base
     el1["lon"] = longitude.to_s if inserted
     el1["user"] = user.display_name
     el1["visibility"] = visibility
-    el1["pending"] = (!inserted).to_s
+    el1["pending"] = inserted ? "false" : "true"
     el1["timestamp"] = timestamp.xmlschema
 
     el2 = XML::Node.new "description"
@@ -181,7 +181,7 @@ class Trace < ActiveRecord::Base
       return Trace.from_xml_node(pt, create)
     end
 
-    fail OSM::APIBadXMLError.new("trace", xml, "XML doesn't contain an osm/gpx_file element.")
+    raise OSM::APIBadXMLError.new("trace", xml, "XML doesn't contain an osm/gpx_file element.")
   rescue LibXML::XML::Error, ArgumentError => ex
     raise OSM::APIBadXMLError.new("trace", xml, ex.message)
   end
@@ -189,15 +189,15 @@ class Trace < ActiveRecord::Base
   def self.from_xml_node(pt, create = false)
     trace = Trace.new
 
-    fail OSM::APIBadXMLError.new("trace", pt, "visibility missing") if pt["visibility"].nil?
+    raise OSM::APIBadXMLError.new("trace", pt, "visibility missing") if pt["visibility"].nil?
     trace.visibility = pt["visibility"]
 
     unless create
-      fail OSM::APIBadXMLError.new("trace", pt, "ID is required when updating.") if pt["id"].nil?
+      raise OSM::APIBadXMLError.new("trace", pt, "ID is required when updating.") if pt["id"].nil?
       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
-      fail 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 == 0
     end
 
     # We don't care about the time, as it is explicitly set on create/update/delete
@@ -206,7 +206,7 @@ class Trace < ActiveRecord::Base
     trace.visible = true
 
     description = pt.find("description").first
-    fail OSM::APIBadXMLError.new("trace", pt, "description missing") if description.nil?
+    raise OSM::APIBadXMLError.new("trace", pt, "description missing") if description.nil?
     trace.description = description.content
 
     pt.find("tag").each do |tag|
@@ -297,7 +297,7 @@ class Trace < ActiveRecord::Base
       self.icon_picture = gpx.icon(min_lat, min_lon, max_lat, max_lon)
       self.size = gpx.actual_points
       self.inserted = true
-      self.save!
+      save!
     end
 
     logger.info "done trace #{id}"
index 0053333e2c3ed5e8ede766dba02d284cb11372a4..e255dc2169b1158cb735f4a3afc244223449409a 100644 (file)
@@ -131,8 +131,8 @@ class User < ActiveRecord::Base
     languages.find { |l| Language.exists?(:code => l) }
   end
 
-  def preferred_language_from(array)
-    (languages & array.collect(&:to_s)).first
+  def preferred_languages
+    @locales ||= Locale.list(languages)
   end
 
   def nearby(radius = NEARBY_RADIUS, num = NEARBY_USERS)
@@ -217,8 +217,8 @@ class User < ActiveRecord::Base
 
     score = description.spam_score / 4.0
     score += diary_entries.where("created_at > ?", 1.day.ago).count * 10
-    score += diary_entry_score / diary_entries.length if diary_entries.length > 0
-    score += diary_comment_score / diary_comments.length if diary_comments.length > 0
+    score += diary_entry_score / diary_entries.length unless diary_entries.empty?
+    score += diary_comment_score / diary_comments.length unless diary_comments.empty?
     score -= changeset_score
     score -= trace_score
 
@@ -242,7 +242,7 @@ class User < ActiveRecord::Base
   private
 
   def set_defaults
-    self.creation_time = Time.now.getutc unless self.attribute_present?(:creation_time)
+    self.creation_time = Time.now.getutc unless attribute_present?(:creation_time)
   end
 
   def encrypt_password
index 9686f7250bdc7234173dad784686811420422594..6bc7435aeaa6590e6421386ce7ac2c6c007488c3 100644 (file)
@@ -1,7 +1,7 @@
 class UserRole < ActiveRecord::Base
   belongs_to :user
 
-  ALL_ROLES = %w(administrator moderator)
+  ALL_ROLES = %w(administrator moderator).freeze
 
   validates :role, :inclusion => ALL_ROLES, :uniqueness => { :scope => :user_id }
 end
index 6d49735f1406bee653d02783eae58ab076b7e5fc..d0a252803631c7d1d81f391683cf8747d2718aba 100644 (file)
@@ -40,7 +40,7 @@ class Way < ActiveRecord::Base
     doc.find("//osm/way").each do |pt|
       return Way.from_xml_node(pt, create)
     end
-    fail OSM::APIBadXMLError.new("node", xml, "XML doesn't contain an osm/way element.")
+    raise OSM::APIBadXMLError.new("node", xml, "XML doesn't contain an osm/way element.")
   rescue LibXML::XML::Error, ArgumentError => ex
     raise OSM::APIBadXMLError.new("way", xml, ex.message)
   end
@@ -48,17 +48,17 @@ class Way < ActiveRecord::Base
   def self.from_xml_node(pt, create = false)
     way = Way.new
 
-    fail OSM::APIBadXMLError.new("way", pt, "Version is required when updating") unless create || !pt["version"].nil?
+    raise OSM::APIBadXMLError.new("way", pt, "Version is required when updating") unless create || !pt["version"].nil?
     way.version = pt["version"]
-    fail OSM::APIBadXMLError.new("way", pt, "Changeset id is missing") if pt["changeset"].nil?
+    raise OSM::APIBadXMLError.new("way", pt, "Changeset id is missing") if pt["changeset"].nil?
     way.changeset_id = pt["changeset"]
 
     unless create
-      fail OSM::APIBadXMLError.new("way", pt, "ID is required when updating") if pt["id"].nil?
+      raise OSM::APIBadXMLError.new("way", pt, "ID is required when updating") if pt["id"].nil?
       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
-      fail 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 == 0
     end
 
     # We don't care about the timestamp nor the visibility as these are either
@@ -71,8 +71,8 @@ class Way < ActiveRecord::Base
 
     # Add in any tags from the XML
     pt.find("tag").each do |tag|
-      fail OSM::APIBadXMLError.new("way", pt, "tag is missing key") if tag["k"].nil?
-      fail OSM::APIBadXMLError.new("way", pt, "tag is missing value") if tag["v"].nil?
+      raise OSM::APIBadXMLError.new("way", pt, "tag is missing key") if tag["k"].nil?
+      raise OSM::APIBadXMLError.new("way", pt, "tag is missing value") if tag["v"].nil?
       way.add_tag_keyval(tag["k"], tag["v"])
     end
 
@@ -147,7 +147,7 @@ class Way < ActiveRecord::Base
 
     # duplicate tags are now forbidden, so we can't allow values
     # in the hash to be overwritten.
-    fail OSM::APIDuplicateTagsError.new("way", id, k) if @tags.include? k
+    raise OSM::APIDuplicateTagsError.new("way", id, k) if @tags.include? k
 
     @tags[k] = v
   end
@@ -163,10 +163,10 @@ class Way < ActiveRecord::Base
 
   def update_from(new_way, user)
     Way.transaction do
-      self.lock!
+      lock!
       check_consistency(self, new_way, user)
       unless new_way.preconditions_ok?(nds)
-        fail OSM::APIPreconditionFailedError.new("Cannot update way #{id}: data is invalid.")
+        raise OSM::APIPreconditionFailedError.new("Cannot update way #{id}: data is invalid.")
       end
 
       self.changeset_id = new_way.changeset_id
@@ -180,8 +180,8 @@ class Way < ActiveRecord::Base
 
   def create_with_history(user)
     check_create_consistency(self, user)
-    unless self.preconditions_ok?
-      fail OSM::APIPreconditionFailedError.new("Cannot create way: data is invalid.")
+    unless preconditions_ok?
+      raise OSM::APIPreconditionFailedError.new("Cannot create way: data is invalid.")
     end
     self.version = 0
     self.visible = true
@@ -191,7 +191,7 @@ class Way < ActiveRecord::Base
   def preconditions_ok?(old_nodes = [])
     return false if nds.empty?
     if nds.length > MAX_NUMBER_OF_WAY_NODES
-      fail OSM::APITooManyWayNodesError.new(id, nds.length, MAX_NUMBER_OF_WAY_NODES)
+      raise OSM::APITooManyWayNodesError.new(id, nds.length, MAX_NUMBER_OF_WAY_NODES)
     end
 
     # check only the new nodes, for efficiency - old nodes having been checked last time and can't
@@ -205,7 +205,7 @@ class Way < ActiveRecord::Base
 
       if db_nds.length < new_nds.length
         missing = new_nds - db_nds.collect(&:id)
-        fail OSM::APIPreconditionFailedError.new("Way #{id} requires the nodes with id in (#{missing.join(',')}), which either do not exist, or are not visible.")
+        raise OSM::APIPreconditionFailedError.new("Way #{id} requires the nodes with id in (#{missing.join(',')}), which either do not exist, or are not visible.")
       end
     end
 
@@ -213,16 +213,16 @@ class Way < ActiveRecord::Base
   end
 
   def delete_with_history!(new_way, user)
-    fail OSM::APIAlreadyDeletedError.new("way", new_way.id) unless visible
+    raise OSM::APIAlreadyDeletedError.new("way", new_way.id) unless visible
 
     # need to start the transaction here, so that the database can
     # provide repeatable reads for the used-by checks. this means it
     # shouldn't be possible to get race conditions.
     Way.transaction do
-      self.lock!
+      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)
-      fail 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
@@ -242,7 +242,7 @@ class Way < ActiveRecord::Base
     nds.map! do |node_id|
       if node_id < 0
         new_id = id_map[:node][node_id]
-        fail OSM::APIBadUserInput.new("Placeholder node not found for reference #{node_id} in way #{id.nil? ? placeholder_id : id}") if new_id.nil?
+        raise OSM::APIBadUserInput.new("Placeholder node not found for reference #{node_id} in way #{id.nil? ? placeholder_id : id}") if new_id.nil?
         new_id
       else
         node_id
@@ -265,7 +265,7 @@ class Way < ActiveRecord::Base
     Way.transaction do
       self.version += 1
       self.timestamp = t
-      self.save!
+      save!
 
       tags = self.tags
       WayTag.delete_all(:way_id => id)
index 0d17de349ca390a6e5ee38e49bd646805cf3b13f..87b7e301bddaa638ca25d9fac809904b6324b1ba 100644 (file)
@@ -1,6 +1,6 @@
 <%
   member_class = link_class(relation_member.member_type.downcase, relation_member.member)
-  linked_name = link_to printable_name(relation_member.member), { :action => relation_member.member_type.downcase, :id => relation_member.member_id.to_s }, :title => link_title(relation_member.member)
+  linked_name = link_to printable_name(relation_member.member), { :action => relation_member.member_type.downcase, :id => relation_member.member_id.to_s }, :title => link_title(relation_member.member), :rel => link_follow(relation_member.member)
   type_str = t'browse.relation_member.type.' + relation_member.member_type.downcase
 %>
   <li class="<%= member_class %>"><%=
index b1dffb9ef40e50268de23c6f0ed2249f60eca294..489b9cf0756f92e69ee78bf6fbf733fe3f9d0276 100644 (file)
@@ -15,7 +15,7 @@
       <ul>
         <% way.way_nodes.each do |wn| %>
           <li>
-            <%= link_to printable_name(wn.node), { :action => "node", :id => wn.node_id.to_s }, :class => link_class('node', wn.node), :title => link_title(wn.node) %>
+            <%= link_to printable_name(wn.node), { :action => "node", :id => wn.node_id.to_s }, :class => link_class('node', wn.node), :title => link_title(wn.node), :rel => link_follow(wn.node) %>
             <% related_ways = wn.node.ways.reject { |w| w.id == wn.way_id } %>
             <% if related_ways.size > 0 then %>
               (<%= raw t 'browse.way.also_part_of', :count => related_ways.size, :related_ways => related_ways.map { |w| link_to(printable_name(w), { :action => "way", :id => w.id.to_s }, :class => link_class('way', w), :title => link_title(w) ) }.to_sentence %>)
index efb7bb7f986945a79c47b9a1defb37bcfece763b..a33214a70231955009b9546847a09f04cd750207 100644 (file)
     </h4>
     <ul>
       <% @nodes.each do |node| %>
-        <li><%= link_to printable_name(node, true), { :action => "node", :id => node.node_id.to_s }, :class => link_class('node', node), :title => link_title(node) %></li>
+        <li><%= link_to printable_name(node, true), { :action => "node", :id => node.node_id.to_s }, :class => link_class('node', node), :title => link_title(node), :rel => link_follow(node) %></li>
       <% end %>
     </ul>
   <% end %>
     <% end %>
     <%=
         user = (@prev_by_user || @next_by_user).user.display_name
-        link_to user, :controller => "changeset", :action => "list", :display_name => user
+        link_to content_tag(:bdi, user), :controller => "changeset", :action => "list", :display_name => user
     %>
     <% if @next_by_user %>
       &middot;
index 8b5076902170f7517c4791b5765ebe2400c44008..a624bf0a60e65f1f0208906a0e7490ac982d67ec 100644 (file)
@@ -6,4 +6,7 @@
     'changeset' => I18n.t('browse.timeout.type.changeset'),
   };
 %>
-<p><%= t'browse.timeout.sorry', :type=> browse_timeout_type[@type] , :id => params[:id] %></p>
+<div class="browse-section">
+  <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+  <%= t'browse.timeout.sorry', :type=> browse_timeout_type[@type] , :id => params[:id] %>
+</div>
index cbc60695b80a137e8d3fbffbe2bd2c06b6d84155..f27b0bc911be60723a8788d7efc304c4f2d32bab 100644 (file)
       <%= changeset.tags['comment'].to_s.presence || t('browse.no_comment') %>
     </a>
   </h4>
+  <div class="comments comments-<%= changeset.comments.length %>">
+    <%= changeset.comments.length %>
+    <span class="icon note grey"></span>
+  </div>
   <div class="details">
     <%= changeset_details(changeset) %>
     &middot;
index 77118b4b4b5214c9183ded9af5af5dd4c8cfc041..7f08a40b3ff5ddc5dda534c1d6b82cbecb38f5a9 100644 (file)
@@ -5,18 +5,11 @@
 <% end -%>
 
 <%
-   if params[:friends] and @user
-     set_title(t 'changeset.list.title_friend')
-     @heading = t 'changeset.list.title_friend'
-   elsif params[:nearby] and @user
-     set_title(t 'changeset.list.title_nearby')
-     @heading = t 'changeset.list.title_nearby'
-   elsif params[:display_name]
-     set_title(t 'changeset.list.title_user', :user => params[:display_name])
+   set_title(changeset_list_title(params, @user))
+   if params[:display_name]
      @heading = t('changeset.list.title_user', :user => link_to(params[:display_name], :controller => "user", :action => "view", :display_name => params[:display_name])).html_safe
    else
-     set_title(t 'changeset.list.title')
-     @heading = t 'changeset.list.title'
+     @heading = @title
    end
 %>
 
index 619dc4a082d2009d3bc1fc3534a29da0913d0e95..3e0cd9ec58c6624bf3c27535f93cc5568351a607 100644 (file)
@@ -2,7 +2,7 @@ atom_feed(:language => I18n.locale, :schema_date => 2009,
           :id => url_for(params.merge({ :only_path => false })),
           :root_url => url_for(params.merge({ :action => :list, :format => nil, :only_path => false })),
           "xmlns:georss" => "http://www.georss.org/georss") do |feed|
-  feed.title @title
+  feed.title changeset_list_title(params, @user)
 
   feed.updated @edits.map {|e|  [e.created_at, e.closed_at].max }.max
   feed.icon "http://#{SERVER_URL}/favicon.ico"
index 4021eaa4d30bf515cd14f2353dc8f88d512b9f75..f29dc30ffec2edce53a397ad78d0a51237c712bb 100644 (file)
       </div>
     </fieldset>
 
-    <%= submit_tag t('diary_entry.edit.save_button') %>
-    <%# TODO: button should say 'publish' or 'save changes' depending on new/edit state %>
+    <% if action_name == 'new' %>
+      <%= submit_tag t('diary_entry.new.publish_button') %>
+    <% else %>
+      <%= submit_tag t('diary_entry.edit.save_button') %>
+    <% end %>
   </div>
 <% end %>
index 35f05028da52798a70aded8d2c3a42b4f473b8ee..240025fa7484a00ec0300ecf96c687a1ed0a86f2 100644 (file)
@@ -8,7 +8,7 @@ xml.rss("version" => "2.0",
     xml.description @description
     xml.link url_for(:action => "list", :host => SERVER_URL)
     xml.image do
-      xml.url "http://www.openstreetmap.org/images/mag_map-rss2.0.png"
+      xml.url image_path("mag_map-rss2.0.png")
       xml.title "OpenStreetMap"
       xml.width "100"
       xml.height "100"
index e721851018af7a3a504bb4913e643877499ee3a0..8b04dac91d465f44844ffe7145519c9375c70732 100644 (file)
@@ -1,20 +1,29 @@
 <% if flash[:error] %>
   <div class="flash error">
-    <%= image_tag("notice.png", :class => "small_icon", :border => 0) %>
+    <picture>
+      <source srcset="<%= image_path "notice.svg" %>" type="image/svg+xml"></source>
+      <%= image_tag("notice.png", :srcset => image_path("notice.svg"), :class => "small_icon", :border => 0) %>
+    </picture>
     <div class="message"><%= flash[:error] %></div>
   </div>
 <% end %>
 
 <% if flash[:warning] %>
   <div class="flash warning">
-    <%= image_tag("notice.png", :class => "small_icon", :border => 0) %>
+    <picture>
+      <source srcset="<%= image_path "notice.svg" %>" type="image/svg+xml"></source>
+      <%= image_tag("notice.png", :srcset => image_path("notice.svg"), :class => "small_icon", :border => 0) %>
+    </picture>
     <div class="message"><%= flash[:warning] %></div>
   </div>
 <% end %>
 
 <% if flash[:notice] %>
   <div class="flash notice">
-    <%= image_tag("notice.png", :class => "small_icon", :border => 0) %>
+    <picture>
+      <source srcset="<%= image_path "notice.svg" %>" type="image/svg+xml"></source>
+      <%= image_tag("notice.png", :srcset => image_path("notice.svg"), :class => "small_icon", :border => 0) %>
+    </picture>
     <div class="message"><%= flash[:notice] %></div>
   </div>
 <% end %>
index ee23358cebde090886a161f3886bff1feda51ef7..118100df62a178980cac212e955df1140f618196 100644 (file)
@@ -26,7 +26,7 @@
   <%= tag("link", { :rel => "publisher", :href => "https://plus.google.com/111953119785824514010" }) %>
   <%= tag("link", { :rel => "search", :type => "application/opensearchdescription+xml", :title => "OpenStreetMap Search", :href => asset_path("osm.xml") }) %>
   <%= tag("meta", { :name => "description", :content => "OpenStreetMap is the free wiki world map." }) %>
-  <%= tag("meta", :property => "og:image", :content => image_path("osm_logo.png")) %>
+  <%= opengraph_tags(@title) %>
   <% if flash[:piwik_goal] -%>
   <%= tag("meta", :name => "piwik-goal", :content => flash[:piwik_goal]) %>
   <% end -%>  
index 09a75d891899bf5aeacee459cda1d603efbd8f5c..116cf227d9ad9b382e8a29265a7bdae4d05844bf 100644 (file)
@@ -1,7 +1,10 @@
 <header class="closed">
   <h1>
     <a href="<%= root_path %>" class="geolink">
-      <%= image_tag "osm_logo.png", :alt => t('layouts.logo.alt_text'), :class => 'logo' %>
+      <picture>
+        <source srcset="<%= image_path "osm_logo.svg" %>" type="image/svg+xml"></source>
+        <%= image_tag "osm_logo.png", :srcset => image_path("osm_logo.svg"), :alt => t('layouts.logo.alt_text'), :class => 'logo' %>
+      </picture>
       <%= t 'layouts.project_name.h1' %>
     </a>
   </h1>
index a6f42e43cf14f2e0a1c7e633954a9ad7596727c4..5e7fdd04cf286c8acf0262cddd820d3b537059e8 100644 (file)
@@ -1,6 +1,6 @@
 <% if defined? ID_KEY %>
   <div id="map">
-    <iframe frameBorder="0" id="id-embed" class="id-embed"></iframe>
+    <iframe frameBorder="0" id="id-embed" class="id-embed" allowfullscreen></iframe>
   </div>
   <script>
     var params = {};
index 3aeafa9cf08c4cedac6a483da66e06d28c328ca3..1c203b2fb3e57ee6c9c5dfd2b80cdf5a559908bb 100644 (file)
@@ -10,7 +10,7 @@
 <script type="text/javascript">alert("<%= t 'site.edit.potlatch2_not_configured' %>")</script>
 <% end %>
 
-<% locale = select_locale(Potlatch2::LOCALES.keys).to_s %>
+<% locale = Locale.list(Potlatch2::LOCALES.keys).preferred(preferred_languages).to_s %>
 
 <script type="text/javascript" defer="defer">
   var changesaved=true;
index 6bf33653562479adb68a7187e585f35d6c30c13c..9ac03e70d5944e51cbc8878d120f68eac8c1028a 100644 (file)
@@ -47,7 +47,7 @@
     <dt><a href="http://download.geofabrik.de/"><%= t'export.start.too_large.geofabrik.title' %></a></dt>
     <dd><%= t'export.start.too_large.geofabrik.description' %></dd>
 
-    <dt><a href="https://mapzen.com/metro-extracts/"><%= t'export.start.too_large.metro.title' %></a></dt>
+    <dt><a href="https://mapzen.com/data/metro-extracts/"><%= t'export.start.too_large.metro.title' %></a></dt>
     <dd><%= t'export.start.too_large.metro.description' %></dd>
 
     <dt><a href="http://wiki.openstreetmap.org/wiki/Download"><%= t'export.start.too_large.other.title' %></a></dt>
index 075e70b740dd18c59835723ca31d856f476b103c..ba8f7da72762d3073d67b6ab2e27274450e7dda6 100644 (file)
 <body>
 <div id='id-container'></div>
 <script>
-  if (typeof iD == 'undefined') {
+  if (typeof iD == 'undefined' || !iD.detect().support) {
     document.getElementById('id-container').innerHTML = 'This editor is supported ' +
-      'in Firefox, Chrome, Safari, Opera, and Internet Explorer 9 and above. ' +
+      'in Firefox, Chrome, Safari, Opera, and Internet Explorer 11 and above. ' +
       'Please upgrade your browser or use Potlatch 2 to edit the map.';
     document.getElementById('id-container').className = 'unsupported';
   } else {
-    <% locale = select_locale(ID::LOCALES).to_s %>
+    <% locale = ID::LOCALES.preferred(preferred_languages).to_s %>
 
     var id = iD()
       .presets(iD.data.presets)
       .imagery(iD.data.imagery)
-      .taginfo(iD.taginfo())
+      .taginfo(iD.services.taginfo())
       .embed(true)
-      .assetPath("/iD/") <%# Cant use asset_path('iD/') in production. %>
+      .assetPath("iD/")
       .assetMap(<%= assets("iD").to_json.html_safe %>)
       .locale("<%= locale %>", "<%= asset_path("iD/locales/#{locale}.json") %>")
       .preauth({
@@ -36,6 +36,7 @@
       });
 
     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 };
diff --git a/app/views/user/_auth_association.html.erb b/app/views/user/_auth_association.html.erb
new file mode 100644 (file)
index 0000000..abddf19
--- /dev/null
@@ -0,0 +1,3 @@
+<p><%= t "user.auth_association.heading" %></p>
+<p><%= t "user.auth_association.option_1" %></p>
+<p><%= t "user.auth_association.option_2" %></p>
index f175fe18a1da9ceabd0246bddd79ed9c8645743a..5f6e2b7f4d7d5b9fd7ad1d80c73ed35ce6fba5a5 100644 (file)
@@ -1,7 +1,10 @@
 <% content_for :heading do %>
-  <h1><%= t 'user.new.heading' %></h1>
+  <h1><%= t 'user.new.title' %></h1>
+  <div class='header-illustration new-user-main'></div>
+  <div class='header-illustration new-user-arm'></div>
 <% end %>
 
-<p><%= t 'user.new.no_auto_account_create' %></p>
-
-<p><%= raw t 'user.new.contact_webmaster' %></p>
+<div class="message">
+  <h1><%= t 'user.new.no_auto_account_create' %></h1>
+  <h2><%= raw t 'user.new.contact_webmaster' %></h2>
+</div>
index ded03318f6e25842993f0df350ac270c82233492..e6efdc5ce72460a2bd9421efea843fb6544b94a1 100644 (file)
@@ -1,8 +1,12 @@
-<div id="login_login">
+<% content_for :head do %>
+  <%= javascript_include_tag "login" %>
+<% end %>
+
 <% content_for :heading do %>
   <h1><%= t 'user.login.heading' %></h1>
 <% end %>
 
+<div id="login_login">
   <%= form_tag({ :action => "login" }, { :id => "login_form" }) do %>
     <%= hidden_field_tag('referer', h(params[:referer])) %>
 
@@ -29,7 +33,7 @@
       </fieldset>
 
       <fieldset>
-        <%= check_box_tag "remember_me", "yes", false, :tabindex => 3 %>
+        <%= check_box_tag "remember_me", "yes", params[:remember_me] == "yes", :tabindex => 3 %>
         <label for="remember_me" class="standard-label">
           <%= t 'user.login.remember' %>
         </label>
   <% end %>
 
 </div>
-
-<script type="text/javascript">
-$(document).ready(function() {
-  // Preserve location hash in referer
-  if (window.location.hash) {
-    $('#referer').val($('#referer').val() + window.location.hash);
-  }
-
-  $("#openid_open_url").click(function() {
-    $("#openid_url").val("http://");
-    $("#login_auth_buttons").hide();
-    $("#login_openid_url").show();
-    $("#login_openid_submit").show();
-  });
-
-  $("#login_openid_url").hide();
-  $("#login_openid_submit").hide();
-});
-</script>
index 142e436c5162d72d59445cf71d7eae095e1866bf..be2cc0a99bb5813ef68fb761f1a8b49e388d2d97 100644 (file)
@@ -56,5 +56,8 @@ module OpenStreetMap
       config.logstasher.logger_path = LOGSTASH_PATH
       config.logstasher.log_controller_parameters = true
     end
+
+    # Configure image optimisation
+    config.assets.image_optim = YAML.load_file("#{Rails.root}/config/image_optim.yml")
   end
 end
index 7435fea89a052d39be95d26c32a992f94cba3454..f60064a392ebb2bbbed8a4c7526139217e444037 100644 (file)
@@ -90,6 +90,11 @@ defaults: &defaults
     - ".*\\.google\\.ru/.*"
   # URL of Overpass instance to use for feature queries
   overpass_url: "//overpass-api.de/api/interpreter"
+  # Routing endpoints
+  graphhopper_url: "//graphhopper.com/api/1/route"
+  mapquest_directions_url: "//open.mapquestapi.com/directions/v2/route"
+  mapzen_valhalla_url: "//valhalla.mapzen.com/route"
+  osrm_url: "//router.project-osrm.org/viaroute"
   # External authentication credentials
   #google_auth_id: ""
   #google_auth_secret: ""
@@ -98,6 +103,10 @@ defaults: &defaults
   #facebook_auth_secret: ""
   #windowslive_auth_id: ""
   #windowslive_auth_secret: ""
+  # MapQuest authentication details
+  #mapquest_key: ""
+  # Mapzen authentication details
+  #mapzen_valhalla_key: ""
 
 development:
   <<: *defaults
diff --git a/config/image_optim.yml b/config/image_optim.yml
new file mode 100644 (file)
index 0000000..094e408
--- /dev/null
@@ -0,0 +1,12 @@
+skip_missing_workers: true
+pngout: false
+pngcrush: false
+advpng: false
+optipng: false
+pngquant: false
+jhead: false
+jpegoptim: false
+gifsicle: false
+jpegtran: false
+svgo:
+  disable_plugins: ["cleanupIDs"]
index 5613e0d007353abd2a7a5b49b23895adec53f66b..89d38456745e8fa9492bc9a0800356f432cc7633 100644 (file)
@@ -4,7 +4,7 @@ if defined?(ActiveRecord::ConnectionAdaptors::AbstractAdapter)
       class AbstractAdapter
         protected
 
-        alias_method :old_log, :log
+        alias old_log log
 
         def log(sql, name)
           if block_given?
index bb647b6a75c5c134f4796eae2df59945d9b693e7..f59f60820e7edce2072f1b097b35fa09dbba9512 100644 (file)
@@ -7,12 +7,12 @@ Rails.application.config.assets.version = "1.0"
 Rails.application.config.assets.manifest = Rails.root.join("tmp/manifest.json")
 
 # Add additional assets to the asset load path
-# Rails.application.config.assets.paths << Emoji.images_path
+Rails.application.config.assets.paths << Rails.root.join("config")
 
 # Precompile additional assets.
 # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
 Rails.application.config.assets.precompile += %w( index.js browse.js welcome.js fixthemap.js )
-Rails.application.config.assets.precompile += %w( user.js diary_entry.js )
+Rails.application.config.assets.precompile += %w( user.js login.js diary_entry.js )
 Rails.application.config.assets.precompile += %w( screen-ltr.css print-ltr.css )
 Rails.application.config.assets.precompile += %w( screen-rtl.css print-rtl.css )
 Rails.application.config.assets.precompile += %w( leaflet-all.css leaflet.ie.css )
@@ -29,3 +29,6 @@ Rails.application.config.assets.precompile += %w( help/introduction.* )
 Rails.application.config.assets.precompile += %w( iD/img/*.svg iD/img/*.png iD/img/*.gif )
 Rails.application.config.assets.precompile += %w( iD/img/pattern/*.png )
 Rails.application.config.assets.precompile += %w( iD/locales/*.json )
+Rails.application.config.assets.precompile += %w( iD/traffico/stylesheets/traffico.css )
+Rails.application.config.assets.precompile += %w( iD/traffico/fonts/traffico_* )
+Rails.application.config.assets.precompile += %w( iD/traffico/string-maps/*.json )
diff --git a/config/initializers/http_accept_language.rb b/config/initializers/http_accept_language.rb
deleted file mode 100644 (file)
index 2e5c92d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Monkey patch HttpAcceptLanguage pending integration of
-# https://github.com/iain/http_accept_language/pull/6
-#
-module HttpAcceptLanguage
-  class Parser
-    def compatible_language_from(available_languages)
-      user_preferred_languages.find do |x|
-        available_languages.find { |y| y.to_s == x.to_s } ||
-          available_languages.find { |y| y.to_s =~ /^#{Regexp.escape(x.to_s)}-/ }
-      end
-    end
-  end
-end
index 91efa2557d741185ef43088d91518c90a3f13872..a94618c7e3f374f580edd1cf6eca371bb723f452 100644 (file)
@@ -8,6 +8,16 @@ module I18n
         ex.entry[:other]
       end
     end
+
+    class Simple
+      def store_translations_with_normalisation(locale, data, options = {})
+        locale = I18n::Locale::Tag::Rfc4646.tag(locale).to_s
+
+        store_translations_without_normalisation(locale, data, options)
+      end
+
+      alias_method_chain :store_translations, :normalisation
+    end
   end
 
   module JS
index e0e659f12bc4e3e326a13a24da67a5aa69da0fa8..07f79660f8a8b13107a3bc84dd6f41430b960200 100644 (file)
@@ -1,5 +1,5 @@
 # This is required otherwise libxml writes out memory errors to
 # the standard output and exits uncleanly
 LibXML::XML::Error.set_handler do |message|
-  fail message
+  raise message
 end
index a654f2aa203cc5bc7771dfc08e73beb1d2d3e04a..610053141205f03dbb9b5849dd254ddb86d23c9d 100644 (file)
@@ -1,7 +1,7 @@
 require "openid/fetchers"
 require "openid/util"
 
-CA_BUNDLES = ["/etc/ssl/certs/ca-certificates.crt", "/etc/pki/tls/cert.pem"]
+CA_BUNDLES = ["/etc/ssl/certs/ca-certificates.crt", "/etc/pki/tls/cert.pem"].freeze
 
 OpenID.fetcher.ca_file = CA_BUNDLES.find { |f| File.exist?(f) }
 OpenID::Util.logger = Rails.logger
index bad88e1bafeeabc8a2e15d2f2f08ff65cb4d2962..545d7bc0274db58afb8488d731ad9ed45f8c6315 100644 (file)
@@ -18,4 +18,6 @@ class R2Template < Tilt::Template
   end
 end
 
-Rails.application.assets.register_engine ".r2", R2Template
+Rails.application.config.assets.configure do |env|
+  env.register_engine ".r2", R2Template
+end
index 3db2a55f9a1fa7cfeb1ec6d6f70fa6c1710f9953..0c27ba2e79e1f489cebbf2c4b9fbddc33b5b3328 100644 (file)
@@ -1,7 +1,7 @@
 # Hack ActionController::DataStreaming to allow streaming from a file handle
 module ActionController
   module DataStreaming
-    alias_method :old_send_file, :send_file
+    alias old_send_file send_file
 
     def send_file(file, options = {})
       if file.is_a?(File) || file.is_a?(Tempfile)
diff --git a/config/initializers/uri_sanitizer.rb b/config/initializers/uri_sanitizer.rb
new file mode 100644 (file)
index 0000000..7f3f3d0
--- /dev/null
@@ -0,0 +1,2 @@
+# Add URI sanitizer to rack middleware
+Rails.configuration.middleware.insert_before Rack::Runtime, Rack::URISanitizer
index 8d632a177ab8b547ae031aa9c6836c79ce1cda18..b6c9b50cf42b1933bb72b44c103e0b1abef5f049 100644 (file)
@@ -1,11 +1,9 @@
 mapnik:
   - { min_zoom: 0, max_zoom: 19, name: motorway, image: motorway.png }
-  - { min_zoom: 0, max_zoom: 11, name: trunk, image: trunk.png }
-  - { min_zoom: 12, max_zoom: 19, name: trunk, image: trunk12.png }
-  - { min_zoom: 7, max_zoom: 11, name: primary, image: primary.png }
-  - { min_zoom: 12, max_zoom: 19, name: primary, image: primary12.png }
-  - { min_zoom: 9, max_zoom: 11, name: secondary, image: secondary.png }
-  - { min_zoom: 12, max_zoom: 19, name: secondary, image: secondary12.png }
+  - { min_zoom: 0, max_zoom: 6, name: main_road, image: mainroad.png }
+  - { min_zoom: 7, max_zoom: 8, name: main_road, image: mainroad7.png }
+  - { min_zoom: 9, max_zoom: 11, name: main_road, image: mainroad9.png }
+  - { min_zoom: 12, max_zoom: 19, name: main_road, image: mainroad12.png }
   - { min_zoom: 13, max_zoom: 19, name: track, image: track.png }
   - { min_zoom: 13, max_zoom: 19, name: bridleway, image: bridleway.png }
   - { min_zoom: 13, max_zoom: 19, name: cycleway, image: cycleway.png }
index 0e817943d3c094c961ee400a443eaf8c5bdfc45e..e66a0cdf8b8c0d2c6c9a9841b1a2ff7f06cef042 100644 (file)
@@ -13,8 +13,8 @@ af:
       friendly: '%e %B %Y om %H:%M'
   activerecord:
     models:
-      acl: Toegangsbeheer
-      changeset: Stel wysigings
+      acl: Toegangsbeheerlys
+      changeset: Wysigingstel
       country: Land
       diary_comment: Dagboekopmerking
       diary_entry: Dagboekinskrywing
@@ -22,7 +22,7 @@ af:
       language: Taal
       message: Boodskap
       node: Node
-      notifier: Melding
+      notifier: Kennisgewer
       old_node: Ou Node
       session: Sessie
       trace: Spoor
@@ -62,7 +62,11 @@ af:
         description: Beskrywing
         languages: Tale
         pass_crypt: Wagwoord
+  editor:
+    id:
+      name: iD
   browse:
+    version: Weergawe
     download_xml: Laai XML af
     view_history: Sien geskiedenis
     view_details: Sien detail
@@ -74,17 +78,17 @@ af:
       type:
         node: Node
         way: Weg
-        relation: Relasie
+        relation: Verwantskap
     containing_relation:
-      entry: Relasie %{relation_name}
-      entry_role: Relasie %{relation_name} (as %{relation_role})
+      entry: Verwantskap %{relation_name}
+      entry_role: Verwantskap %{relation_name} (as %{relation_role})
     not_found:
       sorry: 'Jammer, %{type} #%{id} kan nie gevind word nie.'
       type:
         node: node
         way: weg
-        relation: relasie
-        changeset: Veranderingstel
+        relation: verwantskap
+        changeset: veranderingstel
     timeout:
       sorry: Jammer, dit het te lank geneem om data vir die %{type} met die id %{id}
         op te soek.
@@ -99,7 +103,7 @@ af:
     changeset_paging_nav:
       showing_page: Bladsy %{page}
       next: Volgende »
-      previous: Â» Vorige
+      previous: Â« Vorige
     changeset:
       anonymous: Anoniem
       no_edits: (geen wysigings)
@@ -136,7 +140,7 @@ af:
     view:
       title: '%{user} se dagboek | %{title}'
       user_title: Dagboek van %{user}
-      leave_a_comment: Los opmerking agter
+      leave_a_comment: Los 'n opmerking
       login_to_leave_a_comment: U moet eers %{login_link} alvorens u kommentaar kan
         lewer
       login: Meld aan
@@ -148,7 +152,7 @@ af:
         nie. Kontroleer u spelling, of miskien is die skakel waarop u gekliek het
         verkeerd.
     diary_entry:
-      posted_by: Gepos deur %{link_user} op %{created} in die %{language_link}
+      posted_by: Gepos deur %{link_user} op %{created} in %{language_link}
       comment_link: Lewer kommentaar op hierdie bydrae
       reply_link: Antwoord op hierdie bydrae
       comment_count:
@@ -188,9 +192,9 @@ af:
       export_details: OpenStreetMap se data is gelisensieer onder die <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.af">Creative
         Commons Erkenning-Insgelyks Deel 2.0 lisensie</a>.
       options: Voorkeure
-      format: 'Formaat:'
+      format: Formaat
       scale: Skaal
-      max: max
+      max: maksimum
       image_size: 'Prentgrootte:'
       zoom: Zoom
       add_marker: Plaas 'n merker op die kaart
@@ -315,7 +319,7 @@ af:
           cycleway: Fietspad
           emergency_access_point: Noodtoeganspunt
           footway: Voetpad
-          ford: Fort
+          ford: Drif
           motorway: Snelweg
           motorway_junction: Snelwegknooppunt
           path: Pad
@@ -336,21 +340,21 @@ af:
           tertiary: Tersiêre pad
           track: Spoor
           trail: Wandelpad
-          trunk: Trokpad
-          trunk_link: Trokpad
+          trunk: Hoofroete
+          trunk_link: Hoofroete
           unclassified: Ongeklassifiseerde pad
           unsurfaced: Grondpad
           "yes": Straat
         historic:
-          archaeological_site: Argeologiese vindplaas
+          archaeological_site: Argeologiese werf
           battlefield: Slagveld
-          building: Gebou
+          building: Historiese gebou
           castle: Kasteel
           church: Kerk
           house: Huis
           icon: Ikoon
           manor: Landgoed
-          memorial: Herdenkingsmonument
+          memorial: Gedenkteken
           mine: Myn
           monument: Monument
           ruins: Ruïnes
@@ -373,7 +377,7 @@ af:
           military: Militêre gebied
           mine: Myn
           quarry: Steengroewe
-          railway: Spoor
+          railway: Spoorweg
           reservoir: Reservoir
           residential: Woongebied
           retail: Kleinhandel
@@ -433,7 +437,7 @@ af:
           country: Land
           county: Distrik
           farm: Plaas
-          hamlet: Gehug
+          hamlet: Dorpie
           house: Huis
           houses: Huise
           island: Eiland
@@ -444,10 +448,10 @@ af:
           region: Streek
           sea: See
           state: Staat
-          subdivision: Deelgebied
+          subdivision: Onderverdeling
           suburb: Voorstad
           town: Dorp
-          unincorporated_area: Geïnkorporeerde Ruimte
+          unincorporated_area: Uitgesluite Ruimte
           village: Dorp
         railway:
           construction: Spoor in aanbou
@@ -456,16 +460,16 @@ af:
           halt: Treinhalte
           historic_station: Historiese spoorwegstasie
           junction: Spoorwegkruising
-          level_crossing: Gelykvloerse kruising
-          monorail: Monorail
-          narrow_gauge: Smalspoor
+          level_crossing: Spooroorgang
+          monorail: Monospoor
+          narrow_gauge: Smalspoorweg
           platform: Spoorweg-platform
-          preserved: Historiese spoor
+          preserved: Historiese spoorweg
           station: Spoorwegstasie
           subway: Metrostasie
-          subway_entrance: Metroingang
+          subway_entrance: Ondergrondse spoorwegingang
           switch: Spoogwegpunte
-          tram_stop: Tramhalte
+          tram_stop: Tremhalte
         shop:
           art: Kunswinkel
           bakery: Bakkery
@@ -502,7 +506,7 @@ af:
           grocery: Kruideniersware-winkel
           hairdresser: Haarkapper
           hardware: Hardwarewinkel
-          hifi: Hi-fi
+          hifi: Hi-Fi
           insurance: Versekering
           jewelry: Juwelierswinkel
           kiosk: Kioskwinkel
@@ -516,7 +520,7 @@ af:
           optician: Oogkundige
           organic: Organiese koswinkel
           outdoor: Buitelug-winkel
-          pet: Dierewinkel
+          pet: Troeteldierwinkel
           photo: Fotowinkel
           salon: Skoonheidssalon
           shoes: Skoenwinkel
@@ -537,7 +541,7 @@ af:
           caravan_site: Karavaanpark
           chalet: Chalet
           guest_house: Gastehuis
-          hostel: Hotel
+          hostel: Jeugherberg
           hotel: Hotel
           information: Inligting
           motel: Motel
@@ -591,7 +595,7 @@ af:
     tag_line: Die vrye wiki-wêreldkaart
     intro_header: Welkom by OpenStreetMap!
     intro_text: OpenStreetMap is 'n kaart van die wêreld, geskep deur gewone mense.
-      Dis gratis onder 'n oop lisensie.
+      Dis gratis om te gebruik onder 'n oop lisensie.
     intro_2_create_account: Skep gebruikerrekening
     osm_read_only: Die OpenStreetMap-databasis kan op die oomblik slegs gelees word
       aangesien noodsaaklik onderhoud tans uitgevoer word.
@@ -602,7 +606,7 @@ af:
     community: Gemeenskap
     foundation_title: Die OpenStreetMap-stigting
     make_a_donation:
-      title: Ondersteun OpenStreetMap met'n geldelike donasie
+      title: Ondersteun OpenStreetMap met 'n geldelike donasie
       text: Maak 'n donasie
     learn_more: Meer inligting
     more: Meer
@@ -631,7 +635,7 @@ af:
       failure:
         more_info_2: 'hulle kan gevind word by:'
     signup_confirm:
-      subject: '[OpenStreetMap] Bevestig u e-posadres'
+      subject: '[OpenStreetMap] Welkom by OpenStreetMap'
     email_confirm:
       subject: '[OpenStreetMap] Bevestig u e-posadres'
     email_confirm_plain:
@@ -643,7 +647,7 @@ af:
       click_the_link: As dit u is, kliek op die onderstaande skakel om die verandering
         te bevestig.
     lost_password:
-      subject: '[OpenStreetMap] Versoek nuwe wagwoord'
+      subject: '[OpenStreetMap] Versoek herstel van wagwoord'
     lost_password_plain:
       greeting: Hallo,
       click_the_link: As dit u is, kliek op die onderstaande skakel om die wagwoord
@@ -654,7 +658,7 @@ af:
     inbox:
       title: Inboks
       my_inbox: My inboks
-      outbox: outboks
+      outbox: uitboks
       from: Vanaf
       subject: Onderwerp
       date: Datum
@@ -678,7 +682,7 @@ af:
       title: Die boodskap bestaan nie
       heading: Die boodskap bestaan nie
     outbox:
-      title: Gestuur
+      title: Uitboks
       my_inbox: My %{inbox_link}
       inbox: inboks
       outbox: uitboks
@@ -717,25 +721,24 @@ af:
       search: Soek
       get_directions_title: Kry aanwysings tussen twee punte
       where_am_i: Waar is ek?
-      submit_text: OK
+      submit_text: Soek
     key:
       table:
         entry:
           motorway: Snelweg
-          trunk: Trokpad
+          trunk: Hoofroete
           primary: Primêre pad
           secondary: Sekondêre pad
           unclassified: Ongeklassifiseerde pad
-          unsurfaced: Grondpad
           track: Spoor
           bridleway: Ruiterpad
           cycleway: Fietspad
           footway: Voetpad
           rail: Spoorweg
-          subway: Metro
+          subway: Ondergrondse spoorweg
           tram:
           - Ligte spoor
-          - tram
+          - trem
           cable:
           - Kabelkar
           - stoelhyser
@@ -746,15 +749,14 @@ af:
           - Lughaweplatform
           - terminaal
           admin: Administratiewe grens
-          forest: Bos
+          forest: Woud
           wood: Bos
           golf: Gholfbaan
           park: Park
           resident: Woongebied
-          tourist: Toerisme-trekpleister
           common:
-          - weide
-          - weide
+          - Gemeen
+          - weiland
           retail: Winkelgebied
           industrial: Industriële gebied
           commercial: Kommersiële gebied
@@ -763,7 +765,7 @@ af:
           - Meer
           - reservoir
           farm: Plaas
-          brownfield: Braakliggende terrein
+          brownfield: Braakveld terrein
           cemetery: Begraafplaas
           allotments: Volkstuine
           pitch: Sportveld
@@ -778,10 +780,9 @@ af:
           summit:
           - Piek
           - piek
-          tunnel: Tonnel
-          bridge: Brug
+          tunnel: Strepieomhulsel = tonnel
+          bridge: Swartomhulsel = brug
           private: Privaat toegang
-          permissive: Beperkte toegang
           destination: Bestemmingsverkeer
           construction: Paaie onder konstruksie
   trace:
@@ -805,11 +806,11 @@ af:
       visibility: 'Sigbaarheid:'
       visibility_help: wat beteken dit?
     trace_form:
-      upload_gpx: Laai GPX-lêer op
-      description: Beskrywing
-      tags: Etikette
+      upload_gpx: 'Laai GPX-lêer op:'
+      description: 'Beskrywing:'
+      tags: 'Etikette:'
       tags_help: met kommas geskei
-      visibility: Sigbaarheid
+      visibility: 'Sigbaarheid:'
       visibility_help: wat beteken dit?
       upload_button: Laai op
       help: Hulp
@@ -819,7 +820,7 @@ af:
     trace_optionals:
       tags: Etikette
     view:
-      title: Besigting spoor %{name}
+      title: Besigtig spoor %{name}
       heading: Besigtig spoor %{name}
       pending: BESIG
       filename: 'Lêernaam:'
@@ -847,7 +848,7 @@ af:
       trace_details: Wys spoor besonderhede
       view_map: Wys kaart
       edit: wysig
-      edit_map: Kaart bewysig
+      edit_map: Wysig kaart
       public: OPENBAAR
       identifiable: IDENTIFISEERBAAR
       private: PRIVAAT
@@ -865,19 +866,19 @@ af:
       made_public: Spoor is openbaar gemaak
   oauth:
     oauthorize:
-      allow_read_prefs: u gebruikersvoorkeure te lees.
+      allow_read_prefs: lees u gebruikersvoorkeure.
       allow_write_prefs: verander jou gebruikersvoorkeure.
-      allow_write_api: die kaart te wysig.
-      allow_write_gpx: Laai GPS-spore op.
+      allow_write_api: die kaart wysig.
+      allow_write_gpx: laai GPS-spore op.
   oauth_clients:
     new:
-      title: Registreer 'n nuwe applikasie
+      title: Registreer 'n nuwe toepassing
       submit: Registreer
     edit:
-      title: Wysig u applikasie
+      title: Wysig u toepassing
       submit: Wysig
     show:
-      authorize_url: 'URL vir magtiging:'
+      authorize_url: 'Magtig URL:'
       edit: Wysig details
       allow_read_prefs: lees hulle gebruikersvoorkeure.
       allow_write_diary: skep dagboekinskrywings, lewer kommentaar en maak vriende.
@@ -885,15 +886,15 @@ af:
       allow_write_gpx: laai GPS-spore op.
     index:
       title: My OAuth-details
-      application: Applikasienaam
+      application: Toepassingnaam
       issued_at: Uitgereik op
       revoke: Herroep!
-      my_apps: My kliënt-applikasies
-      register_new: Registreer u applikasie
+      my_apps: My kliënt-toepassing
+      register_new: Registreer u toepassing
     form:
       name: Naam
       required: Verplig
-      url: Applikasie-URL
+      url: Toepassing-URL
       support_url: Ondersteunings-URL
       allow_read_prefs: lees hulle gebruikersvoorkeure.
       allow_write_prefs: verander hulle gebruikersvoorkeure.
@@ -906,7 +907,7 @@ af:
       heading: Meld aan
       email or username: 'E-posadres of gebruikersnaam:'
       password: 'Wagwoord:'
-      remember: 'Onthou my:'
+      remember: Onthou my
       lost password link: Wagwoord vergeet?
       login_button: Meld aan
       auth failure: Jammer, kon nie met hierdie inligting aanmeld nie.
@@ -925,7 +926,7 @@ af:
       heading: Herstel wagwoord vir %{user}
       password: 'Wagwoord:'
       confirm password: 'Bevestig wagwoord:'
-      reset: Kry nuwe wagwoord
+      reset: Herstel wagwoord
       flash changed: U wagwoord is verander.
     new:
       title: Skep rekening
@@ -936,7 +937,7 @@ af:
       email address: 'E-posadres:'
       confirm email address: 'Bevestig E-posadres:'
       not displayed publicly: Word nie publiek vertoon nie (sien <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy"
-        title="wiki-geheimhoudingbeleid insluitend afdeling oor e-posadresse">geheimhoudingbeleid</a>)
+        title="wiki privacy policy including section on email addresses">geheimhoudingbeleid</a>)
       display name: 'Vertoon naam:'
       password: 'Wagwoord:'
       confirm password: 'Bevestig wagwoord:'
@@ -944,7 +945,7 @@ af:
       terms accepted: Dankie dat u die nuwe bydraerooreenkoms aanvaar het!
     terms:
       title: Bydraerooreenkoms
-      heading: Voorwaardes vir bydraes
+      heading: Voorwaardes vir bydraers
       agree: Aanvaar
       decline: Weier
       legale_names:
@@ -957,21 +958,21 @@ af:
       body: Daar is geen gebruiker met die naam %{user} nie. Kontroleer u spelling,
         of die skakel waarop u gekliek het is verkeerd.
     view:
-      my diary: my dagboek
+      my diary: My dagboek
       new diary entry: nuwe dagboekinskrywing
-      my edits: my wysigings
-      my traces: my spore
-      my settings: my voorkeure
+      my edits: My wysigings
+      my traces: My spore
+      my settings: My voorkeure
       oauth settings: Oauth-instellings
       blocks on me: blokkades op my
       blocks by me: blokkades deur my
-      send message: stuur boodskap
-      diary: dagboek
-      edits: wysigings
-      traces: spore
-      remove as friend: verwyder as vriend
-      add as friend: voeg by as vriend
-      mapper since: 'Karteer sedert:'
+      send message: Stuur boodskap
+      diary: Dagboek
+      edits: Wysigings
+      traces: Spore
+      remove as friend: Verwyder as vriend
+      add as friend: Voeg by as vriend
+      mapper since: 'Karteerder sedert:'
       ago: (%{time_in_words_ago} gelede)
       email address: 'E-posadres:'
       created from: 'Geskep vanaf:'
@@ -987,13 +988,13 @@ af:
       km away: '%{count}km vêr'
       m away: '%{count}m vêr'
       nearby users: Ander nabygeleë gebruikers
-      no nearby users: Daar is nog geen gebruikers wat herken dat hulle nabygeleë
-        karterinswerk doen nie.
+      no nearby users: Daar is nog geen gebruikers wat erken dat hulle nabygeleë karterinswerk
+        doen nie.
       role:
         administrator: Hierdie gebruiker is 'n administrateur
         moderator: Hierdie gebruiker is 'n moderator
         grant:
-          administrator: Trek adminregte terug
+          administrator: Ken adminregte toe
           moderator: Ken moderatorregte toe
         revoke:
           administrator: Trek adminregte terug
@@ -1041,17 +1042,17 @@ af:
       return to profile: Terug na profiel
       flash update success: U gebruikersinligting is verander.
     confirm:
-      heading: Bevestig 'n gebruiker se rekening
+      heading: Kontroleer u e-pos!
       press confirm button: Kliek op "Bevestig" hieronder om u rekening aktiveer.
       button: Bevestig
     confirm_email:
       heading: Bevestig verandering van e-posadres
       button: Bevestig
-      success: U e-posadres is bevestig, dankie dat u geregistreer het!
+      success: U e-posadres verandering is bevestig!
     set_home:
-      flash success: U tuisligging is suksesvol gebêre
+      flash success: U tuisligging is suksesvol gestoor
     make_friend:
-      success: '%{name} is nou u vriend.'
+      success: '%{name} is nou u vriend!'
       failed: Jammer, kon nie %{name} as 'n vriend byvoeg nie.
       already_a_friend: U is reeds met %{name} bevriend.
     remove_friend:
@@ -1103,29 +1104,29 @@ af:
       heading: Lys van gebruikersblokkades
       empty: Daar is nog geen blokkades ingestel nie.
     revoke:
-      confirm: Is u seker u wil hierdie blokkade terugtrek?
-      revoke: Terugtrek
-      flash: Hierdie blokkade is teruggetrek.
+      confirm: Is u seker u wil hierdie blokkade herroep?
+      revoke: Herroep!
+      flash: Hierdie blokkade is herroep.
     period:
       one: 1 uur
       other: '%{count} ure'
     partial:
       show: Wys
       edit: Wysig
-      revoke: Terugtrek
+      revoke: Herroep!
       confirm: Is u seker?
       display_name: Geblokkeerde gebruiker
       creator_name: Skepper
       reason: Rede vir blokkade
       status: Status
-      revoker_name: Teruggetrek deur
+      revoker_name: Herroep deur
       not_revoked: (nie herroep nie)
     helper:
       time_future: Verval oor %{time}.
       until_login: Aktief totdat die gebruiker aanmeld.
       time_past: Het %{time} gelede verval.
     blocks_on:
-      title: Blokkades vir %{name}
+      title: Blokkades op %{name}
       heading: Lys van blokkades teen %{name}
       empty: '%{name} is nog nooit geblokkeer nie.'
     blocks_by:
@@ -1140,11 +1141,11 @@ af:
       status: Status
       show: Wys
       edit: Wysig
-      revoke: Terugtrek
+      revoke: Herroep!
       confirm: Is u seker?
       reason: 'Rede vir blokkade:'
       back: Wys alle blokkades
-      revoker: 'Teruggetrek deur:'
+      revoker: 'Herroep deur:'
       needs_view: Die gebruiker moet aanmeld alvorens hierdie blokkade verwyder sal
         word.
   javascripts:
@@ -1152,15 +1153,15 @@ af:
       title: Deel
     map:
       zoom:
-        in: Zoem in
+        in: Zoom in
       locate:
         title: Wys my ligging
       base:
         cycle_map: Fietskaart
     site:
-      edit_disabled_tooltip: Zoem in om die kaart te redigeer
-      createnote_disabled_tooltip: Zoem in om 'n nota by die kaart te voeg
-      map_data_zoom_in_tooltip: Zoem in om kaartdata te sien
+      edit_disabled_tooltip: Zoom in om die kaart te wysig
+      createnote_disabled_tooltip: Zoom in om 'n nota by die kaart te voeg
+      map_data_zoom_in_tooltip: Zoom in om kaartdata te sien
     directions:
       engines:
         graphhopper_bicycle: Fiets (GraphHopper)
index b7d7dfd2422816e0f8fa1f6c417768b5f4ff132c..8126468f163231f471bb69a3889d2ec74427f7ab 100644 (file)
@@ -7,6 +7,7 @@
 # Author: Fitim
 # Author: Gent
 # Author: Heroid
+# Author: Kosovastar
 # Author: Mdupont
 # Author: MicroBoy
 # Author: Nemo bis
@@ -852,8 +853,8 @@ aln:
       deleted: Mesazhi u fshi
   site:
     index:
-      js_1: Ju jeni tuj e përdor naj shfletues që nuk e përkrah JavaScript, ose ju
-        e keni ndalu JavaScript.
+      js_1: Ju jeni duke përdorur ndonjë shfletues që nuk e përkrah JavaScript, ose
+        i keni çativizuar JavaScript.
       js_2: OpenStreetMap përdor Java skriptet për planet e saj të rrëshqitshëm.
       permalink: Permalink
       shortlink: Shortlink
@@ -887,9 +888,7 @@ aln:
           primary: Udhë kryesore
           secondary: rrugë e mesme
           unclassified: Udhë e paklasifikume
-          unsurfaced: rrugë Unsurfaced
           track: Udhë
-          byway: I parrahur
           bridleway: Bridleway
           cycleway: Cycleway
           footway: Këmbësore
@@ -913,7 +912,6 @@ aln:
           golf: fushë e golfit
           park: Park
           resident: Zonë Rezidenciale
-          tourist: tërheqje Turistike
           common:
           - I përbashkët
           - livadh
@@ -943,7 +941,6 @@ aln:
           tunnel: tunel zorrë thye =
           bridge: Shtresë e jashtme e Zi = urë
           private: qasje privat
-          permissive: qasje tolerant
           destination: qasje Destinacioni
           construction: Rrugët në ndërtim e sipër
   trace:
@@ -1251,7 +1248,7 @@ aln:
       my settings: Preferencat e mia
       current email address: 'Email adresa e tanishme:'
       new email address: 'Email adresa e re:'
-      email never displayed publicly: (asniher su kan publike)
+      email never displayed publicly: (asnjëherë nuk është publikuar)
       public editing:
         heading: 'Ndryshime publike:'
         enabled: E pranishme. Jo anonime dhe muni me i ndryshue t'dhanat.
index 5f1fa6b537d32246d2138a57c9fdf845557c6051..ee87120363cc697921359855caf940625e18b774 100644 (file)
@@ -5,6 +5,7 @@
 # Author: Aude
 # Author: Bassem JARKAS
 # Author: Fahad
+# Author: Faris knight
 # Author: Grille chompa
 # Author: Houcinee1
 # Author: Kuwaity26
@@ -176,6 +177,7 @@ ar:
         way: طريق
         relation: علاقة
         changeset: حزمة التغييرات
+        note: ملحوظة
     timeout:
       sorry: عذرًا، بيانات %{type} بالمعرّف %{id} استغرقت وقتًا طويلا للاسترداد.
       type:
@@ -183,6 +185,7 @@ ar:
         way: الطريق
         relation: العلاقة
         changeset: حزمة التغييرات
+        note: ملحوظة
     redacted:
       redaction: التنقيح %{id}
       message_html: لا يمكن إظهار الإصدارة  %{version} من هذا %{type} لأن صياغتها
@@ -262,6 +265,7 @@ ar:
   diary_entry:
     new:
       title: مدخلة يومية جديدة
+      publish_button: نشر
     list:
       title: يوميات المستخدمين
       title_friends: يوميات الأصدقاء
@@ -362,8 +366,10 @@ ar:
             OpenStreetMap
         overpass:
           title: تجاوز API
+          description: تحميل مربع الإحاطة من مرآة قاعدة بيانات خريطة الشارع المفتوحة
         geofabrik:
           title: تنزيلات موقع جيوفابريك
+          description: مقتطفات محدثة بانتظام من القارات والبلدان والمدن المختارة
         other:
           title: مصادر أخرى
       options: خيارات
@@ -1140,9 +1146,7 @@ ar:
           primary: طريق رئيسي
           secondary: طريق ثانوي
           unclassified: طريق غير مصنّف
-          unsurfaced: طريق غير معبد
           track: مسار
-          byway: طريق فرعي
           bridleway: مسلك خيول
           cycleway: طريق دراجات
           footway: طريق مشاة
@@ -1166,7 +1170,6 @@ ar:
           golf: ملعب غولف
           park: منتزه
           resident: منطقة سكنية
-          tourist: مزار سياحي
           common:
           - شائع
           - مرج
@@ -1196,7 +1199,6 @@ ar:
           tunnel: غطاء متقطع = نفق
           bridge: غطاء أسود = جسر
           private: استخدام خصوصي
-          permissive: استخدام متسامح
           destination: استخدام إلى الوجهة
           construction: الطرق تحت الإنشاء
     richtext_area:
index 0a74f4c3492db937cbf267a7d0f65021f19f670d..f9a4e88ba755d75acb165616e76e63a2143eb618 100644 (file)
@@ -730,9 +730,7 @@ arz:
           primary: طريق رئيسي
           secondary: طريق ثانوي
           unclassified: طريق غير مصنّف
-          unsurfaced: طريق غير معبد
           track: مسار
-          byway: طريق فرعي
           bridleway: مسلك خيول
           cycleway: طريق دراجات
           footway: طريق مشاة
@@ -753,7 +751,6 @@ arz:
           golf: ملعب غولف
           park: منتزه
           resident: منطقه سكنية
-          tourist: مزار سياحي
           common:
           - شائع
           - مرج
index 8e8f13ae0de2c003ffab788f7417f0a7e6451c3b..52de58fce34ffb2220fc4396a6fdcc0e0039f5ba 100644 (file)
@@ -1,6 +1,8 @@
 # Messages for Asturian (asturianu)
 # Exported from translatewiki.net
 # Export driver: phpyaml
+# Author: Enolp
+# Author: Macofe
 # Author: Xuacu
 ---
 ast:
@@ -10,7 +12,7 @@ ast:
   activerecord:
     models:
       acl: Llista de Control d'Accesu
-      changeset: Conxuntu de cambios
+      changeset: Conxuntu de cambeos
       changeset_tag: Etiqueta del conxuntu de cambeos
       country: País
       diary_comment: Comentariu del diariu
@@ -157,6 +159,7 @@ ast:
         way: vía
         relation: rellación
         changeset: conxuntu de cambios
+        note: nota
     timeout:
       sorry: Sentímoslo, los datos pa %{type} con id %{id}, tardaron demasiao en descargase.
       type:
@@ -164,6 +167,7 @@ ast:
         way: vía
         relation: rellación
         changeset: conxuntu de cambios
+        note: nota
     redacted:
       redaction: Redaición de %{id}
       message_html: La versión %{version} de %{type} nun se pue amosar porque ta redactada.
@@ -250,6 +254,7 @@ ast:
   diary_entry:
     new:
       title: Nueva entrada del diariu
+      publish_button: Espublizar
     list:
       title: Diarios d'usuarios
       title_friends: Diarios de collacios
@@ -1182,7 +1187,7 @@ ast:
   about_page:
     next: Siguiente
     copyright_html: <span>&copy;</span> Collaboradores<br>d'OpenStreetMap
-    used_by: '%{name} proporciona datos de mapes a cientos de sitios web, aplicaciones
+    used_by: '%{name} proporciona datos de mapes a milenta sitios web, aplicaciones
       pa móviles, y preseos de hardware'
     lede_text: OpenStreetMap ta construíu por una comunidá de cartógrafos que contribuyen
       y caltienen datos de carreteres, senderos, cafeteríes, estaciones de ferrocarril,
@@ -1432,13 +1437,12 @@ ast:
       table:
         entry:
           motorway: Autopista
+          main_road: Carretera principal
           trunk: Carretera nacional
           primary: Carretera primaria
           secondary: Carretera secundaria
           unclassified: Carretera ensin clasificar
-          unsurfaced: Carretera ensin asfaltar
           track: Pista
-          byway: Camín
           bridleway: Caleya
           cycleway: Carril bici
           footway: Camín peatonal
@@ -1462,7 +1466,6 @@ ast:
           golf: Campu de golf
           park: Parque
           resident: Área residencial
-          tourist: Atracción turística
           common:
           - Espaciu comunal
           - prau
@@ -1492,7 +1495,6 @@ ast:
           tunnel: Borde de rayes = túnel
           bridge: Borde prietu = ponte
           private: Accesu priváu
-          permissive: Accesu permisivu
           destination: Accesu pa destín
           construction: Carreteres en construcción
     richtext_area:
@@ -1653,6 +1655,7 @@ ast:
       allow_read_gpx: lleer les tos traces GPS privaes.
       allow_write_gpx: xubir traces GPS.
       allow_write_notes: camudar notes.
+      grant_access: Permitir accesu
     oauthorize_success:
       title: Solicitú d'autorización permitida
       allowed: Permitió que l'aplicación %{app_name} tenga accesu a la so cuenta.
@@ -1823,16 +1826,6 @@ ast:
       use external auth: Alternativamente, usa un terceru p'aniciar sesión
       auth no password: Cola autenticación con un terceru nun fai falta una contraseña,
         pero delles ferramientes estra o sirvidores inda puen necesitala.
-      auth association: |-
-        <p>La to ID inda nun ta asociada con una cuenta d'OpenStreetMap.</p>
-        <ul>
-          <li>Si yes nuevu n'OpenStreetMap, crea una cuenta nueva usando'l formulariu de más abaxo.</li>
-          <li>
-            Si yá tienes una cuenta, pues aniciar sesión con ella usando'l to
-            nome d'usuariu y contraseña y llueu asociar la cuenta cola
-            to ID na configuración d'usuariu.
-          </li>
-        </ul>
       continue: Date d'alta
       terms accepted: ¡Gracies por aceutar les condiciones de collaboración!
       terms declined: Sentimos que decidieras nun aceutar les Condiciones de Collaborador.
@@ -1919,7 +1912,7 @@ ast:
       create_block: bloquiar esti usuariu
       activate_user: activar esti usuariu
       deactivate_user: desactivar esti usuariu
-      confirm_user: confirmar esti usuariu
+      confirm_user: Confirmar esti usuariu
       hide_user: anubrir esti usuariu
       unhide_user: amosar esti usuariu
       delete_user: desaniciar esti usuariu
@@ -2070,6 +2063,15 @@ ast:
       no_authorization_code: Nun hai códigu d'autorización
       unknown_signature_algorithm: Algoritmu de firma desconocíu
       invalid_scope: Ámbitu inválidu
+    auth_association:
+      heading: La to ID inda nun ta asociada con una cuenta d'OpenStreetMap.
+      option_1: |-
+        Si yes nuevu n'OpenStreetMap, crea una cuenta nueva
+        usando'l formulariu de más abaxo.
+      option_2: |-
+        Si yá tienes una cuenta, puedes aniciar sesión nella
+        usando'l to nome d'usuariu y contraseña y llueu asociar
+        la cuenta cola ID nes preferencies d'usuariu.
   user_role:
     filter:
       not_an_administrator: Namái los alministradores pueden xestionar los roles,
@@ -2312,6 +2314,9 @@ ast:
         mapquest_car: Coche (MapQuest)
         mapquest_foot: A pie (MapQuest)
         osrm_car: En coche (OSRM)
+        mapzen_bicycle: En bicicleta (Mapzen)
+        mapzen_car: En coche (Mapzen)
+        mapzen_foot: A pie (Mapzen)
       directions: Indicaciones
       distance: Distancia
       errors:
index b1cdf39f8b8c539927a1dee7cb0274f5429d3e81..5345f315da8e3b5afa31e150b2c9a49850500952 100644 (file)
@@ -53,7 +53,7 @@ az:
         body: Mətn
       diary_entry:
         user: İstifadəçi
-        title: Başlıq
+        title: Mövzu
         latitude: En dairəsi
         longitude: Uzunluq dairəsi
         language: Dil
@@ -71,7 +71,7 @@ az:
         description: İzah
       message:
         sender: Göndərən
-        title: Başlıq
+        title: Mövzu
         body: Mətn
         recipient: Qəbul edən
       user:
@@ -93,8 +93,10 @@ az:
       name: Uzaqdan idarəetmə
       description: Uzaqd