8 """This is the client class to connect to Diaspora.
11 def __init__(self
, pod
, username
, password
):
13 :param pod: The complete url of the diaspora pod to use.
15 :param username: The username used to log in.
17 :param password: The password used to log in.
20 self
._token
_regex
= re
.compile(r
'content="(.*?)"\s+name="csrf-token')
22 self
.session
= requests
.Session()
24 self
._setlogindata
(username
, password
)
28 """This function gets a token needed for authentication in most cases
30 :returns: string -- token used to authenticate
33 r
= self
.session
.get('{0}/stream'.format(self
.pod
))
34 token
= self
._token
_regex
.search(r
.text
).group(1)
37 def _setlogindata(self
, username
, password
):
38 """This function is used to set data for login.
41 It should be called before _login() function.
43 #r = self.session.get(self.pod + '/users/sign_in')
44 #token = self._token_regex.search(r.text).group(1)
45 self
._username
, self
._password
= username
, password
47 'user[username]': self
._username
,
48 'user[password]': self
._password
,
49 'authenticity_token': self
.get_token(),
53 """This function is used to connect to the pod and log in.
55 r
= self
.session
.post('{0}/users/sign_in'.format(self
.pod
),
56 data
=self
._login
_data
,
57 headers
={'accept': 'application/json'})
59 if r
.status_code
!= 201: raise Exception('{0}: Login failed.'.format(r
.status_code
))
61 def _setpostdata(self
, text
, aspect_id
, photos
):
62 """This function prepares data for posting.
64 :param text: Text to post.
66 :param aspect_id: Aspect id to send post to.
70 data
['aspect_id'] = aspect_id
71 data
['status_message'] = {'text': text
}
72 if photos
: data
['photos'] = photos
73 self
._post
_data
= data
76 """Sends post to an aspect.
78 :returns: diaspy.models.Post -- the Post which has been created
80 r
= self
.session
.post('{0}/status_messages'.format(self
.pod
),
81 data
=json
.dumps(self
._post
_data
),
82 headers
={'content-type': 'application/json',
83 'accept': 'application/json',
84 'x-csrf-token': self
.get_token()})
85 if r
.status_code
!= 201: raise Exception('{0}: Post could not be posted.'.format(r
.status_code
))
87 return diaspy
.models
.Post(str(r
.json()['id']), self
)
89 def post(self
, text
, aspect_id
='public', photos
=None):
90 """This function sends a post to an aspect
92 :param text: Text to post.
94 :param aspect_id: Aspect id to send post to.
97 :returns: diaspy.models.Post -- the Post which has been created
99 self
._setpostdata
(text
, aspect_id
, photos
)
104 def get_user_info(self
):
105 """This function returns the current user's attributes.
107 :returns: dict -- json formatted user info.
110 r
= self
.session
.get('{0}/bookmarklet'.format(self
.pod
))
111 regex
= re
.compile(r
'window.current_user_attributes = ({.*})')
112 userdata
= json
.loads(regex
.search(r
.text
).group(1))
115 def post_picture(self
, filename
):
116 """This method posts a picture to D*.
118 :param filename: Path to picture file.
121 aspects
= self
.get_user_info()['aspects']
123 params
['photo[pending]'] = 'true'
124 params
['set_profile_image'] = ''
125 params
['qqfile'] = filename
126 for i
, aspect
in enumerate(aspects
):
127 params
['photo[aspect_ids][%d]' % (i
)] = aspect
['id']
129 data
= open(filename
, 'rb')
131 headers
= {'content-type': 'application/octet-stream',
132 'x-csrf-token': self
.get_token(),
133 'x-file-name': filename
}
135 r
= self
.session
.post('{0}/photos'.format(self
.pod
),
136 params
=params
, data
=data
, headers
=headers
)
140 def get_stream(self
):
141 """This functions returns a list of posts found in the stream.
143 :returns: list -- list of Post objects.
147 data
= {'authenticity_token': self
.get_token()}
148 r
= self
.session
.get('{0}/stream.json'.format(self
.pod
))
150 if r
.status_code
!= 200:
151 raise Exception('wrong status code: {0}'.format(r
.status_code
))
154 posts
= [ diaspy
.models
.Post(str(post
['id']), self
) for post
in stream
]
158 def get_notifications(self
):
159 """This functions returns a list of notifications.
161 :returns: list -- list of json formatted notifications
165 data
= {'authenticity_token': self
.get_token()}
166 r
= self
.session
.get('{0}/notifications.json'.format(self
.pod
))
168 if r
.status_code
!= 200:
169 raise Exception('wrong status code: {0}'.format(r
.status_code
))
171 notifications
= r
.json()
174 def get_mentions(self
):
175 """This functions returns a list of
176 posts the current user is being mentioned in.
178 :returns: list -- list of Post objects
182 data
= {'authenticity_token': self
.get_token()}
183 r
= self
.session
.get('/mentions.json'.format(self
.pod
))
185 if r
.status_code
!= 200:
186 raise Exception('wrong status code: {0}'.format(r
.status_code
))
189 posts
= [ diaspy
.models
.Post(str(post
['id']), self
) for post
in mentions
]
193 def get_tag(self
, tag
):
194 """This functions returns a list of posts containing the tag.
195 :param tag: Name of the tag
198 :returns: list -- list of Post objects
202 data
= {'authenticity_token': self
.get_token()}
203 r
= self
.session
.get('{0}/tags/{1}.json'.format(self
.pod
, tag
))
205 if r
.status_code
!= 200:
206 raise Exception('wrong status code: {0}'.format(r
.status_code
))
208 tagged_posts
= r
.json()
209 posts
= [ diaspy
.models
.Post(str(post
['id']), self
) for post
in tagged_posts
]
213 def add_user_to_aspect(self
, user_id
, aspect_id
):
214 """ this function adds a user to an aspect.
216 :param user_id: User ID
218 :param aspect_id: Aspect ID
223 data
= {'authenticity_token': self
.get_token(),
224 'aspect_id': aspect_id
,
225 'person_id': user_id
}
227 r
= self
.session
.post('{0}/aspect_memberships.json'.format(self
.pod
),
230 if r
.status_code
!= 201:
231 raise Exception('wrong status code: {0}'.format(r
.status_code
))
234 def remove_user_from_aspect(self
, user_id
, aspect_id
):
235 """ this function removes a user from an aspect.
237 :param user_id: User ID
239 :param aspect_id: Aspect ID
244 data
= {'authenticity_token': self
.get_token(),
245 'aspect_id': aspect_id
,
246 'person_id': user_id
}
248 r
= self
.session
.delete('{0}/aspect_memberships/42.json'.format(self
.pod
),
251 if r
.status_code
!= 200:
252 raise Exception('wrong status code: {0}'.format(r
.status_code
))
256 def add_aspect(self
, aspect_name
, visible
=0):
257 """ This function adds a new aspect.
260 data
= {'authenticity_token': self
.get_token(),
261 'aspect[name]': aspect_name
,
262 'aspect[contacts_visible]': visible
}
264 r
= self
.session
.post('{0}/aspects'.format(self
.pod
),
267 if r
.status_code
!= 200:
268 raise Exception('wrong status code: {0}'.format(r
.status_code
))
270 def remove_aspect(self
, aspect_id
):
271 """ This function adds a new aspect.
274 data
= {'authenticity_token': self
.get_token()}
276 r
= self
.session
.delete('{0}/aspects/{1}'.format(self
.pod
, aspect_id
),
279 if r
.status_code
!= 404:
280 raise Exception('wrong status code: {0}'.format(r
.status_code
))
282 def get_mailbox(self
):
283 """This functions returns a list of messages found in the conversation.
285 :returns: list -- list of Conversation objects.
289 data
= {'authenticity_token': self
.get_token()}
290 r
= self
.session
.get('{0}/conversations.json'.format(self
.pod
))
292 if r
.status_code
!= 200:
293 raise Exception('wrong status code: {0}'.format(r
.status_code
))
296 conversations
= [ diaspy
.conversations
.Conversation(str(conversation
['conversation']['id']), self
) for conversation
in mailbox
]
300 def new_conversation(self
, contacts
, subject
, text
):
301 """ start a new conversation
303 :param contacts: recipients ids, no guids, comma sperated.
305 :param subject: subject of the message.
307 :param text: text of the message.
312 data
= {'contact_ids': contacts
,
313 'conversation[subject]': subject
,
314 'conversation[text]': text
,
316 'authenticity_token': self
.get_token()}
318 r
= self
.session
.post('{0}/conversations/'.format(self
.pod
),
320 headers
={'accept': 'application/json'})
321 if r
.status_code
!= 200:
322 raise Exception('{0}: Conversation could not be started.'.format(r
.status_code
))