social_stream-base 0.22.4 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/app/controllers/activities_controller.rb +14 -12
  2. data/app/controllers/api_controller.rb +0 -13
  3. data/app/controllers/frontpage_controller.rb +0 -6
  4. data/app/models/activity.rb +21 -61
  5. data/app/models/actor.rb +4 -8
  6. data/app/models/audience.rb +2 -0
  7. data/app/models/comment.rb +2 -1
  8. data/app/models/group.rb +0 -2
  9. data/app/models/relation.rb +5 -1
  10. data/app/models/relation/custom.rb +17 -4
  11. data/app/models/tie.rb +0 -2
  12. data/app/models/user.rb +0 -2
  13. data/app/views/activities/_options.html.erb +1 -1
  14. data/app/views/activities/index.atom.builder +48 -0
  15. data/app/views/activity_objects/_activity_object.atom.erb +1 -0
  16. data/config/locales/en.yml +8 -0
  17. data/config/locales/es.yml +8 -0
  18. data/config/routes.rb +0 -8
  19. data/lib/rails/social_stream.rb +1 -1
  20. data/lib/social_stream-base.rb +5 -0
  21. data/lib/social_stream/ability/base.rb +4 -16
  22. data/lib/social_stream/activity_streams.rb +39 -0
  23. data/lib/social_stream/activity_streams/subtype.rb +11 -0
  24. data/lib/social_stream/activity_streams/supertype.rb +12 -0
  25. data/lib/social_stream/base/dependencies.rb +2 -0
  26. data/lib/social_stream/base/engine.rb +6 -0
  27. data/lib/social_stream/base/version.rb +1 -1
  28. data/lib/social_stream/models/object.rb +5 -0
  29. data/lib/social_stream/models/subject.rb +1 -1
  30. data/lib/social_stream/models/subtype.rb +2 -0
  31. data/lib/social_stream/models/supertype.rb +2 -0
  32. data/social_stream-base.gemspec +2 -0
  33. data/spec/controllers/activities_controller_spec.rb +18 -0
  34. data/spec/controllers/frontpage_controller_spec.rb +0 -5
  35. data/spec/models/activity_wall_spec.rb +96 -0
  36. data/spec/models/post_authorization_spec.rb +370 -0
  37. data/spec/models/post_spec.rb +0 -2
  38. data/spec/models/relation_spec.rb +22 -0
  39. data/spec/social_stream_activity_streams_spec.rb +16 -0
  40. data/spec/social_stream_spec.rb +1 -1
  41. metadata +27 -8
  42. data/app/assets/images/logos/actor/remote_subject.png +0 -0
  43. data/app/assets/images/logos/actor/remote_user.png +0 -0
  44. data/app/controllers/subjects_controller.rb +0 -7
  45. data/app/views/api/activity_atom_feed.atom.builder +0 -40
  46. data/app/views/frontpage/host_meta.xml.builder +0 -11
  47. data/spec/models/activity_authorization_spec.rb +0 -354
@@ -1,18 +1,20 @@
1
- class ActivitiesController < InheritedResources::Base
2
- actions :index
3
-
4
- respond_to :js
5
-
6
- protected
7
-
8
- def collection
9
- rel = params[:section].to_i if params[:section].present?
10
-
1
+ class ActivitiesController < ApplicationController
2
+ def index
11
3
  # should be activities.page(params[:page], :count => { :select => 'activity.id', :distinct => true }) but it is not working in Rails 3.0.3
12
4
  @activities ||= profile_subject.
13
5
  wall(:profile,
14
- :for => current_subject,
15
- :relation => rel).
6
+ :for => current_subject).
16
7
  page(params[:page])
8
+
9
+ respond_to do |format|
10
+ format.js
11
+ format.atom
12
+ end
13
+ end
14
+
15
+ def show
16
+ activity = Activity.find(params[:id])
17
+
18
+ redirect_to activity.direct_object || activity.receiver_subject
17
19
  end
18
20
  end
@@ -22,17 +22,4 @@ class ApiController < ApplicationController
22
22
 
23
23
  redirect_to :controller => :users, :action => :show, :format => params[:format], :id => params[:id], :auth_token => params[:auth_token]
24
24
  end
