aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAljoscha Rittner <[email protected]>2022-06-16 14:52:15 +0200
committerAljoscha Rittner <[email protected]>2022-06-16 14:52:15 +0200
commit19dbb4594ec4fe47c3e9704c8b9365e3834764c2 (patch)
tree71de0276b71990eb45e15bca46eacf32ba97e403
parente9d2c3d53f7b1d371e5dc5bf47e5fe335b698c85 (diff)
downloadmastodon.py-19dbb4594ec4fe47c3e9704c8b9365e3834764c2.tar.gz
Changes the storage for pagination information
fixes #232
-rw-r--r--mastodon/Mastodon.py34
-rw-r--r--tests/cassettes/test_domain_blocks.yaml7
-rw-r--r--tests/test_pagination.py12
3 files changed, 37 insertions, 16 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index 98ac72a..c22cabe 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -120,10 +120,27 @@ class AttribAccessDict(dict):
120 raise AttributeError("Attribute-style access is read only") 120 raise AttributeError("Attribute-style access is read only")
121 super(AttribAccessDict, self).__setattr__(attr, val) 121 super(AttribAccessDict, self).__setattr__(attr, val)
122 122
123
123### 124###
124# The actual Mastodon class 125# List helper class.
126# Defined at top level so it can be pickled.
125### 127###
128class AttribAccessList(list):
129 def __getattr__(self, attr):
130 if attr in self:
131 return self[attr]
132 else:
133 raise AttributeError("Attribute not found: " + str(attr))
126 134
135 def __setattr__(self, attr, val):
136 if attr in self:
137 raise AttributeError("Attribute-style access is read only")
138 super(AttribAccessList, self).__setattr__(attr, val)
139
140
141###
142# The actual Mastodon class
143###
127class Mastodon: 144class Mastodon:
128 """ 145 """
129 Thorough and easy to use Mastodon 146 Thorough and easy to use Mastodon
@@ -3040,8 +3057,8 @@ class Mastodon:
3040 Returns the next page or None if no further data is available. 3057 Returns the next page or None if no further data is available.
3041 """ 3058 """
3042 if isinstance(previous_page, list) and len(previous_page) != 0: 3059 if isinstance(previous_page, list) and len(previous_page) != 0:
3043 if hasattr(previous_page[-1], '_pagination_next'): 3060 if hasattr(previous_page, '_pagination_next'):
3044 params = copy.deepcopy(previous_page[-1]._pagination_next) 3061 params = copy.deepcopy(previous_page._pagination_next)
3045 else: 3062 else:
3046 return None 3063 return None
3047 else: 3064 else:
@@ -3064,8 +3081,8 @@ class Mastodon:
3064 Returns the previous page or None if no further data is available. 3081 Returns the previous page or None if no further data is available.
3065 """ 3082 """
3066 if isinstance(next_page, list) and len(next_page) != 0: 3083 if isinstance(next_page, list) and len(next_page) != 0:
3067 if hasattr(next_page[0], '_pagination_prev'): 3084 if hasattr(next_page, '_pagination_prev'):
3068 params = copy.deepcopy(next_page[0]._pagination_prev) 3085 params = copy.deepcopy(next_page._pagination_prev)
3069 else: 3086 else:
3070 return None 3087 return None
3071 else: 3088 else:
@@ -3443,6 +3460,7 @@ class Mastodon:
3443 if isinstance(response, list) and \ 3460 if isinstance(response, list) and \
3444 'Link' in response_object.headers and \ 3461 'Link' in response_object.headers and \
3445 response_object.headers['Link'] != "": 3462 response_object.headers['Link'] != "":
3463 response = AttribAccessList(response)
3446 tmp_urls = requests.utils.parse_header_links( 3464 tmp_urls = requests.utils.parse_header_links(
3447 response_object.headers['Link'].rstrip('>').replace('>,<', ',<')) 3465 response_object.headers['Link'].rstrip('>').replace('>,<', ',<'))
3448 for url in tmp_urls: 3466 for url in tmp_urls:
@@ -3467,7 +3485,7 @@ class Mastodon:
3467 del next_params['since_id'] 3485 del next_params['since_id']
3468 if "min_id" in next_params: 3486 if "min_id" in next_params:
3469 del next_params['min_id'] 3487 del next_params['min_id']
3470 response[-1]._pagination_next = next_params 3488 response._pagination_next = next_params
3471 3489
3472 if url['rel'] == 'prev': 3490 if url['rel'] == 'prev':
3473 # Be paranoid and extract since_id or min_id specifically 3491 # Be paranoid and extract since_id or min_id specifically
@@ -3486,7 +3504,7 @@ class Mastodon:
3486 prev_params['since_id'] = since_id 3504 prev_params['since_id'] = since_id
3487 if "max_id" in prev_params: 3505 if "max_id" in prev_params:
3488 del prev_params['max_id'] 3506 del prev_params['max_id']
3489 response[0]._pagination_prev = prev_params 3507 response._pagination_prev = prev_params
3490 3508
3491 # New and fantastico (post-2.6.0): min_id pagination 3509 # New and fantastico (post-2.6.0): min_id pagination
3492 matchgroups = re.search(r"[?&]min_id=([^&]+)", prev_url) 3510 matchgroups = re.search(r"[?&]min_id=([^&]+)", prev_url)
@@ -3501,7 +3519,7 @@ class Mastodon:
3501 prev_params['min_id'] = min_id 3519 prev_params['min_id'] = min_id
3502 if "max_id" in prev_params: 3520 if "max_id" in prev_params:
3503 del prev_params['max_id'] 3521 del prev_params['max_id']
3504 response[0]._pagination_prev = prev_params 3522 response._pagination_prev = prev_params
3505 3523
3506 return response 3524 return response
3507 3525
diff --git a/tests/cassettes/test_domain_blocks.yaml b/tests/cassettes/test_domain_blocks.yaml
index 8889bb1..041541e 100644
--- a/tests/cassettes/test_domain_blocks.yaml
+++ b/tests/cassettes/test_domain_blocks.yaml
@@ -10,10 +10,13 @@ interactions:
10 method: GET 10 method: GET
11 uri: http://localhost:3000/api/v1/domain_blocks 11 uri: http://localhost:3000/api/v1/domain_blocks
12 response: 12 response:
13 body: {string: '[]'} 13 body: {string: '["example.com"]'}
14 headers: 14 headers:
15 Cache-Control: ['no-cache, no-store'] 15 Cache-Control: ['no-cache, no-store']
16 Content-Type: [application/json; charset=utf-8] 16 Content-Type: [application/json; charset=utf-8]
17 Link: ['<http://localhost:3000/api/v1/domain_blocks?max_id=10023>;
18 rel="next", <http://localhost:3000/api/v1/domain_blocks?min_id=10021>;
19 rel="prev"']
17 Referrer-Policy: [strict-origin-when-cross-origin] 20 Referrer-Policy: [strict-origin-when-cross-origin]
18 Transfer-Encoding: [chunked] 21 Transfer-Encoding: [chunked]
19 Vary: ['Accept-Encoding, Origin'] 22 Vary: ['Accept-Encoding, Origin']
@@ -24,6 +27,6 @@ interactions:
24 X-Request-Id: [79ec8c37-a374-47e4-a698-a8b8511ca20f] 27 X-Request-Id: [79ec8c37-a374-47e4-a698-a8b8511ca20f]
25 X-Runtime: ['0.098492'] 28 X-Runtime: ['0.098492']
26 X-XSS-Protection: [1; mode=block] 29 X-XSS-Protection: [1; mode=block]
27 content-length: ['2'] 30 content-length: ['15']
28 status: {code: 200, message: OK} 31 status: {code: 200, message: OK}
29version: 1 32version: 1
diff --git a/tests/test_pagination.py b/tests/test_pagination.py
index 72ac06e..8a85ccb 100644
--- a/tests/test_pagination.py
+++ b/tests/test_pagination.py
@@ -39,9 +39,9 @@ def test_fetch_next_previous_from_pagination_info(api):
39 account = api.account_verify_credentials() 39 account = api.account_verify_credentials()
40 with many_statuses(api): 40 with many_statuses(api):
41 statuses = api.account_statuses(account['id'], limit=5) 41 statuses = api.account_statuses(account['id'], limit=5)
42 next_statuses = api.fetch_next(statuses[-1]._pagination_next) 42 next_statuses = api.fetch_next(statuses._pagination_next)
43 assert next_statuses 43 assert next_statuses
44 previous_statuses = api.fetch_previous(next_statuses[0]._pagination_prev) 44 previous_statuses = api.fetch_previous(next_statuses._pagination_prev)
45 assert previous_statuses 45 assert previous_statuses
46 46
47def test_fetch_next_previous_old_pagination(api): 47def test_fetch_next_previous_old_pagination(api):
@@ -61,9 +61,9 @@ def test_fetch_next_previous_from_pagination_info_old_pagination(api):
61 61
62 with many_statuses(api): 62 with many_statuses(api):
63 statuses = api.account_statuses(account['id'], limit=5) 63 statuses = api.account_statuses(account['id'], limit=5)
64 next_statuses = api.fetch_next(statuses[-1]._pagination_next) 64 next_statuses = api.fetch_next(statuses._pagination_next)
65 assert next_statuses 65 assert next_statuses
66 previous_statuses = api.fetch_previous(next_statuses[0]._pagination_prev) 66 previous_statuses = api.fetch_previous(next_statuses._pagination_prev)
67 assert previous_statuses 67 assert previous_statuses
68 68
69@pytest.mark.vcr() 69@pytest.mark.vcr()
@@ -86,5 +86,5 @@ def test_link_headers(api):
86 }) 86 })
87 87
88 resp = api.timeline_hashtag(UNLIKELY_HASHTAG) 88 resp = api.timeline_hashtag(UNLIKELY_HASHTAG)
89 assert resp[0]._pagination_next['max_id'] == _id 89 assert resp._pagination_next['max_id'] == _id
90 assert resp[0]._pagination_prev['since_id'] == _id 90 assert resp._pagination_prev['since_id'] == _id
Powered by cgit v1.2.3 (git 2.41.0)