cc4b0a448f2539b587178c36b169c38aead08367
8 """This module is only imported in other diaspy modules and
9 MUST NOT import anything.
14 """This class represents an aspect.
16 def __init__(self
, connection
, id=-1):
17 self
._connection
= connection
19 self
.name
= self
._findname
()
22 """Finds name for aspect.
25 aspects
= self
._connection
.getUserInfo()['aspects']
27 if a
['id'] == self
.id:
33 """Returns list of GUIDs of users who are listed in this aspect.
35 start_regexp
= re
.compile('<ul +class=["\']contacts["\'] *>')
36 userline_regexp
= re
.compile('<a href=["\']/people/[a-z0-9]{16,16}["\']>[a-zA-Z0-9 _-]+</a>')
37 personid_regexp
= 'alt="{0}" class="avatar" data-person_id="[0-9]+"'
38 method_regexp
= 'data-method="delete" data-person_id="{0}"'
40 ajax
= self
._connection
.get('aspects/{0}/edit'.format(self
.id)).text
41 begin
= ajax
.find(start_regexp
.search(ajax
).group(0))
42 end
= ajax
.find('</ul>')
43 ajax
= ajax
[begin
:end
]
45 usernames
= [(line
[17:33], line
[35:-4]) for line
in userline_regexp
.findall(ajax
)]
46 personids
= [re
.compile(personid_regexp
.format(name
)).search(ajax
).group(0) for guid
, name
in usernames
]
47 for n
, line
in enumerate(personids
):
49 while line
[i
].isdigit():
52 personids
[n
] = (usernames
[n
][1], id)
55 for name
, id in personids
:
56 if re
.compile(method_regexp
.format(id, self
.id)).search(ajax
): users_in_aspect
.append(name
)
59 for i
, user
in enumerate(usernames
):
61 if name
in users_in_aspect
:
65 def addUser(self
, user_id
):
66 """Add user to current aspect.
68 :param user_id: user to add to aspect
71 data
= {'authenticity_token': self
._connection
.get_token(),
75 request
= self
._connection
.post('aspect_memberships.json', data
=data
)
77 if request
.status_code
== 400:
78 raise Exception('duplicate record, user already exists in aspect: {0}'.format(request
.status_code
))
79 elif request
.status_code
== 404:
80 raise Exception('user not found from this pod: {0}'.format(request
.status_code
))
81 elif request
.status_code
!= 200:
82 raise Exception('wrong status code: {0}'.format(request
.status_code
))
85 def removeUser(self
, user_id
):
86 """Remove user from current aspect.
88 :param user_id: user to remove from aspect
91 data
= {'authenticity_token': self
._connection
.get_token(),
95 request
= self
.connection
.delete('aspect_memberships/{0}.json'.format(self
.id), data
=data
)
97 if request
.status_code
!= 200:
98 raise Exception('wrong status code: {0}'.format(request
.status_code
))
102 class Notification():
103 """This class represents single notification.
105 _who_regexp
= re
.compile(r
'/people/[0-9a-z]+" class=\'hovercardable
')
106 _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
')
108 def __init__(self, connection, data):
109 self._connection = connection
110 self.type = list(data.keys())[0]
111 self.data = data[self.type]
112 self.id = self.data['id']
113 self.unread = self.data['unread
']
115 def __getitem__(self, key):
116 """Returns a key from notification data.
118 return self.data[key]
121 """Returns notification note.
123 string = re.sub('</?
[a
-z
]+( *[a
-z_
-]+=["\'][\w():.,!?#/\- ]*["\'])* */?
>', '', self.data['note_html
'])
124 string = string.strip().split('\n')[0]
125 while ' ' in string: string = string.replace(' ', ' ')
129 """Returns notification note with more details.
131 return '{0}
: {1}
'.format(self.when(), str(self))
134 """Returns list of guids of the users who caused you to get the notification.
136 return [who[8:24] for who in self._who_regexp.findall(self.data['note_html
'])]
139 """Returns UTC time as found in note_html.
141 return self._when_regexp.search(self.data['note_html
']).group(0)
143 def mark(self, unread=False):
144 """Marks notification to read/unread.
145 Marks notification to read if `unread` is False.
146 Marks notification to unread if `unread` is True.
148 :param unread: which state set for notification
151 headers = {'x
-csrf
-token
': self._connection.get_token()}
152 params = {'set_unread
': json.dumps(unread)}
153 self._connection.put('notifications
/{0}
'.format(self['id']), params=params, headers=headers)
154 self.data['unread
'] = unread
158 """This class represents a post.
161 Remember that you need to have access to the post.
163 def __init__(self, post_id, connection):
165 :param post_id: id or guid of the post
167 :param connection: connection object used to authenticate
168 :type connection: connection.Connection
170 self._connection = connection
171 self.post_id = post_id
174 """Returns string containing more information then str().
176 data = self.get_data()
177 return '{0}
({1}
): {2}
'.format(data['author
']['name
'], data['author
']['diaspora_id
'], data['text
'])
180 """Returns text of a post.
182 return self.get_data()['text
']
185 """This function retrieves data of the post.
187 r = self._connection.get('posts
/{0}
.json
'.format(self.post_id))
188 if r.status_code != 200:
189 raise Exception('wrong status code
: {0}
'.format(r.status_code))
193 """This function likes a post.
194 It abstracts the 'Like
' functionality.
196 :returns: dict -- json formatted like object.
198 data = {'authenticity_token
': self._connection.get_token()}
200 r = self._connection.post('posts
/{0}
/likes
'.format(self.post_id),
202 headers={'accept
': 'application
/json
'})
204 if r.status_code != 201:
205 raise Exception('{0}
: Post could
not be liked
.'
206 .format(r.status_code))
210 def delete_like(self):
211 """This function removes a like from a post
213 data = {'authenticity_token
': self._connection.get_token()}
215 post_data = self.get_data()
217 r = self._connection.delete('posts
/{0}
/likes
/{1}
'
218 .format(self.post_id,
219 post_data['interactions
']
223 if r.status_code != 204:
224 raise Exception('{0}
: Like could
not be removed
.'
225 .format(r.status_code))
228 """This function reshares a post
231 post_data = self.get_data()
233 data = {'root_guid
': post_data['guid
'],
234 'authenticity_token
': self._connection.get_token()}
236 r = self._connection.post('reshares
',
238 headers={'accept
': 'application
/json
'})
240 if r.status_code != 201:
241 raise Exception('{0}
: Post could
not be reshared
.'
242 .format(r.status_code))
246 def comment(self, text):
247 """This function comments on a post
249 :param text: text to comment.
252 data = {'text
': text,
253 'authenticity_token
': self._connection.get_token()}
255 r = self._connection.post('posts
/{0}
/comments
'.format(self.post_id),
257 headers={'accept
': 'application
/json
'})
259 if r.status_code != 201:
260 raise Exception('{0}
: Comment could
not be posted
.'
261 .format(r.status_code))
265 def delete_comment(self, comment_id):
266 """This function removes a comment from a post
268 :param comment_id: id of the comment to remove.
269 :type comment_id: str
271 data = {'authenticity_token
': self._connection.get_token()}
273 r = self._connection.delete('posts
/{0}
/comments
/{1}
'
274 .format(self.post_id,
277 headers={'accept
': 'application
/json
'})
279 if r.status_code != 204:
280 raise Exception('{0}
: Comment could
not be deleted
.'
281 .format(r.status_code))
284 """ This function deletes this post
286 data = {'authenticity_token
': self._connection.get_token()}
287 r = self._connection.delete('posts
/{0}
'.format(self.post_id),
289 headers={'accept
': 'application
/json
'})
290 if r.status_code != 204:
291 raise Exception('{0}
: Post could
not be deleted
'.format(r.status_code))