Commit 132422fe authored by Wietse Kuipers's avatar Wietse Kuipers
Browse files

Merge branch 'thaliapp/members-api' into 'master'

Thaliapp: members api

See merge request !490
parents 36a73f5f f9c0313e
from base64 import b64encode
from django.contrib.staticfiles.finders import find as find_static_file
from django.templatetags.static import static
from django.urls import reverse
from rest_framework import serializers
from events.api.serializers import CalenderJSSerializer
from members.models import Member
from members.services import member_achievements
from thaliawebsite.settings import settings
class MemberBirthdaySerializer(CalenderJSSerializer):
......@@ -40,3 +47,58 @@ class MemberBirthdaySerializer(CalenderJSSerializer):
def _text_color(self, instance):
return 'white'
class MemberRetrieveSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = ('pk', 'display_name', 'photo',
'birthday', 'starting_year', 'programme',
'website', 'membership_type', 'achievements')
photo = serializers.SerializerMethodField('_b64_photo')
birthday = serializers.SerializerMethodField('_birthday')
membership_type = serializers.SerializerMethodField('_membership_type')
achievements = serializers.SerializerMethodField('_achievements')
def _birthday(self, instance):
if instance.show_birthday:
return instance.birthday
return None
def _membership_type(self, instance):
membership = instance.current_membership
if membership:
return membership.type
return None
def _achievements(self, instance):
return member_achievements(instance)
def _b64_photo(self, instance):
if instance.photo:
photo = ''.join(['data:image/jpeg;base64,',
b64encode(instance.photo.file.read()).decode()])
else:
filename = find_static_file('members/images/default-avatar.jpg')
with open(filename, 'rb') as f:
photo = ''.join(['data:image/jpeg;base64,',
b64encode(f.read()).decode()])
return photo
class MemberListSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = ('pk', 'display_name', 'photo',)
photo = serializers.SerializerMethodField('_photo')
def _photo(self, instance):
if instance.photo:
return self.context['request'].build_absolute_uri(
'%s%s' % (settings.MEDIA_URL, instance.photo))
else:
return self.context['request'].build_absolute_uri(
static('members/images/default-avatar.jpg'))
......@@ -2,19 +2,35 @@ import copy
from datetime import datetime
from django.utils import timezone
from rest_framework import viewsets
from rest_framework import permissions
from rest_framework import viewsets, filters
from rest_framework.decorators import list_route
from rest_framework.exceptions import ParseError
from rest_framework.response import Response
from rest_framework import permissions
from members.api.serializers import MemberBirthdaySerializer
from members.api.serializers import (MemberBirthdaySerializer,
MemberRetrieveSerializer,
MemberListSerializer)
from members.models import Member
class MemberViewset(viewsets.ViewSet):
class MemberViewset(viewsets.ReadOnlyModelViewSet):
queryset = Member.objects.all()
permission_classes = (permissions.IsAuthenticated,)
filter_backends = (filters.OrderingFilter, filters.SearchFilter,)
ordering_fields = ('starting_year', 'user__first_name', 'user__last_name')
search_fields = ('nickname', 'user__first_name',
'user__last_name', 'user__username')
def get_serializer_class(self):
if self.action == 'retrieve' or self.action == 'me':
return MemberRetrieveSerializer
return MemberListSerializer
def get_queryset(self):
if self.action == 'list':
return Member.active_members
return Member.objects.all()
def _get_birthdays(self, member, start, end):
birthdays = []
......@@ -47,10 +63,9 @@ class MemberViewset(viewsets.ViewSet):
raise ParseError(detail='start or end query parameters invalid')
queryset = (
Member
.active_members
.with_birthdays_in_range(start, end)
.filter(show_birthday=True)
Member.active_members
.with_birthdays_in_range(start, end)
.filter(show_birthday=True)
)
all_birthdays = [
......@@ -61,3 +76,8 @@ class MemberViewset(viewsets.ViewSet):
serializer = MemberBirthdaySerializer(birthdays, many=True)
return Response(serializer.data)
@list_route()
def me(self, request):
serializer = self.get_serializer_class()(request.user.member)
return Response(serializer.data)
from datetime import date
def member_achievements(member):
memberships = member.committeemembership_set.all()
achievements = {}
for membership in memberships:
period = {
'since': membership.since,
'until': membership.until,
'chair': membership.chair
}
if hasattr(membership.committee, 'board'):
period['role'] = membership.role
if (membership.until is None and
hasattr(membership.committee, 'board')):
period['until'] = membership.committee.board.until
name = membership.committee.name
if achievements.get(name):
achievements[name]['periods'].append(period)
if achievements[name]['earliest'] > membership.since:
achievements[name]['earliest'] = membership.since
achievements[name]['periods'].sort(key=lambda x: x['since'])
else:
achievements[name] = {
'name': name,
'periods': [period],
'earliest': membership.since,
}
mentor_years = member.mentorship_set.all()
for mentor_year in mentor_years:
name = "Mentor in {}".format(mentor_year.year)
# Ensure mentorships appear last but are sorted
earliest = date.today()
earliest = earliest.replace(year=earliest.year + mentor_year.year)
if not achievements.get(name):
achievements[name] = {
'name': name,
'earliest': earliest,
}
return sorted(achievements.values(), key=lambda x: x['earliest'])
......@@ -10,6 +10,7 @@ from django.utils.text import slugify
from django.utils.translation import gettext as _
from sendfile import sendfile
from members.services import member_achievements
from . import models
from .forms import MemberForm
......@@ -98,46 +99,7 @@ def profile(request, pk=None):
member = get_object_or_404(models.Member, user=request.user)
# Group the memberships under the committees for easier template rendering
memberships = member.committeemembership_set.all()
achievements = {}
for membership in memberships:
period = {
'since': membership.since,
'until': membership.until,
'chair': membership.chair
}
if hasattr(membership.committee, 'board'):
period['role'] = membership.role
if (membership.until is None and
hasattr(membership.committee, 'board')):
period['until'] = membership.committee.board.until
name = membership.committee.name
if achievements.get(name):
achievements[name]['periods'].append(period)
if achievements[name]['earliest'] > membership.since:
achievements[name]['earliest'] = membership.since
achievements[name]['periods'].sort(key=lambda x: x['since'])
else:
achievements[name] = {
'name': name,
'periods': [period],
'earliest': membership.since,
}
mentor_years = member.mentorship_set.all()
for mentor_year in mentor_years:
name = "Mentor in {}".format(mentor_year.year)
# Ensure mentorships appear last but are sorted
earliest = date.today()
earliest = earliest.replace(year=earliest.year + mentor_year.year)
if not achievements.get(name):
achievements[name] = {
'name': name,
'earliest': earliest,
}
achievements = sorted(achievements.values(), key=lambda x: x['earliest'])
achievements = member_achievements(member)
membership = member.current_membership
membership_type = _("Former member")
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment