diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index e96cefd..1a79945 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -41,6 +41,23 @@ class UserMailer < ActionMailer::Base ) end + def profiles_suggestions_email(user) + @recipient = user.name + @environment = user.environment.name + @url = user.environment.top_url + @people_suggestions_url = user.people_suggestions_url + @people_suggestions = user.suggested_people.sample(3) + @communities_suggestions_url = user.communities_suggestions_url + @communities_suggestions = user.suggested_communities.sample(3) + + mail( + content_type: 'text/html', + to: user.email, + from: "#{user.environment.name} <#{user.environment.contact_email}>", + subject: _("[%s] We have suggestions for your network") % user.environment.name + ) + end + class Job < Struct.new(:user, :method) def perform UserMailer.send(method, user).deliver diff --git a/app/models/profile.rb b/app/models/profile.rb index bbec988..ffdade7 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -513,6 +513,14 @@ class Profile < ActiveRecord::Base generate_url(:profile => identifier, :controller => 'profile', :action => 'index') end + def people_suggestions_url + generate_url(:profile => identifier, :controller => 'friends', :action => 'suggest') + end + + def communities_suggestions_url + generate_url(:profile => identifier, :controller => 'memberships', :action => 'suggest') + end + def generate_url(options) url_options.merge(options) end diff --git a/app/models/profile_suggestion.rb b/app/models/profile_suggestion.rb index 037de13..8964097 100644 --- a/app/models/profile_suggestion.rb +++ b/app/models/profile_suggestion.rb @@ -29,6 +29,119 @@ class ProfileSuggestion < ActiveRecord::Base settings_items category.to_sym attr_accessible category.to_sym end + + RULES = %w[ + friends_of_friends_with_common_friends + people_with_common_communities + people_with_common_tags + communities_with_common_friends + communities_with_common_tags + ] + + # Number of suggestions + N_SUGGESTIONS = 30 + + # Number max of attempts + MAX_ATTEMPTS = N_SUGGESTIONS * 2 + + # Number of friends in common + COMMON_FRIENDS = 2 + + # Number of communities in common + COMMON_COMMUNITIES = 1 + + # Number of friends in common + COMMON_TAGS = 2 + + def self.friends_of_friends_with_common_friends(person) + person_attempts = 0 + person_friends = person.friends + person_friends.each do |friend| + friend.friends.includes.each do |friend_of_friend| + person_attempts += 1 + return unless person.profile_suggestions.count < N_SUGGESTIONS && person_attempts < MAX_ATTEMPTS + unless friend_of_friend == person || friend_of_friend.is_a_friend?(person) || person.already_request_friendship?(friend_of_friend) + common_friends = friend_of_friend.friends & person_friends + if common_friends.size >= COMMON_FRIENDS + person.profile_suggestions.create(:suggestion => friend_of_friend, :common_friends => common_friends.size) + end + end + end + end + end + + def self.people_with_common_communities(person) + person_attempts = 0 + person_communities = person.communities + person_communities.each do |community| + community.members.each do |member| + person_attempts += 1 + return unless person.profile_suggestions.count < N_SUGGESTIONS && person_attempts < MAX_ATTEMPTS + unless member == person || member.is_a_friend?(person) || person.already_request_friendship?(member) + common_communities = person_communities & member.communities + if common_communities.size >= COMMON_COMMUNITIES + person.profile_suggestions.create(:suggestion => member, :common_communities => common_communities.size) + end + end + end + end + end + + def self.people_with_common_tags(person) + person_attempts = 0 + tags = person.article_tags.keys + tags.each do |tag| + person_attempts += 1 + return unless person.profile_suggestions.count < N_SUGGESTIONS && person_attempts < MAX_ATTEMPTS + tagged_content = ActsAsTaggableOn::Tagging.includes(:taggable).where(:tag_id => ActsAsTaggableOn::Tag.find_by_name(tag)) + tagged_content.each do |tg| + author = tg.taggable.created_by + unless author.nil? || author == person || author.is_a_friend?(person) || person.already_request_friendship?(author) + common_tags = tags & author.article_tags.keys + if common_tags.size >= COMMON_TAGS + person.profile_suggestions.create(:suggestion => author, :common_tags => common_tags.size) + end + end + end + end + end + + def self.communities_with_common_friends(person) + community_attempts = 0 + person_friends = person.friends + person_friends.each do |friend| + friend.communities.each do |community| + community_attempts += 1 + return unless person.profile_suggestions.count < N_SUGGESTIONS && community_attempts < MAX_ATTEMPTS + unless person.is_member_of?(community) || community.already_request_membership?(person) + common_friends = community.members & person.friends + if common_friends.size >= COMMON_FRIENDS + person.profile_suggestions.create(:suggestion => community, :common_friends => common_friends.size) + end + end + end + end + end + + def self.communities_with_common_tags(person) + community_attempts = 0 + tags = person.article_tags.keys + tags.each do |tag| + community_attempts += 1 + return unless person.profile_suggestions.count < N_SUGGESTIONS && community_attempts < MAX_ATTEMPTS + tagged_content = ActsAsTaggableOn::Tagging.includes(:taggable).where(:tag_id => ActsAsTaggableOn::Tag.find_by_name(tag)) + tagged_content.each do |tg| + profile = tg.taggable.profile + unless !profile.community? || person.is_member_of?(profile) || profile.already_request_membership?(person) + common_tags = tags & profile.article_tags.keys + if common_tags.size >= COMMON_TAGS + person.profile_suggestions.create(:suggestion => profile, :common_tags => common_tags.size) + end + end + end + end + end + def disable self.enabled = false self.save diff --git a/app/views/user_mailer/profiles_suggestions_email.html.erb b/app/views/user_mailer/profiles_suggestions_email.html.erb new file mode 100644 index 0000000..ea77df2 --- /dev/null +++ b/app/views/user_mailer/profiles_suggestions_email.html.erb @@ -0,0 +1,32 @@ +<%= _('Hi, %{recipient}!') % { :recipient => @recipient } %> + +

<%= _('We want to give you some suggestions to grow up your network. Check it out!') %>

+ +<% unless @people_suggestions.empty? %> +

<%= _('Friends suggestions:') %>

+ +