aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenz Diener <[email protected]>2019-04-28 23:12:27 +0200
committerLorenz Diener <[email protected]>2019-04-28 23:12:27 +0200
commit09c03296db1671e80f5e7814045e826f1975fb0b (patch)
tree87e709b3b2b5aa86909bee4db89a04c0340d3d0d
parent3eba3f8835f25800f37b9da18a09429b084effa0 (diff)
downloadmastodon.py-09c03296db1671e80f5e7814045e826f1975fb0b.tar.gz
Polls
-rw-r--r--docs/index.rst41
-rw-r--r--mastodon/Mastodon.py97
-rw-r--r--tests/cassettes/test_poll_illegal_vote.yaml96
-rw-r--r--tests/cassettes/test_polls.yaml184
4 files changed, 401 insertions, 17 deletions
diff --git a/docs/index.rst b/docs/index.rst
index a98eb23..6e798d7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -314,6 +314,7 @@ Toot dicts
314 'replies_count': # The number of replies to this status. 314 'replies_count': # The number of replies to this status.
315 'card': # A preview card for links from the status, if present at time of delivery, 315 'card': # A preview card for links from the status, if present at time of delivery,
316 # as card dict. 316 # as card dict.
317 'poll': # A poll dict if a poll is attached to this status.
317 } 318 }
318 319
319Mention dicts 320Mention dicts
@@ -355,7 +356,29 @@ Scheduled toot dicts
355 }, 356 },
356 'media_attachments': # Array of media dicts for the attachments to the scheduled toot 357 'media_attachments': # Array of media dicts for the attachments to the scheduled toot
357 } 358 }
358 359
360Poll dicts
361~~~~~~~~~~
362.. _poll dict:
363
364.. code-block:: python
365
366 # Returns the following dictionary:
367 mastodon.poll(id)
368 {
369 'id': # The polls ID
370 'expires_at': # The time at which the poll is set to expire
371 'expired': # Boolean denoting whether you can still vote in this poll
372 'multiple': # Boolean indicating whether it is allowed to vote for more than one option
373 'votes_count': # Total number of votes cast in this poll
374 'voted': # Boolean indicating whether the logged-in user has already voted in this poll
375 'options': # The poll options as a list of dicts, each option with a `title` and a
376 # `votes_count` field. `votes_count` can be None if the poll creator has
377 # chosen to hide vote totals until the poll expires and it hasn't yet.
378 'emojis': # List of emoji dicts for all emoji used in answer strings
379 }
380
381
359Conversation dicts 382Conversation dicts
360~~~~~~~~~~~~~~~~~~ 383~~~~~~~~~~~~~~~~~~
361.. _conversation dict: 384.. _conversation dict:
@@ -797,13 +820,19 @@ These functions allow you to get information about single statuses.
797.. automethod:: Mastodon.status_favourited_by 820.. automethod:: Mastodon.status_favourited_by
798.. automethod:: Mastodon.status_card 821.. automethod:: Mastodon.status_card
799 822
800Writing data: Scheduled statuses 823Reading data: Scheduled statuses
801~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
802These functions allow you to get information about scheduled statuses. 825These functions allow you to get information about scheduled statuses.
803 826
804.. automethod:: Mastodon.scheduled_statuses 827.. automethod:: Mastodon.scheduled_statuses
805.. automethod:: Mastodon.scheduled_status 828.. automethod:: Mastodon.scheduled_status
806 829
830Reading data: Polls
831~~~~~~~~~~~~~~~~~~~
832This function allows you to get and refresh information about polls.
833
834.. automethod:: Mastodon.poll
835
807Reading data: Notifications 836Reading data: Notifications
808--------------------------- 837---------------------------
809This function allows you to get information about a users notifications. 838This function allows you to get information about a users notifications.
@@ -913,6 +942,8 @@ interact with already posted statuses.
913.. automethod:: Mastodon.status_post 942.. automethod:: Mastodon.status_post
914.. automethod:: Mastodon.status_reply 943.. automethod:: Mastodon.status_reply
915.. automethod:: Mastodon.toot 944.. automethod:: Mastodon.toot
945.. _make_poll():
946.. automethod:: Mastodon.make_poll
916.. automethod:: Mastodon.status_reblog 947.. automethod:: Mastodon.status_reblog
917.. automethod:: Mastodon.status_unreblog 948.. automethod:: Mastodon.status_unreblog
918.. automethod:: Mastodon.status_favourite 949.. automethod:: Mastodon.status_favourite
@@ -932,6 +963,12 @@ scheduled statuses.
932.. automethod:: Mastodon.scheduled_status_update 963.. automethod:: Mastodon.scheduled_status_update
933.. automethod:: Mastodon.scheduled_status_delete 964.. automethod:: Mastodon.scheduled_status_delete
934 965
966Writing data: Polls
967~~~~~~~~~~~~~~~~~~~
968This function allows you to vote in polls.
969
970.. automethod:: Mastodon.poll_vote
971
935Writing data: Notifications 972Writing data: Notifications
936--------------------------- 973---------------------------
937These functions allow you to clear all or some notifications. 974These functions allow you to clear all or some notifications.
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index 6b3de9a..27acbaa 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -161,8 +161,9 @@ class Mastodon:
161 __DICT_VERSION_MENTION = "1.0.0" 161 __DICT_VERSION_MENTION = "1.0.0"
162 __DICT_VERSION_MEDIA = "2.3.0" 162 __DICT_VERSION_MEDIA = "2.3.0"
163 __DICT_VERSION_ACCOUNT = "2.4.0" 163 __DICT_VERSION_ACCOUNT = "2.4.0"
164 __DICT_VERSION_STATUS = bigger_version(bigger_version(bigger_version(bigger_version("2.5.0", 164 __DICT_VERSION_POLL = "2.8.0"
165 __DICT_VERSION_MEDIA), __DICT_VERSION_ACCOUNT), __DICT_VERSION_APPLICATION), __DICT_VERSION_MENTION) 165 __DICT_VERSION_STATUS = bigger_version(bigger_version(bigger_version(bigger_version(bigger_version("2.8.0",
166 __DICT_VERSION_MEDIA), __DICT_VERSION_ACCOUNT), __DICT_VERSION_APPLICATION), __DICT_VERSION_MENTION), __DICT_VERSION_POLL)
166 __DICT_VERSION_INSTANCE = bigger_version("2.7.2", __DICT_VERSION_ACCOUNT) 167 __DICT_VERSION_INSTANCE = bigger_version("2.7.2", __DICT_VERSION_ACCOUNT)
167 __DICT_VERSION_HASHTAG = "2.3.4" 168 __DICT_VERSION_HASHTAG = "2.3.4"
168 __DICT_VERSION_EMOJI = "2.1.0" 169 __DICT_VERSION_EMOJI = "2.1.0"
@@ -827,6 +828,20 @@ class Mastodon:
827 return self.__api_request('GET', url) 828 return self.__api_request('GET', url)
828 829
829 ### 830 ###
831 # Reading data: Polls
832 ###
833 @api_version("2.8.0", "2.8.0", __DICT_VERSION_POLL)
834 def poll(self, id):
835 """
836 Fetch information about the poll with the given id
837
838 Returns a `poll dict`_.
839 """
840 id = self.__unpack_id(id)
841 url = '/api/v1/polls/{0}'.format(str(id))
842 return self.__api_request('GET', url)
843
844 ###
830 # Reading data: Notifications 845 # Reading data: Notifications
831 ### 846 ###
832 @api_version("1.0.0", "2.6.0", __DICT_VERSION_NOTIFICATION) 847 @api_version("1.0.0", "2.6.0", __DICT_VERSION_NOTIFICATION)
@@ -1367,11 +1382,11 @@ class Mastodon:
1367 ### 1382 ###
1368 # Writing data: Statuses 1383 # Writing data: Statuses
1369 ### 1384 ###
1370 @api_version("1.0.0", "2.7.0", __DICT_VERSION_STATUS) 1385 @api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
1371 def status_post(self, status, in_reply_to_id=None, media_ids=None, 1386 def status_post(self, status, in_reply_to_id=None, media_ids=None,
1372 sensitive=False, visibility=None, spoiler_text=None, 1387 sensitive=False, visibility=None, spoiler_text=None,
1373 language=None, idempotency_key=None, content_type=None, 1388 language=None, idempotency_key=None, content_type=None,
1374 scheduled_at=None): 1389 scheduled_at=None, poll=None):
1375 """ 1390 """
1376 Post a status. Can optionally be in reply to another status and contain 1391 Post a status. Can optionally be in reply to another status and contain
1377 media. 1392 media.
@@ -1412,6 +1427,9 @@ class Mastodon:
1412 (the time must be at least 5 minutes into the future). If this is passed, 1427 (the time must be at least 5 minutes into the future). If this is passed,
1413 status_post returns a `scheduled toot dict`_ instead. 1428 status_post returns a `scheduled toot dict`_ instead.
1414 1429
1430 Pass `poll` to attach a poll to the status. An appropriate object can be
1431 constructed using `make_poll()`_
1432
1415 Specify `content_type` to set the content type of your post on Pleroma. 1433 Specify `content_type` to set the content type of your post on Pleroma.
1416 It accepts 'text/plain' (default), 'text/markdown', and 'text/html'. 1434 It accepts 'text/plain' (default), 'text/markdown', and 'text/html'.
1417 This parameter is not supported on Mastodon servers, but will be 1435 This parameter is not supported on Mastodon servers, but will be
@@ -1466,10 +1484,14 @@ class Mastodon:
1466 if params_initial['content_type'] == None: 1484 if params_initial['content_type'] == None:
1467 del params_initial['content_type'] 1485 del params_initial['content_type']
1468 1486
1487 use_json = False
1488 if not poll is None:
1489 use_json = True
1490
1469 params = self.__generate_params(params_initial, ['idempotency_key']) 1491 params = self.__generate_params(params_initial, ['idempotency_key'])
1470 return self.__api_request('POST', '/api/v1/statuses', params, headers = headers) 1492 return self.__api_request('POST', '/api/v1/statuses', params, headers = headers, use_json = use_json)
1471 1493
1472 @api_version("1.0.0", "2.7.0", __DICT_VERSION_STATUS) 1494 @api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
1473 def toot(self, status): 1495 def toot(self, status):
1474 """ 1496 """
1475 Synonym for `status_post()`_ that only takes the status text as input. 1497 Synonym for `status_post()`_ that only takes the status text as input.
@@ -1480,10 +1502,10 @@ class Mastodon:
1480 """ 1502 """
1481 return self.status_post(status) 1503 return self.status_post(status)
1482 1504
1483 @api_version("1.0.0", "2.7.0", __DICT_VERSION_STATUS) 1505 @api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
1484 def status_reply(self, to_status, status, media_ids=None, sensitive=False, visibility=None, 1506 def status_reply(self, to_status, status, media_ids=None, sensitive=False, visibility=None,
1485 spoiler_text=None, language=None, idempotency_key=None, content_type=None, 1507 spoiler_text=None, language=None, idempotency_key=None, content_type=None,
1486 scheduled_at=None, untag=False): 1508 scheduled_at=None, poll=None, untag=False):
1487 """ 1509 """
1488 Helper function - acts like status_post, but prepends the name of all 1510 Helper function - acts like status_post, but prepends the name of all
1489 the users that are being replied to to the status text and retains 1511 the users that are being replied to to the status text and retains
@@ -1516,8 +1538,22 @@ class Mastodon:
1516 return self.status_post(status, in_reply_to_id = to_status.id, media_ids = media_ids, sensitive = sensitive, 1538 return self.status_post(status, in_reply_to_id = to_status.id, media_ids = media_ids, sensitive = sensitive,
1517 visibility = visibility, spoiler_text = spoiler_text, language = language, 1539 visibility = visibility, spoiler_text = spoiler_text, language = language,
1518 idempotency_key = idempotency_key, content_type = content_type, 1540 idempotency_key = idempotency_key, content_type = content_type,
1519 scheduled_at = scheduled_at) 1541 scheduled_at = scheduled_at, poll = poll)
1520 1542
1543 @api_version("2.8.0", "2.8.0", __DICT_VERSION_POLL)
1544 def make_poll(self, options, expires_in, multiple=False, hide_totals=False):
1545 """
1546 Generate a poll object that can be passed as the `poll` option when posting a status.
1547
1548 options is an array of strings with the poll options (Maximum, by default: 4),
1549 expires_in is the time in seconds for which the poll should be open.
1550 Set multiple to True to allow people to choose more than one answer. Set
1551 hide_totals to True to hide the results of the poll until it has expired.
1552 """
1553 poll_params = locals()
1554 del poll_params["self"]
1555 return poll_params
1556
1521 @api_version("1.0.0", "1.0.0", "1.0.0") 1557 @api_version("1.0.0", "1.0.0", "1.0.0")
1522 def status_delete(self, id): 1558 def status_delete(self, id):
1523 """ 1559 """
@@ -1654,6 +1690,34 @@ class Mastodon:
1654 self.__api_request('DELETE', url) 1690 self.__api_request('DELETE', url)
1655 1691
1656 ### 1692 ###
1693 # Writing data: Polls
1694 ###
1695 @api_version("2.8.0", "2.8.0", __DICT_VERSION_POLL)
1696 def poll_vote(self, id, choices):
1697 """
1698 Vote in the given poll.
1699
1700 `choices` is the index of the choice you wish to register a vote for
1701 (i.e. its index in the corresponding polls `options` field. In case
1702 of a poll that allows selection of more than one option, a list of
1703 indices can be passed.
1704
1705 You can only submit choices for any given poll once in case of
1706 single-option polls, or only once per option in case of multi-option
1707 polls.
1708
1709 Returns the updated `poll dict`_
1710 """
1711 id = self.__unpack_id(id)
1712 if not isinstance(choices, list):
1713 choices = [choices]
1714 params = self.__generate_params(locals(), ['id'])
1715
1716 url = '/api/v1/polls/{0}/votes'.format(id)
1717 self.__api_request('POST', url, params)
1718
1719
1720 ###
1657 # Writing data: Notifications 1721 # Writing data: Notifications
1658 ### 1722 ###
1659 @api_version("1.0.0", "1.0.0", "1.0.0") 1723 @api_version("1.0.0", "1.0.0", "1.0.0")
@@ -2480,7 +2544,7 @@ class Mastodon:
2480 isotime = isotime[:-2] + ":" + isotime[-2:] 2544 isotime = isotime[:-2] + ":" + isotime[-2:]
2481 return isotime 2545 return isotime
2482 2546
2483 def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, do_ratelimiting=True): 2547 def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, do_ratelimiting=True, use_json = False):
2484 """ 2548 """
2485 Internal API request helper. 2549 Internal API request helper.
2486 """ 2550 """
@@ -2527,11 +2591,14 @@ class Mastodon:
2527 try: 2591 try:
2528 kwargs = dict(headers=headers, files=files, 2592 kwargs = dict(headers=headers, files=files,
2529 timeout=self.request_timeout) 2593 timeout=self.request_timeout)
2530 if method == 'GET': 2594 if use_json == False:
2531 kwargs['params'] = params 2595 if method == 'GET':
2596 kwargs['params'] = params
2597 else:
2598 kwargs['data'] = params
2532 else: 2599 else:
2533 kwargs['data'] = params 2600 kwargs['json'] = params
2534 2601
2535 response_object = self.session.request( 2602 response_object = self.session.request(
2536 method, self.api_base_url + endpoint, **kwargs) 2603 method, self.api_base_url + endpoint, **kwargs)
2537 except Exception as e: 2604 except Exception as e:
diff --git a/tests/cassettes/test_poll_illegal_vote.yaml b/tests/cassettes/test_poll_illegal_vote.yaml
new file mode 100644
index 0000000..72482b9
--- /dev/null
+++ b/tests/cassettes/test_poll_illegal_vote.yaml
@@ -0,0 +1,96 @@
1interactions:
2- request:
3 body: '{"poll": {"hide_totals": false, "multiple": false, "expires_in": 300, "options":
4 ["four twenty", "sixty-nine"]}, "status": "nice"}'
5 headers:
6 Accept: ['*/*']
7 Accept-Encoding: ['gzip, deflate']
8 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2]
9 Connection: [keep-alive]
10 Content-Length: ['130']
11 Content-Type: [application/json]
12 User-Agent: [python-requests/2.18.4]
13 method: POST
14 uri: http://localhost:3000/api/v1/statuses
15 response:
16 body: {string: '{"id":"102005835304968136","created_at":"2019-04-28T21:05:24.088Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"en","uri":"http://localhost/users/admin/statuses/102005835304968136","content":"\u003cp\u003enice\u003c/p\u003e","url":"http://localhost/@admin/102005835304968136","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":false,"muted":false,"pinned":false,"reblog":null,"application":{"name":"Mastodon.py
17 test suite","website":null},"account":{"id":"1","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"created_at":"2019-04-27T18:52:42.626Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@admin","avatar":"http://localhost/avatars/original/missing.png","avatar_static":"http://localhost/avatars/original/missing.png","header":"http://localhost/headers/original/missing.png","header_static":"http://localhost/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":25,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":{"id":"16","expires_at":"2019-04-28T21:10:24.070Z","expired":false,"multiple":false,"votes_count":0,"voted":true,"options":[{"title":"four
18 twenty","votes_count":0},{"title":"sixty-nine","votes_count":0}],"emojis":[]}}'}
19 headers:
20 Cache-Control: ['max-age=0, private, must-revalidate']
21 Content-Type: [application/json; charset=utf-8]
22 ETag: [W/"cb8935a9ac8d3dea6609462bbce81c7d"]
23 Referrer-Policy: [strict-origin-when-cross-origin]
24 Transfer-Encoding: [chunked]
25 Vary: ['Accept-Encoding, Origin']
26 X-Content-Type-Options: [nosniff]
27 X-Download-Options: [noopen]
28 X-Frame-Options: [SAMEORIGIN]
29 X-Permitted-Cross-Domain-Policies: [none]
30 X-Request-Id: [13adc429-bd63-4a6c-8afa-e52db1b58762]
31 X-Runtime: ['0.342656']
32 X-XSS-Protection: [1; mode=block]
33 content-length: ['1383']
34 status: {code: 200, message: OK}
35- request:
36 body: choices%5B%5D=1
37 headers:
38 Accept: ['*/*']
39 Accept-Encoding: ['gzip, deflate']
40 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
41 Connection: [keep-alive]
42 Content-Length: ['15']
43 Content-Type: [application/x-www-form-urlencoded]
44 User-Agent: [python-requests/2.18.4]
45 method: POST
46 uri: http://localhost:3000/api/v1/polls/16/votes
47 response:
48 body: {string: '{"id":"16","expires_at":"2019-04-28T21:10:24.070Z","expired":false,"multiple":false,"votes_count":1,"voted":true,"options":[{"title":"four
49 twenty","votes_count":0},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'}
50 headers:
51 Cache-Control: ['max-age=0, private, must-revalidate']
52 Content-Type: [application/json; charset=utf-8]
53 ETag: [W/"96d62a6ad640c2c992e83b4bffc10c7b"]
54 Referrer-Policy: [strict-origin-when-cross-origin]
55 Transfer-Encoding: [chunked]
56 Vary: ['Accept-Encoding, Origin']
57 X-Content-Type-Options: [nosniff]
58 X-Download-Options: [noopen]
59 X-Frame-Options: [SAMEORIGIN]
60 X-Permitted-Cross-Domain-Policies: [none]
61 X-Request-Id: [d7715baa-8b11-47b3-bc72-401b22f6296c]
62 X-Runtime: ['0.167098']
63 X-XSS-Protection: [1; mode=block]
64 content-length: ['216']
65 status: {code: 200, message: OK}
66- request:
67 body: choices%5B%5D=0
68 headers:
69 Accept: ['*/*']
70 Accept-Encoding: ['gzip, deflate']
71 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
72 Connection: [keep-alive]
73 Content-Length: ['15']
74 Content-Type: [application/x-www-form-urlencoded]
75 User-Agent: [python-requests/2.18.4]
76 method: POST
77 uri: http://localhost:3000/api/v1/polls/16/votes
78 response:
79 body: {string: "{\"error\":\"\u30D0\u30EA\u30C7\u30FC\u30B7\u30E7\u30F3\u306B\u5931\u6557\u3057\u307E\u3057\u305F:
80 \u3053\u306E\u30A2\u30F3\u30B1\u30FC\u30C8\u306B\u306F\u6295\u7968\u6E08\u307F\u3067\u3059\"}"}
81 headers:
82 Cache-Control: [no-cache]
83 Content-Type: [application/json; charset=utf-8]
84 Referrer-Policy: [strict-origin-when-cross-origin]
85 Transfer-Encoding: [chunked]
86 Vary: ['Accept-Encoding, Origin']
87 X-Content-Type-Options: [nosniff]
88 X-Download-Options: [noopen]
89 X-Frame-Options: [SAMEORIGIN]
90 X-Permitted-Cross-Domain-Policies: [none]
91 X-Request-Id: [846275ac-e205-4fb2-8132-edeef42a2ff2]
92 X-Runtime: ['0.101521']
93 X-XSS-Protection: [1; mode=block]
94 content-length: ['101']
95 status: {code: 422, message: Unprocessable Entity}
96version: 1
diff --git a/tests/cassettes/test_polls.yaml b/tests/cassettes/test_polls.yaml
new file mode 100644
index 0000000..6132074
--- /dev/null
+++ b/tests/cassettes/test_polls.yaml
@@ -0,0 +1,184 @@
1interactions:
2- request:
3 body: '{"poll": {"hide_totals": false, "multiple": true, "expires_in": 300, "options":
4 ["four twenty", "sixty-nine"]}, "status": "nice"}'
5 headers:
6 Accept: ['*/*']
7 Accept-Encoding: ['gzip, deflate']
8 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2]
9 Connection: [keep-alive]
10 Content-Length: ['129']
11 Content-Type: [application/json]
12 User-Agent: [python-requests/2.18.4]
13 method: POST
14 uri: http://localhost:3000/api/v1/statuses
15 response:
16 body: {string: '{"id":"102005835265128615","created_at":"2019-04-28T21:05:23.464Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"en","uri":"http://localhost/users/admin/statuses/102005835265128615","content":"\u003cp\u003enice\u003c/p\u003e","url":"http://localhost/@admin/102005835265128615","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":false,"muted":false,"pinned":false,"reblog":null,"application":{"name":"Mastodon.py
17 test suite","website":null},"account":{"id":"1","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"created_at":"2019-04-27T18:52:42.626Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@admin","avatar":"http://localhost/avatars/original/missing.png","avatar_static":"http://localhost/avatars/original/missing.png","header":"http://localhost/headers/original/missing.png","header_static":"http://localhost/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":25,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":0,"voted":true,"options":[{"title":"four
18 twenty","votes_count":0},{"title":"sixty-nine","votes_count":0}],"emojis":[]}}'}
19 headers:
20 Cache-Control: ['max-age=0, private, must-revalidate']
21 Content-Type: [application/json; charset=utf-8]
22 ETag: [W/"9b51d6b8d66f9e0eb1c833ed6f67df71"]
23 Referrer-Policy: [strict-origin-when-cross-origin]
24 Transfer-Encoding: [chunked]
25 Vary: ['Accept-Encoding, Origin']
26 X-Content-Type-Options: [nosniff]
27 X-Download-Options: [noopen]
28 X-Frame-Options: [SAMEORIGIN]
29 X-Permitted-Cross-Domain-Policies: [none]
30 X-Request-Id: [f11d8fa0-461a-446e-a0f5-20b81af7f6cc]
31 X-Runtime: ['0.157309']
32 X-XSS-Protection: [1; mode=block]
33 content-length: ['1382']
34 status: {code: 200, message: OK}
35- request:
36 body: choices%5B%5D=1
37 headers:
38 Accept: ['*/*']
39 Accept-Encoding: ['gzip, deflate']
40 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
41 Connection: [keep-alive]
42 Content-Length: ['15']
43 Content-Type: [application/x-www-form-urlencoded]
44 User-Agent: [python-requests/2.18.4]
45 method: POST
46 uri: http://localhost:3000/api/v1/polls/15/votes
47 response:
48 body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":1,"voted":true,"options":[{"title":"four
49 twenty","votes_count":0},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'}
50 headers:
51 Cache-Control: ['max-age=0, private, must-revalidate']
52 Content-Type: [application/json; charset=utf-8]
53 ETag: [W/"5b2a849b672ccadf70a2620d4dc1cacb"]
54 Referrer-Policy: [strict-origin-when-cross-origin]
55 Transfer-Encoding: [chunked]
56 Vary: ['Accept-Encoding, Origin']
57 X-Content-Type-Options: [nosniff]
58 X-Download-Options: [noopen]
59 X-Frame-Options: [SAMEORIGIN]
60 X-Permitted-Cross-Domain-Policies: [none]
61 X-Request-Id: [9bfef151-c9a3-44cc-94d4-6ed33e9e7c24]
62 X-Runtime: ['0.079564']
63 X-XSS-Protection: [1; mode=block]
64 content-length: ['215']
65 status: {code: 200, message: OK}
66- request:
67 body: null
68 headers:
69 Accept: ['*/*']
70 Accept-Encoding: ['gzip, deflate']
71 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
72 Connection: [keep-alive]
73 User-Agent: [python-requests/2.18.4]
74 method: GET
75 uri: http://localhost:3000/api/v1/polls/15
76 response:
77 body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":1,"voted":true,"options":[{"title":"four
78 twenty","votes_count":0},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'}
79 headers:
80 Cache-Control: ['max-age=0, private, must-revalidate']
81 Content-Type: [application/json; charset=utf-8]
82 ETag: [W/"5b2a849b672ccadf70a2620d4dc1cacb"]
83 Referrer-Policy: [strict-origin-when-cross-origin]
84 Transfer-Encoding: [chunked]
85 Vary: ['Accept-Encoding, Origin']
86 X-Content-Type-Options: [nosniff]
87 X-Download-Options: [noopen]
88 X-Frame-Options: [SAMEORIGIN]
89 X-Permitted-Cross-Domain-Policies: [none]
90 X-Request-Id: [f6a54825-bd65-49b0-a83f-39ef5124a362]
91 X-Runtime: ['0.043202']
92 X-XSS-Protection: [1; mode=block]
93 content-length: ['215']
94 status: {code: 200, message: OK}
95- request:
96 body: choices%5B%5D=0
97 headers:
98 Accept: ['*/*']
99 Accept-Encoding: ['gzip, deflate']
100 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
101 Connection: [keep-alive]
102 Content-Length: ['15']
103 Content-Type: [application/x-www-form-urlencoded]
104 User-Agent: [python-requests/2.18.4]
105 method: POST
106 uri: http://localhost:3000/api/v1/polls/15/votes
107 response:
108 body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":2,"voted":true,"options":[{"title":"four
109 twenty","votes_count":1},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'}
110 headers:
111 Cache-Control: ['max-age=0, private, must-revalidate']
112 Content-Type: [application/json; charset=utf-8]
113 ETag: [W/"567f9562c02e1a5533bf95d1d4bbdede"]
114 Referrer-Policy: [strict-origin-when-cross-origin]
115 Transfer-Encoding: [chunked]
116 Vary: ['Accept-Encoding, Origin']
117 X-Content-Type-Options: [nosniff]
118 X-Download-Options: [noopen]
119 X-Frame-Options: [SAMEORIGIN]
120 X-Permitted-Cross-Domain-Policies: [none]
121 X-Request-Id: [209f0950-c9c0-4ab8-978f-de3239546a97]
122 X-Runtime: ['0.062952']
123 X-XSS-Protection: [1; mode=block]
124 content-length: ['215']
125 status: {code: 200, message: OK}
126- request:
127 body: null
128 headers:
129 Accept: ['*/*']
130 Accept-Encoding: ['gzip, deflate']
131 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN]
132 Connection: [keep-alive]
133 User-Agent: [python-requests/2.18.4]
134 method: GET
135 uri: http://localhost:3000/api/v1/polls/15
136 response:
137 body: {string: '{"id":"15","expires_at":"2019-04-28T21:10:23.457Z","expired":false,"multiple":true,"votes_count":2,"voted":true,"options":[{"title":"four
138 twenty","votes_count":1},{"title":"sixty-nine","votes_count":1}],"emojis":[]}'}
139 headers:
140 Cache-Control: ['max-age=0, private, must-revalidate']
141 Content-Type: [application/json; charset=utf-8]
142 ETag: [W/"567f9562c02e1a5533bf95d1d4bbdede"]
143 Referrer-Policy: [strict-origin-when-cross-origin]
144 Transfer-Encoding: [chunked]
145 Vary: ['Accept-Encoding, Origin']
146 X-Content-Type-Options: [nosniff]
147 X-Download-Options: [noopen]
148 X-Frame-Options: [SAMEORIGIN]
149 X-Permitted-Cross-Domain-Policies: [none]
150 X-Request-Id: [7caa443c-5605-436f-bae1-f7088dc7db1d]
151 X-Runtime: ['0.037629']
152 X-XSS-Protection: [1; mode=block]
153 content-length: ['215']
154 status: {code: 200, message: OK}
155- request:
156 body: null
157 headers:
158 Accept: ['*/*']
159 Accept-Encoding: ['gzip, deflate']
160 Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2]
161 Connection: [keep-alive]
162 Content-Length: ['0']
163 User-Agent: [python-requests/2.18.4]
164 method: DELETE
165 uri: http://localhost:3000/api/v1/statuses/102005835265128615
166 response:
167 body: {string: '{}'}
168 headers:
169 Cache-Control: ['max-age=0, private, must-revalidate']
170 Content-Type: [application/json; charset=utf-8]
171 ETag: [W/"6e856267241253766a52970611e7487c"]
172 Referrer-Policy: [strict-origin-when-cross-origin]
173 Transfer-Encoding: [chunked]
174 Vary: ['Accept-Encoding, Origin']
175 X-Content-Type-Options: [nosniff]
176 X-Download-Options: [noopen]
177 X-Frame-Options: [SAMEORIGIN]
178 X-Permitted-Cross-Domain-Policies: [none]
179 X-Request-Id: [9a5591f2-fbaa-4f0e-832f-86f5d1b8e6b1]
180 X-Runtime: ['0.044707']
181 X-XSS-Protection: [1; mode=block]
182 content-length: ['2']
183 status: {code: 200, message: OK}
184version: 1
Powered by cgit v1.2.3 (git 2.41.0)