kopia lustrzana https://github.com/halcy/Mastodon.py
translation support
rodzic
e5c00a9229
commit
404ff39a2b
|
@ -37,6 +37,7 @@ v2.0.0 (IN PROGRESS)
|
|||
* Add media attachment editing
|
||||
* Add email domain blocking support (`admin_email_domain_blocks`, `admin_email_domain_block`, `admin_email_domain_block_create`, `admin_email_domain_block_delete`)
|
||||
* Add `instance_extended_description`
|
||||
* Add `instance_translation_languages`, translation support (`status_translate`)
|
||||
|
||||
v1.8.1
|
||||
------
|
||||
|
|
|
@ -84,4 +84,9 @@ Reading
|
|||
|
||||
Writing
|
||||
~~~~~~~
|
||||
.. automethod:: Mastodon.poll_vote
|
||||
.. automethod:: Mastodon.poll_vote
|
||||
|
||||
Translation
|
||||
-----------
|
||||
These functions allow you to get machine translations for statuses, if the instance supports it.
|
||||
.. automethod:: Mastodon.status_translate
|
|
@ -18,7 +18,7 @@ current instance as well as data from the instance-wide profile directory.
|
|||
.. automethod:: Mastodon.instance_nodeinfo
|
||||
.. automethod:: Mastodon.instance_rules
|
||||
.. automethod:: Mastodon.instance_extended_description
|
||||
|
||||
|
||||
Profile directory
|
||||
~~~~~~~~~~~~~~~~~
|
||||
.. automethod:: Mastodon.directory
|
||||
|
@ -59,3 +59,7 @@ These functions allow you to search for users, tags and, when enabled, full text
|
|||
|
||||
.. automethod:: Mastodon.search
|
||||
.. automethod:: Mastodon.search_v2
|
||||
|
||||
Translation support
|
||||
-------------------
|
||||
.. automethod:: Mastodon.instance_translation_languages
|
|
@ -6,7 +6,7 @@ from mastodon.compat import urlparse
|
|||
from mastodon.internals import Mastodon as Internals
|
||||
from mastodon.return_types import Instance, InstanceV2, NonPaginatableList, Activity, Nodeinfo, AttribAccessDict, Rule, Announcement, CustomEmoji, Account, IdType, ExtendedDescription
|
||||
|
||||
from typing import Union, Optional
|
||||
from typing import Union, Optional, Dict, List
|
||||
|
||||
class Mastodon(Internals):
|
||||
###
|
||||
|
@ -206,3 +206,16 @@ class Mastodon(Internals):
|
|||
Retrieve the instance's extended description.
|
||||
"""
|
||||
return self.__api_request('GET', '/api/v1/instance/extended_description', parse=False).decode("utf-8")
|
||||
|
||||
def instance_translation_languages(self) -> Dict[str, List[str]]:
|
||||
"""
|
||||
Retrieve the instance's translation languages.
|
||||
|
||||
Returns a dict with language pairs, where the key is the language code and the value is a list of language codes that the instance can translate that language to.
|
||||
"""
|
||||
ret_value = self.__api_request('GET', '/api/v1/instance/translation_languages')
|
||||
result_real = AttribAccessDict()
|
||||
for key, value in ret_value.items():
|
||||
result_real[key] = NonPaginatableList(value)
|
||||
return result_real
|
||||
|
|
@ -9,7 +9,7 @@ from mastodon.utility import api_version
|
|||
|
||||
from mastodon.internals import Mastodon as Internals
|
||||
from mastodon.return_types import Status, IdType, ScheduledStatus, PreviewCard, Context, NonPaginatableList, Account,\
|
||||
MediaAttachment, Poll, StatusSource, StatusEdit, PaginatableList, PathOrFile
|
||||
MediaAttachment, Poll, StatusSource, StatusEdit, PaginatableList, PathOrFile, Translation
|
||||
|
||||
from typing import Union, Optional, List, Dict, Any, Tuple
|
||||
|
||||
|
@ -570,3 +570,18 @@ class Mastodon(Internals):
|
|||
"""
|
||||
id = self.__unpack_id(id)
|
||||
self.__api_request('DELETE', f'/api/v1/scheduled_statuses/{id}')
|
||||
|
||||
##
|
||||
# Translation
|
||||
##
|
||||
@api_version("4.0.0", "4.0.0")
|
||||
def status_translate(self, id: Union[Status, IdType], lang: Optional[str] = None) -> Translation:
|
||||
"""
|
||||
Translate the status content into some language.
|
||||
|
||||
Raises a MastodonAPIError if the server can't perform the requested translation, for any
|
||||
reason (doesn't support translation, unsupported language pair, etc.).
|
||||
"""
|
||||
id = self.__unpack_id(id)
|
||||
params = self.__generate_params(locals(), ['id'])
|
||||
return self.__api_request('POST', f'/api/v1/statuses/{id}/translate', params)
|
|
@ -0,0 +1,193 @@
|
|||
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:
|
||||
- tests/v311
|
||||
method: POST
|
||||
uri: http://localhost:3000/api/v1/statuses
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"114008596311558624","created_at":"2025-02-15T15:25:22.431Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"private","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/114008596311558624","url":"http://localhost:3000/@mastodonpy_test/114008596311558624","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"content":"\u003cp\u003eToot!\u003c/p\u003e","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"113998801242326861","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John
|
||||
Lennon","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-13T00:00:00.000Z","note":"\u003cp\u003eI
|
||||
walk funny\u003c/p\u003e","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"statuses_count":9,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[{"name":"bread","value":"toasty.","verified_at":null},{"name":"lasagna","value":"no!!!","verified_at":null}]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1638'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"b7efe40a95ee9fc07d42c7656cbdf8ec"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.08, sql.active_record;dur=19.05, cache_generate.active_support;dur=5.82,
|
||||
cache_write.active_support;dur=0.18, instantiation.active_record;dur=1.14,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=10.37,
|
||||
render.active_model_serializers;dur=23.35, process_action.action_controller;dur=79.00
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T18:00:00.477175Z'
|
||||
X-Request-Id:
|
||||
- f44e326a-a840-4685-92b7-008f5552cff8
|
||||
X-Runtime:
|
||||
- '0.103655'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: lang=de
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '7'
|
||||
Content-Type:
|
||||
- application/x-www-form-urlencoded
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: POST
|
||||
uri: http://localhost:3000/api/v1/statuses/114008596311558624/translate
|
||||
response:
|
||||
body:
|
||||
string: '{"error":"This action is not allowed"}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '38'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.02, sql.active_record;dur=1.74, cache_generate.active_support;dur=1.03,
|
||||
cache_write.active_support;dur=0.08, instantiation.active_record;dur=0.58,
|
||||
start_processing.action_controller;dur=0.01, render.active_model_serializers;dur=0.05,
|
||||
process_action.action_controller;dur=45.87
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T15:30:00.565674Z'
|
||||
X-Request-Id:
|
||||
- 3e421f8f-e7eb-4e1c-9d60-6d5d726ab2c1
|
||||
X-Runtime:
|
||||
- '0.081421'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 403
|
||||
message: Forbidden
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '0'
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: DELETE
|
||||
uri: http://localhost:3000/api/v1/statuses/114008596311558624
|
||||
response:
|
||||
body:
|
||||
string: '{"id":"114008596311558624","created_at":"2025-02-15T15:25:22.431Z","in_reply_to_id":null,"in_reply_to_account_id":null,"sensitive":false,"spoiler_text":"","visibility":"private","language":"ja","uri":"http://localhost:3000/users/mastodonpy_test/statuses/114008596311558624","url":"http://localhost:3000/@mastodonpy_test/114008596311558624","replies_count":0,"reblogs_count":0,"favourites_count":0,"edited_at":null,"favourited":false,"reblogged":false,"muted":false,"bookmarked":false,"pinned":false,"text":"Toot!","filtered":[],"reblog":null,"application":{"name":"Mastodon.py
|
||||
test suite","website":null},"account":{"id":"113998801242326861","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John
|
||||
Lennon","locked":true,"bot":false,"discoverable":null,"indexable":false,"group":false,"created_at":"2025-02-13T00:00:00.000Z","note":"\u003cp\u003eI
|
||||
walk funny\u003c/p\u003e","url":"http://localhost:3000/@mastodonpy_test","uri":"http://localhost:3000/users/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":1,"statuses_count":8,"last_status_at":"2025-02-15","hide_collections":null,"noindex":false,"emojis":[],"roles":[],"fields":[{"name":"bread","value":"toasty.","verified_at":null},{"name":"lasagna","value":"no!!!","verified_at":null}]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private, no-store
|
||||
Content-Length:
|
||||
- '1608'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
ETag:
|
||||
- W/"34838106aadb8da6b97b3fb5ba7dc85e"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.05, sql.active_record;dur=7.63, cache_generate.active_support;dur=3.53,
|
||||
cache_write.active_support;dur=0.16, instantiation.active_record;dur=0.61,
|
||||
start_processing.action_controller;dur=0.00, transaction.active_record;dur=4.03,
|
||||
render.active_model_serializers;dur=27.61, process_action.action_controller;dur=57.26
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '30'
|
||||
X-RateLimit-Remaining:
|
||||
- '29'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T15:30:00.683901Z'
|
||||
X-Request-Id:
|
||||
- a79bf3e1-4091-4332-9c47-45e8766ba9e6
|
||||
X-Runtime:
|
||||
- '0.072595'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Authorization, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
|
@ -0,0 +1,63 @@
|
|||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- tests/v311
|
||||
method: GET
|
||||
uri: http://localhost:3000/api/v1/instance/translation_languages
|
||||
response:
|
||||
body:
|
||||
string: '{}'
|
||||
headers:
|
||||
Cache-Control:
|
||||
- max-age=300, public, stale-while-revalidate=30, stale-if-error=86400
|
||||
Content-Length:
|
||||
- '2'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none'; frame-ancestors 'none'; form-action 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Sat, 15 Feb 2025 15:20:56 GMT
|
||||
ETag:
|
||||
- W/"44136fa355b3678a1146ad16f7e8649e"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Server-Timing:
|
||||
- cache_read.active_support;dur=0.04, sql.active_record;dur=3.48, cache_generate.active_support;dur=6.47,
|
||||
cache_write.active_support;dur=0.13, instantiation.active_record;dur=0.38,
|
||||
start_processing.action_controller;dur=0.01, render.active_model_serializers;dur=0.02,
|
||||
process_action.action_controller;dur=37.74
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-RateLimit-Limit:
|
||||
- '300'
|
||||
X-RateLimit-Remaining:
|
||||
- '299'
|
||||
X-RateLimit-Reset:
|
||||
- '2025-02-15T15:25:00.208109Z'
|
||||
X-Request-Id:
|
||||
- 915a0f13-8d73-43e0-bcfe-2f43294bdb6d
|
||||
X-Runtime:
|
||||
- '0.074836'
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
vary:
|
||||
- Accept, Origin
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
|
@ -100,3 +100,7 @@ def test_version_parsing(api):
|
|||
assert parse_version_string(api._Mastodon__normalize_version_string("3.5.0 (compatible; Pleroma 1.2.3)")) == (3, 5, 0)
|
||||
assert parse_version_string(api._Mastodon__normalize_version_string("3.2.1rc3 (compatible; Akkoma 3.2.4+shinychariot)")) == (3, 2, 1)
|
||||
assert parse_version_string(api._Mastodon__normalize_version_string("3.5.3+0.17.3+git-6f4cb2f")) == (3, 5, 3)
|
||||
|
||||
@pytest.mark.vcr()
|
||||
def test_translation_languages(api):
|
||||
assert api.instance_translation_languages() is not None
|
|
@ -289,3 +289,10 @@ def test_status_update_with_media_edit(api2):
|
|||
assert updated_status['media_attachments'][0]['preview_url'] != status['media_attachments'][0]['preview_url']
|
||||
finally:
|
||||
api2.status_delete(status['id'])
|
||||
|
||||
@pytest.mark.vcr()
|
||||
def test_status_translate(api, status):
|
||||
# our test server does not support translation, so this will raise a MastodonAPIError
|
||||
with pytest.raises(MastodonAPIError):
|
||||
translation = api.status_translate(status['id'], 'de')
|
||||
|
Ładowanie…
Reference in New Issue