25
-
26
- def activity_atom_feed
27
- @subject = Actor.find_by_slug!(params[:id])
28
- # FIXME: why? check with Victor
29
- @subject ||= current_user
30
-
31
- @activities = @subject.wall(:home).page(params[:page]).per(10)
32
-
33
- respond_to do |format|
34
- format.atom
35
- end
36
- end
37
-
38
25
  end
@@ -7,12 +7,6 @@ class FrontpageController < ApplicationController
7
7
  end
8
8
  end
9
9
 
10
- # Webfinger protocol
11
- # http://code.google.com/p/webfinger/
12
- def host_meta
13
- end
14
-
15
-
16
10
  private
17
11
 
18
12
  def redirect_user_to_home
@@ -197,8 +197,8 @@ class Activity < ActiveRecord::Base
197
197
  case verb
198
198
  when "follow", "make-friend", "like"
199
199
  I18n.t "activity.verb.#{ verb }.#{ receiver.subject_type }.title",
200
- :subject => view.link_name(sender_subject),
201
- :contact => view.link_name(receiver_subject)
200
+ :subject => view.link_name(sender_subject),
201
+ :contact => view.link_name(receiver_subject)
202
202
  when "post", "update"
203
203
  if sender == receiver
204
204
  view.link_name sender_subject
@@ -212,6 +212,25 @@ class Activity < ActiveRecord::Base
212
212
  end.html_safe
213
213
  end
214
214
 
215
+ # Title for activity streams
216
+ def stream_title
217
+ # FIXMEEEEEEEEEEEEEEEEE
218
+ object = ( direct_object.present? ?
219
+ ( direct_object.is_a?(SocialStream::Models::Subject) ?
220
+ direct_object.name :
221
+ direct_object.title ) :
222
+ receiver.name )
223
+
224
+ I18n.t "activity.stream.title.#{ verb }",
225
+ :author => sender_subject.name,
226
+ :activity_object => object
227
+ end
228
+
229
+ # TODO: detailed description of activity
230
+ def stream_content
231
+ stream_title
232
+ end
233
+
215
234
  def notificable?
216
235
  is_root? or ['post','update'].include?(root.verb)
217
236
  end
@@ -245,65 +264,6 @@ class Activity < ActiveRecord::Base
245
264
  [parent] + siblings
246
265
  end
247
266
 
248
- # Is subject allowed to perform action on this {Activity}?
249
- def allow?(subject, action)
250
- return false if author.blank?
251
-
252
- case action
253
- when 'create'
254
- return false if subject.blank? || author_id != Actor.normalize_id(subject)
255
-
256
- rels = Relation.normalize(relation_ids)
257
-
258
- own_rels = rels.select{ |r| r.actor_id == author_id }
259
- # Consider Relation::Single as own_relations
260
- own_rels += rels.select{ |r| r.is_a?(Relation::Single) }
261
-
262
- foreign_rels = rels - own_rels
263
-
264
- # Only posting to own relations or allowed to post to foreign relations
265
- return foreign_rels.blank? && own_rels.present? ||
266
- foreign_rels.present? && Relation.allow(subject,
267
- action,
268
- 'activity',
269
- :in => foreign_rels).
270
- all.size == foreign_rels.size
271
-
272
- when 'read'
273
- return true if relations.select{ |r| r.is_a?(Relation::Public) }.any?
274
-
275
- return false if subject.blank?
276
-
277
- return true if [author_id, owner_id].include?(Actor.normalize_id(subject))
278
- when 'update'
279
- return true if [author_id, owner_id].include?(Actor.normalize_id(subject))
280
- when 'destroy'
281
- # We only allow destroying to sender and receiver by now
282
- return [author_id, owner_id].include?(Actor.normalize_id(subject))
283
- end
284
-
285
- Relation.
286
- allow?(subject, action, 'activity', :in => self.relation_ids, :public => false)
287
- end
288
-
289
- # Can subject delete the object of this activity?
290
- def delete_object_by?(subject)
291
- subject.present? &&
292
- direct_object.present? &&
293
- ! direct_object.is_a?(Actor) &&
294
- ! direct_object.class.ancestors.include?(SocialStream::Models::Subject) &&
295
- allow?(subject, 'destroy')
296
- end
297
-
298
- # Can subject edit the object of this activity?
299
- def edit_object_by?(subject)
300
- subject.present? &&
301
- direct_object.present? &&
302
- ! direct_object.is_a?(Actor) &&
303
- ! direct_object.class.ancestors.include?(SocialStream::Models::Subject) &&
304
- allow?(subject, 'update')
305
- end
306
-
307
267
  # Is this activity public?
