Skip to content
This repository has been archived by the owner on Dec 21, 2022. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
emre committed Aug 5, 2015
1 parent dfe3fef commit 501b0ca
Show file tree
Hide file tree
Showing 5 changed files with 447 additions and 1 deletion.
139 changes: 138 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,139 @@
# relationships
relationships
---
redis backed user relationships on it's simplest form.

####installation

```bash
$ [sudo] pip install relationships
```
or if you like 90s:
```bash
$ [sudo] easy_install relationships
```

####usage

**getting the Relationship class**

```python
from relationships import Relationship
r = Relationship()
```

**follow**

```python

r('Guido').follow('Rasmus')
r('Guido').follow('Larry')
r('Larry').follow('Guido')
r('Rasmus').follow('Guido')
r('Dave').follow('Guido')
r('Larry').follow('Guido')

```

**unfollow**

```python
r('Guido').unfollow("Rasmus")
```

**block**
```python
r('Guido').block("Guido")
r('Rasmus').block("Guido")
```

**unblock**
```python
r('Rasmus').unblock('Guido')
```

**getting friends**
```python
r('Guido').friends()
```

```bash
>>> {'Larry', 'Rasmus'}
```

**getting followers**

```python
r("Guido").followers()
```

```bash
>>> {'Dave', 'Larry', 'Rasmus'}
```
**getting followings**

```python
r("Guido").following()
```

```bash
>>> {'Larry', 'Rasmus'}
```
**getting a simple graph of spesific user**
```python

r('Zlatan Ibrahimovic').follow("Galatasaray")
r('Galatasaray').follow("Zlatan Ibrahimovic")
r('Galatasaray').follow("Podolski")
r('Galatasaray').follow("Drogba")
r('Galatasaray').follow("Sneijder")
r('Galatasaray').follow("Zlatan Ibrahimovic")
r('Sneijder').follow("Galatasaray")
r('Podolski').follow("Galatasaray")

r("Galatasaray").get_network("/tmp/galatasaray_network.png")
```

<img src="http://i.imgur.com/HakrxvJ.png">


**getting block list by user**

```python
# people blocked by guido
r('Guido').blocks()
```

```bash
>>> {'Rasmus'}
```

**getting blocked list by user**

```python
# people who blocked Guido
r('Guido').blocked()
```

```bash
>>> {'Rasmus'}
```

**counts**
```python
r('Guido').block_count() # count of people blocked by Guido
r('Guido').blocked_count() # count of people who blocked Guido

r('Guido').follower_count() # count of people who follows Guido
r('Guido').following_count() # count of people following by Guido
```

**checks**

```python
r('Guido').is_following('Rasmus') # does Guido follows Rasmus?
r('Rasmus').is_follower('Guido') # is Rasmus a follower of Guido?

r('Guido').is_blocked('Rasmus') # did Guido blocked Rasmus?
r('Rasmus').is_blocked_by('Guido') # is Rasmus blocked by Guido?
```

3 changes: 3 additions & 0 deletions relationships/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from relationship import Relationship

__version__ = '0.0.1'
10 changes: 10 additions & 0 deletions relationships/keys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

# list of keys will be used on redis. can be

key_list = {
"following": "following",
"followers": "followers",
"blocked": "blocked",
"blocked_by": "blocked_by",
"prefix": "relationships",
}
140 changes: 140 additions & 0 deletions relationships/relationship.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@

import redis

from keys import key_list as default_key_list


class Relationship(object):

def __init__(self, redis_connection=None, key_list=None, actor=None):

if key_list:
default_key_list.update(key_list)

self.key_list = default_key_list

if redis_connection:
self.redis_connection = redis_connection
else:
self.redis_connection = redis.StrictRedis(
host='localhost',
port=6379,
db=0
)

self.actor = actor

def __call__(self, *args, **kwargs):

self.actor = args[0]

return self

def _action_call(self, command, from_id, to_id, operation_key):
command_values = ':'.join(('user', str(from_id), operation_key)), to_id
return getattr(self.redis_connection, command)(*command_values)

def _list_call(self, operation_key):
return self.redis_connection.smembers(
'user:{}:{}'.format(self._get_actor(), operation_key)
)

def _count_call(self, operation_key):
return self.redis_connection.scard(
'user:{}:{}'.format(
self._get_actor(),
operation_key
)
)

def _get_actor(self):
if hasattr(self, 'actor'):
return self.actor

raise ValueError("actor is not defined")

def block(self, to_id):

self._action_call('sadd', self._get_actor(), to_id, self.key_list["blocked"])
self._action_call('sadd', to_id, self._get_actor(), self.key_list["blocked_by"])

def unblock(self, to_id):

self._action_call('srem', self._get_actor(), to_id, self.key_list["blocked"])
self._action_call('srem', to_id, self._get_actor(), self.key_list["blocked_by"])

def follow(self, to_id):

self._action_call('sadd', self._get_actor(), to_id, self.key_list["following"])
self._action_call('sadd', to_id, self._get_actor(), self.key_list["followers"])

def unfollow(self, to_id):

self._action_call('srem', self._get_actor(), to_id, self.key_list["following"])
self._action_call('srem', to_id, self._get_actor(), self.key_list["followers"])

def friends(self):

return self.redis_connection.sinter(
"user:{}:{}".format(self._get_actor(), self.key_list["following"]),
"user:{}:{}".format(self._get_actor(), self.key_list["followers"]),
)

def followers(self):
return self._list_call(self.key_list["followers"])

def following(self):
return self._list_call(self.key_list["following"])

def blocks(self):
return self._list_call(self.key_list["blocked"])

def blocked(self):
return self._list_call(self.key_list["blocked_by"])

def follower_count(self):
return self._count_call(self.key_list["followers"])

def following_count(self):
return self._count_call(self.key_list["following"])

def block_count(self):
return self._count_call(self.key_list["blocked"])

def blocked_count(self):
return self._count_call(self.key_list["blocked_by"])

def is_follower(self, follower_id):
return self._action_call('sismember', self._get_actor(), follower_id, self.key_list["followers"])

def is_following(self, following_id):
return self._action_call('sismember', self._get_actor(), following_id, self.key_list["following"])

def is_blocked(self, blocked_id):
return self._action_call('sismember', self._get_actor(), blocked_id, self.key_list["blocked"])

def is_blocked_by(self, blocked_by_id):
return self._action_call('sismember', self._get_actor(), blocked_by_id,self.key_list["blocked_by"])

def get_network(self, output):

user_id = self._get_actor()

try:
import pydot
except ImportError:
raise ImportError("You need pydot library to get network functionality.")

graph = pydot.Dot('network_of_user_{}'.format(user_id), graph_type='digraph')
target_node = pydot.Node(user_id)

for _id in self(user_id).following():
user_node = pydot.Node(_id)
graph.add_edge(pydot.Edge(target_node, user_node))

for _id in self(user_id).followers():
user_node = pydot.Node(_id)
graph.add_edge(pydot.Edge(user_node, target_node))

graph.write_png(output)

Loading

0 comments on commit 501b0ca

Please sign in to comment.