social_stream 0.2.3 → 0.3.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/.gitignore +1 -0
- data/README.rdoc +2 -3
- data/app/controllers/likes_controller.rb +2 -2
- data/app/controllers/messages_controller.rb +3 -0
- data/app/controllers/representations_controller.rb +8 -0
- data/app/controllers/ties_controller.rb +1 -1
- data/app/helpers/activities_helper.rb +2 -2
- data/app/helpers/ties_helper.rb +19 -16
- data/app/models/activity.rb +42 -7
- data/app/models/activity_object.rb +1 -0
- data/app/models/activity_verb.rb +5 -1
- data/app/models/actor.rb +113 -68
- data/app/models/group.rb +15 -1
- data/app/models/message.rb +2 -0
- data/app/models/permission.rb +20 -41
- data/app/models/profile.rb +1 -1
- data/app/models/relation.rb +34 -26
- data/app/models/representation.rb +35 -0
- data/app/models/tie.rb +47 -100
- data/app/models/user.rb +12 -17
- data/app/views/activities/_activities.html.erb +2 -2
- data/app/views/activities/_new.html.erb +6 -3
- data/app/views/activities/_options.html.erb +1 -1
- data/app/views/comments/_new.html.erb +2 -2
- data/app/views/frontpage/index.html.erb +0 -2
- data/app/views/groups/_group.html.erb +3 -3
- data/app/views/groups/_index.html.erb +3 -4
- data/app/views/groups/_middle_show.html.erb +7 -4
- data/app/views/groups/_new.html.erb +25 -0
- data/app/views/groups/_right_show.html.erb +4 -2
- data/app/views/groups/new.html.erb +1 -0
- data/app/views/groups/show.html.erb +1 -1
- data/app/views/home/_groups.html.erb +7 -5
- data/app/views/home/_location.html.erb +1 -1
- data/app/views/home/_options.html.erb +2 -2
- data/app/views/home/_right.html.erb +2 -2
- data/app/views/home/index.html.erb +6 -2
- data/app/views/layouts/_footer.html.erb +1 -1
- data/app/views/layouts/_header.erb +4 -1
- data/app/views/layouts/_representation.html.erb +20 -0
- data/app/views/{private_messages → messages}/_form.html.erb +4 -4
- data/app/views/{private_messages → messages}/_index.html.erb +1 -1
- data/app/views/{private_messages → messages}/_location.html.erb +1 -1
- data/app/views/messages/_message.html.erb +17 -0
- data/app/views/messages/_messages.html.erb +2 -0
- data/app/views/messages/edit.html.erb +6 -0
- data/app/views/{private_messages → messages}/index.html.erb +0 -0
- data/app/views/{private_messages → messages}/index.js.erb +0 -0
- data/app/views/{private_messages → messages}/new.html.erb +2 -2
- data/app/views/messages/show.html.erb +21 -0
- data/app/views/subjects/_contacts.html.erb +20 -0
- data/app/views/ties/_new.html.erb +6 -6
- data/app/views/ties/_pendings.html.erb +3 -3
- data/app/views/ties/_suggestions.html.erb +3 -3
- data/app/views/ties/_tie.html.erb +1 -1
- data/app/views/ties/create.js.erb +4 -5
- data/app/views/ties/new.js.erb +1 -1
- data/app/views/users/_groups.html.erb +5 -5
- data/app/views/users/_index.html.erb +3 -1
- data/app/views/users/_options.html.erb +1 -1
- data/app/views/users/_right_show.html.erb +3 -3
- data/app/views/users/show.html.erb +5 -3
- data/config/locales/en.yml +13 -19
- data/config/routes.rb +11 -4
- data/lib/generators/social_stream/install_generator.rb +2 -10
- data/lib/generators/social_stream/templates/initializer.rb +1 -1
- data/lib/generators/social_stream/templates/migration.rb +19 -24
- data/lib/generators/social_stream/templates/public/javascripts/jquery.js +6883 -0
- data/lib/generators/social_stream/templates/public/javascripts/rails.js +146 -0
- data/lib/generators/social_stream/templates/public/javascripts/ui.dropdownchecklist.js +3 -13
- data/lib/generators/social_stream/templates/public/stylesheets/header.css +5 -1
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-icons_222222_256x240.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-icons_454545_256x240.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-icons_888888_256x240.png +0 -0
- data/lib/generators/social_stream/templates/public/{images → stylesheets/images}/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/generators/social_stream/templates/relations.yml +42 -0
- data/lib/social_stream/ability.rb +7 -6
- data/lib/social_stream/controllers/helpers.rb +35 -0
- data/lib/social_stream/models/{activity_object.rb → object.rb} +1 -1
- data/lib/social_stream/models/{actor.rb → subject.rb} +10 -30
- data/lib/social_stream/models/supertype.rb +5 -2
- data/lib/social_stream/rails.rb +25 -6
- data/lib/social_stream/relations.rb +46 -0
- data/lib/social_stream/version.rb +1 -1
- data/lib/social_stream.rb +13 -13
- data/lib/tasks/db/populate.rake +23 -29
- data/spec/controllers/groups_controller_spec.rb +2 -6
- data/spec/controllers/ties_controller_spec.rb +19 -0
- data/spec/controllers/users_controller_spec.rb +0 -2
- data/spec/dummy/config/application.rb +0 -1
- data/spec/dummy/config/initializers/social_stream.rb +14 -2
- data/spec/dummy/config/relations.yml +42 -0
- data/spec/dummy/db/schema.rb +9 -0
- data/spec/dummy/db/seeds.rb +0 -1
- data/spec/factories/activity.rb +2 -2
- data/spec/factories/actor.rb +2 -1
- data/spec/factories/group.rb +1 -0
- data/spec/factories/post.rb +1 -1
- data/spec/factories/tie.rb +16 -22
- data/spec/models/activity_spec.rb +27 -24
- data/spec/models/actor_spec.rb +3 -0
- data/spec/models/representation_spec.rb +16 -0
- data/spec/models/tie_spec.rb +49 -57
- data/spec/models/user_spec.rb +22 -0
- data/spec/support/db.rb +1 -1
- metadata +47 -45
- data/Gemfile.lock +0 -171
- data/app/controllers/private_messages_controller.rb +0 -3
- data/app/models/private_message.rb +0 -6
- data/app/views/groups/_follow.html.erb +0 -9
- data/app/views/groups/_followers.html.erb +0 -16
- data/app/views/home/_contacts.html.erb +0 -17
- data/app/views/private_messages/_messages.html.erb +0 -2
- data/app/views/private_messages/_private_message.html.erb +0 -17
- data/app/views/private_messages/edit.html.erb +0 -6
- data/app/views/private_messages/show.html.erb +0 -21
- data/app/views/ties/_pending.html.erb +0 -21
- data/app/views/users/_contacts.html.erb +0 -19
- data/init.rb +0 -3
- data/lib/generators/social_stream/templates/seeds.yml +0 -64
- data/lib/social_stream/rails/common.rb +0 -36
- data/lib/social_stream/rails/engine.rb +0 -9
- data/lib/social_stream/rails/railtie.rb +0 -9
- data/lib/social_stream/seed.rb +0 -49
- data/spec/dummy/db/seeds/social_stream.yml +0 -64
- data/spec/models/user_space.rb +0 -10
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
jQuery(function ($) {
|
|
2
|
+
var csrf_token = $('meta[name=csrf-token]').attr('content'),
|
|
3
|
+
csrf_param = $('meta[name=csrf-param]').attr('content');
|
|
4
|
+
|
|
5
|
+
$.fn.extend({
|
|
6
|
+
/**
|
|
7
|
+
* Triggers a custom event on an element and returns the event result
|
|
8
|
+
* this is used to get around not being able to ensure callbacks are placed
|
|
9
|
+
* at the end of the chain.
|
|
10
|
+
*
|
|
11
|
+
* TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
|
|
12
|
+
* own events and placing ourselves at the end of the chain.
|
|
13
|
+
*/
|
|
14
|
+
triggerAndReturn: function (name, data) {
|
|
15
|
+
var event = new $.Event(name);
|
|
16
|
+
this.trigger(event, data);
|
|
17
|
+
|
|
18
|
+
return event.result !== false;
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Handles execution of remote calls firing overridable events along the way
|
|
23
|
+
*/
|
|
24
|
+
callRemote: function () {
|
|
25
|
+
var el = this,
|
|
26
|
+
method = el.attr('method') || el.attr('data-method') || 'GET',
|
|
27
|
+
url = el.attr('action') || el.attr('href'),
|
|
28
|
+
dataType = el.attr('data-type') || 'script';
|
|
29
|
+
|
|
30
|
+
if (url === undefined) {
|
|
31
|
+
throw "No URL specified for remote call (action or href must be present).";
|
|
32
|
+
} else {
|
|
33
|
+
if (el.triggerAndReturn('ajax:before')) {
|
|
34
|
+
var data = el.is('form') ? el.serializeArray() : [];
|
|
35
|
+
$.ajax({
|
|
36
|
+
url: url,
|
|
37
|
+
data: data,
|
|
38
|
+
dataType: dataType,
|
|
39
|
+
type: method.toUpperCase(),
|
|
40
|
+
beforeSend: function (xhr) {
|
|
41
|
+
el.trigger('ajax:loading', xhr);
|
|
42
|
+
},
|
|
43
|
+
success: function (data, status, xhr) {
|
|
44
|
+
el.trigger('ajax:success', [data, status, xhr]);
|
|
45
|
+
},
|
|
46
|
+
complete: function (xhr) {
|
|
47
|
+
el.trigger('ajax:complete', xhr);
|
|
48
|
+
},
|
|
49
|
+
error: function (xhr, status, error) {
|
|
50
|
+
el.trigger('ajax:failure', [xhr, status, error]);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
el.trigger('ajax:after');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* confirmation handler
|
|
62
|
+
*/
|
|
63
|
+
var jqueryVersion = $().jquery;
|
|
64
|
+
|
|
65
|
+
if ( (jqueryVersion === '1.4') || (jqueryVersion === '1.4.1') || (jqueryVersion === '1.4.2')){
|
|
66
|
+
$('a[data-confirm],input[data-confirm]').live('click', function () {
|
|
67
|
+
var el = $(this);
|
|
68
|
+
if (el.triggerAndReturn('confirm')) {
|
|
69
|
+
if (!confirm(el.attr('data-confirm'))) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
} else {
|
|
75
|
+
$('body').delegate('a[data-confirm],input[data-confirm]', 'click', function () {
|
|
76
|
+
var el = $(this);
|
|
77
|
+
if (el.triggerAndReturn('confirm')) {
|
|
78
|
+
if (!confirm(el.attr('data-confirm'))) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* remote handlers
|
|
89
|
+
*/
|
|
90
|
+
$('form[data-remote]').live('submit', function (e) {
|
|
91
|
+
$(this).callRemote();
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
$('a[data-remote],input[data-remote]').live('click', function (e) {
|
|
96
|
+
$(this).callRemote();
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
$('a[data-method]:not([data-remote])').live('click', function (e){
|
|
101
|
+
var link = $(this),
|
|
102
|
+
href = link.attr('href'),
|
|
103
|
+
method = link.attr('data-method'),
|
|
104
|
+
form = $('<form method="post" action="'+href+'"></form>'),
|
|
105
|
+
metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';
|
|
106
|
+
|
|
107
|
+
if (csrf_param != null && csrf_token != null) {
|
|
108
|
+
metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
form.hide()
|
|
112
|
+
.append(metadata_input)
|
|
113
|
+
.appendTo('body');
|
|
114
|
+
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
form.submit();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* disable-with handlers
|
|
121
|
+
*/
|
|
122
|
+
var disable_with_input_selector = 'input[data-disable-with]';
|
|
123
|
+
var disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')';
|
|
124
|
+
var disable_with_form_not_remote_selector = 'form:not([data-remote]):has(' + disable_with_input_selector + ')';
|
|
125
|
+
|
|
126
|
+
var disable_with_input_function = function () {
|
|
127
|
+
$(this).find(disable_with_input_selector).each(function () {
|
|
128
|
+
var input = $(this);
|
|
129
|
+
input.data('enable-with', input.val())
|
|
130
|
+
.attr('value', input.attr('data-disable-with'))
|
|
131
|
+
.attr('disabled', 'disabled');
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
$(disable_with_form_remote_selector).live('ajax:before', disable_with_input_function);
|
|
136
|
+
$(disable_with_form_not_remote_selector).live('submit', disable_with_input_function);
|
|
137
|
+
|
|
138
|
+
$(disable_with_form_remote_selector).live('ajax:complete', function () {
|
|
139
|
+
$(this).find(disable_with_input_selector).each(function () {
|
|
140
|
+
var input = $(this);
|
|
141
|
+
input.removeAttr('disabled')
|
|
142
|
+
.val(input.data('enable-with'));
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
});
|
|
@@ -460,20 +460,10 @@
|
|
|
460
460
|
var text = self._formatText(selectOptions, options.firstItemChecksAll, firstOption);
|
|
461
461
|
var controlLabel = controlWrapper.find(".ui-dropdownchecklist-text");
|
|
462
462
|
|
|
463
|
-
var image = $("<img>");
|
|
464
|
-
image.attr("src", "/images/btn/btn_security.png");
|
|
465
|
-
image.attr('alt', 'security');
|
|
466
|
-
image.attr('id','security_image');
|
|
467
|
-
|
|
468
|
-
var down = $("<img>");
|
|
469
|
-
down.attr("src","/images/btn/btn_down.png")
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
463
|
//controlLabel.html(text);
|
|
474
|
-
controlLabel.html(
|
|
464
|
+
controlLabel.html(securityImage);
|
|
475
465
|
controlLabel.append(" ");
|
|
476
|
-
controlLabel.append(
|
|
466
|
+
controlLabel.append(downImage);
|
|
477
467
|
//controlLabel.attr("title", text);
|
|
478
468
|
controlLabel.attr("title", "security");
|
|
479
469
|
|
|
@@ -784,4 +774,4 @@
|
|
|
784
774
|
}
|
|
785
775
|
});
|
|
786
776
|
|
|
787
|
-
})(jQuery);
|
|
777
|
+
})(jQuery);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Relations for Social Stream
|
|
2
|
+
#
|
|
3
|
+
# Define the relations and permissions supported by your application
|
|
4
|
+
#
|
|
5
|
+
user:
|
|
6
|
+
friend:
|
|
7
|
+
name: friend
|
|
8
|
+
permissions:
|
|
9
|
+
- [ create, activity, weak_set ]
|
|
10
|
+
- [ read, activity, star_set ]
|
|
11
|
+
- [ update, activity, weak_set ]
|
|
12
|
+
- [ destroy, activity, weak_set ]
|
|
13
|
+
acquaintance:
|
|
14
|
+
name: acquaintance
|
|
15
|
+
parent: friend
|
|
16
|
+
permissions:
|
|
17
|
+
- [ read, activity, star_set ]
|
|
18
|
+
public:
|
|
19
|
+
name: public
|
|
20
|
+
parent: acquaintance
|
|
21
|
+
permissions:
|
|
22
|
+
- [ read, activity, star_set ]
|
|
23
|
+
|
|
24
|
+
group:
|
|
25
|
+
member:
|
|
26
|
+
name: member
|
|
27
|
+
permissions:
|
|
28
|
+
- [ represent ]
|
|
29
|
+
- [ create, activity, weak_set ]
|
|
30
|
+
- [ read, activity, star_set ]
|
|
31
|
+
- [ update, activity, weak_star_set ]
|
|
32
|
+
- [ destroy, activity, weak_star_set ]
|
|
33
|
+
partner:
|
|
34
|
+
name: partner
|
|
35
|
+
parent: member
|
|
36
|
+
permissions:
|
|
37
|
+
- [ read, activity, star_set ]
|
|
38
|
+
public:
|
|
39
|
+
name: public
|
|
40
|
+
parent: partner
|
|
41
|
+
permissions:
|
|
42
|
+
- [ read, activity, star_set ]
|
|
@@ -4,22 +4,23 @@ module SocialStream
|
|
|
4
4
|
|
|
5
5
|
def initialize(user)
|
|
6
6
|
can :create, Activity do |a|
|
|
7
|
-
# All ties authors must the user
|
|
8
|
-
a.tie.
|
|
9
|
-
a.tie.
|
|
7
|
+
# All ties' authors must be the user
|
|
8
|
+
a.tie.receiver_subject == user &&
|
|
9
|
+
a.tie.allows?(user, 'create', 'activity')
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
can :read, Activity do |a|
|
|
13
|
+
# This condition would not be neccesary if every actor had a public tie with others
|
|
13
14
|
a.tie.relation.name == 'public' ||
|
|
14
|
-
a.tie.
|
|
15
|
+
a.tie.allows?(user, 'read', 'activity')
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
can :update, Activity do |a|
|
|
18
|
-
a.tie.
|
|
19
|
+
a.tie.allows?(user, 'update', 'activity')
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
can :destroy, Activity do |a|
|
|
22
|
-
a.tie.
|
|
23
|
+
a.tie.allows?(user, 'destroy', 'activity')
|
|
23
24
|
end
|
|
24
25
|
end
|
|
25
26
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Controllers
|
|
3
|
+
# Common methods added to ApplicationController
|
|
4
|
+
module Helpers
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
helper_method :current_subject
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module InstanceMethods
|
|
12
|
+
# Current subject represented by the user. Defaults to the own user
|
|
13
|
+
def current_subject
|
|
14
|
+
current_subject_from_session ||
|
|
15
|
+
current_user
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Set represented subject
|
|
19
|
+
def current_subject= instance
|
|
20
|
+
session[:subject_type] = instance.class.to_s
|
|
21
|
+
session[:subject_id] = instance.id
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# Get represented subject from session
|
|
27
|
+
def current_subject_from_session
|
|
28
|
+
return unless session[:subject_type].present? && session[:subject_id].present?
|
|
29
|
+
|
|
30
|
+
session[:subject_type].constantize.find session[:subject_id]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -2,8 +2,8 @@ require 'active_support/concern'
|
|
|
2
2
|
|
|
3
3
|
module SocialStream
|
|
4
4
|
module Models
|
|
5
|
-
# Additional features for models that are subtypes of actors
|
|
6
|
-
module
|
|
5
|
+
# Additional features for models that are subtypes of actors, like User or Group
|
|
6
|
+
module Subject
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
9
9
|
included do
|
|
@@ -16,13 +16,18 @@ module SocialStream
|
|
|
16
16
|
:permalink,
|
|
17
17
|
:logo, :logo=,
|
|
18
18
|
:ties, :sent_ties, :received_ties,
|
|
19
|
-
:
|
|
19
|
+
:ties_to,
|
|
20
|
+
:sent_ties_allowing,
|
|
20
21
|
:pending_ties,
|
|
21
|
-
:
|
|
22
|
+
:relation, :relations,
|
|
23
|
+
:actors, :subjects,
|
|
22
24
|
:suggestions, :suggestion,
|
|
23
|
-
:
|
|
25
|
+
:home_wall, :profile_wall,
|
|
24
26
|
:to => :actor!
|
|
25
27
|
|
|
28
|
+
has_one :profile, :through => :actor
|
|
29
|
+
|
|
30
|
+
accepts_nested_attributes_for :profile
|
|
26
31
|
|
|
27
32
|
validates_presence_of :name
|
|
28
33
|
|
|
@@ -30,8 +35,6 @@ module SocialStream
|
|
|
30
35
|
|
|
31
36
|
scope :with_sent_ties, joins(:actor => :sent_ties)
|
|
32
37
|
scope :with_received_ties, joins(:actor => :received_ties)
|
|
33
|
-
|
|
34
|
-
after_create :initialize_reflexive_ties
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
module InstanceMethods
|
|
@@ -42,32 +45,9 @@ module SocialStream
|
|
|
42
45
|
def to_param
|
|
43
46
|
permalink
|
|
44
47
|
end
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
def initialize_reflexive_ties
|
|
49
|
-
self.class.relations.reflexive.each do |r|
|
|
50
|
-
Tie.create! :sender => self.actor,
|
|
51
|
-
:receiver => self.actor,
|
|
52
|
-
:relation => r
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
48
|
end
|
|
56
49
|
|
|
57
50
|
module ClassMethods
|
|
58
|
-
# Relations defined for this actor model.
|
|
59
|
-
def relations(to = to_s)
|
|
60
|
-
Relation.mode(to_s, to)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Actor subtypes that may receive a tie from an instance of this class
|
|
64
|
-
def receiving_subject_classes
|
|
65
|
-
Relation.select("DISTINCT #{ Relation.quoted_table_name }.receiver_type").
|
|
66
|
-
where(:sender_type => to_s).
|
|
67
|
-
map(&:receiver_type).
|
|
68
|
-
map(&:constantize)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
51
|
def find_by_permalink(perm)
|
|
72
52
|
joins(:actor).where('actors.permalink' => perm).first
|
|
73
53
|
end
|
|
@@ -2,6 +2,9 @@ require 'active_support/concern'
|
|
|
2
2
|
|
|
3
3
|
module SocialStream #:nodoc:
|
|
4
4
|
module Models
|
|
5
|
+
# Common methods for models that have subtypes. Currently, there are two supertypes:
|
|
6
|
+
# * Actor: participates in the social network and has ties with other actors. Its subtypes are subjects, like user or group
|
|
7
|
+
# * ActivityObject: created and managed by actors in activities. Its subtypes are objects, like post or comment
|
|
5
8
|
module Supertype
|
|
6
9
|
extend ActiveSupport::Concern
|
|
7
10
|
|
|
@@ -13,11 +16,11 @@ module SocialStream #:nodoc:
|
|
|
13
16
|
|
|
14
17
|
module ClassMethods
|
|
15
18
|
def subtypes
|
|
16
|
-
SocialStream.__send__ to_s.tableize
|
|
19
|
+
SocialStream.__send__ @subtypes_name.to_s.tableize # SocialStream.subjects # in Actor
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def load_subtype_features
|
|
20
|
-
features = "SocialStream::Models::#{ to_s }".constantize
|
|
23
|
+
features = "SocialStream::Models::#{ @subtypes_name.to_s.classify }".constantize
|
|
21
24
|
|
|
22
25
|
subtypes.each do |s|
|
|
23
26
|
s = s.to_s.classify.constantize
|
data/lib/social_stream/rails.rb
CHANGED
|
@@ -20,12 +20,31 @@ require 'paperclip/social_stream'
|
|
|
20
20
|
# Pagination
|
|
21
21
|
require 'will_paginate'
|
|
22
22
|
|
|
23
|
-
# FIXME: deprecate plugin
|
|
24
|
-
Gem.path.map{ |p| File.expand_path(__FILE__) =~ /^#{ p }/ }.compact.present? ?
|
|
25
|
-
require('social_stream/rails/engine') :
|
|
26
|
-
require('social_stream/rails/railtie')
|
|
27
|
-
|
|
28
23
|
module SocialStream
|
|
29
|
-
|
|
24
|
+
class Engine < ::Rails::Engine #:nodoc:
|
|
25
|
+
config.app_generators.authentication :devise
|
|
26
|
+
config.app_generators.javascript :jquery
|
|
27
|
+
|
|
28
|
+
config.to_prepare do
|
|
29
|
+
%w( actor activity_object ).each do |supertype|
|
|
30
|
+
supertype.classify.constantize.load_subtype_features
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
|
|
34
|
+
ApplicationController.helper ActivitiesHelper
|
|
35
|
+
ApplicationController.helper TiesHelper
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
initializer "social_stream.inflections" do
|
|
39
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
|
40
|
+
inflect.singular /^([Tt]ie)s$/, '\1'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
initializer "social_stream.controller_helpers" do
|
|
45
|
+
ActiveSupport.on_load(:action_controller) do
|
|
46
|
+
include SocialStream::Controllers::Helpers
|
|
47
|
+
end
|
|
48
|
+
end
|
|
30
49
|
end
|
|
31
50
|
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
# Seed you database with initial data for SocialStream
|
|
3
|
+
#
|
|
4
|
+
module Relations
|
|
5
|
+
CONFIG = File.join(::Rails.root, 'config', 'relations.yml')
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
# Relations configuration
|
|
9
|
+
def config
|
|
10
|
+
@config ||= YAML.load_file(CONFIG)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create(model)
|
|
14
|
+
cfg_rels = config[model.singularize.underscore]
|
|
15
|
+
|
|
16
|
+
if cfg_rels.nil?
|
|
17
|
+
raise "Undefined relations for actor #{ model }. Please, add an entry to #{ CONFIG }"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
rels = {}
|
|
21
|
+
|
|
22
|
+
cfg_rels.each_pair do |name, cfg_rel|
|
|
23
|
+
rels[name] =
|
|
24
|
+
Relation.create! :sender_type => model,
|
|
25
|
+
:receiver_type => cfg_rel['receiver_type'],
|
|
26
|
+
:name => cfg_rel['name']
|
|
27
|
+
|
|
28
|
+
if (ps = cfg_rel['permissions']).present?
|
|
29
|
+
ps.each do |p|
|
|
30
|
+
rels[name].permissions <<
|
|
31
|
+
Permission.find_or_create_by_action_and_object_and_function(*p)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Parent, relations must be set after creation
|
|
37
|
+
# FIXME: Can fix with ruby 1.9 and ordered hashes
|
|
38
|
+
cfg_rels.each_pair do |name, cfg_rel|
|
|
39
|
+
rels[name].update_attribute(:parent, rels[cfg_rel['parent']]) if cfg_rel['parent'].present?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
rels.values
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/social_stream.rb
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
# Provides your Rails application with social network and activity stream support
|
|
2
2
|
module SocialStream
|
|
3
|
-
autoload :Ability,
|
|
4
|
-
autoload :Populate,
|
|
5
|
-
autoload :
|
|
3
|
+
autoload :Ability, 'social_stream/ability'
|
|
4
|
+
autoload :Populate, 'social_stream/populate'
|
|
5
|
+
autoload :Relations, 'social_stream/relations'
|
|
6
|
+
|
|
7
|
+
module Controllers
|
|
8
|
+
autoload :Helpers, 'social_stream/controllers/helpers'
|
|
9
|
+
end
|
|
6
10
|
|
|
7
11
|
module Models
|
|
8
12
|
autoload :Supertype, 'social_stream/models/supertype'
|
|
9
|
-
autoload :
|
|
10
|
-
autoload :
|
|
13
|
+
autoload :Subject, 'social_stream/models/subject'
|
|
14
|
+
autoload :Object, 'social_stream/models/object'
|
|
11
15
|
end
|
|
12
16
|
|
|
13
|
-
mattr_accessor :
|
|
14
|
-
@@
|
|
17
|
+
mattr_accessor :subjects
|
|
18
|
+
@@subjects = [ :user, :group ]
|
|
15
19
|
|
|
16
20
|
mattr_accessor :devise_modules
|
|
17
21
|
@@devise_modules = [ :database_authenticatable, :registerable, :recoverable,
|
|
18
22
|
:rememberable, :trackable ]
|
|
19
23
|
|
|
20
|
-
mattr_accessor :
|
|
21
|
-
@@
|
|
24
|
+
mattr_accessor :objects
|
|
25
|
+
@@objects = [ :post, :comment ]
|
|
22
26
|
|
|
23
27
|
class << self
|
|
24
28
|
def setup
|
|
25
29
|
yield self
|
|
26
30
|
end
|
|
27
31
|
|
|
28
|
-
def seed!
|
|
29
|
-
Seed.new(File.join(::Rails.root, 'db', 'seeds', 'social_stream.yml'))
|
|
30
|
-
end
|
|
31
|
-
|
|
32
32
|
# Load models for rewrite in application
|
|
33
33
|
#
|
|
34
34
|
# Use this method when you want to reopen some model in SocialStream in order
|
data/lib/tasks/db/populate.rake
CHANGED
|
@@ -16,7 +16,7 @@ namespace :db do
|
|
|
16
16
|
klass.all.each do |i|
|
|
17
17
|
logo = Dir[File.join(LOGOS_PATH, klass.to_s.tableize, "#{ i.id }.*")].first
|
|
18
18
|
|
|
19
|
-
if File.
|
|
19
|
+
if logo.present? && File.exists?(logo)
|
|
20
20
|
i.logo = File.new(logo)
|
|
21
21
|
i.logo.reprocess!
|
|
22
22
|
i.save!
|
|
@@ -27,13 +27,15 @@ namespace :db do
|
|
|
27
27
|
# = Users
|
|
28
28
|
|
|
29
29
|
# Create demo user if not present
|
|
30
|
-
if User.find_by_name('
|
|
31
|
-
User.create! :name => '
|
|
32
|
-
:email => '
|
|
30
|
+
if User.find_by_name('demo').blank?
|
|
31
|
+
User.create! :name => 'Demo',
|
|
32
|
+
:email => 'demo@social-stream.dit.upm.es',
|
|
33
33
|
:password => 'demonstration',
|
|
34
34
|
:password_confirmation => 'demonstration'
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
require 'forgery'
|
|
38
|
+
|
|
37
39
|
9.times do
|
|
38
40
|
User.create! :name => Forgery::Name.full_name,
|
|
39
41
|
:email => Forgery::Internet.email_address,
|
|
@@ -43,49 +45,41 @@ namespace :db do
|
|
|
43
45
|
|
|
44
46
|
set_logos(User)
|
|
45
47
|
|
|
46
|
-
available_users = User.all
|
|
47
|
-
|
|
48
48
|
# = Groups
|
|
49
|
+
available_actors = Actor.all
|
|
50
|
+
|
|
49
51
|
10.times do
|
|
52
|
+
founder = available_actors[rand(available_actors.size)]
|
|
53
|
+
|
|
50
54
|
Group.create :name => Forgery::Name.company_name,
|
|
51
|
-
:email => Forgery::Internet.email_address
|
|
55
|
+
:email => Forgery::Internet.email_address,
|
|
56
|
+
:_founder => founder.permalink
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
set_logos(Group)
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
# Reload actors to include groups
|
|
62
|
+
available_actors = Actor.all
|
|
57
63
|
|
|
58
64
|
# = Ties
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Forgery::Basic.number(:at_most =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
:relation =>
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
groups = available_groups.dup
|
|
70
|
-
group_relations = Relation.mode('User', 'Group').all
|
|
71
|
-
|
|
72
|
-
Forgery::Basic.number(:at_most => groups.size).times do
|
|
73
|
-
group = groups.delete_at((rand * groups.size).to_i)
|
|
74
|
-
u.sent_ties.create :receiver => group.actor,
|
|
75
|
-
:relation => group_relations.random
|
|
65
|
+
available_actors.each do |a|
|
|
66
|
+
actors = available_actors.dup - Array(a)
|
|
67
|
+
relations = a.relations
|
|
68
|
+
|
|
69
|
+
Forgery::Basic.number(:at_most => actors.size).times do
|
|
70
|
+
actor = actors.delete_at((rand * actors.size).to_i)
|
|
71
|
+
a.sent_ties.create :receiver => actor,
|
|
72
|
+
:relation => relations.random
|
|
76
73
|
end
|
|
77
74
|
end
|
|
78
75
|
|
|
79
76
|
# = Posts
|
|
80
77
|
|
|
81
78
|
SocialStream::Populate.power_law(Tie.all) do |t|
|
|
82
|
-
# Only Post from users
|
|
83
|
-
next if t.relation.sender_type == "Group"
|
|
84
|
-
|
|
85
79
|
updated = Time.at(rand(Time.now))
|
|
86
80
|
|
|
87
81
|
p = Post.create :text =>
|
|
88
|
-
"This post should be for #{
|
|
82
|
+
"This post should be for #{ t.relation.name } of #{ t.sender.name }.\n#{ Forgery::LoremIpsum.paragraph(:random => true) }",
|
|
89
83
|
:created_at => Time.at(rand(updated)),
|
|
90
84
|
:updated_at => updated,
|
|
91
85
|
:_activity_tie_id => t.id
|