Add account_familiar_followers

This commit is contained in:
halcy 2022-11-27 23:38:42 +02:00
parent ee9a3c9c5e
commit b35e3f3da8
6 changed files with 526 additions and 9 deletions

View File

@ -4,6 +4,7 @@ version number. Breaking changes will be indicated by a change in the minor
v1.8.0 (in progress)
--------------------
* Overall: Support level is now 3.5.3 (last before 4.0.0)
* BREAKING CHANGE: Switch the base URL to None, throw an error when no base url is passed. Having mastosoc as default was sensible when there were only three mastodon servers. It is not sensible now and trips people up constantly.
* Fixed an issue with the fix for the Pleroma date bug (thanks adbenitez)
* Added trending APIs (`trending_tags`, `trending_statuses`, `trending_links`, `admin_trending_tags`, `admin_trending_statuses`, `admin_trending_links`)
@ -14,6 +15,7 @@ v1.8.0 (in progress)
* Added the domain blocking admin API (`admin_domain_blocks`, `admin_domain_block`, `admin_update_domain_block`, `admin_delete_domain_block` - thanks catgoat)
* Added the stats admin APIs (`admin_measures`, `admin_dimensions`, `admin_retention`)
* Added client auth data to access token file.
* Added `account_familiar_followers` API
v1.7.0
------

View File

@ -45,7 +45,7 @@ Refer to mastodon changelog and API docs for details when implementing, add or m
* [x] Add notifications for posts deleted by moderators <- by email. not actually API relevant.
* [x] Add explore page with trending posts and links
* [x] Add graphs and retention metrics to admin dashboard
* [ ] Add GET /api/v1/accounts/familiar_followers to REST API
* [x] Add GET /api/v1/accounts/familiar_followers to REST API
* [ ] Add POST /api/v1/accounts/:id/remove_from_followers to REST API
* [x] Add category and rule_ids params to POST /api/v1/reports IN REST API
* [x] Add global lang param to REST API

View File

