<commit_before>module Mongoff
  module GridFs
    class File < Mongoff::Record

      include FileFormatter

      def initialize(model, document = nil, new_record = true)
        raise "Illegal file model #{model}" unless model.is_a?(FileModel)
        super
      end

      def to_s
        filename
      end

      def chunk_model
        orm_model.chunk_model
      end

      def data
        if @new_data
          if @new_data.is_a?(String)
            @new_data
          else
            @new_data.rewind
            data = @new_data.read
            @new_data.rewind
            data
          end
        else
          @data ||=
            begin
              data = ''
              chunks.ascending(:n).each { |chunk| data << chunk.data.data }
              data
            end
        end
      end

      def data=(string_or_readable)
        @new_data = string_or_readable
      end

      attr_accessor :encoding

      def []=(field, value)
        if field.to_s.to_sym == :data
          self.data = value
        else
          value = super
          case :field
          when :filename
            @custom_filename = value
          when :contentType
            @custom_content_type = value
          end
        end
      end

      def decode(data)
        case encoding
        when  'base64', 'strict_base64', 'urlsafe_base64'
          Base64.send(encoding.gsub('base', 'decode'), data)
        else
          data
        end
      end

      def save(options = {})
        self[:metadata] = options[:metadata] || {}
        self[:chunkSize] = FileModel::MINIMUM_CHUNK_SIZE if self[:chunkSize] < FileModel::MINIMUM_CHUNK_SIZE
        temporary_file = nil
        new_chunks_ids =
          if @new_data
            readable =
              if @new_data.is_a?(String)
                temporary_file = Tempfile.new('file_')
                temporary_file.binmode
                temporary_file.write(decode(@new_data))
                temporary_file.rewind
                Cenit::Utility::Proxy.new(temporary_file, original_filename: filename || options[:filename] || options[:default_filename])
              else
                @new_data
              end
            if !options[:valid_data] && (file_data_errors = orm_model.data_type.validate_file(self)).present?
              errors.add(:base, "Invalid file data: #{file_data_errors.to_sentence}")
            else
              create_temporary_chunks(readable, options)
            end
          else
            errors.add(:data, "can't be nil") if new_record?
          end
        temporary_file.close if temporary_file
        [:filename, :contentType].each { |property| self[property] = options[property] unless self[property].present? }
        if errors.blank? && super
          if new_chunks_ids
            chunks.delete_many
            chunk_model.all.any_in(id: new_chunks_ids).update_many('$set' => { files_id: id })<commit_msg>Extension for default file names<commit_after>module Mongoff
  module GridFs
    class File < Mongoff::Record

      include FileFormatter

      def initialize(model, document = nil, new_record = true)
        raise "Illegal file model #{model}" unless model.is_a?(FileModel)
        super
      end

      def to_s
        filename
      end

      def chunk_model
        orm_model.chunk_model
      end

      def data
        if @new_data
          if @new_data.is_a?(String)
            @new_data
          else
            @new_data.rewind
            data = @new_data.read
            @new_data.rewind
            data
          end
        else
          @data ||=
            begin
              data = ''
              chunks.ascending(:n).each { |chunk| data << chunk.data.data }
              data
            end
        end
      end

      def data=(string_or_readable)
        @new_data = string_or_readable
      end

      attr_accessor :encoding

      def []=(field, value)
        if field.to_s.to_sym == :data
          self.data = value
        else
          value = super
          case field
          when :filename
            @custom_filename = value
          when :contentType
            @custom_content_type = value
          end
        end
      end

      def decode(data)
        case encoding
        when 'base64', 'strict_base64', 'urlsafe_base64'
          Base64.send(encoding.gsub('base', 'decode'), data)
        else
          data
        end
      end

      def save(options = {})
        self[:metadata] = options[:metadata] || {}
        self[:chunkSize] = FileModel::MINIMUM_CHUNK_SIZE if self[:chunkSize] < FileModel::MINIMUM_CHUNK_SIZE
        temporary_file = nil
        new_chunks_ids =
          if @new_data
            readable =
              if @new_data.is_a?(String)
                ext =
                  if (content_type = options[:content_type] || self.contentType) &&
                    (types = MIME::Types[content_type]).present? &&
                    (type = types.detect { |t| t.extensions.present? })
                    type.extensions.first
                  else
                    ''
                  end
                temporary_file = Tempfile.new(['file_', ".#{ext}"])
                temporary_file.binmode
                temporary_file.write(decode(@new_data))
                temporary_file.rewind
                Cenit::Utility::Proxy.new(temporary_file, original_filename: filename || options[:filename] || options[:default_filename])
              else
                @new_data
              end
            if !options[:valid_data] && (file_data_errors = orm_model.data_type.validate_file(self)).present?
              errors.add(:base, "Invalid file data: #{file_data_errors.to_sentence}")
            else
              create_temporary_chunks(readable, options)
            end
          else
            errors.add(:data, "can't be nil") if new_record?
          end
        temporary_file.close if temporary_file
        [:filename, :contentType].each { |property| self[property] = options[property] unless self[property].present? }
        if errors.blank? && super
          if new_chunks_ids
            chunks.delete_many
            chunk_model.all.any_in(id: new_chunks_ids).update_many('$set' => { files_id: id })
{'fraction_non_alphanumeric': 0.08922289734569876, 'fraction_numerical': 0.0025583626479053407, 'mean_word_length': 1.6160602258469259, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, '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': '2822566', 'n_tokens_mistral': 1747, 'n_tokens_neox': 1715, 'n_words': 369}