diff --git a/app/logical/file_type_detector.rb b/app/logical/file_type_detector.rb index 797ace84d..9c4cb2245 100644 --- a/app/logical/file_type_detector.rb +++ b/app/logical/file_type_detector.rb @@ -55,8 +55,33 @@ class FileTypeDetector # https://aomediacodec.github.io/av1-avif/#brands-overview when /\A....ftyp(?:avif|avis)/ :avif + + # https://www.loc.gov/preservation/digital/formats/fdd/fdd000354.shtml#sign + # https://en.wikipedia.org/wiki/ZIP_(file_format) + # XXX Does not detect self-extracting archives when /\APK\x03\x04/ :zip + + # https://docs.fileformat.com/compression/7z/#file-signature + # https://py7zr.readthedocs.io/en/latest/archive_format.html#signature + # https://www.loc.gov/preservation/digital/formats/fdd/fdd000539.shtml#sign + # https://en.wikipedia.org/wiki/7z + # XXX Does not detect self-extracting archives + when /\A7z\xbc\xaf\x27\x1c/n + :"7z" + + # Rar 1.5 to 4.0 + # https://www.rarlab.com/technote.htm#rarsign + # https://www.loc.gov/preservation/digital/formats/fdd/fdd000450.shtml#sign + # https://en.wikipedia.org/wiki/RAR_(file_format) + # XXX Does not detect self-extracting archives + when /\ARar!\x1a\x07\x00/n + :rar + + # Rar 5.0+ + when /\ARar!\x1a\x07\x01\x00/n + :rar + else :bin end diff --git a/test/files/archive/ugoira.7z b/test/files/archive/ugoira.7z new file mode 100644 index 000000000..60214e217 Binary files /dev/null and b/test/files/archive/ugoira.7z differ diff --git a/test/files/archive/ugoira.rar b/test/files/archive/ugoira.rar new file mode 100644 index 000000000..e6db164fe Binary files /dev/null and b/test/files/archive/ugoira.rar differ diff --git a/test/files/archive/ugoira.tar.7z b/test/files/archive/ugoira.tar.7z new file mode 100644 index 000000000..e6c7033b6 Binary files /dev/null and b/test/files/archive/ugoira.tar.7z differ diff --git a/test/files/archive/ugoira.zip b/test/files/archive/ugoira.zip new file mode 100644 index 000000000..463bed1c8 Binary files /dev/null and b/test/files/archive/ugoira.zip differ diff --git a/test/unit/danbooru_archive_test.rb b/test/unit/danbooru_archive_test.rb index b07b38e68..a86fd1c8a 100644 --- a/test/unit/danbooru_archive_test.rb +++ b/test/unit/danbooru_archive_test.rb @@ -75,6 +75,27 @@ class DanbooruArchiveTest < ActiveSupport::TestCase filenames.each { |filename| assert_equal(true, File.exist?(filename)) } end end + + should "work with a .zip file" do + Danbooru::Archive.extract!("test/files/archive/ugoira.zip") do |dir, filenames| + assert_equal(5, filenames.size) + filenames.each { |filename| assert_equal(true, File.exist?(filename)) } + end + end + + should "work with a .rar file" do + Danbooru::Archive.extract!("test/files/archive/ugoira.rar") do |dir, filenames| + assert_equal(5, filenames.size) + filenames.each { |filename| assert_equal(true, File.exist?(filename)) } + end + end + + should "work with a .7z file" do + Danbooru::Archive.extract!("test/files/archive/ugoira.7z") do |dir, filenames| + assert_equal(5, filenames.size) + filenames.each { |filename| assert_equal(true, File.exist?(filename)) } + end + end end context "#uncompressed_size method" do @@ -92,9 +113,20 @@ class DanbooruArchiveTest < ActiveSupport::TestCase end context "#format method" do - should "work" do - archive = Danbooru::Archive.open!("test/files/ugoira.zip") - assert_equal("ZIP 2.0 (uncompressed)", archive.format) + should "detect the file type" do + assert_equal("ZIP 2.0 (uncompressed)", Danbooru::Archive.open("test/files/archive/ugoira.zip").format) + assert_equal("RAR5", Danbooru::Archive.open("test/files/archive/ugoira.rar").format) + assert_equal("7-Zip", Danbooru::Archive.open("test/files/archive/ugoira.7z").format) + assert_equal("7-Zip", Danbooru::Archive.open("test/files/archive/ugoira.tar.7z").format) + end + end + + context "#file_ext method" do + should "detect the file extension" do + assert_equal(:zip, Danbooru::Archive.open("test/files/archive/ugoira.zip").file_ext) + assert_equal(:rar, Danbooru::Archive.open("test/files/archive/ugoira.rar").file_ext) + assert_equal(:"7z", Danbooru::Archive.open("test/files/archive/ugoira.7z").file_ext) + assert_equal(:"7z", Danbooru::Archive.open("test/files/archive/ugoira.tar.7z").file_ext) end end