igfetch - ruby

rane 17.08.06 23:05

lataa annetun käyttäjän kaikki kuvat irc-galleriasta

 Tekstiversio  Arvo: 2 (2 ääntä)  Äänestä: +  -
# igfetch.rb by rane | 17.8.2006
# usage: ruby igfetch.rb [USERNAME]
# downloads the pictures of an user given as an argument from IRC-Galleria.net

IGFETCH_DIR = "IGfetch"

require 'net/http'
require 'cgi'
require 'fileutils'

class IGfetch
    def initialize(dir)
        @dir = dir
        @ig_uri = "http://irc-galleria.net/"
        @nick = get_nick
        set_archive_uri
        @default_archive_body = get_default_archive_body
        @count_album = get_album_arr.size
        @total = {:data => 0, :images => 0}
    end

    def output(str, status=nil)
        unless status.nil?
            @status = status
        end
        
        if defined? @status
            print "\r" + @status + ": " + str.ljust(40)
        else
            print "\r" + str.ljust(40)
        end
        STDOUT.flush
    end

    def get_nick
        unless ARGV.size > 0
            puts "Usage: ruby #{File.basename(__FILE__)} [USERNAME]"
            exit
        end
        ARGV.first
    end

    def set_archive_uri
        @archive_uri = @ig_uri + "archive.php?nick=#{@nick}"
    end

    def get_default_archive_body
        response = Net::HTTP.get_response(URI.parse(@archive_uri))
        
        if response.body.length > 0
            output("Acquiring archive page")
            tmp = Net::HTTP.get(URI.parse(@archive_uri))
            puts
            return tmp
        elsif response['location'] =~ /view.php\?nick=/ 
            @nick = $'
            set_archive_uri
            get_default_archive_body
        else
            output("User not found!")
            exit
        end
    end

    def get_album_arr # returns the IDs and names of all albums as hashes in an array | [{:name => album_name, :id => album_id}, .. ]
        album_arr = []
        @default_archive_body.scan(/archive\.php\?nick=#{@nick}&album_id=(\d+)" title="(.+?)"/).uniq.each do |album|
            album_arr << {:name => album[1], :id => album[0]}
        end
        album_arr << {:name => get_default_album_name, :id => nil} # add default album to the array
    end

    def get_default_album_name # returns the name of the default album
        @default_archive_body.scan(/<p><strong>(.+?)<\/strong><\/p>/).flatten.first
    end                                                                                                                                    
        
    def get_view_id_arr(album_id=nil, page=0) # returns the IDs of view-pages of an album
        if album_id.nil?
            @default_archive_body.scan(/view\.php\?nick=#{@nick}&amp;image_id=(\d+)/).uniq.flatten
        else
            view_id_arr = []
            archive_body = Net::HTTP.get(URI.parse(@archive_uri+"&album_id=#{album_id}&page=#{page}"))
            view_id_arr << archive_body.scan(/view\.php\?nick=#{@nick}&amp;image_id=(\d+)/).uniq.flatten
            if archive_body =~ %r{&amp;album_id=#{album_id}&amp;page=([0-9])" class="nextlink"}
                view_id_arr << get_view_id_arr(album_id, page=$1)
            end
            view_id_arr.flatten
        end
    end

    def get_img_uri(view_id) # returns the URI of an image of a view-page
        view_body = Net::HTTP.get(URI.parse(@ig_uri+"view.php?nick="+@nick+"&image_id="+view_id))
        view_body.scan(%r{http://.+?\.irc-galleria\.net/[a-z]{1}/images[0-9]+[\d/]+\d+\.jpg}).first
    end

    def get_img_uri_arr(view_id_arr) # returns URIs of the images of view-pages listed in an array
        img_uri_arr = []
        view_id_arr.each do |view_id|
            img_uri_arr << get_img_uri(view_id)
        end
        img_uri_arr
    end
    
    def gather # returns { album_name_1 => img_uri_arr, album_name_2 => img_uri_arr }]
        album_hash = Hash.new
        get_album_arr.each_with_index do |album_arr, index|
            output(album_arr[:name] + " [" + (index+1).to_s + "/" + (@count_album).to_s + "]", "Parsing albums for images")
            album_hash[album_arr[:name]] = get_img_uri_arr(get_view_id_arr(album_arr[:id]))
        end
        puts
        album_hash
    end

    def download(album_hash) # eats hashes
        start = Time.now
        album_hash.each do |album_name, img_uri_arr|
            img_uri_arr.each_with_index do |img_uri, index|
                img_name = img_uri.split("/").last  
                output(album_name + " ["+ (index+1).to_s + "/" + img_uri_arr.size.to_s + "]", "Downloading images")
                create_file("#{@dir}/#{@nick}/#{album_name.tr(':', '')}/", img_name, Net::HTTP.get(URI.parse(img_uri)))
            end
            puts
        end
        total_time = Time.now.to_f - start.to_f
        
        puts
        puts "Fetched #{humanize(@total[:data])} of images in #{"%.1f" % total_time} seconds"
    end

    def humanize(bytes)
        if bytes < 1024
            return (bytes).to_s + " B"
        elsif bytes > (1024*1024)
            return "%.2f" % (bytes/1024.0/1024.0).to_s + " MiB"       
        elsif bytes > 1024
            return (bytes/1024.0).round.to_s + " KiB"
        end
    end

    def create_file(dir_path, file, body)
        FileUtils.mkdir_p dir_path
        File.open(dir_path + file, "wb") { |fh| fh.write(body) }
        @total[:data] += File.size(dir_path + file)
        @total[:images] += 1
    end

    def display(album_hash) # for debug
        puts
        album_hash.each do |album_name, img_uri_arr|
            puts "\n" + album_name
            puts img_uri_arr
        end
    end
end

igfetch = IGfetch.new("igfetch")
igfetch.download(igfetch.gather)

editoitu: 13:54 18.8.06
rane 23:09 17.8.06 
rane@kahiseva:~$ ruby igfetch.rb weicco
Acquiring archive page
Parsing albums for images: Oletusalbumi [1/1]
Downloading images: Oletusalbumi [12/12]

Fetched 569 KiB of images in 7.5 seconds

rane@kahiseva:~$ ls -R IGfetch
IGfetch:
weicco

IGfetch/weicco:
Oletusalbumi

IGfetch/weicco/Oletusalbumi:
1164542.jpg   18395791.jpg  2648924.jpg   28739719.jpg  37849834.jpg  631457.jpg
14347241.jpg  25810664.jpg  28559119.jpg  31752443.jpg  6227384.jpg   857353.jpg
Jonathan 00:52 18.8.06 
Kirjoitit n+1 riviä koodia ladataksesi weicon kuvat? That's KINKY!
rane 01:18 18.8.06 
indeed :)
T.M. 12:13 18.8.06 
Taas näitä mitäänsanomattomia nimiä >__<
litra 10:57 24.4.07 
mitä väliä nimellä kunhan kuvaus on selkeä?