__init__.py 4.7 KB

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