diff --git a/biometric/cosec.py b/biometric/cosec.py index f571a6dc7..10c4aaaf4 100644 --- a/biometric/cosec.py +++ b/biometric/cosec.py @@ -423,7 +423,11 @@ class COSECBiometric: of the COSEC biometric device, such as setting up card types and their corresponding formats. """ - url = f"{self.__base_url}/smart-card-format?action={action}&card-type={card_type}&index={index}" + url = ( + f"{self.__base_url}/smart-card-format?action={action}" + f"&card-type={card_type}&index={index}" + ) + if action == "set": self.__authenticate_arguments("smart-card-format", kwargs) url += "&" + "&".join( @@ -463,7 +467,11 @@ class COSECBiometric: ref_user_id = 1 code = "13" while code != "0": - url = f"{self.__base_url}/users?action=set&user-id={user_id}&ref-user-id={ref_user_id}&format=xml" + url = ( + f"{self.__base_url}/users?action=set&user-id={user_id}" + f"&ref-user-id={ref_user_id}&format=xml" + ) + response = requests.get( url, headers=self.__header, timeout=self.__timeout ) @@ -524,8 +532,10 @@ class COSECBiometric: "Both user_id and ref_id are mandatory for create & edit a user" ) # user_id : Mandatory To set or retrieve the alphanumeric user ID for the selected user. - # Note: If a set request is sent against an existing user ID, then configuration for this user will be updated with the new values. - # ref_user_id : Mandatory for the set action.Maximum 8 digits.To select the numeric user ID on which the specified operation is to be done. + # Note: If a set request is sent against an existing user ID, then configuration for this + # user will be updated with the new values. + # ref_user_id : Mandatory for the set action.Maximum 8 digits.To select the numeric user + # ID on which the specified operation is to be done. url_arguments = [] url = f"{self.__base_url}/users?action=set" url_arguments.append(f"user-id={user_id}") @@ -556,13 +566,15 @@ class COSECBiometric: url_arguments.append(f"validity-enable={int(validity_enable)}") if validity_date_dd and validity_date_mm and validity_date_yyyy: - # To define the end date for user validity.Valid Values : validity_date_dd = 1-31 & validity_date_mm = 1-12 validity_date_yyyy = based on device model + # To define the end date for user validity.Valid Values : validity_date_dd = 1-31 & + # validity_date_mm = 1-12 validity_date_yyyy = based on device model url_arguments.append(f"validity-date-dd={validity_date_dd}") url_arguments.append(f"validity-date-mm={validity_date_mm}") url_arguments.append(f"validity-date-yyyy={validity_date_yyyy}") if validity_time_hh and validity_time_mm: - # To define the end time for user validity.Valid Values : validity_time_hh = 00-23 & validity_time_mm = 00-59 + # To define the end time for user validity.Valid Values : validity_time_hh = 00-23 + # & validity_time_mm = 00-59 url_arguments.append(f"validity-time-hh={validity_time_hh}") url_arguments.append(f"validity-time-mm={validity_time_mm}") @@ -582,7 +594,8 @@ class COSECBiometric: url_arguments.append(f"by-pass-palm={int(by_pass_palm)}") if card1: - # Values : 64 Bits (8 bytes) (max value - 18446744073709551615).defines the value of access card 1 and 2. + # Values : 64 Bits (8 bytes) (max value - 18446744073709551615). + # Defines the value of access card 1 and 2. url_arguments.append(f"card1={card1}") if card2: url_arguments.append(f"card2={card2}") @@ -594,7 +607,8 @@ class COSECBiometric: url_arguments.append(f"dob-enable={int(dob_enable)}") if dob_dd and dob_mm and dob_yyyy: - # To set or delete the date of birth for a user Valid Values : dob_dd = 1-31 & dob_mm = 1-12 dob_yyyy = 1990-2037 + # To set or delete the date of birth for a user Valid Values : + # dob_dd = 1-31 & dob_mm = 1-12 dob_yyyy = 1990-2037 url_arguments.append(f"dob-dd={dob_dd}") url_arguments.append(f"dob-mm={dob_mm}") url_arguments.append(f"dob-yyyy={dob_yyyy}") @@ -639,7 +653,10 @@ class COSECBiometric: """ Enable or disable face recognition for a user in cosec biometric device. """ - url = f"{self.__base_url}/users?action=set&user-id={user_id}&enable-fr={int(enable_fr)}&format=xml" + url = ( + f"{self.__base_url}/users?action=set&user-id={user_id}" + f"&enable-fr={int(enable_fr)}&format=xml" + ) return self.__send_request(url) def get_user_credential(self, user_id, credential_type=1, finger_index=1): @@ -651,7 +668,8 @@ class COSECBiometric: device based on the provided user ID and credential type. """ - # type values: 1 = Finger , 2 = Card , 3 = Palm , 4 = Palm template with guide mode , 5 = Face Template , 6 = Face Image + # type values: 1 = Finger , 2 = Card , 3 = Palm , 4 = Palm template with + # guide mode , 5 = Face Template , 6 = Face Image if not isinstance(credential_type, int) or not isinstance(finger_index, int): raise ValueError("type and finger_index arguments value must be integers") @@ -661,7 +679,10 @@ class COSECBiometric: if finger_index < 1 or finger_index > 10: raise ValueError("Finger index must be between 1 and 10") - url = f"{self.__base_url}/credential?action=get&type={credential_type}&user-id={user_id}&finger-index={finger_index}" + url = ( + f"{self.__base_url}/credential?action=get&type={credential_type}" + f"&user-id={user_id}&finger-index={finger_index}" + ) return self.__send_request(url) def get_user_credential_count(self, user_id): @@ -686,7 +707,8 @@ class COSECBiometric: card, palm template, face template, or face image, from the COSEC biometric device. """ - # type values: 0 = All , 1 = Finger , 2 = Card , 3 = Palm , 4 = Palm template with guide mode , 5 = Face Template , 6 = Face Image + # type values: 0 = All , 1 = Finger , 2 = Card , 3 = Palm , 4 = Palm template + # with guide mode , 5 = Face Template , 6 = Face Image # type= 5 and 6 are applicable only for ARGO FACE. if type < 0 or type > 6: raise ValueError("Type must be between 0 and 6") @@ -709,5 +731,8 @@ class COSECBiometric: This method retrieves attendance events, such as punch-in and punch-out records, from the COSEC biometric device. """ - url = f"{self.__base_url}/events?action=getevent&roll-over-count={roll_over_count}&seq-number={seq_num}&no-of-events={no_of_events}" + url = ( + f"{self.__base_url}/events?action=getevent&roll-over-count={roll_over_count}" + f"&seq-number={seq_num}&no-of-events={no_of_events}" + ) return self.__send_request(url) diff --git a/biometric/forms.py b/biometric/forms.py index 0f9ec262e..b84697c9c 100644 --- a/biometric/forms.py +++ b/biometric/forms.py @@ -97,8 +97,7 @@ class EmployeeBiometricAddForm(Form): ) def __init__(self, *args, **kwargs): - super(EmployeeBiometricAddForm, self).__init__(*args, **kwargs) - + super().__init__(*args, **kwargs) zk_employee_ids = BiometricEmployees.objects.filter( device_id__machine_type="zk" ).values_list("employee_id", flat=True) @@ -124,7 +123,7 @@ class CosecUserAddForm(Form): ) def __init__(self, *args, **kwargs): - super(CosecUserAddForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) cosec_employee_ids = BiometricEmployees.objects.filter( device_id__machine_type="cosec" ).values_list("employee_id", flat=True) diff --git a/biometric/sidebar.py b/biometric/sidebar.py index 6522f7518..916ca5f11 100644 --- a/biometric/sidebar.py +++ b/biometric/sidebar.py @@ -1,3 +1,7 @@ +""" +Biometric App sidebar configuration +""" + from django.urls import reverse from django.utils.translation import gettext_lazy as trans @@ -15,6 +19,23 @@ SUBMENUS.insert(1, biometric_submenu) def biometric_device_accessibility(request, submenu, user_perms, *args, **kwargs): + """ + Determine if the biometric device submenu should be accessible to the user. + + This function checks if the biometric app exists, if the user has the + necessary permissions to view biometric devices, and if the biometric + system is installed. + + Args: + request: The HTTP request object. + submenu: The submenu being accessed. + user_perms: The permissions of the user. + *args: Additional arguments. + **kwargs: Additional keyword arguments. + + Returns: + bool: True if the submenu should be accessible, False otherwise. + """ return ( biometric_app_exists(None).get("biometric_app_exists") and request.user.has_perm("biometric.view_biometricdevices") diff --git a/biometric/views.py b/biometric/views.py index ab2edc73e..15d01142a 100644 --- a/biometric/views.py +++ b/biometric/views.py @@ -15,7 +15,7 @@ import pytz import requests from apscheduler.schedulers.background import BackgroundScheduler from django.contrib import messages -from django.http import HttpResponse, HttpResponseRedirect, JsonResponse +from django.http import HttpResponse, JsonResponse from django.shortcuts import redirect, render from django.utils.translation import gettext as __ from django.utils.translation import gettext_lazy as _ @@ -105,8 +105,18 @@ def biometric_set_time(conn): class META: + """ + Provides access to HTTP metadata keys. + """ + @classmethod def keys(cls): + """ + Retrieve the list of available HTTP metadata keys. + + Returns: + list: A list of HTTP metadata keys. + """ return ["HTTP_HX_REQUEST"] @@ -502,12 +512,12 @@ def biometric_device_unschedule(request, device_id): Returns: - HttpResponseRedirect: Redirects to the biometric devices view after unscheduling. """ - pd = request.GET.urlencode() + previous_data = request.GET.urlencode() device = BiometricDevices.objects.get(id=device_id) device.is_scheduler = False device.save() messages.success(request, _("Biometric device unscheduled successfully")) - return redirect(f"/biometric/search-devices?{pd}") + return redirect(f"/biometric/search-devices?{previous_data}") @login_required @@ -574,13 +584,13 @@ def biometric_device_archive(request, device_id): """ This method is used to archive or un-archive devices """ - pd = request.GET.urlencode() + previous_data = request.GET.urlencode() device_obj = BiometricDevices.objects.get(id=device_id) device_obj.is_active = not device_obj.is_active device_obj.save() message = _("archived") if not device_obj.is_active else _("un-archived") messages.success(request, _("Device is %(message)s") % {"message": message}) - return redirect(f"/biometric/search-devices?{pd}") + return redirect(f"/biometric/search-devices?{previous_data}") @login_required @@ -602,9 +612,9 @@ def biometric_device_delete(request, device_id): """ device = BiometricDevices.objects.get(id=device_id) device.delete() - pd = request.GET.urlencode() + previous_data = request.GET.urlencode() messages.success(request, _("Biometric device deleted successfully.")) - return redirect(f"/biometric/search-devices?{pd}") + return redirect(f"/biometric/search-devices?{previous_data}") @login_required @@ -1287,17 +1297,16 @@ def edit_cosec_user(request, user_id, device_id): request, _("Biometric user data updated successfully") ) return HttpResponse("") - else: - if update_user.get("error"): - error = update_user.get("error") - if "validity-date-yyyy" in error: - form.add_error( - None, - _( - "This date cannot be used as the Validity End Date for\ - the COSEC Biometric." - ), - ) + if update_user.get("error"): + error = update_user.get("error") + if "validity-date-yyyy" in error: + form.add_error( + None, + _( + "This date cannot be used as the Validity End Date for\ + the COSEC Biometric." + ), + ) return render( request, "biometric/edit_cosec_user.html", @@ -1384,8 +1393,8 @@ def bio_users_bulk_delete(request): ommit_ping=False, ) conn = zk_device.connect() - for id in ids: - user_id = int(id) + for user_id in ids: + user_id = int(user_id) conn.delete_user(user_id=user_id) employee_bio = BiometricEmployees.objects.filter(user_id=user_id).first() employee_bio.delete() @@ -1427,21 +1436,19 @@ def cosec_users_bulk_delete(request): device.cosec_username, device.cosec_password, ) - for id in ids: - cosec.delete_cosec_user(user_id=id) + for user_id in ids: + cosec.delete_cosec_user(user_id=user_id) employee_bio = BiometricEmployees.objects.filter( - user_id=id, device_id=device + user_id=user_id, device_id=device ).first() if employee_bio: employee_bio.delete() messages.success( request, - _( - "{} successfully removed from the biometric device.".format( - employee_bio.employee_id - ), - ), + f"{employee_bio.employee_id} " + + _("successfully removed from the biometric device."), ) + except Exception as error: print(f"An error occurred: {error}") return JsonResponse({"messages": "Success"}) @@ -1575,7 +1582,7 @@ def add_biometric_user(request, device_id): ) response = user.get("Response-Code") if response and response == "0": - employee_bio = BiometricEmployees.objects.create( + BiometricEmployees.objects.create( ref_user_id=ref_user_id, user_id=user_id, employee_id=employee, @@ -1607,7 +1614,7 @@ def biometric_device_live(request): is_live = request.GET.get("is_live") device_id = request.GET.get("deviceId") device = BiometricDevices.objects.get(id=device_id) - is_live = True if is_live == "on" else False + is_live = is_live == "on" if is_live: port_no = device.port machine_ip = device.machine_ip @@ -1643,7 +1650,7 @@ def biometric_device_live(request): }); """ - except Exception as error: + except TimeoutError as error: device.is_live = False device.save() print(f"An error comes in biometric_device_live {error}") @@ -1729,28 +1736,20 @@ def zk_biometric_device_attendance(device_id): time = date_time.time() bio_id = BiometricEmployees.objects.filter(user_id=user_id).first() if bio_id: + request_data = Request( + user=bio_id.employee_id.employee_user_id, + date=date, + time=time, + datetime=date_time, + ) if punch_code in {0, 3, 4}: try: - clock_in( - Request( - user=bio_id.employee_id.employee_user_id, - date=date, - time=time, - datetime=date_time, - ) - ) + clock_in(request_data) except Exception as error: print(f"Got an error : {error}") else: try: - clock_out( - Request( - user=bio_id.employee_id.employee_user_id, - date=date, - time=time, - datetime=date_time, - ) - ) + clock_out(request_data) except Exception as error: print(f"Got an error : {error}") except Exception as error: @@ -1870,10 +1869,7 @@ def cosec_biometric_device_attendance(device_id): elif punch_code in ["2", "4", "6", "8", "10"]: clock_out(request_data) else: - if device.attendance_activity_type == "clock_in": - clock_in(request_data) - elif device.attendance_activity_type == "clock_out": - clock_out(request_data) + pass except Exception as error: print(f"Error processing attendance: {error}")