<commit_before>require 'active_model'
require 'active_support/i18n'
require 'public_suffix'
I18n.load_path += Dir[File.dirname(__FILE__) + "/locale/*.yml"]

module ActiveModel
  module Validations
    class UrlValidator < ActiveModel::EachValidator
      RESERVED_OPTIONS = [:schemes, :no_local]

      def initialize(options)
        options.reverse_merge!(schemes: %w(http https))
        options.reverse_merge!(message: :url)
        options.reverse_merge!(no_local: false)
        options.reverse_merge!(public_suffix: false)

        super(options)
      end

      def validate_each(record, attribute, value)
        schemes = [*options.fetch(:schemes)].map(&:to_s)
        begin
          uri = URI.parse(value)
          validate_suffix = !options.fetch(:public_suffix) || (uri && uri.host && PublicSuffix.valid?(uri.host, :default_rule => nil))
          validate_no_local = !options.fetch(:no_local) || (uri && uri.host && uri.host.include?('.'))
          unless uri && uri.host && schemes.include?(uri.scheme) && validate_no_local && validate_suffix
            record.errors.add(attribute, options.fetch(:message), value: value)
          end
        rescue URI::InvalidURIError
          record.errors.add(attribute, :url, filtered_options(value))
        end
      end

      protected

      def filtered_options(value)
        filtered = options.except(*RESERVED_OPTIONS)
        filtered[:value] = value
        filtered
      end
    end

    module ClassMethods
      # Validates whether the value of the specified attribute is valid url.
      #
      #   class Unicorn
      #     include ActiveModel::Validations
      #     attr_accessor :homepage, :ftpsite
      #     validates_url :homepage, allow_blank: true
      #     validates_url :ftpsite, schemes: ['ftp']
      #   end
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "is not a valid URL").
      # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
      # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
      # * <tt>:schemes</tt> - Array of URI schemes to validate against. (default is +['http', 'https']+)

      def validates_url(*attr_names)
        validates_with UrlValidator, _merge_attributes(attr_names)
      end
    end
  end
end
<commit_msg>Slightly clean up validation code<commit_after>require 'active_model'
require 'active_support/i18n'
require 'public_suffix'
I18n.load_path += Dir[File.dirname(__FILE__) + "/locale/*.yml"]

module ActiveModel
  module Validations
    class UrlValidator < ActiveModel::EachValidator
      RESERVED_OPTIONS = [:schemes, :no_local]

      def initialize(options)
        options.reverse_merge!(schemes: %w(http https))
        options.reverse_merge!(message: :url)
        options.reverse_merge!(no_local: false)
        options.reverse_merge!(public_suffix: false)

        super(options)
      end

      def validate_each(record, attribute, value)
        schemes = [*options.fetch(:schemes)].map(&:to_s)
        begin
          uri = URI.parse(value)
          host = uri && uri.host
          scheme = uri && uri.scheme

          valid_suffix = !options.fetch(:public_suffix) || (host && PublicSuffix.valid?(host, :default_rule => nil))
          valid_no_local = !options.fetch(:no_local) || (host && host.include?('.'))
          valid_scheme = host && scheme && schemes.include?(scheme)

          unless valid_scheme && valid_no_local && valid_suffix
            record.errors.add(attribute, options.fetch(:message), value: value)
          end
        rescue URI::InvalidURIError
          record.errors.add(attribute, :url, filtered_options(value))
        end
      end

      protected

      def filtered_options(value)
        filtered = options.except(*RESERVED_OPTIONS)
        filtered[:value] = value
        filtered
      end
    end

    module ClassMethods
      # Validates whether the value of the specified attribute is valid url.
      #
      #   class Unicorn
      #     include ActiveModel::Validations
      #     attr_accessor :homepage, :ftpsite
      #     validates_url :homepage, allow_blank: true
      #     validates_url :ftpsite, schemes: ['ftp']
      #   end
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "is not a valid URL").
      # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
      # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
      # * <tt>:schemes</tt> - Array of URI schemes to validate against. (default is +['http', 'https']+)

      def validates_url(*attr_names)
        validates_with UrlValidator, _merge_attributes(attr_names)
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.11269614835948645, 'fraction_numerical': 0.0016303240269003464, 'mean_word_length': 2.7987616099071206, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2928353', 'n_tokens_mistral': 1448, 'n_tokens_neox': 1412, 'n_words': 364}