aitor-tog_social 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.
@@ -0,0 +1,112 @@
1
+ # Friendship objects represents the relation between two different members of the social network. The cardinality of the relationship is based on "inviter" and "invited" fields
2
+ # that store who started the relationship and who is the _passive_ subject of the relationship.
3
+ #
4
+ # If you have two profiles, tom and jerry, the following combinations can take place:
5
+ #
6
+ # inviter invited status
7
+ # ------- ------- -------
8
+ # tom jerry pending tom is a follower of jerry OR jerry is followed by tom OR jerry is a 'following' of tom
9
+ # jerry tom pending jerry is a follower of tom OR tom is followed by jerry OR tom is a 'following' of jerry
10
+ #
11
+ # jerry tom accept | | jerry "begun" the friendship
12
+ # or | jerry and tom are friends |
13
+ # jerry tom accept | | tom "begun" the friendship
14
+ class Friendship < ActiveRecord::Base
15
+ belongs_to :inviter, :class_name => 'Profile'
16
+ belongs_to :invited, :class_name => 'Profile'
17
+
18
+ PENDING = 0
19
+ ACCEPTED = 1
20
+
21
+ def validate
22
+ errors.add('inviter', 'inviter and invited can not be the same user') if invited == inviter
23
+ end
24
+ class << self
25
+
26
+ # Create a new follower of the +inviter+ user. Returns boolean value indicating if the relationship
27
+ # correctly created.
28
+ #
29
+ # ==== Options
30
+ #
31
+ # +inviter+ +Profile+ if the person that wants to be a follower if +invited+
32
+ #
33
+ # +invited+ +Profile+ of the user followed by +inviter+
34
+ #
35
+ def add_follower(inviter, invited)
36
+ a = Friendship.create(:inviter => inviter, :invited => invited, :status => PENDING)
37
+ !a.new_record?
38
+ end
39
+
40
+ # Create a friendship between the user and the target. Returns boolean value indicating if
41
+ # the relationship was correctly created.
42
+ #
43
+ # ==== Options
44
+ #
45
+ # +user+ +Profile+ or +User+ that purpose the friendship
46
+ #
47
+ # +target+ +Profile+ or +User+ that receives the purposement relationship
48
+ #
49
+ def make_friends(user, target)
50
+ transaction do
51
+ user = profile_of(user)
52
+ target = profile_of(target)
53
+ begin
54
+ find_friendship(user, target, PENDING).update_attribute(:status, ACCEPTED)
55
+ Friendship.create!(:inviter_id => target.id, :invited_id => user.id, :status => ACCEPTED)
56
+ rescue Exception
57
+ return make_friends(target, user) if user.followed_by? target
58
+ return add_follower(user, target)
59
+ end
60
+ end
61
+ true
62
+ end
63
+
64
+ def stop_being_friends(user, target)
65
+ transaction do
66
+ begin
67
+ find_friendship(target, user, ACCEPTED).update_attribute(:status, PENDING)
68
+ find_friendship(user, target, ACCEPTED).destroy
69
+ rescue Exception
70
+ return false
71
+ end
72
+ end
73
+ true
74
+ end
75
+
76
+ def reset(user, target)
77
+ begin
78
+ find_friendship(user, target).destroy
79
+ find_friendship(target, user, ACCEPTED).update_attribute(:status, PENDING)
80
+ rescue Exception
81
+ return true
82
+ end
83
+ true
84
+ end
85
+
86
+ private
87
+
88
+ def find_friendship(inviter, invited, status)
89
+ conditions = {:inviter_id => inviter.id, :invited_id => invited.id}
90
+ conditions.merge!(:status => status) if status
91
+ Friendship.find(:first, :conditions => conditions)
92
+ end
93
+
94
+ end
95
+
96
+ def accept!
97
+ self.update_attribute(:status, ACCEPTED)
98
+ end
99
+
100
+ private
101
+ def profile_of(user)
102
+ profile = case user
103
+ when User
104
+ user.profile
105
+ when Profile
106
+ user
107
+ else
108
+ nil
109
+ end
110
+ end
111
+
112
+ end
@@ -0,0 +1,97 @@
1
+ class Group < ActiveRecord::Base
2
+
3
+ belongs_to :author, :class_name => 'User', :foreign_key => 'user_id'
4
+
5
+ has_many :memberships
6
+
7
+ has_many :moderator_memberships, :class_name => 'Membership',
8
+ :conditions => ['memberships.moderator = ?', true]
9
+
10
+ has_many :members, :through => :memberships, :source => :user,
11
+ :conditions => ['memberships.state = ?', 'active']
12
+
13
+ has_many :pending_members, :through => :memberships, :source => :user,
14
+ :conditions => ['memberships.state = ?', 'pending']
15
+
16
+ has_many :moderators, :through => :moderator_memberships, :source => :user,
17
+ :conditions => ['memberships.state = ?', 'active']
18
+
19
+
20
+ #file_column :image, :root_path => File.join(RAILS_ROOT, "public/system/group_photos"), :web_root => 'system/group_photos/', :magick => {
21
+ # :versions => {
22
+ # :big => {:crop => "1:1", :size => Tog::Config["system.group.image.versions.big"], :name => "big"},
23
+ # :medium => {:crop => "1:1", :size => Tog::Config["system.group.image.versions.medium"], :name => "medium"},
24
+ # :small => {:crop => "1:1", :size => Tog::Config["system.group.image.versions.small"], :name => "small" },
25
+ # :tiny => {:crop => "1:1", :size => Tog::Config["system.group.image.versions.tiny"], :name => "tiny" }
26
+ # }
27
+ #}
28
+
29
+ acts_as_state_machine :initial => :pending
30
+ state :pending, :enter => :make_activation_code
31
+ state :active, :enter => :do_activate
32
+ event :activate do
33
+ transitions :from => :pending, :to => :active
34
+ end
35
+
36
+ validates_uniqueness_of :name
37
+ validates_presence_of :name
38
+ validates_presence_of :author
39
+
40
+ def membership_of(user)
41
+ mem = memberships.select{|m| m.user == user}
42
+ return mem.first unless mem.blank?
43
+ end
44
+
45
+ def activate_membership(user)
46
+ mem = membership_of(user)
47
+ mem.activate! if mem && mem.pending?
48
+ end
49
+
50
+ def grant_moderator(user)
51
+ moderator_privileges(user,true)
52
+ end
53
+
54
+ def revoke_moderator(user)
55
+ moderator_privileges(user,false)
56
+ end
57
+
58
+ def moderator_privileges(user, grant=false)
59
+ mem = membership_of(user)
60
+ mem.moderator = grant
61
+ mem.save!
62
+ end
63
+
64
+ def join(user,moderator=false)
65
+ # todo Confirm what to do if th user is already a member. By now just ignore it and continue.
66
+ mem = membership_of(user)
67
+ mem = self.memberships.build(:user => user) unless mem
68
+ mem.save!
69
+ mem.activate! unless self.moderated?
70
+ end
71
+
72
+ def leave(user)
73
+ mem = membership_of(user)
74
+ mem.destroy if mem
75
+ end
76
+
77
+ def is_banned(user)
78
+ raise "Implement this..."
79
+ end
80
+
81
+ def ban(user)
82
+ raise "Implement this..."
83
+ end
84
+
85
+
86
+ protected
87
+ def make_activation_code
88
+ self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
89
+ end
90
+
91
+ def do_activate
92
+ self.activated_at = Time.now.utc
93
+ self.activation_code = nil
94
+ self.moderator_memberships.each{|mod| mod.activate!}
95
+ end
96
+
97
+ end
@@ -0,0 +1,25 @@
1
+ class Membership < ActiveRecord::Base
2
+ belongs_to :group
3
+ belongs_to :user
4
+
5
+ acts_as_state_machine :initial => :pending
6
+
7
+ state :pending, :enter => :make_activation_code
8
+ state :active, :enter => :do_activate
9
+
10
+ event :activate do
11
+ transitions :from => :pending, :to => :active
12
+ end
13
+
14
+ protected
15
+
16
+ def make_activation_code
17
+ self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
18
+ end
19
+
20
+ def do_activate
21
+ self.activated_at = Time.now.utc
22
+ self.activation_code = nil
23
+ end
24
+
25
+ end
@@ -0,0 +1,117 @@
1
+ class Profile < ActiveRecord::Base
2
+ belongs_to :user
3
+
4
+ #file_column :icon, :root_path => File.join(RAILS_ROOT, "public/system/profile"), :web_root => 'system/profile/', :magick => {
5
+ # :versions => {
6
+ # :big => {:crop => "1:1", :size => Tog::Config["system.profile.image.versions.big"], :name => "big"},
7
+ # :medium => {:crop => "1:1", :size => Tog::Config["system.profile.image.versions.medium"], :name => "medium"},
8
+ # :small => {:crop => "1:1", :size => Tog::Config["system.profile.image.versions.small"], :name => "small"},
9
+ # :tiny => {:crop => "1:1", :size => Tog::Config["system.profile.image.versions.tiny"], :name => "tiny"}
10
+ # }
11
+ #}
12
+
13
+ has_many :friendships_by_others, :class_name => "Friendship", :foreign_key => 'invited_id', :conditions => "status = #{Friendship::ACCEPTED}"
14
+ has_many :friendships_by_me, :class_name => "Friendship", :foreign_key => 'inviter_id', :conditions => "status = #{Friendship::ACCEPTED}"
15
+
16
+ has_many :follower_friendships, :class_name => "Friendship", :foreign_key => "invited_id", :conditions => "status = #{Friendship::PENDING}"
17
+ has_many :following_friendships, :class_name => "Friendship", :foreign_key => "inviter_id", :conditions => "status = #{Friendship::PENDING}"
18
+
19
+ has_many :friends_by_others, :through => :friendships_by_others, :source => :inviter
20
+ has_many :friends_by_me, :through => :friendships_by_me, :source => :invited
21
+
22
+ has_many :followers, :through => :follower_friendships, :source => :inviter
23
+ has_many :followings, :through => :following_friendships, :source => :invited
24
+
25
+ before_create :set_default_icon
26
+
27
+
28
+ def friends
29
+ # Reload associations just to make sure we're working with the current staff. Bad smell!
30
+ # todo check this... if we don't should reload the relationship to get the test working...
31
+ (friends_by_others(true) + friends_by_me(true)).uniq
32
+ end
33
+ def friendships
34
+ (friendships_by_others(true) + friendships_by_me(true)).uniq
35
+ end
36
+
37
+ def full_name
38
+ #todo apply for internationalization
39
+ first_name.blank? && last_name.blank? ? self.user.login : "#{first_name} #{last_name}".strip
40
+ end
41
+
42
+ def followed_by? profile
43
+ followers(true).include? profile
44
+ end
45
+
46
+ def follows? profile
47
+ followings(true).include? profile
48
+ end
49
+ def is_friend_of? profile
50
+ friends.include? profile
51
+ end
52
+ def is_related_to? profile
53
+ me.followed_by?(profile) || me.follows?(profile) || me.is_friend_of?(profile)
54
+ end
55
+
56
+ def add_follower(follower)
57
+ if follower.follows? me
58
+ return false
59
+ elsif me.follows? follower
60
+ return add_friend(follower)
61
+ else
62
+ flw = Friendship.create(:inviter => follower, :invited => me, :status => Friendship::PENDING)
63
+ unless flw.new_record?
64
+ # todo enable send_friendships_notifications? setting per profile
65
+ # FriendshipMailer.deliver_new_follower(me, follower) if me.send_friendships_notifications?
66
+ FriendshipMailer.deliver_new_follower(me, follower)
67
+ return true
68
+ end
69
+ return false
70
+ end
71
+ end
72
+
73
+ def add_following(following)
74
+ following.add_follower(me)
75
+ end
76
+
77
+ def add_friend(friend)
78
+ relationship = if friend.follows? me
79
+ find_friendship(friend, me, Friendship::PENDING)
80
+ elsif friend.followed_by? me
81
+ find_friendship(me, friend, Friendship::PENDING)
82
+ else
83
+ Friendship.create(:inviter => friend, :invited => me, :status => Friendship::PENDING)
84
+ end
85
+ relationship.accept!
86
+ # todo enable send_friendships_notifications? setting per profile
87
+ # FriendshipMailer.deliver_frienship_validated(relationship.inviter, relationship.invited) if relationship.inviter.send_friendships_notifications?
88
+ FriendshipMailer.deliver_friendship_validated(relationship.inviter, relationship.invited)
89
+ return true
90
+ end
91
+ def remove_friend(friend)
92
+ relationships = me.friendships.select{|f| f.inviter == friend || f.invited == friend }
93
+ relationships.each{|r| r.destroy}
94
+ end
95
+
96
+
97
+ private
98
+ # Freud will be happy.
99
+ def me
100
+ self
101
+ end
102
+
103
+ def find_friendship(inviter, invited, status)
104
+ conditions = {:inviter_id => inviter.id, :invited_id => invited.id}
105
+ conditions.merge!(:status => status) if status
106
+ Friendship.find(:first, :conditions => conditions)
107
+ end
108
+ def set_default_icon
109
+ unless self.icon
110
+ if Tog::Config["system.profile.image.default"]
111
+ default_profile_icon = File.join(RAILS_ROOT, 'public', 'images', Tog::Config["system.profile.image.default"])
112
+ self.icon = File.new(default_profile_icon)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
@@ -0,0 +1,18 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ has_one :profile, :dependent => :destroy
4
+ has_many :memberships
5
+ has_many :moderator_memberships, :class_name => 'Membership',
6
+ :conditions => ['memberships.moderator = ?', true]
7
+
8
+ has_many :groups, :through => :memberships,
9
+ :conditions => "memberships.state='active' and groups.state='active'"
10
+
11
+ has_many :moderated_groups, :through => :moderator_memberships,
12
+ :conditions => "memberships.state='active' and groups.state='active'", :source => :group
13
+
14
+ def name
15
+ profile.full_name
16
+ end
17
+
18
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ # Add your custom routes here. If in config/routes.rb you would
2
+ # add <tt>map.resources</tt>, here you would add just <tt>resources</tt>
3
+
4
+ # resources :tog_socials
@@ -0,0 +1,54 @@
1
+ class CreateTogSocialTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :profiles do |t|
4
+ t.integer :user_id
5
+ t.string :first_name
6
+ t.string :last_name
7
+ t.string :website
8
+ t.string :blog
9
+ t.string :icon
10
+ t.timestamps
11
+ end
12
+ User.find(:all).each{|u|
13
+ profile = Profile.new
14
+ profile.user = u
15
+ profile.save!
16
+ }
17
+
18
+ create_table :groups do |t|
19
+ t.string :name
20
+ t.string :description
21
+ t.string :image
22
+ t.string :state
23
+ t.boolean :private
24
+ t.boolean :moderated, :default => true
25
+ t.integer :user_id
26
+ t.string :activation_code, :limit => 40
27
+ t.datetime :activated_at
28
+ t.timestamps
29
+ end
30
+
31
+ create_table :memberships do |t|
32
+ t.integer :user_id
33
+ t.integer :group_id
34
+ t.boolean :moderator
35
+ t.string :state
36
+ t.string :activation_code, :limit => 40
37
+ t.datetime :activated_at
38
+ t.timestamps
39
+ end
40
+ create_table :friendships do |t|
41
+ t.integer :inviter_id
42
+ t.integer :invited_id
43
+ t.integer :status
44
+ t.timestamps
45
+ end
46
+ end
47
+
48
+ def self.down
49
+ drop_table :friendships
50
+ drop_table :memberships
51
+ drop_table :groups
52
+ drop_table :profiles
53
+ end
54
+ end
data/test/factories.rb ADDED
@@ -0,0 +1,16 @@
1
+ Factory.define :user do |u|
2
+ u.salt '7e3041ebc2fc05a40c60028e2c4901a81035d3cd'
3
+ u.crypted_password '00742970dc9e6319f8019fd54864d3ea740f04b1'
4
+ u.activation_code '8f24789ae988411ccf33ab0c30fe9106fab32e9a'
5
+ u.state 'pending'
6
+ u.email {|a| "#{a.login}@example.com".downcase }
7
+ end
8
+
9
+ Factory.define :profile do |u|
10
+ end
11
+
12
+
13
+ Factory.define :group do |g|
14
+ g.state 'active'
15
+ #g.author{|author| author.association :user, :login => 'chavez'}
16
+ end
@@ -0,0 +1,24 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
3
+ require 'test_help'
4
+ require 'test/unit'
5
+
6
+ require 'factory_girl'
7
+ require File.expand_path(File.dirname(__FILE__) + '/factories')
8
+
9
+ class Test::Unit::TestCase
10
+ self.use_transactional_fixtures = true
11
+ self.use_instantiated_fixtures = false
12
+ fixtures :all
13
+
14
+ def assert_difference(object, method = nil, difference = 1)
15
+ initial_value = object.send(method)
16
+ yield
17
+ assert_equal initial_value + difference, object.send(method), "#{object}##{method} should have a difference of #{difference}"
18
+ end
19
+
20
+ def assert_no_difference(object, method, &block)
21
+ assert_difference object, method, 0, &block
22
+ end
23
+
24
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class GroupTest < Test::Unit::TestCase
4
+ context "A Group" do
5
+
6
+ setup do
7
+ @berlusconi = Factory(:user, :login => 'berlusconi')
8
+ @chavez = Factory(:user, :login => 'chavez')
9
+ @pornfans = Factory(:group, :name => 'Porn without frontiers', :moderated => false, :author => @chavez)
10
+ end
11
+
12
+ should "should allow to join directly" do
13
+ @pornfans.join(@berlusconi)
14
+ assert @pornfans.members.include?(@berlusconi), "The joined user should be on the members list"
15
+ end
16
+
17
+ should "allow give moderator rights" do
18
+ @pornfans.join(@berlusconi)
19
+ assert_no_difference(Membership, :count) do
20
+ @pornfans.grant_moderator(@berlusconi)
21
+ end
22
+ assert_contains @pornfans.moderators, @berlusconi
23
+ end
24
+
25
+ should "allow revoke moderator rights" do
26
+ @pornfans.join(@berlusconi)
27
+ assert_no_difference(Membership, :count) do
28
+ @pornfans.revoke_moderator(@berlusconi)
29
+ end
30
+ assert_does_not_contain @pornfans.moderators, @berlusconi
31
+ end
32
+
33
+ context "that is moderated" do
34
+ setup do
35
+ @selectedporn = Factory(:group, :name => 'Porn for V.I.P', :moderated => true, :author => @chavez)
36
+ end
37
+
38
+ should "not allow to join directly" do
39
+ assert_difference(Membership, :count) do
40
+ @selectedporn.join(@berlusconi)
41
+ end
42
+ assert !@selectedporn.members.include?(@berlusconi)
43
+ @selectedporn.activate_membership(@berlusconi)
44
+ assert @selectedporn.members(true).include?(@berlusconi)
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ProfileTest < Test::Unit::TestCase
4
+ context "A Profile " do
5
+ setup do
6
+ @user = Factory(:user, :login => 'chavez')
7
+ @user2 = Factory(:user, :login => 'evo')
8
+
9
+ @chavez = Factory(:profile, :first_name => 'Hugo', :last_name => 'Chavez', :user => @user)
10
+ @evo = Factory(:profile, :first_name => 'Evo', :last_name => 'Morales', :user => @user2)
11
+ end
12
+
13
+ should "returna full_name correctly base on first_name and last_name" do
14
+ assert_equal "Hugo Chavez", @chavez.full_name, "Full name should Hugo Chavez"
15
+ end
16
+
17
+ should "return last_name as full_name if first_name is blank" do
18
+ [nil, ""].each {|value|
19
+ @chavez.first_name = value
20
+ assert_equal "Chavez", @chavez.full_name, "Full name should Chavez if first name is blank"
21
+ }
22
+ end
23
+ should "return login as full_name if first name and last name are blank" do
24
+ [nil, ""].each {|value|
25
+ @chavez.first_name = @chavez.last_name = value
26
+ assert_equal "chavez", @chavez.full_name, "full_name should defaults to login if first name and last name are blank"
27
+ }
28
+ end
29
+
30
+ should "allow to add a follower" do
31
+ @chavez.add_follower(@evo)
32
+ assert @evo.follows?(@chavez), "Evo should follow Chavez"
33
+ assert @chavez.followed_by?(@evo), "Chavez should be followed by Evo"
34
+ end
35
+
36
+
37
+ def test_add_following
38
+ @evo.add_following(@chavez)
39
+ assert @evo.follows?(@chavez), "Evo should follow Chavez"
40
+ assert @chavez.followed_by?(@evo), "Chavez should be followed by Evo"
41
+ end
42
+
43
+ def test_add_follower_twice_has_no_effect
44
+ assert_difference(Friendship, :count) do
45
+ @chavez.add_follower(@evo)
46
+ end
47
+ assert_no_difference(Friendship, :count) do
48
+ @chavez.add_follower(@evo)
49
+ end
50
+ end
51
+
52
+
53
+ def test_add_follower_from_a_person_im_following_should_convert_the_relationship_on_a_friendship
54
+ @chavez.add_follower(@evo)
55
+ @evo.add_follower(@chavez)
56
+ assert @evo.is_friend_of?(@chavez)
57
+ assert @chavez.is_friend_of?(@evo)
58
+ end
59
+
60
+ def test_add_friend
61
+ assert !@evo.is_related_to?(@chavez)
62
+ assert @evo.add_friend(@chavez)
63
+ assert @evo.is_friend_of?(@chavez), "Evo and Chavez should be friends"
64
+ assert @chavez.is_friend_of?(@evo), "Chavez and Evo should be friends"
65
+ end
66
+
67
+ def test_remove_friend
68
+ assert @evo.add_friend(@chavez)
69
+ assert @evo.is_friend_of?(@chavez), "Evo and Chavez should be friends"
70
+ @evo.remove_friend(@chavez)
71
+ assert !@evo.is_friend_of?(@chavez)
72
+ assert !@evo.is_related_to?(@chavez)
73
+ end
74
+
75
+
76
+
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aitor-tog_social
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Aitor Garcia
8
+ - Roberto Salicio
9
+ - Alberto Molpeceres
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2008-04-24 00:00:00 -07:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: mime-types
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ description: Tog social
27
+ email: aitor@linkingpaths
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - app/helpers
36
+ - app/models/friendship.rb
37
+ - app/models/group.rb
38
+ - app/models/membership.rb
39
+ - app/models/profile.rb
40
+ - app/models/user.rb
41
+ - app/views
42
+ - config/routes.rb
43
+ - db/migrate/001_create_tog_social_tables.rb
44
+ - tasks
45
+ - test/factories.rb
46
+ - test/test_helper.rb
47
+ - test/unit/group_test.rb
48
+ - test/unit/profile_test.rb
49
+ has_rdoc: true
50
+ homepage: http://github.com/aitor/tog_social
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --main
54
+ - README.txt
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.2.0
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: tog_social
76
+ test_files: []
77
+