Permalink
Browse files

Some big changes to photo sync.

  • Loading branch information...
1 parent 5333070 commit 8b665095e5e7a30742653181efa5a7e6f3327794 @timriley committed Jan 2, 2009
View
4 TODO
@@ -7,4 +7,6 @@
- need to verify that sync order is still correct (it looks like it is oldest first after a recent test)
-- max says make it browse flickr sets
+- max says make it browse flickr sets
+
+- make the error page look consistent with the rest of the app's theme (this should perhaps work with the wildcard route and the pages controller?)
@@ -1,6 +1,5 @@
class Admin::LoginsController < Admin::AdminController
skip_before_filter :login_required, :only => [:new, :create]
- layout 'admin_wrapper'
def new
end
@@ -1,9 +1,7 @@
class PhotosController < ApplicationController
- layout 'theme'
-
def show
# Find the photo from id or get the most recent one.
- @photo = params[:id] ? Photo.find(params[:id]) : Photo.find(:first, :order => 'created_at DESC')
+ @photo = params[:id] ? Photo.find_by_flickr_id(params[:id]) : Photo.latest
respond_to do |format|
format.html
View
@@ -13,7 +13,7 @@ def attributes
# and the attributes are retrieved from flickr.
# Idea! Will probably need to dynamically generate all of those accessor methods to
# achieve the above.
-
+
def id
@id
end
@@ -45,13 +45,9 @@ def fullsize_source_url
attributes[:fullsize_source_url]
end
- # :user_id => user_nsid, :tags => tag
+ # {:user_id => 'user_nsid', :tags => "tag1, tag2, tag3"}
def self.find_all(options)
- if !options.empty?
- flickr.photos.search({:sort => 'date-posted-desc'}.merge(options)).collect { |photo| new(photo.id) }
- else
- # TODO return error because we can't have optionless searches
- end
+ flickr.photos.search({:sort => 'date-posted-desc', :tag_mode => 'any'}.merge(options)).collect { |photo| new(photo.id) }
end
protected
@@ -66,7 +62,6 @@ def get_attributes
attrs[:description] = info.description
attrs[:taken_at] = info.dates.taken ? Time.parse(info.dates.taken) : nil # not everything has exif data
attrs[:flickr_posted_at] = Time.at(info.dates.posted.to_i)
- # FIXME wrap lastupdate in time.parse?
attrs[:flickr_updated_at] = Time.at(info.dates.lastupdate.to_i)
urls.each do |u|
View
@@ -1,7 +1,7 @@
class Photo < ActiveRecord::Base
- named_scope :active, :conditions => { :active => true }
- named_scope :with_tag, lambda { |tag| { :conditions => ['tag = ?', tag] } }
+ named_scope :active, :conditions => { :active => true }
+ named_scope :inactive, :conditions => { :active => false }
acts_as_audited
@@ -15,14 +15,24 @@ class Photo < ActiveRecord::Base
validates_presence_of :flickr_posted_at, :message => "can't be blank" # this is used for photo ordering
validates_presence_of :flickr_updated_at, :message => "can't be blank" # needed for syncing
- liquid_methods :id,
- :title,
- :square_source_url,
- :thumb_source_url,
- :medium_source_url,
- :fullsize_source_url,
- :previous,
- :next
+ def to_param
+ flickr_id
+ end
+
+ def to_liquid
+ { 'id' => self.flickr_id,
+ 'title' => self.title,
+ 'square_source_url' => self.square_source_url,
+ 'thumb_source_url' => self.thumb_source_url,
+ 'medium_source_url' => self.medium_source_url,
+ 'fullsize_source_url' => self.fullsize_source_url,
+ 'previous' => self.previous,
+ 'next' => self.next }
+ end
+
+ def self.latest
+ active.first(:order => 'flickr_posted_at DESC, id DESC')
+ end
def previous
@previous_photo ||= Photo.active.first(:order => 'flickr_posted_at DESC, id DESC', :conditions => ['flickr_posted_at < ?', flickr_posted_at])
@@ -32,28 +42,28 @@ def next
@next_photo ||= Photo.active.first(:order => 'flickr_posted_at ASC, id ASC', :conditions => ['flickr_posted_at > ?', flickr_posted_at])
end
+ def new_from_flickr?
+ !synced_with?
+ end
+
def update_from_flickr
- self.attributes = self.attributes.merge(FlickrPhoto.new(self.flickr_id).attributes)
+ merge_attributes_from_flickr_photo(FlickrPhoto.new(flickr_id))
+ end
+
+ def merge_attributes_from_flickr_photo(flickr_photo)
+ self.flickr_id = flickr_photo.id
+ self.attributes = self.attributes.merge(flickr_photo.attributes)
end
def update_from_flickr_photo(flickr_photo)
if flickr_updated_at.to_i < flickr_photo.flickr_updated_at.to_i
- self.attributes = self.attributes.merge(flickr_photo.attributes)
+ merge_attributes_from_flickr_photo(flickr_photo)
end
end
def self.new_from_flickr_photo(flickr_photo)
Photo.new do |photo|
- photo.flickr_id = flickr_photo.id # Basic info
- photo.title = flickr_photo.title
- photo.description = flickr_photo.description
- photo.square_source_url = flickr_photo.square_source_url # URLs
- photo.thumb_source_url = flickr_photo.thumb_source_url
- photo.medium_source_url = flickr_photo.medium_source_url
- photo.fullsize_source_url = flickr_photo.fullsize_source_url
- photo.taken_at = flickr_photo.taken_at # Dates
- photo.flickr_posted_at = flickr_photo.flickr_posted_at
- photo.flickr_updated_at = flickr_photo.flickr_updated_at
+ photo.merge_attributes_from_flickr_photo(flickr_photo)
end
end
@@ -63,40 +73,34 @@ def self.create_from_flickr_photo(flickr_photo)
end
end
- # Only allow the following options, :user_id => user_id, :tag => tag
- def self.sync_with_flickr(options = {})
- if options.empty?
- # TODO return an error because we need at least a :user or a :tag
+ def self.create_or_update_from_flickr_photo(flickr_photo)
+ if photo = find_by_flickr_id(flickr_photo.id)
+ photo.update_from_flickr_photo(flickr_photo)
+ photo.save if photo.changed?
+ else
+ create_from_flickr_photo(flickr_photo)
end
-
+ end
+
+ # Use these options - {:user_id => 'user_id', :tags => 'tags'}
+ def self.sync_with_flickr(options)
transaction do
- if options[:tag]
- update_all('active = false', ['tag != ?', options[:tag]])
- end
-
- search_options = {}
- search_options[:user_id] = options[:user_id] unless options[:user_id].blank?
- search_options[:tags] = options[:tag] unless options[:tag].blank?
-
- flickr_photos = FlickrPhoto.find_all(search_options)
- local_photos = Photo.all
-
- # sort all of the current photos by flickr id
- local_photos_by_flickr_id = {}
- local_photos.each do |photo|
- local_photos_by_flickr_id[photo.flickr_id] = photo
- end
-
- flickr_photos.each do |flickr_photo|
- if local_photo = local_photos_by_flickr_id[flickr_photo.id]
- # we've imported the photo before, update it from flickr if it is stale
- local_photo.update_from_flickr_photo(flickr_photo)
- local_photo.save if local_photo.changed?
- else
- # if the photo does not exist locally, create it.
- Photo.create_from_flickr_photo(flickr_photo)
- end
+ delete_for_sync(options)
+
+ FlickrPhoto.find_all(options).each do |p|
+ photo = create_or_update_from_flickr_photo(p)
+ photo.update_attribute(:synced_with, sync_options_to_s(options)) if photo.new_from_flickr?
end
end
- end
+ end
+
+ private
+
+ def self.delete_for_sync(options)
+ delete_all(["synced_with != ?", sync_options_to_s(options)])
+ end
+
+ def self.sync_options_to_s(options)
+ "#{options[:user_id]}|#{options[:tags]}"
+ end
end
@@ -0,0 +1,9 @@
+class RenameTagToTags < ActiveRecord::Migration
+ def self.up
+ rename_column :photos, :tag, :tags
+ end
+
+ def self.down
+ rename_column :photos, :tags, :tag
+ end
+end
@@ -0,0 +1,13 @@
+class ReplaceTagsWithSyncedWith < ActiveRecord::Migration
+ def self.up
+ remove_column :photos, :tags
+ add_column :photos, :synced_with, :string
+ add_index :photos, :synced_with
+ end
+
+ def self.down
+ remove_index :photos, :synced_with
+ remove_column :photos, :synced_with
+ add_column :photos, :tags, :string
+ end
+end
View
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20081231022531) do
+ActiveRecord::Schema.define(:version => 20090102120632) do
create_table "audits", :force => true do |t|
t.integer "auditable_id"
@@ -86,10 +86,12 @@
t.datetime "created_at"
t.datetime "updated_at"
t.string "square_source_url"
- t.string "tag"
t.datetime "flickr_posted_at"
+ t.string "synced_with"
end
- add_index "photos", ["tag"], :name => "index_photos_on_tag"
+ add_index "photos", ["active"], :name => "index_photos_on_active"
+ add_index "photos", ["flickr_posted_at"], :name => "index_photos_on_flickr_posted_at"
+ add_index "photos", ["synced_with"], :name => "index_photos_on_synced_with"
end
View
@@ -4,4 +4,5 @@
# FIXME log an error when sync fails
true
end
+
Bj.submit "./script/runner ./lib/jobs/synchronise.rb", :submitted_at => 20.minutes.from_now

0 comments on commit 8b66509

Please sign in to comment.