DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Flickr To Desktop Background

09.07.2007
| 2931 views |
  • submit to reddit
        // description of your code here

#!/usr/bin/env ruby

########################################
# config
########################################

groups = ['trees']
flick_api_key = 'cc0880a9d309466758fecb6557d7040b'

# proxy just comment out to disable, types: http, sspi
#http_proxy = {:host=> 'name', :port => 80, :type => :sspi}


# temp files for imagemagick
p1 = 'c:/tmp/img.jpg'
p2 = 'c:\\tmp\\img.bmp'

# Imagemagick path
# http://www.imagemagick.org/script/binary-releases.php#windows
# Recommended package: ImageMagick-6.3.5-6-Q8-windows-static.exe
# convert.exe is needed only, so Imagemagick can be uninstalled.
imagick_path = 'convert.exe'

# images with larger/smaller width will be skipped
skip_small = 1000
skip_big = 2100

########################################
# code
########################################

require 'Win32API'
require 'net/http'
require 'win32/sspi'
require 'json'
require 'yaml'
require "win32/open3"
require "win32/process"

def parse_url(url)
  m = /(?:.*?\/\/)(.*?)(\/.*)/.match(url)
  [ m[1] , m[2] ]
end

class NetWrap
  def initialize(p_type = nil, p_host = nil, p_port = nil)
    if !p_type
      @conn = Net::HTTP
    else
      @conn = Net::HTTP.Proxy(p_host, p_port)
    end
    @p_type = p_type
  end
  
  def download(url)
    site, path = parse_url(url)
    data = ''
    @conn.start(site) do |http|
      if @p_type && @p_type == :sspi
        resp, data = Win32::SSPI::NegotiateAuth.proxy_auth_get(http, path)
      else
        resp, data = http.get(path)
      end
    end
    return data
  end
end

class FlickR
  def initialize(apikey, netw)
    @apikey = apikey
    @netw = netw
  end
  
  def request(api_meth,params = {})
    url = "http://api.flickr.com/services/rest/?method=#{api_meth}&api_key=#{@apikey}&format=json"
    params.each {|key,val| url << "&#{key}=#{val}"}
    res = @netw.download(url)
    JSON.parse(res['jsonFlickrApi('.size..-(');'.size)])
  end
  
  def group_photos(id)
    request('flickr.groups.pools.getPhotos', :group_id => id)['photos']['photo']
  end
  
  def group_lookup(name)
    request('flickr.urls.lookupGroup', :url => "http://flickr.com/groups/#{name}/pool/")['group']['id']
  end

  def photo_urls(id)
    request('flickr.photos.getSizes', :photo_id => id)['sizes']['size']
  end
  
  def photo_best(id, width)
    sizes = photo_urls(id).sort {|a,b| a['width'].to_i <=> b['width'].to_i}
    return sizes.find {|x| x['width'].to_i > width} || sizes.last()
  end
end

class ImgList
  def initialize(cfgname)
    @cfg = cfgname
    @saw = {}
    begin
      if f = open(@cfg,'r')
        @saw = YAML.load(f)
        f.close()
        cnt = 0
        @saw.each {|key,val| cnt += 1 if val[1]}
      end
    rescue
    end
  end
  
  def save()
    if f = open(@cfg,'w+')
      f.write(@saw.to_yaml)
      f.close()
    end
  end
  
  def next()
    img = @saw.detect {|x| !x[1]}
    return img[0] if img
    img
  end
  
  def add(url)
    if !@saw.has_key?(url)
      @saw[url] = false
    end
  end
  
  def mark(url)
    @saw[url] = true
  end
  
  def reset()
    @saw.each {|key,val| @saw[key] = false}
  end
end

if defined?(http_proxy)
  netw = NetWrap.new(http_proxy[:type], http_proxy[:host], http_proxy[:port])
else
  netw = NetWrap.new()
end

scr_w = Win32API.new("user32", "GetSystemMetrics", ['I'] , 'I').call(0)

il = ImgList.new('wpcache.yaml')

photo_url = il.next()

if !photo_url
  fr = FlickR.new(flick_api_key, netw)
  groups.each do |group|
    fr.group_photos(fr.group_lookup(group)).each do |x|
      next if !x['ispublic']
      photo = fr.photo_best(x['id'],scr_w)
      next if skip_small && photo['width'].to_i < skip_small
      next if skip_big && photo['width'].to_i > skip_big
      url = photo['source']
      il.add(url)
    end
  end  
  photo_url = il.next()
end

if !photo_url
  il.reset()
  photo_url = il.next()
end

il.mark(photo_url)
il.save()

open(p1,'wb+') { |f|  f.write(netw.download(photo_url)) }

cmdline = "#{imagick_path} -resize #{scr_w} #{p1} bmp3:#{p2}"
Process::waitpid2(Open4::popen4(cmdline)[3])

Win32API.new("user32", "SystemParametersInfo", ['L','L','P','L'] , 'L').Call(20,0,p2,3)
    

Comments

Snippets Manager replied on Fri, 2007/07/27 - 3:04pm

Really great one, respect!