nathanborror (owner)

Forks

Revisions

gist: 206585 Download_button fork
public
Public Clone URL: git://gist.github.com/206585.git
Embed All Files: show embed
Python #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.core.cache import cache
 
 
RELATIONSHIP_CACHE = 60*60*24*7
RELATIONSHIP_CACHE_KEYS = {
    'FRIENDS': 'friends',
    'FOLLOWERS': 'followers',
    'BLOCKERS': 'blockers',
    'FANS': 'fans'
}
 
 
class RelationshipManager(models.Manager):
    def relationships_for_user(self, user):
        """
Relationships for user
 
Returns a list of friends, people you are following, and followers,
people that are following you but you are not following.
"""
        relationships = {
            'friends': self.get_friends_for_user(user),
            'followers': self.get_followers_for_user(user),
            'fans': self.get_fans_for_user(user)
        }
        return relationships
 
    def _set_cache(self, user, user_list, relationship, flat=False):
        cache_key = 'user_%s_%s' % (user.pk, relationship)
        if flat:
            cache_key = '%s_flat' % cache_key
            user_list = user_list.values_list('to_user', flat=True)
        if not cache.get(cache_key):
            cache.set(cache_key, user_list, RELATIONSHIP_CACHE)
        return cache.get(cache_key)
 
    def get_blockers_for_user(self, user, flat=False):
        """Returns list of people blocking user."""
        user_list = self.filter(to_user=user, is_blocked=True)
        return self._set_cache(user, user_list, RELATIONSHIP_CACHE_KEYS['BLOCKERS'], flat)
 
    def get_friends_for_user(self, user, flat=False):
        """Returns people user is following sans people blocking user."""
        blocked_id_list = self.get_blockers_for_user(user).values_list('from_user', flat=True)
        user_list = self.filter(from_user=user, is_blocked=False).exclude(to_user__in=blocked_id_list)
        return self._set_cache(user, user_list, RELATIONSHIP_CACHE_KEYS['FRIENDS'])
 
    def get_followers_for_user(self, user, flat=False):
        """Returns people following user."""
        user_list = self.filter(to_user=user, is_blocked=False)
        return self._set_cache(user, user_list, RELATIONSHIP_CACHE_KEYS['FOLLOWERS'])
 
    def get_fans_for_user(self, user, flat=False):
        """Returns people following user but user isn't following."""
        friend_id_list = self.get_friends_for_user(user).values_list('to_user', flat=True)
        user_list = self.get_followers_for_user(user).exclude(from_user__in=friend_id_list)
        return self._set_cache(user, user_list, RELATIONSHIP_CACHE_KEYS['FANS'])
 
    def is_following(self, you, them):
        """Answers the question, am I following you?"""
        if self.filter(from_user=you, to_user=them, is_blocked=False).count() > 0:
            return True
        return False
 
    def is_follower(self, you, them):
        """Answers the question, are you following me?"""
        if self.filter(from_user=them, to_user=you, is_blocked=False).count() > 0:
            return True
        return False
 
    def is_blocked(self, you, them):
        """Answers the question, am I blocking you?"""
        if self.filter(from_user=you, to_user=them, is_blocked=True).count() > 0:
            return True
        return False
 
 
class Relationship(models.Model):
    """Relationship model"""
    from_user = models.ForeignKey(User, related_name='from_users')
    to_user = models.ForeignKey(User, related_name='to_users')
    created = models.DateTimeField(auto_now_add=True)
    is_blocked = models.BooleanField(default=False)
    objects = RelationshipManager()
 
    class Meta:
        unique_together = (('from_user', 'to_user'),)
        verbose_name = _('relationship')
        verbose_name_plural = _('relationships')
        db_table = 'relationships'
 
    def __unicode__(self):
        if self.is_blocked:
            return u'%s is blocking %s' % (self.from_user, self.to_user)
        return u'%s is connected to %s' % (self.from_user, self.to_user)
 
    def save(self, force_insert=False, force_update=False):
        for key in RELATIONSHIP_CACHE_KEYS:
            cache.delete('user_%s_%s' % (self.from_user.pk, RELATIONSHIP_CACHE_KEYS[key]))
            cache.delete('user_%s_%s_flat' % (self.from_user.pk, RELATIONSHIP_CACHE_KEYS[key]))
        super(Relationship, self).save(force_insert=force_insert, force_update=force_update)