990d6b853f
This is kind of a huge, monolithic commit. Templates were being served as static files, so Django template tags could not be used for, e.g. internationalization. Now all html files are served as Django templates.
257 lines
9.1 KiB
Python
257 lines
9.1 KiB
Python
from django.shortcuts import render, get_object_or_404
|
|
from django.contrib.auth.decorators import permission_required
|
|
from django.views.decorators.http import require_http_methods
|
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
|
from django.http import HttpResponse, HttpResponseBadRequest
|
|
from django.core.exceptions import ValidationError
|
|
from members.models import Member, MemberRequest
|
|
import json
|
|
from django.core.mail import send_mail
|
|
import requests
|
|
from django.conf import settings
|
|
import logging
|
|
|
|
# Logger function, you can use the same idea when implementing other loggers to other apps
|
|
memberlogger = logging.getLogger(__name__)
|
|
logging.basicConfig(format='[%(levelname)s]%(asctime)s %(message)s', level=settings.LOGGERLEVEL, filename=settings.LOGPATH)
|
|
|
|
|
|
# function to validate reCaptcha
|
|
def validate_recaptcha(response):
|
|
values = {
|
|
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
|
|
'response': response,
|
|
}
|
|
url = "https://www.google.com/recaptcha/api/siteverify"
|
|
headers = {'Content-type': 'application/x-www-form-urlencoded'}
|
|
resp = requests.post(url, values, headers=headers)
|
|
result = json.loads(resp.text)
|
|
memberlogger.info(result)
|
|
if not result["success"]:
|
|
return False
|
|
return True
|
|
|
|
|
|
def send_mail_wrapper(subject, message):
|
|
send_mail(
|
|
subject,
|
|
message,
|
|
'no-reply@sahkoinsinoorikilta.fi',
|
|
['viestintamestari@sahkoinsinoorikilta.fi'],
|
|
fail_silently=False
|
|
)
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def member_list(request, *args, **kwargs):
|
|
context = {}
|
|
return render(request, 'member_list.html', context)
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def add_member(request, *args, **kwargs):
|
|
return render(request, 'add_member.html', {})
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def add_many_members(request, *args, **kwargs):
|
|
return render(request, 'add_many_members.html', {})
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def list_applications(request, *args, **kwargs):
|
|
return render(request, 'list_applications.html', {})
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def tommy_blooper(request, *args, **kwargs):
|
|
return render(request, 'tommy_blooper.html', {})
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def edit_member(request, *args, **kwargs):
|
|
i = kwargs.pop('index', None);
|
|
if i is None:
|
|
return HttpResponse(status=500, error="{'error': 'No member id specified'}")
|
|
else:
|
|
return render(request, 'edit_member.html', {'member_id' : i})
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def edit_application(request, *args, **kwargs):
|
|
i = kwargs.pop('index', None);
|
|
if i is None:
|
|
return HttpResponse(status=500, error="{'error': 'No member id specified'}")
|
|
else:
|
|
return render(request, 'edit_application.html', {'member_id' : i})
|
|
|
|
@ensure_csrf_cookie
|
|
def application_index(request, *args, **kwargs):
|
|
return render(request, 'application_index.html', {})
|
|
|
|
@ensure_csrf_cookie
|
|
def application_success_index(request, *args, **kwargs):
|
|
return render(request, 'application_success.html', {})
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def members(request, *args, **kwargs):
|
|
mems = list(map(lambda m: m.get_dict(), Member.objects.all()))
|
|
return HttpResponse(json.dumps(mems))
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET", "POST", "DELETE", "PUT"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def member(request, *args, **kwargs):
|
|
|
|
# get, put and delete together since all operate on existing objects
|
|
if request.method in ['GET', 'PUT', 'DELETE']:
|
|
|
|
# get object by id or give 404
|
|
idx = kwargs.pop("idx", None)
|
|
try:
|
|
mem = Member.objects.get(pk=idx)
|
|
except Member.DoesNotExist:
|
|
resp = HttpResponse('{"error":"object not found"}')
|
|
resp.status_code = 404
|
|
return resp
|
|
|
|
# delete object if requested
|
|
if request.method == 'DELETE':
|
|
try:
|
|
mem.delete()
|
|
return HttpResponse('{"status":"success"}')
|
|
except:
|
|
resp = HttpResponse('{"error" : "could not delete object"}')
|
|
resp.status_code = 500
|
|
return resp
|
|
|
|
# update model if request type was PUT
|
|
if request.method == 'PUT':
|
|
try:
|
|
data = json.loads(request.body.decode("utf-8"))
|
|
mem.update_from_dict(data)
|
|
except ValueError:
|
|
return HttpResponseBadRequest('{"error" : "Invalid parameters supplied"}')
|
|
|
|
return HttpResponse(json.dumps(mem.get_dict()))
|
|
|
|
if request.method == 'POST':
|
|
try:
|
|
data = json.loads(request.body.decode("utf-8"))
|
|
mem = Member.create_from_dict(data)
|
|
return HttpResponse(json.dumps(mem.get_dict()))
|
|
except ValueError:
|
|
return HttpResponseBadRequest('{"error" : "Invalid parameters supplied"}')
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["POST"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def csv_import(request, *args, **kwargs):
|
|
data = request.body.decode("utf-8")
|
|
resp_data = Member.import_csv(data)
|
|
resp = HttpResponse(json.dumps(resp_data))
|
|
if resp_data['status'] == 'failure':
|
|
resp.status_code = 400
|
|
return resp
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def member_requests(request, *args, **kwargs):
|
|
reqs = list(map(lambda r: r.get_dict(), MemberRequest.objects.all()))
|
|
return HttpResponse(json.dumps(reqs))
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
def new_member_request(request, *args, **kwargs):
|
|
try:
|
|
data = json.loads(request.body.decode("utf-8"))
|
|
# get captcha response from member
|
|
captcha = data.pop("reCaptchaResponse", "")
|
|
# send response to google and check it out
|
|
captcha_ok = validate_recaptcha(captcha)
|
|
# if not ok, inform user
|
|
if not captcha_ok:
|
|
return HttpResponseBadRequest('{"error": "Captcha not ok. Please try again."}')
|
|
# if ok continue
|
|
mem = Member.create_from_dict(data)
|
|
req = MemberRequest.objects.create(member=mem)
|
|
|
|
# Build the email body
|
|
subject = 'New application'
|
|
message = 'You have new application\r\n'
|
|
message += 'Member info:\r\n'
|
|
message += 'First name: ' + mem.first_name + '\r\n'
|
|
message += 'Last name: ' + mem.last_name + '\r\n'
|
|
message += 'Email: ' + mem.email + '\r\n'
|
|
message += 'Place of residence: ' + mem.POR + '\r\n'
|
|
message += 'AYY-membership: ' + str(mem.AYY) + '\r\n'
|
|
message += 'To mail list: ' + str(mem.jas) + '\r\n'
|
|
message += 'Created: ' + mem.created.isoformat(' ') + '\r\n'
|
|
message += 'Please go to the http://sika.sahkoinsinoorikilta.fi/members/ and do something about it!\r\n'
|
|
|
|
# TODO: send mail when application is ready
|
|
# send_mail_wrapper(subject, message)
|
|
|
|
return HttpResponse(json.dumps(mem.get_dict()))
|
|
|
|
except ValueError:
|
|
return HttpResponseBadRequest('{"error" : "Invalid parameters supplied"}')
|
|
except TimeoutError:
|
|
return HttpResponseBadRequest('{"error" : "Much error, no connection"}')
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET", "POST", "DELETE"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def handle_mem_request(request, idx, *args, **kwargs):
|
|
try:
|
|
req = MemberRequest.objects.get(pk=idx)
|
|
except MemberRequest.DoesNotExist:
|
|
resp = HttpResponse('{"error":"object not found"}')
|
|
resp.status_code = 404
|
|
return resp
|
|
if request.method == 'GET':
|
|
return HttpResponse(json.dumps(req.get_dict()))
|
|
elif request.method == 'DELETE':
|
|
req.member.delete()
|
|
else: # method == POST because other aren't allowed here
|
|
req.delete()
|
|
return HttpResponse('{"status":"success"}')
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@require_http_methods(["GET"])
|
|
@permission_required('members.change_member', login_url='/login')
|
|
def export_csv(request, *args, **kwargs):
|
|
import csv
|
|
|
|
response = HttpResponse()
|
|
response['Content-type'] = 'text/csv'
|
|
response['Accept'] = 'text/csv'
|
|
response['Content-Disposition'] = 'filename; filename=members.csv'
|
|
writer = csv.writer(response, csv.excel)
|
|
response.write(u'\ufeff'.encode('utf8')) # BOM (optional...Excel needs it to open UTF-8 file properly)
|
|
for obj in Member.objects.all():
|
|
data = obj.get_dict()
|
|
field_list = map(lambda s: str(data[s]),
|
|
['id', 'first_name', 'last_name', 'email', 'POR', 'AYY', 'jas', 'created', 'paid'])
|
|
|
|
writer.writerow(field_list)
|
|
|
|
return response
|