Add functions to add and remove users to/from aspects
[diaspy.git] / diaspy / client.py
CommitLineData
a993a4b6
MK
1import requests
2import re
3import json
95d2d310 4import diaspy.models
a993a4b6
MK
5
6class Client:
7 """This is the client class to connect to diaspora.
8
a993a4b6
MK
9 """
10
a7661afd
MK
11 def __init__(self, pod, username, password):
12 """
13 :param pod: The complete url of the diaspora pod to use.
14 :type pod: str
15 :param username: The username used to log in.
16 :type username: str
17 :param password: The password used to log in.
18 :type password: str
19
20 """
a993a4b6
MK
21 self._token_regex = re.compile(r'content="(.*?)"\s+name="csrf-token')
22 self.pod = pod
23 self.session = requests.Session()
a7661afd 24 self._login(username, password)
a993a4b6
MK
25
26 def get_token(self):
ae221396
MK
27 """This function gets a token needed for authentication in most cases
28
29 :returns: string -- token used to authenticate
30
31 """
32
a7661afd 33 r = self.session.get(self.pod + '/stream')
a993a4b6
MK
34 token = self._token_regex.search(r.text).group(1)
35 return token
36
a7661afd 37 def _login(self, username, password):
a993a4b6 38 """This function is used to connect to the pod and log in.
a7661afd
MK
39 .. note::
40 This function shouldn't be called manually.
a993a4b6
MK
41 """
42 self._username = username
43 self._password = password
a7661afd 44 r = self.session.get(self.pod + '/users/sign_in')
a993a4b6
MK
45 token = self._token_regex.search(r.text).group(1)
46
47 data = {'user[username]': self._username,
48 'user[password]': self._password,
49 'authenticity_token': token,
50 'commit': ''}
51
a7661afd
MK
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.')
a993a4b6 59
28ca595a 60 def post(self, text, aspect_id='public', photos=None):
a993a4b6
MK
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
95d2d310
MK
68 :returns: diaspy.models.Post -- the Post which has been created
69
a993a4b6
MK
70 """
71 data = {'aspect_ids': aspect_id,
28ca595a
MK
72 'status_message': {'text': text}}
73
74 if photos:
75 data['photos'] = photos
a7661afd
MK
76 r = self.session.post(self.pod +
77 "/status_messages",
28ca595a
MK
78 data=json.dumps(data),
79 headers={'content-type': 'application/json',
80 'accept': 'application/json',
81 'x-csrf-token': self.get_token()})
a7661afd
MK
82 if r.status_code != 201:
83 raise Exception(str(r.status_code) + ': Post could not be posted.')
84
95d2d310 85 return diaspy.models.Post(str(r.json()['id']), self)
a993a4b6
MK
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 """
28ca595a 93 r = self.session.get(self.pod + '/bookmarklet')
a993a4b6
MK
94 regex = re.compile(r'window.current_user_attributes = ({.*})')
95 userdata = json.loads(regex.search(r.text).group(1))
96 return userdata
b356c9f9 97
28ca595a
MK
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', params=params, data=data, headers=headers)
114
115 return r
116
117
118
b356c9f9
MK
119 def get_stream(self):
120 """This functions returns a list of posts found in the stream.
121
122 :returns: list -- list of Post objects.
123
124 """
125
126 data = {'authenticity_token': self.get_token()}
127 r = self.session.get(self.pod + "/stream.json")
128
129 if r.status_code != 200:
130 raise Exception('wrong status code: ' + str(r.status_code))
131
132 stream = r.json()
133
134 posts = []
135
136 for post in stream:
137 posts.append(diaspy.models.Post(str(post['id']), self))
138
139 return posts
33f21ecf
MK
140
141 def get_notifications(self):
142 """This functions returns a list of notifications.
143
144 :returns: list -- list of json formatted notifications
145
146 """
147
148
149 data = {'authenticity_token': self.get_token()}
150 r = self.session.get(self.pod + "/notifications.json")
151
152 if r.status_code != 200:
153 raise Exception('wrong status code: ' + str(r.status_code))
154
155 notifications = r.json()
156 return notifications
3d3dff8f
MK
157
158
159 def get_mentions(self):
160 """This functions returns a list of posts the current user is being mentioned in.
161
162 :returns: list -- list of Post objects
163
164 """
165
166
167 data = {'authenticity_token': self.get_token()}
168 r = self.session.get(self.pod + "/mentions.json")
169
170 if r.status_code != 200:
171 raise Exception('wrong status code: ' + str(r.status_code))
172
173 mentions = r.json()
174
175 posts = []
176
177 for post in mentions:
178 posts.append(diaspy.models.Post(str(post['id']), self))
179
180 return posts
5c2b6162
MK
181
182 def add_user_to_aspect(self, user_id, aspect_id):
183 """ this function adds a user to an aspect.
184
185 :param user_id: User ID
186 :type user_id: str
187 :param aspect_id: Aspect ID
188 :type aspect_id: str
189
190 """
191
192 data = {'authenticity_token': self.get_token(),
193 'aspect_id': aspect_id,
194 'person_id': user_id}
195
196 r = self.session.post(self.pod + '/aspect_memberships.json',
197 data=data)
198
199 if r.status_code != 201:
200 raise Exception('wrong status code: ' + str(r.status_code))
201 return r.json()
202
203 def remove_user_from_aspect(self, user_id, aspect_id):
204 """ this function removes a user from 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.delete(self.pod + '/aspect_memberships/42.json',
218 data=data)
219
220 if r.status_code != 200:
221 raise Exception('wrong status code: ' + str(r.status_code))
222
223 return r.json()