Add get_tag; pep8 fixes
[diaspy.git] / diaspy / client.py
1 import requests
2 import re
3 import json
4 import diaspy.models
5
6
7 class Client:
8 """This is the client class to connect to diaspora.
9
10 """
11
12 def __init__(self, pod, username, password):
13 """
14 :param pod: The complete url of the diaspora pod to use.
15 :type pod: str
16 :param username: The username used to log in.
17 :type username: str
18 :param password: The password used to log in.
19 :type password: str
20
21 """
22 self._token_regex = re.compile(r'content="(.*?)"\s+name="csrf-token')
23 self.pod = pod
24 self.session = requests.Session()
25 self._login(username, password)
26
27 def get_token(self):
28 """This function gets a token needed for authentication in most cases
29
30 :returns: string -- token used to authenticate
31
32 """
33
34 r = self.session.get(self.pod + '/stream')
35 token = self._token_regex.search(r.text).group(1)
36 return token
37
38 def _login(self, username, password):
39 """This function is used to connect to the pod and log in.
40 .. note::
41 This function shouldn't be called manually.
42 """
43 self._username = username
44 self._password = password
45 #r = self.session.get(self.pod + '/users/sign_in')
46 #token = self._token_regex.search(r.text).group(1)
47
48 data = {'user[username]': self._username,
49 'user[password]': self._password,
50 'authenticity_token': self.get_token()}
51
52 r = self.session.post(self.pod +
53 '/users/sign_in',
54 data=data,
55 headers={'accept': 'application/json'})
56
57 if r.status_code != 201:
58 raise Exception(str(r.status_code) + ': Login failed.')
59
60 def post(self, text, aspect_id='public', photos=None):
61 """This function sends a post to an aspect
62
63 :param text: Text to post.
64 :type text: str
65 :param aspect_id: Aspect id to send post to.
66 :type aspect_id: str
67
68 :returns: diaspy.models.Post -- the Post which has been created
69
70 """
71 data = {'aspect_ids': aspect_id,
72 'status_message': {'text': text}}
73
74 if photos:
75 data['photos'] = photos
76 r = self.session.post(self.pod +
77 "/status_messages",
78 data=json.dumps(data),
79 headers={'content-type': 'application/json',
80 'accept': 'application/json',
81 'x-csrf-token': self.get_token()})
82 if r.status_code != 201:
83 raise Exception(str(r.status_code) + ': Post could not be posted.')
84
85 return diaspy.models.Post(str(r.json()['id']), self)
86
87 def get_user_info(self):
88 """This function returns the current user's attributes.
89
90 :returns: dict -- json formatted user info.
91
92 """
93 r = self.session.get(self.pod + '/bookmarklet')
94 regex = re.compile(r'window.current_user_attributes = ({.*})')
95 userdata = json.loads(regex.search(r.text).group(1))
96 return userdata
97
98 def post_picture(self, filename):
99 aspects = self.get_user_info()['aspects']
100 params = {}
101 params['photo[pending]'] = 'true'
102 params['set_profile_image'] = ''
103 params['qqfile'] = filename
104 for i, aspect in enumerate(aspects):
105 params['photo[aspect_ids][%d]' % (i)] = aspect['id']
106
107 data = open(filename, 'rb')
108
109 headers = {'content-type': 'application/octet-stream',
110 'x-csrf-token': self.get_token(),
111 'x-file-name': filename}
112
113 r = self.session.post(self.pod + '/photos',
114 params=params, data=data, headers=headers)
115
116 return r
117
118 def get_stream(self):
119 """This functions returns a list of posts found in the stream.
120
121 :returns: list -- list of Post objects.
122
123 """
124
125 data = {'authenticity_token': self.get_token()}
126 r = self.session.get(self.pod + "/stream.json")
127
128 if r.status_code != 200:
129 raise Exception('wrong status code: ' + str(r.status_code))
130
131 stream = r.json()
132
133 posts = []
134
135 for post in stream:
136 posts.append(diaspy.models.Post(str(post['id']), self))
137
138 return posts
139
140 def get_notifications(self):
141 """This functions returns a list of notifications.
142
143 :returns: list -- list of json formatted notifications
144
145 """
146
147 data = {'authenticity_token': self.get_token()}
148 r = self.session.get(self.pod + "/notifications.json")
149
150 if r.status_code != 200:
151 raise Exception('wrong status code: ' + str(r.status_code))
152
153 notifications = r.json()
154 return notifications
155
156 def get_mentions(self):
157 """This functions returns a list of
158 posts the current user is being mentioned in.
159
160 :returns: list -- list of Post objects
161
162 """
163
164 data = {'authenticity_token': self.get_token()}
165 r = self.session.get(self.pod + "/mentions.json")
166
167 if r.status_code != 200:
168 raise Exception('wrong status code: ' + str(r.status_code))
169
170 mentions = r.json()
171
172 posts = []
173
174 for post in mentions:
175 posts.append(diaspy.models.Post(str(post['id']), self))
176
177 return posts
178
179 def get_tag(self, tag):
180 """This functions returns a list of posts containing the tag.
181 :param tag: Name of the tag
182 :type tag: str
183
184 :returns: list -- list of Post objects
185
186 """
187
188 data = {'authenticity_token': self.get_token()}
189 r = self.session.get(self.pod + '/tags/' + tag + '.json')
190
191 if r.status_code != 200:
192 raise Exception('wrong status code: ' + str(r.status_code))
193
194 tagged_posts = r.json()
195
196 posts = []
197
198 for post in tagged_posts:
199 posts.append(diaspy.models.Post(str(post['id']), self))
200
201 return posts
202
203 def add_user_to_aspect(self, user_id, aspect_id):
204 """ this function adds a user to an aspect.
205
206 :param user_id: User ID
207 :type user_id: str
208 :param aspect_id: Aspect ID
209 :type aspect_id: str
210
211 """
212
213 data = {'authenticity_token': self.get_token(),
214 'aspect_id': aspect_id,
215 'person_id': user_id}
216
217 r = self.session.post(self.pod + '/aspect_memberships.json',
218 data=data)
219
220 if r.status_code != 201:
221 raise Exception('wrong status code: ' + str(r.status_code))
222 return r.json()
223
224 def remove_user_from_aspect(self, user_id, aspect_id):
225 """ this function removes a user from an aspect.
226
227 :param user_id: User ID
228 :type user_id: str
229 :param aspect_id: Aspect ID
230 :type aspect_id: str
231
232 """
233
234 data = {'authenticity_token': self.get_token(),
235 'aspect_id': aspect_id,
236 'person_id': user_id}
237
238 r = self.session.delete(self.pod + '/aspect_memberships/42.json',
239 data=data)
240
241 if r.status_code != 200:
242 raise Exception('wrong status code: ' + str(r.status_code))
243
244 return r.json()
245
246 def add_aspect(self, aspect_name, visible=0):
247 """ This function adds a new aspect.
248 """
249
250 data = {'authenticity_token': self.get_token(),
251 'aspect[name]': aspect_name,
252 'aspect[contacts_visible]': visible}
253
254 r = self.session.post(self.pod + '/aspects',
255 data=data)
256
257 if r.status_code != 200:
258 raise Exception('wrong status code: ' + str(r.status_code))
259
260 def remove_aspect(self, aspect_id):
261 """ This function adds a new aspect.
262 """
263
264 data = {'authenticity_token': self.get_token()}
265
266 r = self.session.delete(self.pod + '/aspects/' + aspect_id,
267 data=data)
268
269 if r.status_code != 404:
270 raise Exception('wrong status code: ' + str(r.status_code))