Rafał Pitoń 11 лет назад
Родитель
Сommit
25ab98cad2

+ 37 - 9
misago/apps/threads/forms.py

@@ -4,7 +4,6 @@ from misago.apps.threadtype.posting.forms import NewThreadForm as NewThreadFormB
 from misago.forms import Form
 from misago.validators import validate_sluggable
 
-
 class PollFormMixin(object):
     def create_poll_form(self):
         self.add_field('poll_question',
@@ -37,7 +36,7 @@ class PollFormMixin(object):
                        forms.CharField(label=_("Poll Question"),
                                        initial=self.poll.question))
         self.add_field('poll_choices',
-                       forms.CharField(label=_("New Choices"),
+                       forms.CharField(label=_("Add New Choices"),
                                        help_text=_("If you want, you can add new options to poll. Enter every option in new line."),
                                        required=False,
                                        widget=forms.Textarea))
@@ -45,20 +44,21 @@ class PollFormMixin(object):
                        forms.IntegerField(label=_("Choices Per User"),
                                           help_text=_("Select on how many options individual user will be able to vote on."),
                                           min_value=1,
-                                          initial=1))
+                                          initial=self.poll.max_choices))
         self.add_field('poll_length',
                        forms.IntegerField(label=_("Poll Length"),
                                           help_text=_("Number of days since poll creations users will be allowed to vote in poll. Enter zero for permanent poll."),
                                           min_value=0,
-                                          initial=0))
+                                          initial=self.poll.length))
 
         self.add_field('poll_changing_votes',
                        forms.BooleanField(label=_("Allow Changing Votes"),
-                                          required=False))
+                                          required=False,
+                                          initial=self.poll.vote_changing))
 
     def clean_poll_question(self):
         data = self.cleaned_data['poll_question'].strip()
-        if data:
+        if data or self.poll:
             if len(data) < 3:
                 raise forms.ValidationError(_("Poll quesiton should be at least three characters long."))
             if len(data) > 255:
@@ -69,6 +69,9 @@ class PollFormMixin(object):
         self.clean_choices = []
         data = self.cleaned_data['poll_choices']
 
+        if self.poll:
+            self.clean_poll_edited_choices()
+
         if data:
             for choice in data.splitlines():
                 choice = choice.strip()
@@ -85,11 +88,26 @@ class PollFormMixin(object):
 
         return '\r\n'.join(self.clean_choices)
 
+    def clean_poll_edited_choices(self):
+        self.changed_choices = []
+        self.deleted_choices = []
+
+        for option in self.poll.option_set.all():
+            new_name = self.request.POST.get('poll_current_choices[%s]' % option.pk, u'')
+            new_name = new_name.strip()
+            if new_name:
+                self.clean_choices.append(new_name)
+                if new_name != option.name:
+                    option.name = new_name
+                    self.changed_choices.append(option)
+            else:
+                self.deleted_choices.append(option)
+
     def clean_poll_max_choices(self):
         data = self.cleaned_data['poll_max_choices']
         if data < 1:
             raise forms.ValidationError(_("Voters must be allowed to make at least one choice."))
-        if data > len(self.clean_choices):
+        if self.clean_choices and data > len(self.clean_choices):
             raise forms.ValidationError(_("Users cannot cast more votes than there are options."))
         return data
 
@@ -99,10 +117,18 @@ class PollFormMixin(object):
             raise forms.ValidationError(_("Poll length cannot be negative."))
         if data > 300:
             raise forms.ValidationError(_("Poll length cannot be longer than 300 days."))
+        if self.poll:
+            org_length = self.poll.length
+            self.poll.length = data
+            try:
+                if self.poll.over:
+                    raise forms.ValidationError(_("You cannot close poll that way."))
+            finally:
+                org_length = self.poll.length
+                self.poll.length = org_length
         return data
 
     def clean_poll(self, data):
-        data = super(NewThreadForm, self).clean()
         try:
             if bool(data['poll_question']) != bool(self.clean_choices):
                 if bool(data['poll_question']):
@@ -116,6 +142,7 @@ class PollFormMixin(object):
 
 class NewThreadForm(NewThreadFormBase, PollFormMixin):
     def type_fields(self):
+        self.poll = None
         if self.request.acl.threads.can_make_polls(self.forum):
             self.create_poll_form()
 
@@ -128,6 +155,7 @@ class NewThreadForm(NewThreadFormBase, PollFormMixin):
 class EditThreadForm(EditThreadFormBase, PollFormMixin):
     def type_fields(self):
         self.poll = self.thread.poll
+
         if self.poll:
             if self.request.acl.threads.can_edit_poll(self.forum, self.poll):
                 self.edit_poll_form()
@@ -175,4 +203,4 @@ class PollVoteForm(Form):
                                                       self.poll.max_choices) % {'limit': self.poll.max_choices})
         except TypeError:
             pass
-        return data
+        return data

