social_stream 0.25.1 → 0.25.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/base/app/controllers/conversations_controller.rb +15 -10
  2. data/base/app/controllers/followers_controller.rb +4 -9
  3. data/base/app/helpers/permissions_helper.rb +4 -0
  4. data/base/app/models/activity_action.rb +4 -0
  5. data/base/app/models/activity_object.rb +9 -0
  6. data/base/app/models/actor.rb +19 -0
  7. data/base/app/models/group.rb +5 -0
  8. data/base/app/models/relation/single.rb +2 -1
  9. data/base/app/models/user.rb +1 -1
  10. data/base/app/views/conversations/destroy.js.erb +2 -0
  11. data/base/app/views/followers/index.html.erb +26 -5
  12. data/base/app/views/permissions/_index.html.erb +7 -2
  13. data/base/app/views/profiles/update.js.erb +4 -9
  14. data/base/app/views/relation/customs/_list.html.erb +4 -0
  15. data/base/config/locales/en.yml +4 -0
  16. data/base/config/locales/es.yml +5 -1
  17. data/base/config/routes.rb +31 -32
  18. data/base/lib/generators/social_stream/base/templates/initializer.rb +5 -1
  19. data/base/lib/social_stream-base.rb +12 -1
  20. data/base/lib/social_stream/base/version.rb +1 -1
  21. data/base/lib/social_stream/models/object.rb +5 -0
  22. data/base/lib/social_stream/models/supertype.rb +1 -1
  23. data/base/lib/social_stream/routing/constraints/custom.rb +11 -0
  24. data/base/lib/social_stream/routing/constraints/follow.rb +11 -0
  25. data/base/lib/social_stream/routing/constraints/resque.rb +11 -0
  26. data/base/spec/controllers/followers_controller_spec.rb +37 -0
  27. data/base/spec/controllers/posts_controller_spec.rb +196 -163
  28. data/base/spec/dummy/config/initializers/social_stream.rb +5 -1
  29. data/base/spec/factories/tie.rb +4 -0
  30. data/base/spec/integration/resque_access_spec.rb +30 -0
  31. data/base/spec/models/post_spec.rb +66 -17
  32. data/documents/app/controllers/documents_controller.rb +3 -10
  33. data/documents/app/views/common_documents/_headers.html.erb +1 -1
  34. data/documents/lib/social_stream/documents/version.rb +1 -1
  35. data/documents/lib/tasks/db/populate_documents.rake +36 -0
  36. data/documents/social_stream-documents.gemspec +1 -1
  37. data/lib/social_stream/version.rb +1 -1
  38. data/social_stream.gemspec +2 -2
  39. metadata +35 -28
@@ -59,17 +59,22 @@ class ConversationsController < ApplicationController
59
59
 
60
60
  @conversation.move_to_trash(@actor)
61
61
 
62
- if params[:location].present?
63
- case params[:location]
64
- when 'conversation'
65
- redirect_to conversations_path(:box => :trash)
66
- return
67
- else
68
- redirect_to conversations_path(:box => @box,:page => params[:page])
69
- return
70
- end
62
+ respond_to do |format|
63
+ format.html {
64
+ if params[:location].present? and params[:location] == 'conversation'
65
+ redirect_to conversations_path(:box => :trash)
66
+ else
67
+ redirect_to conversations_path(:box => @box,:page => params[:page])
68
+ end
69
+ }
70
+ format.js {
71
+ if params[:location].present? and params[:location] == 'conversation'
72
+ render :js => "window.location = '#{conversations_path(:box => @box,:page => params[:page])}';"
73
+ else
74
+ render 'conversations/destroy'
75
+ end
76
+ }
71
77
  end
72
- redirect_to conversations_path(:box => @box,:page => params[:page])
73
78
  end
74
79
 
75
80
  private
@@ -4,17 +4,12 @@ class FollowersController < ApplicationController
4
4
  respond_to :html, :js
5
5
 
6
6
  def index
