social_stream-base 0.20.0 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.rdoc +2 -2
  2. data/app/assets/stylesheets/base.css.scss +1 -1
  3. data/app/controllers/activities_controller.rb +1 -2
  4. data/app/controllers/profiles_controller.rb +40 -8
  5. data/app/controllers/search_controller.rb +6 -49
  6. data/app/helpers/search_helper.rb +4 -34
  7. data/app/models/activity_object.rb +37 -4
  8. data/app/models/actor.rb +6 -0
  9. data/app/models/relation.rb +15 -0
  10. data/app/models/tie.rb +6 -0
  11. data/app/views/comments/create.js.erb +12 -7
  12. data/app/views/messages/_form.html.erb +1 -1
  13. data/app/views/posts/create.js.erb +8 -3
  14. data/app/views/search/_extended_search.html.erb +1 -1
  15. data/app/views/search/_extended_tab.html.erb +5 -0
  16. data/app/views/search/_form.html.erb +3 -3
  17. data/app/views/search/index.js.erb +3 -3
  18. data/config/routes.rb +6 -2
  19. data/lib/logos/groups/1.jpg +0 -0
  20. data/lib/logos/groups/10.jpg +0 -0
  21. data/lib/logos/groups/11.jpg +0 -0
  22. data/lib/logos/groups/12.jpg +0 -0
  23. data/lib/logos/groups/2.jpg +0 -0
  24. data/lib/logos/groups/3.jpg +0 -0
  25. data/lib/logos/groups/4.jpg +0 -0
  26. data/lib/logos/groups/5.jpg +0 -0
  27. data/lib/logos/groups/6.jpg +0 -0
  28. data/lib/logos/groups/7.jpg +0 -0
  29. data/lib/logos/groups/8.jpg +0 -0
  30. data/lib/logos/groups/9.jpg +0 -0
  31. data/lib/logos/partners/1.jpg +0 -0
  32. data/lib/logos/partners/1.png +0 -0
  33. data/lib/logos/partners/2.jpg +0 -0
  34. data/lib/logos/partners/2.png +0 -0
  35. data/lib/logos/users/1.jpg +0 -0
  36. data/lib/logos/users/10.jpg +0 -0
  37. data/lib/logos/users/11.jpg +0 -0
  38. data/lib/logos/users/12.jpg +0 -0
  39. data/lib/logos/users/2.jpg +0 -0
  40. data/lib/logos/users/3.jpg +0 -0
  41. data/lib/logos/users/4.jpg +0 -0
  42. data/lib/logos/users/5.jpg +0 -0
  43. data/lib/logos/users/6.jpg +0 -0
  44. data/lib/logos/users/7.jpg +0 -0
  45. data/lib/logos/users/8.jpg +0 -0
  46. data/lib/logos/users/9.jpg +0 -0
  47. data/lib/social_stream-base.rb +8 -0
  48. data/lib/social_stream/base/dependencies.rb +3 -1
  49. data/lib/social_stream/base/thinking-sphinx.rb +3 -1
  50. data/lib/social_stream/base/version.rb +1 -1
  51. data/lib/social_stream/controllers/helpers.rb +36 -30
  52. data/lib/social_stream/controllers/objects.rb +89 -1
  53. data/lib/social_stream/controllers/subjects.rb +3 -1
  54. data/lib/social_stream/models/object.rb +18 -0
  55. data/lib/social_stream/models/subject.rb +2 -0
  56. data/lib/social_stream/population/activity_object.rb +55 -0
  57. data/lib/social_stream/{populate.rb → population/power_law.rb} +3 -4
  58. data/lib/social_stream/population/timestamps.rb +12 -0
  59. data/lib/social_stream/search.rb +107 -0
  60. data/lib/tasks/db/populate.rake +13 -26
  61. data/social_stream-base.gemspec +3 -1
  62. data/spec/models/post_spec.rb +14 -0
  63. metadata +110 -68
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -26,6 +26,12 @@ module SocialStream
26
26
  autoload :Supertype, 'social_stream/models/supertype'
27
27
  end
28
28
 
29
+ module Population
30
+ autoload :ActivityObject, 'social_stream/population/activity_object'
31
+ autoload :PowerLaw, 'social_stream/population/power_law'
32
+ autoload :Timestamps, 'social_stream/population/timestamps'
33
+ end
34
+
29
35
  module Routing
