Subchange.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/usr/bin/env python3
  2. # Contest Management System - http://cms-dev.github.io/
  3. # Copyright © 2011-2013 Luca Wehrstedt <luca.wehrstedt@gmail.com>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. from cmsranking.Entity import Entity, InvalidData
  18. class Subchange(Entity):
  19. """The entity representing a change in the status of a submission.
  20. It consists of the following properties:
  21. - submission (unicode): the key of the affected submission
  22. - time (int): the time the change takes effect
  23. - score (float): optional, the new score
  24. - token (bool): optional, the new token status
  25. - extra ([unicode]): optional, the new details
  26. """
  27. def __init__(self):
  28. """Set the properties to some default values.
  29. """
  30. Entity.__init__(self)
  31. self.submission = None
  32. self.time = None
  33. self.score = None
  34. self.token = None
  35. self.extra = None
  36. @staticmethod
  37. def validate(data):
  38. """Validate the given dictionary.
  39. See if it contains a valid representation of this entity.
  40. """
  41. try:
  42. assert isinstance(data, dict), \
  43. "Not a dictionary"
  44. assert isinstance(data['submission'], str), \
  45. "Field 'submission' isn't a string"
  46. assert isinstance(data['time'], int), \
  47. "Field 'time' isn't an integer (unix timestamp)"
  48. if 'score' in data:
  49. assert isinstance(data['score'], float), \
  50. "Field 'score' isn't a float"
  51. if 'token' in data:
  52. assert isinstance(data['token'], bool), \
  53. "Field 'token' isn't a boolean"
  54. if 'extra' in data:
  55. assert isinstance(data['extra'], list), \
  56. "Field 'extra' isn't a list of strings"
  57. for i in data['extra']:
  58. assert isinstance(i, str), \
  59. "Field 'extra' isn't a list of strings"
  60. except KeyError as exc:
  61. raise InvalidData("Field %s is missing" % exc)
  62. except AssertionError as exc:
  63. raise InvalidData(str(exc))
  64. def set(self, data):
  65. self.validate(data)
  66. self.submission = data['submission']
  67. self.time = data['time']
  68. self.score = (data['score'] if 'score' in data else None)
  69. self.token = (data['token'] if 'token' in data else None)
  70. self.extra = (data['extra'] if 'extra' in data else None)
  71. def get(self):
  72. result = self.__dict__.copy()
  73. del result['key']
  74. for field in ['score', 'token', 'extra']:
  75. if result[field] is None:
  76. del result[field]
  77. return result
  78. def consistent(self, stores):
  79. return "submission" not in stores \
  80. or self.submission in stores["submission"]