Small changes in regexp used for cleaning notifications HTML text,
[diaspy.git] / diaspy / people.py
CommitLineData
beaa09fb
MM
1import re
2from diaspy.streams import Outer
d589deff 3from diaspy.models import Aspect
beaa09fb
MM
4
5
6class User:
7 """This class abstracts a D* user.
8 This object goes around the limitations of current D* API and will
9 extract user data using black magic.
10 However, no chickens are harmed when you use it.
17d8f406 11
27f09973 12 If user has not posted yet diaspy will not be able to extract the information
c5d935c0
MM
13 from his/her posts. Since there is no official way to do it we rely
14 on user posts. If this will be the case user will be notified with appropriate
15 exception message.
16
27f09973 17 When creating new User() one can pass either guid or handle as
17d8f406 18 an optional parameter. GUID takes precedence over handle.
beaa09fb 19 """
dd0a4d9f
MM
20 data = {}
21 stream = []
17d8f406
MM
22
23 def __init__(self, connection, guid='', handle=''):
beaa09fb 24 self._connection = connection
17d8f406
MM
25 self.guid, self.handle = guid, handle
26 if handle and guid: self.fetchguid(guid)
27 elif guid and not handle: self.fetchguid(guid)
28 elif handle and not guid: self.fetchhandle(handle)
beaa09fb
MM
29
30 def __getitem__(self, key):
31 return self.data[key]
32
33 def _sephandle(self, handle):
34 """Separate D* handle into pod pod and user.
35
36 :param handle: diaspora id: user@pod.example.com
37 :type handle: str
38 :returns: two-tuple (pod, user)
39 """
40 if re.match('^[a-zA-Z]+[a-zA-Z0-9_-]*@[a-z0-9.]+\.[a-z]+$', handle) is None:
41 raise Exception('invalid handle: {0}'.format(handle))
42 handle = handle.split('@')
43 pod, user = handle[1], handle[0]
44 return (pod, user)
45
a8fdc14a
MM
46 def _postproc(self, request):
47 """Makes necessary modifications to user data and
48 sets up a stream.
49
50 :param request: request object
51 :type request: request
beaa09fb 52 """
141216df 53 if request.status_code != 200:
a8fdc14a 54 raise Exception('wrong error code: {0}'.format(request.status_code))
141216df
MM
55 else:
56 request = request.json()
c5d935c0
MM
57
58 if not len(request): raise ('Cannot extract user data: no posts to analyze')
59 data = request[0]['author']
60 final = {}
a8fdc14a
MM
61 names = [('id', 'id'),
62 ('diaspora_id', 'diaspora_id'),
63 ('guid', 'guid'),
64 ('name', 'diaspora_name'),
65 ('avatar', 'image_urls'),
f605e88d 66 ]
a8fdc14a
MM
67 for d, f in names:
68 final[f] = data[d]
69 self.data = final
beaa09fb
MM
70 self.stream = Outer(self._connection, location='people/{0}.json'.format(self.data['guid']))
71
17d8f406
MM
72 def fetchhandle(self, diaspora_id, protocol='https'):
73 """Fetch user data using Diaspora handle.
beaa09fb
MM
74 """
75 pod, user = self._sephandle(diaspora_id)
a8fdc14a
MM
76 request = self._connection.session.get('{0}://{1}/u/{2}.json'.format(protocol, pod, user))
77 self._postproc(request)
beaa09fb 78
beaa09fb
MM
79 def fetchguid(self, guid):
80 """Fetch user data using guid.
81 """
17d8f406
MM
82 request = self._connection.get('people/{0}.json'.format(guid))
83 self._postproc(request)
dd0a4d9f
MM
84
85
86class Contacts():
87 """This class represents user's list of contacts.
88 """
89 def __init__(self, connection):
90 self._connection = connection
91
d589deff
MM
92 def add(self, user_id, aspect_ids):
93 """Add user to aspects of given ids.
dd0a4d9f 94
d589deff
MM
95 :param user_id: user guid
96 :type user_id: str
97 :param aspect_ids: list of aspect ids
98 :type aspect_ids: list
dd0a4d9f 99 """
7a818fdb 100 for aid in aspect_ids: Aspect(self._connection, aid).addUser(user_id)
27f09973 101
d589deff
MM
102 def remove(self, user_id, aspect_ids):
103 """Remove user from aspects of given ids.
27f09973 104
d589deff
MM
105 :param user_id: user guid
106 :type user_id: str
107 :param aspect_ids: list of aspect ids
108 :type aspect_ids: list
27f09973 109 """
7a818fdb 110 for aid in aspect_ids: Aspect(self._connection, aid).removeUser(user_id)
27f09973 111
d589deff 112 def get(self, set=''):
27f09973 113 """Returns list of user contacts.
d589deff
MM
114 Contact is a User() who is in one or more of user's
115 aspects.
116
7a818fdb
MM
117 By default, it will return list of users who are in
118 user's aspects.
119
d589deff
MM
120 If `set` is `all` it will also include users who only share
121 with logged user and are not in his/hers aspects.
7a818fdb 122
d589deff
MM
123 If `set` is `only_sharing` it will return users who are only
124 sharing with logged user and ARE NOT in his/hers aspects.
125
126 :param set: if passed could be 'all' or 'only_sharing'
127 :type set: str
27f09973 128 """
d589deff
MM
129 params = {}
130 if set: params['set'] = set
131
132 request = self._connection.get('contacts.json', params=params)
27f09973
MM
133 if request.status_code != 200:
134 raise Exception('status code {0}: cannot get contacts'.format(request.status_code))
135 contacts = [User(user['guid']) for user in request.json()]
136 return contacts