social_stream 0.0.1 → 0.0.2
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/Gemfile +1 -0
- data/Gemfile.lock +27 -15
- data/app/models/actor.rb +31 -0
- data/app/models/tie.rb +55 -21
- data/app/models/user.rb +1 -4
- data/lib/generators/social_stream/templates/initializer.rb +9 -6
- data/lib/generators/social_stream/templates/migration.rb +1 -0
- data/lib/social_stream.rb +5 -1
- data/lib/social_stream/models/actor.rb +24 -0
- data/lib/social_stream/models/supertype.rb +6 -2
- data/lib/social_stream/rails.rb +1 -0
- data/lib/social_stream/seed.rb +2 -0
- data/lib/social_stream/version.rb +1 -1
- metadata +4 -4
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -31,8 +31,9 @@ GEM
|
|
31
31
|
arel (1.0.1)
|
32
32
|
activesupport (~> 3.0.0)
|
33
33
|
atd-ancestry (1.3.0)
|
34
|
+
bcrypt-ruby (2.1.2)
|
34
35
|
builder (2.1.2)
|
35
|
-
cancan (1.
|
36
|
+
cancan (1.4.0)
|
36
37
|
capybara (0.3.9)
|
37
38
|
culerity (>= 0.2.4)
|
38
39
|
mime-types (>= 1.16)
|
@@ -40,8 +41,13 @@ GEM
|
|
40
41
|
rack (>= 1.0.0)
|
41
42
|
rack-test (>= 0.5.4)
|
42
43
|
selenium-webdriver (>= 0.0.3)
|
44
|
+
childprocess (0.1.3)
|
45
|
+
ffi (~> 0.6.3)
|
43
46
|
columnize (0.3.1)
|
44
47
|
culerity (0.2.12)
|
48
|
+
devise (1.1.3)
|
49
|
+
bcrypt-ruby (~> 2.1.2)
|
50
|
+
warden (~> 0.10.7)
|
45
51
|
diff-lcs (1.1.2)
|
46
52
|
erubis (2.6.6)
|
47
53
|
abstract (>= 1.0.0)
|
@@ -51,7 +57,7 @@ GEM
|
|
51
57
|
i18n (0.4.1)
|
52
58
|
json_pure (1.4.6)
|
53
59
|
linecache (0.43)
|
54
|
-
mail (2.2.
|
60
|
+
mail (2.2.7)
|
55
61
|
activesupport (>= 2.3.6)
|
56
62
|
mime-types
|
57
63
|
treetop (>= 1.4.5)
|
@@ -61,7 +67,7 @@ GEM
|
|
61
67
|
rack (1.2.1)
|
62
68
|
rack-mount (0.6.13)
|
63
69
|
rack (>= 1.0.0)
|
64
|
-
rack-test (0.5.
|
70
|
+
rack-test (0.5.6)
|
65
71
|
rack (>= 1.0)
|
66
72
|
rails (3.0.0)
|
67
73
|
actionmailer (= 3.0.0)
|
@@ -77,31 +83,36 @@ GEM
|
|
77
83
|
rake (>= 0.8.4)
|
78
84
|
thor (~> 0.14.0)
|
79
85
|
rake (0.8.7)
|
80
|
-
rspec (2.0.0
|
81
|
-
rspec-core (= 2.0.0
|
82
|
-
rspec-expectations (= 2.0.0
|
83
|
-
rspec-mocks (= 2.0.0
|
84
|
-
rspec-core (2.0.0
|
85
|
-
rspec-expectations (2.0.0
|
86
|
+
rspec (2.0.0)
|
87
|
+
rspec-core (= 2.0.0)
|
88
|
+
rspec-expectations (= 2.0.0)
|
89
|
+
rspec-mocks (= 2.0.0)
|
90
|
+
rspec-core (2.0.0)
|
91
|
+
rspec-expectations (2.0.0)
|
86
92
|
diff-lcs (>= 1.1.2)
|
87
|
-
rspec-mocks (2.0.0
|
88
|
-
|
89
|
-
rspec (= 2.0.0
|
93
|
+
rspec-mocks (2.0.0)
|
94
|
+
rspec-core (= 2.0.0)
|
95
|
+
rspec-expectations (= 2.0.0)
|
96
|
+
rspec-rails (2.0.1)
|
97
|
+
rspec (~> 2.0.0)
|
90
98
|
ruby-debug (0.10.3)
|
91
99
|
columnize (>= 0.1)
|
92
100
|
ruby-debug-base (~> 0.10.3.0)
|
93
101
|
ruby-debug-base (0.10.3)
|
94
102
|
linecache (>= 0.3)
|
95
103
|
rubyzip (0.9.4)
|
96
|
-
selenium-webdriver (0.0.
|
97
|
-
|
104
|
+
selenium-webdriver (0.0.29)
|
105
|
+
childprocess (>= 0.0.7)
|
106
|
+
ffi (~> 0.6.3)
|
98
107
|
json_pure
|
99
108
|
rubyzip
|
100
109
|
sqlite3-ruby (1.3.1)
|
101
|
-
thor (0.14.
|
110
|
+
thor (0.14.3)
|
102
111
|
treetop (1.4.8)
|
103
112
|
polyglot (>= 0.3.1)
|
104
113
|
tzinfo (0.3.23)
|
114
|
+
warden (0.10.7)
|
115
|
+
rack (>= 1.0.0)
|
105
116
|
|
106
117
|
PLATFORMS
|
107
118
|
ruby
|
@@ -110,6 +121,7 @@ DEPENDENCIES
|
|
110
121
|
atd-ancestry
|
111
122
|
cancan
|
112
123
|
capybara (>= 0.3.9)
|
124
|
+
devise
|
113
125
|
factory_girl
|
114
126
|
rails (= 3.0.0)
|
115
127
|
rspec-rails (>= 2.0.0.beta)
|
data/app/models/actor.rb
CHANGED
@@ -23,9 +23,40 @@ class Actor < ActiveRecord::Base
|
|
23
23
|
Tie.sent_or_received_by(self)
|
24
24
|
end
|
25
25
|
|
26
|
+
# All the subject actors of class type that have at least one tie
|
27
|
+
# with this actor
|
28
|
+
#
|
29
|
+
# Options::
|
30
|
+
# * relations: Restrict the relations of considered ties
|
31
|
+
def contacts(type, options = {})
|
32
|
+
type_class = type.to_s.classify.constantize
|
33
|
+
|
34
|
+
cs = type_class.
|
35
|
+
select("DISTINCT #{ type_class.quoted_table_name }.*").
|
36
|
+
with_received_ties &
|
37
|
+
Tie.sent_by(self)
|
38
|
+
|
39
|
+
if options[:relations].present?
|
40
|
+
cs &=
|
41
|
+
Tie.related_by(Tie.Relation(options[:relations], :mode => [ subject.class, type_class ]))
|
42
|
+
end
|
43
|
+
|
44
|
+
cs
|
45
|
+
end
|
46
|
+
|
47
|
+
# This is an scaffold for a recomendations engine
|
48
|
+
#
|
49
|
+
# By now, it returns another actor without any current relation
|
50
|
+
def suggestion(type = subject.class)
|
51
|
+
candidates = type.to_s.classify.constantize.all - contacts(type)
|
52
|
+
|
53
|
+
candidates[rand(candidates.size)]
|
54
|
+
end
|
55
|
+
|
26
56
|
# The set of activities in the wall of this actor
|
27
57
|
# TODO: authorization
|
28
58
|
def wall
|
29
59
|
Activity.wall ties
|
30
60
|
end
|
31
61
|
end
|
62
|
+
|
data/app/models/tie.rb
CHANGED
@@ -20,17 +20,17 @@
|
|
20
20
|
# * sent_by(actor), ties whose sender is actor
|
21
21
|
# * received_by(actor), ties whose receiver is actor
|
22
22
|
# * sent_or_received_by(actor), the union of the former
|
23
|
+
# * related_by(relation), ties with this relation. Accepts relation, relation_name, integer, array
|
24
|
+
# * pending, ties whose relation grant other relations, like friendship requests.
|
23
25
|
# * inverse(tie), the inverse of tie
|
24
26
|
#
|
25
27
|
class Tie < ActiveRecord::Base
|
26
|
-
# Avoids loops at create_inverse after save callback
|
27
|
-
attr_accessor :_without_inverse
|
28
|
-
attr_protected :_without_inverse
|
29
|
-
|
30
28
|
# Facilitates relation assigment along with find_relation callback
|
31
29
|
attr_accessor :relation_name
|
32
30
|
|
33
|
-
|
31
|
+
# Avoids loops at create_inverse after save callback
|
32
|
+
attr_accessor :_without_inverse
|
33
|
+
attr_protected :_without_inverse
|
34
34
|
|
35
35
|
belongs_to :sender,
|
36
36
|
:class_name => "Actor",
|
@@ -38,6 +38,7 @@ class Tie < ActiveRecord::Base
|
|
38
38
|
belongs_to :receiver,
|
39
39
|
:class_name => "Actor",
|
40
40
|
:include => SocialStream.actors
|
41
|
+
|
41
42
|
belongs_to :relation
|
42
43
|
|
43
44
|
has_many :activities
|
@@ -56,12 +57,24 @@ class Tie < ActiveRecord::Base
|
|
56
57
|
|
57
58
|
}
|
58
59
|
|
60
|
+
scope :related_by, lambda { |r|
|
61
|
+
where(:relation_id => Relation(r))
|
62
|
+
}
|
63
|
+
|
64
|
+
scope :pending, includes(:relation) & Relation.request
|
65
|
+
|
59
66
|
scope :inverse, lambda { |t|
|
60
67
|
sent_by(t.receiver).
|
61
68
|
received_by(t.sender).
|
62
69
|
where(:relation_id => t.relation.inverse_id)
|
63
70
|
}
|
64
71
|
|
72
|
+
validates_presence_of :sender_id, :receiver_id, :relation_id
|
73
|
+
|
74
|
+
before_validation :find_relation
|
75
|
+
|
76
|
+
after_create :complete_weak_set, :create_inverse
|
77
|
+
|
65
78
|
def sender_subject
|
66
79
|
sender.try(:subject)
|
67
80
|
end
|
@@ -70,33 +83,28 @@ class Tie < ActiveRecord::Base
|
|
70
83
|
receiver.try(:subject)
|
71
84
|
end
|
72
85
|
|
73
|
-
before_validation :find_relation
|
74
|
-
|
75
|
-
scope :pending, includes(:relation) & Relation.request
|
76
|
-
|
77
86
|
# The set of ties between sender and receiver
|
78
87
|
#
|
79
|
-
|
88
|
+
# Options::
|
89
|
+
# * relations: Only ties with relations
|
90
|
+
def relation_set(options = {})
|
80
91
|
set = self.class.where(:sender_id => sender_id,
|
81
92
|
:receiver_id => receiver_id)
|
82
93
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
set.where(:relation_id => relation.mode.find_by_name(r))
|
88
|
-
else
|
89
|
-
set.where(:relation_id => r)
|
94
|
+
if options.key?(:relations)
|
95
|
+
set =
|
96
|
+
set.related_by self.class.Relation(options[:relations],
|
97
|
+
:mode => relation.mode)
|
90
98
|
end
|
99
|
+
|
100
|
+
set
|
91
101
|
end
|
92
102
|
|
93
103
|
# The tie with relation r inside this relation_set
|
94
104
|
def related(r)
|
95
|
-
relation_set(r).first
|
105
|
+
relation_set(:relations => r).first
|
96
106
|
end
|
97
107
|
|
98
|
-
after_create :complete_weak_set, :create_inverse
|
99
|
-
|
100
108
|
# Access Control
|
101
109
|
|
102
110
|
scope :with_permissions, lambda { |action, object|
|
@@ -172,7 +180,7 @@ class Tie < ActiveRecord::Base
|
|
172
180
|
# Creates ties with a weaker relations in the strength hierarchy of this tie
|
173
181
|
def complete_weak_set
|
174
182
|
relation.weaker.each do |r|
|
175
|
-
if relation_set(r).blank?
|
183
|
+
if relation_set(:relations => r).blank?
|
176
184
|
t = relation_set.build :relation => r
|
177
185
|
t._without_inverse = true
|
178
186
|
t.save!
|
@@ -203,5 +211,31 @@ class Tie < ActiveRecord::Base
|
|
203
211
|
a.actor.id
|
204
212
|
end
|
205
213
|
end
|
214
|
+
|
215
|
+
# Normalize a relation for ActiveRecord query from relation_name, id or Array
|
216
|
+
#
|
217
|
+
# Options::
|
218
|
+
# mode:: Relation mode
|
219
|
+
def Relation(r, options = {})
|
220
|
+
case r
|
221
|
+
when Relation
|
222
|
+
r
|
223
|
+
when String
|
224
|
+
case options[:mode]
|
225
|
+
when Array
|
226
|
+
Relation.mode(*options[:mode]).find_by_name(r)
|
227
|
+
when ActiveRecord::Relation
|
228
|
+
options[:mode].find_by_name(r)
|
229
|
+
else
|
230
|
+
raise "Must provide a mode when looking up relations from name: #{ options[:mode] }"
|
231
|
+
end
|
232
|
+
when Integer
|
233
|
+
r
|
234
|
+
when Array
|
235
|
+
r.map{ |e| Relation(e, options) }
|
236
|
+
else
|
237
|
+
raise "Unable to normalize relation #{ r.inspect }"
|
238
|
+
end
|
239
|
+
end
|
206
240
|
end
|
207
241
|
end
|
data/app/models/user.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
-
|
3
|
-
# :token_authenticatable, :confirmable, :lockable, :timeoutable, :validatable
|
4
|
-
devise :database_authenticatable, :registerable,
|
5
|
-
:recoverable, :rememberable, :trackable
|
2
|
+
devise *SocialStream.devise_modules
|
6
3
|
|
7
4
|
# Setup accessible (or protected) attributes for your model
|
8
5
|
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
|
@@ -1,14 +1,17 @@
|
|
1
1
|
SocialStream.setup do |config|
|
2
2
|
# List the models that are social entities. These will have ties between them.
|
3
|
-
#
|
4
3
|
# Remember you must add an "actor_id" foreign key column to your migration!
|
5
4
|
#
|
6
|
-
config.actors = [:user ]
|
5
|
+
# config.actors = [:user ]
|
7
6
|
|
8
|
-
#
|
9
|
-
#
|
7
|
+
# Include devise modules in User. See devise documentation for details.
|
8
|
+
# Others available are:
|
9
|
+
# :token_authenticatable, :confirmable, :lockable, :timeoutable, :validatable
|
10
|
+
# config.devise_modules :database_authenticatable, :registerable,
|
11
|
+
:recoverable, :rememberable, :trackable
|
12
|
+
|
13
|
+
# Type of activities managed by actors
|
10
14
|
# Remember you must add an "activity_object_id" foreign key column to your migration!
|
11
15
|
#
|
12
|
-
#
|
13
|
-
config.activity_objects = []
|
16
|
+
# config.activity_objects = []
|
14
17
|
end
|
data/lib/social_stream.rb
CHANGED
@@ -9,7 +9,11 @@ module SocialStream
|
|
9
9
|
end
|
10
10
|
|
11
11
|
mattr_accessor :actors
|
12
|
-
@@actors = []
|
12
|
+
@@actors = [ :user ]
|
13
|
+
|
14
|
+
mattr_accessor :devise_modules
|
15
|
+
@@devise_modules = [ :database_authenticatable, :registerable, :recoverable,
|
16
|
+
:rememberable, :trackable ]
|
13
17
|
|
14
18
|
mattr_accessor :activity_objects
|
15
19
|
@@activity_objects = []
|
@@ -16,14 +16,38 @@ module SocialStream
|
|
16
16
|
:permalink, :permalink=,
|
17
17
|
:disabled, :disabled=,
|
18
18
|
:ties, :sent_ties, :received_ties,
|
19
|
+
:contacts, :suggestion,
|
19
20
|
:wall,
|
20
21
|
:to => :actor!
|
22
|
+
|
23
|
+
after_create :initialize_default_ties
|
21
24
|
end
|
22
25
|
|
23
26
|
module InstanceMethods
|
24
27
|
def actor!
|
25
28
|
actor || build_actor
|
26
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def initialize_default_ties
|
34
|
+
self.class.relations.where(:default => true).each do |r|
|
35
|
+
Tie.create! :sender => self.actor,
|
36
|
+
:receiver => self.actor,
|
37
|
+
:relation => r
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
# Relations defined for this actor model.
|
44
|
+
def relations(to = to_s)
|
45
|
+
Relation.mode(to_s, to)
|
46
|
+
end
|
47
|
+
|
48
|
+
def with_received_ties
|
49
|
+
joins(:actor => :received_ties)
|
50
|
+
end
|
27
51
|
end
|
28
52
|
end
|
29
53
|
end
|
@@ -20,8 +20,12 @@ module SocialStream #:nodoc:
|
|
20
20
|
features = "SocialStream::Models::#{ to_s }".constantize
|
21
21
|
|
22
22
|
subtypes.each do |s|
|
23
|
-
|
24
|
-
|
23
|
+
begin
|
24
|
+
s = s.to_s.classify.constantize
|
25
|
+
s.__send__(:include, features) unless s.ancestors.include?(features)
|
26
|
+
rescue
|
27
|
+
puts "Warning: could not load #{ s }"
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/social_stream/rails.rb
CHANGED
data/lib/social_stream/seed.rb
CHANGED
@@ -24,6 +24,8 @@ module SocialStream
|
|
24
24
|
find_or_create_by_sender_type_and_receiver_type_and_name(r['sender_type'],
|
25
25
|
r['receiver_type'],
|
26
26
|
r['name'])
|
27
|
+
relations[name].update_attribute(:default, r['default'])
|
28
|
+
|
27
29
|
# FIXME: optimize
|
28
30
|
relations[name].relation_permissions.destroy_all
|
29
31
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: social_stream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Antonio Tapiador
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-10-
|
19
|
+
date: 2010-10-19 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|