social_stream-base 0.20.2 → 0.21.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.
- data/app/assets/images/btn/public.png +0 -0
- data/app/assets/images/btn/restricted.png +0 -0
- data/app/assets/javascripts/social_stream.timeline.js +2 -0
- data/app/assets/javascripts/social_stream.wall.js.erb +10 -1
- data/app/assets/stylesheets/activities.css.scss.erb +13 -2
- data/app/assets/stylesheets/base.css.scss +1 -1
- data/app/controllers/audience_controller.rb +16 -0
- data/app/models/activity.rb +111 -39
- data/app/models/activity_object.rb +1 -9
- data/app/models/actor.rb +42 -53
- data/app/models/contact.rb +0 -21
- data/app/models/tie.rb +1 -1
- data/app/views/activities/_new.html.erb +2 -2
- data/app/views/activities/_options.html.erb +7 -1
- data/app/views/audience/_list.html.erb +8 -0
- data/app/views/audience/index.js.erb +1 -0
- data/config/locales/en.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20120526171311_remove_activity_channels.rb +35 -0
- data/lib/social_stream/ability/base.rb +3 -1
- data/lib/social_stream/base/engine.rb +0 -1
- data/lib/social_stream/base/version.rb +1 -1
- data/lib/social_stream-base.rb +0 -1
- data/lib/tasks/db/populate.rake +6 -4
- data/spec/controllers/audience_controller_spec.rb +40 -0
- data/spec/controllers/comments_controller_spec.rb +3 -3
- data/spec/factories/activity.rb +12 -6
- data/spec/models/tie_spec.rb +7 -4
- metadata +9 -5
- data/app/assets/images/btn/btn_security.png +0 -0
- data/app/models/channel.rb +0 -64
- data/lib/social_stream/models/channeled.rb +0 -56
|
Binary file
|
|
Binary file
|
|
@@ -38,6 +38,12 @@ SocialStream.Wall = (function(SS, $, undefined){
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
var changeSecurityImage = function(type) {
|
|
42
|
+
$('#security_chzn .chzn-choices').
|
|
43
|
+
css('background-image', 'url(<%= asset_path('btn/') %>' + type + '.png)');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
41
47
|
var initSecuritySelect = function(){
|
|
42
48
|
var default_security_width = '100px';
|
|
43
49
|
|
|
@@ -63,6 +69,9 @@ SocialStream.Wall = (function(SS, $, undefined){
|
|
|
63
69
|
chosen.results_update_field();
|
|
64
70
|
}
|
|
65
71
|
}
|
|
72
|
+
changeSecurityImage('public');
|
|
73
|
+
} else {
|
|
74
|
+
changeSecurityImage('restricted');
|
|
66
75
|
}
|
|
67
76
|
});
|
|
68
77
|
|
|
@@ -145,6 +154,6 @@ SocialStream.Wall = (function(SS, $, undefined){
|
|
|
145
154
|
addInitCallback: addInitCallback,
|
|
146
155
|
init: init,
|
|
147
156
|
activateAntiRebounds: activateAntiRebounds,
|
|
148
|
-
unblockForms: unblockForms
|
|
157
|
+
unblockForms: unblockForms
|
|
149
158
|
};
|
|
150
159
|
}) (SocialStream, jQuery)
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
#security_chzn .chzn-choices {
|
|
29
29
|
padding-left: 20px;
|
|
30
|
-
background: url('btn/
|
|
30
|
+
background: url('btn/restricted.png') no-repeat 10px center;
|
|
31
31
|
}
|
|
32
32
|
/******************* WALL - ACTIVITY ***************/
|
|
33
33
|
.super_activity{width: 95%;}
|
|
@@ -55,7 +55,6 @@
|
|
|
55
55
|
|
|
56
56
|
.security, .post_time_ago, .verb_comment, .verb_like, .verb_comment, .verb_delete{ display: inline-block;}
|
|
57
57
|
|
|
58
|
-
|
|
59
58
|
/************* ACTIVITY - FOOTER *********/
|
|
60
59
|
.space_comments { padding-top: 1px; padding-bottom: 1px;}
|
|
61
60
|
.space_activities { text-align:center; padding: 0px 0px 0px 1px; width:100%;}
|
|
@@ -88,3 +87,15 @@
|
|
|
88
87
|
.input_new_comments_container{min-height: 30px; position: relative; }
|
|
89
88
|
|
|
90
89
|
.activity_likes{ margin-bottom: 2px; }
|
|
90
|
+
|
|
91
|
+
.timeline-130 {
|
|
92
|
+
width: 130px;
|
|
93
|
+
margin: 10px;
|
|
94
|
+
float: left;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.audience_logo {
|
|
98
|
+
padding: 2px;
|
|
99
|
+
display: inline-block;
|
|
100
|
+
}
|
|
101
|
+
|
|
@@ -137,7 +137,7 @@ div.chzn-container ul.chzn-choices li.search-field input{ cursor:pointer;}
|
|
|
137
137
|
|
|
138
138
|
/*************MENU ICON SECTION**********/
|
|
139
139
|
.menu_header{ border-bottom: thin solid $separation-color; width:14.5em; padding-left:3px; padding-right:3px;}
|
|
140
|
-
.menu_icon{ vertical-align: middle; padding-bottom: 3px; padding-right:
|
|
140
|
+
.menu_icon{ vertical-align: middle; padding-bottom: 3px; padding-right: 2px; padding-left: 2px;
|
|
141
141
|
display: inline-block;}
|
|
142
142
|
|
|
143
143
|
/*************SPACES SECTION *************/
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class AudienceController < ApplicationController
|
|
2
|
+
before_filter :read_activity
|
|
3
|
+
|
|
4
|
+
respond_to :js
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def read_activity
|
|
12
|
+
@activity = Activity.find params[:activity_id]
|
|
13
|
+
|
|
14
|
+
authorize! :read, @activity
|
|
15
|
+
end
|
|
16
|
+
end
|
data/app/models/activity.rb
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
# Activities follow the {Activity Streams}[http://activitystrea.ms/] standard.
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
# Every activity is attached to a {Channel}, which defines the sender and the receiver of the {Activity}
|
|
3
|
+
# Every {Activity} has an {#author}, {#user_author} and {#owner}
|
|
5
4
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# author:: Is the {SocialStream::Models::Subject subject} that originated
|
|
6
|
+
# the activity. The entity that posted something, liked, etc..
|
|
8
7
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
8
|
+
# user_author:: The {User} logged in when the {Activity} was created.
|
|
9
|
+
# If the {User} has not changed the session to represent
|
|
10
|
+
# other entity (a {Group} for example), the user_author
|
|
11
|
+
# will be the same as the author.
|
|
11
12
|
#
|
|
12
|
-
#
|
|
13
|
+
# owner:: The {SocialStream::Models::Subject subject} whose wall was posted
|
|
14
|
+
# or comment was liked, etc..
|
|
15
|
+
#
|
|
16
|
+
# == {Audience Audiences} and visibility
|
|
17
|
+
# Each activity is attached to one or more {Relation relations}, which define
|
|
18
|
+
# the {SocialStream::Models::Subject subject} that can reach the activity
|
|
19
|
+
#
|
|
20
|
+
# In the case of a {Relation::Public public relation} everyone will be
|
|
21
|
+
# able to see the activity.
|
|
22
|
+
#
|
|
23
|
+
# In the case of {Relation::Custom custom relations}, only the subjects
|
|
24
|
+
# that have a {Tie} with that relation (in other words, the contacts that
|
|
25
|
+
# have been added as friends with that relation} will be able to reach the {Activity}
|
|
13
26
|
#
|
|
14
|
-
include NotificationsHelper
|
|
15
|
-
|
|
16
27
|
class Activity < ActiveRecord::Base
|
|
17
|
-
#
|
|
18
|
-
|
|
28
|
+
# FIXME: this does not follow the Rails way
|
|
29
|
+
include NotificationsHelper
|
|
19
30
|
|
|
20
31
|
# This has to be declared before 'has_ancestry' to work around rails issue #670
|
|
21
32
|
# See: https://github.com/rails/rails/issues/670
|
|
@@ -27,6 +38,13 @@ class Activity < ActiveRecord::Base
|
|
|
27
38
|
|
|
28
39
|
belongs_to :activity_verb
|
|
29
40
|
|
|
41
|
+
belongs_to :author,
|
|
42
|
+
:class_name => "Actor"
|
|
43
|
+
belongs_to :owner,
|
|
44
|
+
:class_name => "Actor"
|
|
45
|
+
belongs_to :user_author,
|
|
46
|
+
:class_name => "Actor"
|
|
47
|
+
|
|
30
48
|
has_many :audiences, :dependent => :destroy
|
|
31
49
|
has_many :relations, :through => :audiences
|
|
32
50
|
|
|
@@ -35,10 +53,26 @@ class Activity < ActiveRecord::Base
|
|
|
35
53
|
has_many :activity_objects,
|
|
36
54
|
:through => :activity_object_activities
|
|
37
55
|
|
|
56
|
+
scope :authored_by, lambda { |subject|
|
|
57
|
+
where(:author_id => Actor.normalize_id(subject))
|
|
58
|
+
}
|
|
59
|
+
scope :owned_by, lambda { |subject|
|
|
60
|
+
where(:owner_id => Actor.normalize_id(subject))
|
|
61
|
+
}
|
|
62
|
+
scope :authored_or_owned_by, lambda { |subjects|
|
|
63
|
+
ids = Actor.normalize_id(subjects)
|
|
64
|
+
|
|
65
|
+
where(arel_table[:author_id].in(ids).or(arel_table[:owner_id].in(ids)))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
scope :shared_with, lambda { |subject|
|
|
69
|
+
joins(:audiences).
|
|
70
|
+
merge(Audience.where(:relation_id => Relation.ids_shared_with(subject)))
|
|
71
|
+
}
|
|
72
|
+
|
|
38
73
|
scope :wall, lambda { |args|
|
|
39
74
|
q =
|
|
40
75
|
select("DISTINCT activities.*").
|
|
41
|
-
joins(:channel).
|
|
42
76
|
joins(:audiences).
|
|
43
77
|
joins(:relations).
|
|
44
78
|
roots
|
|
@@ -48,14 +82,13 @@ class Activity < ActiveRecord::Base
|
|
|
48
82
|
where('activity_objects.object_type' => args[:object_type])
|
|
49
83
|
end
|
|
50
84
|
|
|
51
|
-
channels = Channel.arel_table
|
|
52
85
|
audiences = Audience.arel_table
|
|
53
86
|
relations = Relation.arel_table
|
|
54
87
|
|
|
55
88
|
owner_conditions =
|
|
56
|
-
|
|
57
|
-
or(
|
|
58
|
-
or(
|
|
89
|
+
arel_table[:author_id].eq(Actor.normalize_id(args[:owner])).
|
|
90
|
+
or(arel_table[:user_author_id].eq(Actor.normalize_id(args[:owner]))).
|
|
91
|
+
or(arel_table[:owner_id].eq(Actor.normalize_id(args[:owner])))
|
|
59
92
|
|
|
60
93
|
audience_conditions =
|
|
61
94
|
audiences[:relation_id].in(args[:relation_ids]).
|
|
@@ -65,16 +98,16 @@ class Activity < ActiveRecord::Base
|
|
|
65
98
|
case args[:type]
|
|
66
99
|
when :home
|
|
67
100
|
followed_conditions =
|
|
68
|
-
|
|
69
|
-
or(
|
|
101
|
+
arel_table[:author_id].in(args[:followed]).
|
|
102
|
+
or(arel_table[:owner_id].in(args[:followed]))
|
|
70
103
|
|
|
71
104
|
owner_conditions.
|
|
72
105
|
or(followed_conditions.and(audience_conditions))
|
|
73
106
|
when :profile
|
|
74
107
|
if args[:for].present?
|
|
75
108
|
visitor_conditions =
|
|
76
|
-
|
|
77
|
-
or(
|
|
109
|
+
arel_table[:author_id].eq(Actor.normalize_id(args[:for])).
|
|
110
|
+
or(arel_table[:owner_id].eq(Actor.normalize_id(args[:for])))
|
|
78
111
|
|
|
79
112
|
owner_conditions.
|
|
80
113
|
and(visitor_conditions.or(audience_conditions))
|
|
@@ -93,7 +126,7 @@ class Activity < ActiveRecord::Base
|
|
|
93
126
|
after_create :increment_like_count
|
|
94
127
|
after_destroy :decrement_like_count, :delete_notifications
|
|
95
128
|
|
|
96
|
-
validates_presence_of :relations
|
|
129
|
+
validates_presence_of :author_id, :user_author_id, :owner_id, :relations
|
|
97
130
|
|
|
98
131
|
#For now, it should be the last one
|
|
99
132
|
#FIXME
|
|
@@ -109,12 +142,37 @@ class Activity < ActiveRecord::Base
|
|
|
109
142
|
self.activity_verb = ActivityVerb[name]
|
|
110
143
|
end
|
|
111
144
|
|
|
145
|
+
# The {SocialStream::Models::Subject subject} author
|
|
146
|
+
def author_subject
|
|
147
|
+
author.subject
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# The {SocialStream::Models::Subject subject} owner
|
|
151
|
+
def owner_subject
|
|
152
|
+
owner.subject
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# The {SocialStream::Models::Subject subject} user actor
|
|
156
|
+
def user_author_subject
|
|
157
|
+
user_author.subject
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Does this {Activity} have the same sender and receiver?
|
|
161
|
+
def reflexive?
|
|
162
|
+
author_id == owner_id
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Is the author represented in this {Activity}?
|
|
166
|
+
def represented_author?
|
|
167
|
+
author_id != user_author_id
|
|
168
|
+
end
|
|
169
|
+
|
|
112
170
|
# The {Actor} author of this activity
|
|
113
171
|
#
|
|
114
172
|
# This method provides the {Actor}. Use {#sender_subject} for the {SocialStream::Models::Subject Subject}
|
|
115
173
|
# ({User}, {Group}, etc..)
|
|
116
174
|
def sender
|
|
117
|
-
|
|
175
|
+
author
|
|
118
176
|
end
|
|
119
177
|
|
|
120
178
|
# The {SocialStream::Models::Subject Subject} author of this activity
|
|
@@ -122,7 +180,7 @@ class Activity < ActiveRecord::Base
|
|
|
122
180
|
# This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
|
|
123
181
|
# Use {#sender} for the {Actor}.
|
|
124
182
|
def sender_subject
|
|
125
|
-
|
|
183
|
+
author_subject
|
|
126
184
|
end
|
|
127
185
|
|
|
128
186
|
# The wall where the activity is shown belongs to receiver
|
|
@@ -130,7 +188,7 @@ class Activity < ActiveRecord::Base
|
|
|
130
188
|
# This method provides the {Actor}. Use {#receiver_subject} for the {SocialStream::Models::Subject Subject}
|
|
131
189
|
# ({User}, {Group}, etc..)
|
|
132
190
|
def receiver
|
|
133
|
-
|
|
191
|
+
owner
|
|
134
192
|
end
|
|
135
193
|
|
|
136
194
|
# The wall where the activity is shown belongs to the receiver
|
|
@@ -138,7 +196,7 @@ class Activity < ActiveRecord::Base
|
|
|
138
196
|
# This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
|
|
139
197
|
# Use {#receiver} for the {Actor}.
|
|
140
198
|
def receiver_subject
|
|
141
|
-
|
|
199
|
+
owner_subject
|
|
142
200
|
end
|
|
143
201
|
|
|
144
202
|
# The comments about this activity
|
|
@@ -152,7 +210,7 @@ class Activity < ActiveRecord::Base
|
|
|
152
210
|
end
|
|
153
211
|
|
|
154
212
|
def liked_by(user) #:nodoc:
|
|
155
|
-
likes.
|
|
213
|
+
likes.authored_by(user)
|
|
156
214
|
end
|
|
157
215
|
|
|
158
216
|
# Does user like this activity?
|
|
@@ -162,12 +220,11 @@ class Activity < ActiveRecord::Base
|
|
|
162
220
|
|
|
163
221
|
# Build a new children activity where subject like this
|
|
164
222
|
def new_like(subject, user)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
:
|
|
170
|
-
:relation_ids => self.relation_ids
|
|
223
|
+
a = children.new :verb => "like",
|
|
224
|
+
:author_id => Actor.normalize_id(subject),
|
|
225
|
+
:user_author_id => Actor.normalize_id(user),
|
|
226
|
+
:owner_id => owner_id,
|
|
227
|
+
:relation_ids => self.relation_ids
|
|
171
228
|
|
|
172
229
|
if direct_activity_object.present?
|
|
173
230
|
a.activity_objects << direct_activity_object
|
|
@@ -218,7 +275,7 @@ class Activity < ActiveRecord::Base
|
|
|
218
275
|
participants.each do |p|
|
|
219
276
|
p.notify(notification_subject, "Youre not supposed to see this", self) unless p == sender
|
|
220
277
|
end
|
|
221
|
-
elsif ['like','follow','make-friend','post','update'].include? verb and !
|
|
278
|
+
elsif ['like','follow','make-friend','post','update'].include? verb and !reflexive?
|
|
222
279
|
receiver.notify(notification_subject, "Youre not supposed to see this", self)
|
|
223
280
|
end
|
|
224
281
|
true
|
|
@@ -241,15 +298,15 @@ class Activity < ActiveRecord::Base
|
|
|
241
298
|
|
|
242
299
|
# Is subject allowed to perform action on this {Activity}?
|
|
243
300
|
def allow?(subject, action)
|
|
244
|
-
return false if
|
|
301
|
+
return false if author.blank?
|
|
245
302
|
|
|
246
303
|
case action
|
|
247
304
|
when 'create'
|
|
248
|
-
return false if subject.blank? ||
|
|
305
|
+
return false if subject.blank? || author_id != Actor.normalize_id(subject)
|
|
249
306
|
|
|
250
307
|
rels = Relation.normalize(relation_ids)
|
|
251
308
|
|
|
252
|
-
own_rels = rels.select{ |r| r.actor_id ==
|
|
309
|
+
own_rels = rels.select{ |r| r.actor_id == author_id }
|
|
253
310
|
# Consider Relation::Single as own_relations
|
|
254
311
|
own_rels += rels.select{ |r| r.is_a?(Relation::Single) }
|
|
255
312
|
|
|
@@ -268,12 +325,12 @@ class Activity < ActiveRecord::Base
|
|
|
268
325
|
|
|
269
326
|
return false if subject.blank?
|
|
270
327
|
|
|
271
|
-
return true if [
|
|
328
|
+
return true if [author_id, owner_id].include?(Actor.normalize_id(subject))
|
|
272
329
|
when 'update'
|
|
273
|
-
return true if [
|
|
330
|
+
return true if [author_id, owner_id].include?(Actor.normalize_id(subject))
|
|
274
331
|
when 'destroy'
|
|
275
332
|
# We only allow destroying to sender and receiver by now
|
|
276
|
-
return [
|
|
333
|
+
return [author_id, owner_id].include?(Actor.normalize_id(subject))
|
|
277
334
|
end
|
|
278
335
|
|
|
279
336
|
Relation.
|
|
@@ -298,6 +355,21 @@ class Activity < ActiveRecord::Base
|
|
|
298
355
|
allow?(subject, 'update')
|
|
299
356
|
end
|
|
300
357
|
|
|
358
|
+
# Is this activity public?
|
|
359
|
+
def public?
|
|
360
|
+
relation_ids.include? Relation::Public.instance.id
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# The {Actor Actors} this activity is shared with
|
|
364
|
+
def audience
|
|
365
|
+
raise "Cannot get the audience of a public activity!" if public?
|
|
366
|
+
|
|
367
|
+
[ author, user_author, owner ].uniq |
|
|
368
|
+
Actor.
|
|
369
|
+
joins(:received_ties).
|
|
370
|
+
merge(Tie.where(:relation_id => relation_ids))
|
|
371
|
+
end
|
|
372
|
+
|
|
301
373
|
# The {Relation} with which activity is shared
|
|
302
374
|
def audience_in_words(subject, options = {})
|
|
303
375
|
options[:details] ||= :full
|
|
@@ -217,15 +217,7 @@ class ActivityObject < ActiveRecord::Base
|
|
|
217
217
|
|
|
218
218
|
@valid_relations = true
|
|
219
219
|
|
|
220
|
-
self.relation_ids =
|
|
221
|
-
if SocialStream.relation_model == :custom
|
|
222
|
-
owner.
|
|
223
|
-
relations.
|
|
224
|
-
allowing('read', 'activity').
|
|
225
|
-
map(&:id)
|
|
226
|
-
else
|
|
227
|
-
Array.wrap Relation::Public.instance.id
|
|
228
|
-
end
|
|
220
|
+
self.relation_ids = owner.activity_relation_ids
|
|
229
221
|
end
|
|
230
222
|
|
|
231
223
|
# validate method
|
data/app/models/actor.rb
CHANGED
|
@@ -73,16 +73,6 @@ class Actor < ActiveRecord::Base
|
|
|
73
73
|
has_many :relations,
|
|
74
74
|
:dependent => :destroy
|
|
75
75
|
|
|
76
|
-
has_many :authored_channels,
|
|
77
|
-
:class_name => "Channel",
|
|
78
|
-
:foreign_key => :author_id,
|
|
79
|
-
:dependent => :destroy
|
|
80
|
-
|
|
81
|
-
has_many :owned_channels,
|
|
82
|
-
:class_name => "Channel",
|
|
83
|
-
:foreign_key => :owner_id,
|
|
84
|
-
:dependent => :destroy
|
|
85
|
-
|
|
86
76
|
has_many :sent_actions,
|
|
87
77
|
:class_name => "ActivityAction",
|
|
88
78
|
:dependent => :destroy
|
|
@@ -328,11 +318,6 @@ class Actor < ActiveRecord::Base
|
|
|
328
318
|
ties_to(subject).with_permissions(action, object).any?
|
|
329
319
|
end
|
|
330
320
|
|
|
331
|
-
# The {Channel} of this {Actor} to self (totally close!)
|
|
332
|
-
def self_channel
|
|
333
|
-
Channel.find_or_create_by_author_id_and_user_author_id_and_owner_id id, id, id
|
|
334
|
-
end
|
|
335
|
-
|
|
336
321
|
# Return the {ActivityAction} model to an {ActivityObject}
|
|
337
322
|
def action_to(activity_object)
|
|
338
323
|
sent_actions.received_by(activity_object).first
|
|
@@ -391,12 +376,26 @@ class Actor < ActiveRecord::Base
|
|
|
391
376
|
any?
|
|
392
377
|
end
|
|
393
378
|
|
|
394
|
-
#
|
|
395
|
-
#
|
|
396
|
-
|
|
379
|
+
# The default {Relation Relations} for sharing an {Activity} owned
|
|
380
|
+
# by this {Actor}
|
|
381
|
+
def activity_relations
|
|
382
|
+
SocialStream.relation_model == :custom ?
|
|
383
|
+
relations.
|
|
384
|
+
allowing('read', 'activity') :
|
|
385
|
+
[ Relation::Public.instance ]
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# The ids of the default {Relation Relations} for sharing an {Activity}
|
|
389
|
+
# owned by this {Actor}
|
|
390
|
+
def activity_relation_ids
|
|
391
|
+
activity_relations.map(&:id)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# This method returns all the {relations Relation} that subject can choose to broadcast an Activity in this {Actor}'s wall
|
|
397
395
|
#
|
|
396
|
+
# See {Activity} on how they can be shared with multiple {audicences Audience}, which corresponds to a {Relation}.
|
|
398
397
|
#
|
|
399
|
-
def
|
|
398
|
+
def activity_relations_for(subject, options = {})
|
|
400
399
|
if Actor.normalize(subject) == self
|
|
401
400
|
return relation_customs + Array.wrap(Relation::Public.instance)
|
|
402
401
|
else
|
|
@@ -404,9 +403,9 @@ class Actor < ActiveRecord::Base
|
|
|
404
403
|
end
|
|
405
404
|
end
|
|
406
405
|
|
|
407
|
-
# Are
|
|
408
|
-
def
|
|
409
|
-
activity_relations(
|
|
406
|
+
# Are {#activity_relations} available for subject?
|
|
407
|
+
def activity_relations_for?(subject, options = {})
|
|
408
|
+
activity_relations(subject, options).any?
|
|
410
409
|
end
|
|
411
410
|
|
|
412
411
|
# Is this {Actor} allowed to create a comment on activity?
|
|
@@ -459,37 +458,30 @@ class Actor < ActiveRecord::Base
|
|
|
459
458
|
# the wall for members of the group.
|
|
460
459
|
#
|
|
461
460
|
def wall(type, options = {})
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
args[:type] = type
|
|
465
|
-
args[:owner] = self
|
|
466
|
-
# Preserve this options
|
|
467
|
-
[ :for, :object_type ].each do |opt|
|
|
468
|
-
args[opt] = options[opt]
|
|
469
|
-
end
|
|
461
|
+
options[:for] = self if type == :home
|
|
470
462
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
463
|
+
wall =
|
|
464
|
+
Activity.
|
|
465
|
+
select("DISTINCT activities.*").
|
|
466
|
+
roots.
|
|
467
|
+
includes(:author, :user_author, :owner, :activity_objects, :activity_verb, :relations)
|
|
474
468
|
|
|
475
|
-
|
|
476
|
-
args[:relation_ids] =
|
|
469
|
+
actor_ids =
|
|
477
470
|
case type
|
|
478
471
|
when :home
|
|
479
|
-
|
|
480
|
-
Relation.allow(self, 'read', 'activity').map(&:id)
|
|
472
|
+
following_actor_and_self_ids
|
|
481
473
|
when :profile
|
|
482
|
-
|
|
483
|
-
#
|
|
484
|
-
# The relations that can be read by options[:for]
|
|
485
|
-
options[:for].present? ?
|
|
486
|
-
Relation.allow(options[:for], 'read', 'activity').map(&:id) :
|
|
487
|
-
[]
|
|
474
|
+
id
|
|
488
475
|
else
|
|
489
476
|
raise "Unknown type of wall: #{ type }"
|
|
490
477
|
end
|
|
491
478
|
|
|
492
|
-
|
|
479
|
+
wall = wall.authored_or_owned_by(actor_ids)
|
|
480
|
+
|
|
481
|
+
# Authentication
|
|
482
|
+
wall = wall.shared_with(options[:for])
|
|
483
|
+
|
|
484
|
+
wall = wall.order("created_at desc")
|
|
493
485
|
end
|
|
494
486
|
|
|
495
487
|
def logo
|
|
@@ -507,7 +499,7 @@ class Actor < ActiveRecord::Base
|
|
|
507
499
|
end
|
|
508
500
|
|
|
509
501
|
def liked_by(subject) #:nodoc:
|
|
510
|
-
likes.
|
|
502
|
+
likes.authored_by(subject)
|
|
511
503
|
end
|
|
512
504
|
|
|
513
505
|
# Does subject like this {Actor}?
|
|
@@ -517,14 +509,11 @@ class Actor < ActiveRecord::Base
|
|
|
517
509
|
|
|
518
510
|
# Build a new activity where subject like this
|
|
519
511
|
def new_like(subject, user)
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
a = Activity.new :verb => "like",
|
|
526
|
-
:channel => channel,
|
|
527
|
-
:relation_ids => Array(Relation::Public.instance.id)
|
|
512
|
+
a = Activity.new :verb => "like",
|
|
513
|
+
:author_id => Actor.normalize_id(subject),
|
|
514
|
+
:user_author_id => Actor.normalize_id(user),
|
|
515
|
+
:owner_id => id,
|
|
516
|
+
:relation_ids => Array(Relation::Public.instance.id)
|
|
528
517
|
|
|
529
518
|
a.activity_objects << activity_object
|
|
530
519
|
|
data/app/models/contact.rb
CHANGED
|
@@ -164,27 +164,6 @@ class Contact < ActiveRecord::Base
|
|
|
164
164
|
end
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
-
# The related {Channel} to this {Contact}.
|
|
168
|
-
#
|
|
169
|
-
# If the sender of this {Contact} is a user, the {Channel} is defined. If it is
|
|
170
|
-
# other kind of {SocialStream::Models::Subject}, the {Channel#user_author} must
|
|
171
|
-
# be provided.
|
|
172
|
-
def channel(user = nil)
|
|
173
|
-
user_id =
|
|
174
|
-
if sender.subject_type == "User"
|
|
175
|
-
sender_id
|
|
176
|
-
elsif user.present? && Actor.normalize(user).subject_type == "User"
|
|
177
|
-
Actor.normalize_id(user)
|
|
178
|
-
else
|
|
179
|
-
raise "Invalid channel user_author: #{ user.inspect }"
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
Channel.
|
|
183
|
-
find_or_create_by_author_id_and_user_author_id_and_owner_id sender_id,
|
|
184
|
-
user_id,
|
|
185
|
-
receiver_id
|
|
186
|
-
end
|
|
187
|
-
|
|
188
167
|
private
|
|
189
168
|
|
|
190
169
|
def build_user_author
|
data/app/models/tie.rb
CHANGED
|
@@ -146,7 +146,7 @@ class Tie < ActiveRecord::Base
|
|
|
146
146
|
Activity.create! :author => contact.sender,
|
|
147
147
|
:user_author => contact.user_author,
|
|
148
148
|
:owner => contact.receiver,
|
|
149
|
-
:relation_ids => contact.
|
|
149
|
+
:relation_ids => contact.receiver.activity_relation_ids,
|
|
150
150
|
:activity_verb => ActivityVerb[contact.verb]
|
|
151
151
|
end
|
|
152
152
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<%= javascript_tag do %>
|
|
22
22
|
var relation_public = <%= Relation::Public.instance.id %>;
|
|
23
23
|
var public_selected = false;
|
|
24
|
-
var relation_options = <%= escape_javascript(current_subject.
|
|
24
|
+
var relation_options = <%= escape_javascript(current_subject.activity_relations_for(receiver).sort.map{ |r| r.id }.to_json) %>;
|
|
25
25
|
var relation_public_pos = 0;
|
|
26
26
|
for(id in relation_options){
|
|
27
27
|
if(relation_options[id]==relation_public){
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
}
|
|
33
33
|
//For security with check "var default_security_width = '100px';" in activities.js.erb
|
|
34
34
|
<% end %>
|
|
35
|
-
<%= select_tag :relation_ids, options_for_select(current_subject.
|
|
35
|
+
<%= select_tag :relation_ids, options_for_select(current_subject.activity_relations_for(receiver).sort.map{ |r| [ r.name, r.id ] }), :id => 'security', :multiple => true, :title => t("activity.privacy.myself.contacts.#{ receiver.class.to_s.underscore }") %>
|
|
36
36
|
<% else %>
|
|
37
37
|
<div id="security_chzn" class="chzn-container chzn-container-multi">
|
|
38
38
|
<ul class="chzn-choices">
|
|
@@ -8,11 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
<% if user_signed_in? %>
|
|
10
10
|
·
|
|
11
|
-
<%= link_to activity.audience_in_words(current_subject, :details => :summary),
|
|
11
|
+
<%= link_to image_tag("btn/#{ activity.public? ? 'public' : 'restricted' }.png", :class => 'menu_icon') + activity.audience_in_words(current_subject, :details => :summary),
|
|
12
12
|
'javascript:;',
|
|
13
13
|
:class => 'activity_audience_summary' %>
|
|
14
14
|
<div class="activity_audience">
|
|
15
15
|
<%= activity.audience_in_words(current_subject) %>
|
|
16
|
+
<% unless activity.public? %>
|
|
17
|
+
·
|
|
18
|
+
<%= link_to t('activity.audience.show'), audience_path(:activity_id => activity.id), :remote => true %>
|
|
19
|
+
<div class="activity-audience-list-<%= activity.id %>">
|
|
20
|
+
</div>
|
|
21
|
+
<% end %>
|
|
16
22
|
</div>
|
|
17
23
|
<% end %>
|
|
18
24
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$('.activity-audience-list-<%= @activity.id %>').html('<%= j render(:partial => 'list') %>');
|
data/config/locales/en.yml
CHANGED
data/config/locales/es.yml
CHANGED
data/config/routes.rb
CHANGED
|
@@ -86,6 +86,8 @@ Rails.application.routes.draw do
|
|
|
86
86
|
resources :activities do
|
|
87
87
|
resource :like
|
|
88
88
|
end
|
|
89
|
+
|
|
90
|
+
get 'audience/index', :as => :audience
|
|
89
91
|
|
|
90
92
|
match 'cheesecake' => 'cheesecake#index', :as => :cheesecake
|
|
91
93
|
match 'update_cheesecake' => 'cheesecake#update', :as => :update_cheesecake
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class RemoveActivityChannels < ActiveRecord::Migration
|
|
2
|
+
class Channel < ActiveRecord::Base; end
|
|
3
|
+
|
|
4
|
+
def up
|
|
5
|
+
change_table :activities do |t|
|
|
6
|
+
t.references :author
|
|
7
|
+
t.references :user_author
|
|
8
|
+
t.references :owner
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Activity.record_timestamps = false
|
|
12
|
+
Activity.reset_column_information
|
|
13
|
+
|
|
14
|
+
Activity.all.each do |a|
|
|
15
|
+
c = Channel.find a.channel_id
|
|
16
|
+
%w{ author_id user_author_id owner_id }.each do |m|
|
|
17
|
+
a.__send__ "#{ m }=", c.__send__(m) # a.author_id = c.author_id
|
|
18
|
+
end
|
|
19
|
+
a.save!
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
Activity.record_timestamps = true
|
|
23
|
+
|
|
24
|
+
remove_foreign_key :activities, :name => 'index_activities_on_channel_id'
|
|
25
|
+
remove_column :activities, :channel_id
|
|
26
|
+
|
|
27
|
+
Activity.reset_column_information
|
|
28
|
+
|
|
29
|
+
drop_table :channels
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def down
|
|
33
|
+
raise ActiveRecord::IrreversibleMigration
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -20,7 +20,6 @@ module SocialStream
|
|
|
20
20
|
|
|
21
21
|
initializer "social_stream-base.model.supertypes" do
|
|
22
22
|
ActiveSupport.on_load(:active_record) do
|
|
23
|
-
include SocialStream::Models::Channeled::ActiveRecord
|
|
24
23
|
include SocialStream::Models::Subtype::ActiveRecord
|
|
25
24
|
include SocialStream::Models::Supertype::ActiveRecord
|
|
26
25
|
end
|
data/lib/social_stream-base.rb
CHANGED
data/lib/tasks/db/populate.rake
CHANGED
|
@@ -112,14 +112,16 @@ namespace :db do
|
|
|
112
112
|
ties_start = Time.now
|
|
113
113
|
|
|
114
114
|
@available_actors.each do |a|
|
|
115
|
-
actors = @available_actors.dup
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
actors = @available_actors.dup
|
|
116
|
+
actors.delete(a)
|
|
117
|
+
|
|
118
|
+
relations = a.relation_customs + [ Relation::Reject.instance ]
|
|
119
|
+
|
|
118
120
|
Forgery::Basic.number(:at_most => actors.size).times do
|
|
119
121
|
actor = actors.delete_at((rand * actors.size).to_i)
|
|
120
122
|
contact = a.contact_to!(actor)
|
|
121
123
|
contact.user_author = a.user_author if a.subject_type != "User"
|
|
122
|
-
contact.relation_ids =
|
|
124
|
+
contact.relation_ids = [ Forgery::Extensions::Array.new(relations).random.id ]
|
|
123
125
|
end
|
|
124
126
|
end
|
|
125
127
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe AudienceController do
|
|
4
|
+
include SocialStream::TestHelpers
|
|
5
|
+
include SocialStream::TestHelpers::Controllers
|
|
6
|
+
|
|
7
|
+
render_views
|
|
8
|
+
|
|
9
|
+
context "with activity" do
|
|
10
|
+
before :all do
|
|
11
|
+
@activity = Factory(:activity)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should not be redered to public" do
|
|
15
|
+
get :index, :activity_id => @activity.id, :format => :js
|
|
16
|
+
|
|
17
|
+
response.should redirect_to(:new_user_session)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should not be rendered to anyone" do
|
|
21
|
+
sign_in Factory(:user)
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
get :index, :activity_id => @activity.id, :format => :js
|
|
25
|
+
|
|
26
|
+
assert false
|
|
27
|
+
rescue CanCan::AccessDenied
|
|
28
|
+
assert true
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should not be rendered to author" do
|
|
33
|
+
sign_in @activity.author_subject
|
|
34
|
+
|
|
35
|
+
get :index, :activity_id => @activity.id, :format => :js
|
|
36
|
+
|
|
37
|
+
response.should be_success
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -13,7 +13,7 @@ describe CommentsController do
|
|
|
13
13
|
|
|
14
14
|
describe "comment from user" do
|
|
15
15
|
before do
|
|
16
|
-
activity = Factory(:self_activity, :
|
|
16
|
+
activity = Factory(:self_activity, :author => @user.actor)
|
|
17
17
|
|
|
18
18
|
model_attributes[:author_id] = @user.actor_id
|
|
19
19
|
model_attributes[:owner_id] = @user.actor_id
|
|
@@ -38,7 +38,7 @@ describe CommentsController do
|
|
|
38
38
|
describe "comment to friend" do
|
|
39
39
|
before do
|
|
40
40
|
f = Factory(:friend, :contact => Factory(:contact, :receiver => @user.actor)).sender
|
|
41
|
-
activity = Factory(:self_activity, :
|
|
41
|
+
activity = Factory(:self_activity, :author => f)
|
|
42
42
|
|
|
43
43
|
model_attributes[:author_id] = @user.actor_id
|
|
44
44
|
model_attributes[:owner_id] = f.id
|
|
@@ -52,7 +52,7 @@ describe CommentsController do
|
|
|
52
52
|
describe "post to acquaintance" do
|
|
53
53
|
before do
|
|
54
54
|
a = Factory(:acquaintance, :contact => Factory(:contact, :receiver => @user.actor)).sender
|
|
55
|
-
activity = Factory(:self_activity, :
|
|
55
|
+
activity = Factory(:self_activity, :author => a)
|
|
56
56
|
|
|
57
57
|
model_attributes[:author_id] = @user.actor_id
|
|
58
58
|
model_attributes[:owner_id] = a.id
|
data/spec/factories/activity.rb
CHANGED
|
@@ -23,9 +23,11 @@ end
|
|
|
23
23
|
## End of helpers
|
|
24
24
|
|
|
25
25
|
Factory.define :activity do |a|
|
|
26
|
-
a.
|
|
26
|
+
a.author { Factory(:user).actor }
|
|
27
|
+
a.user_author { |b| b.author }
|
|
28
|
+
a.owner { |b| Factory(:friend, :contact => Factory(:contact, :receiver => b.author)).sender }
|
|
27
29
|
a.activity_verb { ActivityVerb["post"] }
|
|
28
|
-
a.relation_ids { |b|
|
|
30
|
+
a.relation_ids { |b| [ b.owner.relation_custom('friend').id ] }
|
|
29
31
|
a.activity_object_ids { |b|
|
|
30
32
|
# Create post
|
|
31
33
|
post = Factory(:post,
|
|
@@ -40,8 +42,10 @@ Factory.define :activity do |a|
|
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
Factory.define :self_activity, :parent => :activity do |a|
|
|
43
|
-
a.
|
|
44
|
-
a.
|
|
45
|
+
a.author { Factory(:user).actor }
|
|
46
|
+
a.user_author { |b| b.author }
|
|
47
|
+
a.owner { |b| b.author }
|
|
48
|
+
a.relation_ids { |b| [ b.author.relation_custom('friend').id ] }
|
|
45
49
|
a.activity_object_ids { |b|
|
|
46
50
|
# Create post
|
|
47
51
|
post = Factory(:post,
|
|
@@ -63,10 +67,12 @@ end
|
|
|
63
67
|
|
|
64
68
|
Factory.define :like_activity, :class => 'Activity' do |a|
|
|
65
69
|
a.association :parent, :factory => :activity
|
|
66
|
-
a.
|
|
70
|
+
a.author { |b| Factory(:friend, :sender => b.parent.owner).receiver }
|
|
71
|
+
a.user_author { |b| b.author }
|
|
72
|
+
a.owner { |b| b.parent.owner }
|
|
67
73
|
a.activity_verb { ActivityVerb["like"] }
|
|
68
74
|
a.relation_ids { |b| b.parent.relation_ids }
|
|
69
|
-
a.after_build{ |b| b.activity_object_ids = b.parent.activity_object_ids }
|
|
75
|
+
a.after_build { |b| b.activity_object_ids = b.parent.activity_object_ids }
|
|
70
76
|
end
|
|
71
77
|
|
|
72
78
|
|
data/spec/models/tie_spec.rb
CHANGED
|
@@ -41,8 +41,9 @@ describe Tie do
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "should create activity with follow verb" do
|
|
44
|
-
@tie.
|
|
45
|
-
|
|
44
|
+
activity = Activity.authored_by(@tie.sender).owned_by(@tie.receiver).first
|
|
45
|
+
activity.should be_present
|
|
46
|
+
activity.verb.should eq('follow')
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
context "reciprocal" do
|
|
@@ -51,8 +52,10 @@ describe Tie do
|
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
it "should create activity with make-friend verb" do
|
|
54
|
-
@reciprocal.
|
|
55
|
-
|
|
55
|
+
activity = Activity.authored_by(@reciprocal.sender).owned_by(@reciprocal.receiver).first
|
|
56
|
+
|
|
57
|
+
activity.should be_present
|
|
58
|
+
activity.verb.should eq('make-friend')
|
|
56
59
|
end
|
|
57
60
|
end
|
|
58
61
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: social_stream-base
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.21.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2012-05-
|
|
13
|
+
date: 2012-05-27 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: deep_merge
|
|
@@ -596,7 +596,6 @@ files:
|
|
|
596
596
|
- app/assets/images/btn/btn_profile.png
|
|
597
597
|
- app/assets/images/btn/btn_rank.png
|
|
598
598
|
- app/assets/images/btn/btn_read.png
|
|
599
|
-
- app/assets/images/btn/btn_security.png
|
|
600
599
|
- app/assets/images/btn/btn_send.png
|
|
601
600
|
- app/assets/images/btn/btn_spam.png
|
|
602
601
|
- app/assets/images/btn/btn_star.png
|
|
@@ -636,6 +635,8 @@ files:
|
|
|
636
635
|
- app/assets/images/btn/point_blue.png
|
|
637
636
|
- app/assets/images/btn/point_gray.png
|
|
638
637
|
- app/assets/images/btn/post.png
|
|
638
|
+
- app/assets/images/btn/public.png
|
|
639
|
+
- app/assets/images/btn/restricted.png
|
|
639
640
|
- app/assets/images/btn/search.png
|
|
640
641
|
- app/assets/images/btn/search_icon.png
|
|
641
642
|
- app/assets/images/btn/shadow.png
|
|
@@ -770,6 +771,7 @@ files:
|
|
|
770
771
|
- app/controllers/activities_controller.rb
|
|
771
772
|
- app/controllers/activity_actions_controller.rb
|
|
772
773
|
- app/controllers/api_controller.rb
|
|
774
|
+
- app/controllers/audience_controller.rb
|
|
773
775
|
- app/controllers/authentications_controller.rb
|
|
774
776
|
- app/controllers/cheesecake_controller.rb
|
|
775
777
|
- app/controllers/comments_controller.rb
|
|
@@ -821,7 +823,6 @@ files:
|
|
|
821
823
|
- app/models/actor.rb
|
|
822
824
|
- app/models/audience.rb
|
|
823
825
|
- app/models/authentication.rb
|
|
824
|
-
- app/models/channel.rb
|
|
825
826
|
- app/models/comment.rb
|
|
826
827
|
- app/models/contact.rb
|
|
827
828
|
- app/models/group.rb
|
|
@@ -858,6 +859,8 @@ files:
|
|
|
858
859
|
- app/views/actors/_actor.html.erb
|
|
859
860
|
- app/views/actors/_actor_cheesecake.html.erb
|
|
860
861
|
- app/views/api/activity_atom_feed.atom.builder
|
|
862
|
+
- app/views/audience/_list.html.erb
|
|
863
|
+
- app/views/audience/index.js.erb
|
|
861
864
|
- app/views/avatars/index.html.erb
|
|
862
865
|
- app/views/avatars/update.js.erb
|
|
863
866
|
- app/views/cheesecake/_cheesecake.html.erb
|
|
@@ -1055,6 +1058,7 @@ files:
|
|
|
1055
1058
|
- db/migrate/20120403175913_create_activity_object_audiences.rb
|
|
1056
1059
|
- db/migrate/20120411132550_add_visit_count_to_activity_object.rb
|
|
1057
1060
|
- db/migrate/20120411151413_relation_public_permissions.rb
|
|
1061
|
+
- db/migrate/20120526171311_remove_activity_channels.rb
|
|
1058
1062
|
- lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb
|
|
1059
1063
|
- lib/acts_as_taggable_on/social_stream.rb
|
|
1060
1064
|
- lib/generators/social_stream/base/install_generator.rb
|
|
@@ -1109,7 +1113,6 @@ files:
|
|
|
1109
1113
|
- lib/social_stream/d3.rb
|
|
1110
1114
|
- lib/social_stream/migrations/base.rb
|
|
1111
1115
|
- lib/social_stream/migrations/components.rb
|
|
1112
|
-
- lib/social_stream/models/channeled.rb
|
|
1113
1116
|
- lib/social_stream/models/object.rb
|
|
1114
1117
|
- lib/social_stream/models/subject.rb
|
|
1115
1118
|
- lib/social_stream/models/subtype.rb
|
|
@@ -1132,6 +1135,7 @@ files:
|
|
|
1132
1135
|
- lib/tasks/workers.rake
|
|
1133
1136
|
- lib/thinking-sphinx/social_stream.rb
|
|
1134
1137
|
- social_stream-base.gemspec
|
|
1138
|
+
- spec/controllers/audience_controller_spec.rb
|
|
1135
1139
|
- spec/controllers/comments_controller_spec.rb
|
|
1136
1140
|
- spec/controllers/contacts_controller_spec.rb
|
|
1137
1141
|
- spec/controllers/followers_controller_spec.rb
|
|
Binary file
|
data/app/models/channel.rb
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# A {Channel} is the union of the three {Actors} that are involved in an {Activity}:
|
|
2
|
-
#
|
|
3
|
-
# * The author that creates a post, comment, etc. This can be a {User}, {Group}
|
|
4
|
-
# or any kind of {SocialStream::Models::Subject subject}
|
|
5
|
-
# * The user_author representing the author. When users change session and
|
|
6
|
-
# act in behalf of a {Group}, Social Stream still records which user is responsible
|
|
7
|
-
# for an {Activity}
|
|
8
|
-
# * The owner in whose wall the Activity is performed.
|
|
9
|
-
#
|
|
10
|
-
class Channel < ActiveRecord::Base
|
|
11
|
-
# Author can be any type of Actor: User, Group, etc.
|
|
12
|
-
belongs_to :author,
|
|
13
|
-
:class_name => "Actor"
|
|
14
|
-
# Owner is the wall's subject this object is posted to
|
|
15
|
-
belongs_to :owner,
|
|
16
|
-
:class_name => "Actor"
|
|
17
|
-
|
|
18
|
-
# UserAuthor is the real user behind the Author
|
|
19
|
-
belongs_to :user_author,
|
|
20
|
-
:class_name => "Actor"
|
|
21
|
-
|
|
22
|
-
has_many :activities, :dependent => :destroy
|
|
23
|
-
|
|
24
|
-
validates_uniqueness_of :author_id, :scope => [ :owner_id, :user_author_id ]
|
|
25
|
-
validates_uniqueness_of :owner_id, :scope => [ :author_id, :user_author_id ]
|
|
26
|
-
validates_uniqueness_of :user_author_id, :scope => [ :author_id, :owner_id ]
|
|
27
|
-
|
|
28
|
-
scope :authored_by, lambda { |subject|
|
|
29
|
-
id = Actor.normalize_id subject
|
|
30
|
-
|
|
31
|
-
where(arel_table[:author_id].eq(id).or(arel_table[:user_author_id].eq(id)))
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
scope :subject_authored_by, lambda { |subject|
|
|
35
|
-
id = Actor.normalize_id subject
|
|
36
|
-
|
|
37
|
-
where(:author_id => id)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
# The {SocialStream::Models::Subject subject} author
|
|
41
|
-
def author_subject
|
|
42
|
-
author.subject
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# The {SocialStream::Models::Subject subject} owner
|
|
46
|
-
def owner_subject
|
|
47
|
-
owner.subject
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# The {SocialStream::Models::Subject subject} user actor
|
|
51
|
-
def user_author_subject
|
|
52
|
-
user_author.subject
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Does this {Channel} have the same sender and receiver?
|
|
56
|
-
def reflexive?
|
|
57
|
-
author_id == owner_id
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Is the author represented in this {Channel}?
|
|
61
|
-
def represented_author?
|
|
62
|
-
author_id != user_author_id
|
|
63
|
-
end
|
|
64
|
-
end
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
module SocialStream
|
|
2
|
-
module Models
|
|
3
|
-
# Models that have author, user_author and owner, properties saved in {Channel}.
|
|
4
|
-
# Currently {Activity} and {ActivityObject}
|
|
5
|
-
module Channeled
|
|
6
|
-
# Add the method {#channeled} to ActiveRecord
|
|
7
|
-
module ActiveRecord
|
|
8
|
-
extend ActiveSupport::Concern
|
|
9
|
-
|
|
10
|
-
module ClassMethods
|
|
11
|
-
# This class is channeled. See {Channel}
|
|
12
|
-
def channeled
|
|
13
|
-
include SocialStream::Models::Channeled
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
extend ActiveSupport::Concern
|
|
19
|
-
|
|
20
|
-
included do
|
|
21
|
-
# Channeled models are subtypes of {Channel}
|
|
22
|
-
# Author, owner and user_author are defined in its channel
|
|
23
|
-
subtype_of :channel,
|
|
24
|
-
:belongs => { :dependent => nil }
|
|
25
|
-
|
|
26
|
-
# before_validation :set_owner_id, :on => :create
|
|
27
|
-
|
|
28
|
-
before_validation :check_existing_channel
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
protected
|
|
32
|
-
|
|
33
|
-
# Use existing channel, do not create a new one
|
|
34
|
-
def check_existing_channel
|
|
35
|
-
return unless channel!.new_record?
|
|
36
|
-
|
|
37
|
-
existing_channel =
|
|
38
|
-
Channel.
|
|
39
|
-
where(:author_id => author_id,
|
|
40
|
-
:owner_id => owner_id,
|
|
41
|
-
:user_author_id => user_author_id).
|
|
42
|
-
first
|
|
43
|
-
|
|
44
|
-
return if existing_channel.blank?
|
|
45
|
-
|
|
46
|
-
self.channel = existing_channel
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
private
|
|
50
|
-
|
|
51
|
-
def set_owner_id
|
|
52
|
-
self.owner_id ||= author_id
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|