Class: Photostat::Flickr

Inherits:
Plugins::Base show all
Includes:
FileUtils, OSUtils
Defined in:
lib/photostat/plugins/02_flickr.rb

Instance Method Summary collapse

Methods included from OSUtils

#exec, #file_md5, #files_in_dir, #input, #partial_file_md5, #string_md5

Methods inherited from Plugins::Base

exposes, exposes_help, extended, #help, help_text, included, inherited, plugin_name, register_plugin

Instance Method Details

#activate!Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/photostat/plugins/02_flickr.rb', line 12

def activate!
  return if @activated
  @activated = 1

  # authenticating to Flickr
  require 'flickraw'

  @config = Photostat.config
  config unless @config[:flickr]

  FlickRaw.api_key = @config[:flickr][:api_key]
  FlickRaw.shared_secret = @config[:flickr][:shared_secret]

  flickr.access_token = @config[:flickr][:access_token]
  flickr.access_secret = @config[:flickr][:access_secret]

  begin
     = flickr.test.
  rescue FlickRaw::FailedResponse => e
    STDERR.puts "ERROR: Flickr Authentication failed : #{e.msg}"
    exit 1
  end      

  Photostat::DB.migrate!
  @db = Photostat::DB.instance
end

#configObject



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/photostat/plugins/02_flickr.rb', line 206

def config
  puts
  config_file = File.expand_path "~/.photostat"

  unless File.exists? config_file
    Photostat.configure_plugin! :local
  end

  config = YAML::load(File.read config_file) 

  config[:flickr] ||= {
    :api_key => nil,
    :shared_secret => nil
  }

  puts "Configuring Flickr!"
  puts "-------------------"
  puts
  puts "You need to create an app to access your account, see:"
  puts "       http://www.flickr.com/services/apps/create/apply/"
  puts "Or if you already have an app key available, find it here:"
  puts "       http://www.flickr.com/services/apps/"
  puts 

  config[:flickr][:api_key] = input("Flickr Authentication :: Api Key",
      :default => config[:flickr][:api_key])
  config[:flickr][:shared_secret] = input("Flickr Authentication :: Shared Secret",
      :default => config[:flickr][:shared_secret])

  require 'flickraw'

  FlickRaw.api_key = config[:flickr][:api_key]
  FlickRaw.shared_secret = config[:flickr][:shared_secret]

  token = flickr.get_request_token
  auth_url = flickr.get_authorize_url(token['oauth_token'], :perms => 'delete')

  puts
  puts "Open this url in your process to complete the authication process:"
  puts "    " + auth_url

  verify = input("Copy here the number given when visiting the link above")
  begin
    flickr.get_access_token(token['oauth_token'], token['oauth_token_secret'], verify)
     = flickr.test.
    puts "You are now authenticated as #{.username} with token #{flickr.access_token} and secret #{flickr.access_secret}"        
  rescue FlickRaw::FailedResponse => e
    STDERR.puts "ERROR: Flickr Authentication failed : #{e.msg}"
    exit 1
  end

  config[:flickr][:access_token]  = flickr.access_token
  config[:flickr][:access_secret] = flickr.access_secret      

  File.open(config_file, 'w') do |fh|
    fh.write(YAML::dump(config))
    puts
    puts " >>>> modified ~/.photostat config"
    puts
  end  
end

#exportObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/photostat/plugins/02_flickr.rb', line 127

def export
  opts = Trollop::options do
    opt :path, "Local path to export web page to", :required => true, :type => :string, :short => "-p"
  end

  Trollop::die :path, "must have valid base directory" unless File.directory? File.dirname(opts[:path])
  Trollop::die :path, "directory already exists" if File.directory? opts[:path]

  activate!
  update_md5_info_on_files!      

  cfg = Photostat.config
  db = Photostat::DB.instance
  Dir.mkdir opts[:path]

  fh = File.open(File.join(opts[:path], 'index.html'), 'w')
             
  rs = flickr.photos.search(:user_id => "me", :extras => 'machine_tags, tags, date_taken, date_upload', :per_page => 500, :privacy_filter => 1)
  rs.each do |fphoto|
    next unless fphoto.machine_tags =~ /checksum:md5=(\w+)/

    md5 = $1
    obj = db[:photos].where(:md5 => md5).first

    fname = File.basename obj[:local_path]
    src_path = File.join(cfg[:repository_path], obj[:local_path])
    dst_path = File.join(opts[:path], fname)

    cp src_path, dst_path
    fh.write "<a href='http://www.flickr.com/photos/alex_ndc/#{fphoto.id}/in/photostream' target='_blank'>\n"
    fh.write "    <img src='#{fname}' />\n"
    fh.write "</a>\n"
  end      

  fh.close
