-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import tkinter as tk | ||
import proctor | ||
import threading | ||
import time | ||
|
||
def show_error_popup(message): | ||
error_popup = tk.Toplevel(app) | ||
error_popup.title("Input Error") | ||
error_popup.geometry("300x150") | ||
error_popup.configure(bg="#2C3E50") | ||
error_label = tk.Label(error_popup, text=message, bg="#2C3E50", fg="#ECF0F1", font=("Helvetica", 12)) | ||
error_label.pack(pady=20) | ||
ok_button = tk.Button(error_popup, text="OK", command=error_popup.destroy, font=("Helvetica", 12, "bold"), bg="#1ABC9C", fg="white") | ||
ok_button.pack(pady=10) | ||
|
||
def show_terms_and_conditions(): | ||
terms_window = tk.Toplevel(app) | ||
terms_window.title("Terms and Conditions") | ||
terms_window.attributes('-fullscreen', True) | ||
terms_window.configure(bg="#2C3E50") | ||
terms_frame = tk.Frame(terms_window, bg="#2C3E50") | ||
terms_frame.pack(expand=True, fill=tk.BOTH, padx=20, pady=20) | ||
terms_text = """\ | ||
Terms and Conditions :- | ||
1.Camera and microphone will be used to monitor exams. | ||
Data is processed locally on your device.If suspicious activity is detected, | ||
the exam may be ended. | ||
Any failure to attend or complete the exam will not be the app’s responsibility. | ||
2.Video, audio, and exam data are processed according to our Privacy Policy | ||
and are not shared without consent, except for exam-related purposes. | ||
3.Violations may result in account suspension or termination. | ||
4.Examify is not responsible for failures to attend or complete | ||
exams due to device issues. | ||
5.Maintain a distance 40-70 Cms from the screen for better exam experience | ||
without any interruption. | ||
6.Make sure you sit in a silent room away from any noise disturbances. | ||
7.You can cry after seeing the questions but make sure the keyboard doesn't | ||
get wet as we won't be responsible for any hardware damage. | ||
8.You can skip the test if you feel like you will fail but don't | ||
blame the app after doing so. | ||
9.It is crucial to stay within the boundary for a valid test. | ||
Certainly! Here’s a more professional version of your message: | ||
10.After selecting "Proceed," you will be directed to a sample camera view where you | ||
can check and adjust your position in relation to your surroundings and the defined boundary limits. | ||
You will have 15 seconds to make these adjustments. Please ensure that the boundary box remains | ||
within the permissible area; if it turns red, it indicates a potential violation. | ||
11.Terms may change; continued use means acceptance of updates. | ||
12.Best of luck. | ||
For questions, contact us at teamx0403@gmail.com | ||
""" | ||
terms_label = tk.Label(terms_frame, text=terms_text, bg="#2C3E50", fg="#ECF0F1", font=("Arial", 10), justify=tk.LEFT) | ||
terms_label.pack(pady=20) | ||
terms_accepted = tk.BooleanVar() | ||
terms_checkbox = tk.Checkbutton(terms_frame, text="I have read and agree to the Terms and Conditions", variable=terms_accepted, bg="#2C3E50", fg="#ECF0F1", font=("Arial", 12), selectcolor="#34495E") | ||
terms_checkbox.pack(pady=10) | ||
proceed_button = tk.Button(terms_frame, text="Proceed", command=lambda: proceed(terms_window, terms_accepted.get()), font=("Arial", 12, "bold"), bg="#28A745", fg="white", state=tk.DISABLED) | ||
proceed_button.pack(pady=20) | ||
terms_accepted.trace("w", lambda *args: proceed_button.config(state=tk.NORMAL if terms_accepted.get() else tk.DISABLED)) | ||
|
||
def proceed(terms_window, accepted): | ||
global full_name,reg_number,test_link | ||
if accepted: | ||
print("Proceeding to the application...") | ||
terms_window.destroy() | ||
app.destroy() | ||
proctor.Tapp(test_link,(full_name,reg_number)) | ||
exit() | ||
else: | ||
print("You must accept the terms to proceed.") | ||
|
||
def submit_form(): | ||
global full_name,reg_number,test_link | ||
full_name = name_entry.get() | ||
reg_number = reg_number_entry.get() | ||
test_link = test_link_entry.get() | ||
if not full_name or not reg_number or not test_link: | ||
show_error_popup("⚠️ All fields are mandatory") | ||
return | ||
print(f"Full Name: {full_name}") | ||
print(f"Registration Number: {reg_number}") | ||
print(f"Test Link: {test_link}") | ||
show_terms_and_conditions() | ||
|
||
app = tk.Tk() | ||
full_name = None | ||
reg_number = None | ||
test_link = None | ||
app.title("Examify") | ||
app.geometry("400x500") | ||
app.configure(bg="#2C3E50") | ||
app.iconbitmap("favicon.ico") | ||
title_label = tk.Label(app, text="Welcome to Examify", bg="#2C3E50", fg="#ECF0F1", font=("Helvetica", 18, "bold")) | ||
title_label.pack(pady=(20, 10)) | ||
border_frame = tk.Frame(app, bg ="#34495E", bd=5, relief="raised") | ||
border_frame.pack(padx=20, pady=20, expand=True, fill=tk.BOTH) | ||
form_frame = tk.Frame(border_frame, bg="#2C3E50") | ||
form_frame.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) | ||
label_font = ("Helvetica", 12, "bold") | ||
entry_font = ("Helvetica", 12) | ||
tk.Label(form_frame, text="Full Name:", bg="#2C3E50", fg="#ECF0F1", font=label_font).pack(pady=(10, 5)) | ||
name_entry = tk.Entry(form_frame, font=entry_font, bg="#34495E", fg="#ECF0F1", insertbackground='white', bd=2, relief="flat", width=30) | ||
name_entry.pack(pady=(0, 10)) | ||
tk.Label(form_frame, text="Registration Number:", bg="#2C3E50", fg="#ECF0F1", font=label_font).pack(pady=(10, 5)) | ||
reg_number_entry = tk.Entry(form_frame, font=entry_font, bg="#34495E", fg="#ECF0F1", insertbackground='white', bd=2, relief="flat", width=30) | ||
reg_number_entry.pack(pady=(0, 10)) | ||
tk.Label(form_frame, text="Test Link:", bg="#2C3E50", fg="#ECF0F1", font=label_font).pack(pady=(10, 5)) | ||
test_link_entry = tk.Entry(form_frame, font=entry_font, bg="#34495E", fg="#ECF0F1", insertbackground='white', bd=2, relief="flat", width=30) | ||
test_link_entry.pack(pady=(0, 10)) | ||
submit_button = tk.Button(form_frame, text="Take Test", command=submit_form, font=("Helvetica", 12, "bold"), bg="#1ABC9C", fg="white", relief="raised", bd=3) | ||
submit_button.pack(pady=20) | ||
app.eval('tk::PlaceWindow . center') | ||
app.mainloop() | ||
|
||
# https://docs.google.com/forms/d/e/1FAIpQLSfuZc4ZKX3ex20-LdhgsOyVwHFRdnWOdZgH2iS72_erJ9sf3A/viewform?usp=sf_link |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import cv2 | ||
import numpy as np | ||
import mediapipe as mp | ||
from math import dist | ||
import winsound | ||
from selenium import webdriver | ||
import time | ||
from threading import Thread | ||
import requests | ||
import keyboard | ||
|
||
data = None | ||
server = "http://localhost:8000" | ||
duration = requests.get(server+"/duration").json()["duration"] | ||
detector = mp.solutions.face_detection.FaceDetection(model_selection=1,min_detection_confidence=0.5) | ||
camera = cv2.VideoCapture(0) | ||
warning = 0 | ||
old = 0 | ||
|
||
def proctor(duration,st): | ||
global warning,old,camera,detector | ||
while time.time()-st<duration: | ||
ret, frame = camera.read() | ||
if not ret: | ||
break | ||
if int(warning)>old: | ||
print("warning") | ||
old=old+1 | ||
winsound.MessageBeep() | ||
h,w,c = frame.shape | ||
frame = cv2.flip(frame, 1) | ||
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) | ||
results = detector.process(rgb_frame) | ||
if results.detections: | ||
for face in results.detections: | ||
face_react = np.multiply( | ||
[ | ||
face.location_data.relative_bounding_box.xmin, | ||
face.location_data.relative_bounding_box.ymin, | ||
face.location_data.relative_bounding_box.width, | ||
face.location_data.relative_bounding_box.height, | ||
],[w,h,w,h]).astype(int) | ||
key_points = np.array([(p.x, p.y) for p in face.location_data.relative_keypoints]) | ||
key_points_coords = np.multiply(key_points,[w,h]).astype(int) | ||
for p in key_points_coords: | ||
cv2.circle(frame, p, 4, (255, 255, 0)) | ||
thresh = dist(key_points_coords[0],key_points_coords[1]) | ||
cv2.putText(frame,f"{thresh}",(30, 30),cv2.FONT_HERSHEY_DUPLEX,0.7,(0, 255, 255),2,) | ||
cv2.putText(frame,f"{warning}",(30, 70),cv2.FONT_HERSHEY_DUPLEX,0.7,(0, 0, 255),2,) | ||
if 65<thresh<120: | ||
cv2.rectangle(frame, face_react, color=(255, 255, 255), thickness=2) | ||
else: | ||
cv2.rectangle(frame, face_react, color=(0, 0, 255), thickness=2) | ||
warning=warning+0.01 | ||
if cv2.waitKey(1) == ord("q"): | ||
break | ||
# cv2.waitKey(1) | ||
cv2.imshow("proctor", frame) | ||
camera.release() | ||
cv2.destroyAllWindows() | ||
|
||
def upload(): | ||
global warning,data | ||
requests.post(server+"/studentdata",json={"name":data[0],"regno":data[1],"warning":warning}) | ||
print(warning,data) | ||
|
||
def test(link,duration): | ||
keyboard.block_key("windows") | ||
driver = webdriver.Chrome(executable_path="chromedriver.exe") | ||
driver.get(link) | ||
driver.fullscreen_window() | ||
time.sleep(duration) | ||
upload() | ||
|
||
def Tapp(link,user_data): | ||
global data,duration | ||
data = user_data | ||
t1 = Thread(target=test,args=(link,duration,)) | ||
t2 = Thread(target=proctor,args=(duration+15,time.time())) | ||
t2.start() | ||
time.sleep(15) | ||
t1.start() | ||
|
||
if __name__ == "__main__": | ||
proctor(60,time.time()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from fastapi import FastAPI | ||
from pydantic import BaseModel | ||
import json | ||
import csv | ||
import math | ||
|
||
class StudentData(BaseModel): | ||
name:"str" | ||
regno:"str" | ||
warning:float | ||
app = FastAPI() | ||
dur = 60 | ||
|
||
@app.get('/duration') | ||
def duration(): | ||
global dur | ||
return {"duration":dur} | ||
|
||
@app.post("/studentdata") | ||
def submit(data:StudentData): | ||
print(data) | ||
with open("credresult.csv","a") as file: | ||
writer = csv.writer(file) | ||
writer.writerow([data.name,data.regno,100-math.floor(data.warning)]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
@echo off | ||
uvicorn server:app | ||
end |