Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

89 linhas
2.8 KiB

  1. # Copyright 2014-2016 OpenMarket Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import logging
  15. from typing import Optional
  16. import attr
  17. from synapse.api.constants import Direction
  18. from synapse.api.errors import SynapseError
  19. from synapse.http.servlet import parse_enum, parse_integer, parse_string
  20. from synapse.http.site import SynapseRequest
  21. from synapse.storage.databases.main import DataStore
  22. from synapse.types import StreamToken
  23. logger = logging.getLogger(__name__)
  24. MAX_LIMIT = 1000
  25. @attr.s(slots=True, auto_attribs=True)
  26. class PaginationConfig:
  27. """A configuration object which stores pagination parameters."""
  28. from_token: Optional[StreamToken]
  29. to_token: Optional[StreamToken]
  30. direction: Direction
  31. limit: int
  32. @classmethod
  33. async def from_request(
  34. cls,
  35. store: "DataStore",
  36. request: SynapseRequest,
  37. default_limit: int,
  38. default_dir: Direction = Direction.FORWARDS,
  39. ) -> "PaginationConfig":
  40. direction = parse_enum(request, "dir", Direction, default=default_dir)
  41. from_tok_str = parse_string(request, "from")
  42. to_tok_str = parse_string(request, "to")
  43. try:
  44. from_tok = None
  45. if from_tok_str == "END":
  46. from_tok = None # For backwards compat.
  47. elif from_tok_str:
  48. from_tok = await StreamToken.from_string(store, from_tok_str)
  49. except Exception:
  50. raise SynapseError(400, "'from' parameter is invalid")
  51. try:
  52. to_tok = None
  53. if to_tok_str:
  54. to_tok = await StreamToken.from_string(store, to_tok_str)
  55. except Exception:
  56. raise SynapseError(400, "'to' parameter is invalid")
  57. limit = parse_integer(request, "limit", default=default_limit)
  58. if limit < 0:
  59. raise SynapseError(400, "Limit must be 0 or above")
  60. limit = min(limit, MAX_LIMIT)
  61. try:
  62. return PaginationConfig(from_tok, to_tok, direction, limit)
  63. except Exception:
  64. logger.exception("Failed to create pagination config")
  65. raise SynapseError(400, "Invalid request.")
  66. def __repr__(self) -> str:
  67. return "PaginationConfig(from_tok=%r, to_tok=%r, direction=%r, limit=%r)" % (
  68. self.from_token,
  69. self.to_token,
  70. self.direction,
  71. self.limit,
  72. )