~cytrogen/masto-fe

c66250abf17b4aad1abc1500c14bf9862c078226 — Nick Schonning 2 years ago 9a65389
Autofix Rubocop Regex Style rules (#23690)

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
M .rubocop_todo.yml => .rubocop_todo.yml +0 -46
@@ 1412,52 1412,6 @@ Style/RedundantFetchBlock:
    - 'config/initializers/paperclip.rb'
    - 'config/puma.rb'

# This cop supports safe autocorrection (--autocorrect).
Style/RedundantRegexpCharacterClass:
  Exclude:
    - 'app/lib/link_details_extractor.rb'
    - 'app/lib/tag_manager.rb'
    - 'app/models/domain_allow.rb'
    - 'app/models/domain_block.rb'
    - 'app/services/fetch_oembed_service.rb'
    - 'config/initializers/rack_attack.rb'
    - 'lib/tasks/emojis.rake'
    - 'lib/tasks/mastodon.rake'

# This cop supports safe autocorrection (--autocorrect).
Style/RedundantRegexpEscape:
  Exclude:
    - 'app/lib/webfinger_resource.rb'
    - 'app/models/account.rb'
    - 'app/models/tag.rb'
    - 'app/services/fetch_link_card_service.rb'
    - 'config/initializers/twitter_regex.rb'
    - 'lib/paperclip/color_extractor.rb'
    - 'lib/tasks/mastodon.rake'

# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
  Exclude:
    - 'app/lib/link_details_extractor.rb'
    - 'app/lib/plain_text_formatter.rb'
    - 'app/lib/tag_manager.rb'
    - 'app/lib/text_formatter.rb'
    - 'app/models/account.rb'
    - 'app/models/domain_allow.rb'
    - 'app/models/domain_block.rb'
    - 'app/models/site_upload.rb'
    - 'app/models/tag.rb'
    - 'app/services/backup_service.rb'
    - 'app/services/fetch_oembed_service.rb'
    - 'app/services/search_service.rb'
    - 'config/initializers/rack_attack.rb'
    - 'config/initializers/twitter_regex.rb'
    - 'config/routes.rb'
    - 'lib/mastodon/premailer_webpack_strategy.rb'
    - 'lib/tasks/mastodon.rake'

# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
# AllowedMethods: present?, blank?, presence, try, try!

M app/lib/link_details_extractor.rb => app/lib/link_details_extractor.rb +7 -7
@@ 7,15 7,15 @@ class LinkDetailsExtractor
  # Some publications wrap their JSON-LD data in their <script> tags
  # in commented-out CDATA blocks, they need to be removed before
  # attempting to parse JSON
  CDATA_JUNK_PATTERN = %r{^[\s]*(
    (/\*[\s]*<!\[CDATA\[[\s]*\*/) # Block comment style opening
  CDATA_JUNK_PATTERN = %r{^\s*(
    (/\*\s*<!\[CDATA\[\s*\*/) # Block comment style opening
    |
    (//[\s]*<!\[CDATA\[) # Single-line comment style opening
    (//\s*<!\[CDATA\[) # Single-line comment style opening
    |
    (/\*[\s]*\]\]>[\s]*\*/) # Block comment style closing
    (/\*\s*\]\]>\s*\*/) # Block comment style closing
    |
    (//[\s]*\]\]>) # Single-line comment style closing
  )[\s]*$}x
    (//\s*\]\]>) # Single-line comment style closing
  )\s*$}x

  class StructuredData
    SUPPORTED_TYPES = %w(


@@ 204,7 204,7 @@ class LinkDetailsExtractor
  def host_to_url(str)
    return if str.blank?

    str.start_with?(/https?:\/\//) ? str : "http://#{str}"
    str.start_with?(%r{https?://}) ? str : "http://#{str}"
  end

  def valid_url_or_nil(str, same_origin_only: false)

M app/lib/plain_text_formatter.rb => app/lib/plain_text_formatter.rb +1 -1
@@ 3,7 3,7 @@
class PlainTextFormatter
  include ActionView::Helpers::TextHelper

  NEWLINE_TAGS_RE = /(<br \/>|<br>|<\/p>)+/
  NEWLINE_TAGS_RE = %r{(<br />|<br>|</p>)+}

  attr_reader :text, :local


M app/lib/tag_manager.rb => app/lib/tag_manager.rb +3 -3
@@ 7,18 7,18 @@ class TagManager
  include RoutingHelper

  def web_domain?(domain)
    domain.nil? || domain.gsub(/[\/]/, '').casecmp(Rails.configuration.x.web_domain).zero?
    domain.nil? || domain.delete('/').casecmp(Rails.configuration.x.web_domain).zero?
  end

  def local_domain?(domain)
    domain.nil? || domain.gsub(/[\/]/, '').casecmp(Rails.configuration.x.local_domain).zero?
    domain.nil? || domain.delete('/').casecmp(Rails.configuration.x.local_domain).zero?
  end

  def normalize_domain(domain)
    return if domain.nil?

    uri = Addressable::URI.new
    uri.host = domain.gsub(/[\/]/, '')
    uri.host = domain.delete('/')
    uri.normalized_host
  end


M app/lib/text_formatter.rb => app/lib/text_formatter.rb +1 -1
@@ 5,7 5,7 @@ class TextFormatter
  include ERB::Util
  include RoutingHelper

  URL_PREFIX_REGEX = /\A(https?:\/\/(www\.)?|xmpp:)/
  URL_PREFIX_REGEX = %r{\A(https?://(www\.)?|xmpp:)}

  DEFAULT_REL = %w(nofollow noopener noreferrer).freeze


M app/lib/webfinger_resource.rb => app/lib/webfinger_resource.rb +1 -1
@@ 13,7 13,7 @@ class WebfingerResource
    case resource
    when /\Ahttps?/i
      username_from_url
    when /\@/
    when /@/
      username_from_acct
    else
      raise InvalidRequest

M app/models/account.rb => app/models/account.rb +3 -3
@@ 62,9 62,9 @@ class Account < ApplicationRecord
    trust_level
  )

  USERNAME_RE   = /[a-z0-9_]+([a-z0-9_\.-]+[a-z0-9_]+)?/i
  MENTION_RE    = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[[:word:]\.\-]+[[:word:]]+)?)/i
  URL_PREFIX_RE = /\Ahttp(s?):\/\/[^\/]+/
  USERNAME_RE   = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
  MENTION_RE    = %r{(?<=^|[^/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}i
  URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
  USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i

  include Attachmentable

M app/models/domain_allow.rb => app/models/domain_allow.rb +1 -1
@@ 35,7 35,7 @@ class DomainAllow < ApplicationRecord
    def rule_for(domain)
      return if domain.blank?

      uri = Addressable::URI.new.tap { |u| u.host = domain.gsub(/[\/]/, '') }
      uri = Addressable::URI.new.tap { |u| u.host = domain.delete('/') }

      find_by(domain: uri.normalized_host)
    end

M app/models/domain_block.rb => app/models/domain_block.rb +1 -1
@@ 67,7 67,7 @@ class DomainBlock < ApplicationRecord
    def rule_for(domain)
      return if domain.blank?

      uri      = Addressable::URI.new.tap { |u| u.host = domain.strip.gsub(/[\/]/, '') }
      uri      = Addressable::URI.new.tap { |u| u.host = domain.strip.delete('/') }
      segments = uri.normalized_host.split('.')
      variants = segments.map.with_index { |_, i| segments[i..-1].join('.') }


M app/models/site_upload.rb => app/models/site_upload.rb +1 -1
@@ 43,7 43,7 @@ class SiteUpload < ApplicationRecord

  has_attached_file :file, styles: ->(file) { STYLES[file.instance.var.to_sym] }, convert_options: { all: '-coalesce +profile "!icc,*" +set modify-date +set create-date' }, processors: [:lazy_thumbnail, :blurhash_transcoder, :type_corrector]

  validates_attachment_content_type :file, content_type: /\Aimage\/.*\z/
  validates_attachment_content_type :file, content_type: %r{\Aimage/.*\z}
  validates :file, presence: true
  validates :var, presence: true, uniqueness: true


M app/models/tag.rb => app/models/tag.rb +1 -1
@@ 34,7 34,7 @@ class Tag < ApplicationRecord
  HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)'
  HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}"

  HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_PAT})/i
  HASHTAG_RE = %r{(?:^|[^/)\w])#(#{HASHTAG_NAME_PAT})}i
  HASHTAG_NAME_RE = /\A(#{HASHTAG_NAME_PAT})\z/i
  HASHTAG_INVALID_CHARS_RE = /[^[:alnum:]#{HASHTAG_SEPARATORS}]/


M app/services/backup_service.rb => app/services/backup_service.rb +2 -2
@@ 77,8 77,8 @@ class BackupService < BaseService
        path = m.file&.path
        next unless path

        path = path.gsub(/\A.*\/system\//, '')
        path = path.gsub(/\A\/+/, '')
        path = path.gsub(%r{\A.*/system/}, '')
        path = path.gsub(%r{\A/+}, '')
        download_to_zip(zipfile, m.file, path)
      end


M app/services/fetch_link_card_service.rb => app/services/fetch_link_card_service.rb +1 -1
@@ 7,7 7,7 @@ class FetchLinkCardService < BaseService
  URL_PATTERN = %r{
    (#{Twitter::TwitterText::Regex[:valid_url_preceding_chars]})                                                                #   $1 preceding chars
    (                                                                                                                           #   $2 URL
      (https?:\/\/)                                                                                                             #   $3 Protocol (required)
      (https?://)                                                                                                               #   $3 Protocol (required)
      (#{Twitter::TwitterText::Regex[:valid_domain]})                                                                           #   $4 Domain(s)
      (?::(#{Twitter::TwitterText::Regex[:valid_port_number]}))?                                                                #   $5 Port number (optional)
      (/#{Twitter::TwitterText::Regex[:valid_url_path]}*)?                                                                      #   $6 URL Path and anchor

M app/services/fetch_oembed_service.rb => app/services/fetch_oembed_service.rb +1 -1
@@ 2,7 2,7 @@

class FetchOEmbedService
  ENDPOINT_CACHE_EXPIRES_IN = 24.hours.freeze
  URL_REGEX                 = /(=(http[s]?(%3A|:)(\/\/|%2F%2F)))([^&]*)/i
  URL_REGEX                 = %r{(=(https?(%3A|:)(//|%2F%2F)))([^&]*)}i

  attr_reader :url, :options, :format, :endpoint_url


M app/services/search_service.rb => app/services/search_service.rb +1 -1
@@ 70,7 70,7 @@ class SearchService < BaseService
  end

  def url_query?
    @resolve && /\Ahttps?:\/\//.match?(@query)
    @resolve && %r{\Ahttps?://}.match?(@query)
  end

  def url_resource_results

M config/initializers/rack_attack.rb => config/initializers/rack_attack.rb +3 -3
@@ 79,7 79,7 @@ class Rack::Attack
  end

  throttle('throttle_api_media', limit: 30, period: 30.minutes) do |req|
    req.authenticated_user_id if req.post? && req.path.match?(/\A\/api\/v\d+\/media\z/i)
    req.authenticated_user_id if req.post? && req.path.match?(%r{\A/api/v\d+/media\z}i)
  end

  throttle('throttle_media_proxy', limit: 30, period: 10.minutes) do |req|


@@ 98,8 98,8 @@ class Rack::Attack
    req.throttleable_remote_ip if req.paging_request? && req.unauthenticated?
  end

  API_DELETE_REBLOG_REGEX = /\A\/api\/v1\/statuses\/[\d]+\/unreblog\z/
  API_DELETE_STATUS_REGEX = /\A\/api\/v1\/statuses\/[\d]+\z/
  API_DELETE_REBLOG_REGEX = %r{\A/api/v1/statuses/\d+/unreblog\z}
  API_DELETE_STATUS_REGEX = %r{\A/api/v1/statuses/\d+\z}

  throttle('throttle_api_delete', limit: 30, period: 30.minutes) do |req|
    req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX))

M config/initializers/twitter_regex.rb => config/initializers/twitter_regex.rb +8 -8
@@ 6,8 6,8 @@ module Twitter::TwitterText
  end

  class Regex
    REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}<>\(\)\?]/iou
    REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}\(\)\?!\*"'「」<>;:=\,\.\$%\[\]~&\|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
    REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}<>()?]/iou
    REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}()?!*"'「」<>;:=,.$%\[\]~&|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
    REGEXEN[:valid_url_balanced_parens] = /
      \(
        (?:


@@ 25,20 25,20 @@ module Twitter::TwitterText
      \)
    /iox
    UCHARS = '\u{A0}-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFEF}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}\u{E000}-\u{F8FF}\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}'
    REGEXEN[:valid_url_query_chars] = /[a-z0-9!?\*'\(\);:&=\+\$\/%#\[\]\-_\.,~|@\^#{UCHARS}]/iou
    REGEXEN[:valid_url_query_ending_chars] = /[a-z0-9_&=#\/\-#{UCHARS}]/iou
    REGEXEN[:valid_url_path] = /(?:
    REGEXEN[:valid_url_query_chars] = %r{[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|@\^#{UCHARS}]}iou
    REGEXEN[:valid_url_query_ending_chars] = %r{[a-z0-9_&=#/\-#{UCHARS}]}iou
    REGEXEN[:valid_url_path] = %r{(?:
      (?:
        #{REGEXEN[:valid_general_url_path_chars]}*
        (?:#{REGEXEN[:valid_url_balanced_parens]} #{REGEXEN[:valid_general_url_path_chars]}*)*
        #{REGEXEN[:valid_url_path_ending_chars]}
      )|(?:#{REGEXEN[:valid_general_url_path_chars]}+\/)
    )/iox
      )|(?:#{REGEXEN[:valid_general_url_path_chars]}+/)
    )}iox
    REGEXEN[:valid_url] = %r{
      (                                                                                     #   $1 total match
        (#{REGEXEN[:valid_url_preceding_chars]})                                            #   $2 Preceding character
        (                                                                                   #   $3 URL
          ((?:https?|dat|dweb|ipfs|ipns|ssb|gopher|gemini):\/\/)?                           #   $4 Protocol (optional)
          ((?:https?|dat|dweb|ipfs|ipns|ssb|gopher|gemini)://)?                             #   $4 Protocol (optional)
          (#{REGEXEN[:valid_domain]})                                                       #   $5 Domain(s)
          (?::(#{REGEXEN[:valid_port_number]}))?                                            #   $6 Port number (optional)
          (/#{REGEXEN[:valid_url_path]}*)?                                                  #   $7 URL Path and anchor

M config/routes.rb => config/routes.rb +3 -3
@@ 115,21 115,21 @@ Rails.application.routes.draw do

  get '/:encoded_at(*path)', to: redirect("/@%{path}"), constraints: { encoded_at: /%40/ }

  constraints(username: /[^@\/.]+/) do
  constraints(username: %r{[^@/.]+}) do
    get '/@:username', to: 'accounts#show', as: :short_account
    get '/@:username/with_replies', to: 'accounts#show', as: :short_account_with_replies
    get '/@:username/media', to: 'accounts#show', as: :short_account_media
    get '/@:username/tagged/:tag', to: 'accounts#show', as: :short_account_tag
  end

  constraints(account_username: /[^@\/.]+/) do
  constraints(account_username: %r{[^@/.]+}) do
    get '/@:account_username/following', to: 'following_accounts#index'
    get '/@:account_username/followers', to: 'follower_accounts#index'
    get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status
    get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status
  end

  get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: /([^\/])+?/ }, format: false
  get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: %r{([^/])+?} }, format: false
  get '/settings', to: redirect('/settings/profile')

  draw(:settings)

M lib/mastodon/premailer_webpack_strategy.rb => lib/mastodon/premailer_webpack_strategy.rb +1 -1
@@ 16,7 16,7 @@ module PremailerWebpackStrategy
            Rails.public_path.join(url).read
          end

    css.gsub(/url\(\//, "url(#{asset_host}/")
    css.gsub(%r{url\(/}, "url(#{asset_host}/")
  end

  module_function :load

M lib/paperclip/color_extractor.rb => lib/paperclip/color_extractor.rb +1 -1
@@ 171,7 171,7 @@ module Paperclip
    end

    def palette_from_histogram(result, quantity)
      frequencies       = result.scan(/([0-9]+)\:/).flatten.map(&:to_f)
      frequencies       = result.scan(/([0-9]+):/).flatten.map(&:to_f)
      hex_values        = result.scan(/\#([0-9A-Fa-f]{6,8})/).flatten
      total_frequencies = frequencies.sum.to_f


M lib/tasks/emojis.rake => lib/tasks/emojis.rake +1 -1
@@ 31,7 31,7 @@ def gen_border(codepoint, color)
end

def codepoints_to_filename(codepoints)
  codepoints.downcase.gsub(/\A[0]+/, '').tr(' ', '-')
  codepoints.downcase.gsub(/\A0+/, '').tr(' ', '-')
end

def codepoints_to_unicode(codepoints)

M lib/tasks/mastodon.rake => lib/tasks/mastodon.rake +4 -4
@@ 21,7 21,7 @@ namespace :mastodon do
      env['LOCAL_DOMAIN'] = prompt.ask('Domain name:') do |q|
        q.required true
        q.modify :strip
        q.validate(/\A[a-z0-9\.\-]+\z/i)
        q.validate(/\A[a-z0-9.-]+\z/i)
        q.messages[:valid?] = 'Invalid domain. If you intend to use unicode characters, enter punycode here'
      end



@@ 240,7 240,7 @@ namespace :mastodon do
          end

          env['S3_PROTOCOL'] = env['S3_ENDPOINT'].start_with?('https') ? 'https' : 'http'
          env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(/\Ahttps?:\/\//, '')
          env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(%r{\Ahttps?://}, '')

          env['S3_BUCKET'] = prompt.ask('Minio bucket name:') do |q|
            q.required true


@@ 269,7 269,7 @@ namespace :mastodon do
          end

          env['S3_PROTOCOL'] = env['S3_ENDPOINT'].start_with?('https') ? 'https' : 'http'
          env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(/\Ahttps?:\/\//, '')
          env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(%r{\Ahttps?://}, '')

          env['S3_BUCKET'] = prompt.ask('Storj DCS bucket name:') do |q|
            q.required true


@@ 573,7 573,7 @@ def dotenv_escape(value)

  # As long as the value doesn't include single quotes, we can safely
  # rely on single quotes
  return "'#{value}'" unless /[']/.match?(value)
  return "'#{value}'" unless value.include?("'")

  # If the value contains the string '\n' or '\r' we simply can't use
  # a double-quoted string, because Dotenv will expand \n or \r no