import re
from diaspy.streams import Outer
from diaspy.models import Aspect
+from diaspy import errors
+from diaspy import search
class User():
extract user data using black magic.
However, no chickens are harmed when you use it.
- If user has not posted yet diaspy will not be able to extract the information
- from his/her posts. Since there is no official way to do it we rely
- on user posts. If this will be the case user will be notified with appropriate
- exception message.
+ The parameter fetch should be either 'posts', 'data' or 'none'. By
+ default it is 'posts' which means in addition to user data, stream
+ will be fetched. If user has not posted yet diaspy will not be able
+ to extract the information from his/her posts. Since there is no official
+ way to do it we rely on user posts. If this will be the case user
+ will be notified with appropriate exception message.
- When creating new User() one can pass either guid or handle as
- an optional parameter. GUID takes precedence over handle.
- """
- data = {}
- stream = []
+ If fetch is 'data', only user data will be fetched. If the user is
+ not found, no exception will be returned.
- def __init__(self, connection, guid='', handle=''):
+ When creating new User() one can pass either guid, handle and/or id as
+ optional parameters. GUID takes precedence over handle when fetching
+ user stream. When fetching user data, handle is required.
+ """
+ def __init__(self, connection, guid='', handle='', fetch='posts', id=0):
self._connection = connection
- self.guid, self.handle = guid, handle
- if handle and guid: self.fetchguid(guid)
- elif guid and not handle: self.fetchguid(guid)
- elif handle and not guid: self.fetchhandle(handle)
+ self.stream = []
+ self.handle = handle
+ self.guid = guid
+ self.data = {
+ 'guid': guid,
+ 'handle': handle,
+ 'id': id,
+ }
+ self._fetch(fetch)
def __getitem__(self, key):
return self.data[key]
- def _sephandle(self, handle):
+ def __str__(self):
+ return self['guid']
+
+ def __repr__(self):
+ return '{0} ({1})'.format(self['diaspora_name'], self['guid'])
+
+ def _fetch(self, fetch):
+ """Fetch user posts or data.
+ """
+ if fetch == 'posts':
+ if self.handle and not self.guid: self.fetchhandle()
+ else: self.fetchguid()
+ elif fetch == 'data' and self.handle:
+ self.fetchprofile()
+
+ def _sephandle(self):
"""Separate D* handle into pod pod and user.
- :param handle: diaspora id: user@pod.example.com
- :type handle: str
:returns: two-tuple (pod, user)
"""
- if re.match('^[a-zA-Z]+[a-zA-Z0-9_-]*@[a-z0-9.]+\.[a-z]+$', handle) is None:
- raise Exception('invalid handle: {0}'.format(handle))
- handle = handle.split('@')
+ if re.match('^[a-zA-Z]+[a-zA-Z0-9_-]*@[a-z0-9.]+\.[a-z]+$', self.handle) is None:
+ raise errors.UserError('invalid handle: {0}'.format(self.handle))
+ handle = self.handle.split('@')
pod, user = handle[1], handle[0]
return (pod, user)
+ def _finalize_data(self, data):
+ names = [('id', 'id'),
+ ('handle', 'diaspora_id'),
+ ('guid', 'guid'),
+ ('name', 'diaspora_name'),
+ ('avatar', 'image_urls'),
+ ]
+ final = {}
+ for d, f in names:
+ final[f] = data[d]
+ return final
+
def _postproc(self, request):
"""Makes necessary modifications to user data and
sets up a stream.
raise Exception('wrong error code: {0}'.format(request.status_code))
else:
request = request.json()
+ if not len(request): raise errors.UserError('cannot extract user data: no posts to analyze')
+ self.data = self._finalize_data(request[0]['author'])
+ self.stream = Outer(self._connection, location='people/{0}.json'.format(self['guid']))
- if not len(request): raise ('Cannot extract user data: no posts to analyze')
- data = request[0]['author']
- final = {}
- names = [('id', 'id'),
- ('diaspora_id', 'diaspora_id'),
- ('guid', 'guid'),
- ('name', 'diaspora_name'),
- ('avatar', 'image_urls'),
- ]
- for d, f in names:
- final[f] = data[d]
- self.data = final
- self.stream = Outer(self._connection, location='people/{0}.json'.format(self.data['guid']))
-
- def fetchhandle(self, diaspora_id, protocol='https'):
- """Fetch user data using Diaspora handle.
+ def fetchhandle(self, protocol='https'):
+ """Fetch user data and posts using Diaspora handle.
"""
- pod, user = self._sephandle(diaspora_id)
+ pod, user = self._sephandle()
request = self._connection.session.get('{0}://{1}/u/{2}.json'.format(protocol, pod, user))
self._postproc(request)
- def fetchguid(self, guid):
- """Fetch user data using guid.
+ def fetchguid(self):
+ """Fetch user data and posts using guid.
"""
- request = self._connection.get('people/{0}.json'.format(guid))
+ request = self._connection.get('people/{0}.json'.format(self.guid))
self._postproc(request)
request = self._connection.get('contacts.json', params=params)
if request.status_code != 200:
raise Exception('status code {0}: cannot get contacts'.format(request.status_code))
- contacts = [User(user['guid']) for user in request.json()]
+ contacts = [User(self._connection, guid=user['guid'], handle=user['handle'], fetch=None, id=user['id']) for user in request.json()]
return contacts