Fixed bugs with getting, showing and deleting users. Deleting users still does not...
[diaspy.git] / diaspy / people.py
index 0a73657bf823e23a9b43e112e59f61414e8281e9..b48c600664349695194c4892d177a02fa174976e 100644 (file)
@@ -1,7 +1,23 @@
+#!/usr/bin/env python3
+
+import json
 import re
 from diaspy.streams import Outer
 from diaspy.models import Aspect
 from diaspy import errors
+from diaspy import search
+
+
+def sephandle(handle):
+    """Separate Diaspora* handle into pod pod and user.
+
+    :returns: two-tuple (pod, user)
+    """
+    if re.match('^[a-zA-Z]+[a-zA-Z0-9_-]*@[a-z0-9.]+\.[a-z]+$', handle) is None:
+        raise errors.InvalidHandleError('{0}'.format(handle))
+    handle = handle.split('@')
+    pod, user = handle[1], handle[0]
+    return (pod, user)
 
 
 class User():
@@ -32,7 +48,7 @@ class User():
             'handle': handle,
             'id': id,
         }
-        self._do_fetch(fetch)
+        self._fetch(fetch)
 
     def __getitem__(self, key):
         return self.data[key]
@@ -41,30 +57,32 @@ class User():
         return self['guid']
 
     def __repr__(self):
-        return '{0} ({1})'.format(self['diaspora_name'], self['guid'])
+        return '{0} ({1})'.format(self['handle'], self['guid'])
 
-    def _do_fetch(self, fetch):
+    def _fetchstream(self):
+        self.stream = Outer(self._connection, location='people/{0}.json'.format(self['guid']))
+
+    def _fetch(self, fetch):
+        """Fetch user posts or data.
+        """
         if fetch == 'posts':
-            if self['handle'] and self['guid']: self.fetchguid()
-            elif self['guid'] and not self['handle']: self.fetchguid()
-            elif self['handle'] and not self['guid']: self.fetchhandle()
-        elif fetch == 'data' and len(self['handle']):
+            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.
-
-        :returns: two-tuple (pod, user)
+    def _finalize_data(self, data):
+        """Adjustments are needed to have similar results returned
+        by search feature and fetchguid()/fetchhandle().
         """
-        if re.match('^[a-zA-Z]+[a-zA-Z0-9_-]*@[a-z0-9.]+\.[a-z]+$', self['handle']) is None:
-            raise Exception('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):
+        names = [('id', 'id'),
+                 ('guid', 'guid'),
+                 ('name', 'name'),
+                 ('avatar', 'avatar'),
+                 ('handle', 'diaspora_id'),
+                 ]
         final = {}
-        for d, f in names:
+        for f, d in names:
             final[f] = data[d]
         return final
 
@@ -75,49 +93,68 @@ class User():
         :param request: request object
         :type request: request
         """
-        if request.status_code != 200:
-            raise Exception('wrong error code: {0}'.format(request.status_code))
-        else:
-            request = request.json()
+        if request.status_code != 200: raise Exception('wrong error code: {0}'.format(request.status_code))
+        request = request.json()
         if not len(request): raise errors.UserError('cannot extract user data: no posts to analyze')
-        names = [('id', 'id'),
-                 ('diaspora_id', 'diaspora_id'),
-                 ('guid', 'guid'),
-                 ('name', 'diaspora_name'),
-                 ('avatar', 'image_urls'),
-                 ]
-        self.data = self._finalize_data(request[0]['author'], names)
-        self.stream = Outer(self._connection, location='people/{0}.json'.format(self['guid']))
+        self.data = self._finalize_data(request[0]['author'])
 
     def fetchhandle(self, protocol='https'):
         """Fetch user data and posts using Diaspora handle.
         """
-        pod, user = self._sephandle()
-        request = self._connection.session.get('{0}://{1}/u/{2}.json'.format(protocol, pod, user))
+        pod, user = sephandle(self['handle'])
+        request = self._connection.get('{0}://{1}/u/{2}.json'.format(protocol, pod, user), direct=True)
         self._postproc(request)
+        self._fetchstream()
 
     def fetchguid(self):
         """Fetch user data and posts using guid.
         """
-        request = self._connection.get('people/{0}.json'.format(self['guid']))
-        self._postproc(request)
+        if self['guid']:
+            request = self._connection.get('people/{0}.json'.format(self['guid']))
+            self._postproc(request)
+            self._fetchstream()
+        else:
+            raise errors.UserError('GUID not set')
 
-    def fetchprofile(self, protocol='https'):
-        """Fetch user data using Diaspora handle.
+    def fetchprofile(self):
+        """Fetches user data.
         """
-        request = self._connection.get('people.json?q={0}'.format(self['handle']))
-        if request.status_code != 200:
-            raise Exception('wrong error code: {0}'.format(request.status_code))
-        else:
-            request = request.json()
-        if len(request):
-            names = [('id', 'id'),
-                     ('handle', 'diaspora_id'),
-                     ('guid', 'guid'),
-                     ('name', 'diaspora_name'),
-                     ('avatar', 'image_urls'),
-                     ]
-            self.data = self._finalize_data(request[0], names)
+        result = search.Search(self._connection).user(self['handle'])
+        
+        # Check if there were any results at all
+        if len(result) < 1:
+            raise errors.UserError('could not fetch profile of user: {0}'.format(self['handle']))
+        
+        self.data = result[0]
+
+    def getHCard(self):
+        """Returns XML string containing user HCard.
+        """
+        request = self._connection.get('hcard/users/{0}'.format(self['guid']))
+        if request.status_code != 200: raise errors.UserError('could not fetch hcard for user: {0}'.format(self['guid']))
+        return request.text
+
+
+class Me():
+    """Object represetnting current user.
+    """
+    _userinfo_regex = re.compile(r'window.current_user_attributes = ({.*})')
+    _userinfo_regex_2 = re.compile(r'gon.user=({.*});gon.preloads')
+
+    def __init__(self, connection):
+        self._connection = connection
+
+    def getInfo(self):
+        """This function returns the current user's attributes.
+
+        :returns: dict
+        """
+        request = self._connection.get('bookmarklet')
+        userdata = self._userinfo_regex.search(request.text)
+        if userdata is None: userdata = self._userinfo_regex_2.search(request.text)
+        if userdata is None: raise errors.DiaspyError('cannot find user data')
+        userdata = userdata.group(1)
+        return json.loads(userdata)
 
 
 class Contacts():
@@ -169,5 +206,4 @@ class Contacts():
         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(self._connection, user['guid'], user['handle'], 'none', user['id']) for user in request.json()]
-        return contacts
+        return [User(self._connection, guid=user['guid'], handle=user['handle'], fetch=None) for user in request.json()]