308
268
  def public?
309
269
  relation_ids.include? Relation::Public.instance.id
@@ -136,13 +136,11 @@ class Actor < ActiveRecord::Base
136
136
  after_create :create_initial_relations
137
137
 
138
138
  after_create :save_or_create_profile
139
-
140
- class << self
141
- def find_by_webfinger!(link)
142
- link =~ /(acct:)?(.*)@/
143
139
 
144
- find_by_slug! $2
145
- end
140
+ # FIXME SocialStream::ActivityStreams::Supertype should take precedence over
141
+ # SocialStream::ActivityStreams::Subtype
142
+ def as_object_type
143
+ subtype_instance.as_object_type
146
144
  end
147
145
 
148
146
  #Returning the email address of the model if an email should be sent for this object (Message or Notification).
@@ -590,5 +588,3 @@ class Actor < ActiveRecord::Base
590
588
  mailbox.inbox(:unread => true).count(:id, :distinct => true)
591
589
  end
592
590
  end
593
-
594
- ActiveSupport.run_load_hooks(:actor, Actor)
@@ -7,3 +7,5 @@ class Audience < ActiveRecord::Base
7
7
  belongs_to :activity
8
8
  belongs_to :relation
9
9
  end
10
+
11
+ ActiveSupport.run_load_hooks(:audience, Audience)
@@ -12,7 +12,8 @@ class Comment < ActiveRecord::Base
12
12
  end
13
13
 
14
14
  def parent_post
15
- self.post_activity.parent.direct_object
15
+ _activity_parent_id && _activity_parent.direct_object ||
16
+ post_activity.parent.direct_object
16
17
  end
17
18
 
18
19
  def title
@@ -57,5 +57,3 @@ class Group < ActiveRecord::Base
57
57
  end
58
58
  end
59
59
  end
60
-
61
- ActiveSupport.run_load_hooks(:group, Group)
@@ -181,6 +181,11 @@ class Relation < ActiveRecord::Base
181
181
  self.class.positive_names.include?(self.class.to_s)
182
182
  end
183
183
 
184
+ # Does this relation include the follow permission?
185
+ def follow?
186
+ permissions.follow.any?
187
+ end
188
+
184
189
  private
185
190
 
186
191
  # Before create callback
@@ -190,4 +195,3 @@ class Relation < ActiveRecord::Base
190
195
  self.sender_type = actor.subject_type
191
196
  end
192
197
  end
193
-
@@ -5,8 +5,11 @@
5
5
  # Default relations are defined at config/relations.yml
6
6
  #
7
7
  class Relation::Custom < Relation
8
- # Default relations are defined in this configuration file
9
- CONFIG = File.join(::Rails.root, 'config', 'relations.yml')
8
+ # Default relations shipped with Social Stream
9
+ DEFAULT = {}
10
+
11
+ # Default relations are re-defined in this configuration file
12
+ CONFIG_FILE = File.join(::Rails.root, 'config', 'relations.yml')
10
13
 
11
14
  # This is weird. We must call #inspect before has_ancestry for Relation::Custom
12
15
  # to recognize STI
@@ -21,14 +24,14 @@ class Relation::Custom < Relation
21
24
  class << self
22
25
  # Relations configuration
23
26
  def config
24
- @config ||= YAML.load_file(CONFIG)
27
+ @config ||= build_config
25
28
  end
26
29
 
27
30
  def defaults_for(actor)
28
31
  cfg_rels = config[actor.subject_type.underscore]
29
32
 
30
33
  if cfg_rels.nil?
31
- raise "Undefined relations for subject type #{ actor.subject_type }. Please, add an entry to #{ CONFIG }"
34
+ raise "Undefined relations for subject type #{ actor.subject_type }. Please, add an entry to #{ CONFIG_FILE }"
32
35
  end
33
36
 
34
37
  rels = {}
@@ -62,6 +65,14 @@ class Relation::Custom < Relation
62
65
  def strongest
63
66
  roots
64
67
  end
68
+
69
+ private
70
+
71
+ # Gets the default relations defined in DEFAULT and updates the values
72
+ # from the CONFIG_FILE configuration file
73
+ def build_config
74
+ DEFAULT.merge YAML.load_file(CONFIG_FILE)
75
+ end
65
76
  end
66
77
 
67
78
  # Compare two relations
@@ -110,3 +121,5 @@ class Relation::Custom < Relation
110
121
  end
111
122
  end
112
123
  end
124
+
125
+ ActiveSupport.run_load_hooks(:relation_custom, Relation::Custom)
@@ -156,5 +156,3 @@ class Tie < ActiveRecord::Base
156
156
  contact.sender_id == relation.actor_id
157
157
  end
158
158
  end
159
-
160
- ActiveSupport.run_load_hooks(:tie, Tie)
@@ -153,5 +153,3 @@ class User < ActiveRecord::Base
153
153
 
154
154
  end
155
155
  end
156
-
157
- ActiveSupport.run_load_hooks(:user, User)
@@ -22,7 +22,7 @@
22
22
  </div>
23
23
  <% end %>
24
24
 
25
- <% if activity.delete_object_by?(current_subject) %>
25
+ <% if activity.direct_object && can?(:destroy, activity.direct_object) %>
26
26
  <div class="verb_delete">
27
27
  · <%= link_to t('activity.delete'), activity.direct_object , :confirm => t('confirm_delete',
28
28
  :scope => activity.direct_object.class.to_s.underscore), :method => :delete,
@@ -0,0 +1,48 @@
1
+ atom_feed('xmlns:activity' => 'http://activitystrea.ms/spec/1.0/') do |feed|
2
+ feed.link :rel => 'next', :href => url_for(:only_path => false, :page => params[:page].to_i + 1, :format => :atom)
3
+ if params[:page].to_i > 1
4
+ feed.link :rel => 'previous', :href => url_for(:only_path => false, :page => params[:page].to_i - 1, :format => :atom)
5
+ end
6
+
7
+ #FIXME find a way to decouple the view from here
8
+
9
+ if defined? SocialStream::Ostatus
10
+ feed.link :rel => 'hub', :href => SocialStream::Ostatus.hub
11
+ feed.link rel: 'salmon', href: salmon_url(profile_subject.slug)
12
+ end
13
+
14
+ feed.title(t 'activity.stream.atom_title', subject: profile_subject.name)
15
+ feed.updated(@activities.first.present? ? @activities.first.updated_at : Time.now)
16
+
17
+ feed.author do
18
+ feed.name(profile_subject.name)
19
+ feed.uri("acct:#{ profile_subject.slug }@#{ request.host_with_port }")
20
+ feed.tag!('activity:object-type', profile_subject.as_object_type.to_s)
21
+ end
22
+
23
+ @activities.each do |activity|
24
+ feed.entry(activity) do |entry|
25
+ entry.title(activity.stream_title)
26
+ entry.summary(activity.direct_object.try(:description))
27
+
28
+ entry.author do |a|
29
+ a.name(activity.sender.name)
30
+ a.uri("acct:#{ activity.sender.slug }@#{ request.host_with_port }")
31
+ a.tag!('activity:object-type', activity.sender.as_object_type.to_s)
32
+ end
33
+
34
+ #TODO Ostatus mentions:
35
+ # entry.link rel: mentioned, href: "acct:#{ mentioned.slug }@#{ host_with_port }"
36
+
37
+ entry.tag!('activity:verb', activity.verb)
38
+
39
+ if (obj = activity.direct_object).present?
40
+ entry.tag!('activity:object') do |act_obj|
41
+ act_obj.title(obj.title)
42
+ act_obj.tag!('activity:object-type', obj.as_object_type.to_s)
43
+ act_obj.published(obj.created_at)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -62,6 +62,14 @@ en:
62
62
  group: "Members of %{receiver}"
63
63
  user: "Contacts of %{receiver}"
64
64
  sending: "Sending"
65
+ stream:
66
+ atom_title: "Activity Stream from %{subject}"
67
+ title:
68
+ follow: "%{author} added %{activity_object} as contact"
69
+ like: "%{author} likes %{activity_object}"
70
+ make-friend: "%{author} also added %{activity_object} as contact"
71
+ post: "%{author} posted %{activity_object}"
72
+ updated: "%{author} posted %{activity_object}"
65
73
  title: "Activities"
66
74
  to_comment: "Comment"
67
75
  unlike: "I do not like anymore"
@@ -61,6 +61,14 @@ es:
61
61
  group: "Integrantes de %{receiver}"
62
62
  user: "Contactos de %{receiver}"
63
63
  sending: "Enviando"
