Stuff done
[diaspy.git] / diaspy / models.py
1 #!/usr/bin/env python3
2
3
4 import json
5 import re
6
7
8 """This module is only imported in other diaspy modules and
9 MUST NOT import anything.
10 """
11
12
13 class Aspect():
14 """This class represents an aspect.
15 """
16 def __init__(self, connection, id=-1):
17 self._connection = connection
18 self.id = id
19 self.name = ''
20
21 def getUsers(self):
22 """Returns list of users who are listed in this aspect.
23 """
24 return []
25
26 def addUser(self, user_id):
27 """Add user to current aspect.
28
29 :param user_id: user to add to aspect
30 :type user: int
31 """
32 data = {'authenticity_token': self._connection.get_token(),
33 'aspect_id': self.id,
34 'person_id': user_id}
35
36 request = self._connection.post('aspect_memberships.json', data=data)
37
38 if request.status_code != 201:
39 raise Exception('wrong status code: {0}'.format(request.status_code))
40 return request.json()
41
42 def removeUser(self, user_id):
43 """Remove user from current aspect.
44
45 :param user_id: user to remove from aspect
46 :type user: int
47 """
48 data = {'authenticity_token': self._connection.get_token(),
49 'aspect_id': self.id,
50 'person_id': user_id}
51
52 request = self.connection.delete('aspect_memberships/{0}.json'.format(self.id), data=data)
53
54 if request.status_code != 200:
55 raise Exception('wrong status code: {0}'.format(request.status_code))
56 return request.json()
57
58
59 class Notification():
60 """This class represents single notification.
61 """
62 _who_regexp = re.compile(r'/people/[0-9a-z]+" class=\'hovercardable')
63 _when_regexp = re.compile(r'[0-9]{4,4}(-[0-9]{2,2}){2,2} [0-9]{2,2}(:[0-9]{2,2}){2,2} UTC')
64
65 def __init__(self, connection, data):
66 self._connection = connection
67 self.type = list(data.keys())[0]
68 self.data = data[self.type]
69 self.id = self.data['id']
70 self.unread = self.data['unread']
71
72 def __getitem__(self, key):
73 """Returns a key from notification data.
74 """
75 return self.data[key]
76
77 def __str__(self):
78 """Returns notification note.
79 """
80 string = re.sub('</?[a-z]+( *[a-z_-]+=["\'][\w():.,!?#/\- ]*["\'])* */?>', '', self.data['note_html'])
81 string = string.strip().split('\n')[0]
82 while ' ' in string: string = string.replace(' ', ' ')
83 return string
84
85 def __repr__(self):
86 """Returns notification note with more details.
87 """
88 return '{0}: {1}'.format(self.when(), str(self))
89
90 def who(self):
91 """Returns list of guids of the users who caused you to get the notification.
92 """
93 return [who[8:24] for who in self._who_regexp.findall(self.data['note_html'])]
94
95 def when(self):
96 """Returns UTC time as found in note_html.
97 """
98 return self._when_regexp.search(self.data['note_html']).group(0)
99
100 def mark(self, unread=False):
101 """Marks notification to read/unread.
102 Marks notification to read if `unread` is False.
103 Marks notification to unread if `unread` is True.
104
105 :param unread: which state set for notification
106 :type unread: bool
107 """
108 headers = {'x-csrf-token': self._connection.get_token()}
109 params = {'set_unread': json.dumps(unread)}
110 self._connection.put('notifications/{0}'.format(self['id']), params=params, headers=headers)
111 self.data['unread'] = unread
112
113
114 class Post():
115 """This class represents a post.
116
117 .. note::
118 Remember that you need to have access to the post.
119 """
120 def __init__(self, post_id, connection):
121 """
122 :param post_id: id or guid of the post
123 :type post_id: str
124 :param connection: connection object used to authenticate
125 :type connection: connection.Connection
126 """
127 self._connection = connection
128 self.post_id = post_id
129
130 def __repr__(self):
131 """Returns string containing more information then str().
132 """
133 data = self.get_data()
134 return '{0} ({1}): {2}'.format(data['author']['name'], data['author']['diaspora_id'], data['text'])
135
136 def __str__(self):
137 """Returns text of a post.
138 """
139 return self.get_data()['text']
140
141 def get_data(self):
142 """This function retrieves data of the post.
143 """
144 r = self._connection.get('posts/{0}.json'.format(self.post_id))
145 if r.status_code != 200:
146 raise Exception('wrong status code: {0}'.format(r.status_code))
147 return r.json()
148
149 def like(self):
150 """This function likes a post.
151 It abstracts the 'Like' functionality.
152
153 :returns: dict -- json formatted like object.
154 """
155 data = {'authenticity_token': self._connection.get_token()}
156
157 r = self._connection.post('posts/{0}/likes'.format(self.post_id),
158 data=data,
159 headers={'accept': 'application/json'})
160
161 if r.status_code != 201:
162 raise Exception('{0}: Post could not be liked.'
163 .format(r.status_code))
164
165 return r.json()
166
167 def delete_like(self):
168 """This function removes a like from a post
169 """
170 data = {'authenticity_token': self._connection.get_token()}
171
172 post_data = self.get_data()
173
174 r = self._connection.delete('posts/{0}/likes/{1}'
175 .format(self.post_id,
176 post_data['interactions']
177 ['likes'][0]['id']),
178 data=data)
179
180 if r.status_code != 204:
181 raise Exception('{0}: Like could not be removed.'
182 .format(r.status_code))
183
184 def reshare(self):
185 """This function reshares a post
186
187 """
188 post_data = self.get_data()
189
190 data = {'root_guid': post_data['guid'],
191 'authenticity_token': self._connection.get_token()}
192
193 r = self._connection.post('reshares',
194 data=data,
195 headers={'accept': 'application/json'})
196
197 if r.status_code != 201:
198 raise Exception('{0}: Post could not be reshared.'
199 .format(r.status_code))
200
201 return r.json()
202
203 def comment(self, text):
204 """This function comments on a post
205
206 :param text: text to comment.
207 :type text: str
208 """
209 data = {'text': text,
210 'authenticity_token': self._connection.get_token()}
211
212 r = self._connection.post('posts/{0}/comments'.format(self.post_id),
213 data=data,
214 headers={'accept': 'application/json'})
215
216 if r.status_code != 201:
217 raise Exception('{0}: Comment could not be posted.'
218 .format(r.status_code))
219
220 return r.json()
221
222 def delete_comment(self, comment_id):
223 """This function removes a comment from a post
224
225 :param comment_id: id of the comment to remove.
226 :type comment_id: str
227 """
228 data = {'authenticity_token': self._connection.get_token()}
229
230 r = self._connection.delete('posts/{0}/comments/{1}'
231 .format(self.post_id,
232 comment_id),
233 data=data,
234 headers={'accept': 'application/json'})
235
236 if r.status_code != 204:
237 raise Exception('{0}: Comment could not be deleted.'
238 .format(r.status_code))
239
240 def delete(self):
241 """ This function deletes this post
242 """
243 data = {'authenticity_token': self._connection.get_token()}
244 r = self._connection.delete('posts/{0}'.format(self.post_id),
245 data=data,
246 headers={'accept': 'application/json'})
247 if r.status_code != 204:
248 raise Exception('{0}: Post could not be deleted'.format(r.status_code))