<commit_before>module Paperclip
  # The Upfile module is a convenience module for adding uploaded-file-type methods
  # to the +File+ class. Useful for testing.
  #   user.avatar = File.new("test/test_avatar.jpg")
  module Upfile

    # Infer the MIME-type of the file from the extension.
    def content_type
      type = (self.path.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
      case type
      when %r"jp(e|g|eg)"            then "image/jpeg"
      when %r"tiff?"                 then "image/tiff"
      when %r"png", "gif", "bmp"     then "image/#{type}"
      when "txt"                     then "text/plain"
      when %r"html?"                 then "text/html"
      when "js"                      then "application/js"
      when "csv", "xml", "css"       then "text/#{type}"
      else
        # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
        content_type = (Paperclip.run("file", "-b --mime-type :file", :file => self.path).split(':').last.strip rescue "application/x-#{type}")
        content_type = "application/x-#{type}" if content_type.match(/\(.*?\)/)
        content_type
      end
    end

    # Returns the file's normal name.
    def original_filename
      File.basename(self.path)
    end

    # Returns the size of the file.
    def size
      File.size(self)
    end

    # Returns the hash of the file.
    def fingerprint
      data = self.read
      self.rewind
      Digest::MD5.hexdigest(data)
    end
  end
end

if defined? StringIO
  class StringIO<commit_msg>Avoid reading the whole file into memory in Upfile#fingerprint<commit_after>module Paperclip
  # The Upfile module is a convenience module for adding uploaded-file-type methods
  # to the +File+ class. Useful for testing.
  #   user.avatar = File.new("test/test_avatar.jpg")
  module Upfile

    # Infer the MIME-type of the file from the extension.
    def content_type
      type = (self.path.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
      case type
      when %r"jp(e|g|eg)"            then "image/jpeg"
      when %r"tiff?"                 then "image/tiff"
      when %r"png", "gif", "bmp"     then "image/#{type}"
      when "txt"                     then "text/plain"
      when %r"html?"                 then "text/html"
      when "js"                      then "application/js"
      when "csv", "xml", "css"       then "text/#{type}"
      else
        # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
        content_type = (Paperclip.run("file", "-b --mime-type :file", :file => self.path).split(':').last.strip rescue "application/x-#{type}")
        content_type = "application/x-#{type}" if content_type.match(/\(.*?\)/)
        content_type
      end
    end

    # Returns the file's normal name.
    def original_filename
      File.basename(self.path)
    end

    # Returns the size of the file.
    def size
      File.size(self)
    end

    # Returns the hash of the file.
    def fingerprint
      fingerprint = if self.path
        Digest::MD5.file(self.path).hexdigest
      else
        Digest::MD5.hexdigest(self.read)
      end
      self.rewind
      fingerprint
    end
  end
end

if defined? StringIO
  class StringIO
{'fraction_non_alphanumeric': 0.12356766800867142, 'fraction_numerical': 0.0021678538247135335, 'mean_word_length': 2.08206106870229, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '479071', 'n_tokens_mistral': 1038, 'n_tokens_neox': 1007, 'n_words': 300}