def get(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = request.GET supervision_id = data.get('supervision_id', None) if supervision_id is None: return throw_bad_request("No supervision ID was specified.") supervision = Supervision.objects.filter(id=supervision_id).first() if supervision is None: return throw_bad_request( "Supervision could not be found with the id " + str(supervision_id)) email_configuration = Configuration.objects.filter(name=EMAIL).first() if email_configuration is None: email_configuration = Configuration.objects.create(name=EMAIL, value="") generated_email = generate_email_content(email_configuration.value, supervision.application, request, supervision.supervisor) return HttpResponse(generated_email, content_type="text/plain")
def put(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = request.data id = data.get('id', None) existing_application = Application.objects.filter(id=id).first() if not existing_application: return throw_bad_request("No application exists with the ID: " + str(id)) application = data.get('application', None) if not application: return throw_bad_request("No application was specified.") application_serializer = ApplicationSerializer( instance=existing_application, data=application, partial=True) if not application_serializer.is_valid(): return throw_invalid_data(application_serializer.errors) application_serializer.save() return Response( { "id": existing_application.id, "registry_ref": existing_application.registry_ref }, status=status.HTTP_200_OK)
def put(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = request.data id = data.get('id', None) existing_academic_year = AcademicYear.objects.filter(id=id).first() if not existing_academic_year: return throw_bad_request("No academic year exists with the ID: " + str(id)) academic_year = data.get('academic_year', None) if not academic_year: return throw_bad_request("No academic year was specified.") academic_year_serializer = AcademicYearSerializer( instance=existing_academic_year, data=academic_year, partial=True) if not academic_year_serializer.is_valid(): return throw_invalid_data(academic_year_serializer.errors) academic_year_serializer.save() return Response({"id": existing_academic_year.id}, status=status.HTTP_200_OK)
def post(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = request.data email_template = data.get('email_template', None) if email_template is None: return throw_bad_request( "First you have to create an email template.") supervision_id = data.get('supervision_id', None) if supervision_id is None: return throw_bad_request("Supervision ID was not specified.") is_template = data.get('template', None) if is_template is None: return throw_bad_request( "You have to specify whether the email is a template.") supervision = Supervision.objects.filter(id=supervision_id).first() if supervision is None: return throw_bad_request( "Supervision could not be found with the id " + str(supervision_id)) application = supervision.application supervisor = supervision.supervisor if is_template: generated_email = generate_email_content(email_template, application, request, supervisor) else: generated_email = email_template # Strip the html, so people will have the text as well text_content = html2text.html2text(generated_email) subject = 'PhD Admissions: {} {} ({})'.format(application.forename, application.surname, application.registry_ref) from_email = user.email to = supervisor.email connection = get_connection( ) # uses SMTP server specified in settings.py connection.open( ) # If you don't open the connection manually, Django will automatically open, then tear down the connection in msg.send() # Create the email, and attach the HTML version as well msg = EmailMultiAlternatives(subject, text_content, from_email, [to], connection=connection) msg.attach_alternative(generated_email, "text/html") msg.send() connection.close() return HttpResponse(status=status.HTTP_200_OK)
def post(self, request): requesting_user = request.user requesting_user_role = requesting_user.role if requesting_user_role.name == SUPERVISOR: return throw_bad_request( "You have no permission to change users' roles.") data = request.data new_user_roles = data.get('new_user_roles', None) if not new_user_roles: return throw_bad_request("No users were specified.") for user, role in new_user_roles.items(): user_object = User.objects.filter(username=user).first() if not user_object: return throw_bad_request("No user was found with the ID " + str(user)) if role not in USER_ROLES: return throw_bad_request("The following roles was invalid: " + str(role)) current_user_role = user_object.role current_user_role.name = role current_user_role.save() return HttpResponse(status=status.HTTP_200_OK)
def post(self, request): json_data = json.loads(request.data["details"]) supervision_id = json_data["supervision_id"] supervision = Supervision.objects.filter(id=supervision_id).first() if not supervision: return throw_bad_request("Supervision was not found with ID " + str(supervision_id)) file_descriptions = json_data['file_descriptions'] files = request.FILES if len(files) == 0: return throw_bad_request("No files were submitted") new_files = [] if files: for key in files: # Find the last occurrence of "_" file_type = key[:key.rfind('_')] file = files[key] file_description = file_descriptions[key] if key in file_descriptions else "" new_file = Documentation.objects.create(supervision=supervision, file=file, file_name=file.name, file_type=file_type, description=file_description) new_files.append(new_file) # Reflect the update on the application application_updated_now(supervision.application) documentation_serializer = DocumentationSerializer(new_files, many=True) return Response({"documentations": documentation_serializer.data}, status=status.HTTP_201_CREATED)
def get(self, request): academic_year_id = request.GET.get('academic_year_id', None) if academic_year_id is None: default_academic_year = AcademicYear.objects.filter( default=True).first() if default_academic_year is None: return throw_bad_request("No default academic year exists!") academic_year_id = default_academic_year.id if academic_year_id == "all": applications = Application.objects.all() else: applications = Application.objects.filter( academic_year_id=academic_year_id) history_type = request.GET.get('history_type', None) if history_type is None or history_type == "MONTHS": response = { "application_counts": get_applications_per_month_in_academic_year(applications) } elif history_type == "30_DAYS": response = { "application_counts": get_applications_per_last_30_days(applications) } else: return throw_bad_request("Type of history was not specified!") json_response = JSONRenderer().render(response) return HttpResponse(json_response, content_type='application/json')
def get(self, request): id = request.GET.get('id', None) token = request.GET.get('token', None) jwt_decode_handler = api_settings.JWT_DECODE_HANDLER try: payload = jwt_decode_handler(token) except jwt.ExpiredSignature: return throw_bad_request("Signature has expired.") except jwt.DecodeError: return throw_bad_request("Error decoding signature.") username = jwt_get_username_from_payload(payload) if not username: return throw_bad_request("Invalid payload.") if not id: return throw_bad_request("Documentation ID was not provided as a GET parameter.") documentation = Documentation.objects.filter(id=id).first() if not documentation: return throw_bad_request("Documentation was not find with the ID." + str(id)) response = HttpResponse(documentation.file, content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename=' + documentation.file_name return response
def get(self, request): academic_year_id = request.GET.get('academic_year_id', None) if academic_year_id is None: default_academic_year = AcademicYear.objects.filter( default=True).first() if default_academic_year is None: return throw_bad_request("No default academic year exists!") academic_year_id = default_academic_year.id fields = request.GET.getlist('fields') ratios = {} if academic_year_id == "all": applications = Application.objects.all() else: applications = Application.objects.filter( academic_year_id=academic_year_id) for field in fields: field_counts = applications.values(field).annotate( field_count=Count(field)) field_series = [entry[field] for entry in field_counts] field_labels = [entry[field] for entry in field_counts] field_data = [entry['field_count'] for entry in field_counts] ratios[field] = { 'series': field_series, 'labels': field_labels, 'data': field_data } json_response = JSONRenderer().render(ratios) return HttpResponse(json_response, content_type='application/json')
def put(self, request): data = request.data id = data.get('id', None) existing_tag = Tag.objects.filter(id=id).first() if not existing_tag: return throw_bad_request("No tag exists with the ID: " + str(id)) tag = data.get('tag', None) existing_tag.name = tag['name'] try: with transaction.atomic(): existing_tag.save() except IntegrityError: return throw_bad_request("The tag '" + tag['name'] + "' already exists!") return HttpResponse(status=status.HTTP_200_OK)
def post(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") application = request.data["application"] json_data = json.loads(application) application_serializer = ApplicationSerializer(data=json_data) if not application_serializer.is_valid(): return throw_invalid_data(application_serializer.errors) application = application_serializer.save() # Manage supervisions supervisors = json_data['supervisors'] if len(supervisors) != 0: supervisor_objects = User.objects.filter(username__in=supervisors) [ Supervision.objects.create(application=application, supervisor=supervisor_object) for supervisor_object in supervisor_objects ] # Create Admin supervision, which is default for all applications admin_supervision = Supervision.objects.create(application=application, supervisor=request.user, type=ADMIN, creator=True) # Manage documentation file_descriptions = json_data['file_descriptions'] files = request.FILES if files: for key in files: # Find the last occurrence of "_" file_type = key[:key.rfind('_')] file = files[key] file_description = file_descriptions[ key] if key in file_descriptions else "" Documentation.objects.create(supervision=admin_supervision, file=file, file_name=file.name, file_type=file_type, description=file_description) # Manage tagging if 'tag_words' in json_data: tags = json_data['tag_words'] for tag_name in tags: Tag.objects.add_tag(application, "\"" + tag_name + "\"") return Response( { "id": application.id, "registry_ref": application.registry_ref }, status=status.HTTP_201_CREATED)
def delete(self, request): data = json.loads(request.body.decode('utf-8')) file_id = data.get("file_id") if not file_id: return throw_bad_request("Documentation ID was not provided as a GET parameter.") documentation = Documentation.objects.filter(id=file_id).first() if not documentation: return throw_bad_request("Documentation was not find with the ID." + str(file_id)) user = request.user if user.role != roles.ADMIN and user.username != documentation.supervision.supervisor.username: return throw_bad_request("No sufficient permission.") documentation.delete() return HttpResponse(status=204)
def post(self, request): if request.user.role.name == SUPERVISOR: return throw_bad_request( "You have no permission to synchronise staff members.") call_command('ldap_sync_users') return HttpResponse(status=HTTP_200_OK, content_type='application/json')
def delete(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") request_body = request.body.decode('utf-8') data = json.loads(request_body) id = data.get('id') if not id: return throw_bad_request("Tag id was not provided as a GET parameter.") tag = Tag.objects.filter(id=id).first() if not tag: return throw_bad_request("Tag was not find with the ID." + str(id)) tag.delete() return HttpResponse(status=204)
def post(self, request): if request.user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = request.data supervision_id = data.get('supervision_id', None) if supervision_id is None: throw_bad_request("No supervision ID was specified.") supervision = Supervision.objects.filter(id=supervision_id).first() if not supervision: return throw_bad_request( "Supervision was not found with the ID: " + str(supervision_id)) supervision.allocated = True supervision.save() return HttpResponse(status=status.HTTP_200_OK)
def post(self, request): data = request.data supervision_type_param = data.get('supervision_type', None) if supervision_type_param and supervision_type_param == ADMIN: user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") supervision_type = ADMIN else: supervision_type = SUPERVISOR application_id = data.get('id', None) application = Application.objects.filter(id=application_id).first() if not application: return throw_bad_request( "Application was not found with the id: " + str(application_id)) supervisor_username = data.get('supervisor', None) supervisor = User.objects.filter(username=supervisor_username).first() if not supervisor: return throw_bad_request( "Supervisor was not find with the username: "******"The " + supervision_type + "supervision already exists!") application_updated_now(application) supervision_serializer = SupervisionSerializer(new_supervision) json_response = JSONRenderer().render(supervision_serializer.data) return HttpResponse(json_response, content_type='application/json')
def post(self, request): data = request.data username = data.get('username', None) password = data.get('password', None) try: user = authenticate(username=username, password=password) except MultiValueDictKeyError: return throw_bad_request("Missing username or password") if user is None: return throw_bad_request("Wrong username or password") if user.is_active: # If this is the first time the user logged in, assign a default role if hasattr(user, 'role'): user_role = user.role else: user_role = UserRole.objects.create(name=SUPERVISOR, user=user) # Manually generate a token for the new user jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) update_last_login(None, user) return Response({ 'token': token, 'username': user.username, 'user_role': user_role.name }) else: return Response( { 'status': 'Unauthorized', 'message': 'This account has been disabled.' }, status=status.HTTP_401_UNAUTHORIZED)
def delete(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = json.loads(request.body.decode('utf-8')) id = data.get('id') if not id: return throw_bad_request( "Academic Year id was not provided as a GET parameter.") academic_year = AcademicYear.objects.filter(id=id).first() if not academic_year: return throw_bad_request( "Academic Year was not find with the ID." + str(id)) academic_year.delete() return HttpResponse(status=204)
def delete(self, request): if request.user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = json.loads(request.body.decode('utf-8')) supervision_id = data.get('supervision_id') if not supervision_id: return throw_bad_request("No supervision was specified.") supervision = Supervision.objects.filter(id=supervision_id).first() if not supervision: return throw_bad_request( "Supervision could not be found with the id: " + str(supervision_id)) supervision.allocated = False supervision.save() return HttpResponse(status=status.HTTP_200_OK)
def put(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") email_configuration = Configuration.objects.filter(name=EMAIL).first() if email_configuration is None: email_configuration = Configuration.objects.create(name=EMAIL, value="") data = request.data value = data.get('value', None) email_configuration_serializer = ConfigurationSerializer( instance=email_configuration, data={'value': value}, partial=True) if not email_configuration_serializer.is_valid(): return throw_bad_request("Posted data was invalid.") email_configuration_serializer.save() return Response(status=status.HTTP_200_OK)
def put(self, request): data = request.data supervision_id = data.get('supervision_id', None) if not supervision_id: return throw_bad_request("No supervision was specified.") supervision = Supervision.objects.filter(id=supervision_id).first() if not supervision: return throw_bad_request( "Supervision could not be found with the id " + str(supervision_id)) # TODO check user roles here supervision_serializer = SupervisionSerializer( instance=supervision, data=data["supervision"], partial=True) if not supervision_serializer.is_valid(): return throw_invalid_data(supervision_serializer.errors) supervision_serializer.save() application_updated_now(supervision.application) return Response(status=status.HTTP_200_OK)
def delete(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") data = json.loads(request.body.decode('utf-8')) supervision_id = data.get('supervision_id') if not supervision_id: return throw_bad_request("No supervision was specified.") supervision = Supervision.objects.filter(id=supervision_id).first() if not supervision: return throw_bad_request( "Supervision could not be found with the id: " + str(supervision_id)) if not supervision.creator: supervision.delete() else: return throw_bad_request("Cannot delete creator supervision.") return HttpResponse(status=204)
def post(self, request): data = request.data tag_name = data.get('name', None) try: with transaction.atomic(): new_tag = Tag.objects.create(name=tag_name) except IntegrityError: return throw_bad_request("The tag '" + tag_name + "' already exists!") tag_serializer = TagSerializer(new_tag) json_response = JSONRenderer().render({"tag": tag_serializer.data}) return HttpResponse(json_response, status=status.HTTP_201_CREATED, content_type='application/json')
def delete(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") request_body = request.body.decode('utf-8') data = json.loads(request_body) tag_id = data.get('tag_id') if not tag_id: return throw_bad_request("Tag ID was not provided as a GET parameter.") application_id = data.get('application_id') if not application_id: return throw_bad_request("Application ID was not provided as a GET parameter.") tagged_item = TaggedItem.objects.filter(object_id=application_id, tag_id=tag_id).first() if not tagged_item: return throw_bad_request("Unable to delete tag from application: the application does not have this tag.") tagged_item.delete() return HttpResponse(status=204)
def get(self, request): token, application_ids, sort_field, sort_by, selected_fields = get_file_request_params(request) verified, error_msg = verify_authentication_token(token) if not verified: return throw_bad_request(error_msg) applications = Application.objects.filter(id__in=application_ids) # Open StringIO to grab in-memory ZIP contents zip_bytes_io = BytesIO() # The zip compressor zf = zipfile.ZipFile(zip_bytes_io, "w") # Organise the files into the ZIP for application in applications.all(): for supervision in application.supervisions.all(): for documentation in supervision.documentations.all(): # Path within the ZIP zip_path = documentation.file.url cropped_zip_path = zip_path.replace(MEDIA_URL + SUB_FOLDER, "", 1) # Add file, at correct path try: zf.write(documentation.file.path, cropped_zip_path) except OSError as e: # TODO: log the error here pass # CSV compressor csv_string_io = io.StringIO() csv_writer = csv.writer(csv_string_io, dialect='excel') write_to_csv_file(applications, csv_writer, selected_fields) # Write CSV to ZIP file zf.writestr("Application Details.csv", csv_string_io.getvalue()) # Must close zip for all contents to be written zf.close() # Grab ZIP file from in-memory, make response with correct MIME-type response = HttpResponse(zip_bytes_io.getvalue(), content_type="application/x-zip-compressed") response['Content-Disposition'] = 'attachment; filename="%s"' % zip_filename() return response
def get(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") email_configuration = Configuration.objects.filter(name=EMAIL).first() if email_configuration is None: email_configuration = Configuration.objects.create(name=EMAIL, value="") email_configuration_serializer = ConfigurationSerializer( email_configuration) json_response = JSONRenderer().render( email_configuration_serializer.data) return HttpResponse(json_response, content_type='application/json')
def post(self, request): data = request.data tag_name = data.get('name', None) application_id = data.get('application_id', None) application = Application.objects.filter(id=application_id).first() if not application: return throw_bad_request("Application could not be found with the id: " + str(application_id)) Tag.objects.add_tag(application, "\"" + tag_name + "\"") tag = Tag.objects.filter(name=tag_name).first() # Return the tag object tag_serializer = TagSerializer(tag) json_response = JSONRenderer().render({"tag": tag_serializer.data}) return HttpResponse(json_response, content_type='application/json')
def post(self, request): user = request.user if user.role != roles.ADMIN: return throw_bad_request("No sufficient permission.") academic_year_serializer = AcademicYearSerializer(data=request.data) if not academic_year_serializer.is_valid(): return throw_invalid_data(academic_year_serializer.errors) academic_year = academic_year_serializer.save() academic_year_serializer = AcademicYearSerializer(academic_year) json_response = JSONRenderer().render( {"academic_year": academic_year_serializer.data}) return HttpResponse(json_response, status=status.HTTP_201_CREATED, content_type='application/json')
def get(self, request): token, application_ids, sort_field, sort_by, selected_fields = get_file_request_params(request) verified, error_msg = verify_authentication_token(token) if not verified: return throw_bad_request(error_msg) applications = Application.objects.filter(id__in=application_ids) if sort_field and sort_by: new_sort_clause = sort_field if sort_by == 'ASC' else "-" + sort_field applications = applications.order_by(new_sort_clause) # Create the HttpResponse object with the appropriate CSV header. response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="' + csv_filename() + '"' writer = csv.writer(response) write_to_csv_file(applications, writer, selected_fields) return response
def get(self, request): id = request.GET.get('id', None) if not id: return throw_bad_request( "PhD Application id was not provided as a GET parameter.") application = Application.objects.all().prefetch_related( "supervisions", "supervisions__supervisor", "supervisions__documentations").filter(id=id).first() if not application: return throw_bad_request( "PhD Application was not find with the ID." + str(id)) application_serializer = ApplicationSerializer(application) # Organise the output to make access simper for the front-end admin_supervisions = [] creator_supervision = None creator_supervision_files = {} supervisor_supervisions = [] supervisor_supervision_files = {} supervisions = application.supervisions.all() for supervision in supervisions: if supervision.type == SUPERVISOR: supervisor_supervisions.append(supervision) # Documentations supervisor_supervision_files[supervision.id] = {} supervision_documentations = supervision.documentations.all() for documentation in supervision_documentations: if documentation.file_type not in supervisor_supervision_files[ supervision.id]: supervisor_supervision_files[supervision.id][ documentation.file_type] = [] supervisor_supervision_file_serializer = DocumentationSerializer( documentation) supervisor_supervision_files[supervision.id][ documentation.file_type].append( supervisor_supervision_file_serializer.data) continue if supervision.type == ADMIN: admin_supervisions.append(supervision) if supervision.creator: creator_supervision = supervision # Documentations supervision_documentations = supervision.documentations.all( ) for documentation in supervision_documentations: if documentation.file_type not in creator_supervision_files: creator_supervision_files[ documentation.file_type] = [] creator_supervision_file_serializer = DocumentationSerializer( documentation) creator_supervision_files[ documentation.file_type].append( creator_supervision_file_serializer.data) continue # Serializers admin_supervision_serializer = SupervisionSerializer( admin_supervisions, many=True) creator_supervision_serializer = SupervisionSerializer( creator_supervision) supervisor_supervision_serializer = SupervisionSerializer( supervisor_supervisions, many=True) response = { "application": application_serializer.data, "admin_supervisions": admin_supervision_serializer.data, "creator_supervision": creator_supervision_serializer.data, "creator_supervision_files": creator_supervision_files, "supervisor_supervisions": supervisor_supervision_serializer.data, "supervisor_supervision_files": supervisor_supervision_files } json_response = JSONRenderer().render(response) return HttpResponse(json_response, content_type='application/json')