7
- @contacts =
8
- if params[:following]
9
- current_subject.sent_contacts
10
- else
11
- current_subject.received_contacts
12
- end
7
+ @followings = current_subject.following_actor_objects.includes(:actor)
8
+ @followers = current_subject.followers
13
9
 
14
10
  respond_to do |format|
15
- format.html { @contacts = @contacts.page(params[:page]).per(20) }
16
- format.js { @contacts = @contacts.page(params[:page]).per(20) }
17
- format.json { render :text => to_json(@contacts) }
11
+ format.html
12
+ format.json { render :text => to_json(@followers) }
18
13
  end
19
14
  end
20
15
 
@@ -14,4 +14,8 @@ module PermissionsHelper
14
14
  Permission.find_or_create_by_action_and_object *p
15
15
  }
16
16
  end
17
+
18
+ def disable_permission_edit? perm
19
+ (perm.action == 'represent') and (@relation.ties.size > 0) and perm.relations.include?(@relation) and (perm.relations.where(:actor_id => @relation.actor_id).find_all{|r| r.ties.size > 0}.size <= 1)
20
+ end
17
21
  end
@@ -11,6 +11,10 @@ class ActivityAction < ActiveRecord::Base
11
11
  where(:actor_id => Actor.normalize_id(actor))
12
12
  }
13
13
 
14
+ scope :not_sent_by, lambda{ |actor|
15
+ where(arel_table[:actor_id].not_in(Actor.normalize_id(actor)))
16
+ }
17
+
14
18
  scope :received_by, lambda{ |activity_object|
15
19
  where(:activity_object_id => ActivityObject.normalize_id(activity_object))
16
20
  }
@@ -56,6 +56,11 @@ class ActivityObject < ActiveRecord::Base
56
56
  merge(ActivityAction.sent_by(subject).where(:author => true))
57
57
  }
58
58
 
59
+ scope :not_authored_by, lambda { |subject|
60
+ joins(:received_actions).
61
+ merge(ActivityAction.not_sent_by(subject).where(:author => true))
62
+ }
63
+
59
64
  scope :followed, order("activity_objects.follower_count DESC")
60
65
 
61
66
  def received_role_action(role)
@@ -122,6 +127,10 @@ class ActivityObject < ActiveRecord::Base
122
127
  object_type == "Actor"
123
128
  end
124
129
 
130
+ def actor!
131
+ actor || raise("Unknown Actor for ActivityObject: #{ inspect }")
132
+ end
133
+
125
134
  # Return the {Action} model to an {Actor}
126
135
  def action_from(actor)
127
136
  received_actions.sent_by(actor).first
@@ -82,6 +82,10 @@ class Actor < ActiveRecord::Base
82
82
  has_many :sent_actions,
83
83
  :class_name => "ActivityAction",
84
84
  :dependent => :destroy
85
+ has_many :followings,
86
+ :through => :sent_actions,
87
+ :source => :activity_object,
88
+ :conditions => { 'activity_actions.follow' => true }
85
89
 
86
90
  scope :alphabetic, order('actors.name')
87
91
 
@@ -294,6 +298,21 @@ class Actor < ActiveRecord::Base
294
298
 
295
299
  alias_method :ego_contact, :self_contact
296
300
 
301
+ # The {ActivityObject ActivityObjects} followed by this {Actor}
302
+ # that are {Actor Actors}
303
+ def following_actor_objects
304
+ followings.
305
+ where('activity_objects.object_type' => "Actor")
306
+ end
307
+
308
+ # An array with the ids of {Actor Actors} followed by this {Actor}
309
+ def following_actor_ids
310
+ following_actor_objects.
311
+ includes(:actor).
312
+ map(&:actor).
313
+ map(&:id)
314
+ end
315
+
297
316
  # The {Channel} of this {Actor} to self (totally close!)
298
317
  def self_channel
299
318
  Channel.find_or_create_by_author_id_and_user_author_id_and_owner_id id, id, id
@@ -1,3 +1,8 @@
1
+ # {Group Groups} are the other kind of social entities supported in SocialStream::Base
2
+ #
3
+ # As with {User}, almost all the interaction with other classes in Social Stream is done
4
+ # through {Actor}. The glue between {Group} and {Actor} is in {SocialStream::Models::Subject}
5
+ #
1
6
  class Group < ActiveRecord::Base
