Skip to content

Commit

Permalink
Merge pull request #233 from arittner/master
Browse files Browse the repository at this point in the history
Changes the storage for pagination information
  • Loading branch information
arittner authored Jun 24, 2022
2 parents 002c651 + e98b033 commit c9008a1
Show file tree
Hide file tree
Showing 4 changed files with 823 additions and 12 deletions.
51 changes: 42 additions & 9 deletions mastodon/Mastodon.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,27 @@ def __setattr__(self, attr, val):
raise AttributeError("Attribute-style access is read only")
super(AttribAccessDict, self).__setattr__(attr, val)


###
# The actual Mastodon class
# List helper class.
# Defined at top level so it can be pickled.
###
class AttribAccessList(list):
def __getattr__(self, attr):
if attr in self:
return self[attr]
else:
raise AttributeError("Attribute not found: " + str(attr))

def __setattr__(self, attr, val):
if attr in self:
raise AttributeError("Attribute-style access is read only")
super(AttribAccessList, self).__setattr__(attr, val)


###
# The actual Mastodon class
###
class Mastodon:
"""
Thorough and easy to use Mastodon
Expand Down Expand Up @@ -3050,8 +3067,8 @@ def fetch_next(self, previous_page):
Returns the next page or None if no further data is available.
"""
if isinstance(previous_page, list) and len(previous_page) != 0:
if hasattr(previous_page[-1], '_pagination_next'):
params = copy.deepcopy(previous_page[-1]._pagination_next)
if hasattr(previous_page, '_pagination_next'):
params = copy.deepcopy(previous_page._pagination_next)
else:
return None
else:
Expand All @@ -3074,8 +3091,8 @@ def fetch_previous(self, next_page):
Returns the previous page or None if no further data is available.
"""
if isinstance(next_page, list) and len(next_page) != 0:
if hasattr(next_page[0], '_pagination_prev'):
params = copy.deepcopy(next_page[0]._pagination_prev)
if hasattr(next_page, '_pagination_prev'):
params = copy.deepcopy(next_page._pagination_prev)
else:
return None
else:
Expand Down Expand Up @@ -3453,6 +3470,7 @@ def __api_request(self, method, endpoint, params={}, files={}, headers={}, acces
if isinstance(response, list) and \
'Link' in response_object.headers and \
response_object.headers['Link'] != "":
response = AttribAccessList(response)
tmp_urls = requests.utils.parse_header_links(
response_object.headers['Link'].rstrip('>').replace('>,<', ',<'))
for url in tmp_urls:
Expand All @@ -3477,7 +3495,12 @@ def __api_request(self, method, endpoint, params={}, files={}, headers={}, acces
del next_params['since_id']
if "min_id" in next_params:
del next_params['min_id']
response[-1]._pagination_next = next_params
response._pagination_next = next_params

# Maybe other API users rely on the pagination info in the last item
# Will be removed in future
if isinstance(response[-1], AttribAccessDict):
response[-1]._pagination_next = next_params

if url['rel'] == 'prev':
# Be paranoid and extract since_id or min_id specifically
Expand All @@ -3496,8 +3519,13 @@ def __api_request(self, method, endpoint, params={}, files={}, headers={}, acces
prev_params['since_id'] = since_id
if "max_id" in prev_params:
del prev_params['max_id']
response[0]._pagination_prev = prev_params

response._pagination_prev = prev_params

# Maybe other API users rely on the pagination info in the first item
# Will be removed in future
if isinstance(response[0], AttribAccessDict):
response[0]._pagination_prev = prev_params

# New and fantastico (post-2.6.0): min_id pagination
matchgroups = re.search(r"[?&]min_id=([^&]+)", prev_url)
if matchgroups:
Expand All @@ -3511,7 +3539,12 @@ def __api_request(self, method, endpoint, params={}, files={}, headers={}, acces
prev_params['min_id'] = min_id
if "max_id" in prev_params:
del prev_params['max_id']
response[0]._pagination_prev = prev_params
response._pagination_prev = prev_params

# Maybe other API users rely on the pagination info in the first item
# Will be removed in future
if isinstance(response[0], AttribAccessDict):
response[0]._pagination_prev = prev_params

return response

Expand Down
7 changes: 5 additions & 2 deletions tests/cassettes/test_domain_blocks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ interactions:
method: GET
uri: http://localhost:3000/api/v1/domain_blocks
response:
body: {string: '[]'}
body: {string: '["example.com"]'}
headers:
Cache-Control: ['no-cache, no-store']
Content-Type: [application/json; charset=utf-8]
Link: ['<http://localhost:3000/api/v1/domain_blocks?max_id=10023>;
rel="next", <http://localhost:3000/api/v1/domain_blocks?min_id=10021>;
rel="prev"']
Referrer-Policy: [strict-origin-when-cross-origin]
Transfer-Encoding: [chunked]
Vary: ['Accept-Encoding, Origin']
Expand All @@ -24,6 +27,6 @@ interactions:
X-Request-Id: [79ec8c37-a374-47e4-a698-a8b8511ca20f]
X-Runtime: ['0.098492']
X-XSS-Protection: [1; mode=block]
content-length: ['2']
content-length: ['15']
status: {code: 200, message: OK}
version: 1
Loading

0 comments on commit c9008a1

Please sign in to comment.