this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add pre-commit-hooks - black, isort, django-migrations-check

+209 -397
+33 -2
.pre-commit-config.yaml
··· 3 3 fail_fast: true 4 4 5 5 repos: 6 - - repo: https://github.com/pre-commit/pre-commit-hooks 6 + - repo: https://github.com/pre-commit/pre-commit-hooks 7 7 rev: master 8 8 hooks: 9 9 - id: trailing-whitespace 10 10 files: (^|/)a/.+\.(py|html|sh|css|js)$ 11 + - id: check-merge-conflict 12 + name: check for merge conflict 13 + description: Prevent accidentally commiting files with merge conflicts. 14 + - id: end-of-file-fixer 15 + name: fix end of files. 16 + description: Ensures that a file is either empty, or ends with one newline. 17 + 11 18 12 - - repo: local 19 + - repo: https://github.com/asottile/seed-isort-config 20 + rev: v2.1.0 21 + hooks: 22 + - id: seed-isort-config 23 + 24 + - repo: https://github.com/pre-commit/mirrors-isort 25 + rev: v4.3.21 26 + hooks: 27 + - id: isort 28 + 29 + - repo: https://github.com/ambv/black 30 + rev: stable 31 + hooks: 32 + - id: black 33 + args: [--line-length=120, --safe] 34 + language_version: python3.7 35 + 36 + - repo: local 13 37 hooks: 14 38 - id: flake8 15 39 name: flake8 ··· 18 42 types: [python] 19 43 args: ['--config=setup.cfg'] 20 44 45 + - id: pre-commit-django-migrations 46 + name: Check django migrations 47 + entry: python manage.py makemigrations --check 48 + language: system 49 + types: [python] 50 + pass_filenames: false 51 + require_serial: true
-1
CONTRIBUTORS.txt
··· 1 -
-1
LICENSE
··· 7 7 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 8 9 9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 -
-1
Procfile
··· 1 1 web: gunicorn config.wsgi:application 2 2 release: python manage.py collectstatic --noinput && python manage.py migrate 3 -
+1 -6
care/__init__.py
··· 1 1 __version__ = "0.1.0" 2 - __version_info__ = tuple( 3 - [ 4 - int(num) if num.isdigit() else num 5 - for num in __version__.replace("-", ".", 1).split(".") 6 - ] 7 - ) 2 + __version_info__ = tuple([int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".")])
+12 -9
care/facility/admin.py
··· 1 1 from django.contrib import admin 2 2 3 3 from .models import ( 4 + Ambulance, 5 + AmbulanceDriver, 6 + Building, 4 7 Facility, 5 - FacilityStaff, 6 8 FacilityCapacity, 9 + FacilityStaff, 7 10 FacilityVolunteer, 8 - Building, 11 + Inventory, 12 + InventoryItem, 13 + InventoryLog, 9 14 Room, 10 15 StaffRoomAllocation, 11 - InventoryItem, 12 - Inventory, 13 - InventoryLog, 14 - AmbulanceDriver, 15 - Ambulance) 16 + ) 16 17 17 18 18 19 class BuildingAdmin(admin.ModelAdmin): ··· 59 60 60 61 class AmbulanceAdmin(admin.ModelAdmin): 61 62 search_fields = ["vehicle_number"] 62 - inlines = [AmbulanceDriverInline, ] 63 + inlines = [ 64 + AmbulanceDriverInline, 65 + ] 63 66 64 67 65 68 class AmbulanceDriverAdmin(admin.ModelAdmin): 66 - autocomplete_fields = ['ambulance'] 69 + autocomplete_fields = ["ambulance"] 67 70 68 71 69 72 admin.site.register(Facility, FacilityAdmin)
+11 -9
care/facility/api/serializers.py
··· 3 3 from drf_extra_fields.geo_fields import PointField 4 4 from rest_framework import serializers 5 5 6 - from care.facility.models import FACILITY_TYPES, AmbulanceDriver 7 - from care.facility.models import Facility, Ambulance 6 + from care.facility.models import FACILITY_TYPES, Ambulance, AmbulanceDriver, Facility 8 7 from config.serializers import ChoiceField 9 8 10 9 User = get_user_model() 11 10 12 - TIMESTAMP_FIELDS = ('created_date', 'modified_date', 'deleted',) 11 + TIMESTAMP_FIELDS = ( 12 + "created_date", 13 + "modified_date", 14 + "deleted", 15 + ) 13 16 14 17 15 18 class FacilitySerializer(serializers.ModelSerializer): ··· 40 43 class AmbulanceDriverSerializer(serializers.ModelSerializer): 41 44 class Meta: 42 45 model = AmbulanceDriver 43 - exclude = TIMESTAMP_FIELDS + ('ambulance',) 46 + exclude = TIMESTAMP_FIELDS + ("ambulance",) 44 47 45 48 46 49 class AmbulanceSerializer(serializers.ModelSerializer): 47 - drivers = serializers.ListSerializer( 48 - child=AmbulanceDriverSerializer()) 50 + drivers = serializers.ListSerializer(child=AmbulanceDriverSerializer()) 49 51 50 52 class Meta: 51 53 model = Ambulance ··· 53 55 54 56 def create(self, validated_data): 55 57 with transaction.atomic(): 56 - drivers = validated_data.pop('drivers', []) 58 + drivers = validated_data.pop("drivers", []) 57 59 ambulance = super(AmbulanceSerializer, self).create(validated_data) 58 60 for d in drivers: 59 - d['ambulance'] = ambulance 61 + d["ambulance"] = ambulance 60 62 AmbulanceDriverSerializer().create(d) 61 63 return ambulance 62 64 63 65 def update(self, instance, validated_data): 64 - validated_data.pop('drivers', []) 66 + validated_data.pop("drivers", []) 65 67 ambulance = super(AmbulanceSerializer, self).update(instance, validated_data) 66 68 return ambulance
+15 -11
care/facility/api/views.py
··· 1 1 from django_filters import rest_framework as filters 2 - from rest_framework import status, serializers 2 + from rest_framework import serializers, status 3 3 from rest_framework.decorators import action 4 4 from rest_framework.mixins import ( 5 + CreateModelMixin, 6 + DestroyModelMixin, 5 7 ListModelMixin, 6 8 RetrieveModelMixin, 7 - CreateModelMixin, 8 9 UpdateModelMixin, 9 - DestroyModelMixin) 10 + ) 10 11 from rest_framework.permissions import IsAuthenticated 11 12 from rest_framework.response import Response 12 13 from rest_framework.viewsets import GenericViewSet 13 14 14 - from care.facility.api.serializers import FacilitySerializer, AmbulanceSerializer, AmbulanceDriverSerializer 15 - from care.facility.models import Facility, Ambulance 15 + from care.facility.api.serializers import ( 16 + AmbulanceDriverSerializer, 17 + AmbulanceSerializer, 18 + FacilitySerializer, 19 + ) 20 + from care.facility.models import Ambulance, Facility 16 21 17 22 18 - class FacilityBaseViewset(CreateModelMixin, RetrieveModelMixin, 19 - UpdateModelMixin, DestroyModelMixin, GenericViewSet): 23 + class FacilityBaseViewset(CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): 20 24 """Base class for all endpoints related to Faclity model.""" 21 25 22 26 permission_classes = (IsAuthenticated,) ··· 42 46 43 47 44 48 class AmbulanceFilterSet(filters.FilterSet): 45 - vehicle_numbers = filters.BaseInFilter(field_name='vehicle_number') 49 + vehicle_numbers = filters.BaseInFilter(field_name="vehicle_number") 46 50 47 51 48 52 class AmbulanceViewSet(FacilityBaseViewset, ListModelMixin): ··· 51 55 filter_backends = (filters.DjangoFilterBackend,) 52 56 filterset_class = AmbulanceFilterSet 53 57 54 - @action(methods=['POST'], detail=True) 58 + @action(methods=["POST"], detail=True) 55 59 def add_driver(self, request): 56 60 ambulance = self.get_object() 57 61 serializer = AmbulanceDriverSerializer(data=request.data) ··· 60 64 driver = ambulance.ambulancedriver_set.create(**serializer.validated_data) 61 65 return Response(data=AmbulanceDriverSerializer(driver).data, status=status.HTTP_201_CREATED) 62 66 63 - @action(methods=['DELETE'], detail=True) 67 + @action(methods=["DELETE"], detail=True) 64 68 def remove_driver(self, request): 65 69 class DeleteDriverSerializer(serializers.Serializer): 66 70 driver_id = serializers.IntegerField() ··· 75 79 serializer = DeleteDriverSerializer(data=request.data) 76 80 serializer.is_valid(raise_exception=True) 77 81 78 - driver = ambulance.ambulancedriver_set.filter(id=serializer.validated_data['driver_id']).first() 82 + driver = ambulance.ambulancedriver_set.filter(id=serializer.validated_data["driver_id"]).first() 79 83 if not driver: 80 84 raise serializers.ValidationError({"driver_id": "Detail not found"}) 81 85
+8 -5
care/facility/forms.py
··· 7 7 class Meta: 8 8 model = Facility 9 9 fields = ["name", "district", "address", "oxygen_capacity", "phone_number"] 10 - labels = {"name": "Enter the name of your hospital", "district": "Pick your District", 11 - "address": "Enter Hospital Address", 12 - "phone_number": "Enter emergency contact number of your hospital","oxygen_capacity":"Enter the total oxygen capacity of your hospital (in litres)"} 10 + labels = { 11 + "name": "Enter the name of your hospital", 12 + "district": "Pick your District", 13 + "address": "Enter Hospital Address", 14 + "phone_number": "Enter emergency contact number of your hospital", 15 + "oxygen_capacity": "Enter the total oxygen capacity of your hospital (in litres)", 16 + } 13 17 14 18 15 19 class FacilityCapacityCreationForm(ModelForm): 16 20 class Meta: 17 21 model = FacilityCapacity 18 22 fields = ["room_type", "total_capacity", "current_capacity"] 19 - labels = {"room_type": "Bed Type", "total_capacity": "Total Capacity", 20 - "current_capacity": "Currently Occupied"} 23 + labels = {"room_type": "Bed Type", "total_capacity": "Total Capacity", "current_capacity": "Currently Occupied"} 21 24 22 25 23 26 class DoctorsCountCreationForm(ModelForm):
+14 -49
care/facility/models.py
··· 1 1 from django.contrib.auth import get_user_model 2 - from django.core.validators import MinValueValidator 3 - from django.core.validators import RegexValidator 2 + from django.core.validators import MinValueValidator, RegexValidator 4 3 from django.db import models 5 4 from location_field.models.spatial import LocationField 6 5 ··· 34 33 ] 35 34 36 35 phone_number_regex = RegexValidator( 37 - regex="^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$", 36 + regex=r"^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$", 38 37 message="Please Enter 10/11 digit mobile number or landline as 0<std code><phone number>", 39 38 code="invalid_mobile", 40 39 ) ··· 50 49 location = LocationField(based_fields=["address"], zoom=7, blank=True, null=True) 51 50 oxygen_capacity = models.IntegerField() 52 51 phone_number = models.CharField(max_length=14, validators=[phone_number_regex]) 53 - created_by = models.ForeignKey( 54 - User, on_delete=models.SET_NULL, null=True, blank=True 55 - ) 52 + created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) 56 53 57 54 def __str__(self): 58 55 return self.name ··· 62 59 63 60 64 61 class HospitalDoctors(FacilityBaseModel): 65 - facility = models.ForeignKey( 66 - "Facility", on_delete=models.CASCADE, null=False, blank=False 67 - ) 62 + facility = models.ForeignKey("Facility", on_delete=models.CASCADE, null=False, blank=False) 68 63 area = models.IntegerField(choices=DOCTOR_TYPES) 69 64 count = models.IntegerField() 70 65 ··· 76 71 77 72 78 73 class FacilityCapacity(FacilityBaseModel): 79 - facility = models.ForeignKey( 80 - "Facility", on_delete=models.CASCADE, null=False, blank=False 81 - ) 74 + facility = models.ForeignKey("Facility", on_delete=models.CASCADE, null=False, blank=False) 82 75 room_type = models.IntegerField(choices=ROOM_TYPES) 83 76 total_capacity = models.IntegerField(default=0, validators=[MinValueValidator(0)]) 84 77 current_capacity = models.IntegerField(default=0, validators=[MinValueValidator(0)]) ··· 88 81 89 82 90 83 class FacilityStaff(FacilityBaseModel): 91 - facility = models.ForeignKey( 92 - "Facility", on_delete=models.CASCADE, null=False, blank=False 93 - ) 84 + facility = models.ForeignKey("Facility", on_delete=models.CASCADE, null=False, blank=False) 94 85 staff = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False) 95 86 96 87 def __str__(self): ··· 98 89 99 90 100 91 class FacilityVolunteer(FacilityBaseModel): 101 - facility = models.ForeignKey( 102 - "Facility", on_delete=models.CASCADE, null=False, blank=False 103 - ) 104 - volunteer = models.ForeignKey( 105 - User, on_delete=models.CASCADE, null=False, blank=False 106 - ) 92 + facility = models.ForeignKey("Facility", on_delete=models.CASCADE, null=False, blank=False) 93 + volunteer = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False) 107 94 108 95 def __str__(self): 109 96 return str(self.volunteer) + " for facility " + str(self.facility) ··· 116 103 117 104 118 105 class Building(FacilityBaseModel): 119 - facility = models.ForeignKey( 120 - "Facility", on_delete=models.CASCADE, null=False, blank=False 121 - ) 106 + facility = models.ForeignKey("Facility", on_delete=models.CASCADE, null=False, blank=False) 122 107 name = models.CharField(max_length=1000) 123 108 num_rooms = models.IntegerField(validators=[MinValueValidator(0)], default=0) 124 109 num_floors = models.IntegerField(validators=[MinValueValidator(0)], default=0) ··· 134 119 135 120 136 121 class Room(FacilityBaseModel): 137 - building = models.ForeignKey( 138 - "Building", on_delete=models.CASCADE, null=False, blank=False 139 - ) 122 + building = models.ForeignKey("Building", on_delete=models.CASCADE, null=False, blank=False) 140 123 num = models.CharField(max_length=1000) 141 124 floor = models.IntegerField(validators=[MinValueValidator(0)], default=0) 142 125 beds_capacity = models.IntegerField(validators=[MinValueValidator(0)], default=0) ··· 167 150 unit = models.CharField(max_length=20) 168 151 169 152 def __str__(self): 170 - return ( 171 - self.name 172 - + " with unit " 173 - + self.unit 174 - + " with minimum stock " 175 - + str(self.minimum_stock) 176 - ) 153 + return self.name + " with unit " + self.unit + " with minimum stock " + str(self.minimum_stock) 177 154 178 155 179 156 class Inventory(FacilityBaseModel): 180 - facility = models.ForeignKey( 181 - "Facility", on_delete=models.CASCADE, null=False, blank=False 182 - ) 157 + facility = models.ForeignKey("Facility", on_delete=models.CASCADE, null=False, blank=False) 183 158 item = models.ForeignKey("InventoryItem", on_delete=models.CASCADE) 184 159 quantitiy = models.IntegerField(validators=[MinValueValidator(0)], default=0) 185 160 186 161 def __str__(self): 187 - return ( 188 - self.item.name 189 - + " : " 190 - + str(self.quantitiy) 191 - + " " 192 - + self.item.unit 193 - + " in " 194 - + str(self.facility) 195 - ) 162 + return self.item.name + " : " + str(self.quantitiy) + " " + self.item.unit + " in " + str(self.facility) 196 163 197 164 class Meta: 198 165 verbose_name_plural = "Inventories" ··· 200 167 201 168 class InventoryLog(FacilityBaseModel): 202 169 inventory = models.ForeignKey("Inventory", on_delete=models.CASCADE) 203 - updated_by = models.ForeignKey( 204 - User, on_delete=models.SET_NULL, null=True, blank=True 205 - ) 170 + updated_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) 206 171 prev_count = models.IntegerField(validators=[MinValueValidator(0)], default=0) 207 172 new_count = models.IntegerField(validators=[MinValueValidator(0)], default=0) 208 173
+10 -26
care/facility/urls.py
··· 1 1 from django.urls import path 2 2 3 3 from .views import ( 4 - FacilityCreation, 4 + DoctorCountCreation, 5 + DoctorCountUpdation, 6 + FacilitiesView, 5 7 FacilityCapacityCreation, 6 - FacilitiesView, 7 - FacilityView, 8 - FacilityUpdation, 9 8 FacilityCapacityUpdation, 10 - DoctorCountCreation, 11 - DoctorCountUpdation, 9 + FacilityCreation, 10 + FacilityUpdation, 11 + FacilityView, 12 12 ) 13 13 14 14 app_name = "facility" ··· 17 17 path("", FacilitiesView.as_view(), name="facilities-view"), 18 18 path("<int:pk>", FacilityView.as_view(), name="facility-view"), 19 19 path("<int:pk>/update", FacilityUpdation.as_view(), name="facility-update"), 20 - path( 21 - "<int:pk>/capacity/add/", 22 - FacilityCapacityCreation.as_view(), 23 - name="facility-capacity-create", 24 - ), 25 - path( 26 - "<int:fpk>/capacity/<int:cpk>/", 27 - FacilityCapacityUpdation.as_view(), 28 - name="facility-capacity-update", 29 - ), 30 - path( 31 - "<int:pk>/doctorcount/add/", 32 - DoctorCountCreation.as_view(), 33 - name="facility-doctor-count-create", 34 - ), 35 - path( 36 - "<int:fpk>/doctorcount/<int:cpk>/", 37 - DoctorCountUpdation.as_view(), 38 - name="facility-doctor-count-update", 39 - ), 20 + path("<int:pk>/capacity/add/", FacilityCapacityCreation.as_view(), name="facility-capacity-create",), 21 + path("<int:fpk>/capacity/<int:cpk>/", FacilityCapacityUpdation.as_view(), name="facility-capacity-update",), 22 + path("<int:pk>/doctorcount/add/", DoctorCountCreation.as_view(), name="facility-doctor-count-create",), 23 + path("<int:fpk>/doctorcount/<int:cpk>/", DoctorCountUpdation.as_view(), name="facility-doctor-count-update",), 40 24 ]
+24 -55
care/facility/views.py
··· 1 1 import logging 2 2 3 - from django.shortcuts import render, redirect 4 - from django.views import View 5 - from django.http import HttpResponseRedirect 6 - from django.db import IntegrityError 3 + from django.conf import settings 7 4 from django.contrib.auth.mixins import LoginRequiredMixin 8 5 from django.contrib.auth.views import redirect_to_login 9 - from django.conf import settings 6 + from django.db import IntegrityError 7 + from django.http import HttpResponseRedirect 8 + from django.shortcuts import redirect, render 9 + from django.views import View 10 10 11 11 from .forms import ( 12 - FacilityCreationForm, 13 - FacilityCapacityCreationForm, 14 12 DoctorsCountCreationForm, 13 + FacilityCapacityCreationForm, 14 + FacilityCreationForm, 15 15 ) 16 16 from .models import Facility, FacilityCapacity, HospitalDoctors 17 17 ··· 25 25 26 26 27 27 class FacilitiesView(LoginRequiredMixin, StaffRequiredMixin, View): 28 - 29 28 template = "facility/facilities_view.html" 30 29 31 30 def get(self, request): ··· 39 38 40 39 41 40 class FacilityView(LoginRequiredMixin, StaffRequiredMixin, View): 42 - 43 41 template = "facility/facility_view.html" 44 42 45 43 def get(self, request, pk): ··· 51 49 return render( 52 50 request, 53 51 self.template, 54 - { 55 - "capacities": capacities, 56 - "doctor_counts": doctor_counts, 57 - "facility": facility_obj, 58 - }, 52 + {"capacities": capacities, "doctor_counts": doctor_counts, "facility": facility_obj,}, 59 53 ) 60 54 except Exception as e: 61 55 logging.error(e) ··· 63 57 64 58 65 59 class FacilityCreation(LoginRequiredMixin, StaffRequiredMixin, View): 66 - 67 60 form_class = FacilityCreationForm 68 61 template = "facility/facility_creation.html" 69 62 ··· 92 85 93 86 94 87 class FacilityUpdation(LoginRequiredMixin, StaffRequiredMixin, View): 95 - 96 88 form_class = FacilityCreationForm 97 89 template = "facility/facility_updation.html" 98 90 ··· 130 122 form = self.form_class() 131 123 current_user = request.user 132 124 facility_obj = Facility.objects.get(id=pk, created_by=current_user) 133 - return render( 134 - request, self.template, {"form": form, "facility": facility_obj} 135 - ) 125 + return render(request, self.template, {"form": form, "facility": facility_obj}) 136 126 except Exception as e: 137 127 logging.error(e) 138 128 return HttpResponseRedirect("/500") ··· 145 135 validation_error = False 146 136 duplicate = False 147 137 if form.is_valid(): 148 - if form.cleaned_data.get('total_capacity') >= form.cleaned_data.get('current_capacity'): 138 + if form.cleaned_data.get("total_capacity") >= form.cleaned_data.get("current_capacity"): 149 139 duplicate = False 150 140 facility_capacity_obj = form.save(commit=False) 151 141 facility_obj = Facility.objects.get(id=pk) ··· 153 143 try: 154 144 facility_capacity_obj.save() 155 145 if "addmore" in data: 156 - return redirect( 157 - "facility:facility-capacity-create", facility_obj.id 158 - ) 146 + return redirect("facility:facility-capacity-create", facility_obj.id) 159 147 else: 160 - return redirect( 161 - "facility:facility-doctor-count-create", facility_obj.id 162 - ) 148 + return redirect("facility:facility-doctor-count-create", facility_obj.id) 163 149 except IntegrityError: 164 150 duplicate = True 165 151 else: ··· 184 170 facility_obj = Facility.objects.get(id=fpk, created_by=current_user) 185 171 capacity_obj = FacilityCapacity.objects.get(id=cpk, facility=facility_obj) 186 172 form = self.form_class(instance=capacity_obj) 187 - return render( 188 - request, self.template, {"form": form, "facility": facility_obj} 189 - ) 173 + return render(request, self.template, {"form": form, "facility": facility_obj}) 190 174 except Exception as e: 191 175 logging.error(e) 192 176 return HttpResponseRedirect("/500") ··· 201 185 duplicate = False 202 186 validation_error = False 203 187 if form.is_valid(): 204 - if form.cleaned_data.get('total_capacity') >= form.cleaned_data.get('current_capacity'): 188 + if form.cleaned_data.get("total_capacity") >= form.cleaned_data.get("current_capacity"): 205 189 try: 206 190 form.save() 207 191 return redirect("facility:facility-view", facility_obj.id) ··· 210 194 else: 211 195 validation_error = True 212 196 return render( 213 - request, self.template, {"form": form, "duplicate": duplicate, 214 - "validation_error": validation_error, "facility": facility_obj} 197 + request, 198 + self.template, 199 + {"form": form, "duplicate": duplicate, "validation_error": validation_error, "facility": facility_obj}, 215 200 ) 216 201 except Exception as e: 217 202 logging.error(e) ··· 227 212 form = self.form_class() 228 213 current_user = request.user 229 214 facility_obj = Facility.objects.get(id=pk, created_by=current_user) 230 - return render( 231 - request, self.template, {"form": form, "facility": facility_obj} 232 - ) 215 + return render(request, self.template, {"form": form, "facility": facility_obj}) 233 216 except Exception as e: 234 217 logging.error(e) 235 218 return HttpResponseRedirect("/500") ··· 246 229 try: 247 230 facility_capacity_obj.save() 248 231 if "addmore" in data: 249 - return redirect( 250 - "facility:facility-doctor-count-create", facility_obj.id 251 - ) 232 + return redirect("facility:facility-doctor-count-create", facility_obj.id) 252 233 else: 253 234 return redirect("facility:facility-view", facility_obj.id) 254 235 except IntegrityError: 255 236 duplicate = True 256 - return render( 257 - request, 258 - self.template, 259 - {"form": form, "facility": facility_obj, "duplicate": duplicate}, 260 - ) 237 + return render(request, self.template, {"form": form, "facility": facility_obj, "duplicate": duplicate},) 261 238 except Exception as e: 262 239 logging.error(e) 263 240 return HttpResponseRedirect("/500") ··· 271 248 try: 272 249 current_user = request.user 273 250 facility_obj = Facility.objects.get(id=fpk, created_by=current_user) 274 - doctor_count_obj = HospitalDoctors.objects.get( 275 - id=cpk, facility=facility_obj 276 - ) 251 + doctor_count_obj = HospitalDoctors.objects.get(id=cpk, facility=facility_obj) 277 252 form = self.form_class(instance=doctor_count_obj) 278 - return render( 279 - request, self.template, {"form": form, "facility": facility_obj} 280 - ) 253 + return render(request, self.template, {"form": form, "facility": facility_obj}) 281 254 except Exception as e: 282 255 logging.error(e) 283 256 return HttpResponseRedirect("/500") ··· 287 260 data = request.POST 288 261 current_user = request.user 289 262 facility_obj = Facility.objects.get(id=fpk, created_by=current_user) 290 - doctor_count_obj = HospitalDoctors.objects.get( 291 - id=cpk, facility=facility_obj 292 - ) 263 + doctor_count_obj = HospitalDoctors.objects.get(id=cpk, facility=facility_obj) 293 264 form = self.form_class(data, instance=doctor_count_obj) 294 265 duplicate = False 295 266 if form.is_valid(): ··· 298 269 return redirect("facility:facility-view", facility_obj.id) 299 270 except IntegrityError: 300 271 duplicate = True 301 - return render( 302 - request, self.template, {"form": form, "duplicate": duplicate} 303 - ) 272 + return render(request, self.template, {"form": form, "duplicate": duplicate}) 304 273 except Exception as e: 305 274 logging.error(e) 306 275 return HttpResponseRedirect("/500")
+1 -1
care/static/css/custom.min.css
··· 1 - .bg-gray-100{background-color:#fbfafc}.btn-primary{background-color:#6025c0;color:#fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);background-image:linear-gradient(135deg,#6025c0,#4d1e9a)}.btn{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;font-weight:600;padding:.5rem 1rem;border-radius:.25rem;cursor:pointer}.care-secondary-color{color:#6025c0}label{margin-top:1rem;display:inline-block}.careblock{display:block!important}@media (min-width:768px){.cardwidth{width:30%!important;min-width:250px!important}} 1 + .bg-gray-100{background-color:#fbfafc}.btn-primary{background-color:#6025c0;color:#fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);background-image:linear-gradient(135deg,#6025c0,#4d1e9a)}.btn{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;font-weight:600;padding:.5rem 1rem;border-radius:.25rem;cursor:pointer}.care-secondary-color{color:#6025c0}label{margin-top:1rem;display:inline-block}.careblock{display:block!important}@media (min-width:768px){.cardwidth{width:30%!important;min-width:250px!important}}
-2
care/templates/500.html
··· 9 9 10 10 <p>We track these errors automatically, but if the problem persists feel free to contact us. In the meantime, try refreshing.</p> 11 11 {% endblock content %} 12 - 13 -
-1
care/templates/account/account_inactive.html
··· 9 9 10 10 <p>{% trans "This account is inactive." %}</p> 11 11 {% endblock %} 12 -
-1
care/templates/account/email.html
··· 77 77 $('.form-group').removeClass('row'); 78 78 </script> 79 79 {% endblock %} 80 -
-1
care/templates/account/email_confirm.html
··· 29 29 {% endif %} 30 30 31 31 {% endblock %} 32 -
-1
care/templates/account/logout.html
··· 19 19 20 20 21 21 {% endblock %} 22 -
-1
care/templates/account/password_change.html
··· 14 14 <button class="btn btn-primary" type="submit" name="action">{% trans "Change Password" %}</button> 15 15 </form> 16 16 {% endblock %} 17 -
-1
care/templates/account/password_reset.html
··· 23 23 24 24 <p>{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}</p> 25 25 {% endblock %} 26 -
-1
care/templates/account/password_reset_done.html
··· 14 14 15 15 <p>{% blocktrans %}We have sent you an e-mail. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}</p> 16 16 {% endblock %} 17 -
-1
care/templates/account/password_reset_from_key.html
··· 22 22 {% endif %} 23 23 {% endif %} 24 24 {% endblock %} 25 -
-1
care/templates/account/password_reset_from_key_done.html
··· 7 7 <h1>{% trans "Change Password" %}</h1> 8 8 <p>{% trans 'Your password is now changed.' %}</p> 9 9 {% endblock %} 10 -
-1
care/templates/account/password_set.html
··· 14 14 <input class="btn btn-primary" type="submit" name="action" value="{% trans 'Set Password' %}"/> 15 15 </form> 16 16 {% endblock %} 17 -
-1
care/templates/account/signup_closed.html
··· 9 9 10 10 <p>{% trans "We are sorry, but the sign up is currently closed." %}</p> 11 11 {% endblock %} 12 -
-1
care/templates/account/verification_sent.html
··· 10 10 <p>{% blocktrans %}We have sent an e-mail to you for verification. Follow the link provided to finalize the signup process. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}</p> 11 11 12 12 {% endblock %} 13 -
-1
care/templates/account/verified_email_required.html
··· 21 21 22 22 23 23 {% endblock %} 24 -
-1
care/templates/users/user_detail.html
··· 33 33 34 34 </div> 35 35 {% endblock content %} 36 -
+2 -1
care/users/admin.py
··· 1 1 from django.contrib import admin 2 2 from django.contrib.auth import admin as auth_admin 3 3 from django.contrib.auth import get_user_model 4 + 4 5 from care.users.forms import UserChangeForm, UserCreationForm 5 6 from care.users.models import Skill 6 7 ··· 14 15 add_form = UserCreationForm 15 16 fieldsets = (("User", {"fields": ("user_type",)}),) + auth_admin.UserAdmin.fieldsets 16 17 list_display = ["username", "is_superuser"] 17 - search_fields = ['first_name', 'last_name'] 18 + search_fields = ["first_name", "last_name"] 18 19 19 20 20 21 admin.site.register(Skill)
-2
care/users/api/serializers.py
··· 30 30 ) 31 31 32 32 extra_kwargs = {"url": {"lookup_field": "username"}} 33 - 34 -
+4 -7
care/users/api/views.py
··· 1 1 from django.contrib.auth import get_user_model 2 - from rest_framework import status 2 + from rest_framework import status, viewsets 3 3 from rest_framework.decorators import action 4 + from rest_framework.permissions import IsAuthenticated 4 5 from rest_framework.response import Response 5 - from rest_framework import viewsets 6 - from rest_framework.permissions import IsAuthenticated, IsAdminUser 7 - 8 6 9 - from users.api.serializers import UserSerializer 7 + from care.users.api.serializers import UserSerializer 10 8 11 9 User = get_user_model() 12 10 ··· 36 34 @action(detail=False, methods=["GET"]) 37 35 def getcurrentuser(self, request): 38 36 return Response( 39 - status=status.HTTP_200_OK, 40 - data=self.serializer_class(request.user, context={"request": request}).data, 37 + status=status.HTTP_200_OK, data=self.serializer_class(request.user, context={"request": request}).data, 41 38 )
+15 -15
care/users/forms.py
··· 1 + from crispy_forms.helper import FormHelper 2 + from crispy_forms.layout import Field, Layout 1 3 from django.contrib.auth import forms, get_user_model 2 4 from django.core.exceptions import ValidationError 3 5 from django.utils.translation import ugettext_lazy as _ 4 - from crispy_forms.helper import FormHelper 5 - from crispy_forms.layout import Layout, Field 6 6 7 7 User = get_user_model() 8 8 ··· 63 63 super(CustomSignupForm, self).__init__(*args, **kwargs) 64 64 self.helper = FormHelper() 65 65 self.helper.layout = Layout( 66 - Field('username', placeholder="Desired Username", css_class=""), 67 - Field('first_name', placeholder="Your first name", css_class=""), 68 - Field('last_name', placeholder="Your last name", css_class=""), 69 - Field('email', placeholder="Your Email Address", css_class=""), 70 - Field('district', css_class=""), 71 - Field('phone_number', placeholder="Your 10 Digit Mobile Number", css_class="'"), 72 - Field('gender', css_class=""), 73 - Field('age', placeholder="Your age in numbers", css_class=""), 74 - Field('skill', css_class=""), 75 - Field('password1', placeholder="Password Confirmation", css_class=""), 76 - Field('password2', placeholder="Password", css_class=""), 66 + Field("username", placeholder="Desired Username", css_class=""), 67 + Field("first_name", placeholder="Your first name", css_class=""), 68 + Field("last_name", placeholder="Your last name", css_class=""), 69 + Field("email", placeholder="Your Email Address", css_class=""), 70 + Field("district", css_class=""), 71 + Field("phone_number", placeholder="Your 10 Digit Mobile Number", css_class="'"), 72 + Field("gender", css_class=""), 73 + Field("age", placeholder="Your age in numbers", css_class=""), 74 + Field("skill", css_class=""), 75 + Field("password1", placeholder="Password Confirmation", css_class=""), 76 + Field("password2", placeholder="Password", css_class=""), 77 77 ) 78 78 79 79 ··· 82 82 super(AuthenticationForm, self).__init__(*args, **kwargs) 83 83 self.helper = FormHelper() 84 84 self.helper.layout = Layout( 85 - Field('username', placeholder=" Username", css_class=""), 86 - Field('password', placeholder="Password", css_class=""), 85 + Field("username", placeholder=" Username", css_class=""), 86 + Field("password", placeholder="Password", css_class=""), 87 87 )
+2 -3
care/users/models.py
··· 1 1 from django.contrib.auth.models import AbstractUser, UserManager 2 + from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator 2 3 from django.db import models 3 4 from django.urls import reverse 4 - from django.core.validators import RegexValidator 5 - from django.core.validators import MaxValueValidator, MinValueValidator 6 5 7 6 8 7 class CustomUserManager(UserManager): ··· 50 49 user_type = models.IntegerField(choices=TYPE_CHOICES, blank=False) 51 50 district = models.IntegerField(choices=DISTRICT_CHOICES, blank=False) 52 51 phone_number_regex = RegexValidator( 53 - regex="^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$", 52 + regex=r"^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$", 54 53 message="Please Enter 10/11 digit mobile number or landline as 0<std code><phone number>", 55 54 code="invalid_mobile", 56 55 )
+6 -20
care/users/urls.py
··· 1 + from django.contrib.auth.views import LogoutView 1 2 from django.urls import path 3 + 4 + from .views import SignupView, SinginView 2 5 3 6 # from care.users.views import ( 4 7 # user_detail_view, ··· 6 9 # user_update_view, 7 10 # ) 8 11 9 - from django.contrib.auth.views import LogoutView 10 - from .views import SignupView, SinginView 11 12 12 13 app_name = "users" 13 14 urlpatterns = [ 14 15 # path("~redirect/", view=user_redirect_view, name="redirect"), 15 16 # path("~update/", view=user_update_view, name="update"), 16 17 # path("<str:username>/", view=user_detail_view, name="detail"), 17 - path( 18 - "signup/volunteer/", 19 - SignupView.as_view(), 20 - {"type": 20, "name": "Volunteer"}, 21 - name="signup-volunteer", 22 - ), 23 - path( 24 - "signup/doctor/", 25 - SignupView.as_view(), 26 - {"type": 5, "name": "Doctor"}, 27 - name="signup-doctor", 28 - ), 29 - path( 30 - "signup/staff/", 31 - SignupView.as_view(), 32 - {"type": 10, "name": "Hospital Administrator"}, 33 - name="signup-staff", 34 - ), 18 + path("signup/volunteer/", SignupView.as_view(), {"type": 20, "name": "Volunteer"}, name="signup-volunteer",), 19 + path("signup/doctor/", SignupView.as_view(), {"type": 5, "name": "Doctor"}, name="signup-doctor",), 20 + path("signup/staff/", SignupView.as_view(), {"type": 10, "name": "Hospital Administrator"}, name="signup-staff",), 35 21 path("signin/", SinginView.as_view(), name="signin"), 36 22 path("logout/", LogoutView.as_view(), name="logout"), 37 23 ]
+6 -8
care/users/views.py
··· 1 1 import logging 2 2 3 - from django.shortcuts import render, redirect 4 - from django.contrib.auth import login, authenticate 3 + from django.contrib.auth import authenticate, login 5 4 from django.contrib.auth.forms import AuthenticationForm 5 + from django.http import HttpResponseRedirect 6 + from django.shortcuts import redirect, render 6 7 from django.views import View 7 - from django.http import HttpResponseRedirect 8 8 9 9 from care.users.forms import CustomSignupForm, User 10 10 ··· 20 20 def get(self, request, **kwargs): 21 21 try: 22 22 form = self.form_class() 23 - if kwargs["type"] != User.TYPE_VALUE_MAP['Volunteer']: 24 - form.fields.pop('skill') 25 - return render( 26 - request, self.template, {"form": form, "type": kwargs["name"]} 27 - ) 23 + if kwargs["type"] != User.TYPE_VALUE_MAP["Volunteer"]: 24 + form.fields.pop("skill") 25 + return render(request, self.template, {"form": form, "type": kwargs["name"]}) 28 26 except Exception as e: 29 27 logging.error(e) 30 28 return HttpResponseRedirect("/500")
+1 -1
config/api_router.py
··· 1 1 from django.conf import settings 2 2 from rest_framework.routers import DefaultRouter, SimpleRouter 3 3 4 - from care.facility.api.views import FacilityViewSet, AmbulanceViewSet 4 + from care.facility.api.views import AmbulanceViewSet, FacilityViewSet 5 5 from care.users.api.views import UserViewSet 6 6 7 7 if settings.DEBUG:
+1 -2
config/authentication.py
··· 1 + from rest_framework.authentication import BasicAuthentication 1 2 from rest_framework_simplejwt.authentication import JWTAuthentication 2 - 3 - from rest_framework.authentication import BasicAuthentication 4 3 5 4 6 5 class CustomJWTAuthentication(JWTAuthentication):
+9 -37
config/settings/base.py
··· 2 2 Base settings to build other settings files upon. 3 3 """ 4 4 5 + from datetime import timedelta 6 + 5 7 import environ 6 - from datetime import timedelta 7 8 8 9 ROOT_DIR = environ.Path(__file__) - 3 # (care/config/settings/base.py - 3 = care/) 9 10 APPS_DIR = ROOT_DIR.path("care") ··· 45 46 DATABASES["default"]["ATOMIC_REQUESTS"] = True 46 47 DATABASES["default"]["ENGINE"] = "django.contrib.gis.db.backends.postgis" 47 48 48 - 49 49 # URLS 50 50 # ------------------------------------------------------------------------------ 51 51 # https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf ··· 55 55 56 56 # CollectFast 57 57 COLLECTFAST_STRATEGY = "collectfast.strategies.boto3.Boto3Strategy" 58 - 59 58 60 59 # APPS 61 60 # ------------------------------------------------------------------------------ ··· 102 101 ] 103 102 104 103 ACCOUNT_FORMS = {"signup": "users.forms.CustomSignupForm"} 105 - 106 104 107 105 # https://docs.djangoproject.com/en/dev/ref/settings/#auth-user-model 108 106 AUTH_USER_MODEL = "users.User" ··· 123 121 ] 124 122 # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators 125 123 AUTH_PASSWORD_VALIDATORS = [ 126 - { 127 - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" 128 - }, 124 + {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, 129 125 {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, 130 126 {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, 131 127 {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ··· 185 181 "OPTIONS": { 186 182 # https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders 187 183 # https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types 188 - "loaders": [ 189 - "django.template.loaders.filesystem.Loader", 190 - "django.template.loaders.app_directories.Loader", 191 - ], 184 + "loaders": ["django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader",], 192 185 # https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors 193 186 "context_processors": [ 194 187 "django.template.context_processors.debug", ··· 230 223 # EMAIL 231 224 # ------------------------------------------------------------------------------ 232 225 # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend 233 - EMAIL_BACKEND = env( 234 - "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend" 235 - ) 226 + EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend") 236 227 # https://docs.djangoproject.com/en/2.2/ref/settings/#email-timeout 237 228 EMAIL_TIMEOUT = 5 238 229 ··· 253 244 LOGGING = { 254 245 "version": 1, 255 246 "disable_existing_loggers": False, 256 - "formatters": { 257 - "verbose": { 258 - "format": "%(levelname)s %(asctime)s %(module)s " 259 - "%(process)d %(thread)d %(message)s" 260 - } 261 - }, 262 - "handlers": { 263 - "console": { 264 - "level": "DEBUG", 265 - "class": "logging.StreamHandler", 266 - "formatter": "verbose", 267 - } 268 - }, 247 + "formatters": {"verbose": {"format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s"}}, 248 + "handlers": {"console": {"level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose",}}, 269 249 "root": {"level": "INFO", "handlers": ["console"]}, 270 250 } 271 - 272 251 273 252 # django-allauth 274 253 # ------------------------------------------------------------------------------ ··· 284 263 # https://django-allauth.readthedocs.io/en/latest/configuration.html 285 264 SOCIALACCOUNT_ADAPTER = "care.users.adapters.SocialAccountAdapter" 286 265 287 - 288 266 # Django Rest Framework 289 267 # ------------------------------------------------------------------------------ 290 268 ··· 310 288 LOGOUT_REDIRECT_URL = "/" 311 289 STAFF_ACCOUNT_TYPE = 10 312 290 313 - 314 291 # Simple JWT 315 292 SIMPLE_JWT = { 316 - "ACCESS_TOKEN_LIFETIME": timedelta( 317 - minutes=env("JWT_ACCESS_TOKEN_LIFETIME", default=120) 318 - ), 319 - "REFRESH_TOKEN_LIFETIME": timedelta( 320 - days=env("JWT_REFRESH_TOKEN_LIFETIME", default=7) 321 - ), 293 + "ACCESS_TOKEN_LIFETIME": timedelta(minutes=env("JWT_ACCESS_TOKEN_LIFETIME", default=120)), 294 + "REFRESH_TOKEN_LIFETIME": timedelta(days=env("JWT_REFRESH_TOKEN_LIFETIME", default=7)), 322 295 } 323 - 324 296 325 297 LOCATION_FIELD = { 326 298 "search.provider": "google",
+2 -12
config/settings/local.py
··· 6 6 # https://docs.djangoproject.com/en/dev/ref/settings/#debug 7 7 DEBUG = True 8 8 # https://docs.djangoproject.com/en/dev/ref/settings/#secret-key 9 - SECRET_KEY = env( 10 - "DJANGO_SECRET_KEY", 11 - default="eXZQzOzx8gV38rDG0Z0fFZWweUGl3LwMZ9aTKqJiXQTI0nKMh0Z7sbHfqT8KFEnd", 12 - ) 9 + SECRET_KEY = env("DJANGO_SECRET_KEY", default="eXZQzOzx8gV38rDG0Z0fFZWweUGl3LwMZ9aTKqJiXQTI0nKMh0Z7sbHfqT8KFEnd",) 13 10 # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts 14 11 ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1", "*"] 15 12 16 13 # CACHES 17 14 # ------------------------------------------------------------------------------ 18 15 # https://docs.djangoproject.com/en/dev/ref/settings/#caches 19 - CACHES = { 20 - "default": { 21 - "BACKEND": "django.core.cache.backends.locmem.LocMemCache", 22 - "LOCATION": "", 23 - } 24 - } 16 + CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "",}} 25 17 26 18 # EMAIL 27 19 # ------------------------------------------------------------------------------ ··· 34 26 # ------------------------------------------------------------------------------ 35 27 # http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development 36 28 INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405 37 - 38 29 39 30 # django-debug-toolbar 40 31 # ------------------------------------------------------------------------------ ··· 49 40 } 50 41 # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips 51 42 INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] 52 - 53 43 54 44 # django-extensions 55 45 # ------------------------------------------------------------------------------
+9 -39
config/settings/production.py
··· 2 2 import logging 3 3 4 4 import sentry_sdk 5 - 6 5 from sentry_sdk.integrations.django import DjangoIntegration 7 6 from sentry_sdk.integrations.logging import LoggingIntegration 8 7 ··· 52 51 # TODO: set this to 60 seconds first and then to 518400 once you prove the former works 53 52 SECURE_HSTS_SECONDS = 60 54 53 # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains 55 - SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( 56 - "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True 57 - ) 54 + SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool("DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True) 58 55 # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload 59 56 SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True) 60 57 # https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff 61 - SECURE_CONTENT_TYPE_NOSNIFF = env.bool( 62 - "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True 63 - ) 58 + SECURE_CONTENT_TYPE_NOSNIFF = env.bool("DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True) 64 59 65 60 # STATIC 66 61 # ------------------------ ··· 74 69 TEMPLATES[-1]["OPTIONS"]["loaders"] = [ # type: ignore[index] # noqa F405 75 70 ( 76 71 "django.template.loaders.cached.Loader", 77 - [ 78 - "django.template.loaders.filesystem.Loader", 79 - "django.template.loaders.app_directories.Loader", 80 - ], 72 + ["django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader",], 81 73 ) 82 74 ] 83 75 84 76 # EMAIL 85 77 # ------------------------------------------------------------------------------ 86 78 # https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email 87 - DEFAULT_FROM_EMAIL = env( 88 - "DJANGO_DEFAULT_FROM_EMAIL", default="Care <noreply@coronasafe.in>" 89 - ) 79 + DEFAULT_FROM_EMAIL = env("DJANGO_DEFAULT_FROM_EMAIL", default="Care <noreply@coronasafe.in>") 90 80 # https://docs.djangoproject.com/en/dev/ref/settings/#server-email 91 81 SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) 92 82 # https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix ··· 121 111 LOGGING = { 122 112 "version": 1, 123 113 "disable_existing_loggers": True, 124 - "formatters": { 125 - "verbose": { 126 - "format": "%(levelname)s %(asctime)s %(module)s " 127 - "%(process)d %(thread)d %(message)s" 128 - } 129 - }, 130 - "handlers": { 131 - "console": { 132 - "level": "DEBUG", 133 - "class": "logging.StreamHandler", 134 - "formatter": "verbose", 135 - } 136 - }, 114 + "formatters": {"verbose": {"format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s"}}, 115 + "handlers": {"console": {"level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose",}}, 137 116 "root": {"level": "INFO", "handlers": ["console"]}, 138 117 "loggers": { 139 - "django.db.backends": { 140 - "level": "ERROR", 141 - "handlers": ["console"], 142 - "propagate": False, 143 - }, 118 + "django.db.backends": {"level": "ERROR", "handlers": ["console"], "propagate": False,}, 144 119 # Errors logged by the SDK itself 145 120 "sentry_sdk": {"level": "ERROR", "handlers": ["console"], "propagate": False}, 146 - "django.security.DisallowedHost": { 147 - "level": "ERROR", 148 - "handlers": ["console"], 149 - "propagate": False, 150 - }, 121 + "django.security.DisallowedHost": {"level": "ERROR", "handlers": ["console"], "propagate": False,}, 151 122 }, 152 123 } 153 124 ··· 157 128 SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) 158 129 159 130 sentry_logging = LoggingIntegration( 160 - level=SENTRY_LOG_LEVEL, # Capture info and above as breadcrumbs 161 - event_level=logging.ERROR, # Send errors as events 131 + level=SENTRY_LOG_LEVEL, event_level=logging.ERROR, # Capture info and above as breadcrumbs # Send errors as events 162 132 ) 163 133 sentry_sdk.init(dsn=SENTRY_DSN, integrations=[sentry_logging, DjangoIntegration()]) 164 134
+3 -14
config/settings/test.py
··· 8 8 # GENERAL 9 9 # ------------------------------------------------------------------------------ 10 10 # https://docs.djangoproject.com/en/dev/ref/settings/#secret-key 11 - SECRET_KEY = env( 12 - "DJANGO_SECRET_KEY", 13 - default="GlSRVXhTNJXx3Fnu5HUYlgeoMIXy3rl76CIhfOAEHtXE4jrGAEDbAWyzIpW7SVQn", 14 - ) 11 + SECRET_KEY = env("DJANGO_SECRET_KEY", default="GlSRVXhTNJXx3Fnu5HUYlgeoMIXy3rl76CIhfOAEHtXE4jrGAEDbAWyzIpW7SVQn",) 15 12 # https://docs.djangoproject.com/en/dev/ref/settings/#test-runner 16 13 TEST_RUNNER = "django.test.runner.DiscoverRunner" 17 14 18 15 # CACHES 19 16 # ------------------------------------------------------------------------------ 20 17 # https://docs.djangoproject.com/en/dev/ref/settings/#caches 21 - CACHES = { 22 - "default": { 23 - "BACKEND": "django.core.cache.backends.locmem.LocMemCache", 24 - "LOCATION": "", 25 - } 26 - } 18 + CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "",}} 27 19 28 20 # PASSWORDS 29 21 # ------------------------------------------------------------------------------ ··· 35 27 TEMPLATES[-1]["OPTIONS"]["loaders"] = [ # type: ignore[index] # noqa F405 36 28 ( 37 29 "django.template.loaders.cached.Loader", 38 - [ 39 - "django.template.loaders.filesystem.Loader", 40 - "django.template.loaders.app_directories.Loader", 41 - ], 30 + ["django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader",], 42 31 ) 43 32 ] 44 33
+12 -38
config/urls.py
··· 1 1 from django.conf import settings 2 + from django.conf.urls import url 2 3 from django.conf.urls.static import static 3 4 from django.contrib import admin 4 5 from django.urls import include, path 5 - from django.conf.urls import url 6 6 from django.views import defaults as default_views 7 7 from django.views.generic import TemplateView 8 + from drf_yasg import openapi 9 + from drf_yasg.views import get_schema_view 10 + from rest_framework import permissions 8 11 from rest_framework_simplejwt.views import ( 9 12 TokenObtainPairView, 10 13 TokenRefreshView, 11 14 TokenVerifyView, 12 15 ) 13 - from rest_framework import permissions 14 - from drf_yasg.views import get_schema_view 15 - from drf_yasg import openapi 16 16 17 17 from config import api_router 18 18 ··· 32 32 33 33 urlpatterns = [ 34 34 path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), 35 - path( 36 - "ksdma/", TemplateView.as_view(template_name="pages/ksdma.html"), name="ksdma" 37 - ), 35 + path("ksdma/", TemplateView.as_view(template_name="pages/ksdma.html"), name="ksdma"), 38 36 # API Docs 39 - url( 40 - r"^swagger(?P<format>\.json|\.yaml)$", 41 - schema_view.without_ui(cache_timeout=0), 42 - name="schema-json", 43 - ), 44 - url( 45 - r"^swagger/$", 46 - schema_view.with_ui("swagger", cache_timeout=0), 47 - name="schema-swagger-ui", 48 - ), 49 - url( 50 - r"^redoc/$", schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc" 51 - ), 37 + url(r"^swagger(?P<format>\.json|\.yaml)$", schema_view.without_ui(cache_timeout=0), name="schema-json",), 38 + url(r"^swagger/$", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui",), 39 + url(r"^redoc/$", schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc"), 52 40 # Rest API 53 41 path("api/v1/auth/login/", TokenObtainPairView.as_view(), name="token_obtain_pair"), 54 - path( 55 - "api/v1/auth/token/refresh/", TokenRefreshView.as_view(), name="token_refresh" 56 - ), 42 + path("api/v1/auth/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), 57 43 path("api/v1/auth/token/verify/", TokenVerifyView.as_view(), name="token_verify"), 58 44 # Django Admin, use {% url 'admin:index' %} 59 45 path(settings.ADMIN_URL, admin.site.urls), ··· 70 56 # This allows the error pages to be debugged during development, just visit 71 57 # these url in browser to see how these error pages look like. 72 58 urlpatterns += [ 73 - path( 74 - "400/", 75 - default_views.bad_request, 76 - kwargs={"exception": Exception("Bad Request!")}, 77 - ), 78 - path( 79 - "403/", 80 - default_views.permission_denied, 81 - kwargs={"exception": Exception("Permission Denied")}, 82 - ), 83 - path( 84 - "404/", 85 - default_views.page_not_found, 86 - kwargs={"exception": Exception("Page not Found")}, 87 - ), 59 + path("400/", default_views.bad_request, kwargs={"exception": Exception("Bad Request!")},), 60 + path("403/", default_views.permission_denied, kwargs={"exception": Exception("Permission Denied")},), 61 + path("404/", default_views.page_not_found, kwargs={"exception": Exception("Page not Found")},), 88 62 path("500/", default_views.server_error), 89 63 ] 90 64 if "debug_toolbar" in settings.INSTALLED_APPS:
+1 -3
config/wsgi.py
··· 20 20 21 21 # This allows easy placement of apps within the interior 22 22 # care directory. 23 - app_path = os.path.abspath( 24 - os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) 25 - ) 23 + app_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)) 26 24 sys.path.append(os.path.join(app_path, "care")) 27 25 # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks 28 26 # if running multiple sites in the same mod_wsgi process. To fix this, use
+1 -3
merge_production_dotenvs_in_dotenv.py
··· 12 12 DOTENV_FILE_PATH = os.path.join(ROOT_DIR_PATH, ".env") 13 13 14 14 15 - def merge( 16 - output_file_path: str, merged_file_paths: Sequence[str], append_linesep: bool = True 17 - ) -> None: 15 + def merge(output_file_path: str, merged_file_paths: Sequence[str], append_linesep: bool = True) -> None: 18 16 with open(output_file_path, "w") as output_file: 19 17 for merged_file_path in merged_file_paths: 20 18 with open(merged_file_path, "r") as merged_file:
+6
setup.cfg
··· 1 1 [flake8] 2 2 max-line-length = 120 3 3 exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules 4 + extend-ignore = 5 + # See https://github.com/PyCQA/pycodestyle/issues/373 6 + E203, E231, 4 7 5 8 [pycodestyle] 6 9 max-line-length = 120 ··· 21 24 [mypy-*.migrations.*] 22 25 # Django migrations should not produce any errors: 23 26 ignore_errors = True 27 + 28 + [isort] 29 + known_third_party = allauth,crispy_forms,django,django_filters,drf_extra_fields,drf_yasg,environ,location_field,pytest,rest_framework,rest_framework_simplejwt,sentry_sdk