kopia lustrzana https://github.com/halcy/Mastodon.py
add status editing
rodzic
6abaff55e7
commit
f3d25fa19d
2
TODO.md
2
TODO.md
|
@ -65,5 +65,5 @@ General improvements that would be good to do before doing another release:
|
||||||
* [ ] Split mastodon.py into parts in some way that makes sense, it's getting very unwieldy
|
* [ ] Split mastodon.py into parts in some way that makes sense, it's getting very unwieldy
|
||||||
* [x] Fix the CI
|
* [x] Fix the CI
|
||||||
* [ ] Get test coverage like, real high
|
* [ ] Get test coverage like, real high
|
||||||
* [ ] Add all those streaming events??
|
* [x] Add all those streaming events??
|
||||||
* [ ] Document return values
|
* [ ] Document return values
|
||||||
|
|
|
@ -876,6 +876,19 @@ Admin account dicts
|
||||||
'account': # The user's account, as a standard user dict
|
'account': # The user's account, as a standard user dict
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status edit dicts
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
.. _status edit dict:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
mastodonstatus_history(id)[0]
|
||||||
|
# Returns the following dictionary
|
||||||
|
{
|
||||||
|
TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
App registration and user authentication
|
App registration and user authentication
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
Before you can use the Mastodon API, you have to register your
|
Before you can use the Mastodon API, you have to register your
|
||||||
|
@ -967,6 +980,8 @@ These functions allow you to get information about single statuses.
|
||||||
.. automethod:: Mastodon.status_reblogged_by
|
.. automethod:: Mastodon.status_reblogged_by
|
||||||
.. automethod:: Mastodon.status_favourited_by
|
.. automethod:: Mastodon.status_favourited_by
|
||||||
.. automethod:: Mastodon.status_card
|
.. automethod:: Mastodon.status_card
|
||||||
|
.. automethod:: Mastodon.status_history
|
||||||
|
.. automethod:: Mastodon.status_source
|
||||||
|
|
||||||
Reading data: Scheduled statuses
|
Reading data: Scheduled statuses
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1142,6 +1157,8 @@ interact with already posted statuses.
|
||||||
.. automethod:: Mastodon.status_bookmark
|
.. automethod:: Mastodon.status_bookmark
|
||||||
.. automethod:: Mastodon.status_unbookmark
|
.. automethod:: Mastodon.status_unbookmark
|
||||||
.. automethod:: Mastodon.status_delete
|
.. automethod:: Mastodon.status_delete
|
||||||
|
.. automethod:: Mastodon.status_update
|
||||||
|
|
||||||
|
|
||||||
Writing data: Scheduled statuses
|
Writing data: Scheduled statuses
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -229,30 +229,25 @@ class Mastodon:
|
||||||
__DICT_VERSION_HASHTAG = "2.3.4"
|
__DICT_VERSION_HASHTAG = "2.3.4"
|
||||||
__DICT_VERSION_EMOJI = "3.0.0"
|
__DICT_VERSION_EMOJI = "3.0.0"
|
||||||
__DICT_VERSION_RELATIONSHIP = "3.3.0"
|
__DICT_VERSION_RELATIONSHIP = "3.3.0"
|
||||||
__DICT_VERSION_NOTIFICATION = bigger_version(bigger_version(
|
__DICT_VERSION_NOTIFICATION = bigger_version(bigger_version("1.0.0", __DICT_VERSION_ACCOUNT), __DICT_VERSION_STATUS)
|
||||||
"1.0.0", __DICT_VERSION_ACCOUNT), __DICT_VERSION_STATUS)
|
|
||||||
__DICT_VERSION_CONTEXT = bigger_version("1.0.0", __DICT_VERSION_STATUS)
|
__DICT_VERSION_CONTEXT = bigger_version("1.0.0", __DICT_VERSION_STATUS)
|
||||||
__DICT_VERSION_LIST = "2.1.0"
|
__DICT_VERSION_LIST = "2.1.0"
|
||||||
__DICT_VERSION_CARD = "3.2.0"
|
__DICT_VERSION_CARD = "3.2.0"
|
||||||
__DICT_VERSION_SEARCHRESULT = bigger_version(bigger_version(bigger_version(
|
__DICT_VERSION_SEARCHRESULT = bigger_version(bigger_version(bigger_version("1.0.0", __DICT_VERSION_ACCOUNT), __DICT_VERSION_STATUS), __DICT_VERSION_HASHTAG)
|
||||||
"1.0.0", __DICT_VERSION_ACCOUNT), __DICT_VERSION_STATUS), __DICT_VERSION_HASHTAG)
|
|
||||||
__DICT_VERSION_ACTIVITY = "2.1.2"
|
__DICT_VERSION_ACTIVITY = "2.1.2"
|
||||||
__DICT_VERSION_REPORT = "2.9.1"
|
__DICT_VERSION_REPORT = "2.9.1"
|
||||||
__DICT_VERSION_PUSH = "2.4.0"
|
__DICT_VERSION_PUSH = "2.4.0"
|
||||||
__DICT_VERSION_PUSH_NOTIF = "2.4.0"
|
__DICT_VERSION_PUSH_NOTIF = "2.4.0"
|
||||||
__DICT_VERSION_FILTER = "2.4.3"
|
__DICT_VERSION_FILTER = "2.4.3"
|
||||||
__DICT_VERSION_CONVERSATION = bigger_version(bigger_version(
|
__DICT_VERSION_CONVERSATION = bigger_version(bigger_version("2.6.0", __DICT_VERSION_ACCOUNT), __DICT_VERSION_STATUS)
|
||||||
"2.6.0", __DICT_VERSION_ACCOUNT), __DICT_VERSION_STATUS)
|
__DICT_VERSION_SCHEDULED_STATUS = bigger_version("2.7.0", __DICT_VERSION_STATUS)
|
||||||
__DICT_VERSION_SCHEDULED_STATUS = bigger_version(
|
|
||||||
"2.7.0", __DICT_VERSION_STATUS)
|
|
||||||
__DICT_VERSION_PREFERENCES = "2.8.0"
|
__DICT_VERSION_PREFERENCES = "2.8.0"
|
||||||
__DICT_VERSION_ADMIN_ACCOUNT = bigger_version(
|
__DICT_VERSION_ADMIN_ACCOUNT = bigger_version("2.9.1", __DICT_VERSION_ACCOUNT)
|
||||||
"2.9.1", __DICT_VERSION_ACCOUNT)
|
|
||||||
__DICT_VERSION_FEATURED_TAG = "3.0.0"
|
__DICT_VERSION_FEATURED_TAG = "3.0.0"
|
||||||
__DICT_VERSION_MARKER = "3.0.0"
|
__DICT_VERSION_MARKER = "3.0.0"
|
||||||
__DICT_VERSION_REACTION = "3.1.0"
|
__DICT_VERSION_REACTION = "3.1.0"
|
||||||
__DICT_VERSION_ANNOUNCEMENT = bigger_version(
|
__DICT_VERSION_ANNOUNCEMENT = bigger_version("3.1.0", __DICT_VERSION_REACTION)
|
||||||
"3.1.0", __DICT_VERSION_REACTION)
|
__DICT_VERSION_STATUS_EDIT = "3.5.0"
|
||||||
|
|
||||||
###
|
###
|
||||||
# Registering apps
|
# Registering apps
|
||||||
|
@ -1797,6 +1792,82 @@ class Mastodon:
|
||||||
###
|
###
|
||||||
# Writing data: Statuses
|
# Writing data: Statuses
|
||||||
###
|
###
|
||||||
|
def __status_internal(self, status, in_reply_to_id=None, media_ids=None,
|
||||||
|
sensitive=False, visibility=None, spoiler_text=None,
|
||||||
|
language=None, idempotency_key=None, content_type=None,
|
||||||
|
scheduled_at=None, poll=None, quote_id=None, edit=False):
|
||||||
|
if quote_id is not None:
|
||||||
|
if self.feature_set != "fedibird":
|
||||||
|
raise MastodonIllegalArgumentError('quote_id is only available with feature set fedibird')
|
||||||
|
quote_id = self.__unpack_id(quote_id)
|
||||||
|
|
||||||
|
if content_type is not None:
|
||||||
|
if self.feature_set != "pleroma":
|
||||||
|
raise MastodonIllegalArgumentError('content_type is only available with feature set pleroma')
|
||||||
|
# It would be better to read this from nodeinfo and cache, but this is easier
|
||||||
|
if not content_type in ["text/plain", "text/html", "text/markdown", "text/bbcode"]:
|
||||||
|
raise MastodonIllegalArgumentError('Invalid content type specified')
|
||||||
|
|
||||||
|
if in_reply_to_id is not None:
|
||||||
|
in_reply_to_id = self.__unpack_id(in_reply_to_id)
|
||||||
|
|
||||||
|
if scheduled_at is not None:
|
||||||
|
scheduled_at = self.__consistent_isoformat_utc(scheduled_at)
|
||||||
|
|
||||||
|
params_initial = locals()
|
||||||
|
|
||||||
|
# Validate poll/media exclusivity
|
||||||
|
if poll is not None:
|
||||||
|
if media_ids is not None and len(media_ids) != 0:
|
||||||
|
raise ValueError(
|
||||||
|
'Status can have media or poll attached - not both.')
|
||||||
|
|
||||||
|
# Validate visibility parameter
|
||||||
|
valid_visibilities = ['private', 'public', 'unlisted', 'direct']
|
||||||
|
if params_initial['visibility'] is None:
|
||||||
|
del params_initial['visibility']
|
||||||
|
else:
|
||||||
|
params_initial['visibility'] = params_initial['visibility'].lower()
|
||||||
|
if params_initial['visibility'] not in valid_visibilities:
|
||||||
|
raise ValueError('Invalid visibility value! Acceptable values are %s' % valid_visibilities)
|
||||||
|
|
||||||
|
if params_initial['language'] is None:
|
||||||
|
del params_initial['language']
|
||||||
|
|
||||||
|
if params_initial['sensitive'] is False:
|
||||||
|
del [params_initial['sensitive']]
|
||||||
|
|
||||||
|
headers = {}
|
||||||
|
if idempotency_key is not None:
|
||||||
|
headers['Idempotency-Key'] = idempotency_key
|
||||||
|
|
||||||
|
if media_ids is not None:
|
||||||
|
try:
|
||||||
|
media_ids_proper = []
|
||||||
|
if not isinstance(media_ids, (list, tuple)):
|
||||||
|
media_ids = [media_ids]
|
||||||
|
for media_id in media_ids:
|
||||||
|
media_ids_proper.append(self.__unpack_id(media_id))
|
||||||
|
except Exception as e:
|
||||||
|
raise MastodonIllegalArgumentError("Invalid media dict: %s" % e)
|
||||||
|
|
||||||
|
params_initial["media_ids"] = media_ids_proper
|
||||||
|
|
||||||
|
if params_initial['content_type'] is None:
|
||||||
|
del params_initial['content_type']
|
||||||
|
|
||||||
|
use_json = False
|
||||||
|
if poll is not None:
|
||||||
|
use_json = True
|
||||||
|
|
||||||
|
params = self.__generate_params(params_initial, ['idempotency_key', 'edit'])
|
||||||
|
if edit is None:
|
||||||
|
# Post
|
||||||
|
return self.__api_request('POST', '/api/v1/statuses', params, headers=headers, use_json=use_json)
|
||||||
|
else:
|
||||||
|
# Edit
|
||||||
|
return self.__api_request('PUT', '/api/v1/statuses/{0}'.format(str(self.__unpack_id(edit))), params, headers=headers, use_json=use_json)
|
||||||
|
|
||||||
@api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
|
@api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
|
||||||
def status_post(self, status, in_reply_to_id=None, media_ids=None,
|
def status_post(self, status, in_reply_to_id=None, media_ids=None,
|
||||||
sensitive=False, visibility=None, spoiler_text=None,
|
sensitive=False, visibility=None, spoiler_text=None,
|
||||||
|
@ -1857,77 +1928,21 @@ class Mastodon:
|
||||||
|
|
||||||
Returns a `toot dict`_ with the new status.
|
Returns a `toot dict`_ with the new status.
|
||||||
"""
|
"""
|
||||||
if quote_id is not None:
|
return self.__status_internal(
|
||||||
if self.feature_set != "fedibird":
|
status,
|
||||||
raise MastodonIllegalArgumentError(
|
in_reply_to_id,
|
||||||
'quote_id is only available with feature set fedibird')
|
media_ids,
|
||||||
quote_id = self.__unpack_id(quote_id)
|
sensitive,
|
||||||
|
visibility,
|
||||||
if content_type is not None:
|
spoiler_text,
|
||||||
if self.feature_set != "pleroma":
|
language,
|
||||||
raise MastodonIllegalArgumentError(
|
idempotency_key,
|
||||||
'content_type is only available with feature set pleroma')
|
content_type,
|
||||||
# It would be better to read this from nodeinfo and cache, but this is easier
|
scheduled_at,
|
||||||
if not content_type in ["text/plain", "text/html", "text/markdown", "text/bbcode"]:
|
poll,
|
||||||
raise MastodonIllegalArgumentError(
|
quote_id,
|
||||||
'Invalid content type specified')
|
edit=None
|
||||||
|
)
|
||||||
if in_reply_to_id is not None:
|
|
||||||
in_reply_to_id = self.__unpack_id(in_reply_to_id)
|
|
||||||
|
|
||||||
if scheduled_at is not None:
|
|
||||||
scheduled_at = self.__consistent_isoformat_utc(scheduled_at)
|
|
||||||
|
|
||||||
params_initial = locals()
|
|
||||||
|
|
||||||
# Validate poll/media exclusivity
|
|
||||||
if poll is not None:
|
|
||||||
if media_ids is not None and len(media_ids) != 0:
|
|
||||||
raise ValueError(
|
|
||||||
'Status can have media or poll attached - not both.')
|
|
||||||
|
|
||||||
# Validate visibility parameter
|
|
||||||
valid_visibilities = ['private', 'public', 'unlisted', 'direct']
|
|
||||||
if params_initial['visibility'] is None:
|
|
||||||
del params_initial['visibility']
|
|
||||||
else:
|
|
||||||
params_initial['visibility'] = params_initial['visibility'].lower()
|
|
||||||
if params_initial['visibility'] not in valid_visibilities:
|
|
||||||
raise ValueError('Invalid visibility value! Acceptable '
|
|
||||||
'values are %s' % valid_visibilities)
|
|
||||||
|
|
||||||
if params_initial['language'] is None:
|
|
||||||
del params_initial['language']
|
|
||||||
|
|
||||||
if params_initial['sensitive'] is False:
|
|
||||||
del [params_initial['sensitive']]
|
|
||||||
|
|
||||||
headers = {}
|
|
||||||
if idempotency_key is not None:
|
|
||||||
headers['Idempotency-Key'] = idempotency_key
|
|
||||||
|
|
||||||
if media_ids is not None:
|
|
||||||
try:
|
|
||||||
media_ids_proper = []
|
|
||||||
if not isinstance(media_ids, (list, tuple)):
|
|
||||||
media_ids = [media_ids]
|
|
||||||
for media_id in media_ids:
|
|
||||||
media_ids_proper.append(self.__unpack_id(media_id))
|
|
||||||
except Exception as e:
|
|
||||||
raise MastodonIllegalArgumentError("Invalid media "
|
|
||||||
"dict: %s" % e)
|
|
||||||
|
|
||||||
params_initial["media_ids"] = media_ids_proper
|
|
||||||
|
|
||||||
if params_initial['content_type'] is None:
|
|
||||||
del params_initial['content_type']
|
|
||||||
|
|
||||||
use_json = False
|
|
||||||
if poll is not None:
|
|
||||||
use_json = True
|
|
||||||
|
|
||||||
params = self.__generate_params(params_initial, ['idempotency_key'])
|
|
||||||
return self.__api_request('POST', '/api/v1/statuses', params, headers=headers, use_json=use_json)
|
|
||||||
|
|
||||||
@api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
|
@api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
|
||||||
def toot(self, status):
|
def toot(self, status):
|
||||||
|
@ -1940,6 +1955,45 @@ class Mastodon:
|
||||||
"""
|
"""
|
||||||
return self.status_post(status)
|
return self.status_post(status)
|
||||||
|
|
||||||
|
@api_version("3.5.0", "3.5.0", __DICT_VERSION_STATUS)
|
||||||
|
def status_update(self, id, status = None, spoiler_text = None, sensitive = None, media_ids = None, poll = None):
|
||||||
|
"""
|
||||||
|
Edit a status. The meanings of the fields are largely the same as in `status_post()`_,
|
||||||
|
though not every field can be edited.
|
||||||
|
|
||||||
|
Note that editing a poll will reset the votes.
|
||||||
|
"""
|
||||||
|
return self.__status_internal(
|
||||||
|
status = status,
|
||||||
|
media_ids = media_ids,
|
||||||
|
sensitive = sensitive,
|
||||||
|
spoiler_text = spoiler_text,
|
||||||
|
poll = poll,
|
||||||
|
edit = id
|
||||||
|
)
|
||||||
|
|
||||||
|
@api_version("3.5.0", "3.5.0", __DICT_VERSION_STATUS_EDIT)
|
||||||
|
def status_history(self, id):
|
||||||
|
"""
|
||||||
|
Returns the edit history of a status as a list of `status edit dicts`_, starting
|
||||||
|
from the original form. Note that this means that a status that has been edited
|
||||||
|
once will have *two* entries in this list, a status that has been edited twice
|
||||||
|
will have three, and so on.
|
||||||
|
"""
|
||||||
|
id = self.__unpack_id(id)
|
||||||
|
return self.__api_request('GET', "/api/v1/statuses/{0}/history".format(str(id)))
|
||||||
|
|
||||||
|
def status_source(self, id):
|
||||||
|
"""
|
||||||
|
Returns the source of a status for editing.
|
||||||
|
|
||||||
|
Return value is a dictionary containing exactly the parameters you could pass to
|
||||||
|
`status_update()`_ to change nothing about the status, except `status` is `text`
|
||||||
|
instead.
|
||||||
|
"""
|
||||||
|
id = self.__unpack_id(id)
|
||||||
|
return self.__api_request('GET', "/api/v1/statuses/{0}/source".format(str(id)))
|
||||||
|
|
||||||
@api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
|
@api_version("1.0.0", "2.8.0", __DICT_VERSION_STATUS)
|
||||||
def status_reply(self, to_status, status, in_reply_to_id=None, media_ids=None,
|
def status_reply(self, to_status, status, in_reply_to_id=None, media_ids=None,
|
||||||
sensitive=False, visibility=None, spoiler_text=None,
|
sensitive=False, visibility=None, spoiler_text=None,
|
||||||
|
|
|
@ -0,0 +1,379 @@
|
||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: status=the+best+editor%3F+why%2C+of+course+it+is+VS+Code
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Length:
|
||||||
|
- '56'
|
||||||
|
Content-Type:
|
||||||
|
- application/x-www-form-urlencoded
|
||||||
|
User-Agent:
|
||||||
|
- tests/v311
|
||||||
|
method: POST
|
||||||
|
uri: http://localhost:3000/api/v1/statuses
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"id":"109384054168698393","created_at":"2022-11-21T22:03:29.362Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109384054168698393","url":"http://localhost:3000/@mastodonpy_test/109384054168698393","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003ethe
|
||||||
|
best editor? why, of course it is VS Code\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||||
|
test suite","website":null},"account":{"id":"109383687546708201","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-21T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":6,"last_status_at":"2022-11-21","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-3UDW6mpgnOTfx5Euaa1LQA=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"8a45eb762bdb11cdd6cd63bfebe39f63"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-RateLimit-Limit:
|
||||||
|
- '300'
|
||||||
|
X-RateLimit-Remaining:
|
||||||
|
- '292'
|
||||||
|
X-RateLimit-Reset:
|
||||||
|
- '2022-11-22T00:00:00.383365Z'
|
||||||
|
X-Request-Id:
|
||||||
|
- e56f662b-28f8-4ba7-9b38-36e71ac7d73c
|
||||||
|
X-Runtime:
|
||||||
|
- '0.033929'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: null
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
User-Agent:
|
||||||
|
- tests/v311
|
||||||
|
method: GET
|
||||||
|
uri: http://localhost:3000/api/v1/statuses/109384054168698393/history
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '[]'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-oKku/pMs24FqYkpW5MkiGQ=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- 4a780264-f947-4745-a5de-7165d8eee3d9
|
||||||
|
X-Runtime:
|
||||||
|
- '0.010494'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: status=the+best+editor%3F+why%2C+of+course+it+is+the+KDE+Advanced+Text+Editor%2C+Kate
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Length:
|
||||||
|
- '85'
|
||||||
|
Content-Type:
|
||||||
|
- application/x-www-form-urlencoded
|
||||||
|
User-Agent:
|
||||||
|
- tests/v311
|
||||||
|
method: PUT
|
||||||
|
uri: http://localhost:3000/api/v1/statuses/109384054168698393
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"id":"109384054168698393","created_at":"2022-11-21T22:03:29.362Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109384054168698393","url":"http://localhost:3000/@mastodonpy_test/109384054168698393","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":"2022-11-21T22:03:29.418Z","favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003ethe
|
||||||
|
best editor? why, of course it is the KDE Advanced Text Editor, Kate\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||||
|
test suite","website":null},"account":{"id":"109383687546708201","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-21T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":6,"last_status_at":"2022-11-21","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-11jMbHJPLcAv+qMX8EK9Eg=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"976b69a807cf9d4601d0c73c8eb249fc"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-RateLimit-Limit:
|
||||||
|
- '300'
|
||||||
|
X-RateLimit-Remaining:
|
||||||
|
- '291'
|
||||||
|
X-RateLimit-Reset:
|
||||||
|
- '2022-11-22T00:00:00.437259Z'
|
||||||
|
X-Request-Id:
|
||||||
|
- 1f4c3ffd-1c13-45ee-a9df-8d7fff11a17c
|
||||||
|
X-Runtime:
|
||||||
|
- '0.033812'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: null
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
User-Agent:
|
||||||
|
- tests/v311
|
||||||
|
method: GET
|
||||||
|
uri: http://localhost:3000/api/v1/statuses/109384054168698393
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"id":"109384054168698393","created_at":"2022-11-21T22:03:29.362Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"public","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/109384054168698393","url":"http://localhost:3000/@mastodonpy_test/109384054168698393","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":"2022-11-21T22:03:29.418Z","favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"content":"\u003cp\u003ethe
|
||||||
|
best editor? why, of course it is the KDE Advanced Text Editor, Kate\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||||
|
test suite","website":null},"account":{"id":"109383687546708201","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-21T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":6,"last_status_at":"2022-11-21","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-/HjTa7cbsYkrasMByN5dRw=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"8d8244c105ccd1fff42ddc2e75976f91"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- 36c0e7e0-064a-42f1-91e0-82c90ebc4456
|
||||||
|
X-Runtime:
|
||||||
|
- '0.030588'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: null
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
User-Agent:
|
||||||
|
- tests/v311
|
||||||
|
method: GET
|
||||||
|
uri: http://localhost:3000/api/v1/statuses/109384054168698393/history
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '[{"content":"\u003cp\u003ethe best editor? why, of course it is VS
|
||||||
|
Code\u003c/p\u003e","spoiler_text":"","sensitive":false,"created_at":"2022-11-21T22:03:29.362Z","account":{"id":"109383687546708201","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-21T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":6,"last_status_at":"2022-11-21","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"emojis":[]},{"content":"\u003cp\u003ethe
|
||||||
|
best editor? why, of course it is the KDE Advanced Text Editor, Kate\u003c/p\u003e","spoiler_text":"","sensitive":false,"created_at":"2022-11-21T22:03:29.418Z","account":{"id":"109383687546708201","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"","locked":true,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-21T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test","avatar":"http://localhost:3000/avatars/original/missing.png","avatar_static":"http://localhost:3000/avatars/original/missing.png","header":"http://localhost:3000/headers/original/missing.png","header_static":"http://localhost:3000/headers/original/missing.png","followers_count":0,"following_count":0,"statuses_count":6,"last_status_at":"2022-11-21","noindex":false,"emojis":[],"fields":[]},"media_attachments":[],"emojis":[]}]'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-mn4VRGJCjg55CXsiLcW5tA=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"e5185ce4a3ebf261210613a8bb85e77e"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- 17896b84-96a0-4ed4-b3a0-8fca353a3725
|
||||||
|
X-Runtime:
|
||||||
|
- '0.016628'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
- request:
|
||||||
|
body: null
|
||||||
|
headers:
|
||||||
|
Accept:
|
||||||
|
- '*/*'
|
||||||
|
Accept-Encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
Authorization:
|
||||||
|
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN_2
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
User-Agent:
|
||||||
|
- tests/v311
|
||||||
|
method: GET
|
||||||
|
uri: http://localhost:3000/api/v1/statuses/109384054168698393/source
|
||||||
|
response:
|
||||||
|
body:
|
||||||
|
string: '{"id":"109384054168698393","text":"the best editor? why, of course
|
||||||
|
it is the KDE Advanced Text Editor, Kate","spoiler_text":""}'
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-store
|
||||||
|
Content-Security-Policy:
|
||||||
|
- 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
|
||||||
|
''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
|
||||||
|
style-src ''self'' http://localhost:3000 ''nonce-1CVpCwMC0PSWzPM4QmGGoA=='';
|
||||||
|
media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
|
||||||
|
https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
|
||||||
|
data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
|
||||||
|
ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
|
||||||
|
''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
|
||||||
|
worker-src ''self'' blob: http://localhost:3000'
|
||||||
|
Content-Type:
|
||||||
|
- application/json; charset=utf-8
|
||||||
|
ETag:
|
||||||
|
- W/"41ed5fd640708627beb7f31b84cb65d3"
|
||||||
|
Referrer-Policy:
|
||||||
|
- strict-origin-when-cross-origin
|
||||||
|
Transfer-Encoding:
|
||||||
|
- chunked
|
||||||
|
Vary:
|
||||||
|
- Accept, Origin
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
X-Request-Id:
|
||||||
|
- b5919220-e51e-4496-80f5-5a17e908702f
|
||||||
|
X-Runtime:
|
||||||
|
- '0.016356'
|
||||||
|
X-XSS-Protection:
|
||||||
|
- 1; mode=block
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
version: 1
|
|
@ -213,3 +213,19 @@ def test_scheduled_status_long_part2(api):
|
||||||
if text in status.content:
|
if text in status.content:
|
||||||
found_status = True
|
found_status = True
|
||||||
assert found_status
|
assert found_status
|
||||||
|
|
||||||
|
@pytest.mark.vcr()
|
||||||
|
def test_status_edit(api, api2):
|
||||||
|
status = api.status_post("the best editor? why, of course it is VS Code")
|
||||||
|
edit_list_1 = api2.status_history(status)
|
||||||
|
status_edited = api.status_update(status, "the best editor? why, of course it is the KDE Advanced Text Editor, Kate")
|
||||||
|
status_result = api2.status(status)
|
||||||
|
edit_list_2 = api2.status_history(status)
|
||||||
|
|
||||||
|
assert len(edit_list_1) == 0
|
||||||
|
assert len(edit_list_2) == 2
|
||||||
|
assert "the best editor? why, of course it is the KDE Advanced Text Editor, Kate" in status_result.content
|
||||||
|
|
||||||
|
source = api2.status_source(status)
|
||||||
|
assert source.text == "the best editor? why, of course it is the KDE Advanced Text Editor, Kate"
|
||||||
|
|
Ładowanie…
Reference in New Issue