2
7
  include SocialStream::Models::Subject
3
8
 
@@ -6,7 +6,8 @@
6
6
  class Relation::Single < Relation
7
7
  class << self
8
8
  def instance
9
- first || create!
9
+ @instance ||=
10
+ first || create!
10
11
  end
11
12
  end
12
13
 
@@ -6,7 +6,7 @@ require 'devise/orm/active_record'
6
6
  # for managing authentication
7
7
  #
8
8
  # Almost all the logic of the interaction between {User} and the rest of classes in Social Stream
9
- # is done through {SocialStream::Models::Subject} and {Actor}
9
+ # is done through {Actor}. The glue between {User} and {Actor} is in {SocialStream::Models::Subject}
10
10
  #
11
11
  class User < ActiveRecord::Base
12
12
  include SocialStream::Models::Subject
@@ -0,0 +1,2 @@
1
+ $('#conversation_<%= @conversation.id %>').remove();
2
+
@@ -1,5 +1,26 @@
1
- <% if params[:following] %>
2
- <%= render @contacts %>
3
- <% else %>
4
- <%= render @contacts.map(&:inverse!) %>
5
- <% end %>
1
+ <% sidebar %>
2
+ <% toolbar :profile, :subject => current_subject %>
3
+ <div class="followers tabbable">
4
+ <ul class="nav nav-tabs">
5
+ <li class="active">
6
+ <a data-toggle="tab" href="#following"><%=t('follow.followings')%></a>
7
+ </li>
8
+ <li class="">
9
+ <a data-toggle="tab" href="#follower"><%=t('follow.followers')%></a>
10
+ </li>
11
+ </ul>
12
+ <div class="tab-content">
13
+ <div id="following" class="tab-pane active offset1">
14
+ <%= render @followings.
15
+ page(params[:page]).
16
+ per(20).
17
+ map { |f| current_subject.contact_to!(f) } %>
18
+ </div>
19
+ <div id="follower" class="tab-pane offset1 ">
20
+ <%= render @followers.
21
+ page(params[:page]).
22
+ per(20).
23
+ map { |f| current_subject.contact_to!(f) } %>
24
+ </div>
25
+ </div>
26
+ </div>
@@ -9,8 +9,13 @@
9
9
  <tr>
10
10
  <td>
11
11
  <div contain=<%= dom_id p %> class="checkboxPermissionOptionLeft">
12
- <input id=<%= dom_id p %> class="permission" type="checkbox"/>
13
- <label for=<%= dom_id p %>><%= p.description(:brief, :subject => current_subject) %></label>
12
+ <% if disable_permission_edit? p %>
13
+ <input id=<%= dom_id p %> class="permission" type="checkbox" disabled="disabled"/>
14
+ <label for=<%= dom_id p %>><%= p.description(:brief, :subject => current_subject) %></label>
15
+ <% else %>
16
+ <input id=<%= dom_id p %> class="permission" type="checkbox"/>
17
+ <label for=<%= dom_id p %>><%= p.description(:brief, :subject => current_subject) %></label>
18
+ <% end %>
14
19
  <div class="clearfloat"></div>
15
20
  </div>
16
21
  </td>
@@ -1,15 +1,10 @@
1
-
1
+ <% if @profile.valid? %>
2
+ <% flash[:notice] = t('profile.update.success') %>
3
+ document.location.href="<%= resource_path(@profile) %>";
4
+ <% else %>
2
5
  if ($("#profile_notice").length == 0){
3
6
  $("#profile_form").prepend('<div id="profile_notice" class="notice"></div>');
4
7
  }
5
-
6
- <% if @profile.valid? %>
7
-
8
- $("#profile_notice").html("<%= t('profile.update.success')%>");
9
- $("#profile_notice").removeClass('error');
10
- $("#profile_notice").addClass('success');
11
-
12
- <% else %>
13
8
  $("#profile_notice").html("<h2><%= pluralize(@profile.errors.count, "error") %> <%= t('profile.update.error')%></h2>"
14
9
  +"<ul><% @profile.errors.full_messages.each do |msg| %><li><%= msg %></li><% end %></ul>");
