views.py 7.19 KB
Newer Older
1
import json
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
2
import os
3
from datetime import date, datetime
4

5 6
from django.contrib.auth.decorators import login_required
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
7
from django.db.models import Q
8 9
from django.shortcuts import get_object_or_404, render
from django.utils.text import slugify
10
from django.utils.translation import gettext as _
11
from sendfile import sendfile
12

Thom Wiggers's avatar
Thom Wiggers committed
13
from . import models
14
from .forms import MemberForm
15

16

17
@login_required
18
def index(request):
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
19 20 21 22
    query_filter = '' if request.GET.get(
        'filter') is None else request.GET.get('filter')
    keywords = '' if request.GET.get('keywords') is None else request.GET.get(
        'keywords')
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
23 24

    page = request.GET.get('page')
25 26 27
    page = 1 if page is None or not page.isdigit() else int(page)

    start_year = date.today().year - 4
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
28 29
    # If language is English show one year less
    # since the width is smaller than needed for the translations to fit
30 31 32 33
    if request.LANGUAGE_CODE == 'en':
        start_year += 1
    year_range = reversed(range(start_year, date.today().year + 1))

34 35
    memberships_query = Q(until__gt=datetime.now()) | Q(until=None)
    members_query = ~Q(id=None)
36

37
    if query_filter and query_filter.isdigit() and not (
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
38 39
                        query_filter == 'ex' or
                        query_filter == 'honor' or
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
40
                        query_filter == 'old'):
41
        members_query &= Q(starting_year=int(query_filter))
42
    elif query_filter == 'old':
43
        members_query &= Q(starting_year__lt=start_year)
44
    elif query_filter == 'ex':
45 46 47
        memberships = models.Membership.objects.filter(memberships_query)
        members_query &= ~Q(user__in=memberships.values('user'))
        memberships_query = Q(type='member') & Q(until__lte=datetime.now())
48
    elif query_filter == 'honor':
49 50 51 52 53 54 55 56 57 58 59
        memberships_query = Q(until__gt=datetime.now().date()) | Q(until=None)
        memberships_query &= Q(type='honorary')

    if keywords is not None:
        memberships_query &= (Q(user__member__nickname__icontains=keywords) |
                              Q(user__first_name__icontains=keywords) |
                              Q(user__last_name__icontains=keywords) |
                              Q(user__username__icontains=keywords))

    memberships = models.Membership.objects.filter(memberships_query)
    members_query &= Q(user__in=memberships.values('user'))
60 61
    members = models.Member.objects.filter(members_query).order_by(
            '-starting_year', 'user__first_name')
62 63 64

    paginator = Paginator(members, 24)

Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
65 66 67 68 69 70 71 72 73
    try:
        members = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        members = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        members = paginator.page(paginator.num_pages)

74 75 76
    page_range = range(1, paginator.num_pages + 1)
    if paginator.num_pages > 7:
        if page > 3:
77 78 79 80
            page_range_end = paginator.num_pages
            if page + 3 <= paginator.num_pages:
                page_range_end = page + 3

Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
81
            page_range = range(page - 2, page_range_end)
82 83 84 85
            while page_range.stop - page_range.start < 5:
                page_range = range(page_range.start - 1, page_range.stop)
        else:
            page_range = range(1, 6)
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
86

Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
87 88 89 90
    return render(request, 'members/index.html',
                  {'members': members, 'filter': query_filter,
                   'year_range': year_range, 'page_range': page_range,
                   'keywords': keywords})
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
91 92


93
@login_required
94 95
def profile(request, pk=None):
    if pk:
Thom Wiggers's avatar
Thom Wiggers committed
96
        member = get_object_or_404(models.Member, pk=int(pk))
97
    else:
Thom Wiggers's avatar
Thom Wiggers committed
98
        member = get_object_or_404(models.Member, user=request.user)
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
99

100 101 102 103
    # Group the memberships under the committees for easier template rendering
    memberships = member.committeemembership_set.all()
    achievements = {}
    for membership in memberships:
104 105 106 107 108 109
        period = {
            'since': membership.since,
            'until': membership.until,
            'chair': membership.chair
        }

110 111 112
        if hasattr(membership.committee, 'board'):
            period['role'] = membership.role

113 114 115 116
        if (membership.until is None and
                hasattr(membership.committee, 'board')):
            period['until'] = membership.committee.board.until

117 118
        name = membership.committee.name
        if achievements.get(name):
119
            achievements[name]['periods'].append(period)
120 121
            if achievements[name]['earliest'] > membership.since:
                achievements[name]['earliest'] = membership.since
122
            achievements[name]['periods'].sort(key=lambda x: x['since'])
123 124 125
        else:
            achievements[name] = {
                'name': name,
126
                'periods': [period],
127
                'earliest': membership.since,
128
            }
129
    mentor_years = member.mentorship_set.all()
130
    for mentor_year in mentor_years:
Thom Wiggers's avatar
Thom Wiggers committed
131
        name = "Mentor in {}".format(mentor_year.year)
132 133 134
        # Ensure mentorships appear last but are sorted
        earliest = date.today()
        earliest = earliest.replace(year=earliest.year + mentor_year.year)
135 136
        if not achievements.get(name):
            achievements[name] = {
137 138
                'name': name,
                'earliest': earliest,
139
            }
140
    achievements = sorted(achievements.values(), key=lambda x: x['earliest'])
141 142 143 144 145

    membership = member.current_membership
    membership_type = _("Former member")
    if membership:
        membership_type = membership.get_type_display()
146
    return render(request, 'members/profile.html',
147 148 149 150 151
                  {
                      'achievements': achievements,
                      'member': member,
                      'membership_type': membership_type,
                   })
152

153

154 155 156 157
@login_required
def account(request):
    return render(request, 'members/account.html')

158

159 160
@login_required
def edit_profile(request):
Thom Wiggers's avatar
Thom Wiggers committed
161
    member = get_object_or_404(models.Member, user=request.user)
162
    saved = False
163 164

    if request.POST:
165
        form = MemberForm(request.POST, request.FILES, instance=member)
166
        if form.is_valid():
167
            saved = True
168 169 170
            form.save()
    else:
        form = MemberForm(instance=member)
171 172

    return render(request, 'members/edit_profile.html',
173
                  {'form': form, 'saved': saved})
174

175 176

def become_a_member(request):
Thom Wiggers's avatar
Thom Wiggers committed
177
    context = {'documents': models.BecomeAMemberDocument.objects.all()}
178 179 180 181
    return render(request, 'singlepages/become_a_member.html', context)


def get_become_a_member_document(request, pk):
Thom Wiggers's avatar
Thom Wiggers committed
182
    document = get_object_or_404(models.BecomeAMemberDocument, pk=int(pk))
183
    ext = os.path.splitext(document.file.path)[1]
Thom Wiggers's avatar
Thom Wiggers committed
184 185 186
    return sendfile(request,
                    document.file.path,
                    attachment=True,
187
                    attachment_filename=slugify(document.name) + ext)
188 189 190


def statistics(request):
191
    member_types = ("member", "supporter", "honorary")
192 193

    # The numbers
Thom Wiggers's avatar
Thom Wiggers committed
194
    total = models.Member.active_members.count()
195 196

    context = {
Thom Wiggers's avatar
Thom Wiggers committed
197
        "total_members": total,
198 199 200
        "total_stats_year": json.dumps(models.gen_stats_year(member_types)),
        "total_stats_member_type": json.dumps(
            models.gen_stats_member_type(member_types)),
201 202 203
    }

    return render(request, 'members/statistics.html', context)