Compare commits
2 commits
43b62eed96
...
8d6eb57fe0
Author | SHA1 | Date | |
---|---|---|---|
8d6eb57fe0 | |||
3013fda863 |
1 changed files with 93 additions and 0 deletions
93
lib/archive.rb
Normal file
93
lib/archive.rb
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
require 'net/http'
|
||||||
|
require 'uri'
|
||||||
|
require 'open3'
|
||||||
|
require 'fileutils'
|
||||||
|
require 'open-uri'
|
||||||
|
|
||||||
|
module Archive
|
||||||
|
MAGIC_NUMBERS = {
|
||||||
|
"\x1F\x8B" => 'gzip',
|
||||||
|
"\x50\x4B\x03\x04" => 'zip',
|
||||||
|
"\x28\xB5\x2F\xFD" => 'zstd',
|
||||||
|
"\xFD\x37\x7A\x58" => 'xz'
|
||||||
|
}
|
||||||
|
|
||||||
|
def self.detect_format_from_url(url)
|
||||||
|
case File.extname(url)
|
||||||
|
when '.gz', '.tgz' then 'gzip'
|
||||||
|
when '.zip' then 'zip'
|
||||||
|
when '.zst' then 'zstd'
|
||||||
|
when '.xz' then 'xz'
|
||||||
|
else nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.detect_format_from_headers(uri)
|
||||||
|
response = Net::HTTP.get_response(uri)
|
||||||
|
content_type = response['content-type']
|
||||||
|
case content_type
|
||||||
|
when /gzip/ then 'gzip'
|
||||||
|
when /zip/ then 'zip'
|
||||||
|
when /zstd/ then 'zstd'
|
||||||
|
when /xz/ then 'xz'
|
||||||
|
else nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.detect_format_from_magic(file_path)
|
||||||
|
File.open(file_path, 'rb') do |f|
|
||||||
|
bytes = f.read(4)
|
||||||
|
MAGIC_NUMBERS.each do |magic, format|
|
||||||
|
return format if bytes.start_with?(magic)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.download_file(uri, output_path)
|
||||||
|
URI.open(uri) do |input|
|
||||||
|
File.open(output_path, 'wb') do |output|
|
||||||
|
IO.copy_stream(input, output)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.extract_archive(file_path, format)
|
||||||
|
case format
|
||||||
|
when 'gzip'
|
||||||
|
system("tar -xzf #{Shellwords.escape(file_path)}")
|
||||||
|
when 'zip'
|
||||||
|
system("unzip #{Shellwords.escape(file_path)}")
|
||||||
|
when 'zstd'
|
||||||
|
system("unzstd #{Shellwords.escape(file_path)}")
|
||||||
|
when 'xz'
|
||||||
|
system("tar -xJf #{Shellwords.escape(file_path)}")
|
||||||
|
else
|
||||||
|
raise "Unsupported archive format: #{format}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.fetch_and_extract(url)
|
||||||
|
uri = URI.parse(url)
|
||||||
|
file_name = File.basename(uri.path)
|
||||||
|
tmp_path = "/tmp/#{file_name}"
|
||||||
|
|
||||||
|
format = detect_format_from_url(url)
|
||||||
|
puts "format #{format}"
|
||||||
|
download_file(uri, tmp_path)
|
||||||
|
|
||||||
|
unless format
|
||||||
|
format = detect_format_from_headers(uri)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless format
|
||||||
|
format = detect_format_from_magic(tmp_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
raise "Could not determine archive format" unless format
|
||||||
|
|
||||||
|
extract_archive(tmp_path, format)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Example usage:
|
||||||
|
# fetch_and_extract("https://codeberg.org/forgejo/forgejo/releases/download/v12.0.1/forgejo-12.0.1-linux-amd64.xz")
|
Loading…
Add table
Add a link
Reference in a new issue