30
36
  module Constraints
31
37
  autoload :Custom, 'social_stream/routing/constraints/custom'
@@ -34,6 +40,8 @@ module SocialStream
34
40
  end
35
41
  end
36
42
 
43
+ autoload :Search, 'social_stream/search'
44
+
37
45
  module Views
38
46
  autoload :List, 'social_stream/views/list'
39
47
  autoload :Location, 'social_stream/views/location'
@@ -1,4 +1,6 @@
1
- # Monkey path Ruby on Rails
1
+ # Hash deep merge
2
+ require 'deep_merge'
3
+ # Monkey patch Ruby on Rails
2
4
  require 'rails/social_stream'
3
5
  # Database foreign keys
4
6
  require 'foreigner'
@@ -9,7 +9,9 @@ module SocialStream
9
9
  indexes activity_object.tags.name, :as => :tags
10
10
 
11
11
  has created_at
12
- has activity_object.author_action(:actor_id), :as => :author_id
12
+ has activity_object.author_actions(:actor_id), :as => :author_id
13
+ has activity_object.owner_actions(:actor_id), :as => :owner_id
14
+ has activity_object.activity_object_audiences(:relation_id), :as => :relation_ids
13
15
  end
14
16
  end
15
17
  end
@@ -1,5 +1,5 @@
1
1
  module SocialStream
2
2
  module Base
3
- VERSION = "0.20.0".freeze
3
+ VERSION = "0.20.1".freeze
4
4
  end
5
5
  end
@@ -12,22 +12,12 @@ module SocialStream
12
12
  end
13
13
 
14
14
  module ClassMethods
15
- # Add to controllers that have nested subjects. Examples are:
15
+ # Get the class relative to controller name
16
16
  #
17
- # class ProfilesController < InheritedResources::Base
18
- # belongs_to_subjects(:singleton => true) # provides /users/demo/profile
19
- # end
17
+ # Post #=> in PostsController
20
18
  #
21
- # class ActivitiesController < InheritedResources::Base
22
- # belongs_to_subjects # provides /users/demo/activities
23
- # end
24
- #
25
- def belongs_to_subjects(options = {})
26
- opts = { :polymorphic => true, :finder => :find_by_slug! }.update(options)
27
-
28
- args = SocialStream.subjects + [ opts ]
29
-
30
- belongs_to *args
19
+ def model_class
20
+ controller_name.classify.constantize
31
21
  end
32
22
  end
33
23
 
@@ -52,14 +42,7 @@ module SocialStream
52
42
  end
53
43
 
54
44
  # Returns the {SocialStream::Models::Subject subject} that is in the path, or
55
- # the {#current_subject} if some {User} is logged in.
56
- #
57
- # Requirements: the controller must inherit from +InheritedResources::Base+ and the method
58
- # {ClassMethods#belongs_to_subjects} must be called
59
- #
60
- # class PostsController < InheritedResources::Base
61
- # belongs_to_subjects :optional => true
62
- # end
45
+ # nil if it is not provided
63
46
  #
64
47
  # # /users/demo/posts
65
48
  # profile_subject #=> User demo
@@ -68,26 +51,35 @@ module SocialStream
68
51
  # profile_subject #=> Group test
69
52
  #
70
53
  # # /posts
71
- # profile_subject #=> current_subject
54
+ # profile_subject #=> nil
72
55
  #
73
56
  #
74
57
  def profile_subject
75
- @profile_subject ||= association_chain[-1] || current_subject
58
+ @profile_subject ||= find_profile_subject
59
+ end
60
+
61
+ # Is {#profile_subject} provided?
62
+ def profile_subject?
63
+ profile_subject.present?
76
64
  end
77
65
 
78
- # Go to sign in page if {#profile_subject} is blank
66
+ # Raise error if {#profile_subject} is not provided
79
67
  def profile_subject!
80
- @profile_subject ||= association_chain[-1] || warden.authenticate!
68
+ profile_subject || warden.authenticate!
81
69
  end
82
70
 
83
- # Profile subject is suitable for paths like:
84
- # /users/demo/posts
71
+ # Returns the {SocialStream::Models::Subject subject} that is in the path, or
72
+ # the {#current_subject} if some {User} is logged in.
85
73
  #
