RubyZip устанавливает временные метки файла - PullRequest
0 голосов
/ 10 мая 2018

Я целый день колотил по этому поводу, может быть, вы можете помочь? Я заархивировал файл с помощью RubyZip, и мне нужно установить время создания / обновления / изменения этого файла на определенное время в часовом поясе (что зависит от часового пояса клиента, который у меня есть в переменной @time_zone).

Я знаю, что это, скорее всего, супер неверно, и я взял эту волшебную строку 'UT\x5\0\x3\250$\r@Ux\0\0' из файла тестов RubyZip, и я понятия не имею, что это такое. ЛОЛ. Однако - я заставил это работать теперь на моем ПК. Это действительно архивирует файл и устанавливает правильные временные метки для него в соответствии с указанным часовым поясом.

НО - он не работает на сервере приложений, который в качестве часового пояса ОС находится в часовом поясе UTC. Он генерирует другое время для файлов, которые не совпадают.

Вот как далеко я это сделал:

def save_to_zip(file_path)
  Zip::OutputStream.open(file_path) do |out|
    @sheets.each do |csv|
      name = csv.name
      extra = time_for_zip
      out.put_next_entry("#{name}.#{@file_extension}", nil, extra)
      tmpfile = csv.tmpfile
      tmpfile.close
      source = File.open(tmpfile.path, 'r')
      source.each do |line|
        out.write(line)
      end
    end
  end
end

def time_for_zip
  return nil if @time_zone.blank?

  timestamp = Zip::ExtraField.new('UT\x5\0\x3\250$\r@Ux\0\0')
  localtime_str = Time.now.in_time_zone(@time_zone).strftime("%Y-%m-%dT%H:%M:%S")
  dos_time_in_store_tz = ::Zip::DOSTime.parse(localtime_str)

  timestamp['UniversalTime'].ctime = dos_time_in_store_tz
  timestamp['UniversalTime'].atime = dos_time_in_store_tz
  timestamp['UniversalTime'].mtime = dos_time_in_store_tz

  timestamp
end

Подскажите, пожалуйста, как правильно установить время файла в zip-файле?

Действительно ценится ...

Maris

1 Ответ

0 голосов
/ 11 мая 2018

Решено так:

    def save_to_zip(file_path)
  Zip::OutputStream.open(file_path) do |out|
    @sheets.each do |csv|
      name = csv.name
      tmpfile = csv.tmpfile
      tmpfile.close
      source = File.open(tmpfile.path, 'r')
      zip_entry = Zip::Entry.new(out, "#{name}.#{@file_extension}", nil, nil, nil, nil, nil, nil, time_for_zip(source.ctime))
      out.put_next_entry(zip_entry)
      source.each do |line|
        out.write(line)
      end
    end
  end
end

def time_for_zip(file_time)
  return Zip::DOSTime.at(file_time) if @time_zone.blank?

  Zip::DOSTime.parse(file_time.utc.in_time_zone(@time_zone).strftime("%Y-%m-%d %H:%M:%S"))
end

Престижность этой темы: https://github.com/rubyzip/rubyzip/pull/40

...