diff --git a/README.md b/README.md index 626383f3ae92cc853959f9b27122885fd71b8a49..4523eefb0ee9ae3727baf6b736000b42ac34177c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Helios is an end-to-end verifiable voting system. ## Info -vÄ›tve v gitu: +VÄ›tve v gitu: - `original` je kopie https://github.com/benadida/helios-server - `master` je z `original` odvozená Pirátská verze nasazená v produkci diff --git a/helios/fields.py b/helios/fields.py index 8d8e885fec3c13f72a0c24cd6ea0d7a39ab80d5c..e8eafff4e3665b0e4b8c18904ea7595d4b42b285 100644 --- a/helios/fields.py +++ b/helios/fields.py @@ -1,6 +1,8 @@ import datetime +import pytz from django.forms import fields +from django.utils.timezone import make_aware, make_naive from .widgets import SplitSelectDateTimeWidget @@ -25,6 +27,8 @@ class SplitDateTimeField(fields.MultiValueField): if data_list: if not (data_list[0] and data_list[1]): return None - return datetime.datetime.combine(*data_list) + value = datetime.datetime.combine(*data_list) + # do formuláře zadáváme Europe/Prague, ale do DB se ukládá naivnĂ UTC + return make_naive(make_aware(value, pytz.timezone("Europe/Prague")), pytz.UTC) return None diff --git a/helios/forms.py b/helios/forms.py index f7540a54c150eed4c4edf384e6b3dd8553c17d3b..b1d6687fda8534bb076007007f84a595730ea82c 100644 --- a/helios/forms.py +++ b/helios/forms.py @@ -3,8 +3,11 @@ Forms for Helios """ +import pytz + from django import forms from django.conf import settings +from django.utils.timezone import make_aware, make_naive from .fields import SplitDateTimeField from .models import Election @@ -21,18 +24,24 @@ class ElectionForm(forms.Form): randomize_answer_order = forms.BooleanField(required=False, initial=False, help_text=u'zvolte, pokud chcete, aby se kaĹľdĂ©mu voliÄŤi zobrazovaly odpovÄ›di na otázky v náhodnÄ› zvolenĂ©m poĹ™adĂ', label=u"OdpovÄ›di v náhodnĂ©m poĹ™adĂ") private_p = forms.BooleanField(required=False, initial=False, label=u"SoukromĂ©?", help_text=u'SoukromĂ© hlasovánĂ je viditelnĂ© jen pro registrovanĂ© voliÄŤe.') help_email = forms.CharField(required=False, initial="", label=u"E-mail pro nápovÄ›du", help_text=u'e-mailová adresa, na kterou se budou voliÄŤi obracet s žádostmi o pomoc.') - voting_starts_at = SplitDateTimeField(help_text = u'datum a ÄŤas zahájenĂ hlasovánĂ; v UTC, takĹľe oproti ÄŤasovĂ©mu pásmu ÄŚR je menšà o 1 hodinu v zimnĂm, resp. o 2 hodiny v letnĂm ÄŤase', - widget=SplitSelectDateTimeWidget, required=False, label=u"HlasovánĂ zaÄŤĂná v") - voting_ends_at = SplitDateTimeField(help_text = u'datum a ÄŤas ukonÄŤenĂ hlasovánĂ; v UTC, takĹľe oproti ÄŤasovĂ©mu pásmu ÄŚR je menšà o 1 v zimnĂm, resp. o 2 hodiny v letnĂm ÄŤase', - widget=SplitSelectDateTimeWidget, required=False, label=u"HlasovánĂ konÄŤĂ v") + voting_starts_at = SplitDateTimeField(help_text = u'datum a ÄŤas zahájenĂ hlasovánĂ v lokálnĂm ÄŤase!', widget=SplitSelectDateTimeWidget, required=False, label=u"HlasovánĂ zaÄŤĂná v") + voting_ends_at = SplitDateTimeField(help_text = u'datum a ÄŤas ukonÄŤenĂ hlasovánĂ v lokálnĂm ÄŤase!', widget=SplitSelectDateTimeWidget, required=False, label=u"HlasovánĂ konÄŤĂ v") if settings.ALLOW_ELECTION_INFO_URL: election_info_url = forms.CharField(required=False, initial="", label=u"URL pro staĹľenĂ informacĂ o hlasovánĂ", help_text=u"URL dokumentu ve formátu PDF, obsahujĂcĂho doplĹkovĂ© informace k hlasovánĂ, napĹ™. Ĺľivotopisy a profily kandidátĹŻ") - pass + def __init__(self, data=None, *args, **kwargs): + # v DB se ukládá naivnĂ UTC, ale do formuláře potĹ™ebujeme pĹ™evĂ©st zpÄ›t na Europe/Prague + if data: + tz = pytz.timezone("Europe/Prague") + if "voting_starts_at" in data: + data["voting_starts_at"] = make_naive(make_aware(data["voting_starts_at"], pytz.UTC), tz) + if "voting_ends_at" in data: + data["voting_ends_at"] = make_naive(make_aware(data["voting_ends_at"], pytz.UTC), tz) + super().__init__(data, *args, **kwargs) class ElectionTimeExtensionForm(forms.Form): - voting_extended_until = SplitDateTimeField(help_text = u'datum a ÄŤas prodlouĹľenĂ©ho ukonÄŤenĂ hlasovánĂ; v UTC', + voting_extended_until = SplitDateTimeField(help_text = u'datum a ÄŤas prodlouĹľenĂ©ho ukonÄŤenĂ hlasovánĂ; v lokálnĂm ÄŤase!', widget=SplitSelectDateTimeWidget, required=False, label=u"HlasovánĂ prodlouĹľeno do") class EmailVotersForm(forms.Form): diff --git a/helios/templates/election_not_started.html b/helios/templates/election_not_started.html index 3735a12a4466af35e9171d9bf42caec1f0ba9c9e..18cd5c9f74d1efac60e440d4f0f8b43676f4ca04 100644 --- a/helios/templates/election_not_started.html +++ b/helios/templates/election_not_started.html @@ -1,4 +1,5 @@ {% extends TEMPLATE_BASE %} +{% load tz %} {% block content %} @@ -9,8 +10,8 @@ </p> <p> - {% if election.voting_start_at %}začátek hlasovánĂ: {{election.voting_start_at}}<br />{% endif %} - {% if election.voting_end_at %}konec hlasovánĂ: {{election.voting_end_at}}<br />{% endif %} + {% if election.voting_start_at %}začátek hlasovánĂ: {{election.voting_start_at|timezone:"Europe/Prague"}}<br />{% endif %} + {% if election.voting_end_at %}konec hlasovánĂ: {{election.voting_end_at|timezone:"Europe/Prague"}}<br />{% endif %} </p> <p> diff --git a/helios/templates/election_tallied.html b/helios/templates/election_tallied.html index dd729d281e1df1a542157f443a56b623ed4bc341..b46d21533dde43794fb51671470d51c13a338582 100644 --- a/helios/templates/election_tallied.html +++ b/helios/templates/election_tallied.html @@ -1,4 +1,5 @@ {% extends TEMPLATE_BASE %} +{% load tz %} {% block content %} @@ -9,8 +10,8 @@ </p> <p> - {% if election.voting_start_at %}začátek hlasovánĂ: {{election.voting_start_at}}<br />{% endif %} - {% if election.voting_end_at %}konec hlasovánĂ: {{election.voting_end_at}}<br />{% endif %} + {% if election.voting_start_at %}začátek hlasovánĂ: {{election.voting_start_at|timezone:"Europe/Prague"}}<br />{% endif %} + {% if election.voting_end_at %}konec hlasovánĂ: {{election.voting_end_at|timezone:"Europe/Prague"}}<br />{% endif %} </p> <p> diff --git a/helios/templates/election_view.html b/helios/templates/election_view.html index 0d04aa626c75e4791aadc6a01618714450ebe77f..6617500603328778cfc4527d893bb32c23e6f411 100644 --- a/helios/templates/election_view.html +++ b/helios/templates/election_view.html @@ -1,4 +1,5 @@ {% extends TEMPLATE_BASE %} +{% load tz %} {% block title %}{{election.name}}{% endblock %} {% block content %} <div style="float: left; margin-right: 50px;"> @@ -48,8 +49,8 @@ toto {{election.election_type}} <u>nenĂ</u> zobrazeno na titulnĂ stránce. <p> {% if election.help_email and admin_p%}Email pro nápovÄ›du: {{election.help_email}}<br />{% endif %} -{% if election.voting_start_at %}HlasovánĂ zaÄŤĂná: {{election.voting_start_at}}<br />{% endif %} -{% if election.voting_end_at %}HlasovánĂ konÄŤĂ: {{election.voting_end_at}}<br />{% endif %} +{% if election.voting_start_at %}HlasovánĂ zaÄŤĂná: {{election.voting_start_at|timezone:"Europe/Prague"}}<br />{% endif %} +{% if election.voting_end_at %}HlasovánĂ konÄŤĂ: {{election.voting_end_at|timezone:"Europe/Prague"}}<br />{% endif %} </p> {% if election.election_info_url %} @@ -97,7 +98,7 @@ toto {{election.election_type}} <u>nenĂ</u> zobrazeno na titulnĂ stránce. <br /> {% if election.voting_starts_at %} jakmile to uÄŤinĂte, hlasovánĂ bude pĹ™ipraveno k odevzdávánĂ hlasovacĂch lĂstkĹŻ a bude automaticky zahájeno<br /> -v {{election.voting_starts_at}}, podle vašeho nastavenĂ. +v {{election.voting_starts_at|timezone:"Europe/Prague"}}, podle vašeho nastavenĂ. {% else %} jakmile to uÄŤinĂte, hlasovánĂ bude ihned zahájeno. {% endif %} @@ -158,7 +159,7 @@ PotĂ© uvidĂte vĂ˝sledek pouze vy jakoĹľto zakladatel hlasovánĂ. {% if show_result %} {% if election.result_released_at %} <span class="highlight-box round"> - Toto hlasovánĂ bylo ukonÄŤeno. VĂ˝sledek byl zveĹ™ejnÄ›n {{election.result_released_at}}. Celkem bylo odevzdáno {{election.num_cast_votes}} hlasĹŻ. +Toto hlasovánĂ bylo ukonÄŤeno. VĂ˝sledek byl zveĹ™ejnÄ›n {{election.result_released_at|timezone:"Europe/Prague"}}. Celkem bylo odevzdáno {{election.num_cast_votes}} hlasĹŻ. </span><br /><br /><br /> {% endif %} @@ -185,12 +186,12 @@ PotĂ© uvidĂte vĂ˝sledek pouze vy jakoĹľto zakladatel hlasovánĂ. <br /> <br /> {% if election.voting_extended_until %} -Toto {{election.election_type}} mÄ›lo pĹŻvodnÄ› skonÄŤit v {{election.voting_ends_at}} (UTC),<br /> -ale bylo prodlouĹľeno do {{ election.voting_extended_until }} (UTC). +Toto {{election.election_type}} mÄ›lo pĹŻvodnÄ› skonÄŤit v {{election.voting_ends_at|timezone:"Europe/Prague"}},<br /> +ale bylo prodlouĹľeno do {{ election.voting_extended_until|timezone:"Europe/Prague" }}. {% else %} {% if election.voting_ends_at %} <br /> -Toto {{election.election_type}} bude uzavĹ™eno v {{election.voting_ends_at}} (UTC). +Toto {{election.election_type}} bude uzavĹ™eno v {{election.voting_ends_at|timezone:"Europe/Prague"}}. {% else %} Toto {{election.election_type}} bude uzavĹ™eno podle rozhodnutĂ jeho zakladatele. {% endif %} diff --git a/helios/templates/email/vote_body.txt b/helios/templates/email/vote_body.txt index 8503778eec770ea6ca55df5cdc9ca1708f0148cf..6e42d0873eb48f6ee183248930307efebb3008a1 100644 --- a/helios/templates/email/vote_body.txt +++ b/helios/templates/email/vote_body.txt @@ -1,11 +1,12 @@ +{% load tz %} VáženĂ˝ {{voter.name}}, {{custom_message|safe}} URL HlasovánĂ: {{election_vote_url}} Otisk HlasovánĂ©: {{voter.election.hash}} -{% if election.voting_start_at %}HlasovánĂ zaÄŤĂná {{election.voting_start_at}} -{% endif %}{% if election.voting_end_at %}HlasovánĂ konÄŤĂ {{election.voting_end_at}} +{% if election.voting_start_at %}HlasovánĂ zaÄŤĂná {{election.voting_start_at|timezone:"Europe/Prague"}} +{% endif %}{% if election.voting_end_at %}HlasovánĂ konÄŤĂ {{election.voting_end_at|timezone:"Europe/Prague"}} {% endif %} {% ifequal voter.voter_type "password" %} diff --git a/helios/widgets.py b/helios/widgets.py index ba271ce70e67b0485b4fc6b4daef75941fc2d8de..3e8c36db25f478bda1a6cde6b77ae34b687ebc51 100644 --- a/helios/widgets.py +++ b/helios/widgets.py @@ -95,16 +95,17 @@ class SelectTimeWidget(Widget): self.meridiem_val = 'a.m.' else: self.meridiem_val = None - + # If we're doing a 12-hr clock, there will be a meridiem value, so make sure the # hours get printed correctly if self.twelve_hr and self.meridiem_val: if self.meridiem_val.lower().startswith('p') and hour_val > 12 and hour_val < 24: hour_val = hour_val % 12 - elif hour_val == 0: - hour_val = 12 - + # BUG this breaks 24h clock on 0 hours + # elif hour_val == 0: + # hour_val = 12 + output = [] if 'id' in self.attrs: id_ = self.attrs['id'] diff --git a/settings.py b/settings.py index 05fed0bbd467c6693e06a2e4ce95e8d9df33749c..a158572929f1ffd11b7e3b7080c92d33aa8e2894 100644 --- a/settings.py +++ b/settings.py @@ -62,11 +62,11 @@ if get_from_env('DATABASE_URL', None): # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = 'America/Los_Angeles' +TIME_ZONE = 'UTC' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'cs-cz' SITE_ID = 1 @@ -74,6 +74,8 @@ SITE_ID = 1 # to load the internationalization machinery. USE_I18N = True +USE_L10N = True + # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = ''