__init__.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. """
  2. Posting process implementation
  3. """
  4. from importlib import import_module
  5. from django.utils import timezone
  6. from misago.conf import settings
  7. from misago.core import forms
  8. START = 0
  9. REPLY = 1
  10. EDIT = 2
  11. class PostingInterrupt(Exception):
  12. def __init__(self, message):
  13. if not message:
  14. raise ValueError("You have to provide PostingInterrupt message.")
  15. self.message = message
  16. class EditorFormset(object):
  17. def __init__(self, **kwargs):
  18. self.errors = []
  19. self._forms_list = []
  20. self._forms_dict = {}
  21. self.kwargs = kwargs
  22. self.__dict__.update(kwargs)
  23. self.datetime = timezone.now()
  24. self.middlewares = []
  25. self._load_middlewares()
  26. @property
  27. def start_form(self):
  28. return self.mode == START
  29. @property
  30. def reply_form(self):
  31. return self.mode == REPLY
  32. @property
  33. def edit_form(self):
  34. return self.mode == EDIT
  35. def _load_middlewares(self):
  36. kwargs = self.kwargs.copy()
  37. kwargs.update({
  38. 'datetime': self.datetime,
  39. 'parsing_result': {},
  40. })
  41. for middleware in settings.MISAGO_POSTING_MIDDLEWARES:
  42. module_name = '.'.join(middleware.split('.')[:-1])
  43. class_name = middleware.split('.')[-1]
  44. middleware_module = import_module(module_name)
  45. middleware_class = getattr(middleware_module, class_name)
  46. try:
  47. middleware_obj = middleware_class(prefix=middleware, **kwargs)
  48. if middleware_obj.use_this_middleware():
  49. self.middlewares.append((middleware, middleware_obj))
  50. except PostingInterrupt:
  51. raise ValueError("Posting process can only be "
  52. "interrupted during pre_save phase")
  53. def get_forms_list(self):
  54. """return list of forms belonging to formset"""
  55. if not self._forms_list:
  56. self._build_forms_cache()
  57. return self._forms_list
  58. def get_forms_dict(self):
  59. """return list of forms belonging to formset"""
  60. if not self._forms_dict:
  61. self._build_forms_cache()
  62. return self._forms_dict
  63. def _build_forms_cache(self):
  64. try:
  65. for middleware, obj in self.middlewares:
  66. form = obj.make_form()
  67. if form:
  68. self._forms_dict[middleware] = form
  69. self._forms_list.append(form)
  70. except PostingInterrupt:
  71. raise ValueError("Posting process can only be "
  72. "interrupted during pre_save phase")
  73. def get_main_forms(self):
  74. """return list of main forms"""
  75. main_forms = []
  76. for form in self.get_forms_list():
  77. try:
  78. if form.is_main and form.legend:
  79. main_forms.append(form)
  80. except AttributeError:
  81. pass
  82. return main_forms
  83. def get_supporting_forms(self):
  84. """return list of supporting forms"""
  85. supporting_forms = []
  86. for form in self.get_forms_list():
  87. try:
  88. if form.is_supporting and form.legend:
  89. supporting_forms.append(form)
  90. except AttributeError:
  91. pass
  92. return supporting_forms
  93. def is_valid(self):
  94. """validate all forms"""
  95. all_forms_valid = True
  96. for form in self.get_forms_list():
  97. if not form.is_valid():
  98. all_forms_valid = False
  99. return all_forms_valid
  100. def save(self):
  101. """change state"""
  102. forms_dict = self.get_forms_dict()
  103. for middleware, obj in self.middlewares:
  104. obj.pre_save(forms_dict.get(middleware))
  105. try:
  106. for middleware, obj in self.middlewares:
  107. obj.save(forms_dict.get(middleware))
  108. for middleware, obj in self.middlewares:
  109. obj.post_save(forms_dict.get(middleware))
  110. except PostingInterrupt:
  111. raise ValueError("Posting process can only be "
  112. "interrupted during pre_save phase")
  113. def update(self):
  114. """handle POST that shouldn't result in state change"""
  115. forms_dict = self.get_forms_dict()
  116. for middleware, obj in self.middlewares:
  117. obj.pre_save(forms_dict.get(middleware))
  118. class PostingMiddleware(object):
  119. """
  120. Abstract middleware classes
  121. """
  122. def __init__(self, **kwargs):
  123. self.kwargs = kwargs
  124. self.__dict__.update(kwargs)
  125. def use_this_middleware(self):
  126. return True
  127. def make_form(self):
  128. pass
  129. def pre_save(self, form):
  130. pass
  131. def save(self, form):
  132. pass
  133. def post_save(self, form):
  134. pass