From: Anton Khorev Date: Thu, 19 Sep 2024 13:49:29 +0000 (+0300) Subject: Merge branch 'pull/5117' X-Git-Tag: live~695 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/6595d43e3cda580508a069e174d0059febcdc6ea?hp=ef2c6ef026f263303d8c9fdd633c437f288d362c Merge branch 'pull/5117' --- diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index dc1092360..7384a8d95 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -26,6 +26,7 @@ FactoryBot/ExcessiveCreateList: - 'test/controllers/notes_controller_test.rb' - 'test/controllers/traces_controller_test.rb' - 'test/controllers/user_blocks_controller_test.rb' + - 'test/system/users_test.rb' # Offense count: 635 # This cop supports safe autocorrection (--autocorrect). diff --git a/DOCKER.md b/DOCKER.md index f6caa6988..4804d09b3 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -75,12 +75,16 @@ Run the Rails database migrations: Prepare the test database: - docker compose run --rm web bundle exec rails db:test:prepare + docker compose run --rm web bundle exec rails db:test:prepare Run the test suite: docker compose run --rm web bundle exec rails test:all +If you encounter errors about missing assets, precompile the assets: + + docker compose run --rm web bundle exec rake assets:precompile + ### Loading an OSM extract This installation comes with no geographic data loaded. You can either create new data using one of the editors (Potlatch 2, iD, JOSM etc) or by loading an OSM extract. Here an example for loading an OSM extract into your Docker-based OSM instance. diff --git a/Dockerfile b/Dockerfile index 1c5638275..dae25be3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,51 +1,39 @@ -FROM ubuntu:22.04 +FROM debian:bookworm ENV DEBIAN_FRONTEND=noninteractive # Install system packages then clean up to minimize image size RUN apt-get update \ - && apt-get install --no-install-recommends -y \ - build-essential \ - curl \ - default-jre-headless \ - file \ - git-core \ - gpg-agent \ - libarchive-dev \ - libffi-dev \ - libgd-dev \ - libpq-dev \ - libsasl2-dev \ - libvips-dev \ - libxml2-dev \ - libxslt1-dev \ - libyaml-dev \ - locales \ - postgresql-client \ - ruby \ - ruby-dev \ - ruby-bundler \ - software-properties-common \ - tzdata \ - unzip - -# Install Node.js 18 and npm -RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ - && apt-get install -y nodejs + && apt-get install --no-install-recommends -y \ + build-essential \ + curl \ + default-jre-headless \ + file \ + git-core \ + gpg-agent \ + libarchive-dev \ + libffi-dev \ + libgd-dev \ + libpq-dev \ + libsasl2-dev \ + libvips-dev \ + libxml2-dev \ + libxslt1-dev \ + libyaml-dev \ + locales \ + postgresql-client \ + ruby-dev \ + ruby-bundler \ + tzdata \ + unzip \ + nodejs \ + npm \ + osmosis \ + ca-certificates \ + firefox-esr # Install yarn globally -RUN npm install --global yarn \ - # We can't use snap packages for firefox inside a container, so we need to get firefox+geckodriver elsewhere - && add-apt-repository -y ppa:mozillateam/ppa \ - && echo "Package: *\nPin: release o=LP-PPA-mozillateam\nPin-Priority: 1001" > /etc/apt/preferences.d/mozilla-firefox \ - && apt-get install --no-install-recommends -y \ - firefox-geckodriver \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install compatible Osmosis to help users import sample data in a new instance -RUN curl -OL https://github.com/openstreetmap/osmosis/releases/download/0.47.2/osmosis-0.47.2.tgz \ - && tar -C /usr/local -xzf osmosis-0.47.2.tgz +RUN npm install --global yarn ENV DEBIAN_FRONTEND=dialog diff --git a/Gemfile.lock b/Gemfile.lock index afc6463b3..1012a09db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -65,7 +65,7 @@ GEM activemodel (= 7.1.4) activesupport (= 7.1.4) timeout (>= 0.4.0) - activerecord-import (1.8.0) + activerecord-import (1.8.1) activerecord (>= 4.2) activestorage (7.1.4) actionpack (= 7.1.4) @@ -95,17 +95,17 @@ GEM autoprefixer-rails (10.4.19.0) execjs (~> 2) aws-eventstream (1.3.0) - aws-partitions (1.970.0) - aws-sdk-core (3.202.2) + aws-partitions (1.976.0) + aws-sdk-core (3.205.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.88.0) - aws-sdk-core (~> 3, >= 3.201.0) + aws-sdk-kms (1.91.0) + aws-sdk-core (~> 3, >= 3.205.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.159.0) - aws-sdk-core (~> 3, >= 3.201.0) + aws-sdk-s3 (1.162.0) + aws-sdk-core (~> 3, >= 3.205.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) aws-sigv4 (1.9.1) @@ -234,7 +234,7 @@ GEM erubi (1.13.0) execjs (2.9.1) exifr (1.4.0) - factory_bot (6.4.6) + factory_bot (6.5.0) activesupport (>= 5.0.0) factory_bot_rails (6.4.3) factory_bot (~> 6.4) @@ -265,7 +265,7 @@ GEM reline htmlentities (4.3.4) http_accept_language (2.1.1) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) i18n-js (3.9.2) i18n (>= 0.6.6) @@ -299,7 +299,7 @@ GEM irb (1.14.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - jbuilder (2.12.0) + jbuilder (2.13.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) jmespath (1.6.2) @@ -308,7 +308,7 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (2.7.2) - jwt (2.8.2) + jwt (2.9.0) base64 kgio (2.11.4) kramdown (2.4.0) @@ -348,7 +348,7 @@ GEM mutex_m (0.2.0) net-http (0.4.1) uri - net-imap (0.4.15) + net-imap (0.4.16) date net-protocol net-pop (0.1.2) @@ -384,8 +384,8 @@ GEM omniauth-github (2.0.1) omniauth (~> 2.0) omniauth-oauth2 (~> 1.8) - omniauth-google-oauth2 (1.1.3) - jwt (>= 2.0) + omniauth-google-oauth2 (1.2.0) + jwt (>= 2.9) oauth2 (~> 2.0) omniauth (~> 2.0) omniauth-oauth2 (~> 1.8) @@ -415,10 +415,10 @@ GEM iniparse (~> 1.4) rexml (~> 3.2) parallel (1.26.3) - parser (3.3.4.2) + parser (3.3.5.0) ast (~> 2.4.1) racc - pg (1.5.7) + pg (1.5.8) popper_js (2.11.8) progress (3.6.0) psych (5.1.2) @@ -492,28 +492,27 @@ GEM rdoc (6.7.0) psych (>= 4.0.0) regexp_parser (2.9.2) - reline (0.5.9) + reline (0.5.10) io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - rexml (3.3.6) - strscan + rexml (3.3.7) rinku (2.0.6) rotp (6.3.0) - rouge (4.3.0) + rouge (4.4.0) rtlcss (0.2.1) mini_racer (>= 0.6.3) - rubocop (1.66.0) + rubocop (1.66.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.1, < 2.0) + rubocop-ast (>= 1.32.2, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.2) + rubocop-ast (1.32.3) parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) @@ -522,10 +521,10 @@ GEM rubocop-minitest (0.36.0) rubocop (>= 1.61, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-performance (1.21.1) + rubocop-performance (1.22.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.26.0) + rubocop-rails (2.26.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) @@ -554,7 +553,7 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-html (0.12.3) + simplecov-html (0.13.1) simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) simpleidn (0.2.3) @@ -575,7 +574,6 @@ GEM stringio (3.1.1) strong_migrations (1.8.0) activerecord (>= 5.2) - strscan (3.1.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) terser (1.2.3) @@ -583,13 +581,13 @@ GEM thor (1.3.2) tilt (2.4.0) timeout (0.4.1) - turbo-rails (2.0.6) + turbo-rails (2.0.7) actionpack (>= 6.0.0) activejob (>= 6.0.0) railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.5.0) + unicode-display_width (2.6.0) uri (0.13.1) validates_email_format_of (1.8.2) i18n (>= 0.8.0) diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index c8d18b9aa..9a8f193a1 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -7,7 +7,7 @@ class Ability can :query, :browse can :show, [Node, Way, Relation] can [:index, :show], [OldNode, OldWay, OldRelation] - can [:show, :new], Note + can [:show, :create], Note can :search, :direction can [:index, :permalink, :edit, :help, :fixthemap, :offline, :export, :about, :communities, :preview, :copyright, :key, :id], :site can [:finish, :embed], :export @@ -20,11 +20,11 @@ class Ability can [:index, :rss, :show], DiaryEntry can :index, DiaryComment can [:index], Note - can [:new, :create, :edit, :update], :password + can [:create, :update], :password can [:index, :show], Redaction - can [:new, :create, :destroy], :session + can [:create, :destroy], :session can [:index, :show, :data, :georss], Trace - can [:terms, :new, :create, :save, :suspended, :show, :auth_success, :auth_failure], User + can [:terms, :create, :save, :suspended, :show, :auth_success, :auth_failure], User can [:index, :show, :blocks_on, :blocks_by], UserBlock end @@ -34,21 +34,21 @@ class Ability if Settings.status != "database_offline" can [:subscribe, :unsubscribe], Changeset - can [:index, :new, :create, :show, :edit, :update, :destroy], :oauth2_application + can [:index, :create, :show, :update, :destroy], :oauth2_application can [:index, :destroy], :oauth2_authorized_application - can [:new, :show, :create, :destroy], :oauth2_authorization - can [:edit, :update, :destroy], :account + can [:show, :create, :destroy], :oauth2_authorization + can [:update, :destroy], :account can [:show], :dashboard - can [:new, :create, :subscribe, :unsubscribe], DiaryEntry + can [:create, :subscribe, :unsubscribe], DiaryEntry can :update, DiaryEntry, :user => user can [:create], DiaryComment can [:make_friend, :remove_friend], Friendship - can [:new, :create, :reply, :show, :inbox, :outbox, :muted, :mark, :unmute, :destroy], Message + can [:create, :reply, :show, :inbox, :outbox, :muted, :mark, :unmute, :destroy], Message can [:close, :reopen], Note - can [:show, :edit, :update], :preference - can [:edit, :update], :profile - can [:new, :create], Report - can [:mine, :new, :create, :edit, :update, :destroy], Trace + can [:show, :update], :preference + can :update, :profile + can :create, Report + can [:mine, :create, :update, :destroy], Trace can [:account, :go_public], User can [:index, :create, :destroy], UserMute @@ -56,8 +56,8 @@ class Ability can [:hide, :unhide], [DiaryEntry, DiaryComment] can [:index, :show, :resolve, :ignore, :reopen], Issue can :create, IssueComment - can [:new, :create, :edit, :update, :destroy], Redaction - can [:new, :create, :revoke_all], UserBlock + can [:create, :update, :destroy], Redaction + can [:create, :revoke_all], UserBlock can :update, UserBlock, :creator => user can :update, UserBlock, :revoker => user can :update, UserBlock, :active? => true diff --git a/app/abilities/api_capability.rb b/app/abilities/api_capability.rb index 07345d254..d8be13643 100644 --- a/app/abilities/api_capability.rb +++ b/app/abilities/api_capability.rb @@ -27,7 +27,7 @@ class ApiCapability if user.moderator? can [:destroy, :restore], ChangesetComment if scope?(token, :write_api) can :destroy, Note if scope?(token, :write_notes) - can :redact, [OldNode, OldWay, OldRelation] if user&.terms_agreed? && (scope?(token, :write_api) || scope?(token, :write_redactions)) + can :redact, [OldNode, OldWay, OldRelation] if user&.terms_agreed? && scope?(token, :write_redactions) end end end diff --git a/app/assets/images/key/opnvkarte/bus_stop13.svg b/app/assets/images/key/opnvkarte/bus_stop13.svg deleted file mode 100644 index ae4ffeeaf..000000000 --- a/app/assets/images/key/opnvkarte/bus_stop13.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/assets/images/key/opnvkarte/bus_stop15.svg b/app/assets/images/key/opnvkarte/bus_stop15.svg deleted file mode 100644 index a25991954..000000000 --- a/app/assets/images/key/opnvkarte/bus_stop15.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/assets/images/key/opnvkarte/rail17.svg b/app/assets/images/key/opnvkarte/rail17.svg deleted file mode 100644 index 8cada29c9..000000000 --- a/app/assets/images/key/opnvkarte/rail17.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/app/assets/images/key/opnvkarte/stop13.svg b/app/assets/images/key/opnvkarte/stop13.svg deleted file mode 100644 index cfe65b344..000000000 --- a/app/assets/images/key/opnvkarte/stop13.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/assets/images/key/opnvkarte/stop15.svg b/app/assets/images/key/opnvkarte/stop15.svg deleted file mode 100644 index 3ae62672e..000000000 --- a/app/assets/images/key/opnvkarte/stop15.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/assets/javascripts/embed.js.erb b/app/assets/javascripts/embed.js.erb index 9a0ec07d3..66cd02b98 100644 --- a/app/assets/javascripts/embed.js.erb +++ b/app/assets/javascripts/embed.js.erb @@ -37,18 +37,16 @@ window.onload = function () { map.attributionControl.setPrefix(''); map.removeControl(map.attributionControl); - if (!args.layer || args.layer === "mapnik" || args.layer === "osmarender" || args.layer === "mapquest") { - new L.OSM.Mapnik(mapnikOptions).addTo(map); - } else if (args.layer === "cyclosm") { + if (args.layer === "cyclosm") { new L.OSM.CyclOSM().addTo(map); } else if (args.layer === "cyclemap" || args.layer === "cycle map") { new L.OSM.CycleMap(thunderforestOptions).addTo(map); } else if (args.layer === "transportmap") { new L.OSM.TransportMap(thunderforestOptions).addTo(map); - } else if (args.layer === "opnvkarte") { - new L.OSM.OPNVKarte().addTo(map); } else if (args.layer === "hot") { new L.OSM.HOT().addTo(map); + } else { + new L.OSM.Mapnik(mapnikOptions).addTo(map); } if (args.marker) { diff --git a/app/assets/javascripts/richtext.js b/app/assets/javascripts/richtext.js index e069f6f88..56aad8c73 100644 --- a/app/assets/javascripts/richtext.js +++ b/app/assets/javascripts/richtext.js @@ -1,24 +1,20 @@ -$(document).ready(function () { +(function () { /* * When the text in an edit pane is changed, clear the contents of * the associated preview pne so that it will be regenerated when * the user next switches to it. */ - $(".richtext_container textarea").change(function () { + $(document).on("change", ".richtext_container textarea", function () { var container = $(this).closest(".richtext_container"); container.find(".tab-pane[id$='_preview']").empty(); - }).on("invalid", function () { - var container = $(this).closest(".richtext_container"); - - container.find("button[data-bs-target$='_edit']").tab("show"); }); /* * Install a handler to set the minimum preview pane height * when switching away from an edit pane */ - $(".richtext_container button[data-bs-target$='_edit']").on("hide.bs.tab", function () { + $(document).on("hide.bs.tab", ".richtext_container button[data-bs-target$='_edit']", function () { var container = $(this).closest(".richtext_container"); var editor = container.find("textarea"); var preview = container.find(".tab-pane[id$='_preview']"); @@ -30,7 +26,7 @@ $(document).ready(function () { /* * Install a handler to switch to preview mode */ - $(".richtext_container button[data-bs-target$='_preview']").on("show.bs.tab", function () { + $(document).on("show.bs.tab", ".richtext_container button[data-bs-target$='_preview']", function () { var container = $(this).closest(".richtext_container"); var editor = container.find("textarea"); var preview = container.find(".tab-pane[id$='_preview']"); @@ -47,7 +43,20 @@ $(document).ready(function () { } }); - var updateHelp = function () { + $(window).on("resize", updateHelp); + + $(document).on("turbo:load", function () { + $(".richtext_container textarea").on("invalid", invalidTextareaListener); + updateHelp(); + }); + + function invalidTextareaListener() { + var container = $(this).closest(".richtext_container"); + + container.find("button[data-bs-target$='_edit']").tab("show"); + } + + function updateHelp() { $(".richtext_container .richtext_help_sidebar:not(:visible):not(:empty)").each(function () { var container = $(this).closest(".richtext_container"); $(this).children().appendTo(container.find(".tab-pane[id$='_help']")); @@ -59,8 +68,5 @@ $(document).ready(function () { container.find("button[data-bs-target$='_edit']").tab("show"); } }); - }; - - updateHelp(); - $(window).on("resize", updateHelp); -}); + } +}()); diff --git a/app/assets/javascripts/user.js b/app/assets/javascripts/user.js index 495470f2f..681ec3ace 100644 --- a/app/assets/javascripts/user.js +++ b/app/assets/javascripts/user.js @@ -1,5 +1,11 @@ //= require leaflet.locatecontrol/src/L.Control.Locate +(function () { + $(document).on("change", "#user_all", function () { + $("#user_list input[type=checkbox]").prop("checked", $("#user_all").prop("checked")); + }); +}()); + $(document).ready(function () { var defaultHomeZoom = 12; var map, marker, deleted_lat, deleted_lon; @@ -200,10 +206,6 @@ $(document).ready(function () { enableAuth(); } - $("#user_all").change(function () { - $("#user_list input[type=checkbox]").prop("checked", $("#user_all").prop("checked")); - }); - $("#content.user_confirm").each(function () { $(this).hide(); $(this).find("#confirm").submit(); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4b36607bb..fdc2ac4e8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -216,20 +216,25 @@ class ApplicationController < ActionController::Base ## # wrap a web page in a timeout def web_timeout(&block) + raise Timeout::Error if Settings.web_timeout.negative? + Timeout.timeout(Settings.web_timeout, &block) rescue ActionView::Template::Error => e e = e.cause if e.is_a?(Timeout::Error) || (e.is_a?(ActiveRecord::StatementInvalid) && e.message.include?("execution expired")) - ActiveRecord::Base.connection.raw_connection.cancel - render :action => "timeout" + respond_to_timeout else raise end rescue Timeout::Error + respond_to_timeout + end + + def respond_to_timeout ActiveRecord::Base.connection.raw_connection.cancel - render :action => "timeout" + render :action => "timeout", :status => :gateway_timeout end ## diff --git a/app/controllers/changesets_controller.rb b/app/controllers/changesets_controller.rb index 2c50ff905..928f1c1ec 100644 --- a/app/controllers/changesets_controller.rb +++ b/app/controllers/changesets_controller.rb @@ -79,13 +79,13 @@ class ChangesetsController < ApplicationController @changeset = Changeset.find(params[:id]) case turbo_frame_request_id when "changeset_nodes" - @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "node_page") + @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :order => [:node_id, :version], :per_page => 20, :parameter => "node_page") render :partial => "elements", :locals => { :type => "node", :elements => @nodes, :pages => @node_pages } when "changeset_ways" - @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "way_page") + @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :order => [:way_id, :version], :per_page => 20, :parameter => "way_page") render :partial => "elements", :locals => { :type => "way", :elements => @ways, :pages => @way_pages } when "changeset_relations" - @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "relation_page") + @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :order => [:relation_id, :version], :per_page => 20, :parameter => "relation_page") render :partial => "elements", :locals => { :type => "relation", :elements => @relations, :pages => @relation_pages } else @comments = if current_user&.moderator? @@ -93,9 +93,9 @@ class ChangesetsController < ApplicationController 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") + @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :order => [:node_id, :version], :per_page => 20, :parameter => "node_page") + @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :order => [:way_id, :version], :per_page => 20, :parameter => "way_page") + @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :order => [:relation_id, :version], :per_page => 20, :parameter => "relation_page") if @changeset.user.active? && @changeset.user.data_public? changesets = conditions_nonempty(@changeset.user.changesets) @next_by_user = changesets.where("id > ?", @changeset.id).reorder(:id => :asc).first diff --git a/app/controllers/friendships_controller.rb b/app/controllers/friendships_controller.rb index ab54cbfd1..8f0c1ad85 100644 --- a/app/controllers/friendships_controller.rb +++ b/app/controllers/friendships_controller.rb @@ -20,7 +20,7 @@ class FriendshipsController < ApplicationController if current_user.friends_with?(@friend) flash[:warning] = t ".already_a_friend", :name => @friend.display_name elsif current_user.friendships.where(:created_at => Time.now.utc - 1.hour..).count >= current_user.max_friends_per_hour - flash.now[:error] = t ".limit_exceeded" + flash[:error] = t ".limit_exceeded" elsif friendship.save flash[:notice] = t ".success", :name => @friend.display_name UserMailer.friendship_notification(friendship).deliver_later diff --git a/app/controllers/user_blocks_controller.rb b/app/controllers/user_blocks_controller.rb index 6bf86de3f..c42c2659d 100644 --- a/app/controllers/user_blocks_controller.rb +++ b/app/controllers/user_blocks_controller.rb @@ -25,7 +25,7 @@ class UserBlocksController < ApplicationController @show_user_name = true @show_creator_name = true - render :partial => "blocks" if turbo_frame_request_id == "pagination" + render :partial => "page" if turbo_frame_request_id == "pagination" end def show @@ -71,7 +71,7 @@ class UserBlocksController < ApplicationController def update if @valid_params if cannot?(:update, @user_block) - flash[:error] = t(@user_block.revoker ? ".only_creator_or_revoker_can_edit" : ".only_creator_can_edit") + flash[:error] = @user_block.revoker ? t(".only_creator_or_revoker_can_edit") : t(".only_creator_can_edit") redirect_to :action => "edit" else user_block_was_active = @user_block.active? @@ -127,7 +127,7 @@ class UserBlocksController < ApplicationController @show_user_name = false @show_creator_name = true - render :partial => "blocks" if turbo_frame_request_id == "pagination" + render :partial => "page" if turbo_frame_request_id == "pagination" end ## @@ -142,7 +142,7 @@ class UserBlocksController < ApplicationController @show_user_name = true @show_creator_name = false - render :partial => "blocks" if turbo_frame_request_id == "pagination" + render :partial => "page" if turbo_frame_request_id == "pagination" end private diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 4ebeb1ec3..63a83ad1d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -36,9 +36,11 @@ class UsersController < ApplicationController users = User.all users = users.where(:status => @params[:status]) if @params[:status] - users = users.where(:creation_ip => @params[:ip]) if @params[:ip] + users = users.where(:creation_address => @params[:ip]) if @params[:ip] + + @users_count = users.limit(501).count + @users_count = I18n.t("count.at_least_pattern", :count => 500) if @users_count > 500 - @users_count = users.count @users, @newer_users_id, @older_users_id = get_page_items(users, :limit => 50) render :partial => "page" if turbo_frame_request_id == "pagination" @@ -266,7 +268,7 @@ class UsersController < ApplicationController def save_new_user(email_hmac, referer = nil) current_user.data_public = true current_user.description = "" if current_user.description.nil? - current_user.creation_ip = request.remote_ip + current_user.creation_address = request.remote_ip current_user.languages = http_accept_language.user_preferred_languages current_user.terms_agreed = Time.now.utc current_user.tou_agreed = Time.now.utc diff --git a/app/helpers/browse_helper.rb b/app/helpers/browse_helper.rb index 0ea10e219..9ea384811 100644 --- a/app/helpers/browse_helper.rb +++ b/app/helpers/browse_helper.rb @@ -86,13 +86,13 @@ module BrowseHelper max_width_for_default_padding = 35 width = 0 - pagination_items(pages, {}).each do |body| + pagination_items(pages, {}).each do |(body)| width += 2 # padding width width += body.length end link_classes = ["page-link", { "px-1" => width > max_width_for_default_padding }] - tag.ul :class => "pagination pagination-sm mb-1 ms-auto" do + tag.ul :class => "pagination pagination-sm mb-2" do pagination_items(pages, {}).each do |body, page_or_class| linked = !(page_or_class.is_a? String) link = if linked diff --git a/app/models/user.rb b/app/models/user.rb index ceeefd40f..6b5418256 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -15,7 +15,6 @@ # pass_salt :string # email_valid :boolean default(FALSE), not null # new_email :string -# creation_ip :string # languages :string # status :enum default("pending"), not null # terms_agreed :datetime @@ -33,9 +32,11 @@ # tou_agreed :datetime # diary_comments_count :integer default(0) # note_comments_count :integer default(0) +# creation_address :inet # # Indexes # +# index_users_on_creation_address (creation_address) USING gist # users_auth_idx (auth_provider,auth_uid) UNIQUE # users_display_name_canonical_idx (lower(NORMALIZE(display_name, NFKC))) # users_display_name_idx (display_name) UNIQUE @@ -48,6 +49,8 @@ class User < ApplicationRecord require "digest" include AASM + self.ignored_columns += ["creation_ip"] + has_many :traces, -> { where(:visible => true) } has_many :diary_entries, -> { order(:created_at => :desc) }, :inverse_of => :user has_many :diary_comments, -> { order(:created_at => :desc) }, :inverse_of => :user diff --git a/app/views/changeset_comments/feeds/timeout.atom.builder b/app/views/changeset_comments/feeds/timeout.atom.builder deleted file mode 100644 index b5eeeed4a..000000000 --- a/app/views/changeset_comments/feeds/timeout.atom.builder +++ /dev/null @@ -1,12 +0,0 @@ -atom_feed(:language => I18n.locale, :schema_date => 2009, - :id => url_for(params.merge(:only_path => false)), - :root_url => url_for(params.merge(:only_path => false, :format => nil)), - "xmlns:georss" => "http://www.georss.org/georss") do |feed| - feed.title @title - - feed.subtitle :type => "xhtml" do |xhtml| - xhtml.p do |p| - p << t(".sorry") - end - end -end diff --git a/app/views/changeset_comments/feeds/timeout.html.erb b/app/views/changeset_comments/feeds/timeout.html.erb deleted file mode 100644 index 641b1dfb8..000000000 --- a/app/views/changeset_comments/feeds/timeout.html.erb +++ /dev/null @@ -1 +0,0 @@ -

