From eb0fa327c4b3b520e243d7b888724512a905347a Mon Sep 17 00:00:00 2001 From: Lorenz Diener Date: Sun, 28 Apr 2019 21:24:31 +0200 Subject: [PATCH] Add reblog visibility --- mastodon/Mastodon.py | 20 +++- .../test_status_reblog_visibility.yaml | 96 +++++++++++++++++++ tests/test_status.py | 5 + 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 tests/cassettes/test_status_reblog_visibility.yaml diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index dd710b7..3fe3d21 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py @@ -1370,8 +1370,7 @@ class Mastodon: should be marked as sensitive, which hides it by default on the Mastodon web front-end. - The visibility parameter is a string value and matches the visibility - option on the /api/v1/status POST API endpoint. It accepts any of: + The visibility parameter is a string value and accepts any of: 'direct' - post will be visible only to mentioned users 'private' - post will be visible only to followers 'unlisted' - post will be public but not appear on the public timeline @@ -1514,15 +1513,26 @@ class Mastodon: self.__api_request('DELETE', url) @api_version("1.0.0", "2.0.0", __DICT_VERSION_STATUS) - def status_reblog(self, id): + def status_reblog(self, id, visibility=None): """ - Reblog a status. + Reblog / boost a status. + + The visibility parameter functions the same as in `status_post()`_ and + allows you to reduce the visibility of a reblogged status. Returns a `toot dict`_ with a new status that wraps around the reblogged one. """ + params = self.__generate_params(locals(), ['id']) + valid_visibilities = ['private', 'public', 'unlisted', 'direct'] + if 'visibility' in params: + params['visibility'] = params['visibility'].lower() + if params['visibility'] not in valid_visibilities: + raise ValueError('Invalid visibility value! Acceptable ' + 'values are %s' % valid_visibilities) + id = self.__unpack_id(id) url = '/api/v1/statuses/{0}/reblog'.format(str(id)) - return self.__api_request('POST', url) + return self.__api_request('POST', url, params) @api_version("1.0.0", "2.0.0", __DICT_VERSION_STATUS) def status_unreblog(self, id): diff --git a/tests/cassettes/test_status_reblog_visibility.yaml b/tests/cassettes/test_status_reblog_visibility.yaml new file mode 100644 index 0000000..500a68d --- /dev/null +++ b/tests/cassettes/test_status_reblog_visibility.yaml @@ -0,0 +1,96 @@ +interactions: +- request: + body: status=Toot%21 + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] + Connection: [keep-alive] + Content-Length: ['14'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [python-requests/2.18.4] + method: POST + uri: http://localhost:3000/api/v1/statuses + response: + body: {string: '{"id":"102005434139190710","created_at":"2019-04-28T19:23:22.764Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost/users/mastodonpy_test/statuses/102005434139190710","content":"\u003cp\u003eToot!\u003c/p\u003e","url":"http://localhost/@mastodonpy_test/102005434139190710","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":false,"muted":false,"pinned":false,"reblog":null,"application":{"name":"Mastodon.py + test suite","website":null},"account":{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"created_at":"2019-04-27T20:56:20.155Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@mastodonpy_test","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":1,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'} + headers: + Cache-Control: ['max-age=0, private, must-revalidate'] + Content-Type: [application/json; charset=utf-8] + ETag: [W/"5f9216b37a617266e1e57234796c9452"] + Referrer-Policy: [strict-origin-when-cross-origin] + Transfer-Encoding: [chunked] + Vary: ['Accept-Encoding, Origin'] + X-Content-Type-Options: [nosniff] + X-Download-Options: [noopen] + X-Frame-Options: [SAMEORIGIN] + X-Permitted-Cross-Domain-Policies: [none] + X-Request-Id: [9c86d267-e58f-44e5-a529-26b9ff76fc9e] + X-Runtime: ['0.201113'] + X-XSS-Protection: [1; mode=block] + content-length: ['1235'] + status: {code: 200, message: OK} +- request: + body: visibility=unlisted + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] + Connection: [keep-alive] + Content-Length: ['19'] + Content-Type: [application/x-www-form-urlencoded] + User-Agent: [python-requests/2.18.4] + method: POST + uri: http://localhost:3000/api/v1/statuses/102005434139190710/reblog + response: + body: {string: '{"id":"102005434155449471","created_at":"2019-04-28T19:23:23.011Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"unlisted","language":null,"uri":"http://localhost/users/mastodonpy_test/statuses/102005434155449471/activity","content":"\u003cp\u003eRT + \u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost/@mastodonpy_test\" + class=\"u-url mention\"\u003e@\u003cspan\u003emastodonpy_test\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e + Toot!\u003c/p\u003e","url":"http://localhost/@mastodonpy_test/102005434155449471","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":true,"muted":false,"reblog":{"id":"102005434139190710","created_at":"2019-04-28T19:23:22.764Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost/users/mastodonpy_test/statuses/102005434139190710","content":"\u003cp\u003eToot!\u003c/p\u003e","url":"http://localhost/@mastodonpy_test/102005434139190710","replies_count":0,"reblogs_count":1,"favourites_count":0,"favourited":false,"reblogged":true,"muted":false,"pinned":false,"reblog":null,"application":{"name":"Mastodon.py + test suite","website":null},"account":{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"created_at":"2019-04-27T20:56:20.155Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@mastodonpy_test","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":2,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null},"application":null,"account":{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"created_at":"2019-04-27T20:56:20.155Z","note":"\u003cp\u003e\u003c/p\u003e","url":"http://localhost/@mastodonpy_test","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":2,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'} + headers: + Cache-Control: ['max-age=0, private, must-revalidate'] + Content-Type: [application/json; charset=utf-8] + ETag: [W/"2959f64592e5d171090e7ddea7694697"] + Referrer-Policy: [strict-origin-when-cross-origin] + Transfer-Encoding: [chunked] + Vary: ['Accept-Encoding, Origin'] + X-Content-Type-Options: [nosniff] + X-Download-Options: [noopen] + X-Frame-Options: [SAMEORIGIN] + X-Permitted-Cross-Domain-Policies: [none] + X-Request-Id: [cf8be3bc-b130-41f2-b113-19d60a7b7f2a] + X-Runtime: ['0.306052'] + X-XSS-Protection: [1; mode=block] + content-length: ['2613'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] + Connection: [keep-alive] + Content-Length: ['0'] + User-Agent: [python-requests/2.18.4] + method: DELETE + uri: http://localhost:3000/api/v1/statuses/102005434139190710 + response: + body: {string: '{}'} + headers: + Cache-Control: ['max-age=0, private, must-revalidate'] + Content-Type: [application/json; charset=utf-8] + ETag: [W/"7f009dc9f14d1cd3a178123556c5e99c"] + Referrer-Policy: [strict-origin-when-cross-origin] + Transfer-Encoding: [chunked] + Vary: ['Accept-Encoding, Origin'] + X-Content-Type-Options: [nosniff] + X-Download-Options: [noopen] + X-Frame-Options: [SAMEORIGIN] + X-Permitted-Cross-Domain-Policies: [none] + X-Request-Id: [11dfaf76-732a-4a29-a1cf-41a526ad3c9a] + X-Runtime: ['0.031563'] + X-XSS-Protection: [1; mode=block] + content-length: ['2'] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/test_status.py b/tests/test_status.py index 88c59ce..4f6295f 100644 --- a/tests/test_status.py +++ b/tests/test_status.py @@ -49,6 +49,11 @@ def test_status_reblogged_by(status, api): reblogs = api.status_reblogged_by(status['id']) assert reblogs +@pytest.mark.vcr() +def test_status_reblog_visibility(status, api): + reblog_result = api.status_reblog(status['id'], visibility = 'unlisted') + assert reblog_result.visibility == 'unlisted' + @pytest.mark.vcr() def test_status_favourited_by(status, api): api.status_favourite(status['id'])