social_engine 0.0.1

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.
Files changed (68) hide show
  1. data/Gemfile +13 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +340 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/comments_controller.rb +13 -0
  6. data/app/controllers/favorites_controller.rb +21 -0
  7. data/app/controllers/ratings_controller.rb +15 -0
  8. data/app/controllers/reputation_actions_controller.rb +13 -0
  9. data/app/controllers/social_engine_controller.rb +32 -0
  10. data/app/controllers/votes_controller.rb +15 -0
  11. data/app/helpers/social_engine_helper.rb +82 -0
  12. data/app/models/comment.rb +10 -0
  13. data/app/models/favorite.rb +4 -0
  14. data/app/models/friending.rb +21 -0
  15. data/app/models/rating.rb +6 -0
  16. data/app/models/reputation.rb +24 -0
  17. data/app/models/reputation_action.rb +15 -0
  18. data/app/models/social_engine/commentable.rb +14 -0
  19. data/app/models/social_engine/favoriteable.rb +14 -0
  20. data/app/models/social_engine/friendable.rb +56 -0
  21. data/app/models/social_engine/helpers.rb +37 -0
  22. data/app/models/social_engine/rateable.rb +33 -0
  23. data/app/models/social_engine/reputatable.rb +14 -0
  24. data/app/models/social_engine/sociable.rb +17 -0
  25. data/app/models/social_engine/social_user.rb +16 -0
  26. data/app/models/social_engine/voteable.rb +28 -0
  27. data/app/models/vote.rb +13 -0
  28. data/app/views/comments/_comment.haml +11 -0
  29. data/app/views/comments/_form.haml +8 -0
  30. data/app/views/comments/_list.haml +4 -0
  31. data/app/views/comments/new.haml +1 -0
  32. data/app/views/common/_user_attributes.haml +6 -0
  33. data/app/views/favorites/_widget.haml +8 -0
  34. data/app/views/ratings/_form.haml +6 -0
  35. data/app/views/ratings/_rating.haml +3 -0
  36. data/app/views/ratings/new.haml +1 -0
  37. data/app/views/reputation_actions/_form.haml +5 -0
  38. data/app/views/reputation_actions/edit.haml +3 -0
  39. data/app/views/reputation_actions/index.haml +21 -0
  40. data/app/views/reputation_actions/new.haml +9 -0
  41. data/app/views/third_party/_fb_friend_box.html.erb +5 -0
  42. data/app/views/third_party/_fb_javascript_sdk.html.erb +13 -0
  43. data/app/views/third_party/_fb_og_tags.html.erb +10 -0
  44. data/app/views/third_party/_fblike.html.erb +3 -0
  45. data/app/views/third_party/_tweetme.html.erb +6 -0
  46. data/app/views/votes/_widget.haml +13 -0
  47. data/config/routes.rb +3 -0
  48. data/lib/generators/social_engine/install/USAGE +17 -0
  49. data/lib/generators/social_engine/install/install_generator.rb +34 -0
  50. data/lib/generators/social_engine/install/templates/create_comments_table.rb +23 -0
  51. data/lib/generators/social_engine/install/templates/create_favorites_table.rb +19 -0
  52. data/lib/generators/social_engine/install/templates/create_friendings_table.rb +20 -0
  53. data/lib/generators/social_engine/install/templates/create_ratings_table.rb +21 -0
  54. data/lib/generators/social_engine/install/templates/create_reputation_actions_table.rb +14 -0
  55. data/lib/generators/social_engine/install/templates/create_reputations_table.rb +19 -0
  56. data/lib/generators/social_engine/install/templates/create_votes_table.rb +21 -0
  57. data/lib/generators/social_engine/install/templates/formtastic.css +145 -0
  58. data/lib/generators/social_engine/install/templates/social_engine.css +26 -0
  59. data/lib/generators/social_engine/install/templates/social_engine_yetting.yml +89 -0
  60. data/lib/generators/social_engine/user_reputation/templates/add_reputation_to_users_table.rb +9 -0
  61. data/lib/generators/social_engine/user_reputation/user_reputation_generator.rb +22 -0
  62. data/lib/social_engine.rb +11 -0
  63. data/lib/social_engine/core_ext/array.rb +13 -0
  64. data/lib/social_engine/core_ext/hash.rb +26 -0
  65. data/lib/social_engine/engine.rb +44 -0
  66. data/lib/social_engine/railties/tasks.rake +0 -0
  67. data/social_engine.gemspec +126 -0
  68. metadata +211 -0
