| 1 | # show photo image on Flickr.com |
|---|
| 2 | # |
|---|
| 3 | # usage: |
|---|
| 4 | # flickr(photo_id[, size[, place]]) |
|---|
| 5 | # - photo_id: The id of the photo to show. |
|---|
| 6 | # - size: Size of photo. (optional) |
|---|
| 7 | # Choose from square, thumbnail, small, medium, or large. |
|---|
| 8 | # - place: class name of img element. default is 'flickr'. |
|---|
| 9 | # |
|---|
| 10 | # flickr_left(photo_id[, size]) |
|---|
| 11 | # |
|---|
| 12 | # flickr_right(photo_id[, size]) |
|---|
| 13 | # |
|---|
| 14 | # options configurable through settings: |
|---|
| 15 | # @conf['flickr.apikey'] : a key for access Flickr API |
|---|
| 16 | # @conf['flickr.default_size'] : default image size |
|---|
| 17 | # |
|---|
| 18 | # Copyright (c) MATSUOKA Kohei <http://www.machu.jp/> |
|---|
| 19 | # Distributed under the GPL |
|---|
| 20 | # |
|---|
| 21 | require 'open-uri' |
|---|
| 22 | require 'digest/md5' |
|---|
| 23 | require 'rexml/document' |
|---|
| 24 | |
|---|
| 25 | def flickr(photo_id, size = nil, place = 'flickr') |
|---|
| 26 | unless @conf['flickr.apikey'] || @conf['flickr.apikey'].empty? |
|---|
| 27 | return '[ERROR] flickr.rb: API Key is not specified.' |
|---|
| 28 | end |
|---|
| 29 | size ||= @conf['flickr.default_size'] || 'small' |
|---|
| 30 | photo = flickr_photo_info(photo_id.to_s, size) |
|---|
| 31 | unless photo |
|---|
| 32 | return '[ERROR] flickr.rb: failed to get photo.' |
|---|
| 33 | end |
|---|
| 34 | |
|---|
| 35 | if @cgi.mobile_agent? |
|---|
| 36 | body = %Q|<a href="#{photo[:src]}">#{photo[:title]}</a>| |
|---|
| 37 | else |
|---|
| 38 | body = %Q|<a href="#{photo[:page]}"><img title="#{photo[:title]}" alt="#{photo[:title]}" src="#{photo[:src]}" class="#{place}"| |
|---|
| 39 | body << %Q| width="#{photo[:width]}"| if photo[:width] |
|---|
| 40 | body << %Q| height="#{photo[:height]}"| if photo[:height] |
|---|
| 41 | body << %Q|></a>| |
|---|
| 42 | end |
|---|
| 43 | |
|---|
| 44 | body |
|---|
| 45 | end |
|---|
| 46 | |
|---|
| 47 | def flickr_left(photo_id, size = nil) |
|---|
| 48 | flickr(photo_id, size, 'left') |
|---|
| 49 | end |
|---|
| 50 | |
|---|
| 51 | def flickr_right(photo_id, size = nil) |
|---|
| 52 | flickr(photo_id, size, 'right') |
|---|
| 53 | end |
|---|
| 54 | |
|---|
| 55 | def flickr_photo_info(photo_id, size) |
|---|
| 56 | photo = {} |
|---|
| 57 | |
|---|
| 58 | begin |
|---|
| 59 | flickr_open('flickr.photos.getInfo', photo_id) {|f| |
|---|
| 60 | res = REXML::Document.new(f) |
|---|
| 61 | photo[:page] = res.elements['//rsp/photo/urls/url'].text |
|---|
| 62 | photo[:title] = res.elements['//rsp/photo/title'].text |
|---|
| 63 | } |
|---|
| 64 | flickr_open('flickr.photos.getSizes', photo_id) {|f| |
|---|
| 65 | res = REXML::Document.new(f) |
|---|
| 66 | res.elements.each('//rsp/sizes/size') do |s| |
|---|
| 67 | if s.attributes['label'].downcase == size.downcase |
|---|
| 68 | photo[:src] = s.attributes['source'] |
|---|
| 69 | photo[:width] = s.attributes['width'] |
|---|
| 70 | photo[:height] = s.attributes['height'] |
|---|
| 71 | end |
|---|
| 72 | end |
|---|
| 73 | } |
|---|
| 74 | rescue Exception => e |
|---|
| 75 | return nil |
|---|
| 76 | end |
|---|
| 77 | photo |
|---|
| 78 | end |
|---|
| 79 | |
|---|
| 80 | def flickr_open(method, photo_id) |
|---|
| 81 | cache_dir = "#{@cache_path}/flickr" |
|---|
| 82 | Dir::mkdir(cache_dir) unless File::directory?(cache_dir) |
|---|
| 83 | |
|---|
| 84 | file = "#{cache_dir}/#{photo_id}.#{method}" |
|---|
| 85 | unless File.exist?(file) |
|---|
| 86 | req = Flickr::Request.new(@conf['flickr.apikey']) |
|---|
| 87 | req['method'] = method |
|---|
| 88 | req['photo_id'] = photo_id |
|---|
| 89 | begin |
|---|
| 90 | timeout(5) do |
|---|
| 91 | open(file, 'w') {|fout| |
|---|
| 92 | req.open.each {|line| fout.puts line } |
|---|
| 93 | } |
|---|
| 94 | end |
|---|
| 95 | rescue TimeoutError => e |
|---|
| 96 | File.delete(file) |
|---|
| 97 | raise e |
|---|
| 98 | end |
|---|
| 99 | end |
|---|
| 100 | open(file) {|f| yield f } |
|---|
| 101 | end |
|---|
| 102 | |
|---|
| 103 | FLICKER_FORM_PID = 'plugin_flickr_pid' |
|---|
| 104 | add_edit_proc do |date| |
|---|
| 105 | photo_id = @cgi.params[FLICKER_FORM_PID][0] or next |
|---|
| 106 | |
|---|
| 107 | # this code was from image.rb |
|---|
| 108 | case @conf.style.sub( /^blog/i, '' ) |
|---|
| 109 | when /^wiki|markdown$/i |
|---|
| 110 | ptag1 = "{{" |
|---|
| 111 | ptag2 = "}}" |
|---|
| 112 | when /^rd$/i |
|---|
| 113 | ptag1 = "((%" |
|---|
| 114 | ptag2 = "%))" |
|---|
| 115 | else |
|---|
| 116 | ptag1 = "<%=" |
|---|
| 117 | ptag2 = "%>" |
|---|
| 118 | end |
|---|
| 119 | |
|---|
| 120 | ptag = %Q|#{ptag1}flickr #{photo_id}#{ptag2}| |
|---|
| 121 | photo = flickr_photo_info(photo_id.to_s, 'thumbnail') |
|---|
| 122 | flickr_image = %Q|<img title="#{photo[:title]}" alt="#{photo[:title]}" src="#{photo[:src]}">| |
|---|
| 123 | |
|---|
| 124 | <<-FORM |
|---|
| 125 | <h3 class="subtitle">Flickr</h3> |
|---|
| 126 | <input type="hidden" name="#{FLICKER_FORM_PID}" value="#{photo_id}"> |
|---|
| 127 | <div class="field title"> |
|---|
| 128 | #{flickr_image} |
|---|
| 129 | <input type="button" onclick="flickr_edit_insert("#{ptag}")" value="#{@flickr_label_form_add}"> |
|---|
| 130 | </div> |
|---|
| 131 | <script type="text/javascript"> |
|---|
| 132 | <!-- |
|---|
| 133 | function flickr_edit_insert(photo_id) { |
|---|
| 134 | window.document.forms[0].body.value += photo_id; |
|---|
| 135 | } |
|---|
| 136 | //--> |
|---|
| 137 | </script> |
|---|
| 138 | FORM |
|---|
| 139 | end |
|---|
| 140 | |
|---|
| 141 | def flickr_slideshow(tag, id = nil) |
|---|
| 142 | id ||= @conf['flickr.id'] |
|---|
| 143 | return unless id |
|---|
| 144 | %Q|<iframe align="center" src="http://www.flickr.com/slideShow/index.gne?user_id=#{id}&tags=#{tag}" frameBorder="0" width="500" scrolling="no" height="500"></iframe>| |
|---|
| 145 | end |
|---|
| 146 | |
|---|
| 147 | module Flickr |
|---|
| 148 | class Request < Hash |
|---|
| 149 | def initialize(api_key, secret = nil) |
|---|
| 150 | self['api_key'] = api_key |
|---|
| 151 | @secret = secret |
|---|
| 152 | end |
|---|
| 153 | |
|---|
| 154 | def open(*param, &block) |
|---|
| 155 | Kernel::open(query, *param, &block) |
|---|
| 156 | end |
|---|
| 157 | |
|---|
| 158 | def query |
|---|
| 159 | sign = @secret ? "&api_sig=#{signature}" : '' |
|---|
| 160 | base_url + sort.map{|key, val| "#{key}=#{val}" }.join('&') + sign |
|---|
| 161 | end |
|---|
| 162 | |
|---|
| 163 | def signature |
|---|
| 164 | data = sort.map{|key, val| "#{key}#{val}" }.join |
|---|
| 165 | Digest::MD5.hexdigest("#{@secret}#{data}") |
|---|
| 166 | end |
|---|
| 167 | |
|---|
| 168 | def base_url |
|---|
| 169 | 'http://flickr.com/services/rest/?' |
|---|
| 170 | end |
|---|
| 171 | end |
|---|
| 172 | |
|---|
| 173 | class RequestAuth < Request |
|---|
| 174 | def base_url |
|---|
| 175 | 'http://flickr.com/services/auth/?' |
|---|
| 176 | end |
|---|
| 177 | end |
|---|
| 178 | end |
|---|