[UPDT] BIOMETRIC: Updated biometric app by adding function to enable face recognition for a user in cosec

This commit is contained in:
Horilla
2024-06-11 22:58:41 +05:30
parent 7edcfcd751
commit d15d94cdb3
4 changed files with 108 additions and 67 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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")

View File

@@ -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("<script>window.location.reload()</script>")
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):
});
</script>
"""
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}")