@@ -0,0 +1,32 @@
1
+ require 'digest/sha2'
2
+ module SocialEngineController
3
+
4
+ def add_fingerprint_and_user_id(obj,save=false)
5
+ obj[:ip_address]=request.remote_ip
6
+ obj[:session_hash]=request.session_options[:id]
7
+ obj[:browser_fingerprint]=browser_fingerprint
8
+ obj[:user_id] = current_user.id if current_user
9
+ obj.save if save
10
+ end
11
+
12
+ def add_able_rep(name,obj)
13
+ able = able_method_name(obj)
14
+ if obj and obj.send(able) and obj.send(able).respond_to?(:user)
15
+ Reputation.add(name, obj.send(able).user) rescue nil
16
+ end
17
+ end
18
+
19
+ def browser_fingerprint
20
+ Digest::SHA2.hexdigest(request.user_agent+request.accept+request.accept_charset+request.accept_encoding+request.accept_language) rescue nil
21
+ end
22
+
23
+ def set_polymorphic_vars(obj,able_method=nil)
24
+ able = able_method || able_method_name(obj)
25
+ obj.send("#{able}_type=", request.path.split("/")[1].classify)
26
+ obj.send("#{able}_id=", request.path.split("/")[2])
27
+ end
28
+
29
+ def able_method_name(obj)
30
+ "#{obj.class.to_s.underscore}able"
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ class VotesController < InheritedResources::Base
2
+ def create
3
+ @vote = Vote.new(params[:vote])
4
+ set_polymorphic_vars(@vote)
5
+ add_fingerprint_and_user_id(@vote)
6
+ create! do |success, failure|
7
+ success.html do
8
+ add_able_rep("upvote",@vote) if @vote.up?
9
+ add_able_rep("downvote",@vote) if @vote.down?
10
+ redirect_to :back
11
+ end
12
+ failure.html { redirect_to :back }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,82 @@
1
+ module SocialEngineHelper
2
+ def tweetme(options={})
3
+ defaults = {count: SocialEngineYetting.tweetme["count"], url: request.url, div_class: SocialEngineYetting.tweetme["div_class"]}
4
+ options.reverse_merge!(defaults)
5
+ render "third_party/tweetme", options: options
6
+ end
7
+
8
+ def fb_like(options={})
9
+ defaults = get_defaults(:fb_like)
10
+ options.reverse_merge!(defaults)
11
+ options.reverse_merge!(:url=>request.url)
12
+ render "third_party/fblike", options: options
13
+ end
14
+
15
+ def fb_friend_box(options={})
16
+ defaults = get_defaults(:fb_friend_box)
17
+ options.reverse_merge!(defaults)
18
+ render "third_party/fb_friend_box", options: options
19
+ end
20
+
21
+ def fb_og_tags(options={})
22
+ defaults = get_defaults(:fb_og_tags)
23
+ options.reverse_merge!(defaults)
24
+ render "third_party/fb_og_tags", options: options
25
+ end
26
+
27
+ def fb_javascript_sdk(options={})
28
+ defaults = get_defaults(:fb_javascript_sdk)
29
+ options.reverse_merge!(defaults)
30
+ render "third_party/fb_javascript_sdk", options: options
31
+ end
32
+
33
+ def comment_form(commentable,*options)
34
+ options = options.to_options_hash
35
+ defaults = get_defaults(:comment_form)
36
+ options.optional_reverse_merge!(defaults, [:comment])
37
+ render "comments/form", commentable: commentable, comment: Comment.new, options: options
38
+ end
39
+
40
+ def comments_list(commentable, options={})
41
+ defaults = get_defaults(:comment_list)
42
+ options.reverse_merge!(defaults)
43
+ comments = commentable.comments.order("id #{options[:order]}")
44
+ comments = comments.limit(options[:display_limit]) if options[:display_limit].is_a? Fixnum
45
+ render "comments/list", commentable: commentable, options: options, comments: comments
46
+ end
47
+
48
+ def favorites_widget(favoriteable,options={})
49
+ if current_user
50
+ defaults = get_defaults(:favorites_widget)
51
+ options.reverse_merge!(defaults)
52
+ favorite = Favorite.where(favoriteable_type:favoriteable.class.to_s, favoriteable_id: favoriteable.id, user_id: current_user.id).first rescue Favorite.new
53
+ render "favorites/widget", favoriteable: favoriteable, favorite: favorite, options: options
54
+ end
55
+ end
56
+
57
+ def vote_widget(voteable,options={})
58
+ defaults = get_defaults(:vote_widget)
59
+ options.reverse_merge!(defaults)
60
+ render "votes/widget", voteable: voteable, options: options
61
+ end
62
+
63
+ ##
64
+ def rating_form(rateable,options={})
65
+ defaults = get_defaults(:rating_form)
66
+ options.reverse_merge!(defaults)
67
+ render "ratings/form", rateable: rateable, rating: Rating.new, options: options
68
+ end
69
+
70
+ def get_defaults(key)
71
+ begin
72
+ SocialEngineYetting.send(key).symbolize_keys!
73
+ rescue
74
+ puts "WARNING: Defaults not found for #{key} in SocialEngineYettings. This key is missing from config/yettings/social_engine.yml"
75
+ return {}
76
+ end
77
+ end
78
+
79
+ def div_id(klass)
80
+ "se-#{klass.class.to_s.underscore.gsub('_','-')}#{klass.id}"
81
+ end
82
+ end
@@ -0,0 +1,10 @@
1
+ class Comment < ActiveRecord::Base
2
+ belongs_to :commentable, :polymorphic=>true
3
+ belongs_to :user
4
+ validates_presence_of :comment
5
+ is_voteable
6
+ is_commentable
7
+ is_rateable
8
+
9
+ include SocialEngine::Helpers::User
10
+ end
@@ -0,0 +1,4 @@
1
+ class Favorite < ActiveRecord::Base
2
+ belongs_to :favoriteable, :polymorphic=>true
3
+ belongs_to :user
4
+ end
@@ -0,0 +1,21 @@
1
+ class Friending < ActiveRecord::Base
2
+ belongs_to :friendee, :class_name=>'User'
3
+ belongs_to :friendor, :class_name=>'User'
4
+ validates_uniqueness_of :friendee_id, :scope=> :friendor_id
5
+ validate :not_friending_self
6
+
7
+ def confirm
8
+ self.update_attributes(:confirmed=>true)
9
+ end
10
+
11
+ def reject
12
+ self.update_attributes(:rejected=>true)
13
+ end
14
+
15
+ private
16
+ def not_friending_self
17
+ errors.add(:friendee_id, "can't be the same as friendor_id") if
18
+ friendee_id == friendor_id
19
+ end
20
+
21
+ end
@@ -0,0 +1,6 @@
1
+ class Rating < ActiveRecord::Base
2
+ belongs_to :rateable, :polymorphic=>true
3
+ belongs_to :user
4
+ validates_uniqueness_of :rateable_type, :scope=> SocialEngine::Helpers::Fingerprint.fingerprint_type(:rateable_id),
5
+ :if => Proc.new { |x| SocialEngineYetting.fingerprint_method != "none" }
6
+ end
@@ -0,0 +1,24 @@
1
+ class Reputation < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :reputation_action
4
+
5
+ def self.add(name,*users)
6
+ reputation_action = ReputationAction.where(:name=>name).first
7
+ if reputation_action.present? and users
8
+ users.each do |user|
9
+ if user.present?
10
+ self.create(:user_id=>user.id,:reputation_action_id=>reputation_action.id,:value=>reputation_action.value)
11
+ self.update_user_rep(user,reputation_action.value)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ def self.update_user_rep(user,value)
18
+ if SocialEngineYetting.reputation["update_user_model"]
19
+ rep_field = SocialEngineYetting.reputation["user_model_rep_field_name"].to_s.to_sym
20
+ new_rep_value = user.send(rep_field).to_i + value
21
+ user.update_attributes(rep_field=>new_rep_value)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ class ReputationAction < ActiveRecord::Base
2
+ has_many :reputations, :dependent=>:destroy
3
+
4
+ def self.list_from_rails_source
5
+ list = []
6
+ files = Dir.glob("{#{Rails.root.to_s},#{SocialEngine::Engine.root.to_s}}/app/{controllers,models}/**/*.rb")
7
+ files.each do |file|
8
+ source = IO.read(file)
9
+ source.scan(/(Reputation.add|add_able_rep)\(("|')(.*)("|'),.*\)/).each do |line|
10
+ list << line[2] if line[2].present?
11
+ end
12
+ end
13
+ list
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module SocialEngine
2
+ module Commentable
3
+ def is_commentable
4
+ has_many :comments, :as=>:commentable, :dependent => :destroy
5
+ include InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def commentable?
10
+ true
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module SocialEngine
2
+ module Favoriteable
3
+ def is_favoriteable
4
+ has_many :favorites, :as=>:favoriteable, :dependent => :destroy
5
+ include InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def favoriteable?
10
+ true
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,56 @@
1
+ module SocialEngine
2
+ module Friendable
3
+ def is_friendable
4
+
5
+ # Setup conditions
6
+ active = ["confirmed = ? AND rejected = ?", true, false]
7
+ pending = ["confirmed = ?", false]
8
+ requested = ["confirmed = ? AND rejected = ?", false, false]
9
+ rejected = ["rejected = ?", true]
10
+
11
+ # Active friendships
12
+ has_many :friendorings, :class_name=>'Friending',
13
+ :foreign_key=>:friendee_id, :conditions=>active
14
+ has_many :friendeeings, :class_name=>'Friending',
15
+ :foreign_key=>:friendor_id, :conditions=>active
16
+ # Pending friend requests from the user
17
+ has_many :pending_friendships, :class_name=>'Friending',
18
+ :foreign_key=>:friendor_id, :conditions=>pending
19
+ # Pending friend requests to the user
20
+ has_many :friend_requests, :class_name=>'Friending',
21
+ :foreign_key=>:friendee_id, :conditions=>requested
22
+ # Friend requests rejected by the user
23
+ has_many :friend_rejections, :class_name=>'Friending',
24
+ :foreign_key=>:friendee_id, :conditions=>rejected
25
+
26
+ # Friend relations (these return collections of Users)
27
+ has_many :friendors, :through=>:friendorings, :class_name=>'User'
28
+ has_many :friendees, :through=>:friendeeings, :class_name=>'User'
29
+ has_many :pending_friends, :through=>:pending_friendships,
30
+ :source=>:friendee, :class_name=>'User'
31
+ has_many :requesting_friends, :through=>:friend_requests,
32
+ :source=>:friendor, :class_name=>'User'
33
+ has_many :rejected_friends, :through=>:friend_rejections,
34
+ :source=>:friendor, :class_name=>'User'
35
+
36
+ include InstanceMethods
37
+ end
38
+
39
+ module InstanceMethods
40
+ def friendable?
41
+ true
42
+ end
43
+
44
+ def friends(expire_association_cache=false)
45
+ return self.friendors(true) + self.friendees(true) if expire_association_cache
46
+ self.friendors + self.friendees
47
+ end
48
+
49
+ def add_friend(user)
50
+ Friending.create(:friendor_id=>self.id, :friendee_id=>user.id,
51
+ :confirmed=>!SocialEngineYetting.confirm_friends)
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,37 @@
1
+ module SocialEngine
2
+ module Helpers
3
+ module User
4
+ def name
5
+ self.user ? self.user.name : self.unauthenticated_name
6
+ end
7
+
8
+ def email
9
+ self.user ? self.user.email : self.unauthenticated_email
10
+ end
11
+
12
+ def website
13
+ self.user ? self.user.website : self.unauthenticated_website
14
+ end
15
+ end
16
+
17
+ module Fingerprint
18
+ def self.fingerprint_type(able)
19
+ ftype = [able]
20
+ fingerprint = SocialEngineYetting.fingerprint_method rescue nil
21
+ case fingerprint
22
+ when "ip_address"
23
+ ftype << :ip_address
24
+ when "session_hash"
25
+ ftype << :session_hash
26
+ when "browser"
27
+ ftype << :browser_fingerprint
28
+ when "ip_browser"
29
+ ftype.concat [:ip_browser,:browser_fingerprint]
30
+ when "none"
31
+ ftype = [:none]
32
+ end
33
+ ftype
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ module SocialEngine
2
+ module Rateable
3
+ def is_rateable
4
+ has_many :ratings, :as=>:rateable, :dependent=>:destroy
5
+ include InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def rateable?
10
+ true
11
+ end
12
+
13
+ def avg_rating
14
+ avg = self.ratings.sum(:value).to_f/self.rating_count.to_f rescue 0
15
+ avg = 0 if avg.nan?
16
+ avg
17
+ end
18
+
19
+ def avg_rating_formatted(decimal_places=1)
20
+ return self.avg_rating.to_i.to_s if decimal_places==0
21
+ sprintf("%.#{decimal_places}f", self.avg_rating)
22
+ end
23
+
24
+ def rating_count
25
+ self.ratings.size
26
+ end
27
+
28
+ def avg_rating_round_half
29
+ (avg_rating*2).round / 2.0
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,14 @@
1
+ module SocialEngine
2
+ module Reputatable
3
+ def has_reputation
4
+ has_many :reputations
5
+ include InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def has_reputation?
10
+ true
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module SocialEngine
2
+ module Sociable
3
+ def is_sociable
4
+ is_rateable
5
+ is_voteable
6
+ is_commentable
7
+ is_favoriteable
8
+ include InstanceMethods
9
+ end
10
+
11
+ module InstanceMethods
12
+ def sociable?
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module SocialEngine
2
+ module SocialUser
3
+ def is_social
4
+ has_many :comments
5
+ has_many :votes
6
+ has_many :ratings
7
+ has_many :favorites
8
+ include InstanceMethods
9
+ end
10
+ module InstanceMethods
11
+ def is_social?
12
+ true
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ module SocialEngine
2
+ module Voteable
3
+ def is_voteable
4
+ has_many :votes, :as=>:voteable, :dependent=>:destroy
5
+ include InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def voteable?
10
+ true
11
+ end
12
+
13
+ def upvote(options={})
14
+ options.reverse_merge!(:value=>1)
15
+ self.votes.create(options)
16
+ end
17
+
18
+ def downvote(options={})
19
+ options.reverse_merge!(:value=>-1)
20
+ self.votes.create(options)
21
+ end
22
+
23
+ def vote_sum
24
+ self.votes.inject(0){|sum,vote| sum = sum + vote.value}
25
+ end
26
+ end
27
+ end
28
+ end