@ -864,6 +864,18 @@ Announcement dicts
} ],
}
Familiar follower dicts
~~~~~~~~~~~~~~~~~~~~~~~
.. _familiar follower dict:
.. code-block:: python
mastodon.account_familiar_followers(1)[0]
# Returns the following dictionary:
{
}
Admin account dicts
~~~~~~~~~~~~~~~~~~~
.. _admin account dict:
@ -1087,8 +1099,9 @@ their relationships.
.. automethod:: Mastodon.account_followers
.. automethod:: Mastodon.account_relationships
.. automethod:: Mastodon.account_search
.. automethod:: Mastodon.account_lists
.. automethod:: Mastodon.account_lookup
.. automethod:: Mastodon.account_lists
.. automethod:: Mastodon.account_familiar_followers
Reading data: Featured tags
~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -459,6 +459,7 @@ class Mastodon:
self.api_base_url = try_base_url
# For EVEN newer vesions, we ALSO ALSO store the client id and secret so that you don't need to reauth to revoke
if self.client_id is None:
try:
self.client_id = token_file.readline().rstrip()
self.client_secret = token_file.readline().rstrip()
@ -1356,6 +1357,19 @@ class Mastodon:
"""
return self.__api_request('GET', '/api/v1/accounts/lookup', self.__generate_params(locals()))
@api_version("3.5.0", "3.5.0", __DICT_VERSION_ACCOUNT)
def account_familiar_followers(self, id):
"""
Find followers for the account given by id (can be a list) that also follow the
logged in account.
Returns a list of `familiar follower dicts`_
"""
if not isinstance(id, list):
id = [id]
for i in range(len(id)):
id[i] = self.__unpack_id(id[i])
return self.__api_request('GET', '/api/v1/accounts/familiar_followers', {'id': id}, use_json=True)
###
# Reading data: Featured hashtags

View File

@ -0,0 +1,474 @@
interactions:
- 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/accounts/verify_credentials
response:
body:
string: '{"id":"109411885671340064","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-26T00:00:00.000Z","note":"","url":"http://localhost:3000/@admin","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":0,"last_status_at":null,"noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"follow_requests_count":0},"emojis":[],"fields":[],"role":{"id":"3","name":"Owner","permissions":"1048575","color":"","highlighted":true}}'
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-HsglxmIP4X9/7gzWNyzBNQ=='';
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/"a92dcb08b6f874d680c45eede3cca2ec"
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:
- 04a9eb59-b11c-4188-b958-d7dfeb53ae6d
X-Runtime:
- '0.029692'
X-XSS-Protection:
- 1; mode=block
status:
code: 200
message: OK
- request:
body: '{"id": [109411885671340064]}'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
Connection:
- keep-alive
Content-Length:
- '28'
Content-Type:
- application/json
User-Agent:
- tests/v311
method: GET
uri: http://localhost:3000/api/v1/accounts/familiar_followers
response:
body:
string: '[{"id":"109411885671340064","accounts":[]}]'
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-5j9VM0TO7+8xoit9RncpvA=='';
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/"b97f7c3306068f25d5289e9c8bdd190b"
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:
- 17dcfa85-da42-4267-b758-06852ec1d5ad
X-Runtime:
- '0.036562'
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/accounts/verify_credentials
response:
body:
string: '{"id":"109411885671340064","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-26T00:00:00.000Z","note":"","url":"http://localhost:3000/@admin","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":0,"last_status_at":null,"noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"follow_requests_count":0},"emojis":[],"fields":[],"role":{"id":"3","name":"Owner","permissions":"1048575","color":"","highlighted":true}}'
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-AqTmg/2+pH5lHD7Nqp5zvA=='';
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/"a92dcb08b6f874d680c45eede3cca2ec"
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:
- e219b468-eea5-4147-b8b6-f529b78f46a7
X-Runtime:
- '0.019573'
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/accounts/verify_credentials
response:
body:
string: '{"id":"109411885671340064","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-26T00:00:00.000Z","note":"","url":"http://localhost:3000/@admin","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":0,"last_status_at":null,"noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"follow_requests_count":0},"emojis":[],"fields":[],"role":{"id":"3","name":"Owner","permissions":"1048575","color":"","highlighted":true}}'
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-pEDEgC21lzY+5lANf9Y82A=='';
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/"a92dcb08b6f874d680c45eede3cca2ec"
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:
- cc4eac3a-7f0b-4a9f-9e1e-13746da6e32e
X-Runtime:
- '0.016836'
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_3
Connection:
- keep-alive
User-Agent:
- tests/v311
method: GET
uri: http://localhost:3000/api/v1/accounts/verify_credentials
response:
body:
string: '{"id":"109411886050231694","username":"mastodonpy_test_2","acct":"mastodonpy_test_2","display_name":"","locked":false,"bot":false,"discoverable":true,"group":false,"created_at":"2022-11-26T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test_2","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":0,"last_status_at":null,"noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"follow_requests_count":0},"emojis":[],"fields":[],"role":{"id":"-99","name":"","permissions":"65536","color":"","highlighted":false}}'
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-xQuOD8nr/iV0EOtUeqpFzw=='';
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/"9b2f5aee7759c56dec7b8052fd486107"
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:
- 4b007953-7d3a-4ed4-9ec1-c73b57593373
X-Runtime:
- '0.068161'
X-XSS-Protection:
- 1; mode=block
status:
code: 200
message: OK
- request:
body: '{"id": [109411885671340064, 109411886050231694]}'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
Connection:
- keep-alive
Content-Length:
- '48'
Content-Type:
- application/json
User-Agent:
- tests/v311
method: GET
uri: http://localhost:3000/api/v1/accounts/familiar_followers
response:
body:
string: '[{"id":"109411885671340064","accounts":[]},{"id":"109411886050231694","accounts":[]}]'
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-0rxKBZJV0bQR4XvobxIHsA=='';
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/"7cd1229a63b01fb300cbaaa957e53b53"
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:
- 24a35cec-aded-4710-9c69-442a5b49852b
X-Runtime:
- '0.013945'
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/accounts/verify_credentials
response:
body:
string: '{"id":"109411885671340064","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"discoverable":null,"group":false,"created_at":"2022-11-26T00:00:00.000Z","note":"","url":"http://localhost:3000/@admin","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":0,"last_status_at":null,"noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"follow_requests_count":0},"emojis":[],"fields":[],"role":{"id":"3","name":"Owner","permissions":"1048575","color":"","highlighted":true}}'
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-g7eI+n5KW3K5e9BunAxYDw=='';
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/"a92dcb08b6f874d680c45eede3cca2ec"
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:
- 135538ed-c3cc-4971-9dfc-a76caf6e9c49
X-Runtime:
- '0.017874'
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_3
Connection:
- keep-alive
User-Agent:
- tests/v311
method: GET
uri: http://localhost:3000/api/v1/accounts/verify_credentials
response:
body:
string: '{"id":"109411886050231694","username":"mastodonpy_test_2","acct":"mastodonpy_test_2","display_name":"","locked":false,"bot":false,"discoverable":true,"group":false,"created_at":"2022-11-26T00:00:00.000Z","note":"","url":"http://localhost:3000/@mastodonpy_test_2","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":0,"last_status_at":null,"noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"follow_requests_count":0},"emojis":[],"fields":[],"role":{"id":"-99","name":"","permissions":"65536","color":"","highlighted":false}}'
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-1ZPdVwRxFGNenU8svTXCJw=='';
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/"9b2f5aee7759c56dec7b8052fd486107"
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:
- 57c760f3-1384-464d-a8e1-93e054a2076c
X-Runtime:
- '0.018550'
X-XSS-Protection:
- 1; mode=block
status:
code: 200
message: OK
version: 1

View File

@ -291,3 +291,17 @@ def test_account_lookup(api, api3):
pass
assert(api.account_lookup("mastodonpy_test").id == id)
assert(api.account_lookup("mastodonpy_test@localhost:3000").id == id)
@pytest.mark.vcr()
def test_account_familiar_followers(api, api2, api3):
followers_list = api.account_familiar_followers(api2.me())
assert followers_list
assert len(followers_list) == 1
assert followers_list[0].id == api2.me().id
assert "accounts" in followers_list[0]
followers_list = api.account_familiar_followers([api2.me(), api3.me()])
assert followers_list
assert len(followers_list) == 2
assert followers_list[0].id == api2.me().id
assert followers_list[1].id == api3.me().id