diff --git a/README.md b/README.md index 1226eea9..13e6bcc1 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,16 @@ The 3rd step will populate the database with a small amount of random data, incl That should be it! +#### Docker Compose + +If you have `docker-compose` installed you should only need these 1-2 commands: + +Start web + db containers: +`docker-compose up` + +Run database migrations (if needed): +`docker-compose run wasaweb python manage.py migrate` + ### Manual installation using pip If you run into errors manually installing with `pip` (or get error output from `pip` wile running `initial_setup.py`), more often than not it's due to you not having MySQL installed. Try commenting those lines out of the `requirements.txt` file and running pip again. diff --git a/VERSION b/VERSION index 70016a7c..f25c43cd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.10.12 +0.10.13 diff --git a/docker-compose.yml b/docker-compose.yml index c00e68bf..4480d8f4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,21 +4,25 @@ # docker-compose up # Then migrate the database: (you might need to run it twice) # docker-compose run wasaweb python manage.py migrate +version: '2' -wasaweb: - build: . - volumes: - - .:/usr/src/app - ports: - - "8000:8000" - links: - - "db" - environment: - - DOCKER_DB_HOST=db -db: - image: mysql - environment: - - MYSQL_ROOT_PASSWORD=docker - - MYSQL_DATABASE=docker - - MYSQL_USER=docker - - MYSQL_PASSWORD=docker +services: + wasaweb: + build: . + volumes: + - .:/usr/src/app + ports: + - "8000:8000" + links: + - "db" + environment: + - DOCKER_DB_HOST=db + depends_on: + - db + db: + image: mysql:5 + environment: + - MYSQL_ROOT_PASSWORD=docker + - MYSQL_DATABASE=docker + - MYSQL_USER=docker + - MYSQL_PASSWORD=docker diff --git a/election/migrations/0010_auto_20180705_2005.py b/election/migrations/0010_auto_20180705_2005.py new file mode 100644 index 00000000..93a62bb6 --- /dev/null +++ b/election/migrations/0010_auto_20180705_2005.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.13 on 2018-07-05 20:05 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('election', '0009_auto_20171201_1340'), + ] + + operations = [ + migrations.RenameField( + model_name='election', + old_name='stats_limit', + new_name='results_limit', + ), + ] diff --git a/election/migrations/0011_auto_20180711_2207.py b/election/migrations/0011_auto_20180711_2207.py new file mode 100644 index 00000000..5557209f --- /dev/null +++ b/election/migrations/0011_auto_20180711_2207.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.13 on 2018-07-11 22:07 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('election', '0010_auto_20180705_2005'), + ] + + operations = [ + migrations.AlterField( + model_name='election', + name='results_limit', + field=models.IntegerField(blank=True, null=True, verbose_name='How many candidates will be publicly listed in the results of an election'), + ), + ] diff --git a/election/models.py b/election/models.py index ff10ebaf..c4e7107b 100644 --- a/election/models.py +++ b/election/models.py @@ -40,6 +40,15 @@ class Election(models.Model): # should to be turned into a proper Django model. results_are_ordered = models.BooleanField(default=True, verbose_name=_('Results are ordered')) + # How many candidates will be publicly listed in the results of an + # election. Officers still see entire list. Individual candidates can also + # see where they ended up in the results. + results_limit = models.IntegerField( + null=True, + blank=True, + verbose_name=_('How many candidates will be publicly listed in the results of an election') + ) + deadline_candidacy = models.DateTimeField(verbose_name=_('Deadline for candidacies')) starttime_votes = models.DateTimeField(null=True, blank=True, verbose_name=_('Election begins')) deadline_votes = models.DateTimeField(verbose_name=_('Election ends')) @@ -60,7 +69,6 @@ class Election(models.Model): # These are election statistics; stats = models.TextField(null=True, blank=True, verbose_name=_('Statistics as JSON')) - stats_limit = models.IntegerField(null=True, blank=True, verbose_name=_('Limit how many candidates we publish stats for')) stats_publish_ballots_basic = models.BooleanField(default=False, verbose_name=_('Publish basic ballot statistics')) stats_publish_ballots_per_candidate = models.BooleanField(default=False, verbose_name=_('Publish ballot statistics for each candidate')) stats_publish_files = models.BooleanField(default=False, verbose_name=_('Publish advanced statistics (downloadable)')) @@ -309,11 +317,11 @@ def get_stats(self, user=None, load_users=True, rename_users=False): # Censor the statistics, if we only want to publish details about # the top N candidates. - if self.stats_limit: + if self.results_limit: excluded = set([]) if not user or not user.is_staff: excluded |= set(cand.user.username for cand in - self.get_winners()[self.stats_limit:]) + self.get_winners()[self.results_limit:]) if user and user.username in excluded: excluded.remove(user.username) stats = BallotCounter.exclude_candidate_stats(stats, excluded) diff --git a/wasa2il/templates/accounts/personal_data.html b/wasa2il/templates/accounts/personal_data.html index ab1c64d9..34cea4a1 100644 --- a/wasa2il/templates/accounts/personal_data.html +++ b/wasa2il/templates/accounts/personal_data.html @@ -19,9 +19,13 @@

{% trans 'Terms and Conditions' %}

{% trans 'Here you can retrieve the latest version of our terms and conditions to which you have provided your consent. There you should find anything you might need regarding to your personal data, including why and how we process it. If not, please let us know!' %}

- - {% trans 'Show terms and conditions' %} - + {% if terms %} + + {% trans 'Show terms and conditions' %} + + {% else %} + {% trans 'No terms and conditions provided yet.' %} + {% endif %}

diff --git a/wasa2il/templates/election/election_view.html b/wasa2il/templates/election/election_view.html index 11d981cc..99441756 100644 --- a/wasa2il/templates/election/election_view.html +++ b/wasa2il/templates/election/election_view.html @@ -211,8 +211,8 @@

{% trans 'Election results' %}

    {% for candidate in ordered_candidates %} - {% if not election.stats_limit or forloop.counter <= election.stats_limit or candidate.user == user or user.is_staff %} -
  1. election.stats_limit %} style="background: #efe;"{% endif %}> + {% if not election.results_limit or forloop.counter <= election.results_limit or candidate.user == user or user.is_staff %} +
  2. election.results_limit %} style="background: #efe;"{% endif %}>
    {{ candidate.user.get_name }} @@ -226,7 +226,7 @@

    {% trans 'Election results' %}

    {% endwith %}
    {% endif %} - {% if election.stats_limit and forloop.counter > election.stats_limit %} + {% if election.results_limit and forloop.counter > election.results_limit %} {% trans "for your eyes only" %} {% endif %}
@@ -260,7 +260,7 @@

{% trans 'Election results' %}

XLS
{% trans "Downloads include rankings, pairwise victories and ballot counts." %} - {% if election.stats_limit %}{% with election.stats_limit as limit %}{% blocktrans %} + {% if election.results_limit %}{% with election.results_limit as limit %}{% blocktrans %} Details below {{limit}}. place are omitted except for the candidates themselves and members of staff. {% endblocktrans %}{% endwith %}{% endif %}