+ 26 - 2
misago/apps/threads/posting.py

@@ -41,7 +41,31 @@ class PollFormMixin(object):
         self.thread.save()
 
     def update_poll(self, form):
-        pass
+        poll = self.thread.poll
+        poll.question = form.cleaned_data['poll_question']
+        poll.max_choices = form.cleaned_data['poll_max_choices']
+        poll.length = form.cleaned_data['poll_length']
+        poll.vote_changing = form.cleaned_data['poll_changing_votes']
+        self.update_poll_choices(poll, form)
+        poll.save()
+
+    def update_poll_choices(self, poll, form):
+        choices = []
+        for option in form.changed_choices:
+            option.save()
+            choices.append(option)
+        for option in form.deleted_choices:
+            poll.votes -= option.votes
+            option.delete()
+        for name in set(form.clean_choices) - set([x.name for x in form.changed_choices]):
+            option = PollOption.objects.create(
+                                               poll=poll,
+                                               forum=self.forum,
+                                               thread=self.thread,
+                                               name=name,
+                                               )
+            choices.append(option)
+        poll.choices_cache = choices
 
     def delete_poll(self):
         self.thread.poll.delete()
@@ -65,7 +89,7 @@ class NewThreadView(NewThreadBaseView, TypeMixin, PollFormMixin):
         return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % self.post.pk))
 
 
-class EditThreadView(EditThreadBaseView, TypeMixin):
+class EditThreadView(EditThreadBaseView, TypeMixin, PollFormMixin):
     form_type = EditThreadForm
 
     def after_form(self, form):

+ 1 - 1
misago/models/pollmodel.py

@@ -9,7 +9,7 @@ except ImportError:
 
 class Poll(models.Model):
     forum = models.ForeignKey('Forum')
-    thread = models.OneToOneField('Thread', primary_key=True)
+    thread = models.OneToOneField('Thread', primary_key=True, related_name='poll_of')
     user = models.ForeignKey('User', null=True, blank=True, on_delete=models.SET_NULL)
     user_name = models.CharField(max_length=255, null=True, blank=True)
     user_slug = models.SlugField(max_length=255, null=True, blank=True)

+ 7 - 0
misago/models/threadmodel.py

@@ -90,6 +90,13 @@ class Thread(models.Model):
     def timeline_date(self):
         return self.start
 
+    @property
+    def poll(self):
+        if self.has_poll:
+            return self.poll_of
+        else:
+            return None
+
     def delete(self, *args, **kwargs):
         """
         FUGLY HAX for weird stuff that happens with

+ 2 - 0
templates/cranefly/threads/poll_votes.html

@@ -27,6 +27,8 @@
       <li><i class="icon-calendar"></i> {% trans end=poll.end_date|date %}Poll ended on {{ end }}{% endtrans %}</li>
       {% elif thread.poll.length %}
       <li><i class="icon-calendar"></i> {% trans end=poll.end_date|date %}Poll ends on {{ end }}{% endtrans %}</li>
+      {% else %}
+      <li><i class="icon-lock"></i> {% trans %}Permanent poll.{% endtrans %}</li>
       {% endif %}
     </ul>
   </div>

+ 13 - 0
templates/cranefly/threads/posting.html

@@ -75,6 +75,19 @@
             <h4>{% if thread and thread.poll %}{% trans %}Edit Poll{% endtrans %}{% else %}{% trans %}Create Poll{% endtrans %}{% endif %}</h4>
             {% if 'poll_question' in form.fields %}
             {{ form_theme.row(form.poll_question, attrs={'class': 'span8'}) }}
+            {% if thread and thread.poll %}
+            <div class="control-group">
+              <label class="control-label">{% trans %}Edit Poll Choices{% endtrans %}:</label>
+              <div class="controls">
+                {% for option in thread.poll.option_set.all() %}
+                <div>
+                  <input type="text" name="poll_current_choices[{{ option.pk }}]" value="{{ option.name }}" class="span8">
+                </div>
+                {% endfor %}
+              </div>
+              <p class="help-block">{% trans %}To delete existing choice, empty its text input.{% endtrans %}</p>
+            </div>
+            {% endif %}
             {{ form_theme.row(form.poll_choices, attrs={'class': 'span8', 'rows': 4}) }}
             {{ form_theme.row(form.poll_max_choices, attrs={'class': 'span8'}) }}
             {{ form_theme.row(form.poll_length, attrs={'class': 'span8'}) }}

+ 2 - 0
templates/cranefly/threads/thread.html

@@ -106,6 +106,8 @@
           {% trans end=poll.end_date|date %}Poll ended on {{ end }}{% endtrans %}
           {% elif thread.poll.length %}
           {% trans end=poll.end_date|date %}Poll ends on {{ end }}{% endtrans %}
+          {% else %}
+          {% trans %}Permanent poll.{% endtrans %}
           {% endif %}
         </p>
       </div>