Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import smtplib
|
3 |
+
from email.mime.text import MIMEText
|
4 |
+
from email.mime.multipart import MIMEMultipart
|
5 |
+
import sqlite3
|
6 |
+
from datetime import datetime
|
7 |
+
import pandas as pd
|
8 |
+
from werkzeug.security import generate_password_hash, check_password_hash
|
9 |
+
import random
|
10 |
+
import string
|
11 |
+
|
12 |
+
# Database setup
|
13 |
+
conn = sqlite3.connect("attendance.db", check_same_thread=False)
|
14 |
+
cursor = conn.cursor()
|
15 |
+
|
16 |
+
cursor.execute('''CREATE TABLE IF NOT EXISTS users (
|
17 |
+
id INTEGER PRIMARY KEY,
|
18 |
+
email TEXT UNIQUE,
|
19 |
+
password TEXT,
|
20 |
+
verified INTEGER DEFAULT 0
|
21 |
+
)''')
|
22 |
+
|
23 |
+
cursor.execute('''CREATE TABLE IF NOT EXISTS attendance (
|
24 |
+
id INTEGER PRIMARY KEY,
|
25 |
+
email TEXT,
|
26 |
+
date TEXT,
|
27 |
+
status TEXT
|
28 |
+
)''')
|
29 |
+
|
30 |
+
# Helper Functions
|
31 |
+
def generate_random_password():
|
32 |
+
return ''.join(random.choices(string.ascii_letters + string.digits, k=8))
|
33 |
+
|
34 |
+
def send_email(to_email, subject, body):
|
35 |
+
try:
|
36 |
+
print(f"Sending email to {to_email}: {subject}\n{body}") # Mock email sending
|
37 |
+
return "Email sent successfully!"
|
38 |
+
except Exception as e:
|
39 |
+
return f"Failed to send email: {e}"
|
40 |
+
|
41 |
+
# User Registration
|
42 |
+
user_verification_tokens = {}
|
43 |
+
|
44 |
+
def register_user(email):
|
45 |
+
random_password = generate_random_password()
|
46 |
+
hashed_password = generate_password_hash(random_password)
|
47 |
+
try:
|
48 |
+
cursor.execute("INSERT INTO users (email, password) VALUES (?, ?)", (email, hashed_password))
|
49 |
+
conn.commit()
|
50 |
+
|
51 |
+
# Generate verification link
|
52 |
+
verification_token = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
|
53 |
+
user_verification_tokens[email] = verification_token
|
54 |
+
verification_link = f"http://localhost/verify/{verification_token}" # Replace with actual host
|
55 |
+
|
56 |
+
send_email(email, "Verify Your Account", f"Click here to verify your account: {verification_link}\nYour temporary password: {random_password}")
|
57 |
+
|
58 |
+
return "Registration successful! Check your email to verify your account."
|
59 |
+
except sqlite3.IntegrityError:
|
60 |
+
return "Email already registered."
|
61 |
+
|
62 |
+
# Verify User
|
63 |
+
def verify_user(token):
|
64 |
+
for email, stored_token in user_verification_tokens.items():
|
65 |
+
if stored_token == token:
|
66 |
+
cursor.execute("UPDATE users SET verified = 1 WHERE email = ?", (email,))
|
67 |
+
conn.commit()
|
68 |
+
return "Account verified! Please log in and change your password."
|
69 |
+
return "Invalid verification token."
|
70 |
+
|
71 |
+
# Change Password
|
72 |
+
def change_password(email, old_password, new_password):
|
73 |
+
cursor.execute("SELECT password FROM users WHERE email = ?", (email,))
|
74 |
+
result = cursor.fetchone()
|
75 |
+
if result and check_password_hash(result[0], old_password):
|
76 |
+
hashed_new_password = generate_password_hash(new_password)
|
77 |
+
cursor.execute("UPDATE users SET password = ? WHERE email = ?", (hashed_new_password, email))
|
78 |
+
conn.commit()
|
79 |
+
return "Password changed successfully!"
|
80 |
+
return "Incorrect old password."
|
81 |
+
|
82 |
+
# Log Attendance
|
83 |
+
def log_attendance(email, status):
|
84 |
+
date = datetime.now().strftime("%Y-%m-%d")
|
85 |
+
cursor.execute("INSERT INTO attendance (email, date, status) VALUES (?, ?, ?)", (email, date, status))
|
86 |
+
conn.commit()
|
87 |
+
return "Attendance logged!"
|
88 |
+
|
89 |
+
# Generate Monthly Fees Report
|
90 |
+
def calculate_fees(email):
|
91 |
+
current_month = datetime.now().strftime("%Y-%m")
|
92 |
+
cursor.execute("SELECT COUNT(*) FROM attendance WHERE email = ? AND status = 'Present' AND date LIKE ?", (email, f"{current_month}%"))
|
93 |
+
count_present = cursor.fetchone()[0]
|
94 |
+
total_fees = count_present * 66.67
|
95 |
+
|
96 |
+
# Send email with fees details
|
97 |
+
send_email(email, "Monthly Fees", f"You attended {count_present} classes. Your total fees for the month: ${total_fees:.2f}")
|
98 |
+
|
99 |
+
return f"Fees calculated and email sent: ${total_fees:.2f}"
|
100 |
+
|
101 |
+
# Gradio Interface
|
102 |
+
def login(email, password):
|
103 |
+
cursor.execute("SELECT password, verified FROM users WHERE email = ?", (email,))
|
104 |
+
result = cursor.fetchone()
|
105 |
+
if result and check_password_hash(result[0], password):
|
106 |
+
if result[1] == 1:
|
107 |
+
return f"Welcome {email}!", gr.update(visible=True), email
|
108 |
+
else:
|
109 |
+
return "Account not verified. Check your email.", gr.update(visible=False), None
|
110 |
+
return "Invalid credentials.", gr.update(visible=False), None
|
111 |
+
|
112 |
+
with gr.Blocks() as app:
|
113 |
+
email_state = gr.State()
|
114 |
+
|
115 |
+
# Login Page
|
116 |
+
with gr.Row():
|
117 |
+
gr.Markdown("# Attendance Tracker")
|
118 |
+
|
119 |
+
with gr.Row():
|
120 |
+
email = gr.Textbox(label="Email")
|
121 |
+
password = gr.Textbox(label="Password", type="password")
|
122 |
+
login_button = gr.Button("Login")
|
123 |
+
|
124 |
+
login_message = gr.Textbox(label="Message", interactive=False)
|
125 |
+
attendance_section = gr.Group(visible=False)
|
126 |
+
|
127 |
+
with attendance_section:
|
128 |
+
with gr.Row():
|
129 |
+
gr.Markdown("### Log Attendance")
|
130 |
+
email_display = gr.Textbox(label="Email", interactive=False)
|
131 |
+
status = gr.Radio(["Present", "Absent"], label="Status")
|
132 |
+
log_button = gr.Button("Log Attendance")
|
133 |
+
attendance_message = gr.Textbox(label="Message", interactive=False)
|
134 |
+
|
135 |
+
login_button.click(login, inputs=[email, password], outputs=[login_message, attendance_section, email_state])
|
136 |
+
log_button.click(log_attendance, inputs=[email_state, status], outputs=[attendance_message])
|
137 |
+
|
138 |
+
app.launch()
|