From: Andy Allan Date: Wed, 12 Jul 2017 09:16:11 +0000 (+0100) Subject: Merge branch 'master' into moderation X-Git-Tag: live~3065^2~116 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/dbd88d893f3c3fce9cafd666b94396988646d81f?hp=-c Merge branch 'master' into moderation --- dbd88d893f3c3fce9cafd666b94396988646d81f diff --combined Gemfile index 25d80f1c0,baa1dcc04..0fd68e4e2 --- a/Gemfile +++ b/Gemfile @@@ -1,7 -1,7 +1,7 @@@ source "https://rubygems.org" # Require rails - gem "rails", "4.2.7" + gem "rails", "5.0.4" # Require things which have moved to gems in ruby 1.9 gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19 @@@ -22,7 -22,7 +22,7 @@@ gem "sass-rails", "~> 5.0 gem "uglifier", ">= 1.3.0" # Use CoffeeScript for .js.coffee assets and views - gem "coffee-rails", "~> 4.1.0" + gem "coffee-rails", "~> 4.2" # Use jquery as the JavaScript library gem "jquery-rails" @@@ -38,45 -38,44 +38,47 @@@ gem "r2 gem "autoprefixer-rails" # Use image_optim to optimise images - gem "image_optim", ">= 0.22.0" + gem "image_optim_rails" # Load rails plugins - gem "rails-i18n", "~> 4.0.0" + gem "actionpack-page_caching" + gem "composite_primary_keys", "~> 9.0.7" + gem "deadlock_retry", ">= 1.2.0" gem "dynamic_form" - gem "rinku", ">= 1.2.2", :require => "rails_rinku" - gem "oauth-plugin", ">= 0.5.1" - gem "validates_email_format_of", ">= 1.5.1" - gem "composite_primary_keys", "~> 8.1.0" gem "http_accept_language", "~> 2.0.0" + gem "i18n-js", ">= 3.0.0" + gem "oauth-plugin", ">= 0.5.1" gem "paperclip", "~> 4.0" - gem "deadlock_retry", ">= 1.2.0" - gem "i18n-js", ">= 3.0.0.rc10" gem "rack-cors" - gem "actionpack-page_caching" + gem "rails-i18n", "~> 4.0.0" + gem "record_tag_helper" + gem "rinku", ">= 1.2.2", :require => "rails_rinku" + gem "validates_email_format_of", ">= 1.5.1" # Sanitise URIs gem "rack-uri_sanitizer" # Omniauth for authentication gem "omniauth" - gem "omniauth-openid" - gem "omniauth-google-oauth2", ">= 0.2.7" gem "omniauth-facebook" - gem "omniauth-windowslive" gem "omniauth-github" + gem "omniauth-google-oauth2", ">= 0.2.7" + gem "omniauth-mediawiki", ">= 0.0.3" + gem "omniauth-openid" + gem "omniauth-windowslive" # Markdown formatting support gem "redcarpet" +# For status transitions of Issues +gem "aasm" + # Load libxml support for XML parsing and generation gem "libxml-ruby", ">= 2.0.5", :require => "libxml" # Use for HTML sanitisation - gem "sanitize" gem "htmlentities" + gem "sanitize" # Load SystemTimer for implementing request timeouts gem "SystemTimer", ">= 1.1.3", :require => "system_timer", :platforms => :ruby_18 @@@ -84,33 -83,44 +86,44 @@@ # Load faraday for mockable HTTP client gem "faraday" - # Load httpclient and soap4r for SOAP support for Quova GeoIP queries - gem "httpclient" - gem "soap4r-ruby1.9" + # Load geoip for querying Maxmind GeoIP database + gem "geoip" + + # Load rotp to generate TOTP tokens + gem "rotp" # Load memcache client in case we are using it gem "dalli" gem "kgio" + # Load secure_headers for Content-Security-Policy support + gem "secure_headers" + + # Load canonical-rails to generate canonical URLs + gem "canonical-rails" + # Used to generate logstash friendly log files gem "logstasher" # Gems useful for development group :development do + gem "listen" gem "vendorer" end # Gems needed for running tests group :test do - gem "rubocop" - gem "timecop" gem "minitest", "~> 5.1", :platforms => [:ruby_19, :ruby_20] + gem "rails-controller-testing" + gem "rubocop" + gem "webmock" end # Needed in development as well so rake can see konacha tasks group :development, :test do + gem "coveralls", :require => false + gem "factory_girl_rails" gem "jshint" - gem "konacha" + # gem "konacha" gem "poltergeist" - gem "coveralls", :require => false end diff --combined Gemfile.lock index a00712521,9b79e9ca1..f25e2e7f0 --- a/Gemfile.lock +++ b/Gemfile.lock @@@ -2,80 -2,84 +2,85 @@@ GE remote: https://rubygems.org/ specs: SystemTimer (1.2.3) + aasm (4.1.0) - actionmailer (4.2.7) - actionpack (= 4.2.7) - actionview (= 4.2.7) - activejob (= 4.2.7) + actioncable (5.0.4) + actionpack (= 5.0.4) + nio4r (>= 1.2, < 3.0) + websocket-driver (~> 0.6.1) + actionmailer (5.0.4) + actionpack (= 5.0.4) + actionview (= 5.0.4) + activejob (= 5.0.4) mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.7) - actionview (= 4.2.7) - activesupport (= 4.2.7) - rack (~> 1.6) - rack-test (~> 0.6.2) - rails-dom-testing (~> 1.0, >= 1.0.5) + rails-dom-testing (~> 2.0) + actionpack (5.0.4) + actionview (= 5.0.4) + activesupport (= 5.0.4) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionpack-page_caching (1.0.2) - actionpack (>= 4.0.0, < 5) - actionview (4.2.7) - activesupport (= 4.2.7) + actionpack-page_caching (1.1.0) + actionpack (>= 4.0.0, < 6) + actionview (5.0.4) + activesupport (= 5.0.4) builder (~> 3.1) erubis (~> 2.7.0) - rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - activejob (4.2.7) - activesupport (= 4.2.7) - globalid (>= 0.3.0) - activemodel (4.2.7) - activesupport (= 4.2.7) - builder (~> 3.1) - activerecord (4.2.7) - activemodel (= 4.2.7) - activesupport (= 4.2.7) - arel (~> 6.0) - activesupport (4.2.7) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.0.4) + activesupport (= 5.0.4) + globalid (>= 0.3.6) + activemodel (5.0.4) + activesupport (= 5.0.4) + activerecord (5.0.4) + activemodel (= 5.0.4) + activesupport (= 5.0.4) + arel (~> 7.0) + activesupport (5.0.4) + concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.4.0) - arel (6.0.3) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + arel (7.1.4) ast (2.3.0) - autoprefixer-rails (6.3.7) + autoprefixer-rails (7.1.1.2) execjs bigdecimal (1.1.0) - builder (3.2.2) - capybara (2.7.1) + builder (3.2.3) + canonical-rails (0.2.0) + rails (>= 4.1, < 5.2) + capybara (2.14.3) addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - climate_control (0.0.3) - activesupport (>= 3.0) + climate_control (0.2.0) cliver (0.3.2) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) - coffee-rails (4.1.1) + coffee-rails (4.2.2) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.1.x) + railties (>= 4.0.0) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.10.0) - colorize (0.8.1) - composite_primary_keys (8.1.3) - activerecord (~> 4.2.0) - concurrent-ruby (1.0.2) - coveralls (0.8.14) + coffee-script-source (1.12.2) + composite_primary_keys (9.0.7) + activerecord (~> 5.0.0) + concurrent-ruby (1.0.5) + coveralls (0.8.21) json (>= 1.8, < 3) - simplecov (~> 0.12.0) + simplecov (~> 0.14.1) term-ansicolor (~> 1.3) - thor (~> 0.19.1) - tins (~> 1.6.0) + thor (~> 0.19.4) + tins (~> 1.6) + crack (0.4.3) + safe_yaml (~> 1.0.0) crass (1.0.2) dalli (2.7.6) deadlock_retry (1.2.0) @@@ -83,76 -87,83 +88,83 @@@ dynamic_form (1.1.4) erubis (2.7.0) execjs (2.7.0) - exifr (1.2.4) - faraday (0.9.2) + exifr (1.2.5) + factory_girl (4.8.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) + railties (>= 3.0.0) + faraday (0.12.1) multipart-post (>= 1.2, < 3) - fspath (2.1.1) - globalid (0.3.6) - activesupport (>= 4.1.0) - hashie (3.4.4) + ffi (1.9.18) + fspath (3.1.0) + geoip (1.6.3) + globalid (0.4.0) + activesupport (>= 4.2.0) + hashdiff (0.3.4) + hashie (3.5.5) htmlentities (4.3.4) http_accept_language (2.0.5) - httpclient (2.8.0) - i18n (0.7.0) - i18n-js (3.0.0.rc13) + i18n (0.8.4) + i18n-js (3.0.0) i18n (~> 0.6, >= 0.6.6) - image_optim (0.22.1) + image_optim (0.24.3) exifr (~> 1.2, >= 1.2.2) - fspath (~> 2.1) - image_size (~> 1.3) + fspath (~> 3.0) + image_size (~> 1.5) in_threads (~> 1.3) progress (~> 3.0, >= 3.0.1) - image_size (1.4.2) - in_threads (1.3.1) - jquery-rails (4.1.1) + image_optim_rails (0.4.0) + image_optim (~> 0.24.0) + rails + sprockets + image_size (1.5.0) + in_threads (1.4.0) + jquery-rails (4.3.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jshint (1.4.0) + jshint (1.5.0) execjs (>= 1.4.0) multi_json (~> 1.0) therubyracer (~> 0.12.1) - json (1.8.3) + json (2.1.0) jsonify (0.3.1) multi_json (~> 1.0) jsonify-rails (0.3.2) actionpack jsonify (< 0.4.0) - jwt (1.5.4) - kgio (2.10.0) - konacha (4.0.0) - actionpack (>= 4.1, < 5) - capybara - colorize - railties (>= 4.1, < 5) - sprockets (>= 2, < 4) - sprockets-rails (>= 2, < 4) - tilt - libv8 (3.16.14.15) - libxml-ruby (2.9.0) + jwt (1.5.6) + kgio (2.11.0) + libv8 (3.16.14.19) + libxml-ruby (3.0.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) logstash-event (1.2.02) - logstasher (1.0.0) - activerecord (>= 4.0) + logstasher (1.2.1) activesupport (>= 4.0) logstash-event (~> 1.2.0) request_store loofah (2.0.3) nokogiri (>= 1.5.9) - mail (2.6.4) + mail (2.6.6) mime-types (>= 1.16, < 4) + method_source (0.8.2) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mimemagic (0.3.0) - mini_portile2 (2.1.0) - minitest (5.9.0) + mini_portile2 (2.2.0) + minitest (5.10.2) multi_json (1.12.1) - multi_xml (0.5.5) + multi_xml (0.6.0) multipart-post (2.0.0) - nokogiri (1.6.8) - mini_portile2 (~> 2.1.0) - pkg-config (~> 1.1.7) - nokogumbo (1.4.7) + nio4r (2.1.0) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) + nokogumbo (1.4.13) nokogiri oauth (0.4.7) oauth-plugin (0.5.1) @@@ -160,147 -171,172 +172,172 @@@ oauth (~> 0.4.4) oauth2 (>= 0.5.0) rack - oauth2 (1.2.0) - faraday (>= 0.8, < 0.10) + oauth2 (1.4.0) + faraday (>= 0.8, < 0.13) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - omniauth (1.3.1) - hashie (>= 1.2, < 4) - rack (>= 1.0, < 3) - omniauth-facebook (3.0.0) + omniauth (1.6.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) + omniauth-facebook (4.0.0) omniauth-oauth2 (~> 1.2) - omniauth-github (1.1.2) - omniauth (~> 1.0) - omniauth-oauth2 (~> 1.1) - omniauth-google-oauth2 (0.4.1) - jwt (~> 1.5.2) + omniauth-github (1.3.0) + omniauth (~> 1.5) + omniauth-oauth2 (>= 1.4.0, < 2.0) + omniauth-google-oauth2 (0.5.0) + jwt (~> 1.5) multi_json (~> 1.3) omniauth (>= 1.1.1) omniauth-oauth2 (>= 1.3.1) + omniauth-mediawiki (0.0.3) + jwt (~> 1.0) + omniauth-oauth (~> 1.0) + omniauth-oauth (1.1.0) + oauth + omniauth (~> 1.0) omniauth-oauth2 (1.4.0) oauth2 (~> 1.0) omniauth (~> 1.2) omniauth-openid (1.0.1) omniauth (~> 1.0) rack-openid (~> 1.3.1) - omniauth-windowslive (0.0.9.1) - multi_json (>= 1.0.3) - omniauth-oauth2 (~> 1.0) + omniauth-windowslive (0.0.12) + multi_json (~> 1.12) + omniauth-oauth2 (~> 1.4) paperclip (4.3.7) activemodel (>= 3.2.0) activesupport (>= 3.2.0) cocaine (~> 0.5.5) mime-types mimemagic (= 0.3.0) - parser (2.3.1.2) + parallel (1.11.2) + parser (2.4.0.0) ast (~> 2.2) - pg (0.18.4) - pkg-config (1.1.7) - poltergeist (1.10.0) + pg (0.21.0) + poltergeist (1.15.0) capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) powerpack (0.1.1) - progress (3.1.1) - psych (2.1.0) + progress (3.3.1) + psych (2.2.4) + public_suffix (2.0.5) r2 (0.2.6) - rack (1.6.4) - rack-cors (0.4.0) + rack (2.0.3) + rack-cors (0.4.1) rack-openid (1.3.1) rack (>= 1.1.0) ruby-openid (>= 2.1.8) rack-test (0.6.3) rack (>= 1.0) rack-uri_sanitizer (0.0.2) - rails (4.2.7) - actionmailer (= 4.2.7) - actionpack (= 4.2.7) - actionview (= 4.2.7) - activejob (= 4.2.7) - activemodel (= 4.2.7) - activerecord (= 4.2.7) - activesupport (= 4.2.7) + rails (5.0.4) + actioncable (= 5.0.4) + actionmailer (= 5.0.4) + actionpack (= 5.0.4) + actionview (= 5.0.4) + activejob (= 5.0.4) + activemodel (= 5.0.4) + activerecord (= 5.0.4) + activesupport (= 5.0.4) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.7) - sprockets-rails - rails-deprecated_sanitizer (1.0.3) - activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.7) - activesupport (>= 4.2.0.beta, < 5.0) - nokogiri (~> 1.6.0) - rails-deprecated_sanitizer (>= 1.0.1) + railties (= 5.0.4) + sprockets-rails (>= 2.0.0) + rails-controller-testing (1.0.2) + actionpack (~> 5.x, >= 5.0.1) + actionview (~> 5.x, >= 5.0.1) + activesupport (~> 5.x) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - rails-i18n (4.0.9) - i18n (~> 0.7) - railties (~> 4.0) - railties (4.2.7) - actionpack (= 4.2.7) - activesupport (= 4.2.7) + rails-i18n (4.0.2) + i18n (~> 0.6) + rails (>= 4.0) + railties (5.0.4) + actionpack (= 5.0.4) + activesupport (= 5.0.4) + method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.1.0) - rake (11.2.2) - redcarpet (3.3.4) + rainbow (2.2.2) + rake + rake (12.0.0) + rb-fsevent (0.9.8) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + record_tag_helper (1.0.0) + actionview (~> 5.x) + redcarpet (3.4.0) ref (2.0.0) - request_store (1.3.1) - rinku (2.0.0) - rubocop (0.41.2) - parser (>= 2.3.1.1, < 3.0) + request_store (1.3.2) + rinku (2.0.2) + rotp (3.3.0) + rubocop (0.49.1) + parallel (~> 1.10) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-openid (2.7.0) ruby-progressbar (1.8.1) - sanitize (4.0.1) + ruby_dep (1.5.0) + safe_yaml (1.0.4) + sanitize (4.5.0) crass (~> 1.0.2) nokogiri (>= 1.4.4) nokogumbo (~> 1.4.1) - sass (3.4.22) - sass-rails (5.0.5) + sass (3.4.24) + sass-rails (5.0.6) railties (>= 4.0.0, < 6) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - simplecov (0.12.0) + secure_headers (3.6.5) + useragent + simplecov (0.14.1) docile (~> 1.1.0) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) - simplecov-html (0.10.0) - soap4r-ruby1.9 (2.0.5) - sprockets (3.6.3) + simplecov-html (0.10.1) + sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.1.1) + sprockets-rails (3.2.0) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - term-ansicolor (1.3.2) + term-ansicolor (1.6.0) tins (~> 1.0) - therubyracer (0.12.2) - libv8 (~> 3.16.14.0) + therubyracer (0.12.3) + libv8 (~> 3.16.14.15) ref - thor (0.19.1) - thread_safe (0.3.5) - tilt (2.0.5) - timecop (0.8.1) - tins (1.6.0) - tzinfo (1.2.2) + thor (0.19.4) + thread_safe (0.3.6) + tilt (2.0.7) + tins (1.14.0) + tzinfo (1.2.3) thread_safe (~> 0.1) - uglifier (3.0.0) + uglifier (3.2.0) execjs (>= 0.3.0, < 3) - unicode-display_width (1.1.0) + unicode-display_width (1.3.0) + useragent (0.16.8) validates_email_format_of (1.6.3) i18n vendorer (0.1.16) - websocket-driver (0.6.4) + webmock (3.0.1) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) - xpath (2.0.0) + xpath (2.1.0) nokogiri (~> 1.3) PLATFORMS @@@ -308,29 -344,30 +345,31 @@@ DEPENDENCIES SystemTimer (>= 1.1.3) + aasm actionpack-page_caching autoprefixer-rails bigdecimal (~> 1.1.0) - coffee-rails (~> 4.1.0) - composite_primary_keys (~> 8.1.0) + canonical-rails + coffee-rails (~> 4.2) + composite_primary_keys (~> 9.0.7) coveralls dalli deadlock_retry (>= 1.2.0) dynamic_form + factory_girl_rails faraday + geoip htmlentities http_accept_language (~> 2.0.0) - httpclient - i18n-js (>= 3.0.0.rc10) - image_optim (>= 0.22.0) + i18n-js (>= 3.0.0) + image_optim_rails jquery-rails jshint json jsonify-rails kgio - konacha libxml-ruby (>= 2.0.5) + listen logstasher minitest (~> 5.1) oauth-plugin (>= 0.5.1) @@@ -338,6 -375,7 +377,7 @@@ omniauth-facebook omniauth-github omniauth-google-oauth2 (>= 0.2.7) + omniauth-mediawiki (>= 0.0.3) omniauth-openid omniauth-windowslive paperclip (~> 4.0) @@@ -347,18 -385,21 +387,21 @@@ r2 rack-cors rack-uri_sanitizer - rails (= 4.2.7) + rails (= 5.0.4) + rails-controller-testing rails-i18n (~> 4.0.0) + record_tag_helper redcarpet rinku (>= 1.2.2) + rotp rubocop sanitize sass-rails (~> 5.0) - soap4r-ruby1.9 - timecop + secure_headers uglifier (>= 1.3.0) validates_email_format_of (>= 1.5.1) vendorer + webmock BUNDLED WITH - 1.10.6 + 1.13.7 diff --combined app/assets/stylesheets/common.scss index 251731a4c,121e0c6d6..2410c210a --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@@ -148,6 -148,8 +148,8 @@@ small, aside .red { color: $red; } + .piwik { border: 0; } + /* Rules for icons */ .icon { @@@ -491,7 -493,8 +493,8 @@@ body.compact background-color: black; } - &.disabled { + &.disabled, + &.leaflet-disabled { background-color: #333; background-color: rgba(0,0,0,.5); cursor: default; @@@ -547,6 -550,10 +550,10 @@@ background: #fff; font-size: 12px; + #sidebar_loader { + display: none; + } + > div { position: relative; float: left; @@@ -582,12 -589,19 +589,19 @@@ .icon.close { float: right; + cursor: pointer; } - p.error { - background-color: #ff7070; - padding: 10px; - font-weight: bold; + .flash { + padding: 15px; + + picture { + margin-right: -25px; + } + + div.message { + margin-left: 30px; + } } } @@@ -724,7 -738,7 +738,7 @@@ font-size: 16px; text-stroke: 2px #fff; background: rgba(255,255,255,.9); - z-index: 2; // For IE9 + z-index: 1000; input[type="radio"] { display: none; } @@@ -869,10 -883,15 +883,15 @@@ #sidebar { #sidebar_loader, + .search_more { + width: 100%; + margin: $lineheight auto; + } + .loader, .load_more { text-align: center; - margin: $lineheight auto; + margin: auto; width: 40px; display: block; } @@@ -1175,6 -1194,7 +1194,7 @@@ tr.turn:hover width: 50%; padding: 6px 10px; word-wrap: break-word; + white-space: pre-wrap; } .browse-tag-k { @@@ -1469,6 -1489,18 +1489,18 @@@ } } + /* Rules for the trace view */ + + .trace-view { + .trace_pending { + color: red; + } + + .geo { + display: inline; + } + } + /* Rules for the new trace form */ #new_trace { @@@ -1674,6 -1706,13 +1706,13 @@@ float: left; } + + .diary-subscribe-buttons { + position:relative; + top: -30px; + left: 130px; + } + /* Rules for the log in page */ #login_auth_buttons { @@@ -1694,6 -1733,14 +1733,14 @@@ margin-bottom: $lineheight; overflow: auto; height: 20em; + + li { + list-style: inherit; + } + + ol ol { + list-style-type: lower-alpha; + } } #decline { @@@ -1752,6 -1799,12 +1799,12 @@@ border-radius: 0 2px 2px 0; } + /* Rules for the oauth authorization page */ + + .oauth-authorize ul { + list-style: none; + } + /* Rules for messages pages */ .messages { @@@ -2739,54 -2792,3 +2792,54 @@@ input.richtext_title[type="text"] display: none; } } + +.read-reports { + background: #eee; + opacity: 0.7; +} + +.report-related-block { + display:inline-block; +} + +.report-block { + width:475px; + float:left; + margin-right:100px; +} + +.related-block{ + width:280px; + float:right; +} + +.issue-comments { + width:475px; +} + +.new-report-form { + border:1px solid #ccc; + border-radius:4px; + display:block-inline; +} + +.new-report-checkbox{ + float:left; + margin-left:10px; + margin-top:3px; +} + +.new-report-string { + font-size:15px; +} + +.report-button { + float:right; +} + +.disclaimer { + width: 600px; + background: #fff1f0; + color: #d85030; + border-color: rgba(216, 80, 48, 0.3); +} diff --combined app/controllers/diary_entry_controller.rb index 105ddb590,1635dc0d0..89107ab1a --- a/app/controllers/diary_entry_controller.rb +++ b/app/controllers/diary_entry_controller.rb @@@ -3,16 -3,16 +3,16 @@@ class DiaryEntryController < Applicatio before_action :authorize_web before_action :set_locale - before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment] + before_action :require_user, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe] before_action :lookup_this_user, :only => [:view, :comments] before_action :check_database_readable - before_action :check_database_writable, :only => [:new, :edit] + before_action :check_database_writable, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe] before_action :require_administrator, :only => [:hide, :hidecomment] def new @title = t "diary_entry.new.title" - if params[:diary_entry] + if request.post? @diary_entry = DiaryEntry.new(entry_params) @diary_entry.user = @user @@@ -24,14 -24,18 +24,18 @@@ else @user.preferences.create(:k => "diary.default_language", :v => @diary_entry.language_code) end - redirect_to :controller => "diary_entry", :action => "list", :display_name => @user.display_name + + # Subscribe user to diary comments + @diary_entry.subscriptions.create(:user => @user) + + redirect_to :action => "list", :display_name => @user.display_name else render :action => "edit" end else default_lang = @user.preferences.where(:k => "diary.default_language").first lang_code = default_lang ? default_lang.v : @user.preferred_language - @diary_entry = DiaryEntry.new(:language_code => lang_code) + @diary_entry = DiaryEntry.new(entry_params.merge(:language_code => lang_code)) set_map_location render :action => "edit" end @@@ -42,9 -46,9 +46,9 @@@ @diary_entry = DiaryEntry.find(params[:id]) if @user != @diary_entry.user - redirect_to :controller => "diary_entry", :action => "view", :id => params[:id] + redirect_to :action => "view", :id => params[:id] elsif params[:diary_entry] && @diary_entry.update_attributes(entry_params) - redirect_to :controller => "diary_entry", :action => "view", :id => params[:id] + redirect_to :action => "view", :id => params[:id] end set_map_location @@@ -57,11 -61,18 +61,18 @@@ @diary_comment = @entry.comments.build(comment_params) @diary_comment.user = @user if @diary_comment.save - if @diary_comment.user != @entry.user - Notifier.diary_comment_notification(@diary_comment).deliver_now + + # Notify current subscribers of the new comment + @entry.subscribers.visible.each do |user| + if @user != user + Notifier.diary_comment_notification(@diary_comment, user).deliver_now + end end - redirect_to :controller => "diary_entry", :action => "view", :display_name => @entry.user.display_name, :id => @entry.id + # Add the commenter to the subscribers if necessary + @entry.subscriptions.create(:user => @user) unless @entry.subscribers.exists?(@user.id) + + redirect_to :action => "view", :display_name => @entry.user.display_name, :id => @entry.id else render :action => "view" end @@@ -69,9 -80,29 +80,29 @@@ render :action => "no_such_entry", :status => :not_found end + def subscribe + diary_entry = DiaryEntry.find(params[:id]) + + diary_entry.subscriptions.create(:user => @user) unless diary_entry.subscribers.exists?(@user.id) + + redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id + rescue ActiveRecord::RecordNotFound + render :action => "no_such_entry", :status => :not_found + end + + def unsubscribe + diary_entry = DiaryEntry.find(params[:id]) + + diary_entry.subscriptions.where(:user => @user).delete_all if diary_entry.subscribers.exists?(@user.id) + + redirect_to :action => "view", :display_name => diary_entry.user.display_name, :id => diary_entry.id + rescue ActiveRecord::RecordNotFound + render :action => "no_such_entry", :status => :not_found + end + def list if params[:display_name] - @this_user = User.active.find_by_display_name(params[:display_name]) + @this_user = User.active.find_by(:display_name => params[:display_name]) if @this_user @title = t "diary_entry.list.user_title", :user => @this_user.display_name @@@ -97,7 -128,7 +128,7 @@@ return end else - @entries = DiaryEntry.joins(:user).where(:users => { :status => %w(active confirmed) }) + @entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] }) if params[:language] @title = t "diary_entry.list.in_language_title", :language => Language.find(params[:language]).english_name @@@ -107,6 -138,8 +138,8 @@@ end end + @params = params.permit(:display_name, :friends, :nearby, :language) + @page = (params[:page] || 1).to_i @page_size = 20 @@@ -119,7 -152,7 +152,7 @@@ def rss if params[:display_name] - user = User.active.find_by_display_name(params[:display_name]) + user = User.active.find_by(:display_name => params[:display_name]) if user @entries = user.diary_entries @@@ -127,11 -160,11 +160,11 @@@ @description = I18n.t("diary_entry.feed.user.description", :user => user.display_name) @link = "http://#{SERVER_URL}/user/#{user.display_name}/diary" else - render :text => "", :status => :not_found + head :not_found return end else - @entries = DiaryEntry.joins(:user).where(:users => { :status => %w(active confirmed) }) + @entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] }) if params[:language] @entries = @entries.where(:language_code => params[:language]) @@@ -152,9 -185,6 +185,9 @@@ @entry = @this_user.diary_entries.visible.where(:id => params[:id]).first if @entry @title = t "diary_entry.view.title", :user => params[:display_name], :title => @entry.title + if params[:comment_id] + @reported_comment = DiaryComment.where(:id => params[:comment_id]) + end else @title = t "diary_entry.no_such_entry.title", :id => params[:id] render :action => "no_such_entry", :status => :not_found @@@ -190,6 -220,8 +223,8 @@@ # return permitted diary entry parameters def entry_params params.require(:diary_entry).permit(:title, :body, :language_code, :latitude, :longitude) + rescue ActionController::ParameterMissing + ActionController::Parameters.new.permit(:title, :body, :language_code, :latitude, :longitude) end ## @@@ -204,7 -236,7 +239,7 @@@ def require_administrator unless @user.administrator? flash[:error] = t("user.filter.not_an_administrator") - redirect_to :controller => "diary_entry", :action => "view" + redirect_to :action => "view" end end diff --combined app/models/notifier.rb index 1b1da7b5e,8f9e3e295..54eb9b418 --- a/app/models/notifier.rb +++ b/app/models/notifier.rb @@@ -3,6 -3,8 +3,8 @@@ class Notifier < ActionMailer::Bas :return_path => EMAIL_RETURN_PATH, :auto_submitted => "auto-generated" helper :application + before_action :set_shared_template_vars + before_action :attach_project_logo def signup_confirm(user, token) with_recipient_locale user do @@@ -76,6 -78,9 +78,9 @@@ @replyurl = url_for(:host => SERVER_URL, :controller => "message", :action => "reply", :message_id => message.id) + @author = @from_user + + attach_user_avatar(message.sender) mail :from => from_address(message.sender.display_name, "m", message.id, message.digest), :to => message.recipient.email, @@@ -83,9 -88,9 +88,9 @@@ end end - def diary_comment_notification(comment) - with_recipient_locale comment.diary_entry.user do - @to_user = comment.diary_entry.user.display_name + def diary_comment_notification(comment, recipient) + with_recipient_locale recipient do + @to_user = recipient.display_name @from_user = comment.user.display_name @text = comment.body @title = comment.diary_entry.title @@@ -106,9 -111,12 +111,12 @@@ :action => "new", :display_name => comment.user.display_name, :title => "Re: #{comment.diary_entry.title}") + @author = @from_user - mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest), - :to => comment.diary_entry.user.email, + attach_user_avatar(comment.user) + + mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest, recipient.id), + :to => recipient.email, :subject => I18n.t("notifier.diary_comment_notification.subject", :user => comment.user.display_name) end end @@@ -122,7 -130,9 +130,9 @@@ @friendurl = url_for(:host => SERVER_URL, :controller => "user", :action => "make_friend", :display_name => @friend.befriender.display_name) + @author = @friend.befriender.display_name + attach_user_avatar(@friend.befriender) mail :to => friend.befriendee.email, :subject => I18n.t("notifier.friend_notification.subject", :user => friend.befriender.display_name) end @@@ -142,6 -152,9 +152,9 @@@ I18n.t("notifier.note_comment_notification.anonymous") end + @author = @commenter + attach_user_avatar(comment.author) + subject = if @owner I18n.t("notifier.note_comment_notification.#{@event}.subject_own", :commenter => @commenter) else @@@ -154,6 -167,7 +167,7 @@@ def changeset_comment_notification(comment, recipient) with_recipient_locale recipient do + @to_user = recipient.display_name @changeset_url = changeset_url(comment.changeset, :host => SERVER_URL) @comment = comment.body @owner = recipient == comment.changeset.user @@@ -161,6 -175,7 +175,7 @@@ @changeset_comment = comment.changeset.tags["comment"].presence @time = comment.created_at @changeset_author = comment.changeset.user.display_name + @author = @commenter subject = if @owner I18n.t("notifier.changeset_comment_notification.commented.subject_own", :commenter => @commenter) @@@ -168,32 -183,48 +183,59 @@@ I18n.t("notifier.changeset_comment_notification.commented.subject_other", :commenter => @commenter) end + attach_user_avatar(comment.author) + mail :to => recipient.email, :subject => subject end end + def new_issue_notification(issue_id, recipient) + with_recipient_locale recipient do + @url = url_for(:host => SERVER_URL, + :controller => "issues", + :action => "show", + :id => issue_id) + subject = I18n.t("notifier.new_issue_notification.subject") + mail :to => recipient.email, :subject => subject + end + end + private + def set_shared_template_vars + @root_url = root_url(:host => SERVER_URL) + end + + def attach_project_logo + attachments.inline["logo.png"] = File.read(Rails.root.join("app", "assets", "images", "osm_logo_30.png")) + end + + def attach_user_avatar(user) + attachments.inline["avatar.png"] = File.read(user_avatar_file_path(user)) + end + + def user_avatar_file_path(user) + image = user && user.image + if image && image.file? + return image.path(:small) + else + return Rails.root.join("app", "assets", "images", "users", "images", "small.png") + end + end + def with_recipient_locale(recipient) I18n.with_locale Locale.available.preferred(recipient.preferred_languages) do yield end end - def from_address(name, type, id, digest) + def from_address(name, type, id, digest, user_id = nil) if Object.const_defined?(:MESSAGES_DOMAIN) && domain = MESSAGES_DOMAIN - "#{name} <#{type}-#{id}-#{digest[0, 6]}@#{domain}>" + if user_id + "#{name} <#{type}-#{id}-#{user_id}-#{digest[0, 6]}@#{domain}>" + else + "#{name} <#{type}-#{id}-#{digest[0, 6]}@#{domain}>" + end else EMAIL_FROM end diff --combined app/models/user.rb index 6fbf8eecb,3ce48e7cd..63c9527c7 --- a/app/models/user.rb +++ b/app/models/user.rb @@@ -4,10 -4,12 +4,12 @@@ class User < ActiveRecord::Bas has_many :traces, -> { where(:visible => true) } has_many :diary_entries, -> { order(:created_at => :desc) } has_many :diary_comments, -> { order(:created_at => :desc) } + has_many :diary_entry_subscriptions, :class_name => "DiaryEntrySubscription" + has_many :diary_subscriptions, :through => :diary_entry_subscriptions, :source => :diary_entry has_many :messages, -> { where(:to_user_visible => true).order(:sent_on => :desc).preload(:sender, :recipient) }, :foreign_key => :to_user_id has_many :new_messages, -> { where(:to_user_visible => true, :message_read => false).order(:sent_on => :desc) }, :class_name => "Message", :foreign_key => :to_user_id has_many :sent_messages, -> { where(:from_user_visible => true).order(:sent_on => :desc).preload(:sender, :recipient) }, :class_name => "Message", :foreign_key => :from_user_id - has_many :friends, -> { joins(:befriendee).where(:users => { :status => %w(active confirmed) }) } + has_many :friends, -> { joins(:befriendee).where(:users => { :status => %w[active confirmed] }) } has_many :friend_users, :through => :friends, :source => :befriendee has_many :tokens, :class_name => "UserToken" has_many :preferences, :class_name => "UserPreference" @@@ -26,14 -28,8 +28,14 @@@ has_many :roles, :class_name => "UserRole" + has_many :issues, :class_name => "Issue", :foreign_key => :reported_user_id + has_one :issue, :class_name => "Issue", :foreign_key => :updated_by + has_many :issue_comments + + has_many :reports + - scope :visible, -> { where(:status => %w(pending active confirmed)) } - scope :active, -> { where(:status => %w(active confirmed)) } + scope :visible, -> { where(:status => %w[pending active confirmed]) } + scope :active, -> { where(:status => %w[active confirmed]) } scope :identifiable, -> { where(:data_public => true) } has_attached_file :image, @@@ -41,7 -37,7 +43,7 @@@ :styles => { :large => "100x100>", :small => "50x50>" } validates :display_name, :presence => true, :allow_nil => true, :length => 3..255, - :exclusion => %w(new terms save confirm confirm-email go_public reset-password forgot-password suspended) + :exclusion => %w[new terms save confirm confirm-email go_public reset-password forgot-password suspended] validates :display_name, :if => proc { |u| u.display_name_changed? }, :uniqueness => { :case_sensitive => false } validates :display_name, :if => proc { |u| u.display_name_changed? }, @@@ -87,7 -83,7 +89,7 @@@ user = nil end elsif options[:token] - token = UserToken.find_by_token(options[:token]) + token = UserToken.find_by(:token => options[:token]) user = token.user if token end @@@ -98,7 -94,7 +100,7 @@@ user = nil end - token.update_column(:expiry, 1.week.from_now) if token && user + token.update(:expiry => 1.week.from_now) if token && user user end @@@ -165,13 -161,13 +167,13 @@@ ## # returns true if a user is visible def visible? - %w(pending active confirmed).include? status + %w[pending active confirmed].include? status end ## # returns true if a user is active def active? - %w(active confirmed).include? status + %w[active confirmed].include? status end ## @@@ -220,8 -216,8 +222,8 @@@ def spam_score changeset_score = changesets.size * 50 trace_score = traces.size * 50 - diary_entry_score = diary_entries.inject(0) { |a, e| a + e.body.spam_score } - diary_comment_score = diary_comments.inject(0) { |a, e| a + e.body.spam_score } + diary_entry_score = diary_entries.inject(0) { |acc, elem| acc + elem.body.spam_score } + diary_comment_score = diary_comments.inject(0) { |acc, elem| acc + elem.body.spam_score } score = description.spam_score / 4.0 score += diary_entries.where("created_at > ?", 1.day.ago).count * 10 @@@ -237,14 -233,14 +239,14 @@@ # perform a spam check on a user def spam_check if status == "active" && spam_score > SPAM_THRESHOLD - update_column(:status, "suspended") + update(:status => "suspended") end end ## # return an oauth access token for a specified application def access_token(application_key) - ClientApplication.find_by_key(application_key).access_token_for_user(self) + ClientApplication.find_by(:key => application_key).access_token_for_user(self) end private diff --combined app/views/diary_entry/view.html.erb index 8bc2b6469,6a2a21abc..23a5230c1 --- a/app/views/diary_entry/view.html.erb +++ b/app/views/diary_entry/view.html.erb @@@ -10,11 -10,7 +10,11 @@@
-<%= render :partial => 'diary_comment', :collection => @entry.visible_comments %> + <% if @reported_comment %> + <%= render :partial => 'diary_comment', :collection => @reported_comment %> + <% else %> + <%= render :partial => 'diary_comment', :collection => @entry.visible_comments %> + <% end %>
<%= if_logged_in(:div) do %>

<%= t 'diary_entry.view.leave_a_comment' %>

@@@ -25,6 -21,11 +25,11 @@@ <%= richtext_area :diary_comment, :body, :cols => 80, :rows => 15 %> <%= submit_tag t('diary_entry.view.save_button') %> <% end %> + <% if @user and @entry.subscribers.exists?(@user.id) %> +
<%= link_to t('javascripts.changesets.show.unsubscribe'), diary_entry_unsubscribe_path(:display_name => @entry.user.display_name, :id => @entry.id), :method => :post, :class => :button %>
+ <% elsif @user %> +
<%= link_to t('javascripts.changesets.show.subscribe'), diary_entry_subscribe_path(:display_name => @entry.user.display_name, :id => @entry.id), :method => :post, :class => :button %>
+ <% end %> <% end %> <%= if_not_logged_in(:div) do %> diff --combined app/views/layouts/_header.html.erb index bc8fde49c,262989752..cd18e79df --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@@ -38,9 -38,6 +38,9 @@@