aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mastodon/admin.py')
-rw-r--r--mastodon/admin.py572
1 files changed, 572 insertions, 0 deletions
diff --git a/mastodon/admin.py b/mastodon/admin.py
new file mode 100644
index 0000000..e2f5f20
--- /dev/null
+++ b/mastodon/admin.py
@@ -0,0 +1,572 @@
1# admin.py - admin / moderation endpoints
2
3from .versions import _DICT_VERSION_ADMIN_ACCOUNT, _DICT_VERSION_REPORT, _DICT_VERSION_HASHTAG, _DICT_VERSION_STATUS, _DICT_VERSION_CARD, \
4 _DICT_VERSION_ADMIN_DOMAIN_BLOCK, _DICT_VERSION_ADMIN_MEASURE, _DICT_VERSION_ADMIN_DIMENSION, _DICT_VERSION_ADMIN_RETENTION
5from .errors import MastodonIllegalArgumentError
6from .utility import api_version
7
8from .internals import Mastodon as Internals
9
10class Mastodon(Internals):
11 ###
12 # Moderation API
13 ###
14 @api_version("2.9.1", "4.0.0", _DICT_VERSION_ADMIN_ACCOUNT)
15 def admin_accounts_v2(self, origin=None, by_domain=None, status=None, username=None, display_name=None, email=None, ip=None,
16 permissions=None, invited_by=None, role_ids=None, max_id=None, min_id=None, since_id=None, limit=None):
17 """
18 Fetches a list of accounts that match given criteria. By default, local accounts are returned.
19
20 * Set `origin` to "local" or "remote" to get only local or remote accounts.
21 * Set `by_domain` to a domain to get only accounts from that domain.
22 * Set `status` to one of "active", "pending", "disabled", "silenced" or "suspended" to get only accounts with that moderation status (default: active)
23 * Set `username` to a string to get only accounts whose username contains this string.
24 * Set `display_name` to a string to get only accounts whose display name contains this string.
25 * Set `email` to an email to get only accounts with that email (this only works on local accounts).
26 * Set `ip` to an ip (as a string, standard v4/v6 notation) to get only accounts whose last active ip is that ip (this only works on local accounts).
27 * Set `permissions` to "staff" to only get accounts with staff permissions.
28 * Set `invited_by` to an account id to get only accounts invited by this user.
29 * Set `role_ids` to a list of role IDs to get only accounts with those roles.
30
31 Returns a list of :ref:`admin account dicts <admin account dicts>`.
32 """
33 if max_id is not None:
34 max_id = self.__unpack_id(max_id, dateconv=True)
35
36 if min_id is not None:
37 min_id = self.__unpack_id(min_id, dateconv=True)
38
39 if since_id is not None:
40 since_id = self.__unpack_id(since_id, dateconv=True)
41
42 if role_ids is not None:
43 if not isinstance(role_ids, list):
44 role_ids = [role_ids]
45 role_ids = list(map(self.__unpack_id, role_ids))
46
47 if invited_by is not None:
48 invited_by = self.__unpack_id(invited_by)
49
50 if permissions is not None and not permissions in ["staff"]:
51 raise MastodonIllegalArgumentError("Permissions must be staff if passed")
52
53 if origin is not None and not origin in ["local", "remote"]:
54 raise MastodonIllegalArgumentError("Origin must be local or remote")
55
56 if status is not None and not status in ["active", "pending", "disabled", "silenced", "suspended"]:
57 raise MastodonIllegalArgumentError("Status must be local or active, pending, disabled, silenced or suspended")
58
59 if not by_domain is None:
60 by_domain = self.__deprotocolize(by_domain)
61
62 params = self.__generate_params(locals())
63 return self.__api_request('GET', '/api/v2/admin/accounts', params)
64
65 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
66 def admin_accounts(self, remote=False, by_domain=None, status='active', username=None, display_name=None, email=None, ip=None, staff_only=False, max_id=None, min_id=None, since_id=None, limit=None):
67 """
68 Currently a synonym for admin_accounts_v1, now deprecated. You are strongly encouraged to use admin_accounts_v2 instead, since this one is kind of bad.
69
70 !!!!! This function may be switched to calling the v2 API in the future. This is your warning. If you want to keep using v1, use it explicitly. !!!!!
71 """
72 return self.admin_accounts_v1(
73 remote=remote,
74 by_domain=by_domain,
75 status=status,
76 username=username,
77 display_name=display_name,
78 email=email,
79 ip=ip,
80 staff_only=staff_only,
81 max_id=max_id,
82 min_id=min_id,
83 since_id=since_id
84 )
85
86 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
87 def admin_accounts_v1(self, remote=False, by_domain=None, status='active', username=None, display_name=None, email=None, ip=None, staff_only=False, max_id=None, min_id=None, since_id=None, limit=None):
88 """
89 Fetches a list of accounts that match given criteria. By default, local accounts are returned.
90
91 * Set `remote` to True to get remote accounts, otherwise local accounts are returned (default: local accounts)
92 * Set `by_domain` to a domain to get only accounts from that domain.
93 * Set `status` to one of "active", "pending", "disabled", "silenced" or "suspended" to get only accounts with that moderation status (default: active)
94 * Set `username` to a string to get only accounts whose username contains this string.
95 * Set `display_name` to a string to get only accounts whose display name contains this string.
96 * Set `email` to an email to get only accounts with that email (this only works on local accounts).
97 * Set `ip` to an ip (as a string, standard v4/v6 notation) to get only accounts whose last active ip is that ip (this only works on local accounts).
98 * Set `staff_only` to True to only get staff accounts (this only works on local accounts).
99
100 Note that setting the boolean parameters to False does not mean "give me users to which this does not apply" but
101 instead means "I do not care if users have this attribute".
102
103 Deprecated in Mastodon version 3.5.0.
104
105 Returns a list of :ref:`admin account dicts <admin account dicts>`.
106 """
107 if max_id is not None:
108 max_id = self.__unpack_id(max_id, dateconv=True)
109
110 if min_id is not None:
111 min_id = self.__unpack_id(min_id, dateconv=True)
112
113 if since_id is not None:
114 since_id = self.__unpack_id(since_id, dateconv=True)
115
116 params = self.__generate_params(locals(), ['remote', 'status', 'staff_only'])
117
118 if remote:
119 params["remote"] = True
120
121 mod_statuses = ["active", "pending", "disabled", "silenced", "suspended"]
122 if not status in mod_statuses:
123 raise ValueError("Invalid moderation status requested.")
124
125 if staff_only:
126 params["staff"] = True
127
128 for mod_status in mod_statuses:
129 if status == mod_status:
130 params[status] = True
131
132 if not by_domain is None:
133 by_domain = self.__deprotocolize(by_domain)
134
135 return self.__api_request('GET', '/api/v1/admin/accounts', params)
136
137 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
138 def admin_account(self, id):
139 """
140 Fetches a single :ref:`admin account dict <admin account dict>` for the user with the given id.
141
142 Returns that dict.
143 """
144 id = self.__unpack_id(id)
145 return self.__api_request('GET', '/api/v1/admin/accounts/{0}'.format(id))
146
147 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
148 def admin_account_enable(self, id):
149 """
150 Reenables login for a local account for which login has been disabled.
151
152 Returns the updated :ref:`admin account dict <admin account dict>`.
153 """
154 id = self.__unpack_id(id)
155 return self.__api_request('POST', '/api/v1/admin/accounts/{0}/enable'.format(id))
156
157 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
158 def admin_account_approve(self, id):
159 """
160 Approves a pending account.
161
162 Returns the updated :ref:`admin account dict <admin account dict>`.
163 """
164 id = self.__unpack_id(id)
165 return self.__api_request('POST', '/api/v1/admin/accounts/{0}/approve'.format(id))
166
167 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
168 def admin_account_reject(self, id):
169 """
170 Rejects and deletes a pending account.
171
172 Returns the updated :ref:`admin account dict <admin account dict>` for the account that is now gone.
173 """
174 id = self.__unpack_id(id)
175 return self.__api_request('POST', '/api/v1/admin/accounts/{0}/reject'.format(id))
176
177 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
178 def admin_account_unsilence(self, id):
179 """
180 Unsilences an account.
181
182 Returns the updated :ref:`admin account dict <admin account dict>`.
183 """
184 id = self.__unpack_id(id)
185 return self.__api_request('POST', '/api/v1/admin/accounts/{0}/unsilence'.format(id))
186
187 @api_version("2.9.1", "2.9.1", _DICT_VERSION_ADMIN_ACCOUNT)
188 def admin_account_unsuspend(self, id):
189 """
190 Unsuspends an account.
191
192 Returns the updated :ref:`admin account dict <admin account dict>`.
193 """
194 id = self.__unpack_id(id)
195 return self.__api_request('POST', '/api/v1/admin/accounts/{0}/unsuspend'.format(id))
196
197 @api_version("3.3.0", "3.3.0", _DICT_VERSION_ADMIN_ACCOUNT)
198 def admin_account_delete(self, id):
199 """
200 Delete a local user account.
201
202 The deleted accounts :ref:`admin account dict <admin account dict>`.
203 """
204 id = self.__unpack_id(id)
205 return self.__api_request('DELETE', '/api/v1/admin/accounts/{0}'.format(id))
206
207 @api_version("3.3.0", "3.3.0", _DICT_VERSION_ADMIN_ACCOUNT)
208 def admin_account_unsensitive(self, id):
209 """
210 Unmark an account as force-sensitive.
211
212 Returns the updated :ref:`admin account dict <admin account dict>`.
213 """
214 id = self.__unpack_id(id)
215 return self.__api_request('POST', '/api/v1/admin/accounts/{0}/unsensitive'.format(id))
216
217 @api_version("2.9.1", "2.9.1", "2.9.1")
218 def admin_account_moderate(self, id, action=None, report_id=None, warning_preset_id=None, text=None, send_email_notification=True):
219 """
220 Perform a moderation action on an account.
221
222 Valid actions are:
223 * "disable" - for a local user, disable login.
224 * "silence" - hide the users posts from all public timelines.
225 * "suspend" - irreversibly delete all the user's posts, past and future.
226 * "sensitive" - forcce an accounts media visibility to always be sensitive.
227
228 If no action is specified, the user is only issued a warning.
229
230 Specify the id of a report as `report_id` to close the report with this moderation action as the resolution.
231 Specify `warning_preset_id` to use a warning preset as the notification text to the user, or `text` to specify text directly.
232 If both are specified, they are concatenated (preset first). Note that there is currently no API to retrieve or create
233 warning presets.
234
235 Set `send_email_notification` to False to not send the user an email notification informing them of the moderation action.
236 """
237 if action is None:
238 action = "none"
239
240 if not send_email_notification:
241 send_email_notification = None
242
243 id = self.__unpack_id(id)
244 if report_id is not None:
245 report_id = self.__unpack_id(report_id)
246
247 params = self.__generate_params(locals(), ['id', 'action'])
248
249 params["type"] = action
250
251 self.__api_request(
252 'POST', '/api/v1/admin/accounts/{0}/action'.format(id), params)
253
254 @api_version("2.9.1", "2.9.1", _DICT_VERSION_REPORT)
255 def admin_reports(self, resolved=False, account_id=None, target_account_id=None, max_id=None, min_id=None, since_id=None, limit=None):
256 """
257 Fetches the list of reports.
258
259 Set `resolved` to True to search for resolved reports. `account_id` and `target_account_id`
260 can be used to get reports filed by or about a specific user.
261
262 Returns a list of :ref:`report dicts <report dicts>`.
263 """
264 if max_id is not None:
265 max_id = self.__unpack_id(max_id, dateconv=True)
266
267 if min_id is not None:
268 min_id = self.__unpack_id(min_id, dateconv=True)
269
270 if since_id is not None:
271 since_id = self.__unpack_id(since_id, dateconv=True)
272
273 if account_id is not None:
274 account_id = self.__unpack_id(account_id)
275
276 if target_account_id is not None:
277 target_account_id = self.__unpack_id(target_account_id)
278
279 if not resolved:
280 resolved = None
281
282 params = self.__generate_params(locals())
283 return self.__api_request('GET', '/api/v1/admin/reports', params)
284
285 @api_version("2.9.1", "2.9.1", _DICT_VERSION_REPORT)
286 def admin_report(self, id):
287 """
288 Fetches the report with the given id.
289
290 Returns a :ref:`report dict <report dict>`.
291 """
292 id = self.__unpack_id(id)
293 return self.__api_request('GET', '/api/v1/admin/reports/{0}'.format(id))
294
295 @api_version("2.9.1", "2.9.1", _DICT_VERSION_REPORT)
296 def admin_report_assign(self, id):
297 """
298 Assigns the given report to the logged-in user.
299
300 Returns the updated :ref:`report dict <report dict>`.
301 """
302 id = self.__unpack_id(id)
303 return self.__api_request('POST', '/api/v1/admin/reports/{0}/assign_to_self'.format(id))
304
305 @api_version("2.9.1", "2.9.1", _DICT_VERSION_REPORT)
306 def admin_report_unassign(self, id):
307 """
308 Unassigns the given report from the logged-in user.
309
310 Returns the updated :ref:`report dict <report dict>`.
311 """
312 id = self.__unpack_id(id)
313 return self.__api_request('POST', '/api/v1/admin/reports/{0}/unassign'.format(id))
314
315 @api_version("2.9.1", "2.9.1", _DICT_VERSION_REPORT)
316 def admin_report_reopen(self, id):
317 """
318 Reopens a closed report.
319
320 Returns the updated :ref:`report dict <report dict>`.
321 """
322 id = self.__unpack_id(id)
323 return self.__api_request('POST', '/api/v1/admin/reports/{0}/reopen'.format(id))
324
325 @api_version("2.9.1", "2.9.1", _DICT_VERSION_REPORT)
326 def admin_report_resolve(self, id):
327 """
328 Marks a report as resolved (without taking any action).
329
330 Returns the updated :ref:`report dict <report dict>`.
331 """
332 id = self.__unpack_id(id)
333 return self.__api_request('POST', '/api/v1/admin/reports/{0}/resolve'.format(id))
334
335 @api_version("3.5.0", "3.5.0", _DICT_VERSION_HASHTAG)
336 def admin_trending_tags(self, limit=None):
337 """
338 Admin version of :ref:`trending_tags() <trending_tags()>`. Includes unapproved tags.
339
340 Returns a list of :ref:`hashtag dicts <hashtag dicts>`, sorted by the instance's trending algorithm,
341 descending.
342 """
343 params = self.__generate_params(locals())
344 return self.__api_request('GET', '/api/v1/admin/trends/tags', params)
345
346 @api_version("3.5.0", "3.5.0", _DICT_VERSION_STATUS)
347 def admin_trending_statuses(self):
348 """
349 Admin version of :ref:`trending_statuses() <trending_statuses()>`. Includes unapproved tags.
350
351 Returns a list of :ref:`status dicts <status dicts>`, sorted by the instance's trending algorithm,
352 descending.
353 """
354 params = self.__generate_params(locals())
355 return self.__api_request('GET', '/api/v1/admin/trends/statuses', params)
356
357 @api_version("3.5.0", "3.5.0", _DICT_VERSION_CARD)
358 def admin_trending_links(self):
359 """
360 Admin version of :ref:`trending_links() <trending_links()>`. Includes unapproved tags.
361
362 Returns a list of :ref:`card dicts <card dicts>`, sorted by the instance's trending algorithm,
363 descending.
364 """
365 params = self.__generate_params(locals())
366 return self.__api_request('GET', '/api/v1/admin/trends/links', params)
367
368 @api_version("4.0.0", "4.0.0", _DICT_VERSION_ADMIN_DOMAIN_BLOCK)
369 def admin_domain_blocks(self, id=None, limit:int=None):
370 """
371 Fetches a list of blocked domains. Requires scope `admin:read:domain_blocks`.
372
373 Provide an `id` to fetch a specific domain block based on its database id.
374
375 Returns a list of :ref:`admin domain block dicts <admin domain block dicts>`, raises a `MastodonAPIError` if the specified block does not exist.
376 """
377 if id is not None:
378 id = self.__unpack_id(id)
379 return self.__api_request('GET', '/api/v1/admin/domain_blocks/{0}'.format(id))
380 else:
381 params = self.__generate_params(locals(),['limit'])
382 return self.__api_request('GET', '/api/v1/admin/domain_blocks/', params)
383
384 @api_version("4.0.0", "4.0.0", _DICT_VERSION_ADMIN_DOMAIN_BLOCK)
385 def admin_create_domain_block(self, domain:str, severity:str=None, reject_media:bool=None, reject_reports:bool=None, private_comment:str=None, public_comment:str=None, obfuscate:bool=None):
386 """
387 Perform a moderation action on a domain. Requires scope `admin:write:domain_blocks`.
388
389 Valid severities are:
390 * "silence" - hide all posts from federated timelines and do not show notifications to local users from the remote instance's users unless they are following the remote user.
391 * "suspend" - deny interactions with this instance going forward. This action is reversible.
392 * "limit" - generally used with reject_media=true to force reject media from an instance without silencing or suspending..
393
394 If no action is specified, the domain is only silenced.
395 `domain` is the domain to block. Note that using the top level domain will also imapct all subdomains. ie, example.com will also impact subdomain.example.com.
396 `reject_media` will not download remote media on to your local instance media storage.
397 `reject_reports` ignores all reports from the remote instance.
398 `private_comment` sets a private admin comment for the domain.
399 `public_comment` sets a publicly available comment for this domain, which will be available to local users and may be available to everyone depending on your settings.
400 `obfuscate` censors some part of the domain name. Useful if the domain name contains unwanted words like slurs.
401
402 Returns the new domain block as an :ref:`admin domain block dict <admin domain block dict>`.
403 """
404 if domain is None:
405 raise AttributeError("Must provide a domain to block a domain")
406 params = self.__generate_params(locals())
407 return self.__api_request('POST', '/api/v1/admin/domain_blocks/', params)
408
409 @api_version("4.0.0", "4.0.0", _DICT_VERSION_ADMIN_DOMAIN_BLOCK)
410 def admin_update_domain_block(self, id, severity:str=None, reject_media:bool=None, reject_reports:bool=None, private_comment:str=None, public_comment:str=None, obfuscate:bool=None):
411 """
412 Modify existing moderation action on a domain. Requires scope `admin:write:domain_blocks`.
413
414 Valid severities are:
415 * "silence" - hide all posts from federated timelines and do not show notifications to local users from the remote instance's users unless they are following the remote user.
416 * "suspend" - deny interactions with this instance going forward. This action is reversible.
417 * "limit" - generally used with reject_media=true to force reject media from an instance without silencing or suspending.
418
419 If no action is specified, the domain is only silenced.
420 `domain` is the domain to block. Note that using the top level domain will also imapct all subdomains. ie, example.com will also impact subdomain.example.com.
421 `reject_media` will not download remote media on to your local instance media storage.
422 `reject_reports` ignores all reports from the remote instance.
423 `private_comment` sets a private admin comment for the domain.
424 `public_comment` sets a publicly available comment for this domain, which will be available to local users and may be available to everyone depending on your settings.
425 `obfuscate` censors some part of the domain name. Useful if the domain name contains unwanted words like slurs.
426
427 Returns the modified domain block as an :ref:`admin domain block dict <admin domain block dict>`, raises a `MastodonAPIError` if the specified block does not exist.
428 """
429 if id is None:
430 raise AttributeError("Must provide an id to modify the existing moderation actions on a given domain.")
431 id = self.__unpack_id(id)
432 params = self.__generate_params(locals(), ["id"])
433 return self.__api_request('PUT', '/api/v1/admin/domain_blocks/{0}'.format(id), params)
434
435 @api_version("4.0.0", "4.0.0", _DICT_VERSION_ADMIN_DOMAIN_BLOCK)
436 def admin_delete_domain_block(self, id=None):
437 """
438 Removes moderation action against a given domain. Requires scope `admin:write:domain_blocks`.
439
440 Provide an `id` to remove a specific domain block based on its database id.
441
442 Raises a `MastodonAPIError` if the specified block does not exist.
443 """
444 if id is not None:
445 id = self.__unpack_id(id)
446 self.__api_request('DELETE', '/api/v1/admin/domain_blocks/{0}'.format(id))
447 else:
448 raise AttributeError("You must provide an id of an existing domain block to remove it.")
449
450 @api_version("3.5.0", "3.5.0", _DICT_VERSION_ADMIN_MEASURE)
451 def admin_measures(self, start_at, end_at, active_users=False, new_users=False, interactions=False, opened_reports = False, resolved_reports=False,
452 tag_accounts=None, tag_uses=None, tag_servers=None, instance_accounts=None, instance_media_attachments=None, instance_reports=None,
453 instance_statuses=None, instance_follows=None, instance_followers=None):
454 """
455 Retrieves numerical instance information for the time period (at day granularity) between `start_at` and `end_at`.
456
457 * `active_users`: Pass true to retrieve the number of active users on your instance within the time period
458 * `new_users`: Pass true to retrieve the number of users who joined your instance within the time period
459 * `interactions`: Pass true to retrieve the number of interactions (favourites, boosts, replies) on local statuses within the time period
460 * `opened_reports`: Pass true to retrieve the number of reports filed within the time period
461 * `resolved_reports` = Pass true to retrieve the number of reports resolved within the time period
462 * `tag_accounts`: Pass a tag ID to get the number of accounts which used that tag in at least one status within the time period
463 * `tag_uses`: Pass a tag ID to get the number of statuses which used that tag within the time period
464 * `tag_servers`: Pass a tag ID to to get the number of remote origin servers for statuses which used that tag within the time period
465 * `instance_accounts`: Pass a domain to get the number of accounts originating from that remote domain within the time period
466 * `instance_media_attachments`: Pass a domain to get the amount of space used by media attachments from that remote domain within the time period
467 * `instance_reports`: Pass a domain to get the number of reports filed against accounts from that remote domain within the time period
468 * `instance_statuses`: Pass a domain to get the number of statuses originating from that remote domain within the time period
469 * `instance_follows`: Pass a domain to get the number of accounts from a remote domain followed by that local user within the time period
470 * `instance_followers`: Pass a domain to get the number of local accounts followed by accounts from that remote domain within the time period
471
472 This API call is relatively expensive - watch your servers load if you want to get a lot of statistical data. Especially the instance_statuses stats
473 might take a long time to compute and, in fact, time out.
474
475 There is currently no way to get tag IDs implemented in Mastodon.py, because the Mastodon public API does not implement one. This will be fixed in a future
476 release.
477
478 Returns a list of :ref:`admin measure dicts <admin measure dicts>`.
479 """
480 params_init = locals()
481 keys = []
482 for key in ["active_users", "new_users", "interactions", "opened_reports", "resolved_reports"]:
483 if params_init[key] == True:
484 keys.append(key)
485
486 params = {}
487 for key in ["tag_accounts", "tag_uses", "tag_servers"]:
488 if params_init[key] is not None:
489 keys.append(key)
490 params[key] = {"id": self.__unpack_id(params_init[key])}
491 for key in ["instance_accounts", "instance_media_attachments", "instance_reports", "instance_statuses", "instance_follows", "instance_followers"]:
492 if params_init[key] is not None:
493 keys.append(key)
494 params[key] = {"domain": Mastodon.__deprotocolize(params_init[key]).split("/")[0]}
495
496 if len(keys) == 0:
497 raise MastodonIllegalArgumentError("Must request at least one metric.")
498
499 params["keys"] = keys
500 params["start_at"] = self.__consistent_isoformat_utc(start_at)
501 params["end_at"] = self.__consistent_isoformat_utc(end_at)
502
503 return self.__api_request('POST', '/api/v1/admin/measures', params, use_json=True)
504
505 @api_version("3.5.0", "3.5.0", _DICT_VERSION_ADMIN_DIMENSION)
506 def admin_dimensions(self, start_at, end_at, limit=None, languages=False, sources=False, servers=False, space_usage=False, software_versions=False,
507 tag_servers=None, tag_languages=None, instance_accounts=None, instance_languages=None):
508 """
509 Retrieves primarily categorical instance information for the time period (at day granularity) between `start_at` and `end_at`.
510
511 * `languages`: Pass true to get the most-used languages on this server
512 * `sources`: Pass true to get the most-used client apps on this server
513 * `servers`: Pass true to get the remote servers with the most statuses
514 * `space_usage`: Pass true to get the how much space is used by different components your software stack
515 * `software_versions`: Pass true to get the version numbers for your software stack
516 * `tag_servers`: Pass a tag ID to get the most-common servers for statuses including a trending tag
517 * `tag_languages`: Pass a tag ID to get the most-used languages for statuses including a trending tag
518 * `instance_accounts`: Pass a domain to get the most-followed accounts from a remote server
519 * `instance_languages`: Pass a domain to get the most-used languages from a remote server
520
521 Pass `limit` to set how many results you want on queries where that makes sense.
522
523 This API call is relatively expensive - watch your servers load if you want to get a lot of statistical data.
524
525 There is currently no way to get tag IDs implemented in Mastodon.py, because the Mastodon public API does not implement one. This will be fixed in a future
526 release.
527
528 Returns a list of :ref:`admin dimension dicts <admin dimension dicts>`.
529 """
530 params_init = locals()
531 keys = []
532 for key in ["languages", "sources", "servers", "space_usage", "software_versions"]:
533 if params_init[key] == True:
534 keys.append(key)
535
536 params = {}
537 for key in ["tag_servers", "tag_languages"]:
538 if params_init[key] is not None:
539 keys.append(key)
540 params[key] = {"id": self.__unpack_id(params_init[key])}
541 for key in ["instance_accounts", "instance_languages"]:
542 if params_init[key] is not None:
543 keys.append(key)
544 params[key] = {"domain": Mastodon.__deprotocolize(params_init[key]).split("/")[0]}
545
546 if len(keys) == 0:
547 raise MastodonIllegalArgumentError("Must request at least one dimension.")
548
549 params["keys"] = keys
550 if limit is not None:
551 params["limit"] = limit
552 params["start_at"] = self.__consistent_isoformat_utc(start_at)
553 params["end_at"] = self.__consistent_isoformat_utc(end_at)
554
555 return self.__api_request('POST', '/api/v1/admin/dimensions', params, use_json=True)
556
557 @api_version("3.5.0", "3.5.0", _DICT_VERSION_ADMIN_RETENTION)
558 def admin_retention(self, start_at, end_at, frequency="day"):
559 """
560 Gets user retention statistics (at `frequency` - "day" or "month" - granularity) between `start_at` and `end_at`.
561
562 Returns a list of :ref:`admin retention dicts <admin retention dicts>`
563 """
564 if not frequency in ["day", "month"]:
565 raise MastodonIllegalArgumentError("Frequency must be day or month")
566
567 params = {
568 "start_at": self.__consistent_isoformat_utc(start_at),
569 "end_at": self.__consistent_isoformat_utc(end_at),
570 "frequency": frequency
571 }
572 return self.__api_request('POST', '/api/v1/admin/retention', params) \ No newline at end of file
Powered by cgit v1.2.3 (git 2.41.0)