social_stream-base 0.7.11 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -11,3 +11,4 @@ nbproject
11
11
  lib/generators/social_stream/base/templates/public/images/tmp/
12
12
  **.*swp
13
13
  .code_swarm
14
+ .rvmrc
@@ -0,0 +1,67 @@
1
+ //= require d3
2
+ //= require d3.layout
3
+ //= require d3.geom
4
+
5
+ (function( $ ){
6
+ $.fn.tiesGraph = function( data ) {
7
+ //TODO: better handling of width and height
8
+ var w = 860,
9
+ h = 500,
10
+ fill = d3.scale.category20();
11
+
12
+ var vis = d3.select(this.selector)
13
+ .append("svg:svg")
14
+ .attr("width", w)
15
+ .attr("height", h);
16
+
17
+ var force = d3.layout.force()
18
+ .charge(-120)
19
+ .linkDistance(40)
20
+ .nodes(data.nodes)
21
+ .links(data.links)
22
+ .size([w, h])
23
+ .start();
24
+
25
+ var link = vis.selectAll("line.link")
26
+ .data(data.links)
27
+ .enter().append("svg:line")
28
+ .attr("class", "link")
29
+ .style("stroke-width", function(d) { return Math.sqrt(d.value); })
30
+ .attr("x1", function(d) { return d.source.x; })
31
+ .attr("y1", function(d) { return d.source.y; })
32
+ .attr("x2", function(d) { return d.target.x; })
33
+ .attr("y2", function(d) { return d.target.y; });
34
+
35
+ var node = vis.selectAll("g.node")
36
+ .data(data.nodes)
37
+ .enter().append("svg:g")
38
+ .attr("class", "node")
39
+ .call(force.drag);
40
+
41
+ node.append("svg:image")
42
+ .attr("class", "circle")
43
+ .attr("xlink:href", function(d) { return d.logo; })
44
+ .attr("x", "-10px")
45
+ .attr("y", "-10px")
46
+ .attr("width", "20px")
47
+ .attr("height", "20px");
48
+
49
+ node.append("svg:title")
50
+ .text(function(d) { return d.name; });
51
+
52
+ vis.style("opacity", 1e-6)
53
+ .transition()
54
+ .duration(1000)
55
+ .style("opacity", 1);
56
+
57
+ force.on("tick", function() {
58
+ link.attr("x1", function(d) { return d.source.x; })
59
+ .attr("y1", function(d) { return d.source.y; })
60
+ .attr("x2", function(d) { return d.target.x; })
61
+ .attr("y2", function(d) { return d.target.y; });
62
+
63
+ node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
64
+ });
65
+ };
66
+ })( jQuery );
67
+
@@ -23,7 +23,7 @@
23
23
  .activity { text-align:left; display: block; vertical-align: top; padding: 10px 0px 5px 0px;
24
24
  display: inline-block; color: #000; font-size: 13px; color: #2A3890;border-bottom:1px solid #E9E9E9;}
25
25
  .actor_logo { width: 38px; padding: 8px 0px 5px 5px; display: inline-block; vertical-align: top;}
26
- .activity_content { padding: 8px 0px 0px 0px; display: inline-block; color: #000; width: 90%;}
26
+ .activity_content { padding: 8px 0px 0px 0px; display: inline-block; color: #000; width: 89%;}
27
27
  .actor_name {font-size: 13px;}
28
28
  .actor_name a{font-weight: bold;}
29
29
  .post a { color: #2A3890;}
@@ -1,6 +1,6 @@
1
1
  /*************Basic SECTION ********************/
2
2
  * { margin: 0; padding: 0; font-family: Arial; }
3
- html, body {height: 100%;}
3
+ html, body {height: auto;}
4
4
  .p { margin: 0px; padding: 0px; font-size: inherit; font-family: inherit; font-weight: inherit;
5
5
  text-align: inherit; color: inherit; line-height: inherit; vertical-align: top;}
6
6
  p { padding-top: 0px; margin-top: 0px;}
@@ -15,7 +15,7 @@ h2{padding-left:10px;}
15
15
 
16
16
 
17
17
  /******* Main Structure SECTION***************************/
18
- body{font-size:1.0em; color:#2A3890; background-color:#ffffff; }
18
+ body{font-size:1.0em; color:#2A3890; background-color:#ffffff; overflow-y: scroll;}
19
19
  #wrapper { background-color: #f5f5f5; width: 100%; margin: 0px auto; }
20
20
  #wrapper_body{min-height: 552px; width: 960px; margin:0px auto; margin-left: auto; margin-right: auto;
21
21
  margin-top: auto; margin-bottom:auto;}
@@ -102,6 +102,7 @@ textarea.new_contact_text_area{ height: 100px; color: #2A3890;}
102
102
  .block .header_icon{ margin-top: 2px; width:14px; height:14px; }
103
103
  .block .header_icon_right { float: right; padding-right: 5px; padding-top: 3px;}
104
104
  .block .header_text { margin-top: 3px; display: inline-block;}
105
+ .block .header_title { margin-top: 3px; display: inline-block; font-weight: bold}
105
106
  .block .logo{ display: inline-block; vertical-align:top;}
106
107
  .block .right{padding-right:20px; float:right;}
107
108
  .block .row { display: block;}
@@ -0,0 +1,10 @@
1
+ circle.node {
2
+ stroke: #fff;
3
+ stroke-width: 1.5px;
4
+ }
5
+
6
+ line.link {
7
+ stroke: #999;
8
+ stroke-opacity: .6;
9
+ }
10
+
@@ -0,0 +1,8 @@
1
+ class TiesController < ApplicationController
2
+ respond_to :html
3
+
4
+ before_filter :authenticate_user!
5
+
6
+ def index
7
+ end
8
+ end
@@ -1,15 +1,15 @@
1
1
  module SubjectsHelper
2
-
3
- NAME_MAX_LENGHT = 30
4
-
2
+
3
+ NAME_MAX_LENGTH = 30
4
+
5
5
  # Return a link to this subject with the name
6
6
  def link_name(subject, options = {})
7
7
  link_to subject.name, subject, options
8
8
  end
9
-
9
+
10
10
  # Return the truncated name
11
11
  def truncate_name(name, options={})
12
- options = {:length => NAME_MAX_LENGHT, :separator => ' '}.merge options
12
+ options = {:length => NAME_MAX_LENGTH, :separator => ' '}.merge options
13
13
  truncate(name,options)
14
14
  end
15
15
  end
data/app/models/actor.rb CHANGED
@@ -280,6 +280,13 @@ class Actor < ActiveRecord::Base
280
280
  ties_to(subject).present?
281
281
  end
282
282
 
283
+ # The {Tie ties} sent by this actor, plus the second grade ties
284
+ def egocentric_ties
285
+ @egocentric_ties ||=
286
+ load_egocentric_ties
287
+ end
288
+
289
+
283
290
  # Can this actor be represented by subject. Does she has permissions for it?
284
291
  def represented_by?(subject)
285
292
  return false if subject.blank?
@@ -444,4 +451,18 @@ class Actor < ActiveRecord::Base
444
451
  create_profile
445
452
  end
446
453
  end
454
+
455
+ # Calculate {#egocentric_ties}
456
+ def load_egocentric_ties
457
+ ties = sent_ties.includes(:contact).to_a
458
+
459
+ contact_ids = ties.map{ |t| t.contact.receiver_id }
460
+
461
+ second_grade_ties =
462
+ contact_ids.
463
+ map{ |i| Tie.sent_by(i) }.
464
+ flatten
465
+
466
+ ties + second_grade_ties
467
+ end
447
468
  end
@@ -0,0 +1,8 @@
1
+ <% toolbar :option => :contacts %>
2
+
3
+ <div id="ties"></div>
4
+
5
+ <%= javascript_tag do %>
6
+ var tiesData = <%= raw SocialStream::D3::Force.new(current_subject.egocentric_ties, self).to_json %>;
7
+ $('#ties').tiesGraph(tiesData);
8
+ <% end %>
@@ -307,7 +307,7 @@ en:
307
307
  title: "Privacy & context"
308
308
  relation_public:
309
309
  name: "Public"
310
- required: "* These fields are required"
310
+ required: "(*) These fields are required"
311
311
  settings:
312
312
  error: "Some errors raised when saving your changes"
313
313
  for: "Settings for"
data/config/routes.rb CHANGED
@@ -65,6 +65,7 @@ Rails.application.routes.draw do
65
65
  resource :like
66
66
  end
67
67
 
68
+ match 'ties' => 'ties#index', :as => :ties
68
69
 
69
70
  # Social Stream objects configured in config/initializers/social_stream.rb
70
71
  (SocialStream.objects - [ :actor ]).each do |object|
@@ -4,11 +4,11 @@ module Mailboxer
4
4
  def decode_notification notification_text, activity
5
5
  return if activity.nil?
6
6
  notification_text = notification_text.gsub(/\%\{sender\}/, link_to(truncate_name(activity.sender.name),
7
- url_for(:controller=> activity.sender.subject.class.to_s.downcase.pluralize,
7
+ url_for(:controller=> activity.sender.subject.class.to_s.underscore.pluralize,
8
8
  :action=> :show, :id=> activity.sender.subject.slug, :only_path => false)))
9
9
  notification_text = notification_text.gsub(/\%\{confirm\}/,link_to(t('notification.confirm'),edit_contact_url(activity.receiver.contact_to!(activity.sender), :s => activity.sender.slug)))
10
10
  notification_text = notification_text.gsub(/\%\{look\}/,link_to(t('notification.look'),
11
- url_for(:controller=> activity.sender.subject.class.to_s.downcase.pluralize,
11
+ url_for(:controller=> activity.sender.subject.class.to_s.underscore.pluralize,
12
12
  :action=> :show, :id=> activity.sender.subject.slug, :only_path => false)))
13
13
  notification_text = notification_text.gsub(/\%\{sender.name\}/,truncate_name(activity.sender.name))
14
14
 
@@ -23,12 +23,12 @@ module Mailboxer
23
23
  if activity.direct_object.present?
24
24
  object = activity.direct_object
25
25
  object = object.subject if object.is_a? Actor
26
- notification_text=notification_text.gsub(/\%\{object\}/,link_to(object.class.to_s.downcase,
27
- url_for(:controller=> object.class.to_s.downcase.pluralize, :action=> :show,
26
+ notification_text=notification_text.gsub(/\%\{object\}/,link_to(object.class.to_s.underscore,
27
+ url_for(:controller=> object.class.to_s.underscore.pluralize, :action=> :show,
28
28
  :id=> object.id, :only_path => false)))
29
- notification_text=notification_text.gsub(/\%\{object.name\}/,object.class.to_s.downcase)
29
+ notification_text=notification_text.gsub(/\%\{object.name\}/,object.class.to_s.underscore)
30
30
  notification_text=notification_text.gsub(/\%\{object.text\}/,link_to(object.text.truncate(100, :separator =>' '),
31
- url_for(:controller=> object.class.to_s.downcase.pluralize, :action=> :show,
31
+ url_for(:controller=> object.class.to_s.underscore.pluralize, :action=> :show,
32
32
  :id=> object.id, :only_path => false))) if object.respond_to? :text
33
33
 
34
34
  #notification_text=notification_text.gsub(/\%\{object.image\}/,thumb_for(object)) if SocialStream.activity_forms.include? :document and object.is_a? Document
@@ -59,8 +59,8 @@ module Mailboxer
59
59
  if activity.direct_object.present?
60
60
  object = activity.direct_object
61
61
  object = object.subject if object.is_a? Actor
62
- notification_text=notification_text.gsub(/\%\{object\}/,object.class.to_s.downcase)
63
- notification_text=notification_text.gsub(/\%\{object.name\}/,object.class.to_s.downcase)
62
+ notification_text=notification_text.gsub(/\%\{object\}/,object.class.to_s.underscore)
63
+ notification_text=notification_text.gsub(/\%\{object.name\}/,object.class.to_s.underscore)
64
64
  notification_text=notification_text.gsub(/\%\{object.text\}/,object.text.truncate(100, :separator =>' ')) if object.respond_to? :text
65
65
 
66
66
  #notification_text=notification_text.gsub(/\%\{object.image\}/,thumb_for(object)) if SocialStream.activity_forms.include? :document and object.is_a? Document
@@ -1,5 +1,5 @@
1
1
  module SocialStream
2
2
  module Base
3
- VERSION = "0.7.11".freeze
3
+ VERSION = "0.8.0".freeze
4
4
  end
5
5
  end
@@ -57,9 +57,8 @@ module SocialStream
57
57
  # Requirements: the controller must inherit from +InheritedResources::Base+ and the method
58
58
  # {ClassMethods#belongs_to_subjects} must be called
59
59
  #
60
- #
61
60
  # class PostsController < InheritedResources::Base
62
- # belongs_to_subjects
61
+ # belongs_to_subjects :optional => true
63
62
  # end
64
63
  #
65
64
  # # /users/demo/posts
@@ -100,10 +99,9 @@ module SocialStream
100
99
 
101
100
  subject = Actor.find_by_slug!(params[:s]).subject
102
101
 
103
- # remove security to control allow "slug" until tapiador fix it
104
- #unless subject.represented_by?(current_user)
105
- # raise CanCan::AccessDenied.new("Not authorized!", :represent, subject.name)
106
- #end
102
+ unless subject.represented_by?(current_user)
103
+ raise CanCan::AccessDenied.new("Not authorized!", :represent, subject.name)
104
+ end
107
105
 
108
106
  self.current_subject = subject
109
107
  end
@@ -0,0 +1,53 @@
1
+ module SocialStream
2
+ # Methods for d3.js library
3
+ # http://mbostock.github.com/d3/
4
+ module D3
5
+ class Force
6
+ def initialize(ties, view)
7
+ @view = view
8
+
9
+ @force =
10
+ ties.inject({ :nodes => [], :links => [] }) { |result, t|
11
+ add_node(result[:nodes], t.sender)
12
+ add_node(result[:nodes], t.receiver)
13
+
14
+ add_link(result[:links], t, result[:nodes])
15
+
16
+ result
17
+ }
18
+ end
19
+
20
+ def to_json
21
+ @force.to_json
22
+ end
23
+
24
+ private
25
+
26
+ def node(actor)
27
+ {
28
+ :name => actor.name,
29
+ :logo => @view.image_path(actor.logo.url(:representation)),
30
+ :group => SocialStream.subjects.index(actor.subject_type.underscore.to_sym) + 1
31
+ }
32
+ end
33
+
34
+ def add_node(nodes, actor)
35
+ return if nodes_actor_index(nodes, actor)
36
+
37
+ nodes << node(actor)
38
+ end
39
+
40
+ def add_link(links, tie, nodes)
41
+ links << {
42
+ :source => nodes_actor_index(nodes, tie.sender),
43
+ :target => nodes_actor_index(nodes, tie.receiver),
44
+ :value => 1
45
+ }
46
+ end
47
+
48
+ def nodes_actor_index(nodes, actor)
49
+ nodes.index(nodes.find{ |n| n[:name] == actor.name })
50
+ end
51
+ end
52
+ end
53
+ end
@@ -43,6 +43,7 @@ module SocialStream
43
43
  :options => {:link => {:id => "contacts_menu"}},
44
44
  :items => [
45
45
  {:key => :invitations, :name => image_tag("btn/btn_friend.png")+t('contact.current'), :url => contacts_path},
46
+ {:key => :contacts_graph, :name => image_tag("btn/btn_friend.png")+t('contact.graph'), :url => ties_path},
46
47
  {:key => :invitations, :name => image_tag("btn/btn_friend.png")+t('contact.pending.other'), :url => contacts_path(:pending=>true)},
47
48
  {:key => :invitations, :name => image_tag("btn/btn_invitation.png")+t('invitation.toolbar'), :url => new_invitation_path}
48
49
  ]}
@@ -39,6 +39,7 @@ require 'modernizr-rails'
39
39
  # Provides your Rails application with social network and activity stream support
40
40
  module SocialStream
41
41
  autoload :Ability, 'social_stream/ability'
42
+ autoload :D3, 'social_stream/d3'
42
43
  autoload :Populate, 'social_stream/populate'
43
44
  autoload :Relations, 'social_stream/relations'
44
45
  autoload :TestHelpers, 'social_stream/test_helpers'
@@ -95,11 +96,16 @@ module SocialStream
95
96
  #
96
97
  # Maybe Rails provides some method to do this, in this case, please tell!!
97
98
  def require_model(m)
98
- path = $:.find{ |f| f =~ Regexp.new(File.join('social_stream.*', 'app', 'models')) }
99
+ paths = $:.find_all{ |f| f =~ Regexp.new(File.join('social_stream.*', 'app', 'models')) }
99
100
 
100
- raise "Can't find social_stream path" if path.blank?
101
+ raise "Can't find social_stream path" if paths.blank?
102
+
103
+ paths.each do |path|
104
+ if File.exists?(File.join(path, "#{m}.rb"))
105
+ require_dependency File.join(path, m)
106
+ end
107
+ end
101
108
 
102
- require_dependency File.join(path, m)
103
109
  end
104
110
  end
105
111
  end
@@ -1,26 +1,26 @@
1
1
  namespace :db do
2
2
  desc 'Populate database with fake data for development'
3
3
  task :populate => [ 'db:seed', 'db:populate:create' ]
4
-
4
+
5
5
  namespace :populate do
6
-
6
+
7
7
  desc "Reload populate data"
8
8
  task :reload => [ 'db:reset', :create ]
9
-
9
+
10
10
  desc "Create populate data"
11
11
  task :create => :environment do
12
-
12
+
13
13
  LOGOS_PATH = File.join(Rails.root, 'lib', 'logos')
14
-
14
+
15
15
  Mailboxer.setup do |config|
16
16
  config.uses_emails = false
17
17
  end
18
-
18
+
19
19
  def set_logos(klass)
20
20
  klass.all.each do |i|
21
21
  logo = Dir[File.join(LOGOS_PATH, klass.to_s.tableize, "#{ i.id }.*")].first
22
22
  avatar = Dir[File.join(LOGOS_PATH, klass.to_s.tableize, "#{ i.id }.*")].first
23
-
23
+
24
24
  if avatar.present? && File.exists?(avatar)
25
25
  Avatar.copy_to_temp_file(avatar)
26
26
  dimensions = Avatar.get_image_dimensions(avatar)
@@ -30,7 +30,7 @@ namespace :db do
30
30
  end
31
31
  end
32
32
  end
33
-
33
+
34
34
  def set_tags(klass)
35
35
  klass.all.each do |el|
36
36
  el.tag_list = Forgery::LoremIpsum.words(1,:random => true)+", "+
@@ -39,12 +39,12 @@ namespace :db do
39
39
  el.save!
40
40
  end
41
41
  end
42
-
42
+
43
43
  puts 'User population'
44
44
  users_start = Time.now
45
-
45
+
46
46
  # = Users
47
-
47
+
48
48
  # Create demo user if not present
49
49
  if User.find_by_name('demo').blank?
50
50
  User.create! :name => 'Demo',
@@ -52,100 +52,98 @@ namespace :db do
52
52
  :password => 'demonstration',
53
53
  :password_confirmation => 'demonstration'
54
54
  end
55
-
55
+
56
56
  require 'forgery'
57
-
57
+
58
58
  9.times do
59
59
  User.create! :name => Forgery::Name.full_name,
60
60
  :email => Forgery::Internet.email_address,
61
61
  :password => 'demonstration',
62
62
  :password_confirmation => 'demonstration'
63
63
  end
64
-
65
- set_logos(User)
66
-
67
- users_end = Time.now
64
+
65
+
66
+ users_end = Time.now
68
67
  puts ' -> ' + (users_end - users_start).round(4).to_s + 's'
69
-
68
+
70
69
  puts 'Groups population'
71
70
  groups_start = Time.now
72
-
71
+
73
72
  # = Groups
74
73
  available_actors = Actor.all
75
74
 
76
75
  10.times do
77
76
  founder = available_actors[rand(available_actors.size)]
78
-
77
+
79
78
  Group.create! :name => Forgery::Name.company_name,
80
79
  :email => Forgery::Internet.email_address,
81
80
  :_founder => founder.slug
82
81
  end
83
-
84
- set_logos(Group)
82
+
85
83
  set_tags(Group)
86
-
87
- groups_end = Time.now
84
+
85
+ groups_end = Time.now
88
86
  puts ' -> ' + (groups_end - groups_start).round(4).to_s + 's'
89
-
90
-
87
+
88
+
91
89
  puts 'Ties population'
92
90
  ties_start = Time.now
93
-
91
+
94
92
  # Reload actors to include groups
95
- available_actors = Actor.all
96
-
93
+ available_actors = Actor.all
94
+
97
95
  # = Ties
98
96
  available_actors.each do |a|
99
97
  actors = available_actors.dup - Array(a)
100
98
  relations = a.relations
101
-
99
+
102
100
  Forgery::Basic.number(:at_most => actors.size).times do
103
101
  actor = actors.delete_at((rand * actors.size).to_i)
104
- a.contact_to!(actor).relation_ids = Array(relations.random.id)
102
+ a.contact_to!(actor).relation_ids = Array(Forgery::Extensions::Array.new(relations).random.id)
105
103
  end
106
104
  end
107
-
105
+
108
106
  ties_end = Time.now
109
107
  puts ' -> ' + (ties_end - ties_start).round(4).to_s + 's'
110
-
108
+
111
109
  # = Posts
112
-
110
+
113
111
  puts 'Post population'
114
112
  posts_start = Time.now
115
-
113
+
116
114
  SocialStream::Populate.power_law(Tie.all) do |t|
117
115
  updated = Time.at(rand(Time.now.to_i))
118
-
116
+
119
117
  p = Post.create :text =>
120
118
  "This post should be for #{ t.relation.name } of #{ t.sender.name }.\n#{ Forgery::LoremIpsum.paragraph(:random => true) }",
121
119
  :created_at => Time.at(rand(updated.to_i)),
122
120
  :updated_at => updated,
123
121
  :_contact_id => t.contact_id,
124
122
  :_relation_ids => Array(t.relation_id)
125
-
123
+
126
124
  p.post_activity.update_attributes(:created_at => p.created_at,
127
125
  :updated_at => p.updated_at)
128
126
  end
129
-
130
- posts_end = Time.now
127
+
128
+ posts_end = Time.now
131
129
  puts ' -> ' + (posts_end - posts_start).round(4).to_s + 's'
132
-
130
+
133
131
  puts 'Mailboxer population'
134
132
  mailboxer_start = Time.now
135
-
133
+
136
134
  # = Mailboxer
137
135
  available_actors = Actor.all
138
-
136
+
139
137
  available_actors.each do |a|
140
138
  actors = available_actors.dup - Array(a)
141
-
139
+
142
140
  mult_recp = actors.uniq
143
141
  if (demo = User.find_by_name('demo')) and !mult_recp.include? Actor.normalize(demo)
144
142
  mult_recp << Actor.normalize(demo)
145
143
  end
146
144
  actor = mult_recp[(rand * mult_recp.size).to_i]
147
145
  mult_recp.delete(actor)
148
- mail = actor.send_message(mult_recp, "Hello all, I am #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}", Forgery::LoremIpsum.words(10,:random => true))
146
+ mail = actor.send_message(mult_recp, "Hello all, I am #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}", Forgery::LoremIpsum.words(10,:random => true))
149
147
  actor = mult_recp[(rand * mult_recp.size).to_i]
150
148
  mail = actor.reply_to_all(mail, "Well, I am #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}")
151
149
  actor = mult_recp[(rand * mult_recp.size).to_i]
@@ -153,11 +151,11 @@ namespace :db do
153
151
  actor = mult_recp[(rand * mult_recp.size).to_i]
154
152
  mail = actor.reply_to_all(mail, "Pretty well, I am #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}")
155
153
  actor = mult_recp[(rand * mult_recp.size).to_i]
156
- actor.reply_to_all(mail, "Finally, I am #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}")
157
-
158
-
154
+ actor.reply_to_all(mail, "Finally, I am #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}")
155
+
156
+
159
157
  if (demo = User.find_by_name('demo'))
160
- next if Actor.normalize(demo)==Actor.normalize(a)
158
+ next if Actor.normalize(demo)==Actor.normalize(a)
161
159
  mail = a.send_message(demo, "Hello, #{demo.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}", Forgery::LoremIpsum.words(10,:random => true))
162
160
  if rand > 0.5
163
161
  mail = demo.reply_to_sender(mail, "Pretty well #{a.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}")
@@ -168,11 +166,11 @@ namespace :db do
168
166
  if rand > 0.75
169
167
  mail.conversation.move_to_trash(demo)
170
168
  end
171
- end
172
-
169
+ end
170
+
173
171
  Forgery::Basic.number(:at_most => actors.size).times do
174
172
  actor = actors.delete_at((rand * actors.size).to_i)
175
- next if Actor.normalize(actor)==Actor.normalize(a)
173
+ next if Actor.normalize(actor)==Actor.normalize(a)
176
174
  mail = a.send_message(actor, "Hello, #{actor.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}", Forgery::LoremIpsum.words(10,:random => true))
177
175
  if rand > 0.5
178
176
  mail = actor.reply_to_sender(mail, "Pretty well #{a.name}. #{Forgery::LoremIpsum.sentences(2,:random => true)}")
@@ -182,13 +180,21 @@ namespace :db do
182
180
  end
183
181
  if rand > 0.75
184
182
  mail.conversation.move_to_trash(actor)
185
- end
183
+ end
186
184
  end
187
185
  end
188
-
186
+
189
187
  mailboxer_end = Time.now
190
188
  puts ' -> ' + (mailboxer_end - mailboxer_start).round(4).to_s + 's'
191
-
189
+
190
+
191
+
192
+ puts 'Avatar population'
193
+ avatar_start = Time.now
194
+ SocialStream.subjects.each {|a| set_logos(Kernel.const_get(a.to_s.classify)) }
195
+ avatar_end = Time.now
196
+ puts ' -> ' + (avatar_end - avatar_start).round(4).to_s + 's'
197
+
192
198
  end
193
199
  end
194
200
  end