2 from diaspy
.streams
import Outer
3 from diaspy
.models
import Aspect
4 from diaspy
import errors
5 from diaspy
import search
9 """Separate Diaspora* handle into pod pod and user.
11 :returns: two-tuple (pod, user)
13 if re
.match('^[a-zA-Z]+[a-zA-Z0-9_-]*@[a-z0-9.]+\.[a-z]+$', handle
) is None:
14 raise errors
.InvalidHandleError('{0}'.format(handle
))
15 handle
= handle
.split('@')
16 pod
, user
= handle
[1], handle
[0]
21 """This class abstracts a D* user.
22 This object goes around the limitations of current D* API and will
23 extract user data using black magic.
24 However, no chickens are harmed when you use it.
26 The parameter fetch should be either 'posts', 'data' or 'none'. By
27 default it is 'posts' which means in addition to user data, stream
28 will be fetched. If user has not posted yet diaspy will not be able
29 to extract the information from his/her posts. Since there is no official
30 way to do it we rely on user posts. If this will be the case user
31 will be notified with appropriate exception message.
33 If fetch is 'data', only user data will be fetched. If the user is
34 not found, no exception will be returned.
36 When creating new User() one can pass either guid, handle and/or id as
37 optional parameters. GUID takes precedence over handle when fetching
38 user stream. When fetching user data, handle is required.
40 def __init__(self
, connection
, guid
='', handle
='', fetch
='posts', id=0):
41 self
._connection
= connection
50 def __getitem__(self
, key
):
57 return '{0} ({1})'.format(self
['diaspora_name'], self
['guid'])
59 def _fetchstream(self
):
60 self
.stream
= Outer(self
._connection
, location
='people/{0}.json'.format(self
['guid']))
62 def _fetch(self
, fetch
):
63 """Fetch user posts or data.
66 if self
['handle'] and not self
['guid']: self
.fetchhandle()
67 else: self
.fetchguid()
68 elif fetch
== 'data' and self
['handle']:
71 def _finalize_data(self
, data
):
72 """Adjustments are needed to have similar results returned
73 by search feature and fetchguid()/fetchhandle().
75 names
= [('id', 'id'),
79 ('handle', 'diaspora_id'),
86 def _postproc(self
, request
):
87 """Makes necessary modifications to user data and
90 :param request: request object
91 :type request: request
93 if request
.status_code
!= 200: raise Exception('wrong error code: {0}'.format(request
.status_code
))
94 request
= request
.json()
95 if not len(request
): raise errors
.UserError('cannot extract user data: no posts to analyze')
96 self
.data
= self
._finalize
_data
(request
[0]['author'])
98 def fetchhandle(self
, protocol
='https'):
99 """Fetch user data and posts using Diaspora handle.
101 pod
, user
= sephandle(self
['handle'])
102 request
= self
._connection
.get('{0}://{1}/u/{2}.json'.format(protocol
, pod
, user
), direct
=True)
103 self
._postproc
(request
)
107 """Fetch user data and posts using guid.
110 request
= self
._connection
.get('people/{0}.json'.format(self
['guid']))
111 self
._postproc
(request
)
114 raise errors
.UserError('GUID not set')
116 def fetchprofile(self
):
117 """Fetches user data.
119 data
= search
.Search(self
._connection
).user(self
['handle'])[0]
124 """This class represents user's list of contacts.
126 def __init__(self
, connection
):
127 self
._connection
= connection
129 def add(self
, user_id
, aspect_ids
):
130 """Add user to aspects of given ids.
132 :param user_id: user guid
134 :param aspect_ids: list of aspect ids
135 :type aspect_ids: list
137 for aid
in aspect_ids
: Aspect(self
._connection
, aid
).addUser(user_id
)
139 def remove(self
, user_id
, aspect_ids
):
140 """Remove user from aspects of given ids.
142 :param user_id: user guid
144 :param aspect_ids: list of aspect ids
145 :type aspect_ids: list
147 for aid
in aspect_ids
: Aspect(self
._connection
, aid
).removeUser(user_id
)
149 def get(self
, set=''):
150 """Returns list of user contacts.
151 Contact is a User() who is in one or more of user's
154 By default, it will return list of users who are in
157 If `set` is `all` it will also include users who only share
158 with logged user and are not in his/hers aspects.
160 If `set` is `only_sharing` it will return users who are only
161 sharing with logged user and ARE NOT in his/hers aspects.
163 :param set: if passed could be 'all' or 'only_sharing'
167 if set: params
['set'] = set
169 request
= self
._connection
.get('contacts.json', params
=params
)
170 if request
.status_code
!= 200:
171 raise Exception('status code {0}: cannot get contacts'.format(request
.status_code
))
172 return [User(self
._connection
, guid
=user
['guid'], handle
=user
['handle'], fetch
=None) for user
in request
.json()]