Files
danbooru/app/logical/danbooru.rb
evazion d7d3427488 Fix #5363: Inconsistent order of files from zip uploads.
Upload files in natural order rather than archive order when uploading archive files.

Before files were listed in the same order they appeared in the zip file. This could be in
non-alphabetical order, or even with files from different directories interleaved between each
other. Now files are uploaded in natural order, which is alphabetical order but with numbers sorted
properly, so that `file-9.jpg` appears before `file-10.jpg`.
2022-12-02 18:04:45 -06:00

33 lines
1.0 KiB
Ruby

# frozen_string_literal: true
# The Danbooru module contains miscellaneous global helper functions.
module Danbooru
module EnumerableMethods
extend self
# Sort a list of strings in natural order, e.g. with "file-2.txt" before "file-10.txt".
#
# @see https://en.wikipedia.org/wiki/Natural_sort_order
# @see https://stackoverflow.com/a/15170063
#
# @param list [Enumerable<String>] The list to sort.
# @return [Array] The sorted list.
def natural_sort(list)
natural_sort_by(list, &:to_s)
end
# Sort a list of objects in natural order. The block should return a sort key, which is compared in natural order.
#
# @param list [Enumerable<Object>] The list to sort.
# @return [Array] The sorted list.
def natural_sort_by(list, &block)
list.sort_by do |element|
# "file-2022-10-01.txt" => ["file-", 2022, "-", 10, "-", 1, ".txt"]
yield(element).to_s.split(/(\d+)/).map { |str| str.match?(/\A\d+\z/) ? str.to_i : str }
end
end
end
extend EnumerableMethods
end