15
10
  $("#profile_notice").removeClass('success');
@@ -39,6 +39,8 @@
39
39
  <%= javascript_tag do %>
40
40
  $(function(){
41
41
  $('#relation_customs_list :radio').change(function(){
42
+ $("#new_relation_custom_title_block").show();
43
+ $("#new_relation_custom_input_block").hide();
42
44
  selectRelation(this);
43
45
  });
44
46
 
@@ -56,6 +58,8 @@
56
58
  });
57
59
 
58
60
  $("#new_relation_custom_title").click(function() {
61
+ $("#permissions_list").hide();
62
+ $("#privacy_rules").hide();
59
63
  $("#new_relation_custom_title_block").hide();
60
64
  $("#new_relation_custom_input_block").show();
61
65
  });
@@ -191,6 +191,10 @@ en:
191
191
  instructions: "Type the email address bound to your account and we will sent you instructions to change it:"
192
192
  update: "Change your password"
193
193
  follower:
194
+ follower:
195
+ title: "Followers"
196
+ following:
197
+ title: "Followings"
194
198
  n:
195
199
  one: "1 follower"
196
200
  other: "%{count} followers"
@@ -190,7 +190,11 @@ es:
190
190
  instructions: "Introduce el correo electrónico y te mandaremos instrucciones para cambiarlo"
191
191
  update: "Cambiar contraseña"
192
192
  follower:
193
- n:
193
+ follower:
194
+ title: "Seguidores"
195
+ following:
196
+ title: "Siguiendo"
197
+ n:
194
198
  one: "1 seguidor/a"
195
199
  other: "%{count} seguidores"
196
200
  forgot_password: "¿Olvidaste tu contraseña?"
@@ -1,22 +1,11 @@
1
1
  Rails.application.routes.draw do
2
- #Background tasks
3
- resque_constraint = lambda do |request|
4
- #request.env['warden'].authenticate? and request.env['warden'].user.admin?
5
- true
6
- end
7
-
8
- constraints resque_constraint do
9
- mount Resque::Server, :at => "/resque"
10
- end
11
-
12
2
  root :to => "frontpage#index"
13
3
 
14
4
  match 'home' => 'home#index', :as => :home
15
5
  match 'home' => 'home#index', :as => :user_root # devise after_sign_in_path_for
16
-
17
- # Webfinger
18
- match '.well-known/host-meta',:to => 'frontpage#host_meta'
19
-
6
+
7
+ match 'search' => 'search#index', :as => :search
8
+
20
9
  # Social Stream subjects configured in config/initializers/social_stream.rb
21
10
  SocialStream.subjects.each do |actor|
22
11
  resources actor.to_s.pluralize do
@@ -40,15 +29,9 @@ Rails.application.routes.draw do
40
29
  resources object.to_s.pluralize
41
30
  end
42
31
 
43
- case SocialStream.relation_model
44
- when :follow
45
- resources :followers
46
- resources :contacts do
47
- collection do
48
- get 'pending'
49
- end
50
- end
51
- when :custom
32
+ resources :comments
33
+
34
+ constraints SocialStream::Routing::Constraints::Custom.new do
52
35
  resources :contacts do
53
36
  collection do
54
37
  get 'pending'
@@ -62,13 +45,20 @@ Rails.application.routes.draw do
62
45
  resources :permissions
63
46
  end
64
47
 
48
+ constraints SocialStream::Routing::Constraints::Follow.new do
49
+ match 'followings' => 'followers#index', :as => :followings, :defaults => { :direction => 'sent' }
50
+ match 'followers' => 'followers#index', :as => :followers, :defaults => { :direction => 'received' }
51
+ resources :followers
52
+
53
+ resources :contacts do
54
+ collection do
55
+ get 'pending'
56
+ end
57
+ end
58
+ end
59
+
65
60
  resources :activity_actions
