130 lines
3 KiB
Ruby
Executable file
130 lines
3 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
|
|
# Download imgur.com galleries easily
|
|
#
|
|
# Requirements:
|
|
# gem install nokogiri
|
|
#
|
|
# Usage:
|
|
# ruby imgur.rb [url of gallery] [directory to download into] [namespace for files]
|
|
#
|
|
# Example:
|
|
# ruby imgur.rb http://imgur.com/a/npV94 battlefield3 scenery
|
|
# All files will be downloaded into battlefield3 with filenames in the pattern of
|
|
# scenery-[number].jpg
|
|
|
|
|
|
require 'nokogiri'
|
|
require 'open-uri'
|
|
require 'date'
|
|
require 'fileutils'
|
|
require 'optparse'
|
|
require 'pp'
|
|
require "shellwords"
|
|
|
|
|
|
def album_url origin_url
|
|
url = URI.parse origin_url
|
|
|
|
url.hostname = case url.hostname
|
|
when /(.*\.)?imgur.com/ then "imgur.com"
|
|
else raise "ERROR: unknown url hostname !"
|
|
end
|
|
|
|
url.path = case url.path
|
|
when /^\/a\/(\S+).*?/ then
|
|
'/a/' + $1 + '/layout/blog'
|
|
else raise "ERROR: unknown url path !"
|
|
end
|
|
|
|
puts "Fixed url #{url}"
|
|
return url
|
|
end
|
|
|
|
def parse_cmdline args
|
|
options = {}
|
|
OptionParser.new do |opts|
|
|
opts.banner = "Usage: #{File.basename $0} [options]"
|
|
|
|
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
|
options[:verbose] = v
|
|
end
|
|
|
|
opts.on("-z", "--[no-]zip", "Compress album to cbz (zip)") do |v|
|
|
options[:zip] = v
|
|
end
|
|
|
|
opts.on("-f", "--[no-]force", "Force overwrite in case file(s) exists") do |v|
|
|
options[:force] = v
|
|
end
|
|
end.parse! args
|
|
return options
|
|
end
|
|
|
|
options = parse_cmdline ARGV
|
|
|
|
#pp options
|
|
#pp ARGV
|
|
#exit 0
|
|
|
|
images = []
|
|
now = Time.now
|
|
url = album_url(ARGV[0])
|
|
directory = ( defined?(ARGV[1]) ? ARGV[1] : nil )
|
|
#namespace = ( defined?(ARGV[2]) ? ARGV[2] : "image" )
|
|
namespace = "image"
|
|
|
|
# filter url
|
|
|
|
page = Nokogiri::HTML(open url)
|
|
if directory.nil? then
|
|
directory = page.title.strip.gsub(/\//,'-')
|
|
directory = "#{directory} (#{url.path.split('/')[2]})"
|
|
end
|
|
directory = "#{now.year}#{sprintf("%02d", now.month)}/#{directory}"
|
|
|
|
page.search('.thumb-title').each do |image|
|
|
uri = URI.parse(image.attributes['data-src'].value.gsub(/s.jpg/, '.jpg'))
|
|
uri.scheme ||= "http"
|
|
images << uri.to_s
|
|
end
|
|
|
|
destination_exist = false
|
|
if options[:zip] and File.exist?(directory + ".cbz")
|
|
destination_exist = true
|
|
elsif (
|
|
not options[:zip] and
|
|
FileTest.directory? directory and
|
|
FileTest.file? "#{directory}/.imguralbum"
|
|
) then
|
|
destination_exist = true
|
|
end
|
|
|
|
if destination_exist and not options[:force] then
|
|
STDERR.puts "Destination already exists (use --force to overwrite)"
|
|
exit 1
|
|
end
|
|
|
|
unless FileTest.directory? directory then
|
|
puts "Creating #{directory}"
|
|
FileUtils.mkdir_p directory
|
|
end
|
|
|
|
puts "Downloading images into #{directory}...\n\n"
|
|
|
|
images.each_with_index do |image, i|
|
|
indexstr = sprintf("%04d", i)
|
|
puts "Downloading #{image} as #{namespace}-#{indexstr}.jpg..."
|
|
file = open(image)
|
|
File.open("#{directory}/#{namespace}-#{indexstr}.jpg", 'w') do |f|
|
|
f.write file.read
|
|
end
|
|
end
|
|
FileUtils.touch "#{directory}/.imguralbum"
|
|
|
|
if options[:zip] then
|
|
%x{zip -r #{directory.shellescape}.cbz #{directory.shellescape}}
|
|
FileUtils.rm_rf directory
|
|
end
|
|
|
|
puts "\nDone."
|