end

#syncObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/photostat/plugins/02_flickr.rb', line 164

def sync
  activate!

  update_md5_info_on_files!
  update_flickr_info!

  db = Photostat::DB.instance
  config = Photostat.config
       
  rs = db[:photos].where(:type => 'jpg', :has_flickr_upload => false)
  total = rs.count
  count = 0

  rs.order('created_at').all do |obj|
    count += 1
    STDOUT.write("\r - uploading file: #{count} / #{total}")
    STDOUT.flush

    src_path = File.join(config[:repository_path], obj[:local_path])

    options = {}
    options[:title] = obj[:uid]
    options[:tags]  = 'sync checksum:md5=' + obj[:md5]
    options[:safety_level] = '1'
    options[:content_type] = '1'
    options[:is_family] = '0'
    options[:is_friend] = '0'
    options[:is_public] = '0'
    options[:hidden] = '2'

    begin
      photoid = flickr.upload_photo(src_path, options)
    rescue
      sleep 5
      # retrying again
      photoid = flickr.upload_photo(src_path, options)
    end
  end

  puts "\n"
end

#update_flickr_info!Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/photostat/plugins/02_flickr.rb', line 60

def update_flickr_info!
  activate!
  update_md5_info_on_files!

  db = Photostat::DB.instance
       
  rs = flickr.photos.search(:user_id => "me", :extras => 'machine_tags, tags, date_taken, date_upload', :per_page => 500)
  pages_nr = rs.pages
  page_idx = 1

  count = 0
  not_local = 0
  not_tagged = 0
  are_valid = 0
  total = rs.total.to_i

  valid_ids = []

  puts if total > 0
  while rs.length > 0

    rs.each do |fphoto|
      count += 1

      unless fphoto.machine_tags =~ /checksum:md5=(\w+)/
        not_tagged += 1
        next
      end

      md5 = $1
      obj = db[:photos].where(:md5 => md5).first

      if not obj
        not_local += 1
        next
      end

      db[:tags].where(:photo_id => obj[:id]).delete          
      if fphoto[:tags] and !fphoto.tags.empty?
        tags = fphoto.tags.split.select{|x| ! ['private', 'sync'].member?(x) && x !~ /checksum:/}
        tags.each do |tag_name|
          db[:tags].insert(:name => tag_name, :photo_id => obj[:id])
        end
      end

      if fphoto.ispublic == 1
        visibility = 'public'
      elsif fphoto.isfamily == 1
        visibility = 'protected'
      else
        visibility = 'private'
      end

      db[:photos].where(:md5 => md5).update(:has_flickr_upload => true, :visibility => visibility)
      
      STDOUT.write("\r - reading flickr meta: #{count} of #{total}, with #{not_tagged} not tagged on flickr, #{not_local} not local")
      STDOUT.flush
    end  
    
    page_idx += 1
    break if page_idx > pages_nr
    rs = flickr.photos.search(:user_id => "me", :extras => 'machine_tags', :per_page => 500, :page => page_idx)
  end      

  puts("\r - reading flickr meta: #{count} of #{total}, with #{not_tagged} not tagged on flickr, #{not_local} not local")
end

#update_md5_info_on_files!Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/photostat/plugins/02_flickr.rb', line 39

def update_md5_info_on_files!
  activate!

  rs = @db[:photos].where(:type => "jpg", :md5 => nil)
  
  count = 0
  total = rs.count
  puts if total > 0

  @db[:photos].where(:type => "jpg", :md5 => nil).all do |obj|        
    md5 = file_md5 File.join(@config[:repository_path], obj[:local_path])
    @db[:photos].where(:uid => obj[:uid]).update(:md5 => md5)

    count += 1
    STDOUT.write("\r - processed md5 hash for local files: #{count} / #{total}")
    STDOUT.flush
  end

  puts if total > 0
end