86
74
  # This method tries {#profile_subject} first and then {#current_subject}
87
75
  def profile_or_current_subject
88
76
  profile_subject || current_subject
89
- rescue
90
- current_subject
77
+ end
78
+
79
+ # This method tries {#profile_or_current_subject} but tries to
80
+ # authenticate if the user is not logged in
81
+ def profile_or_current_subject!
82
+ profile_or_current_subject || warden.authenticate!
91
83
  end
92
84
 
93
85
  # A {User} must be logged in and is equal to {#profile_subject}
@@ -128,6 +120,20 @@ module SocialStream
128
120
 
129
121
  session[:subject_type].constantize.find session[:subject_id]
130
122
  end
123
+
124
+ def find_profile_subject
125
+ SocialStream.subjects.each do |type|
126
+ id = params["#{ type }_id"]
127
+
128
+ next if id.blank?
129
+
130
+ subject_class = type.to_s.classify.constantize
131
+
132
+ return subject_class.find_by_slug! id
133
+ end
134
+
135
+ nil
136
+ end
131
137
  end
132
138
  end
133
139
  end
@@ -10,7 +10,7 @@ module SocialStream
10
10
 
11
11
  after_filter :increment_visit_count, :only => :show
12
12
 
13
- load_and_authorize_resource :except => :index
13
+ load_and_authorize_resource :except => [ :index, :search ]
14
14
 
15
15
  respond_to :html, :js
16
16
 
@@ -20,11 +20,50 @@ module SocialStream
20
20
 
21
21
  # Methods that should be included after the included block
22
22
  module UpperInstanceMethods
23
+ def search
24
+ collection_variable_set self.class.model_class.search(params[:q], search_options)
25
+
26
+ render :layout => false
27
+ end
28
+
23
29
  def destroy
24
30
  @post_activity = resource.post_activity
25
31
 
26
32
  destroy!
27
33
  end
34
+
35
+ private
36
+
37
+ def collection
38
+ collection_variable_get ||
39
+ collection_variable_set(build_collection)
40
+ end
41
+
42
+ def build_collection
43
+ collection =
44
+ self.class.model_class # @posts = Post
45
+
46
+ # /users/demo/posts
47
+ if profile_subject?
48
+ # get posts posted to demo's wall
49
+ collection = collection.owned_by(profile_subject)
50
+
51
+ # if current_subject != demo, auth filter results
52
+ unless profile_subject_is_current?
53
+ collection = collection.shared_with(current_subject)
54
+ end
55
+ else
56
+ # auth filter results
57
+ collection = collection.shared_with(current_subject)
58
+
59
+ # if logged in, show the posts from the people following
60
+ if user_signed_in?
61
+ collection = collection.followed_by(current_subject)
62
+ end
63
+ end
64
+
65
+ collection = collection.page(params[:page])
66
+ end
28
67
  end
29
68
 
30
69
  protected
@@ -37,6 +76,55 @@ module SocialStream
37
76
  resource_params.first[:author_id] = current_subject.try(:actor_id)
38
77
  resource_params.first[:user_author_id] = current_user.try(:actor_id)
39
78
  end
79
+
80
+ def collection_variable_get
81
+ instance_variable_get "@#{ controller_name }"
82
+ end
83
+
84
+ def collection_variable_set value
85
+ instance_variable_set "@#{ controller_name }", value
86
+ end
87
+
88
+ private
89
+
90
+ def search_options
91
+ opts = search_scope_options
92
+
93
+ # profile_subject
94
+ if profile_subject.present?
95
+ opts.deep_merge!( { :with => { :owner_id => profile_subject.actor_id } } )
96
+ end
97
+
98
+ # Authentication
99
+ opts.deep_merge!({ :with => { :relation_ids => Relation.ids_shared_with(current_subject) } } )
100
+
101
+ # Pagination
102
+ opts.merge!({
103
+ :order => :created_at,
104
+ :sort_mode => :desc,
105
+ :per_page => params[:per_page] || self.class.model_class.default_per_page,
106
+ :page => params[:page]
107
+ })
108
+
109
+ opts
110
+ end
111
+
112
+ def search_scope_options
113
+ if params[:scope].blank? || ! user_signed_in?
114
+ return {}
115
+ end
116
+
117
+ case params[:scope]
118
+ when "me"
119
+ { :with => { :author_id => [ current_subject.author_id ] } }
120
+ when "net"
121
+ { :with => { :author_id => current_subject.following_actor_and_self_ids } }
122
+ when "other"
123
+ { :without => { :author_id => current_subject.following_actor_and_self_ids } }
124
+ else
125
+ raise "Unknown search scope #{ params[:scope] }"
126
+ end
127
+ end
40
128
  end
