aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mastodon/accounts.py')
-rw-r--r--mastodon/accounts.py395
1 files changed, 394 insertions, 1 deletions
diff --git a/mastodon/accounts.py b/mastodon/accounts.py
index 5ecdf93..219edac 100644
--- a/mastodon/accounts.py
+++ b/mastodon/accounts.py
@@ -1,5 +1,10 @@
1# accounts.py - account related endpoints
2
3import collections
4
5from .versions import _DICT_VERSION_ACCOUNT, _DICT_VERSION_STATUS, _DICT_VERSION_RELATIONSHIP, _DICT_VERSION_LIST, _DICT_VERSION_FAMILIAR_FOLLOWERS, _DICT_VERSION_HASHTAG
1from .defaults import _DEFAULT_SCOPES, _SCOPE_SETS 6from .defaults import _DEFAULT_SCOPES, _SCOPE_SETS
2from .error import MastodonIllegalArgumentError, MastodonAPIError 7from .errors import MastodonIllegalArgumentError, MastodonAPIError
3from .utility import api_version 8from .utility import api_version
4 9
5from .internals import Mastodon as Internals 10from .internals import Mastodon as Internals
@@ -105,3 +110,391 @@ class Mastodon(Internals):
105 Only available to the app that the user originally signed up with. 110 Only available to the app that the user originally signed up with.
106 """ 111 """
107 self.__api_request('POST', '/api/v1/emails/confirmations') 112 self.__api_request('POST', '/api/v1/emails/confirmations')
113
114 ###
115 # Reading data: Accounts
116 ###
117 @api_version("1.0.0", "1.0.0", _DICT_VERSION_ACCOUNT)
118 def account(self, id):
119 """
120 Fetch account information by user `id`.
121
122 Does not require authentication for publicly visible accounts.
123
124 Returns a :ref:`account dict <account dict>`.
125 """
126 id = self.__unpack_id(id)
127 url = '/api/v1/accounts/{0}'.format(str(id))
128 return self.__api_request('GET', url)
129
130 @api_version("1.0.0", "2.1.0", _DICT_VERSION_ACCOUNT)
131 def account_verify_credentials(self):
132 """
133 Fetch logged-in user's account information.
134
135 Returns a :ref:`account dict <account dict>` (Starting from 2.1.0, with an additional "source" field).
136 """
137 return self.__api_request('GET', '/api/v1/accounts/verify_credentials')
138
139 @api_version("1.0.0", "2.1.0", _DICT_VERSION_ACCOUNT)
140 def me(self):
141 """
142 Get this user's account. Synonym for `account_verify_credentials()`, does exactly
143 the same thing, just exists becase `account_verify_credentials()` has a confusing
144 name.
145 """
146 return self.account_verify_credentials()
147
148 @api_version("1.0.0", "2.8.0", _DICT_VERSION_STATUS)
149 def account_statuses(self, id, only_media=False, pinned=False, exclude_replies=False, exclude_reblogs=False, tagged=None, max_id=None, min_id=None, since_id=None, limit=None):
150 """
151 Fetch statuses by user `id`. Same options as :ref:`timeline() <timeline()>` are permitted.
152 Returned toots are from the perspective of the logged-in user, i.e.
153 all statuses visible to the logged-in user (including DMs) are
154 included.
155
156 If `only_media` is set, return only statuses with media attachments.
157 If `pinned` is set, return only statuses that have been pinned. Note that
158 as of Mastodon 2.1.0, this only works properly for instance-local users.
159 If `exclude_replies` is set, filter out all statuses that are replies.
160 If `exclude_reblogs` is set, filter out all statuses that are reblogs.
161 If `tagged` is set, return only statuses that are tagged with `tagged`. Only a single tag without a '#' is valid.
162
163 Does not require authentication for Mastodon versions after 2.7.0 (returns
164 publicly visible statuses in that case), for publicly visible accounts.
165
166 Returns a list of :ref:`status dicts <status dicts>`.
167 """
168 id = self.__unpack_id(id)
169 if max_id is not None:
170 max_id = self.__unpack_id(max_id, dateconv=True)
171
172 if min_id is not None:
173 min_id = self.__unpack_id(min_id, dateconv=True)
174
175 if since_id is not None:
176 since_id = self.__unpack_id(since_id, dateconv=True)
177
178 params = self.__generate_params(locals(), ['id'])
179 if not pinned:
180 del params["pinned"]
181 if not only_media:
182 del params["only_media"]
183 if not exclude_replies:
184 del params["exclude_replies"]
185 if not exclude_reblogs:
186 del params["exclude_reblogs"]
187
188 url = '/api/v1/accounts/{0}/statuses'.format(str(id))
189 return self.__api_request('GET', url, params)
190
191 @api_version("1.0.0", "2.6.0", _DICT_VERSION_ACCOUNT)
192 def account_following(self, id, max_id=None, min_id=None, since_id=None, limit=None):
193 """
194 Fetch users the given user is following.
195
196 Returns a list of :ref:`account dicts <account dicts>`.
197 """
198 id = self.__unpack_id(id)
199 if max_id is not None:
200 max_id = self.__unpack_id(max_id, dateconv=True)
201
202 if min_id is not None:
203 min_id = self.__unpack_id(min_id, dateconv=True)
204
205 if since_id is not None:
206 since_id = self.__unpack_id(since_id, dateconv=True)
207
208 params = self.__generate_params(locals(), ['id'])
209 url = '/api/v1/accounts/{0}/following'.format(str(id))
210 return self.__api_request('GET', url, params)
211
212 @api_version("1.0.0", "2.6.0", _DICT_VERSION_ACCOUNT)
213 def account_followers(self, id, max_id=None, min_id=None, since_id=None, limit=None):
214 """
215 Fetch users the given user is followed by.
216
217 Returns a list of :ref:`account dicts <account dicts>`.
218 """
219 id = self.__unpack_id(id)
220 if max_id is not None:
221 max_id = self.__unpack_id(max_id, dateconv=True)
222
223 if min_id is not None:
224 min_id = self.__unpack_id(min_id, dateconv=True)
225
226 if since_id is not None:
227 since_id = self.__unpack_id(since_id, dateconv=True)
228
229 params = self.__generate_params(locals(), ['id'])
230 url = '/api/v1/accounts/{0}/followers'.format(str(id))
231 return self.__api_request('GET', url, params)
232
233 @api_version("1.0.0", "1.4.0", _DICT_VERSION_RELATIONSHIP)
234 def account_relationships(self, id):
235 """
236 Fetch relationship (following, followed_by, blocking, follow requested) of
237 the logged in user to a given account. `id` can be a list.
238
239 Returns a list of :ref:`relationship dicts <relationship dicts>`.
240 """
241 id = self.__unpack_id(id)
242 params = self.__generate_params(locals())
243 return self.__api_request('GET', '/api/v1/accounts/relationships',
244 params)
245
246 @api_version("1.0.0", "2.3.0", _DICT_VERSION_ACCOUNT)
247 def account_search(self, q, limit=None, following=False):
248 """
249 Fetch matching accounts. Will lookup an account remotely if the search term is
250 in the username@domain format and not yet in the database. Set `following` to
251 True to limit the search to users the logged-in user follows.
252
253 Returns a list of :ref:`account dicts <account dicts>`.
254 """
255 params = self.__generate_params(locals())
256
257 if params["following"] == False:
258 del params["following"]
259
260 return self.__api_request('GET', '/api/v1/accounts/search', params)
261
262 @api_version("2.1.0", "2.1.0", _DICT_VERSION_LIST)
263 def account_lists(self, id):
264 """
265 Get all of the logged-in user's lists which the specified user is
266 a member of.
267
268 Returns a list of :ref:`list dicts <list dicts>`.
269 """
270 id = self.__unpack_id(id)
271 params = self.__generate_params(locals(), ['id'])
272 url = '/api/v1/accounts/{0}/lists'.format(str(id))
273 return self.__api_request('GET', url, params)
274
275 @api_version("3.4.0", "3.4.0", _DICT_VERSION_ACCOUNT)
276 def account_lookup(self, acct):
277 """
278 Look up an account from user@instance form (@instance allowed but not required for
279 local accounts). Will only return accounts that the instance already knows about,
280 and not do any webfinger requests. Use `account_search` if you need to resolve users
281 through webfinger from remote.
282
283 Returns an :ref:`account dict <account dict>`.
284 """
285 return self.__api_request('GET', '/api/v1/accounts/lookup', self.__generate_params(locals()))
286
287 @api_version("3.5.0", "3.5.0", _DICT_VERSION_FAMILIAR_FOLLOWERS)
288 def account_familiar_followers(self, id):
289 """
290 Find followers for the account given by id (can be a list) that also follow the
291 logged in account.
292
293 Returns a list of :ref:`familiar follower dicts <familiar follower dicts>`
294 """
295 if not isinstance(id, list):
296 id = [id]
297 for i in range(len(id)):
298 id[i] = self.__unpack_id(id[i])
299 return self.__api_request('GET', '/api/v1/accounts/familiar_followers', {'id': id}, use_json=True)
300
301 ###
302 # Writing data: Accounts
303 ###
304 @api_version("1.0.0", "3.3.0", _DICT_VERSION_RELATIONSHIP)
305 def account_follow(self, id, reblogs=True, notify=False):
306 """
307 Follow a user.
308
309 Set `reblogs` to False to hide boosts by the followed user.
310 Set `notify` to True to get a notification every time the followed user posts.
311
312 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
313 """
314 id = self.__unpack_id(id)
315 params = self.__generate_params(locals(), ["id"])
316
317 if params["reblogs"] is None:
318 del params["reblogs"]
319
320 url = '/api/v1/accounts/{0}/follow'.format(str(id))
321 return self.__api_request('POST', url, params)
322
323 @api_version("1.0.0", "2.1.0", _DICT_VERSION_ACCOUNT)
324 def follows(self, uri):
325 """
326 Follow a remote user by uri (username@domain).
327
328 Returns a :ref:`account dict <account dict>`.
329 """
330 params = self.__generate_params(locals())
331 return self.__api_request('POST', '/api/v1/follows', params)
332
333 @api_version("1.0.0", "1.4.0", _DICT_VERSION_RELATIONSHIP)
334 def account_unfollow(self, id):
335 """
336 Unfollow a user.
337
338 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
339 """
340 id = self.__unpack_id(id)
341 return self.__api_request('POST', '/api/v1/accounts/{0}/unfollow'.format(str(id)))
342
343 @api_version("3.5.0", "3.5.0", _DICT_VERSION_RELATIONSHIP)
344 def account_remove_from_followers(self, id):
345 """
346 Remove a user from the logged in users followers (i.e. make them unfollow the logged in
347 user / "softblock" them).
348
349 Returns a :ref:`relationship dict <relationship dict>` reflecting the updated following status.
350 """
351 id = self.__unpack_id(id)
352 return self.__api_request('POST', '/api/v1/accounts/{0}/remove_from_followers'.format(str(id)))
353
354
355 @api_version("1.0.0", "1.4.0", _DICT_VERSION_RELATIONSHIP)
356 def account_block(self, id):
357 """
358 Block a user.
359
360 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
361 """
362 id = self.__unpack_id(id)
363 url = '/api/v1/accounts/{0}/block'.format(str(id))
364 return self.__api_request('POST', url)
365
366 @api_version("1.0.0", "1.4.0", _DICT_VERSION_RELATIONSHIP)
367 def account_unblock(self, id):
368 """
369 Unblock a user.
370
371 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
372 """
373 id = self.__unpack_id(id)
374 url = '/api/v1/accounts/{0}/unblock'.format(str(id))
375 return self.__api_request('POST', url)
376
377 @api_version("1.1.0", "2.4.3", _DICT_VERSION_RELATIONSHIP)
378 def account_mute(self, id, notifications=True, duration=None):
379 """
380 Mute a user.
381
382 Set `notifications` to False to receive notifications even though the user is
383 muted from timelines. Pass a `duration` in seconds to have Mastodon automatically
384 lift the mute after that many seconds.
385
386 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
387 """
388 id = self.__unpack_id(id)
389 params = self.__generate_params(locals(), ['id'])
390 url = '/api/v1/accounts/{0}/mute'.format(str(id))
391 return self.__api_request('POST', url, params)
392
393 @api_version("1.1.0", "1.4.0", _DICT_VERSION_RELATIONSHIP)
394 def account_unmute(self, id):
395 """
396 Unmute a user.
397
398 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
399 """
400 id = self.__unpack_id(id)
401 url = '/api/v1/accounts/{0}/unmute'.format(str(id))
402 return self.__api_request('POST', url)
403
404 @api_version("1.1.1", "3.1.0", _DICT_VERSION_ACCOUNT)
405 def account_update_credentials(self, display_name=None, note=None,
406 avatar=None, avatar_mime_type=None,
407 header=None, header_mime_type=None,
408 locked=None, bot=None,
409 discoverable=None, fields=None):
410 """
411 Update the profile for the currently logged-in user.
412
413 `note` is the user's bio.
414
415 `avatar` and 'header' are images. As with media uploads, it is possible to either
416 pass image data and a mime type, or a filename of an image file, for either.
417
418 `locked` specifies whether the user needs to manually approve follow requests.
419
420 `bot` specifies whether the user should be set to a bot.
421
422 `discoverable` specifies whether the user should appear in the user directory.
423
424 `fields` can be a list of up to four name-value pairs (specified as tuples) to
425 appear as semi-structured information in the user's profile.
426
427 Returns the updated `account dict` of the logged-in user.
428 """
429 params_initial = collections.OrderedDict(locals())
430
431 # Convert fields
432 if fields is not None:
433 if len(fields) > 4:
434 raise MastodonIllegalArgumentError(
435 'A maximum of four fields are allowed.')
436
437 fields_attributes = []
438 for idx, (field_name, field_value) in enumerate(fields):
439 params_initial['fields_attributes[' +
440 str(idx) + '][name]'] = field_name
441 params_initial['fields_attributes[' +
442 str(idx) + '][value]'] = field_value
443
444 # Clean up params
445 for param in ["avatar", "avatar_mime_type", "header", "header_mime_type", "fields"]:
446 if param in params_initial:
447 del params_initial[param]
448
449 # Create file info
450 files = {}
451 if avatar is not None:
452 files["avatar"] = self.__load_media_file(avatar, avatar_mime_type)
453 if header is not None:
454 files["header"] = self.__load_media_file(header, header_mime_type)
455
456 params = self.__generate_params(params_initial)
457 return self.__api_request('PATCH', '/api/v1/accounts/update_credentials', params, files=files)
458
459 @api_version("2.5.0", "2.5.0", _DICT_VERSION_RELATIONSHIP)
460 def account_pin(self, id):
461 """
462 Pin / endorse a user.
463
464 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
465 """
466 id = self.__unpack_id(id)
467 url = '/api/v1/accounts/{0}/pin'.format(str(id))
468 return self.__api_request('POST', url)
469
470 @api_version("2.5.0", "2.5.0", _DICT_VERSION_RELATIONSHIP)
471 def account_unpin(self, id):
472 """
473 Unpin / un-endorse a user.
474
475 Returns a :ref:`relationship dict <relationship dict>` containing the updated relationship to the user.
476 """
477 id = self.__unpack_id(id)
478 url = '/api/v1/accounts/{0}/unpin'.format(str(id))
479 return self.__api_request('POST', url)
480
481 @api_version("3.2.0", "3.2.0", _DICT_VERSION_RELATIONSHIP)
482 def account_note_set(self, id, comment):
483 """
484 Set a note (visible to the logged in user only) for the given account.
485
486 Returns a :ref:`status dict <status dict>` with the `note` updated.
487 """
488 id = self.__unpack_id(id)
489 params = self.__generate_params(locals(), ["id"])
490 return self.__api_request('POST', '/api/v1/accounts/{0}/note'.format(str(id)), params)
491
492 @api_version("3.3.0", "3.3.0", _DICT_VERSION_HASHTAG)
493 def account_featured_tags(self, id):
494 """
495 Get an account's featured hashtags.
496
497 Returns a list of :ref:`hashtag dicts <hashtag dicts>` (NOT `featured tag dicts`_).
498 """
499 id = self.__unpack_id(id)
500 return self.__api_request('GET', '/api/v1/accounts/{0}/featured_tags'.format(str(id)))
Powered by cgit v1.2.3 (git 2.41.0)