From c82b0b19196d5d390419d71e2b45f11ec1c74a05 Mon Sep 17 00:00:00 2001 From: Lorenz Diener Date: Sun, 28 Apr 2019 21:15:47 +0200 Subject: [PATCH] Add more parameters to search API --- mastodon/Mastodon.py | 44 +++++++++++--- tests/cassettes/test_search.yaml | 98 +++++++++++++++++++++++++++++--- tests/test_search.py | 11 ++++ 3 files changed, 137 insertions(+), 16 deletions(-) diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index 679aac8..dd710b7 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py @@ -1090,28 +1090,56 @@ class Mastodon: ### # Reading data: Searching ### - @api_version("1.1.0", "2.1.0", __DICT_VERSION_SEARCHRESULT) - def search(self, q, resolve=False): + @api_version("2.8.0", "2.8.0", __DICT_VERSION_SEARCHRESULT) + def search(self, q, resolve=True, result_type=None, account_id=None, offset=None, min_id=None, max_id=None): """ - Fetch matching hashtags, accounts and statuses. Will search federated - instances if resolve is True. Full-text search is only enabled if + Fetch matching hashtags, accounts and statuses. Will perform webfinger + lookups if resolve is True. Full-text search is only enabled if the instance supports it, and is restricted to statuses the logged-in user wrote or was mentioned in. + + `result_type` can be one of "accounts", "hashtags" or "statuses", to only + search for that type of object. + + Specify `account_id` to only get results from the account with that id. + + `offset`, `min_id` and `max_id` can be used to paginate. + + Returns a `search result dict`_, with tags as `hashtag dicts`_. + """ + return self.search_v2(q, resolve=resolve, result_type=result_type, account_id=account_id, + offset=offset, min_id=min_id, max_id=max_id) + + @api_version("1.1.0", "2.1.0", __DICT_VERSION_SEARCHRESULT) + def search_v1(self, q, resolve=False): + """ + Identical to `search_v2()`, except in that it does not return + tags as `hashtag dicts`_. Returns a `search result dict`_. """ params = self.__generate_params(locals()) + if resolve == False: + del params['resolve'] return self.__api_request('GET', '/api/v1/search', params) - @api_version("2.4.3", "2.4.3", __DICT_VERSION_SEARCHRESULT) - def search_v2(self, q, resolve=False): + @api_version("2.8.0", "2.8.0", __DICT_VERSION_SEARCHRESULT) + def search_v2(self, q, resolve=True, result_type=None, account_id=None, offset=None, min_id=None, max_id=None): """ - Identical to `search()`, except in that it returns tags as - `hashtag dicts`_. + Identical to `search_v1()`, except in that it returns tags as + `hashtag dicts`_, has more parameters, and resolves by default. Returns a `search result dict`_. """ params = self.__generate_params(locals()) + + if resolve == False: + del params['resolve'] + + if "result_type" in params: + params["type"] = params["result_type"] + del params["result_type"] + return self.__api_request('GET', '/api/v2/search', params) ### diff --git a/tests/cassettes/test_search.yaml b/tests/cassettes/test_search.yaml index b4ecccc..1983178 100644 --- a/tests/cassettes/test_search.yaml +++ b/tests/cassettes/test_search.yaml @@ -8,15 +8,13 @@ interactions: Connection: [keep-alive] User-Agent: [python-requests/2.18.4] method: GET - uri: http://localhost:3000/api/v1/search?resolve=0&q=mastodonpy_test + uri: http://localhost:3000/api/v1/search?q=mastodonpy_test response: - body: {string: '{"hashtags":[],"accounts":[{"id":"1234567890123456","username":"mastodonpy_test","acct":"mastodonpy_test","display_name":"John - Lennon","locked":true,"bot":false,"created_at":"2019-04-27T20:03:12.393Z","note":"\u003cp\u003eI - walk funny\u003c/p\u003e","url":"http://localhost/@mastodonpy_test","avatar":"http://localhost/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpeg?1556389071","avatar_static":"http://localhost/system/accounts/avatars/123/456/789/012/345/original/mastodonpyupload_.jpeg?1556389071","header":"http://localhost/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpeg?1556389071","header_static":"http://localhost/system/accounts/headers/123/456/789/012/345/original/mastodonpyupload_.jpeg?1556389071","followers_count":0,"following_count":0,"statuses_count":61,"emojis":[],"fields":[{"name":"bread","value":"toasty.","verified_at":null},{"name":"lasagna","value":"no!!!","verified_at":null}]}],"statuses":[]}'} + body: {string: '{"hashtags":[],"accounts":[{"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":0,"emojis":[],"fields":[]}],"statuses":[]}'} headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"e9c64c1dd043adc13b1f271dc991b218"] + ETag: [W/"9b6c418bdbb3a0abd5277c65cc102118"] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -24,9 +22,93 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [4173731a-1280-4915-8023-adc11ffbcbb8] - X-Runtime: ['0.105438'] + X-Request-Id: [0d222257-5114-433c-b10b-1e7c849a6b9a] + X-Runtime: ['0.025732'] X-XSS-Protection: [1; mode=block] - content-length: ['973'] + content-length: ['610'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] + Connection: [keep-alive] + User-Agent: [python-requests/2.18.4] + method: GET + uri: http://localhost:3000/api/v2/search?resolve=1&q=mastodonpy_test + response: + body: {string: '{"accounts":[{"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":0,"emojis":[],"fields":[]}],"statuses":[],"hashtags":[]}'} + headers: + Cache-Control: ['max-age=0, private, must-revalidate'] + Content-Type: [application/json; charset=utf-8] + ETag: [W/"dc01e7fe955c38320762927b42201386"] + 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: [fe4a8ac5-89c8-40fa-b156-b53907927af8] + X-Runtime: ['0.036339'] + X-XSS-Protection: [1; mode=block] + content-length: ['610'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] + Connection: [keep-alive] + User-Agent: [python-requests/2.18.4] + method: GET + uri: http://localhost:3000/api/v2/search?resolve=1&q=mastodonpy_test + response: + body: {string: '{"accounts":[{"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":0,"emojis":[],"fields":[]}],"statuses":[],"hashtags":[]}'} + headers: + Cache-Control: ['max-age=0, private, must-revalidate'] + Content-Type: [application/json; charset=utf-8] + ETag: [W/"dc01e7fe955c38320762927b42201386"] + 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: [db56fc6d-bc14-4197-ad8e-526451c31ef8] + X-Runtime: ['0.031569'] + X-XSS-Protection: [1; mode=block] + content-length: ['610'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate'] + Authorization: [Bearer __MASTODON_PY_TEST_ACCESS_TOKEN] + Connection: [keep-alive] + User-Agent: [python-requests/2.18.4] + method: GET + uri: http://localhost:3000/api/v2/search?resolve=1&q=mastodonpy_test&type=statuses + response: + body: {string: '{"accounts":[],"statuses":[],"hashtags":[]}'} + headers: + Cache-Control: ['max-age=0, private, must-revalidate'] + Content-Type: [application/json; charset=utf-8] + ETag: [W/"2f5f5aeb866795515ef92460da252331"] + 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: [0af31e14-f026-43f7-9fdc-b8e3130479cf] + X-Runtime: ['0.043284'] + X-XSS-Protection: [1; mode=block] + content-length: ['43'] status: {code: 200, message: OK} version: 1 diff --git a/tests/test_search.py b/tests/test_search.py index 7a39581..f05a023 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -2,5 +2,16 @@ import pytest @pytest.mark.vcr() def test_search(api): + results = api.search_v1('mastodonpy_test') + assert isinstance(results, dict) + + results = api.search_v2('mastodonpy_test') + assert isinstance(results, dict) + results = api.search('mastodonpy_test') assert isinstance(results, dict) + + results = api.search('mastodonpy_test', result_type="statuses") + assert isinstance(results, dict) + assert len(results["hashtags"]) == 0 + assert len(results["accounts"]) == 0