From 2332d2802254af5d77ff4808a69b42523fdae4c3 Mon Sep 17 00:00:00 2001 From: Peter Bhat Harkins Date: Thu, 28 Dec 2023 18:35:30 -0600 Subject: [PATCH] bump gems except commonmarker (#1234) lot of irritating churn out of standardrb here --- .ruby-version | 2 +- .standard.yml | 9 +- Gemfile | 2 +- Gemfile.lock | 86 ++++++++--------- app/controllers/application_controller.rb | 2 +- app/controllers/avatars_controller.rb | 4 +- app/controllers/categories_controller.rb | 2 +- app/controllers/hats_controller.rb | 2 +- app/controllers/login_controller.rb | 2 +- app/controllers/messages_controller.rb | 4 +- app/controllers/signup_controller.rb | 2 +- app/controllers/stories_controller.rb | 6 +- app/controllers/tags_controller.rb | 2 +- app/helpers/stories_helper.rb | 16 +--- app/helpers/users_helper.rb | 14 +-- ...fication.rb => ban_notification_mailer.rb} | 2 +- ...ail_message.rb => email_message_mailer.rb} | 2 +- .../{email_reply.rb => email_reply_mailer.rb} | 2 +- ...word_reset.rb => password_reset_mailer.rb} | 2 +- app/models/comment.rb | 18 ++-- app/models/hat.rb | 6 +- app/models/hat_request.rb | 4 +- app/models/keystore.rb | 2 +- app/models/message.rb | 4 +- app/models/mod_note.rb | 2 +- app/models/moderation.rb | 2 +- app/models/read_ribbon.rb | 8 +- app/models/replying_comment.rb | 2 +- app/models/story.rb | 10 +- app/models/story_repository.rb | 4 +- app/models/user.rb | 16 ++-- .../notify.text.erb | 0 app/views/comments/_threads.html.erb | 2 +- .../notify.text.erb | 0 .../mention.text.erb | 0 .../reply.text.erb | 0 .../password_reset_link.text.erb | 0 app/views/stories/_form.html.erb | 2 +- app/views/users/show.html.erb | 4 +- config/application.rb | 6 +- config/brakeman.ignore | 96 +++++++++---------- config/environments/production.rb | 2 +- config/initializers/00_zeitwerk.rb | 2 +- config/sitemap.rb | 2 +- db/seeds.rb | 20 ++-- extras/markdowner.rb | 2 + lib/tasks/fake_data.rake | 8 +- script/mail_new_activity.rb | 12 +-- script/send_new_webmentions | 2 +- script/sync_twitter_users | 2 +- spec/factories/user.rb | 2 +- spec/features/comment_spec.rb | 2 +- spec/features/homepage_spec.rb | 4 +- spec/features/submit_story_spec.rb | 6 +- ...ply_spec.rb => email_reply_mailer_spec.rb} | 14 +-- spec/models/category_spec.rb | 2 +- spec/models/email_parser_spec.rb | 2 +- spec/models/replying_comment_spec.rb | 2 +- spec/models/story_spec.rb | 4 +- spec/models/tag_spec.rb | 2 +- spec/requests/login_spec.rb | 2 +- 61 files changed, 223 insertions(+), 222 deletions(-) rename app/mailers/{ban_notification.rb => ban_notification_mailer.rb} (87%) rename app/mailers/{email_message.rb => email_message_mailer.rb} (85%) rename app/mailers/{email_reply.rb => email_reply_mailer.rb} (96%) rename app/mailers/{password_reset.rb => password_reset_mailer.rb} (80%) rename app/views/{ban_notification => ban_notification_mailer}/notify.text.erb (100%) rename app/views/{email_message => email_message_mailer}/notify.text.erb (100%) rename app/views/{email_reply => email_reply_mailer}/mention.text.erb (100%) rename app/views/{email_reply => email_reply_mailer}/reply.text.erb (100%) rename app/views/{password_reset => password_reset_mailer}/password_reset_link.text.erb (100%) rename spec/mailers/{email_reply_spec.rb => email_reply_mailer_spec.rb} (81%) diff --git a/.ruby-version b/.ruby-version index be94e6f5..15a27998 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.3.0 diff --git a/.standard.yml b/.standard.yml index 40eea15e..20a43366 100644 --- a/.standard.yml +++ b/.standard.yml @@ -1,10 +1,17 @@ ignore: + - '**/*': + # there's no "don't delete these records or shit will be on fire" option, + # just various "sure automatically destroy lots of data yolo" options + - Rails/HasManyOrHasOneDependent + # is a multimaster db while needing microsecond accurate sorting really 'standard' + - Rails/OrderById # it's mad about the class variables and I don't want to risk the refactor now - 'extras/**/*': - Naming/VariableName - # migrations are not live code; ignore those before standardrb + # migrations are not live code - 'db/migrate/201*' - 'db/migrate/2020*' + - 'db/migrate/2022*' - 'db/migrate/202309*' plugins: diff --git a/Gemfile b/Gemfile index b8b9d1a6..adb35b8b 100644 --- a/Gemfile +++ b/Gemfile @@ -26,7 +26,7 @@ gem "rotp" gem "rqrcode" # parsing -gem "commonmarker" +gem "commonmarker", "<1" gem "htmlentities" gem "pdf-reader" gem "nokogiri" diff --git a/Gemfile.lock b/Gemfile.lock index 092e7b7e..c1f554f1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,13 +80,13 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) afm (0.2.2) ast (2.4.2) attr_extras (7.1.0) - base64 (0.1.1) - bcrypt (3.1.19) + base64 (0.2.0) + bcrypt (3.1.20) benchmark-perf (0.6.0) bigdecimal (3.1.5) brakeman (6.1.1) @@ -124,19 +124,19 @@ GEM exception_notification (4.5.0) actionmailer (>= 5.2, < 8) activesupport (>= 5.2, < 8) - execjs (2.9.0) - factory_bot (6.2.1) + execjs (2.9.1) + factory_bot (6.4.4) activesupport (>= 5.0.0) - factory_bot_rails (6.2.0) - factory_bot (~> 6.2.0) + factory_bot_rails (6.4.2) + factory_bot (~> 6.4) railties (>= 5.0.0) - faker (3.2.1) + faker (3.2.2) i18n (>= 1.8.11, < 2) - ffi (1.15.5) + ffi (1.16.3) flamegraph (0.9.5) globalid (1.2.1) activesupport (>= 6.1) - hashdiff (1.0.1) + hashdiff (1.1.0) hashery (2.1.2) hashie (5.0.0) htmlentities (4.3.4) @@ -146,7 +146,7 @@ GEM irb (1.11.0) rdoc reline (>= 0.3.8) - json (2.6.3) + json (2.7.1) language_server-protocol (3.17.0.3) lint_roller (1.1.0) listen (3.8.0) @@ -168,7 +168,7 @@ GEM minitest (5.20.0) mutex_m (0.2.0) mysql2 (0.5.5) - net-imap (0.4.8) + net-imap (0.4.9) date net-protocol net-pop (0.1.2) @@ -178,10 +178,10 @@ GEM net-smtp (0.4.0) net-protocol nio4r (2.7.0) - nokogiri (1.15.5) + nokogiri (1.16.0) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.15.5-x86_64-linux) + nokogiri (1.16.0-x86_64-linux) racc (~> 1.4) oauth (1.1.0) oauth-tty (~> 1.0, >= 1.0.1) @@ -190,14 +190,14 @@ GEM oauth-tty (1.0.5) version_gem (~> 1.1, >= 1.1.1) optimist (3.1.0) - parallel (1.23.0) - parser (3.2.2.3) + parallel (1.24.0) + parser (3.2.2.4) ast (~> 2.4.1) racc parslet (2.0.0) patience_diff (1.2.0) optimist (~> 3.0) - pdf-reader (2.11.0) + pdf-reader (2.12.0) Ascii85 (~> 1.0) afm (~> 0.2.1) hashery (~> 2.0) @@ -205,14 +205,14 @@ GEM ttfunk psych (5.1.2) stringio - public_suffix (5.0.3) - puma (6.3.1) + public_suffix (5.0.4) + puma (6.4.0) nio4r (~> 2.0) racc (1.7.3) rack (3.0.8) rack-attack (6.7.0) rack (>= 1.0, < 4) - rack-mini-profiler (3.1.1) + rack-mini-profiler (3.3.0) rack (>= 1.2.0) rack-session (2.0.0) rack (>= 3.0.0) @@ -258,9 +258,9 @@ GEM rb-readline (0.5.5) rdoc (6.6.2) psych (>= 4.0.0) - redis-client (0.17.0) + redis-client (0.19.1) connection_pool - regexp_parser (2.8.1) + regexp_parser (2.8.3) reline (0.4.1) io-console (~> 0.5) rexml (3.2.6) @@ -277,7 +277,7 @@ GEM rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-rails (6.0.3) + rspec-rails (6.1.0) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -286,28 +286,28 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.12.1) - rubocop (1.56.3) - base64 (~> 0.1.1) + rubocop (1.59.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) - rubocop-performance (1.19.0) - rubocop (>= 1.7.0, < 2.0) - rubocop-ast (>= 0.4.0) - rubocop-rails (2.20.2) + rubocop-performance (1.20.1) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) + rubocop-rails (2.23.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) - rubocop-sorbet (0.7.3) + rubocop-ast (>= 1.30.0, < 2.0) + rubocop-sorbet (0.7.6) rubocop (>= 0.90.0) ruby-progressbar (1.13.0) ruby-rc4 (0.1.5) @@ -318,7 +318,7 @@ GEM scenic-mysql_adapter (1.0.1) mysql2 scenic (>= 1.4.0) - sidekiq (7.1.4) + sidekiq (7.2.0) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) @@ -342,21 +342,21 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) stackprof (0.2.25) - standard (1.31.1) + standard (1.33.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.56.2) + rubocop (~> 1.59.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.2) + standard-performance (~> 1.3) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.2.0) + standard-performance (1.3.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.19.0) - standard-rails (0.2.0) + rubocop-performance (~> 1.20.1) + standard-rails (1.0.0) lint_roller (~> 1.0) - rubocop-rails (~> 2.20.2) + rubocop-rails (~> 2.23.1) standard-sorbet (0.0.2) lint_roller (~> 1.1) rubocop-sorbet (~> 0.7.0) @@ -373,7 +373,7 @@ GEM concurrent-ruby (~> 1.0) uglifier (4.2.0) execjs (>= 0.3.0, < 3) - unicode-display_width (2.4.2) + unicode-display_width (2.5.0) vcr (6.2.0) version_gem (1.1.3) webmock (3.19.1) @@ -400,7 +400,7 @@ DEPENDENCIES brakeman byebug capybara - commonmarker + commonmarker (< 1) database_cleaner exception_notification factory_bot_rails diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ff8e3294..02d38c25 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -31,7 +31,7 @@ class ApplicationController < ActionController::Base def agent_is_spider? ua = request.env["HTTP_USER_AGENT"].to_s - (ua == "" || ua.match(/(Google|bing|Slack|Twitter)bot|Slurp|crawler|Feedly|FeedParser|RSS/)) + ua == "" || ua.match(/(Google|bing|Slack|Twitter)bot|Slurp|crawler|Feedly|FeedParser|RSS/) end def authenticate_user diff --git a/app/controllers/avatars_controller.rb b/app/controllers/avatars_controller.rb index f588e72f..bc8f16df 100644 --- a/app/controllers/avatars_controller.rb +++ b/app/controllers/avatars_controller.rb @@ -5,7 +5,7 @@ class AvatarsController < ApplicationController ALLOWED_SIZES = [16, 32, 100, 200].freeze - CACHE_DIR = "#{Rails.root}/public/avatars/".freeze + CACHE_DIR = Rails.public_path.join("avatars/").to_s.freeze def expire expired = 0 @@ -13,7 +13,7 @@ class AvatarsController < ApplicationController Dir.entries(CACHE_DIR).select { |f| f.match(/\A#{@user.username}-(\d+)\.png\z/) }.each do |f| - Rails.logger.debug "Expiring #{f}" + Rails.logger.debug { "Expiring #{f}" } File.unlink("#{CACHE_DIR}/#{f}") expired += 1 rescue => e diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index c1a1360b..811b0ad2 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -9,7 +9,7 @@ class CategoriesController < ApplicationController end def create - category = Category.create(category_params) + category = Category.create!(category_params) if category.valid? flash[:success] = "Category #{category.category} has been created" redirect_to tags_path diff --git a/app/controllers/hats_controller.rb b/app/controllers/hats_controller.rb index f7d18d22..727e266b 100644 --- a/app/controllers/hats_controller.rb +++ b/app/controllers/hats_controller.rb @@ -16,7 +16,7 @@ class HatsController < ApplicationController @hat_groups = {} - Hat.active.includes(:user).each do |h| + Hat.active.includes(:user).find_each do |h| @hat_groups[h.hat] ||= [] @hat_groups[h.hat].push h end diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index 27a19c12..d7bf5d4a 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -63,7 +63,7 @@ class LoginController < ApplicationController if !user.password_digest.to_s.match(/^\$2a\$#{BCrypt::Engine::DEFAULT_COST}\$/o) user.password = user.password_confirmation = params[:password].to_s - user.save + user.save! end if user.has_2fa? && !Rails.env.development? diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 4689a86b..b5bec6c0 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -86,7 +86,7 @@ class MessagesController < ApplicationController if @message.recipient_user_id == @user.id @message.has_been_read = true - @message.save + @message.save! end Rails.cache.delete("user:#{@user.id}:unread_replies") end @@ -144,7 +144,7 @@ class MessagesController < ApplicationController def keep_as_new @message.has_been_read = false - @message.save + @message.save! redirect_to "/messages" end diff --git a/app/controllers/signup_controller.rb b/app/controllers/signup_controller.rb index 809de77f..68c1d009 100644 --- a/app/controllers/signup_controller.rb +++ b/app/controllers/signup_controller.rb @@ -61,7 +61,7 @@ class SignupController < ApplicationController end if @new_user.save - @invitation&.update(used_at: Time.current, new_user: @new_user) + @invitation&.update!(used_at: Time.current, new_user: @new_user) session[:u] = @new_user.session_token flash[:success] = "Welcome to #{Rails.application.name}, " \ "#{@new_user.username}!" diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 5b3f7c96..7303d8ba 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -21,7 +21,7 @@ class StoriesController < ApplicationController if @story.valid? && !(@story.already_posted_recently? && !@story.seen_previous) if @story.save - ReadRibbon.where(user: @user, story: @story).first_or_create + ReadRibbon.where(user: @user, story: @story).first_or_create! return redirect_to @story.comments_path end end @@ -437,7 +437,7 @@ class StoriesController < ApplicationController @story = if @user.is_moderator? Story.where(short_id: params[:story_id] || params[:id]).first else - Story.where(user_id: @user.id, short_id: (params[:story_id] || params[:id])).first + Story.where(user_id: @user.id, short_id: params[:story_id] || params[:id]).first end if !@story @@ -471,7 +471,7 @@ class StoriesController < ApplicationController def track_story_reads @story = Story.where(short_id: params[:id]).first! - @ribbon = ReadRibbon.where(user: @user, story: @story).first_or_create + @ribbon = ReadRibbon.where(user: @user, story: @story).first_or_create! yield @ribbon.bump end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 41341d10..76a4d581 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -30,7 +30,7 @@ class TagsController < ApplicationController def create @title = "Create Tag" tag = Tag.create(tag_params) - if tag.valid? + if tag.persisted? flash[:success] = "Tag #{tag.tag} has been created" redirect_to tags_path else diff --git a/app/helpers/stories_helper.rb b/app/helpers/stories_helper.rb index eb7b4359..1850a50e 100644 --- a/app/helpers/stories_helper.rb +++ b/app/helpers/stories_helper.rb @@ -1,19 +1,19 @@ # typed: false module StoriesHelper - def show_guidelines? - if !@user + def show_guidelines?(user) + if !user return true end - if @user.stories_submitted_count <= 5 + if user.stories_submitted_count <= 5 return true end if Moderation.joins(:story) .where( "stories.user_id = ? AND moderations.created_at > ?", - @user.id, + user.id, 5.days.ago ).exists? return true @@ -21,12 +21,4 @@ module StoriesHelper false end - - def is_unread?(comment) - if !@user || !@ribbon - return false - end - - (comment.created_at > @ribbon.updated_at) && (comment.user_id != @user.id) - end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index e4eb253a..cf84e348 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -1,7 +1,7 @@ # typed: false module UsersHelper - def stories_submitted_content(showing_user) + def stories_submitted_content(user, showing_user) tag = showing_user.most_common_story_tag stories_submitted = showing_user.stories_submitted_count @@ -11,7 +11,7 @@ module UsersHelper capture do concat link_to(stories_displayed, newest_by_user_path(showing_user)) - concat(" (+#{stories_deleted} deleted)") if user_is_moderator? && stories_deleted > 0 + concat(" (+#{stories_deleted} deleted)") if user&.is_moderator? && stories_deleted > 0 if tag concat ", most commonly tagged " @@ -20,13 +20,13 @@ module UsersHelper end end - def comments_posted_content(showing_user) + def comments_posted_content(user, showing_user) comments_deleted = showing_user.comments_deleted_count capture do concat link_to(showing_user.comments_posted_count, user_threads_path(showing_user)) - if user_is_moderator? && comments_deleted > 0 + if user&.is_moderator? && comments_deleted > 0 concat " (+#{comments_deleted} deleted)" end end @@ -62,10 +62,4 @@ module UsersHelper "(#{user.karma})" end end - - private - - def user_is_moderator? - @user&.is_moderator? - end end diff --git a/app/mailers/ban_notification.rb b/app/mailers/ban_notification_mailer.rb similarity index 87% rename from app/mailers/ban_notification.rb rename to app/mailers/ban_notification_mailer.rb index e48b291b..e35fbc34 100644 --- a/app/mailers/ban_notification.rb +++ b/app/mailers/ban_notification_mailer.rb @@ -1,6 +1,6 @@ # typed: false -class BanNotification < ApplicationMailer +class BanNotificationMailer < ApplicationMailer def notify(user, banner, reason) @banner = banner @reason = reason diff --git a/app/mailers/email_message.rb b/app/mailers/email_message_mailer.rb similarity index 85% rename from app/mailers/email_message.rb rename to app/mailers/email_message_mailer.rb index de65d53b..b0a19db8 100644 --- a/app/mailers/email_message.rb +++ b/app/mailers/email_message_mailer.rb @@ -1,6 +1,6 @@ # typed: false -class EmailMessage < ApplicationMailer +class EmailMessageMailer < ApplicationMailer def notify(message, user) @message = message @user = user diff --git a/app/mailers/email_reply.rb b/app/mailers/email_reply_mailer.rb similarity index 96% rename from app/mailers/email_reply.rb rename to app/mailers/email_reply_mailer.rb index 41a51c38..17bf00a0 100644 --- a/app/mailers/email_reply.rb +++ b/app/mailers/email_reply_mailer.rb @@ -1,6 +1,6 @@ # typed: false -class EmailReply < ApplicationMailer +class EmailReplyMailer < ApplicationMailer def reply(comment, user) @comment = comment @user = user diff --git a/app/mailers/password_reset.rb b/app/mailers/password_reset_mailer.rb similarity index 80% rename from app/mailers/password_reset.rb rename to app/mailers/password_reset_mailer.rb index 29f43166..03041699 100644 --- a/app/mailers/password_reset.rb +++ b/app/mailers/password_reset_mailer.rb @@ -1,6 +1,6 @@ # typed: false -class PasswordReset < ApplicationMailer +class PasswordResetMailer < ApplicationMailer def password_reset_link(user, ip) @user = user @ip = ip diff --git a/app/models/comment.rb b/app/models/comment.rb index 19013074..4392cbf7 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -109,7 +109,7 @@ class Comment < ApplicationRecord Comment.all.find_each do |c| c.markeddown_comment = c.generated_markeddown_comment - c.save(validate: false) + c.save!(validate: false) end Comment.record_timestamps = true @@ -194,7 +194,7 @@ class Comment < ApplicationRecord return false unless parent_comment_id return false if user.is_moderator? - parent_comment_ids = parent_comment.parents.pluck(:id).append(parent_comment.id) + parent_comment_ids = parent_comment.parents.ids.append(parent_comment.id) flag_count = Vote.comments_flags(parent_comment_ids).count commenter_flag_count = Vote.comments_flags(parent_comment_ids, user).count # double-count author delay = (2 + flag_count + commenter_flag_count).minutes @@ -205,7 +205,7 @@ class Comment < ApplicationRecord return false if recent.blank? wait = ActionController::Base.helpers - .distance_of_time_in_words(Time.now, (recent.created_at + delay)) + .distance_of_time_in_words(Time.zone.now, (recent.created_at + delay)) Rails.logger.info "breaks_speed_limit: #{user.username} replying to https://lobste.rs/c/#{parent_comment.short_id} parent_comment_ids (#{parent_comment_ids.join(" ")}) flags #{flag_count} commenter_flag_count #{commenter_flag_count} delay #{delay} delay.ago #{delay.ago} recent #{recent.id}" errors.add( :comment, @@ -247,12 +247,12 @@ class Comment < ApplicationRecord m.reason = reason end - m.save + m.save! User.update_counters user_id, karma: (votes.count * -2) end - save(validate: false) + save!(validate: false) Comment.record_timestamps = true story.update_cached_columns @@ -268,7 +268,7 @@ class Comment < ApplicationRecord if u.email_mentions? begin - EmailReply.mention(self, u).deliver_now + EmailReplyMailer.mention(self, u).deliver_now rescue => e Rails.logger.error "error e-mailing #{u.email}: #{e}" end @@ -307,7 +307,7 @@ class Comment < ApplicationRecord users_following_thread.each do |u| if u.email_replies? begin - EmailReply.reply(self, u).deliver_now + EmailReplyMailer.reply(self, u).deliver_now rescue => e Rails.logger.error "error e-mailing #{u.email}: #{e}" end @@ -581,11 +581,11 @@ class Comment < ApplicationRecord m.comment_id = id m.moderator_user_id = user.id m.action = "undeleted comment" - m.save + m.save! end end - save(validate: false) + save!(validate: false) Comment.record_timestamps = true story.update_cached_columns diff --git a/app/models/hat.rb b/app/models/hat.rb index c9956e02..d03db02b 100644 --- a/app/models/hat.rb +++ b/app/models/hat.rb @@ -29,11 +29,11 @@ class Hat < ApplicationRecord m.action = "Revoked hat \"#{hat}\": #{reason}" m.save! - destroy + destroy! end def to_html_label - hl = (link.present? && link.match(/^https?:\/\//)) + hl = link.present? && link.match(/^https?:\/\//) h = " e Rails.logger.error "error e-mailing #{recipient.email}: #{e}" end diff --git a/app/models/mod_note.rb b/app/models/mod_note.rb index 92941dab..c973caaf 100644 --- a/app/models/mod_note.rb +++ b/app/models/mod_note.rb @@ -11,7 +11,7 @@ class ModNote < ApplicationRecord inverse_of: :mod_notes scope :recent, -> { where("created_at >= ?", 1.week.ago).order("created_at desc") } - scope :for, ->(user) { includes(:moderator).where("user_id = ?", user).order("created_at desc") } + scope :for, ->(user) { includes(:moderator).where(user_id: user).order("created_at desc") } validates :note, :markeddown_note, presence: true, length: {maximum: 65_535} diff --git a/app/models/moderation.rb b/app/models/moderation.rb index 96264614..788586f9 100644 --- a/app/models/moderation.rb +++ b/app/models/moderation.rb @@ -84,7 +84,7 @@ class Moderation < ApplicationRecord m.body << "\n" \ "*This is an automated message.*" - m.save + m.save! end protected diff --git a/app/models/read_ribbon.rb b/app/models/read_ribbon.rb index 09015c8e..20e592af 100644 --- a/app/models/read_ribbon.rb +++ b/app/models/read_ribbon.rb @@ -4,6 +4,12 @@ class ReadRibbon < ApplicationRecord belongs_to :user belongs_to :story + def is_unread? comment + return false if !user + + (comment.created_at > updated_at) && (comment.user_id != user.id) + end + # don't add callbacks to this model; for performance the read tracking in # StoriesController uses .bump and RepliesController uses update_all, etc. @@ -28,7 +34,7 @@ class ReadRibbon < ApplicationRecord # save without callbacks, validation, or transaction def bump if new_record? - save + save! else update_column(:updated_at, Time.now.utc) end diff --git a/app/models/replying_comment.rb b/app/models/replying_comment.rb index b560d8e5..2a5e5364 100644 --- a/app/models/replying_comment.rb +++ b/app/models/replying_comment.rb @@ -13,7 +13,7 @@ class ReplyingComment < ApplicationRecord scope :unread_replies_for, ->(user_id) { for_user(user_id).where(is_unread: true) } scope :comment_replies_for, ->(user_id) { for_user(user_id).where.not(parent_comment_id: nil) } - scope :story_replies_for, ->(user_id) { for_user(user_id).where("parent_comment_id is null") } + scope :story_replies_for, ->(user_id) { for_user(user_id).where(parent_comment_id: nil) } protected diff --git a/app/models/story.rb b/app/models/story.rb index 895db2f8..c6a79abb 100644 --- a/app/models/story.rb +++ b/app/models/story.rb @@ -99,7 +99,7 @@ class Story < ApplicationRecord user.nil? ? none : joins(:savings).merge(SavedStory.by(user)) } scope :to_tweet, -> { - hottest(nil, Tag.where(tag: "meta").pluck(:id)) + hottest(nil, Tag.where(tag: "meta").ids) .where(twitter_id: nil) .where("score >= 2") .where("created_at >= ?", 2.days.ago) @@ -153,9 +153,9 @@ class Story < ApplicationRecord attr_writer :fetched_response before_validation :assign_short_id_and_score, on: :create - before_create :assign_initial_hotness before_save :log_moderation before_save :fix_bogus_chars + before_create :assign_initial_hotness after_create :mark_submitter, :record_initial_upvote after_save :update_cached_columns, :update_story_text @@ -591,7 +591,7 @@ class Story < ApplicationRecord }.join(", ") m.reason = moderation_reason - m.save + m.save! self.is_moderated = true end @@ -614,7 +614,7 @@ class Story < ApplicationRecord end def merge_story_short_id=(sid) - self.merged_story_id = sid.present? ? Story.where(short_id: sid).pluck(:id).first : nil + self.merged_story_id = sid.present? ? Story.where(short_id: sid).pick(:id) : nil end def merge_story_short_id @@ -676,7 +676,7 @@ class Story < ApplicationRecord st.each do |tagging| if !new_tag_names_a.include?(tagging.tag.tag) - tagging.destroy + tagging.destroy! end end diff --git a/app/models/story_repository.rb b/app/models/story_repository.rb index b8b9428c..f41bd545 100644 --- a/app/models/story_repository.rb +++ b/app/models/story_repository.rb @@ -7,7 +7,7 @@ class StoryRepository end def categories(cats) - tagged_story_ids = Tagging.select(:story_id).where(tag_id: Tag.where(category: cats).pluck(:id)) + tagged_story_ids = Tagging.select(:story_id).where(tag_id: Tag.where(category: cats).select(:id)) Story.base(@user).positive_ranked.where(id: tagged_story_ids).order(created_at: :desc) end @@ -28,7 +28,7 @@ class StoryRepository def active Story.base(@user) - .where.not(id: Story.hidden_by(@user).pluck(:id)) + .where.not(id: Story.hidden_by(@user).select(:id)) .filter_tags(@params[:exclude_tags] || []) .select('stories.*, ( select max(comments.id) diff --git a/app/models/user.rb b/app/models/user.rb index d4ec4646..0d68d209 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -52,7 +52,7 @@ class User < ApplicationRecord through: :votes, source: :story has_many :hats, dependent: :destroy - has_many :wearable_hats, -> { where("doffed_at is null") }, + has_many :wearable_hats, -> { where(doffed_at: nil) }, class_name: "Hat", inverse_of: :user @@ -184,7 +184,7 @@ class User < ApplicationRecord h = super(only: attrs) h[:avatar_url] = avatar_url - h[:invited_by_user] = User.where(id: invited_by_user_id).pluck(:username).first + h[:invited_by_user] = User.where(id: invited_by_user_id).pick(:username) if github_username.present? h[:github_username] = github_username @@ -264,7 +264,7 @@ class User < ApplicationRecord self.banned_by_user_id = banner.id self.banned_reason = reason - BanNotification.notify(self, banner, reason) unless deleted_at? + BanNotificationMailer.notify(self, banner, reason) unless deleted_at? delete! m = Moderation.new @@ -375,11 +375,11 @@ class User < ApplicationRecord sent_messages.each do |m| m.deleted_by_author = true - m.save + m.save! end received_messages.each do |m| m.deleted_by_recipient = true - m.save + m.save! end invitations.destroy_all @@ -396,11 +396,11 @@ class User < ApplicationRecord User.transaction do sent_messages.each do |m| m.deleted_by_author = false - m.save + m.save! end received_messages.each do |m| m.deleted_by_recipient = false - m.save + m.save! end self.deleted_at = nil @@ -449,7 +449,7 @@ class User < ApplicationRecord self.password_reset_token = "#{Time.current.to_i}-#{Utils.random_str(30)}" save! - PasswordReset.password_reset_link(self, ip).deliver_now + PasswordResetMailer.password_reset_link(self, ip).deliver_now end def has_2fa? diff --git a/app/views/ban_notification/notify.text.erb b/app/views/ban_notification_mailer/notify.text.erb similarity index 100% rename from app/views/ban_notification/notify.text.erb rename to app/views/ban_notification_mailer/notify.text.erb diff --git a/app/views/comments/_threads.html.erb b/app/views/comments/_threads.html.erb index 80da5412..4cf54c0a 100644 --- a/app/views/comments/_threads.html.erb +++ b/app/views/comments/_threads.html.erb @@ -27,7 +27,7 @@ show_story ||= @story.try(:id) != comment.story_id # show merge icon only on story page when merged was_merged = @story && (@story.id != comment.story_id) - is_unread = is_unread?(comment) + is_unread = @ribbon&.is_unread?(comment) %> <%#heinous_inline_partial(comments/_comment.html.erb)%> diff --git a/app/views/email_message/notify.text.erb b/app/views/email_message_mailer/notify.text.erb similarity index 100% rename from app/views/email_message/notify.text.erb rename to app/views/email_message_mailer/notify.text.erb diff --git a/app/views/email_reply/mention.text.erb b/app/views/email_reply_mailer/mention.text.erb similarity index 100% rename from app/views/email_reply/mention.text.erb rename to app/views/email_reply_mailer/mention.text.erb diff --git a/app/views/email_reply/reply.text.erb b/app/views/email_reply_mailer/reply.text.erb similarity index 100% rename from app/views/email_reply/reply.text.erb rename to app/views/email_reply_mailer/reply.text.erb diff --git a/app/views/password_reset/password_reset_link.text.erb b/app/views/password_reset_mailer/password_reset_link.text.erb similarity index 100% rename from app/views/password_reset/password_reset_link.text.erb rename to app/views/password_reset_mailer/password_reset_link.text.erb diff --git a/app/views/stories/_form.html.erb b/app/views/stories/_form.html.erb index 3ffb8f1e..80e8ab8c 100644 --- a/app/views/stories/_form.html.erb +++ b/app/views/stories/_form.html.erb @@ -76,7 +76,7 @@ Please don't use this to promote the story, summarize the post, or explain why y See the guidelines below for more." %> - <%= tag.details class: "boxline actions", open: show_guidelines? ? true : nil do %> + <%= tag.details class: "boxline actions", open: show_guidelines?(@user) ? true : nil do %> Story submission guidelines