Commit bdeae54c authored by Manuel Schölling's avatar Manuel Schölling

Make Photos not inherit from Posts

parent 02a3c3f8
......@@ -104,7 +104,7 @@ GEM
xml-simple
bcrypt-ruby (2.1.4)
builder (2.1.2)
bunny (0.7.6)
bunny (0.7.8)
capistrano (2.5.19)
highline
net-scp (>= 1.0.0)
......@@ -128,14 +128,14 @@ GEM
erubis
extlib
highline
json (<= 1.4.6, >= 1.4.4)
json (>= 1.4.4, <= 1.4.6)
mixlib-authentication (>= 1.1.0)
mixlib-cli (>= 1.1.0)
mixlib-config (>= 1.1.2)
mixlib-log (>= 1.2.0)
moneta
ohai (>= 0.5.7)
rest-client (< 1.7.0, >= 1.0.4)
rest-client (>= 1.0.4, < 1.7.0)
uuidtools
childprocess (0.2.2)
ffi (~> 1.0.6)
......@@ -164,7 +164,7 @@ GEM
warden (~> 1.0.3)
devise_invitable (0.5.0)
devise (~> 1.3.1)
rails (<= 3.2, >= 3.0.0)
rails (>= 3.0.0, <= 3.2)
diff-lcs (1.1.3)
em-synchrony (0.2.0)
eventmachine (>= 0.12.9)
......@@ -181,7 +181,7 @@ GEM
faraday (0.6.1)
addressable (~> 2.2.4)
multipart-post (~> 1.1.0)
rack (< 2, >= 1.1.0)
rack (>= 1.1.0, < 2)
faraday-stack (0.1.3)
faraday (~> 0.6)
faraday_middleware (0.6.5)
......@@ -211,7 +211,7 @@ GEM
rspec-instafail (~> 0.1.8)
ruby-progressbar (~> 0.0.10)
gem_plugin (0.2.3)
gherkin (2.5.1)
gherkin (2.5.2)
json (>= 1.4.6)
haml (3.1.2)
hashie (1.0.0)
......@@ -281,7 +281,7 @@ GEM
net-ssh (2.0.24)
net-ssh-gateway (1.1.0)
net-ssh (>= 1.99.1)
newrelic_rpm (3.1.2)
newrelic_rpm (3.2.0)
nokogiri (1.4.3.1)
oa-basic (0.2.6)
oa-core (= 0.2.6)
......@@ -318,7 +318,7 @@ GEM
addressable (~> 2.2)
ohai (0.5.8)
extlib
json (<= 1.4.6, >= 1.4.4)
json (>= 1.4.4, <= 1.4.6)
mixlib-cli
mixlib-config
mixlib-log
......@@ -366,7 +366,8 @@ GEM
rake (0.9.2)
rash (0.3.0)
hashie (~> 1.0.0)
rdoc (3.9.4)
rdoc (3.10)
json (~> 1.4)
redcarpet (2.0.0b5)
redis (2.2.2)
redis-namespace (0.8.0)
......@@ -434,7 +435,7 @@ GEM
sqlite3 (1.3.4)
subexec (0.0.4)
systemu (2.4.0)
term-ansicolor (1.0.6)
term-ansicolor (1.0.7)
thin (1.2.11)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
......@@ -459,13 +460,13 @@ GEM
uuidtools (2.1.2)
vegas (0.1.8)
rack (>= 1.0.0)
warden (1.0.5)
warden (1.0.6)
rack (>= 1.0)
webmock (1.6.2)
addressable (>= 2.2.2)
crack (>= 0.1.7)
will_paginate (3.0.pre2)
xml-simple (1.1.0)
xml-simple (1.1.1)
yard (0.7.2)
yui-compressor (0.9.6)
POpen4 (>= 0.1.4)
......
......@@ -48,7 +48,7 @@ class ActivityStreams::PhotosController < ApplicationController
end
def show
@photo = current_user.find_visible_post_by_id(params[:id])
@photo = current_user.find_visible_shareable_by_id(Photo, params[:id])
respond_with @photo
end
......
......@@ -14,7 +14,7 @@ class CommentsController < ApplicationController
end
def create
target = current_user.find_visible_post_by_id params[:post_id]
target = current_user.find_visible_shareable_by_id Post, params[:post_id]
text = params[:text]
if target
......@@ -55,7 +55,7 @@ class CommentsController < ApplicationController
end
def index
@post = current_user.find_visible_post_by_id(params[:post_id])
@post = current_user.find_visible_shareable_by_id(Post, params[:post_id])
if @post
@comments = @post.comments.includes(:author => :profile).order('created_at ASC')
render :layout => false
......
......@@ -59,10 +59,10 @@ class LikesController < ApplicationController
def target
@target ||= if params[:post_id]
current_user.find_visible_post_by_id(params[:post_id])
current_user.find_visible_shareable_by_id(Post, params[:post_id])
else
comment = Comment.find(params[:comment_id])
comment = nil unless current_user.find_visible_post_by_id(comment.commentable_id)
comment = nil unless current_user.find_visible_shareable_by_id(Post, comment.commentable_id)
comment
end
end
......
......@@ -29,7 +29,7 @@ class PhotosController < ApplicationController
@contacts_of_contact_count = 0
end
@posts = current_user.posts_from(@person).where(:type => 'Photo').paginate(:page => params[:page])
@posts = current_user.photos_from(@person).paginate(:page => params[:page])
render 'people/show'
......@@ -118,7 +118,7 @@ class PhotosController < ApplicationController
end
def destroy
photo = current_user.posts.where(:id => params[:id]).first
photo = current_user.photos.where(:id => params[:id]).first
if photo
current_user.retract(photo)
......@@ -148,7 +148,7 @@ class PhotosController < ApplicationController
end
def edit
if @photo = current_user.posts.where(:id => params[:id]).first
if @photo = current_user.photos.where(:id => params[:id]).first
respond_with @photo
else
redirect_to person_photos_path(current_user.person)
......@@ -156,7 +156,7 @@ class PhotosController < ApplicationController
end
def update
photo = current_user.posts.where(:id => params[:id]).first
photo = current_user.photos.where(:id => params[:id]).first
if photo
if current_user.update_post( photo, params[:photo] )
flash.now[:notice] = I18n.t 'photos.update.notice'
......@@ -187,7 +187,7 @@ class PhotosController < ApplicationController
end
def photo
@photo ||= current_user.find_visible_post_by_id(params[:id], :type => 'Photo')
@photo ||= current_user.find_visible_shareable_by_id(Photo, params[:id])
end
def additional_photos
......
......@@ -18,7 +18,7 @@ class PostsController < ApplicationController
key = params[:id].to_s.length <= 8 ? :id : :guid
if user_signed_in?
@post = current_user.find_visible_post_by_id(params[:id], :key => key)
@post = current_user.find_visible_shareable_by_id(Post, params[:id], :key => key)
else
@post = Post.where(key => params[:id], :public => true).includes(:author, :comments => :author).first
end
......
......@@ -10,6 +10,7 @@ class Aspect < ActiveRecord::Base
has_many :aspect_visibilities
has_many :posts, :through => :aspect_visibilities, :source => :shareable, :source_type => 'Post'
has_many :photos, :through => :aspect_visibilities, :source => :shareable, :source_type => 'Photo'
validates :name, :presence => true, :length => { :maximum => 20 }
......@@ -24,5 +25,17 @@ class Aspect < ActiveRecord::Base
def to_s
name
end
def << (shareable)
case shareable
when Post
self.posts << shareable
when Photo
self.photos << shareable
else
raise "Unknown shareable type '#{shareable.class.base_class.to_s}'"
end
end
end
......@@ -54,9 +54,9 @@ class Contact < ActiveRecord::Base
:into => aspects.first)
end
def receive_post(post)
ShareVisibility.create!(:shareable_id => post.id, :shareable_type => 'Post', :contact_id => self.id)
post.socket_to_user(self.user, :aspect_ids => self.aspect_ids) if post.respond_to? :socket_to_user
def receive_shareable(shareable)
ShareVisibility.create!(:shareable_id => shareable.id, :shareable_type => shareable.class.base_class.to_s, :contact_id => self.id)
shareable.socket_to_user(self.user, :aspect_ids => self.aspect_ids) if shareable.respond_to? :socket_to_user
end
def contacts
......
......@@ -28,6 +28,7 @@ class Person < ActiveRecord::Base
has_many :contacts, :dependent => :destroy # Other people's contacts for this person
has_many :posts, :foreign_key => :author_id, :dependent => :destroy # This person's own posts
has_many :photos, :foreign_key => :author_id, :dependent => :destroy # This person's own photos
has_many :comments, :foreign_key => :author_id, :dependent => :destroy # This person's own comments
belongs_to :owner, :class_name => 'User'
......@@ -249,7 +250,7 @@ class Person < ActiveRecord::Base
end
def has_photos?
self.posts.where(:type => "Photo").exists?
self.photos.exists?
end
def as_json( opts = {} )
......
......@@ -2,8 +2,12 @@
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class Photo < Post
class Photo < ActiveRecord::Base
require 'carrierwave/orm/activerecord'
include Diaspora::Commentable
include Diaspora::Shareable
mount_uploader :processed_image, ProcessedImage
mount_uploader :unprocessed_image, UnprocessedImage
......@@ -40,7 +44,12 @@ class Photo < Post
end
def self.diaspora_initialize(params = {})
photo = super(params)
photo = self.new params.to_hash
photo.author = params[:author]
photo.public = params[:public] if params[:public]
photo.pending = params[:pending] if params[:pending]
photo.diaspora_handle = photo.author.diaspora_handle
image_file = params.delete(:user_file)
photo.random_string = ActiveSupport::SecureRandom.hex(10)
photo.unprocessed_image.store! image_file
......
......@@ -3,20 +3,13 @@
# the COPYRIGHT file.
class Post < ActiveRecord::Base
require File.join(Rails.root, 'lib/diaspora/web_socket')
include ApplicationHelper
include ROXML
include Diaspora::Webhooks
include Diaspora::Guid
include Diaspora::Likeable
include Diaspora::Commentable
include Diaspora::Shareable
xml_attr :diaspora_handle
xml_attr :provider_display_name
xml_attr :public
xml_attr :created_at
has_many :mentions, :dependent => :destroy
......@@ -25,14 +18,9 @@ class Post < ActiveRecord::Base
belongs_to :o_embed_cache
belongs_to :author, :class_name => 'Person'
validates :guid, :uniqueness => true
after_create :cache_for_author
#scopes
scope :all_public, where(:public => true, :pending => false)
scope :includes_for_a_stream, includes(:o_embed_cache, {:author => :profile}, :mentions => {:person => :profile}) #note should include root and photos, but i think those are both on status_message
def self.for_a_stream(max_time, order)
......@@ -47,27 +35,6 @@ class Post < ActiveRecord::Base
end
#############
def diaspora_handle
read_attribute(:diaspora_handle) || self.author.diaspora_handle
end
def user_refs
if AspectVisibility.exists?(:shareable_id => self.id, :shareable_type => 'Post')
self.share_visibilities.count + 1
else
self.share_visibilities.count
end
end
def reshare_count
@reshare_count ||= Post.where(:root_guid => self.guid).count
end
def diaspora_handle= nd
self.author = Person.where(:diaspora_handle => nd).first
write_attribute(:diaspora_handle, nd)
end
def self.diaspora_initialize params
new_post = self.new params.to_hash
new_post.author = params[:author]
......@@ -77,23 +44,15 @@ class Post < ActiveRecord::Base
new_post
end
def reshare_count
@reshare_count ||= Post.where(:root_guid => self.guid).count
end
# @return Returns true if this Post will accept updates (i.e. updates to the caption of a photo).
def mutable?
false
end
# The list of people that should receive this Post.
#
# @param [User] user The context, or dispatching user.
# @return [Array<Person>] The list of subscribers to this post
def subscribers(user)
if self.public?
user.contact_people
else
user.people_in_aspects(user.aspects_with_post(self.id))
end
end
def activity_streams?
false
end
......@@ -106,12 +65,6 @@ class Post < ActiveRecord::Base
I18n.t('notifier.a_post_you_shared')
end
# @return [Integer]
def update_comments_counter
self.class.where(:id => self.id).
update_all(:comments_count => self.comments.count)
end
# @return [Boolean]
def cache_for_author
if self.should_cache_for_author?
......@@ -126,72 +79,4 @@ class Post < ActiveRecord::Base
self.triggers_caching? && RedisCache.configured? &&
RedisCache.acceptable_types.include?(self.type) && user = self.author.owner
end
# @param [User] user The user that is receiving this post.
# @param [Person] person The person who dispatched this post to the
# @return [void]
def receive(user, person)
#exists locally, but you dont know about it
#does not exsist locally, and you dont know about it
#exists_locally?
#you know about it, and it is mutable
#you know about it, and it is not mutable
self.class.transaction do
local_post = persisted_post
if local_post && verify_persisted_post(local_post)
self.receive_persisted(user, person, local_post)
elsif !local_post
self.receive_non_persisted(user, person)
else
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason='update not from post owner' existing_post=#{self.id}")
false
end
end
end
protected
# @return [Post,void]
def persisted_post
self.class.where(:guid => self.guid).first
end
# @return [Boolean]
def verify_persisted_post(persisted_post)
persisted_post.author_id == self.author_id
end
def receive_persisted(user, person, local_post)
known_post = user.find_visible_post_by_id(self.guid, :key => :guid)
if known_post
if known_post.mutable?
known_post.update_attributes(self.attributes)
true
else
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason=immutable") #existing_post=#{known_post.id}")
false
end
else
user.contact_for(person).receive_post(local_post)
user.notify_if_mentioned(local_post)
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=complete sender=#{self.diaspora_handle}") #existing_post=#{local_post.id}")
true
end
end
def receive_non_persisted(user, person)
if self.save
user.contact_for(person).receive_post(self)
user.notify_if_mentioned(self)
Rails.logger.info("event=receive payload_type=#{self.class} update=false status=complete sender=#{self.diaspora_handle}")
true
else
Rails.logger.info("event=receive payload_type=#{self.class} update=false status=abort sender=#{self.diaspora_handle} reason=#{self.errors.full_messages}")
false
end
end
end
......@@ -15,7 +15,7 @@ class Retraction
def subscribers(user)
unless self.type == 'Person'
@subscribers ||= self.object.subscribers(user)
@subscribers -= self.object.resharers
@subscribers -= self.object.resharers unless self.object.is_a?(Photo)
@subscribers
else
raise 'HAX: you must set the subscribers manaully before unfriending' if @subscribers.nil?
......
......@@ -30,7 +30,7 @@ class User < ActiveRecord::Base
validates_associated :person
has_one :person, :foreign_key => :owner_id
delegate :public_key, :posts, :owns?, :diaspora_handle, :name, :public_url, :profile, :first_name, :last_name, :to => :person
delegate :public_key, :posts, :photos, :owns?, :diaspora_handle, :name, :public_url, :profile, :first_name, :last_name, :to => :person
has_many :invitations_from_me, :class_name => 'Invitation', :foreign_key => :sender_id, :dependent => :destroy
has_many :invitations_to_me, :class_name => 'Invitation', :foreign_key => :recipient_id, :dependent => :destroy
......@@ -207,7 +207,7 @@ class User < ActiveRecord::Base
def add_to_streams(post, aspects_to_insert)
post.socket_to_user(self, :aspect_ids => aspects_to_insert.map{|x| x.id}) if post.respond_to? :socket_to_user
aspects_to_insert.each do |aspect|
aspect.posts << post
aspect << post
end
end
......
......@@ -9,6 +9,9 @@ class ShareAnything < ActiveRecord::Migration
t.string :shareable_type, :default => 'Post', :null => false
end
add_index :aspect_visibilities, [:shareable_id, :shareable_type, :aspect_id], :name => 'shareable_and_aspect_id'
add_index :aspect_visibilities, [:shareable_id, :shareable_type]
remove_foreign_key :post_visibilities, :posts
remove_index :post_visibilities, :contact_id_and_post_id
......@@ -18,24 +21,38 @@ class ShareAnything < ActiveRecord::Migration
t.rename :post_id, :shareable_id
t.string :shareable_type, :default => 'Post', :null => false
end
rename_table :post_visibilities, :share_visibilities
end
rename_table :post_visibilities, :share_visibilities
add_index :share_visibilities, [:shareable_id, :shareable_type, :contact_id], :name => 'shareable_and_contact_id'
add_index :share_visibilities, [:shareable_id, :shareable_type, :hidden, :contact_id], :name => 'shareable_and_hidden_and_contact_id'
end
def self.down
rename_column :aspect_visibilities, :shareable_id, :post_id
add_foreign_key :aspect_visibilities, :posts
add_index :aspect_visibilities, :post_id
remove_column :aspect_visibilities, :shareable_type
remove_index :share_visibilities, :name => 'shareable_and_hidden_and_contact_id'
remove_index :share_visibilities, :name => 'shareable_and_contact_id'
rename_table :share_visibilities, :post_visibilities
rename_column :post_visibilities, :shareable_id, :post_id
add_foreign_key :post_visibilities, :posts
add_index :post_visibilities, :post_id_and_post_id
add_index :post_visibilities, [:contact_id, :post_id]
change_table :post_visibilities do |t|
t.remove :shareable_type
t.rename :shareable_id, :post_id
end
add_index :post_visibilities, [:post_id, :hidden, :contact_id]
add_index :post_visibilities, :post_id
remove_column :post_visibilities, :shareable_type
add_index :post_visibilities, [:contact_id, :post_id]
add_foreign_key :post_visibilities, :posts
remove_index :aspect_visibilities, [:shareable_id, :shareable_type]
remove_index :aspect_visibilities, :name => 'shareable_and_aspect_id'
change_table :aspect_visibilities do |t|
t.remove :shareable_type
t.rename :shareable_id, :post_id
end
add_index :aspect_visibilities, :post_id
add_index :aspect_visibilities, [:post_id, :aspect_id]
add_foreign_key :aspect_visibilities, :posts
end
end
class MovePhotosToTheirOwnTable < ActiveRecord::Migration
def self.up
create_table "photos", :force => true do |t|
t.integer "author_id", :null => false
t.boolean "public", :default => false, :null => false
t.string "diaspora_handle"
t.string "guid", :null => false
t.boolean "pending", :default => false, :null => false
t.text "text"
t.text "remote_photo_path"
t.string "remote_photo_name"
t.string "random_string"
t.string "processed_image"
t.datetime "created_at"
t.datetime "updated_at"
t.string "unprocessed_image"
t.string "status_message_guid"
t.integer "comments_count"
end
execute <<SQL
INSERT INTO photos
SELECT id, author_id, public, diaspora_handle, guid, pending, text, remote_photo_path, remote_photo_name, random_string, processed_image,
created_at, updated_at, unprocessed_image, status_message_guid, comments_count
FROM posts
WHERE type = 'Photo'
SQL
execute "UPDATE aspect_visibilities AS av, photos SET av.shareable_type='Photo' WHERE av.shareable_id=photos.id"
execute "UPDATE share_visibilities AS sv, photos SET sv.shareable_type='Photo' WHERE sv.shareable_id=photos.id"
# all your base are belong to us!
execute "DELETE FROM posts WHERE type='Photo'"
end
def self.down
execute <<SQL
INSERT INTO posts
SELECT NULL AS id, author_id, public, diaspora_handle, guid, pending, 'Photo' AS type, text, remote_photo_path, remote_photo_name, random_string,
processed_image, NULL AS youtube_titles, created_at, updated_at, unprocessed_image, NULL AS object_url, NULL AS image_url, NULL AS image_height, NULL AS image_width, NULL AS provider_display_name,
NULL AS actor_url, NULL AS objectId, NULL AS root_guid, status_message_guid, 0 AS likes_count, comments_count, NULL AS o_embed_cache_id
FROM photos
SQL
execute <<SQL
UPDATE aspect_visibilities, posts, photos
SET
aspect_visibilities.shareable_id=posts.id,
aspect_visibilities.shareable_type='Post'
WHERE
posts.guid=photos.guid AND
photos.id=aspect_visibilities.shareable_id
SQL
execute <<SQL
UPDATE share_visibilities, posts, photos
SET
share_visibilities.shareable_id=posts.id,
share_visibilities.shareable_type='Post'
WHERE
posts.guid=photos.guid AND
photos.id=share_visibilities.shareable_id
SQL
execute "DROP TABLE photos"
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20111011193702) do
ActiveRecord::Schema.define(:version => 20111012215141) do
create_table "aspect_memberships", :force => true do |t|
t.integer "aspect_id", :null => false
......@@ -32,6 +32,8 @@ ActiveRecord::Schema.define(:version => 20111011193702) do
end
add_index "aspect_visibilities", ["aspect_id"], :name => "index_aspect_visibilities_on_aspect_id"
add_index "aspect_visibilities", ["shareable_id", "shareable_type", "aspect_id"], :name => "shareable_and_aspect_id"
add_index "aspect_visibilities", ["shareable_id", "shareable_type"], :name => "index_aspect_visibilities_on_shareable_id_and_shareable_type"
create_table "aspects", :force => true do |t|
t.string "name", :null => false
......@@ -242,6 +244,24 @@ ActiveRecord::Schema.define(:version => 20111011193702) do
add_index "people", ["guid"], :name => "index_people_on_guid", :unique => true
add_index "people", ["owner_id"], :name => "index_people_on_owner_id", :unique => true
create_table "photos", :force => true do |t|