class Aspect():
"""This class represents an aspect.
-
+
Class can be initialized by passing either an id and/or name as
parameters.
If both are missing, an exception will be raised.
self.id = self._findid()
elif not id and not name:
raise Exception("Aspect must be initialized with either an id or name")
-
+
def _findname(self):
"""Finds name for aspect.
"""
name = a['name']
break
return name
-
+
def _findid(self):
"""Finds id for aspect.
"""
break
return id
- def getUsers(self):
- """Returns list of GUIDs of users who are listed in this aspect.
+ def _getajax(self):
+ """Returns HTML returned when editing aspects via web UI.
"""
start_regexp = re.compile('<ul +class=["\']contacts["\'] *>')
- userline_regexp = re.compile('<a href=["\']/people/[a-z0-9]{16,16}["\']>[a-zA-Z0-9()@. _-]+</a>')
- personid_regexp = 'alt=["\']{0}["\'] class=["\']avatar["\'] data-person_id=["\'][0-9]+["\']'
- method_regexp = 'data-method="delete" data-person_id="{0}"'
-
ajax = self._connection.get('aspects/{0}/edit'.format(self.id)).text
begin = ajax.find(start_regexp.search(ajax).group(0))
end = ajax.find('</ul>')
- ajax = ajax[begin:end]
+ return ajax[begin:end]
+
+ def _extractusernames(self, ajax):
+ """Extracts usernames and GUIDs from ajax returned by Diaspora*.
+ Returns list of two-tuples: (guid, diaspora_name).
+ """
+ userline_regexp = re.compile('<a href=["\']/people/[a-z0-9]{16,16}["\']>[\w()*@. -]+</a>')
+ return [(line[17:33], re.escape(line[35:-4])) for line in userline_regexp.findall(ajax)]
- usernames = [(line[17:33], line[35:-4]) for line in userline_regexp.findall(ajax)]
- for i, data in enumerate(usernames):
- guid, name = data
- for char in ['(', ')', '.']: name = name.replace(char, '\\'+char)
- usernames[i] = (guid, name)
+ def _extractpersonids(self, ajax, usernames):
+ """Extracts `person_id`s and usernames from ajax and list of usernames.
+ Returns list of two-tuples: (username, id)
+ """
+ personid_regexp = 'alt=["\']{0}["\'] class=["\']avatar["\'] data-person_id=["\'][0-9]+["\']'
personids = [re.compile(personid_regexp.format(name)).search(ajax).group(0) for guid, name in usernames]
for n, line in enumerate(personids):
i, id = -2, ''
id = line[i] + id
i -= 1
personids[n] = (usernames[n][1], id)
+ return personids
- users_in_aspect = []
- for name, id in personids:
- if re.compile(method_regexp.format(id, self.id)).search(ajax): users_in_aspect.append(name)
-
+ def _defineusers(self, ajax, personids):
+ """Gets users contained in this aspect by getting users who have `delete` method.
+ """
+ method_regexp = 'data-method="delete" data-person_id="{0}"'
users = []
- for i, user in enumerate(usernames):
- guid, name = user
- if name in users_in_aspect: users.append(guid)
+ for name, id in personids:
+ if re.compile(method_regexp.format(id)).search(ajax): users.append(name)
return users
+ def _getguids(self, users_in_aspect, usernames):
+ """Defines users contained in this aspect.
+ """
+ guids = []
+ for guid, name in usernames:
+ if name in users_in_aspect: guids.append(guid)
+ return guids
+
+ def getUsers(self):
+ """Returns list of GUIDs of users who are listed in this aspect.
+ """
+ ajax = self._getajax()
+ usernames = self._extractusernames(ajax)
+ personids = self._extractpersonids(ajax, usernames)
+ users_in_aspect = self._defineusers(ajax, personids)
+ return self._getguids(users_in_aspect, usernames)
+
def addUser(self, user_id):
"""Add user to current aspect.
:param user_id: user to add to aspect
- :type user: int
+ :type user_id: int
+ :returns: JSON from request
"""
data = {'authenticity_token': self._connection.get_token(),
'aspect_id': self.id,
import re
from diaspy.streams import Outer
from diaspy.models import Aspect
+from diaspy import errors
class User():
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 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.
-
+
If fetch is 'data', only user data will be fetched. If the user is
not found, no exception will be returned.
handle = self['handle'].split('@')
pod, user = handle[1], handle[0]
return (pod, user)
-
+
def _finalize_data(self, data, names):
final = {}
for d, f in names:
raise Exception('wrong error code: {0}'.format(request.status_code))
else:
request = request.json()
- if not len(request): raise Exception('Cannot extract user data: no posts to analyze')
+ if not len(request): raise errors.UserError('cannot extract user data: no posts to analyze')
names = [('id', 'id'),
('diaspora_id', 'diaspora_id'),
('guid', 'guid'),
"""
request = self._connection.get('people/{0}.json'.format(self['guid']))
self._postproc(request)
-
+
def fetchprofile(self, protocol='https'):
"""Fetch user data using Diaspora handle.
"""