def _get_keys(self, action): identifier = registry.get_identifier(self.instance) prefix = self.storage.add_prefix('uid') uid = manager.make_uid(self.instance) keys = [ get_key(prefix, uid, 'private'), get_key(prefix, uid, 'private', 'target', identifier) ] if action.actor == self.instance: keys.append(get_key(prefix, uid, 'public')) keys.append(get_key(prefix, uid, 'public', 'target', identifier)) if action.target is not None and action.target != action.actor: identifier = registry.get_identifier(action.target) keys.append(get_key(prefix, uid, 'private', 'target', identifier)) if action.actor == self.instance: keys.append( get_key(prefix, uid, 'public', 'target', identifier)) return keys
def _get_keys(self, action): identifier = registry.get_identifier(self.instance) prefix = self.storage.add_prefix('uid') uid = manager.make_uid(self.instance) keys = [ get_key(prefix, uid, 'private'), get_key(prefix, uid, 'private', 'target', identifier) ] if action.actor == self.instance: keys.append(get_key(prefix, uid, 'public')) keys.append(get_key(prefix, uid, 'public', 'target', identifier)) if action.target is not None and action.target != action.actor: identifier = registry.get_identifier(action.target) keys.append(get_key(prefix, uid, 'private', 'target', identifier)) if action.actor == self.instance: keys.append(get_key(prefix, uid, 'public', 'target', identifier)) return keys
def test_follow(self): from ..models import follow, get_followings_count, get_followers_count follow(self.user, self.project) self.assertEqual(get_followings_count(self.user), 1) self.assertEqual(get_followings_count(self.user, registry.get_identifier(self.project)), 1) self.assertEqual(get_followers_count(self.project), 1) self.assertEqual(get_followers_count(self.project, registry.get_identifier(self.user)), 1)
def unfollow(self, from_instance, to_instance, fail_silently=FAIL_SILENTLY, dispatch=True): if not self.is_following(from_instance, to_instance): if fail_silently is False: raise NotFollowingException('%s is not following %s' % (from_instance, to_instance)) return logger.error('%s is not following %s' % (from_instance, to_instance)) from_uid = manager.make_uid(from_instance) to_uid = manager.make_uid(to_instance) from_identifier = registry.get_identifier(from_instance) to_identifier = registry.get_identifier(to_instance) prefix = manager.add_prefix('uid') with client.pipeline() as pipe: pipe.decr(get_key(prefix, from_uid, 'followings', 'count')) pipe.decr(get_key(prefix, to_uid, 'followers', 'count')) pipe.decr(get_key(prefix, from_uid, 'followings', to_identifier, 'count')) pipe.decr(get_key(prefix, to_uid, 'followers', from_identifier, 'count')) if self.is_following(to_instance, from_instance): pipe.decr(get_key(prefix, to_uid, 'friends', 'count')) pipe.decr(get_key(prefix, to_uid, 'friends', from_identifier, 'count')) pipe.zrem(get_key(prefix, to_uid, 'friends'), '%s' % from_uid) pipe.zrem(get_key(prefix, to_uid, 'friends', from_identifier), '%s' % from_uid) pipe.decr(get_key(prefix, from_uid, 'friends', 'count')) pipe.decr(get_key(prefix, from_uid, 'friends', to_identifier, 'count')) pipe.zrem(get_key(prefix, from_uid, 'friends'), '%s' % to_uid) pipe.zrem(get_key(prefix, from_uid, 'friends', to_identifier), '%s' % to_uid) pipe.zrem(get_key(prefix, to_uid, 'followers'), '%s' % from_uid) pipe.zrem(get_key(prefix, to_uid, 'followers', from_identifier), '%s' % from_uid) pipe.zrem(get_key(prefix, from_uid, 'followings'), '%s' % to_uid) pipe.zrem(get_key(prefix, from_uid, 'followings', to_identifier), '%s' % to_uid) pipe.execute() if dispatch: signals.unfollowed.send(sender=from_instance.__class__, from_instance=from_instance, to_instance=to_instance)
def _make_key(self, name, action=None, target=None): segments = [ self.storage.add_prefix('uid'), manager.make_uid(self.instance), name, ] if target: if isinstance(target, six.string_types): segments += ['target', target] else: if isinstance(target, models.Model) or issubclass( target, models.Model): segments += ['target', registry.get_identifier(target)] if action: if isinstance(action, six.string_types): segments += ['verb', action] elif issubclass(action, Action): segments += ['verb', action.verb] key = get_key(*segments) return key
def test_follow_view(self): user = self.user self.client.login(username=user.username, password='******') response = self.client.post(reverse('sequere_follow')) self.assertEqual(response.status_code, 400) response = self.client.post(reverse('sequere_follow'), data={ 'identifier': 'not-an-identifier', 'object_id': 1 }) self.assertEqual(response.status_code, 400) project = self.project identifier = registry.get_identifier(project) response = self.client.post(reverse('sequere_follow'), data={ 'identifier': identifier, 'object_id': project.pk }) self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['followings_count'], 1) self.assertEqual(content['%s_followings_count' % identifier], 1)
def test_unfollow_view(self): from ..models import follow user = self.user self.client.login(username=user.username, password='******') response = self.client.post(reverse('sequere_follow')) project = self.project follow(self.user, project) identifier = registry.get_identifier(project) response = self.client.post(reverse('sequere_unfollow'), data={ 'identifier': identifier, 'object_id': project.pk }) self.assertEqual(response.status_code, 200) content = json.loads(response.content.decode()) self.assertEqual(content['followings_count'], 0) self.assertEqual(content['%s_followings_count' % identifier], 0)
def test_follow(self): from ..models import follow, get_followings_count, get_followers_count follow(self.user, self.project) self.assertEqual(get_followings_count(self.user), 1) self.assertEqual( get_followings_count(self.user, registry.get_identifier(self.project)), 1) self.assertEqual(get_followers_count(self.project), 1) self.assertEqual( get_followers_count(self.project, registry.get_identifier(self.user)), 1)
def _params(self, from_instance=None, to_instance=None): params = {} if from_instance: from_identifier = registry.get_identifier(from_instance) params.update({ 'from_identifier': from_identifier, 'from_object_id': from_instance.pk, }) if to_instance: to_identifier = registry.get_identifier(to_instance) params.update({ 'to_identifier': to_identifier, 'to_object_id': to_instance.pk }) return params
def make_uid(self, instance): uid = self.get_uid(instance) if not uid: identifier = registry.get_identifier(instance) uid = super(InstanceManager, self).make_uid({ 'identifier': identifier, 'object_id': instance.pk }) self.client.set(self.make_uid_key(instance), uid) return uid
def test_friends(self): from ..models import (follow, get_friends_count, unfollow) follow(self.user, self.project) self.assertEqual(get_friends_count(self.user), 0) follow(self.project, self.user) from_identifier = registry.get_identifier(self.user) to_identifier = registry.get_identifier(self.project) self.assertEqual(get_friends_count(self.user), 1) self.assertEqual(get_friends_count(self.user, to_identifier), 1) self.assertEqual(get_friends_count(self.user, from_identifier), 0) self.assertEqual(get_friends_count(self.project), 1) self.assertEqual(get_friends_count(self.project, from_identifier), 1) self.assertEqual(get_friends_count(self.project, to_identifier), 0) unfollow(self.user, self.project) self.assertEqual(get_friends_count(self.project), 0) self.assertEqual(get_friends_count(self.user), 0)
def make_uid(self, instance): uid = self.get_uid(instance) if not uid: identifier = registry.get_identifier(instance) with self.client.pipeline() as pipe: uid = super(InstanceManager, self).make_uid(data={ 'identifier': identifier, 'object_id': instance.pk }, client=pipe) pipe.set(self.make_uid_key(instance), uid) pipe.execute() return uid
def _make_key(self, name, action=None, target=None): segments = [ self.storage.add_prefix('uid'), manager.make_uid(self.instance), name, ] if target: if isinstance(target, six.string_types): segments += ['target', target] else: if isinstance(target, models.Model) or issubclass(target, models.Model): segments += ['target', registry.get_identifier(target)] if action: if isinstance(action, six.string_types): segments += ['verb', action] elif issubclass(action, Action): segments += ['verb', action.verb] key = get_key(*segments) return key
def from_instance(self, instance): from_identifier = registry.get_identifier(instance) return self.filter(from_identifier=from_identifier, from_object_id=instance.pk)
def to_instance(self, instance): to_identifier = registry.get_identifier(instance) return self.filter(to_identifier=to_identifier, to_object_id=instance.pk)
def identifier(instance, arg=None): return registry.get_identifier(instance)
def follow(self, from_instance, to_instance, timestamp=None, fail_silently=FAIL_SILENTLY, dispatch=True): if from_instance == to_instance: raise SequereException('%s cannot follows itself' % from_instance) if self.is_following(from_instance, to_instance): if fail_silently is False: raise AlreadyFollowingException('%s is already following %s' % (from_instance, to_instance)) return logger.error('%s is already following %s' % (from_instance, to_instance)) from_uid = manager.make_uid(from_instance) to_uid = manager.make_uid(to_instance) from_identifier = registry.get_identifier(from_instance) to_identifier = registry.get_identifier(to_instance) prefix = manager.add_prefix('uid') with client.pipeline() as pipe: pipe.incr(get_key(prefix, from_uid, 'followings', 'count')) pipe.incr(get_key(prefix, to_uid, 'followers', 'count')) pipe.incr(get_key(prefix, from_uid, 'followings', to_identifier, 'count')) pipe.incr(get_key(prefix, to_uid, 'followers', from_identifier, 'count')) timestamp = timestamp or int(time.time()) pipe.zadd(get_key(prefix, to_uid, 'followers'), **{ '%s' % from_uid: timestamp }) pipe.zadd(get_key(prefix, to_uid, 'followers', from_identifier), **{ '%s' % from_uid: timestamp }) pipe.zadd(get_key(prefix, from_uid, 'followings'), **{ '%s' % to_uid: timestamp }) pipe.zadd(get_key(prefix, from_uid, 'followings', to_identifier), **{ '%s' % to_uid: timestamp }) if self.is_following(to_instance, from_instance): pipe.incr(get_key(prefix, to_uid, 'friends', 'count')) pipe.incr(get_key(prefix, to_uid, 'friends', from_identifier, 'count')) pipe.zadd(get_key(prefix, to_uid, 'friends'), **{ '%s' % from_uid: timestamp }) pipe.zadd(get_key(prefix, to_uid, 'friends', from_identifier), **{ '%s' % from_uid: timestamp }) pipe.incr(get_key(prefix, from_uid, 'friends', 'count')) pipe.incr(get_key(prefix, from_uid, 'friends', to_identifier, 'count')) pipe.zadd(get_key(prefix, from_uid, 'friends'), **{ '%s' % to_uid: timestamp }) pipe.zadd(get_key(prefix, from_uid, 'friends', to_identifier), **{ '%s' % to_uid: timestamp }) pipe.execute() if dispatch: signals.followed.send(sender=from_instance.__class__, from_instance=from_instance, to_instance=to_instance)
def make_uid_key(self, instance): identifier = registry.get_identifier(instance) object_id = instance.pk return self.add_prefix(get_key('uid', identifier, object_id))
def follow(self, from_instance, to_instance, timestamp=None, fail_silently=FAIL_SILENTLY, dispatch=True): if from_instance == to_instance: raise SequereException('%s cannot follows itself' % from_instance) if self.is_following(from_instance, to_instance): if fail_silently is False: raise AlreadyFollowingException('%s is already following %s' % (from_instance, to_instance)) return logger.error('%s is already following %s' % (from_instance, to_instance)) from_uid = manager.make_uid(from_instance) to_uid = manager.make_uid(to_instance) from_identifier = registry.get_identifier(from_instance) to_identifier = registry.get_identifier(to_instance) prefix = manager.add_prefix('uid') with client.pipeline() as pipe: pipe.incr(get_key(prefix, from_uid, 'followings', 'count')) pipe.incr(get_key(prefix, to_uid, 'followers', 'count')) pipe.incr( get_key(prefix, from_uid, 'followings', to_identifier, 'count')) pipe.incr( get_key(prefix, to_uid, 'followers', from_identifier, 'count')) timestamp = timestamp or int(time.time()) pipe.zadd(get_key(prefix, to_uid, 'followers'), **{'%s' % from_uid: timestamp}) pipe.zadd(get_key(prefix, to_uid, 'followers', from_identifier), **{'%s' % from_uid: timestamp}) pipe.zadd(get_key(prefix, from_uid, 'followings'), **{'%s' % to_uid: timestamp}) pipe.zadd(get_key(prefix, from_uid, 'followings', to_identifier), **{'%s' % to_uid: timestamp}) if self.is_following(to_instance, from_instance): pipe.incr(get_key(prefix, to_uid, 'friends', 'count')) pipe.incr( get_key(prefix, to_uid, 'friends', from_identifier, 'count')) pipe.zadd(get_key(prefix, to_uid, 'friends'), **{'%s' % from_uid: timestamp}) pipe.zadd(get_key(prefix, to_uid, 'friends', from_identifier), **{'%s' % from_uid: timestamp}) pipe.incr(get_key(prefix, from_uid, 'friends', 'count')) pipe.incr( get_key(prefix, from_uid, 'friends', to_identifier, 'count')) pipe.zadd(get_key(prefix, from_uid, 'friends'), **{'%s' % to_uid: timestamp}) pipe.zadd(get_key(prefix, from_uid, 'friends', to_identifier), **{'%s' % to_uid: timestamp}) pipe.execute() if dispatch: signals.followed.send(sender=from_instance.__class__, from_instance=from_instance, to_instance=to_instance)
def unfollow(self, from_instance, to_instance, fail_silently=FAIL_SILENTLY, dispatch=True): if not self.is_following(from_instance, to_instance): if fail_silently is False: raise NotFollowingException('%s is not following %s' % (from_instance, to_instance)) return logger.error('%s is not following %s' % (from_instance, to_instance)) from_uid = manager.make_uid(from_instance) to_uid = manager.make_uid(to_instance) from_identifier = registry.get_identifier(from_instance) to_identifier = registry.get_identifier(to_instance) prefix = manager.add_prefix('uid') with client.pipeline() as pipe: pipe.decr(get_key(prefix, from_uid, 'followings', 'count')) pipe.decr(get_key(prefix, to_uid, 'followers', 'count')) pipe.decr( get_key(prefix, from_uid, 'followings', to_identifier, 'count')) pipe.decr( get_key(prefix, to_uid, 'followers', from_identifier, 'count')) if self.is_following(to_instance, from_instance): pipe.decr(get_key(prefix, to_uid, 'friends', 'count')) pipe.decr( get_key(prefix, to_uid, 'friends', from_identifier, 'count')) pipe.zrem(get_key(prefix, to_uid, 'friends'), '%s' % from_uid) pipe.zrem(get_key(prefix, to_uid, 'friends', from_identifier), '%s' % from_uid) pipe.decr(get_key(prefix, from_uid, 'friends', 'count')) pipe.decr( get_key(prefix, from_uid, 'friends', to_identifier, 'count')) pipe.zrem(get_key(prefix, from_uid, 'friends'), '%s' % to_uid) pipe.zrem(get_key(prefix, from_uid, 'friends', to_identifier), '%s' % to_uid) pipe.zrem(get_key(prefix, to_uid, 'followers'), '%s' % from_uid) pipe.zrem(get_key(prefix, to_uid, 'followers', from_identifier), '%s' % from_uid) pipe.zrem(get_key(prefix, from_uid, 'followings'), '%s' % to_uid) pipe.zrem(get_key(prefix, from_uid, 'followings', to_identifier), '%s' % to_uid) pipe.execute() if dispatch: signals.unfollowed.send(sender=from_instance.__class__, from_instance=from_instance, to_instance=to_instance)