41
129
  end
42
130
  end
@@ -4,12 +4,14 @@ module SocialStream
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
+ include SocialStream::Controllers::Helpers
8
+
7
9
  inherit_resources
8
10
  end
9
11
 
10
12
  # Overwrite {SocialStream::Controllers::Helpers::InstanceMethods#profile_subject}
11
13
  def profile_subject
12
- !resource.new_record? && resource || current_subject
14
+ self.class.model_class.find_by_slug(params[:id])
13
15
  end
14
16
  end
15
17
  end
@@ -11,6 +11,9 @@ module SocialStream
11
11
  has_many :received_actions,
12
12
  :through => :activity_object
13
13
 
14
+ has_many :activity_object_audiences,
15
+ :through => :activity_object
16
+
14
17
  unless self == Actor
15
18
  validates_presence_of :author_id, :owner_id, :user_author_id
16
19
 
@@ -29,6 +32,21 @@ module SocialStream
29
32
  joins(:activity_object).
30
33
  merge(ActivityObject.not_authored_by(subject))
31
34
  }
35
+
36
+ scope :owned_by, lambda { |subject|
37
+ joins(:activity_object).
38
+ merge(ActivityObject.owned_by(subject))
39
+ }
40
+
41
+ scope :shared_with, lambda { |subject|
42
+ joins(:activity_object).
43
+ merge(ActivityObject.shared_with(subject))
44
+ }
45
+
46
+ scope :followed_by, lambda { |subject|
47
+ joins(:activity_object).
48
+ merge(ActivityObject.followed_by(subject))
49
+ }
32
50
  end
33
51
  end
34
52
  end
@@ -71,6 +71,8 @@ module SocialStream
71
71
  indexes actor.slug
72
72
 
73
73
  has created_at
74
+ has Relation::Public.instance.id.to_s, :type => :integer, :as => :relation_ids
75
+
74
76
  end
75
77
  end
76
78
 
@@ -0,0 +1,55 @@
1
+ module SocialStream
2
+ module Population
3
+ class ActivityObject
4
+ def initialize(klass, &block)
5
+ puts "#{ klass.name } population"
6
+ start_time = Time.now
7
+
8
+ 50.times do
9
+ author = Actor.all[rand(Actor.all.size)]
10
+ owner = author
11
+ relation_ids = [Relation::Public.instance.id]
12
+
13
+ populate klass, author, owner, relation_ids, &block
14
+ end
15
+
16
+ if SocialStream.relation_model == :custom
17
+ PowerLaw.new(Tie.allowing('create', 'activity').all) do |t|
18
+
19
+ author = t.receiver
20
+ owner = t.sender
21
+ relation_ids = Array(t.relation_id)
22
+
23
+ populate klass, author, owner, relation_ids, &block
24
+ end
25
+ end
26
+
27
+ end_time = Time.now
28
+ puts ' -> ' + (end_time - start_time).round(4).to_s + 's'
29
+ end
30
+
31
+ def populate klass, author, owner, relation_ids, &block
32
+ user_author = ( author.subject_type == "User" ? author : author.user_author )
33
+ timestamps = Timestamps.new
34
+
35
+ o = klass.new
36
+
37
+ o.created_at = timestamps.created
38
+ o.updated_at = timestamps.updated
39
+ o.author_id = author.id
40
+ o.owner_id = owner.id
41
+ o.user_author_id = user_author.id
42
+ o.relation_ids = relation_ids
43
+
44
+ yield o
45
+
46
+ o.save!
47
+
48
+ o.post_activity.update_attributes(:created_at => o.created_at,
49
+ :updated_at => o.updated_at)
50
+
51
+ o
52
+ end
53
+ end
54
+ end
55
+ end