social_stream 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -1
- data/README.rdoc +4 -4
- data/app/controllers/private_messages_controller.rb +3 -0
- data/app/controllers/users_controller.rb +26 -0
- data/app/models/permission.rb +19 -0
- data/app/models/private_message.rb +6 -0
- data/app/models/profile.rb +3 -0
- data/app/models/tie.rb +28 -2
- data/app/models/user.rb +29 -13
- data/app/views/home/_options.html.erb +4 -1
- data/app/views/home/_right.html.erb +1 -1
- data/app/views/layouts/application.html.erb +7 -4
- data/app/views/private_messages/_form.html.erb +24 -0
- data/app/views/private_messages/_index.html.erb +24 -0
- data/app/views/private_messages/_location.html.erb +3 -0
- data/app/views/private_messages/_messages.html.erb +2 -0
- data/app/views/private_messages/_private_message.html.erb +17 -0
- data/app/views/private_messages/edit.html.erb +6 -0
- data/app/views/private_messages/index.html.erb +1 -0
- data/app/views/private_messages/index.js.erb +1 -0
- data/app/views/private_messages/new.html.erb +14 -0
- data/app/views/private_messages/show.html.erb +21 -0
- data/app/views/users/_contacts.html.erb +2 -0
- data/app/views/users/_profile.html.erb +44 -57
- data/app/views/users/edit.html.erb +164 -0
- data/config/locales/en.yml +5 -4
- data/config/routes.rb +1 -0
- data/lib/generators/social_stream/install_generator.rb +4 -0
- data/lib/generators/social_stream/templates/migration.rb +21 -3
- data/lib/generators/social_stream/templates/public/javascripts/jquery-ui.min.js +401 -0
- data/lib/generators/social_stream/templates/public/stylesheets/edit_user.css +80 -0
- data/lib/generators/social_stream/templates/public/stylesheets/message.css +46 -0
- data/lib/social_stream/populate.rb +26 -0
- data/lib/social_stream/version.rb +1 -1
- data/lib/tasks/db/populate.rake +2 -2
- data/spec/controllers/.groups_controller_spec.rb.swp +0 -0
- data/spec/controllers/.users_controller_spec.rb.swp +0 -0
- data/spec/controllers/frontpage_controller_spec.rb +11 -0
- data/spec/controllers/groups_controller_spec.rb +51 -0
- data/spec/controllers/home_controller_spec.rb +24 -0
- data/spec/controllers/users_controller_spec.rb +48 -0
- data/spec/factories/post.rb +1 -0
- data/spec/factories/user.rb +2 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/devise.rb +4 -0
- metadata +29 -7
- data/spec/dummy/app/models/post.rb +0 -2
- data/spec/dummy/app/models/user.rb +0 -2
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
= Social Stream: building social network
|
2
|
-
Social Stream is an engine for Ruby on Rails. It provides
|
3
|
-
|
1
|
+
= Social Stream: core for building social network websites
|
2
|
+
Social Stream is an engine for Ruby on Rails. It provides a robust and flexible core
|
3
|
+
with social networking features and activity streams for building websites.
|
4
4
|
|
5
5
|
== Social networking
|
6
6
|
Social networks are a new paradigm on web application design. Social networking platforms stand
|
@@ -68,7 +68,7 @@ initializer.
|
|
68
68
|
|
69
69
|
= Documentation
|
70
70
|
|
71
|
-
{Social Stream documentation is available at rdoc.info}[http://
|
71
|
+
{Social Stream documentation is available at rdoc.info}[http://rubydoc.info/gems/social_stream/frames]
|
72
72
|
|
73
73
|
= Discussion
|
74
74
|
|
@@ -6,6 +6,32 @@ class UsersController < ApplicationController
|
|
6
6
|
respond_to do |format|
|
7
7
|
format.html # show.html.erb
|
8
8
|
format.xml { render :xml => @user }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def edit
|
13
|
+
@user = User.find_by_permalink!(params[:id])
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
format.html # edit.html.erb
|
17
|
+
format.xml { render :xml => @user }
|
9
18
|
end
|
10
19
|
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
|
23
|
+
@user = User.find_by_permalink!(params[:id])
|
24
|
+
|
25
|
+
respond_to do |format|
|
26
|
+
if @user.update_attributes(params[:user])
|
27
|
+
#format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
|
28
|
+
format.html { render :action => "edit", :notice => 'User was successfully updated.' }
|
29
|
+
format.xml { head :ok }
|
30
|
+
else
|
31
|
+
format.html { render :action => "edit" }
|
32
|
+
format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
11
37
|
end
|
data/app/models/permission.rb
CHANGED
@@ -1,7 +1,26 @@
|
|
1
|
+
# SocialStream provides a sophisticated and powerful system of permissions based on the relations
|
2
|
+
# and ties of the social network.
|
3
|
+
#
|
4
|
+
# Permissions are composed by action, objective and parameterized. Action and objective are classical
|
5
|
+
# in content management systems, e.g. "create" "activity", "update" "tie", "read" "post"
|
6
|
+
#
|
7
|
+
# parameterized is a novel feature. It supports applying the permission to certain set of ties.
|
8
|
+
# This set of ties changes with the formation of ties in your website.
|
9
|
+
#
|
10
|
+
# Permissions is assigned to relations, and through relations, to ties.
|
11
|
+
# When a sender establishes a tie with a receiver, she grants to the receiver the permissions assigned
|
12
|
+
# to relation of the tie she has just established. For example, when Alice establishes a "friend" tie
|
13
|
+
# to Bob, she is granting him the permissions associated with "friend" relation.
|
14
|
+
#
|
15
|
+
# One of this permissions can be "read" "activity" "inverse_group_set". This way, Bob will have access
|
16
|
+
# to read the activities attached to ties inside the "inverse_group_set", which are the ties from all
|
17
|
+
# the "friends" of Alice to Alice herself.
|
18
|
+
#
|
1
19
|
class Permission < ActiveRecord::Base
|
2
20
|
has_many :relation_permissions, :dependent => :destroy
|
3
21
|
has_many :relations, :through => :relation_permissions
|
4
22
|
|
23
|
+
# The SQL and ARel conditions for permission queries
|
5
24
|
ParameterConditions = {
|
6
25
|
:table => {
|
7
26
|
'tie' =>
|
data/app/models/tie.rb
CHANGED
@@ -121,8 +121,34 @@ class Tie < ActiveRecord::Base
|
|
121
121
|
Tie.inverse(self).first
|
122
122
|
end
|
123
123
|
|
124
|
-
# Access Control
|
125
|
-
|
124
|
+
# = Access Control
|
125
|
+
#
|
126
|
+
# Access control enforcement in ties come from the permissions assigned to other ties through relations.
|
127
|
+
# The access_set is the set of ties that grant some permission on a particular tie.
|
128
|
+
#
|
129
|
+
# Enforcing access control on activities and ties are a matter of finding its access set.
|
130
|
+
# There are two approaches for this, checking the permissions on particular tie or finding all the ties
|
131
|
+
# granted some permission.
|
132
|
+
#
|
133
|
+
# == Particular tie
|
134
|
+
# ------------------ ------------------
|
135
|
+
# | particular tie |--------| access_set |
|
136
|
+
# | t | | ties |
|
137
|
+
# ------------------ ------------------
|
138
|
+
#
|
139
|
+
# Because t is given, the scopes are applied to the ties table
|
140
|
+
# We get the set of ties that allow permission on t
|
141
|
+
#
|
142
|
+
# == Finding ties
|
143
|
+
# ------------------ join ------------------
|
144
|
+
# | finding ties |--------| access_set |
|
145
|
+
# | ties | | ties_as |
|
146
|
+
# ------------------ ------------------
|
147
|
+
#
|
148
|
+
# Because we want to find ties, an additional join table (ties_as) is needed for applying access set conditions
|
149
|
+
# We get the set of ties that are allowed to certain condition
|
150
|
+
#
|
151
|
+
|
126
152
|
scope :with_permissions, lambda { |action, object|
|
127
153
|
joins(:relation => :permissions).
|
128
154
|
where('permissions.action' => action).
|
data/app/models/user.rb
CHANGED
@@ -2,24 +2,38 @@ require 'devise/orm/active_record'
|
|
2
2
|
|
3
3
|
class User < ActiveRecord::Base
|
4
4
|
devise *SocialStream.devise_modules
|
5
|
-
|
5
|
+
has_one :profile
|
6
|
+
accepts_nested_attributes_for :profile
|
7
|
+
|
6
8
|
# Setup accessible (or protected) attributes for your model
|
7
|
-
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
|
8
|
-
|
9
|
+
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :profile_attributes, :birthday
|
10
|
+
|
9
11
|
validates_presence_of :email
|
12
|
+
|
10
13
|
validates_format_of :email, :with => Devise.email_regexp, :allow_blank => true
|
11
14
|
# TODO: uniqueness of email, which is in actor
|
12
|
-
|
15
|
+
|
13
16
|
with_options :if => :password_required? do |v|
|
14
17
|
v.validates_presence_of :password
|
15
18
|
v.validates_confirmation_of :password
|
16
19
|
v.validates_length_of :password, :within => Devise.password_length, :allow_blank => true
|
17
20
|
end
|
18
|
-
|
21
|
+
|
19
22
|
def recent_groups
|
20
23
|
receiver_subjects(:group, :relations => 'follower') & Tie.recent
|
21
24
|
end
|
22
25
|
|
26
|
+
|
27
|
+
|
28
|
+
def age
|
29
|
+
return nil if self.birthday.blank?
|
30
|
+
now = Time.now.utc.to_date
|
31
|
+
now.year - self.birthday.year - (self.birthday.to_date.change(:year => now.year) > now ? 1 : 0)
|
32
|
+
end
|
33
|
+
|
34
|
+
after_create :create_profile
|
35
|
+
|
36
|
+
|
23
37
|
def friends
|
24
38
|
receiver_subjects(:user, :relations => 'friend')
|
25
39
|
end
|
@@ -30,7 +44,7 @@ class User < ActiveRecord::Base
|
|
30
44
|
def password_required?
|
31
45
|
!persisted? || !password.nil? || !password_confirmation.nil?
|
32
46
|
end
|
33
|
-
|
47
|
+
|
34
48
|
class << self
|
35
49
|
%w( email permalink name ).each do |a|
|
36
50
|
eval <<-EOS
|
@@ -42,7 +56,7 @@ class User < ActiveRecord::Base
|
|
42
56
|
end # end
|
43
57
|
EOS
|
44
58
|
end
|
45
|
-
|
59
|
+
|
46
60
|
# Overwrite devise default find method to support login with email,
|
47
61
|
# presence ID and login
|
48
62
|
def find_for_authentication(conditions)
|
@@ -56,7 +70,7 @@ class User < ActiveRecord::Base
|
|
56
70
|
super
|
57
71
|
end
|
58
72
|
end
|
59
|
-
|
73
|
+
|
60
74
|
def find_or_initialize_with_error_by(attribute, value, error=:invalid)
|
61
75
|
if attribute == :email
|
62
76
|
find_or_initialize_with_error_by_email(value, error)
|
@@ -64,26 +78,28 @@ class User < ActiveRecord::Base
|
|
64
78
|
super
|
65
79
|
end
|
66
80
|
end
|
67
|
-
|
81
|
+
|
68
82
|
# Overwrite devise default method to support finding with actor.email
|
69
83
|
def find_or_initialize_with_error_by_email(value, error)
|
70
84
|
if value.present?
|
71
85
|
record = find_by_email(value)
|
72
86
|
end
|
73
|
-
|
87
|
+
|
74
88
|
unless record
|
75
89
|
record = new
|
76
|
-
|
90
|
+
|
77
91
|
if value.present?
|
78
92
|
record.email = value
|
79
93
|
else
|
80
94
|
error = :blank
|
81
95
|
end
|
82
|
-
|
96
|
+
|
83
97
|
record.errors.add(:email, error)
|
84
98
|
end
|
85
|
-
|
99
|
+
|
86
100
|
record
|
87
101
|
end
|
88
102
|
end
|
103
|
+
|
104
|
+
|
89
105
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
<ul class="menu noaccordion">
|
2
2
|
<li>
|
3
|
-
<%= link_to( image_tag("btn/btn_inbox.png", :class => "menu_icon")+t('inbox.one'),
|
3
|
+
<%= link_to( image_tag("btn/btn_inbox.png", :class => "menu_icon")+t('inbox.one'), private_messages_path, :remote => true) %>
|
4
|
+
</li>
|
5
|
+
<li>
|
6
|
+
<%= link_to( image_tag("btn/btn_group.png", :class => "menu_icon")+t('group.new'), "#", :remote => true) %>
|
4
7
|
</li>
|
5
8
|
</ul>
|
@@ -18,11 +18,14 @@
|
|
18
18
|
<%= stylesheet_link_tag "carousel", :media => "screen, projection" %>
|
19
19
|
<%= stylesheet_link_tag "smoothness/jquery-ui-1.8.4.custom", :media => "screen, projection" %>
|
20
20
|
<%= stylesheet_link_tag "ui.dropdownchecklist", :media => "screen, projection" %>
|
21
|
+
<!-- datepicker css -->
|
22
|
+
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
|
23
|
+
<%= stylesheet_link_tag "edit_user", :media => "screen, projection" %>
|
21
24
|
|
22
25
|
|
23
26
|
<%= javascript_include_tag :defaults %>
|
24
27
|
|
25
|
-
<%= javascript_include_tag 'jquery', 'jquery-ui
|
28
|
+
<%= javascript_include_tag 'jquery', 'jquery-ui.min', 'jquery.livequery',
|
26
29
|
'jquery.boxy', 'menu','ui.dropdownchecklist' %>
|
27
30
|
|
28
31
|
|
@@ -47,11 +50,11 @@
|
|
47
50
|
</div>
|
48
51
|
<div id="middle">
|
49
52
|
<div id="middleContent">
|
50
|
-
<div class="
|
53
|
+
<div class="space_profile">
|
51
54
|
</div>
|
52
|
-
<div class="
|
55
|
+
<div class="space_profile">
|
53
56
|
</div>
|
54
|
-
<div class="
|
57
|
+
<div class="space_profile">
|
55
58
|
</div>
|
56
59
|
<%= yield :middle %>
|
57
60
|
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= form_for(@private_message) do |f| %>
|
2
|
+
<% if @private_message.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(@private_message.errors.count, "error") %> prohibited this private_message from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% @private_message.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= f.hidden_field :sender_id %>
|
15
|
+
<%= f.hidden_field :receiver_id %>
|
16
|
+
|
17
|
+
<div class="field">
|
18
|
+
<%= f.label :text %><br />
|
19
|
+
<%= f.text_area :text %>
|
20
|
+
</div>
|
21
|
+
<div class="actions">
|
22
|
+
<%= f.submit %>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% content_for :middle do %>
|
2
|
+
<%= render :partial => 'home/middle' %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<% content_for :right do %>
|
6
|
+
<%= render :partial => "home/right" %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= render :partial => 'location' %>
|
10
|
+
|
11
|
+
<br class="clearfloat" />
|
12
|
+
<div class="space_center">
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div id="new_message" ><%= link_to 'New Message', new_private_message_path %></div>
|
16
|
+
<div class="space_center">
|
17
|
+
</div>
|
18
|
+
<div class="space_center">
|
19
|
+
</div>
|
20
|
+
|
21
|
+
|
22
|
+
<div id="messages">
|
23
|
+
<%= render :partial => 'messages' %>
|
24
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= div_for (private_message) do %>
|
2
|
+
<div class="actor_logo">
|
3
|
+
<%= link_to image_tag(private_message.text,
|
4
|
+
:alt => private_message.text),
|
5
|
+
private_message %>
|
6
|
+
</div>
|
7
|
+
<div class="activity_content_message">
|
8
|
+
<div class="actor_name_message">
|
9
|
+
<%= link_to(private_message.text, private_message) %>
|
10
|
+
</div>
|
11
|
+
<div class="option_msg">
|
12
|
+
<div class="edit_message"><%= link_to ( image_tag('btn/btn_edit.png', :class=>"btn_config"), edit_private_message_path(private_message)) %></div>
|
13
|
+
<div class="detele_message"><%= link_to ( image_tag('btn/btn_delete.png', :class=>"btn_config"), private_message, :confirm => 'Are you sure?', :method => :delete) %></div>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'index' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
$("#content").html("<%=escape_javascript(render :partial => 'index') %>");
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% content_for :middle do %>
|
2
|
+
<%= render :partial => 'home/middle' %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<% content_for :right do %>
|
6
|
+
<%= render :partial => "home/right" %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
|
10
|
+
<h1>New private_message</h1>
|
11
|
+
|
12
|
+
<%= render 'form' %>
|
13
|
+
|
14
|
+
<%= link_to 'Back', private_messages_path %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
<p id="notice"><%= notice %></p>
|
3
|
+
|
4
|
+
<p>
|
5
|
+
<b>Sender:</b>
|
6
|
+
<%= @private_message.sender %>
|
7
|
+
</p>
|
8
|
+
|
9
|
+
<p>
|
10
|
+
<b>Receiver:</b>
|
11
|
+
<%= @private_message.receiver %>
|
12
|
+
</p>
|
13
|
+
|
14
|
+
<p>
|
15
|
+
<b>Text:</b>
|
16
|
+
<%= @private_message.text %>
|
17
|
+
</p>
|
18
|
+
|
19
|
+
|
20
|
+
<%= link_to 'Edit', edit_private_message_path(@private_message) %> |
|
21
|
+
<%= link_to 'Back', private_messages_path %>
|