Merge branch 'master' of https://github.com/Javafant/diaspora-api into contacts
[diaspy.git] / diaspy / models.py
CommitLineData
88ec6cda 1#!/usr/bin/env python3
ae221396
MK
2
3
178faa46 4import json
c8438f07 5import re
178faa46
MM
6
7
8"""This module is only imported in other diaspy modules and
9MUST NOT import anything.
10"""
11
12
7a818fdb
MM
13class 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
488d7ff6
MM
21 def getUsers(self):
22 """Returns list of users who are listed in this aspect.
23 """
24 return []
25
7a818fdb
MM
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
178faa46
MM
59class Notification():
60 """This class represents single notification.
61 """
c8438f07
MM
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
178faa46
MM
65 def __init__(self, connection, data):
66 self._connection = connection
178faa46
MM
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):
c8438f07
MM
73 """Returns a key from notification data.
74 """
178faa46
MM
75 return self.data[key]
76
c8438f07
MM
77 def __str__(self):
78 """Returns notification note.
79 """
4eb05209 80 string = re.sub('</?[a-z]+( *[a-z_-]+=["\'][\w():.,!?#/\- ]*["\'])* */?>', '', self.data['note_html'])
c8438f07 81 string = string.strip().split('\n')[0]
4eb05209 82 while ' ' in string: string = string.replace(' ', ' ')
c8438f07
MM
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):
19a4a78a 91 """Returns list of guids of the users who caused you to get the notification.
c8438f07 92 """
19a4a78a 93 return [who[8:24] for who in self._who_regexp.findall(self.data['note_html'])]
c8438f07
MM
94
95 def when(self):
96 """Returns UTC time as found in note_html.
b0b4c46d 97 """
19a4a78a 98 return self._when_regexp.search(self.data['note_html']).group(0)
b0b4c46d 99
178faa46
MM
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)}
178faa46
MM
110 self._connection.put('notifications/{0}'.format(self['id']), params=params, headers=headers)
111 self.data['unread'] = unread
112
113
dd0a4d9f 114class Post():
ae221396
MK
115 """This class represents a post.
116
117 .. note::
118 Remember that you need to have access to the post.
ae221396 119 """
b95ffe83 120 def __init__(self, post_id, connection):
a7661afd
MK
121 """
122 :param post_id: id or guid of the post
123 :type post_id: str
b95ffe83
MM
124 :param connection: connection object used to authenticate
125 :type connection: connection.Connection
a7661afd 126 """
b95ffe83 127 self._connection = connection
8095ac8b
MK
128 self.post_id = post_id
129
1467ec15
MM
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
66c3bb76
MM
136 def __str__(self):
137 """Returns text of a post.
138 """
63cc182d 139 return self.get_data()['text']
66c3bb76 140
7eb90eb7 141 def get_data(self):
0e858bba
MM
142 """This function retrieves data of the post.
143 """
505fc964
MM
144 r = self._connection.get('posts/{0}.json'.format(self.post_id))
145 if r.status_code != 200:
0e858bba 146 raise Exception('wrong status code: {0}'.format(r.status_code))
505fc964 147 return r.json()
a993a4b6
MK
148
149 def like(self):
88ec6cda 150 """This function likes a post.
df912114 151 It abstracts the 'Like' functionality.
a993a4b6
MK
152
153 :returns: dict -- json formatted like object.
a993a4b6 154 """
59ad210c 155 data = {'authenticity_token': self._connection.get_token()}
a993a4b6 156
b95ffe83 157 r = self._connection.post('posts/{0}/likes'.format(self.post_id),
385e7ebe
MM
158 data=data,
159 headers={'accept': 'application/json'})
a7661afd
MK
160
161 if r.status_code != 201:
9088535d
MK
162 raise Exception('{0}: Post could not be liked.'
163 .format(r.status_code))
a7661afd 164
a993a4b6
MK
165 return r.json()
166
5e809c8b 167 def delete_like(self):
a993a4b6 168 """This function removes a like from a post
a993a4b6 169 """
59ad210c 170 data = {'authenticity_token': self._connection.get_token()}
a993a4b6 171
7eb90eb7 172 post_data = self.get_data()
8095ac8b 173
b95ffe83 174 r = self._connection.delete('posts/{0}/likes/{1}'
385e7ebe
MM
175 .format(self.post_id,
176 post_data['interactions']
177 ['likes'][0]['id']),
178 data=data)
a993a4b6 179
a7661afd 180 if r.status_code != 204:
9088535d
MK
181 raise Exception('{0}: Like could not be removed.'
182 .format(r.status_code))
a7661afd 183
a993a4b6
MK
184 def reshare(self):
185 """This function reshares a post
186
187 """
7eb90eb7 188 post_data = self.get_data()
8095ac8b
MK
189
190 data = {'root_guid': post_data['guid'],
59ad210c 191 'authenticity_token': self._connection.get_token()}
a993a4b6 192
b95ffe83 193 r = self._connection.post('reshares',
385e7ebe
MM
194 data=data,
195 headers={'accept': 'application/json'})
a7661afd
MK
196
197 if r.status_code != 201:
9088535d
MK
198 raise Exception('{0}: Post could not be reshared.'
199 .format(r.status_code))
a993a4b6
MK
200
201 return r.json()
202
203 def comment(self, text):
204 """This function comments on a post
205
a993a4b6
MK
206 :param text: text to comment.
207 :type text: str
a993a4b6 208 """
a993a4b6 209 data = {'text': text,
59ad210c 210 'authenticity_token': self._connection.get_token()}
a993a4b6 211
b95ffe83 212 r = self._connection.post('posts/{0}/comments'.format(self.post_id),
385e7ebe
MM
213 data=data,
214 headers={'accept': 'application/json'})
a7661afd
MK
215
216 if r.status_code != 201:
9088535d
MK
217 raise Exception('{0}: Comment could not be posted.'
218 .format(r.status_code))
a993a4b6
MK
219
220 return r.json()
ae221396 221
5e809c8b 222 def delete_comment(self, comment_id):
a993a4b6
MK
223 """This function removes a comment from a post
224
91d2d5dc
B
225 :param comment_id: id of the comment to remove.
226 :type comment_id: str
a993a4b6 227 """
59ad210c 228 data = {'authenticity_token': self._connection.get_token()}
a993a4b6 229
b95ffe83 230 r = self._connection.delete('posts/{0}/comments/{1}'
385e7ebe
MM
231 .format(self.post_id,
232 comment_id),
233 data=data,
234 headers={'accept': 'application/json'})
a7661afd
MK
235
236 if r.status_code != 204:
9088535d
MK
237 raise Exception('{0}: Comment could not be deleted.'
238 .format(r.status_code))
5e809c8b
MK
239
240 def delete(self):
241 """ This function deletes this post
5e809c8b 242 """
59ad210c 243 data = {'authenticity_token': self._connection.get_token()}
b95ffe83 244 r = self._connection.delete('posts/{0}'.format(self.post_id),
385e7ebe
MM
245 data=data,
246 headers={'accept': 'application/json'})
65b91311
MM
247 if r.status_code != 204:
248 raise Exception('{0}: Post could not be deleted'.format(r.status_code))