64
+ stream:
65
+ atom_title: "Actividades de %{subject}"
66
+ title:
67
+ follow: "%{author} añadió a %{activity_object} como contacto"
68
+ like: "A %{author} le gusta %{activity_object}"
69
+ make-friend: "%{author} también añadió a %{activity_object} como contacto"
70
+ post: "%{author} publicó %{activity_object}"
71
+ updated: "%{author} actualizó %{activity_object}"
64
72
  title: "Actividades"
65
73
  to_comment: "Comentar"
66
74
  unlike: "Ya no me gusta"
@@ -101,21 +101,13 @@ Rails.application.routes.draw do
101
101
  match 'api/user/:id' => 'api#users', :as => :api_user
102
102
  match 'api/me' => 'api#users', :as => :api_me
103
103
  match 'api/me/home/' => 'api#activity_atom_feed', :format => 'atom', :as => :api_my_home
104
- match 'api/user/:id/public' => 'api#activity_atom_feed', :format => 'atom', :as => :api_user_activities
105
104
 
106
105
  match 'api/me/contacts' => 'contacts#index', :format => 'json', :as => :api_contacts
107
106
  match 'api/subjects/:s/contacts' => 'contacts#index', :format => 'json', :as => :api_subject_contacts
108
107
  ##/API##
109
-
110
108
 
111
109
  #Background tasks
112
110
  constraints SocialStream::Routing::Constraints::Resque.new do
113
111
  mount Resque::Server, :at => "/resque"
114
112
  end
115
-
116
- # Webfinger
117
- match '.well-known/host-meta',:to => 'frontpage#host_meta'
118
-
119
- # Find subjects by slug
120
- match 'subjects/lrdd/:id' => 'subjects#lrdd', :as => 'subject_lrdd'
121
113
  end
@@ -5,7 +5,7 @@ class ActionDispatch::Http::UploadedFile
5
5
  def initialize_with_magic(*args, &block)
6
6
  initialize_without_magic(*args, &block)
7
7
 
8
- if (unix_file = `which file`.chomp).present? && File.exists?(unix_file)
8
+ if (unix_file = `which file`.try(:chomp)).present? && File.exists?(unix_file)
9
9
  `#{ unix_file } -v 2>&1` =~ /^file-(.*)$/
10
10
  version = $1
11
11
 
@@ -4,6 +4,11 @@ require 'social_stream/base/dependencies'
4
4
  # Provides your Rails application with social network and activity stream support
5
5
  module SocialStream
6
6
  autoload :Ability, 'social_stream/ability'
7
+ autoload :ActivityStreams, 'social_stream/activity_streams'
8
+ module ActivityStreams
9
+ autoload :Supertype, 'social_stream/activity_streams/supertype'
10
+ autoload :Subtype, 'social_stream/activity_streams/subtype'
11
+ end
7
12
  autoload :D3, 'social_stream/d3'
8
13
  autoload :Populate, 'social_stream/populate'
9
14
  autoload :Relations, 'social_stream/relations'
@@ -37,40 +37,28 @@ module SocialStream
37
37
  end
38
38
 
39
39
  can :create, Comment do |c|
40
- c._activity_parent.allow?(subject, 'read')
40
+ can? :read, c.parent_post
41
41
  end
42
42
 
43
43
  can :read, Comment do |c|
44
- c.post_activity.allow?(subject, 'read')
44
+ can? :read, c.parent_post
45
45
  end
46
46
 
47
47
  can :update, Comment do |c|
48
- c.post_activity.allow?(subject, 'update')
48
+ can? :update, c.parent_post
49
49
  end
50
50
 
51
51
  can :destroy, Comment do |c|
52
- c.post_activity.allow?(subject, 'destroy')
52
+ can? :destroy, c.parent_post
53
53
  end
54
54
 
55
55
  # Activities
56
- can :create, Activity do |a|
57
- a.allow?(subject, 'create')
58
- end
59
-
60
56
  can :read, Activity do |a|
61
57
  a.public? ||
62
58
  subject.present? &&
63
59
  a.audience.include?(subject.actor)
64
60
  end
65
61
 
66
- can :update, Activity do |a|
67
- a.allow?(subject, 'update')
68
- end
69
-
70
- can :destroy, Activity do |a|
71
- a.allow?(subject, 'destroy')
72
- end
73
-
74
62
  # Users
75
63
  can :read, User
76
64