66
61
 
67
- match 'tags' => 'tags#index', :as => 'tags'
68
-
69
- # Find subjects by slug
70
- match 'subjects/lrdd/:id' => 'subjects#lrdd', :as => 'subject_lrdd'
71
-
72
62
  resource :representation
73
63
 
74
64
  resources :settings do
@@ -89,19 +79,16 @@ Rails.application.routes.draw do
89
79
  end
90
80
  end
91
81
 
92
- resources :comments
93
-
94
82
  resources :activities do
95
83
  resource :like
96
84
  end
97
85
 
98
- match 'search' => 'search#index', :as => :search
99
-
100
86
  match 'cheesecake' => 'cheesecake#index', :as => :cheesecake
101
87
  match 'update_cheesecake' => 'cheesecake#update', :as => :update_cheesecake
102
88
 
103
89
  match 'ties' => 'ties#index', :as => :ties
104
90
 
91
+ match 'tags' => 'tags#index', :as => 'tags'
105
92
 
106
93
  ##API###
107
94
  match 'api/keygen' => 'api#create_key', :as => :api_keygen
@@ -113,4 +100,16 @@ Rails.application.routes.draw do
113
100
  match 'api/me/contacts' => 'contacts#index', :format => 'json', :as => :api_contacts
114
101
  match 'api/subjects/:s/contacts' => 'contacts#index', :format => 'json', :as => :api_subject_contacts
115
102
  ##/API##
103
+
104
+
105
+ #Background tasks
106
+ constraints SocialStream::Routing::Constraints::Resque.new do
107
+ mount Resque::Server, :at => "/resque"
108
+ end
109
+
110
+ # Webfinger
111
+ match '.well-known/host-meta',:to => 'frontpage#host_meta'
112
+
113
+ # Find subjects by slug
114
+ match 'subjects/lrdd/:id' => 'subjects#lrdd', :as => 'subject_lrdd'
116
115
  end
@@ -27,7 +27,11 @@ SocialStream.setup do |config|
27
27
  # :follow - user just follow other users, like Twitter
28
28
  #
29
29
  # config.relation_model = :custom
30
-
30
+
31
+ # Expose resque interface to manage background tasks at /resque
32
+ #
33
+ # config.resque_access = true
34
+
31
35
  # Quick search (header) and Extended search models and its order. Remember to create
32
36
  # the indexes with thinking-sphinx if you are using customized models.
33
37
  #
@@ -26,6 +26,14 @@ module SocialStream
26
26
  autoload :Supertype, 'social_stream/models/supertype'
27
27
  end
28
28
 
29
+ module Routing
30
+ module Constraints
31
+ autoload :Custom, 'social_stream/routing/constraints/custom'
32
+ autoload :Follow, 'social_stream/routing/constraints/follow'
33
+ autoload :Resque, 'social_stream/routing/constraints/resque'
34
+ end
35
+ end
36
+
29
37
  module Views
30
38
  autoload :List, 'social_stream/views/list'
31
39
 
@@ -62,7 +70,10 @@ module SocialStream
62
70
 
63
71
  mattr_accessor :relation_model
64
72
  @@relation_model = :custom
65
-
73
+
74
+ mattr_accessor :resque_access
75
+ @@resque_access = true
76
+
66
77
  mattr_accessor :quick_search_models
67
78
  @@quick_search_models = [ :user, :group, :post ]
68
79
 
@@ -1,5 +1,5 @@
1
1
  module SocialStream
2
2
  module Base
3
- VERSION = "0.19.1".freeze
3
+ VERSION = "0.19.2".freeze
4
4
  end
5
5
  end
@@ -24,6 +24,11 @@ module SocialStream
24
24
  joins(:activity_object).
25
25
  merge(ActivityObject.authored_by(subject))
26
26
  }
27
+
28
+ scope :not_authored_by, lambda { |subject|
29
+ joins(:activity_object).
30
+ merge(ActivityObject.not_authored_by(subject))
31
+ }
27
32
  end
28
33
  end
29
34
  end