<%= t ".sorry" %>

diff --git a/app/views/changeset_comments/feeds/timeout.rss.builder b/app/views/changeset_comments/feeds/timeout.rss.builder new file mode 100644 index 000000000..c56ebb879 --- /dev/null +++ b/app/views/changeset_comments/feeds/timeout.rss.builder @@ -0,0 +1,12 @@ +xml.rss("version" => "2.0", + "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do + xml.channel do + if params[:changeset_id] + xml.title t("changeset_comments.feeds.show.title_particular", :changeset_id => params[:changeset_id]) + else + xml.title t("changeset_comments.feeds.show.title_all") + end + xml.link root_url + xml.description t(".sorry") + end +end diff --git a/app/views/changesets/_paging_nav.html.erb b/app/views/changesets/_paging_nav.html.erb index fbdf1d507..058738222 100644 --- a/app/views/changesets/_paging_nav.html.erb +++ b/app/views/changesets/_paging_nav.html.erb @@ -1,11 +1,9 @@ -
-

<%= type_and_paginated_count(type, pages) %>

- <% if pages.page_count > 1 %> - <%= sidebar_classic_pagination(pages, "#{type}_page") do |page| - { - :title => type_and_paginated_count(type, pages, page), - :data => { :turbo => "true" } - } - end %> - <% end %> -
+

<%= type_and_paginated_count(type, pages) %>

+<% if pages.page_count > 1 %> + <%= sidebar_classic_pagination(pages, "#{type}_page") do |page| + { + :title => type_and_paginated_count(type, pages, page), + :data => { :turbo => "true" } + } + end %> +<% end %> diff --git a/app/views/changesets/index.html.erb b/app/views/changesets/index.html.erb index 97e6351a0..fc5f7cbbc 100644 --- a/app/views/changesets/index.html.erb +++ b/app/views/changesets/index.html.erb @@ -13,9 +13,9 @@ <% end -%> <% elsif params[:bbox] %> -

<%= t(params[:max_id] ? ".no_more_area" : ".empty_area") %>

+

<%= params[:max_id] ? t(".no_more_area") : t(".empty_area") %>

<% elsif params[:display_name] %> -

<%= t(params[:max_id] ? ".no_more_user" : ".empty_user") %>

+

<%= params[:max_id] ? t(".no_more_user") : t(".empty_user") %>

<% else %> -

<%= t(params[:max_id] ? ".no_more" : ".empty") %>

+

<%= params[:max_id] ? t(".no_more") : t(".empty") %>

<% end %> diff --git a/app/views/diary_comments/_page.html.erb b/app/views/diary_comments/_page.html.erb index 66e40cd80..cc6019cff 100644 --- a/app/views/diary_comments/_page.html.erb +++ b/app/views/diary_comments/_page.html.erb @@ -19,8 +19,6 @@ <%= render "shared/pagination", - :newer_key => "diary_comments.page.newer_comments", - :older_key => "diary_comments.page.older_comments", :newer_id => @newer_comments_id, :older_id => @older_comments_id %> diff --git a/app/views/diary_entries/_page.html.erb b/app/views/diary_entries/_page.html.erb index f07db9b6c..c44a5417e 100644 --- a/app/views/diary_entries/_page.html.erb +++ b/app/views/diary_entries/_page.html.erb @@ -4,8 +4,6 @@ <%= render @entries %> <%= render "shared/pagination", - :newer_key => "diary_entries.page.newer_entries", - :older_key => "diary_entries.page.older_entries", :newer_id => @newer_entries_id, :older_id => @older_entries_id %> diff --git a/app/views/issues/_page.html.erb b/app/views/issues/_page.html.erb index b46b1798c..f625f0e04 100644 --- a/app/views/issues/_page.html.erb +++ b/app/views/issues/_page.html.erb @@ -36,8 +36,6 @@ <%= render "shared/pagination", - :newer_key => "issues.page.newer_issues", - :older_key => "issues.page.older_issues", :newer_id => @newer_issues_id, :older_id => @older_issues_id %> <% end %> diff --git a/app/views/layouts/_flash.html.erb b/app/views/layouts/_flash.html.erb index d8adbd0fd..8a7ed6fe4 100644 --- a/app/views/layouts/_flash.html.erb +++ b/app/views/layouts/_flash.html.erb @@ -1,26 +1,13 @@ -<% if flash[:error] %> -
-
- <%= notice_svg_tag %> -
-
<%= render_flash(flash[:error]) %>
-
-<% end %> - -<% if flash[:warning] %> -
-
- <%= notice_svg_tag %> -
-
<%= render_flash(flash[:warning]) %>
-
-<% end %> - -<% if flash[:notice] %> -
-
- <%= notice_svg_tag %> -
-
<%= render_flash(flash[:notice]) %>
-
+<% [[:error, :danger], [:warning, :warning], [:notice, :success]].each do |flash_type, bootstrap_type| %> + <% if flash[flash_type] %> + <%= tag.div :class => "alert alert-#{bootstrap_type} row mx-0 mb-0 p-3 rounded-0 align-items-center", + :data => { :turbo_temporary => true } do %> +
+ <%= notice_svg_tag %> +
+
+ <%= render_flash flash[flash_type] %> +
+ <% end %> + <% end %> <% end %> diff --git a/app/views/nodes/timeout.html.erb b/app/views/nodes/timeout.html.erb new file mode 100644 index 000000000..61415c650 --- /dev/null +++ b/app/views/nodes/timeout.html.erb @@ -0,0 +1,5 @@ +<% set_title(t("browse.timeout.title")) %> + +<%= render "sidebar_header", :title => t("browse.timeout.title") %> + +

<%= t ".sorry", :id => params[:id] %>

diff --git a/app/views/notes/_notes_paging_nav.html.erb b/app/views/notes/_notes_paging_nav.html.erb index 207f88779..5209256d6 100644 --- a/app/views/notes/_notes_paging_nav.html.erb +++ b/app/views/notes/_notes_paging_nav.html.erb @@ -1,17 +1,36 @@ -

+

diff --git a/app/views/oauth2_applications/_form.html.erb b/app/views/oauth2_applications/_form.html.erb index 51267c069..7fde3e0e7 100644 --- a/app/views/oauth2_applications/_form.html.erb +++ b/app/views/oauth2_applications/_form.html.erb @@ -3,5 +3,5 @@ <%= f.form_group :confidential do %> <%= f.check_box :confidential %> <% end %> -<%= f.collection_check_boxes :scopes, Oauth.scopes(:oauth2 => true, :privileged => current_user.administrator?), :name, :description %> +<%= f.collection_check_boxes :scopes, Oauth.scopes(:privileged => current_user.administrator?), :name, :description %> <%= f.primary %> diff --git a/app/views/old_nodes/timeout.html.erb b/app/views/old_nodes/timeout.html.erb new file mode 100644 index 000000000..61415c650 --- /dev/null +++ b/app/views/old_nodes/timeout.html.erb @@ -0,0 +1,5 @@ +<% set_title(t("browse.timeout.title")) %> + +<%= render "sidebar_header", :title => t("browse.timeout.title") %> + +

<%= t ".sorry", :id => params[:id] %>

diff --git a/app/views/old_relations/timeout.html.erb b/app/views/old_relations/timeout.html.erb new file mode 100644 index 000000000..61415c650 --- /dev/null +++ b/app/views/old_relations/timeout.html.erb @@ -0,0 +1,5 @@ +<% set_title(t("browse.timeout.title")) %> + +<%= render "sidebar_header", :title => t("browse.timeout.title") %> + +

<%= t ".sorry", :id => params[:id] %>

diff --git a/app/views/old_ways/timeout.html.erb b/app/views/old_ways/timeout.html.erb new file mode 100644 index 000000000..61415c650 --- /dev/null +++ b/app/views/old_ways/timeout.html.erb @@ -0,0 +1,5 @@ +<% set_title(t("browse.timeout.title")) %> + +<%= render "sidebar_header", :title => t("browse.timeout.title") %> + +

<%= t ".sorry", :id => params[:id] %>

diff --git a/app/views/redactions/index.html.erb b/app/views/redactions/index.html.erb index b6b6ef46e..26dad64cf 100644 --- a/app/views/redactions/index.html.erb +++ b/app/views/redactions/index.html.erb @@ -10,3 +10,9 @@ <% else %>

<%= t ".empty" %>

<% end %> + +<% if can?(:create, Redaction) %> +
+ <%= link_to t(".new"), new_redaction_path, :class => "btn btn-outline-primary" %> +
+<% end %> diff --git a/app/views/redactions/show.html.erb b/app/views/redactions/show.html.erb index 5b9749a51..fe073d123 100644 --- a/app/views/redactions/show.html.erb +++ b/app/views/redactions/show.html.erb @@ -18,7 +18,7 @@ <%= link_to t(".edit"), edit_redaction_path(@redaction), :class => "btn btn-outline-primary" %> <% end %> <% if can?(:destroy, Redaction) %> - <%= link_to t(".destroy"), @redaction, :method => "delete", :class => "btn btn-outline-danger", :remote => true, :data => { :confirm => t(".confirm") } %> + <%= link_to t(".destroy"), @redaction, :class => "btn btn-outline-danger", :data => { :turbo => true, :turbo_method => "DELETE", :turbo_confirm => t(".confirm") } %> <% end %> <% end %> diff --git a/app/views/relations/timeout.html.erb b/app/views/relations/timeout.html.erb new file mode 100644 index 000000000..61415c650 --- /dev/null +++ b/app/views/relations/timeout.html.erb @@ -0,0 +1,5 @@ +<% set_title(t("browse.timeout.title")) %> + +<%= render "sidebar_header", :title => t("browse.timeout.title") %> + +

<%= t ".sorry", :id => params[:id] %>

diff --git a/app/views/shared/_pagination.html.erb b/app/views/shared/_pagination.html.erb index c8eddcd37..f10d0a9dc 100644 --- a/app/views/shared/_pagination.html.erb +++ b/app/views/shared/_pagination.html.erb @@ -1,9 +1,10 @@ +<% translation_scope ||= "shared.pagination.#{controller.controller_name}" %>