Skip to content
Snippets Groups Projects
Commit c1a8e826 authored by jan.bednarik's avatar jan.bednarik
Browse files

API with elections and voters

parent 4cb4b564
No related branches found
No related tags found
No related merge requests found
Pipeline #17029 passed
from django.apps import AppConfig
class HeliosConfig(AppConfig):
name = "api"
verbose_name = "API"
<!DOCTYPE html>
<html>
<body>
<h1>Helios API</h1>
<h2>Examples</h2>
<hr>
<pre>
GET /api/user/&lt;username&gt;/elections/
GET /api/user/&lt;username&gt;/elections/?limit=10
GET /api/elections/
GET /api/elections/?limit=10
GET /api/elections/&lt;uuid&gt;/voters/
</pre>
<hr>
<p>* default limits are 100 objects</p>
</body>
</html>
from django.conf.urls import url
from . import views
urlpatterns = [
url(r"^$", views.IndexView.as_view()),
url(r"^user/(?P<username>[^/]+)/elections/$", views.UserElectionsView.as_view()),
url(r"^elections/$", views.ElectionsView.as_view()),
url(r"^elections/(?P<uuid>[^/]+)/voters/$", views.ElectionVotersView.as_view()),
]
import pytz
from django.http import JsonResponse
from django.views.generic import TemplateView, View
from helios.models import Election
from helios_auth.models import User
DEFAULT_LIMIT = 100
class JsonView(View):
def get_payload(self, request, *args, **kwargs):
raise NotImplementedError
def get(self, request, *args, **kwargs):
return JsonResponse(self.get_payload(request, *args, **kwargs))
class IndexView(TemplateView):
template_name = "api/index.html"
def election_as_dict(election):
voting_start_at = (
election.voting_start_at.replace(tzinfo=pytz.UTC)
if election.voting_start_at
else None
)
voting_end_at = (
election.voting_end_at.replace(tzinfo=pytz.UTC)
if election.voting_end_at
else None
)
return {
"name": election.name,
"uuid": election.uuid,
"short_name": election.short_name,
"url": election.url,
"created_at": election.created_at,
"voting_has_started": election.voting_has_started(),
"voting_has_stopped": election.voting_has_stopped(),
"voting_start_at": voting_start_at,
"voting_end_at": voting_end_at,
}
class ElectionsView(JsonView):
def get_payload(self, request, *args, **kwargs):
limit = int(request.GET.get("limit", DEFAULT_LIMIT))
qs = Election.objects.exclude(frozen_at=None).order_by("-created_at")[:limit]
elections = []
for election in qs:
elections.append(election_as_dict(election))
return {"elections": elections}
class UserElectionsView(JsonView):
def get_payload(self, request, username, *args, **kwargs):
try:
user = User.objects.get(user_id__iexact=username)
except User.DoesNotExist:
return {}
limit = int(request.GET.get("limit", DEFAULT_LIMIT))
qs = (
user.voter_set.all()
.order_by("-election__created_at")
.select_related("election")[:limit]
)
elections = []
for voter in qs:
election = election_as_dict(voter.election)
election["user_has_voted"] = voter.vote_hash is not None
elections.append(election)
return {"username": username, "elections": elections}
class ElectionVotersView(JsonView):
def get_payload(self, request, uuid, *args, **kwargs):
try:
election = Election.objects.get(uuid=uuid)
except Election.DoesNotExist:
return {}
result = election_as_dict(election)
result["voters"] = []
voters = (
election.voter_set.all()
.values_list("user__user_id", "vote_hash")
.order_by("user__user_id")
)
for user_id, vote_hash in voters:
result["voters"].append(
{"username": user_id, "has_voted": vote_hash is not None}
)
return result
manage.py 100644 → 100755
File mode changed from 100644 to 100755
......@@ -166,6 +166,7 @@ INSTALLED_APPS = (
'helios_auth',
'helios',
'server_ui',
'api',
)
ANYMAIL = {
......
......@@ -15,5 +15,7 @@ urlpatterns = [
url(r'static/helios/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/helios/media'}),
url(r'static/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/server_ui/media'}),
url(r'^api/', include('api.urls')),
url(r'^', include('server_ui.urls')),
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment