1039 lines
42 KiB
Python
1039 lines
42 KiB
Python
|
||
from kivy.properties import ObjectProperty
|
||
from datetime import datetime, timedelta
|
||
from kivy.core.text import LabelBase
|
||
from kivy.metrics import dp
|
||
from kivy.uix.anchorlayout import AnchorLayout
|
||
from kivy.uix.boxlayout import BoxLayout
|
||
from kivy.uix.button import Button
|
||
from kivy.uix.gridlayout import GridLayout
|
||
from kivy.uix.image import Image
|
||
from kivymd.app import MDApp
|
||
from kivy.core.window import Window
|
||
from kivy.uix.screenmanager import ScreenManager
|
||
from kivy.lang import Builder
|
||
from kivy.uix.screenmanager import ScreenManager, Screen
|
||
from kivymd.uix.datatables import MDDataTable
|
||
import random
|
||
|
||
import csv
|
||
|
||
from kivymd.uix.boxlayout import MDBoxLayout
|
||
from kivymd.uix.button import MDFlatButton
|
||
from kivymd.uix.dialog import MDDialog
|
||
from kivymd.uix.label import MDLabel
|
||
from kivy.uix.label import Label
|
||
|
||
LabelBase.register(name="MPoppins", fn_regular="fonts/Chinese/msyh.ttf")
|
||
LabelBase.register(name="BPoppins", fn_regular="fonts/Chinese/msyh.ttf")
|
||
LabelBase.register(name="RRubik", fn_regular="fonts/Chinese/msyh.ttf")
|
||
LabelBase.register(name="RCro", fn_regular="fonts/Chinese/msyh.ttf")
|
||
LabelBase.register(name="RPac", fn_regular="fonts/Chinese/msyh.ttf")
|
||
|
||
def get_books():
|
||
pass
|
||
|
||
|
||
class MainScreen(Screen):
|
||
pass
|
||
|
||
class LoginScreen(Screen):
|
||
login = ObjectProperty(None)
|
||
|
||
class SignUpScreen(Screen):
|
||
signup: ObjectProperty = ObjectProperty(None)
|
||
|
||
class ForgetPassScreen(Screen):
|
||
forget_Password = ObjectProperty(None)
|
||
|
||
class OtpScreen(Screen):
|
||
otp = ObjectProperty(None)
|
||
|
||
class ResetPassScreen(Screen):
|
||
reset_pass = ObjectProperty(None)
|
||
|
||
class HomeScreen(Screen):
|
||
home = ObjectProperty(None)
|
||
|
||
class ProfileScreen(Screen):
|
||
profile = ObjectProperty(None)
|
||
|
||
class ProfileEditScreen(Screen):
|
||
profile_edit = ObjectProperty(None)
|
||
|
||
class SearchBookScreen(Screen):
|
||
search_book = ObjectProperty(None)
|
||
|
||
class NotificationScreen(Screen):
|
||
notifications = ObjectProperty(None)
|
||
|
||
class RecommendScreen(Screen):
|
||
recommendation = ObjectProperty(None)
|
||
|
||
class BorrowBookScreen(Screen):
|
||
borrow_book = ObjectProperty(None)
|
||
|
||
class ReturnBookScreen(Screen):
|
||
return_book = ObjectProperty(None)
|
||
|
||
class RenewBookScreen(Screen):
|
||
renew_book = ObjectProperty(None)
|
||
|
||
class HistoryScreen(Screen):
|
||
history = ObjectProperty(None)
|
||
|
||
class app(MDApp):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.signup_sem = None
|
||
self.signup_branch = None
|
||
self.user_name = None
|
||
self.book_pos_name = None
|
||
self.book_pos = None
|
||
self.rec_label = None
|
||
self.rec_grid = None
|
||
self.recommend_screen = None
|
||
self.book_input = None
|
||
self.data_tables = None
|
||
self.search_grid = None
|
||
self.search_field = None
|
||
self.renew_grid = None
|
||
self.renewable_books = []
|
||
self.renew = self.renewable_books
|
||
self.history_grid = None
|
||
self.books_history = []
|
||
self.history = self.books_history
|
||
self.image_label_grid = None
|
||
self.books = []
|
||
self.items = self.books
|
||
self.book_name = None
|
||
self.isbn = None
|
||
self.a = None
|
||
self.back_button = None
|
||
self.user = None
|
||
self.dialog = None
|
||
self.profile_edit_screen = None
|
||
self.edit_email = None
|
||
self.edit_prn = None
|
||
self.edit_name = None
|
||
self.edit_number = None
|
||
self.edit_branch = None
|
||
self.profile_semester = None
|
||
self.profile_branch = None
|
||
self.profile_number = None
|
||
self.profile_prn = None
|
||
self.profile_email = None
|
||
self.profile_name = None
|
||
self.user_no = None
|
||
self.user_email = None
|
||
self.user_prn = None
|
||
self.d2 = None
|
||
self.d3 = None
|
||
self.d4 = None
|
||
self.user_pass = None
|
||
self.d1 = None
|
||
self.edit_semester = None
|
||
self.otp_button = None
|
||
self.new_pass = None
|
||
self.new_pass1 = None
|
||
self.mobile_no = None
|
||
self.password = None
|
||
self.username = None
|
||
|
||
|
||
def build(self):
|
||
Builder.load_file('kv/app.kv')
|
||
screen_manager = ScreenManager()
|
||
screen_manager.add_widget(MainScreen(name="main"))
|
||
screen_manager.add_widget(HomeScreen(name="home"))
|
||
screen_manager.add_widget(LoginScreen(name="login"))
|
||
screen_manager.add_widget(SignUpScreen(name="signup"))
|
||
screen_manager.add_widget(ForgetPassScreen(name="forgot_pass"))
|
||
screen_manager.add_widget(OtpScreen(name="otp"))
|
||
screen_manager.add_widget(ResetPassScreen(name="reset_pass"))
|
||
screen_manager.add_widget(ProfileScreen(name="profile"))
|
||
screen_manager.add_widget(ProfileEditScreen(name="profile_edit"))
|
||
screen_manager.add_widget(NotificationScreen(name="notification"))
|
||
screen_manager.add_widget(SearchBookScreen(name="searchBook"))
|
||
screen_manager.add_widget(RecommendScreen(name="recommend"))
|
||
screen_manager.add_widget(BorrowBookScreen(name="borrow_book"))
|
||
screen_manager.add_widget(ReturnBookScreen(name="return_book"))
|
||
screen_manager.add_widget(RenewBookScreen(name="renew_book"))
|
||
screen_manager.add_widget(HistoryScreen(name="history"))
|
||
|
||
return screen_manager
|
||
|
||
#############################################ALL INPUT TEXT############################################################
|
||
def on_start(self):
|
||
login_screen = self.root.get_screen("login")
|
||
self.username = login_screen.ids.username
|
||
self.password = login_screen.ids.password
|
||
|
||
home_screen = self.root.get_screen("home")
|
||
self.user = home_screen.ids.user
|
||
self.book_pos_name = home_screen.ids.book_pos_name
|
||
self.book_pos = home_screen.ids.book_pos
|
||
|
||
forgot_pass_screen = self.root.get_screen("forgot_pass")
|
||
self.mobile_no = forgot_pass_screen.ids.forgotPass_no
|
||
|
||
reset_pass_screen = self.root.get_screen("reset_pass")
|
||
self.new_pass = reset_pass_screen.ids.new_pass
|
||
self.new_pass1 = reset_pass_screen.ids.new_pass1
|
||
|
||
otp_screen = self.root.get_screen("otp")
|
||
self.otp_button = otp_screen.ids.otp_button
|
||
self.back_button = otp_screen.ids.back_button
|
||
self.d1 = otp_screen.ids.d1
|
||
self.d2 = otp_screen.ids.d2
|
||
self.d3 = otp_screen.ids.d3
|
||
self.d4 = otp_screen.ids.d4
|
||
|
||
signup_screen = self.root.get_screen("signup")
|
||
self.user_name = signup_screen.ids.signup_name
|
||
self.user_prn = signup_screen.ids.signup_prn
|
||
self.user_email = signup_screen.ids.signup_email
|
||
self.user_no = signup_screen.ids.signup_no
|
||
self.user_pass = signup_screen.ids.signup_pass
|
||
self.signup_branch = signup_screen.ids.signup_branch
|
||
self.signup_sem = signup_screen.ids.signup_sem
|
||
|
||
profile_screen = self.root.get_screen("profile")
|
||
self.profile_name = profile_screen.ids.profile_name
|
||
self.profile_email = profile_screen.ids.profile_email
|
||
self.profile_prn = profile_screen.ids.profile_prn
|
||
self.profile_number = profile_screen.ids.profile_number
|
||
self.profile_branch = profile_screen.ids.profile_branch
|
||
self.profile_semester = profile_screen.ids.profile_semester
|
||
|
||
self.profile_edit_screen = self.root.get_screen("profile_edit")
|
||
self.edit_name = self.profile_edit_screen.ids.edit_name
|
||
self.edit_email = self.profile_edit_screen.ids.edit_email
|
||
self.edit_prn = self.profile_edit_screen.ids.edit_prn
|
||
self.edit_number = self.profile_edit_screen.ids.edit_no
|
||
self.edit_branch = self.profile_edit_screen.ids.edit_branch
|
||
self.edit_semester = self.profile_edit_screen.ids.edit_sem
|
||
|
||
borrow_screen = self.root.get_screen("borrow_book")
|
||
self.isbn = borrow_screen.ids.isbn
|
||
|
||
return_book_screen = self.root.get_screen("return_book")
|
||
self.image_label_grid = return_book_screen.ids.image_label_grid
|
||
|
||
renew_book_screen = self.root.get_screen("renew_book")
|
||
self.renew_grid = renew_book_screen.ids.renew_grid
|
||
|
||
history_screen = self.root.get_screen("history")
|
||
self.history_grid = history_screen.ids.history_grid
|
||
|
||
search_book_screen = self.root.get_screen("searchBook")
|
||
self.search_field = search_book_screen.ids.search_field
|
||
self.search_grid = search_book_screen.ids.search_grid
|
||
|
||
self.recommend_screen = self.root.get_screen("recommend")
|
||
self.book_input = self.recommend_screen.ids.book_input
|
||
self.rec_grid = self.recommend_screen.ids.rec_grid
|
||
self.rec_label = self.recommend_screen.ids.rec_label
|
||
|
||
#############################################@Frequently used functions##################################################
|
||
|
||
@staticmethod
|
||
def change_cursor(is_enter):
|
||
if is_enter:
|
||
Window.set_system_cursor('hand')
|
||
else:
|
||
Window.set_system_cursor('arrow')
|
||
@staticmethod
|
||
def toggle_password_visibility(password_field, icon_button):
|
||
if password_field.password:
|
||
password_field.password = False
|
||
icon_button.icon = "eye"
|
||
else:
|
||
password_field.password = True
|
||
icon_button.icon = "eye-off"
|
||
|
||
def clear_text(self):
|
||
self.search_field.text = ""
|
||
self.book_input.text = ""
|
||
self.username.text = ""
|
||
self.password.text = ""
|
||
self.mobile_no.text = ""
|
||
self.d1.text = ""
|
||
self.d2.text = ""
|
||
self.d3.text = ""
|
||
self.d4.text = ""
|
||
self.book_pos_name.text = ""
|
||
self.book_pos.text = "Example.,Book Position is 1L42 , 1 represent row no., L represent left side of row, 4 represent rack/shelves no. ,2 represent shelves step no."
|
||
self.mobile_no.text = ""
|
||
self.isbn.text = ''
|
||
|
||
def on_press_back_arrow(self):
|
||
self.username.text = ""
|
||
self.password.text = ""
|
||
self.mobile_no.text = ""
|
||
self.d1.text = ""
|
||
self.d2.text = ""
|
||
self.d3.text = ""
|
||
self.d4.text = ""
|
||
|
||
def focus_text_field(self, icon_button, focus, page):
|
||
if focus:
|
||
icon_button.icon_color = self.theme_cls.primary_color
|
||
elif page == "password":
|
||
icon_button.icon_color = 162 / 255, 169 / 255, 188 / 255, 1
|
||
elif page == "sign_pass":
|
||
icon_button.icon_color = 217 / 255, 217 / 255, 217 / 255, 1
|
||
else:
|
||
pass
|
||
|
||
def otp_button_fun(self, obj):
|
||
if obj == "True":
|
||
self.otp_button.text = "Reset Password"
|
||
elif obj == "1":
|
||
self.otp_button.text = "Edit Credentials"
|
||
elif obj == "2":
|
||
self.otp_button.text = "Verify OTP"
|
||
else:
|
||
self.otp_button.text = "Sign Up"
|
||
|
||
def otp_back_arrow_fun(self):
|
||
if self.otp_button.text == "Sign Up":
|
||
self.root.current = 'signup'
|
||
elif self.otp_button.text == "Reset Password":
|
||
self.root.current = 'reset_pass'
|
||
elif self.otp_button.text == "Verify OTP":
|
||
self.root.current = 'borrow_book'
|
||
|
||
############################################@DIALOG BOX most used functions##############################################
|
||
# MDDialog box function 'dialog'
|
||
|
||
def dialog1(self, text, title="Tips"):
|
||
close_button = MDFlatButton(
|
||
text="关闭",
|
||
font_name="MPoppins",
|
||
on_release=self.close_dialog
|
||
)
|
||
|
||
content_label = Label(
|
||
text=text,
|
||
font_name="MPoppins",
|
||
color=(0, 0, 0, 1),
|
||
size_hint_y=None,
|
||
height=dp(30),
|
||
halign="center",
|
||
valign="middle"
|
||
)
|
||
content_label.bind(size=content_label.setter('text_size'))
|
||
|
||
self.dialog = MDDialog(
|
||
title=title,
|
||
type="custom",
|
||
content_cls=content_label,
|
||
size_hint=(0.84, None),
|
||
buttons=[close_button]
|
||
)
|
||
self.dialog.open()
|
||
|
||
# MDDialog box dismiss function 'close_dialog'
|
||
def close_dialog(self, *args):
|
||
self.dialog.dismiss()
|
||
|
||
###################################LoginPageWork-Start#################################################
|
||
|
||
# login Verification function "verify"
|
||
def verify(self, obj):
|
||
status = False
|
||
if self.username.text == "" or self.password.text == "":
|
||
check = "请输入账户和密码"
|
||
return self.dialog1(check)
|
||
else:
|
||
name = ""
|
||
with open('data/Users.csv', "r", encoding="utf-8") as file:
|
||
csv_reader = csv.reader(file, delimiter=",")
|
||
for line in csv_reader:
|
||
try:
|
||
if not obj:
|
||
a = (line[1] == self.username.text or line[2] == self.username.text)
|
||
else:
|
||
a = (line[1] == self.edit_prn.text or line[2] == self.edit_email.text)
|
||
if a and line[4] == self.password.text:
|
||
status = True
|
||
name = line[0]
|
||
prn = line[1]
|
||
email = line[2]
|
||
number = line[3]
|
||
branch = line[5]
|
||
semester = line[6]
|
||
break
|
||
except IndexError:
|
||
pass
|
||
except Exception as e:
|
||
print(e)
|
||
|
||
if status:
|
||
if not obj:
|
||
check = "Login Successful" + "\nHello! " + name
|
||
else:
|
||
check = "Profile Updated Successfully!"
|
||
self.secure_profile()
|
||
self.root.current = "home"
|
||
self.user.text = f"""[b]Hey! {name}[/b]"""
|
||
self.profile_name.text = self.edit_name.text = name
|
||
self.profile_email.text = self.edit_email.text = email
|
||
self.profile_prn.text = self.edit_prn.text = prn
|
||
self.profile_number.text = self.edit_number.text = number
|
||
self.profile_semester.text = self.edit_semester.text = semester
|
||
self.profile_branch.text = self.edit_branch.text = branch
|
||
|
||
else:
|
||
check = "Login Failed!. " + "Enter correct username and password."
|
||
self.dialog1(check)
|
||
|
||
click_count = 0
|
||
def login_mode(self, username_text, button_text):
|
||
self.click_count += 1
|
||
if self.click_count % 2 == 0:
|
||
username_text.hint_text = "Enter PRN"
|
||
button_text.text = "VIT Email Login"
|
||
username_text.icon_right = "dialpad"
|
||
username_text.helper_text = "PRN of 8 digits starting with 1 2 ......only*"
|
||
username_text.max_text_length = 8
|
||
else:
|
||
username_text.hint_text = "Enter Email"
|
||
username_text.icon_right = "email-arrow-left"
|
||
button_text.text = "VIT PRN Login"
|
||
username_text.helper_text = "enter email ID of vit.edu only*"
|
||
username_text.max_text_length = 50
|
||
|
||
###############################################SIGNUP Page Functions#####################################################
|
||
|
||
# signup Verification function "check_signup"
|
||
def check_signup(self, name, prn, email, num, password, branch, sem):
|
||
if name == "" or prn == "" or email == "" or num == "" or password == "" or branch == "" or sem == "":
|
||
check = "Enter all required fields"
|
||
return self.dialog1(check)
|
||
else:
|
||
status = "None"
|
||
with open('data/Users.csv', "r") as file:
|
||
csv_reader = csv.reader(file, delimiter=',')
|
||
for line in csv_reader:
|
||
try:
|
||
if line[3] == num:
|
||
status = "num"
|
||
break
|
||
if line[1] == prn:
|
||
status = "prn"
|
||
break
|
||
if line[2] == email:
|
||
status = "email"
|
||
break
|
||
|
||
else:
|
||
status = False
|
||
except IndexError:
|
||
pass
|
||
if status == "num":
|
||
check = "Number already registered Please enter a new number"
|
||
return self.dialog1(check)
|
||
elif status == "prn":
|
||
check = "PRN already registered Please enter a PRN"
|
||
return self.dialog1(check)
|
||
elif status == "email":
|
||
check = "Email already registered Please enter a new email"
|
||
return self.dialog1(check)
|
||
else:
|
||
self.root.current = "otp"
|
||
self.send_otp(num)
|
||
check = "One Time Password has been shared on your registered Whatsapp No. Successful!."
|
||
self.dialog1(check)
|
||
|
||
##################################################FORGOT PassWord Page##################################################
|
||
|
||
# FORGOT PASSWORD page mobile number verification function 'verify_no'
|
||
def verify_no(self):
|
||
status = False
|
||
if self.mobile_no.text == "":
|
||
check = "Please enter your Mobile Number."
|
||
return self.dialog1(check)
|
||
else:
|
||
with open('data/Users.csv', "r", encoding="utf-8") as file:
|
||
csv_reader = csv.reader(file, delimiter=",")
|
||
for line in csv_reader:
|
||
try:
|
||
if line[3] == self.mobile_no.text:
|
||
status = True
|
||
break
|
||
else:
|
||
status = False
|
||
except IndexError:
|
||
pass
|
||
except Exception as e:
|
||
print(e)
|
||
|
||
if status:
|
||
check = "One Time Password has been shared on your registered Whatsapp No. Successful!."
|
||
self.root.current = "otp"
|
||
self.send_otp(self.mobile_no.text)
|
||
return self.dialog1(check)
|
||
else:
|
||
check = "Enter Registered Mobile Number."
|
||
self.dialog1(check)
|
||
|
||
def reset_password(self):
|
||
if self.new_pass.text == "" or self.new_pass1.text == "":
|
||
check = "Please enter your new password"
|
||
return self.dialog1(check)
|
||
|
||
elif not self.new_pass.text == self.new_pass1.text:
|
||
check = "Password Does Not Match. \nPlease Re-check your password."
|
||
return self.dialog1(check)
|
||
|
||
else:
|
||
with open('data/Users.csv', "r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
|
||
for row in rows:
|
||
if row['Student_Whatsapp_no'] == self.mobile_no.text:
|
||
row['Student_pass'] = self.new_pass.text
|
||
break
|
||
|
||
try:
|
||
with open('data/Users.csv', "w", newline='', encoding="utf-8") as file:
|
||
headers = ["Student_Name", "Student_PRN", "Student_Email", "Student_Whatsapp_no", "Student_pass",
|
||
"Branch", "Semester"]
|
||
csv_writer = csv.DictWriter(file, fieldnames=headers)
|
||
csv_writer.writeheader()
|
||
csv_writer.writerows(rows)
|
||
check = "Password Updated Successfully!"
|
||
self.root.current = "login"
|
||
except Exception as e:
|
||
print(e)
|
||
check = "Something went wrong please try again."
|
||
self.dialog1(check)
|
||
|
||
###############################################PROFILE & EDIT Profile Page##############################################
|
||
|
||
def edit_profile(self):
|
||
if self.edit_name.text == "" or self.edit_prn.text == "" or self.edit_email.text == "" or self.edit_number.text == "":
|
||
check = "Enter all required fields"
|
||
return self.dialog1(check)
|
||
else:
|
||
with open('data/Users.csv', "r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
|
||
for row in rows:
|
||
if row['Student_Whatsapp_no'] == self.profile_number.text:
|
||
row['Student_Name'] = self.edit_name.text
|
||
row['Student_PRN'] = self.edit_prn.text
|
||
row['Student_Email'] = self.edit_email.text
|
||
row['Student_Whatsapp_no'] = self.edit_number.text
|
||
row['Student_pass'] = self.password.text
|
||
row['Branch'] = self.edit_branch.text
|
||
row['Semester'] = self.edit_semester.text
|
||
break
|
||
|
||
with open('data/Users.csv', newline="", mode="w", encoding="utf-8") as file:
|
||
header = ["Student_Name", "Student_PRN", "Student_Email", "Student_Whatsapp_no", "Student_pass",
|
||
"Branch", "Semester"]
|
||
csv_writer = csv.DictWriter(file, fieldnames=header)
|
||
csv_writer.writeheader()
|
||
csv_writer.writerows(rows)
|
||
self.verify(True)
|
||
self.root.current = "home"
|
||
|
||
def secure_profile(self):
|
||
self.profile_edit_screen.ids.edit_email.readonly = True
|
||
self.profile_edit_screen.ids.edit_prn.readonly = True
|
||
self.profile_edit_screen.ids.edit_no.readonly = True
|
||
self.profile_edit_screen.ids.edit_private_credential_butn.disabled = False
|
||
|
||
|
||
#############################################OTP SEND & VERIFY PAGE#####################################################
|
||
|
||
def send_otp(self, number):
|
||
self.a = random.randint(1000, 9999)
|
||
if len(str(number)) == 10:
|
||
number1 = "+91" + str(number)
|
||
message = f"""Your verification code is {self.a}. It expires in 10 minutes. Don’t share this code with anyone."""
|
||
pywhatkit.sendwhatmsg_instantly(number1, message, wait_time=15, tab_close=True, close_time=3)
|
||
elif len(str(number)) != 10:
|
||
check = "Please enter a 10 digit number."
|
||
return self.dialog1(check)
|
||
else:
|
||
pass
|
||
|
||
def verify_otp(self, d1, d2, d3, d4, otp_button):
|
||
entered_otp = str(d1) + str(d2) + str(d3) + str(d4)
|
||
if entered_otp == str(self.a):
|
||
if otp_button == "Reset Password":
|
||
self.root.current = "reset_pass"
|
||
check = "Reset your password "
|
||
return self.dialog1(check)
|
||
|
||
elif otp_button == "Edit Credentials":
|
||
self.root.current = "profile_edit"
|
||
check = "Edit your credentials "
|
||
self.profile_edit_screen.ids.edit_email.readonly = False
|
||
self.profile_edit_screen.ids.edit_prn.readonly = False
|
||
self.profile_edit_screen.ids.edit_no.readonly = False
|
||
self.profile_edit_screen.ids.edit_private_credential_butn.disabled = True
|
||
return self.dialog1(check)
|
||
|
||
elif otp_button == "Verify OTP":
|
||
self.root.current = "home"
|
||
self.add_book()
|
||
|
||
else:
|
||
data = [self.user_name.text, self.user_prn.text, self.user_email.text, self.user_no.text,
|
||
self.user_pass.text, self.signup_branch.text, self.signup_sem.text]
|
||
|
||
with open('data/Users.csv', encoding="utf-8") as file:
|
||
csv_writer = csv.writer(file, delimiter=",")
|
||
csv_writer.writerow(data)
|
||
|
||
self.root.current = "home"
|
||
check = "SignUP Successful" + "\nHello ! " + self.user_name.text
|
||
self.user.text = "H e y !" + self.user_name.text
|
||
self.verify(True)
|
||
return self.dialog1(check)
|
||
|
||
elif entered_otp != str(self.a):
|
||
check = "Please enter a correct verification code."
|
||
self.d1.text = ""
|
||
self.d2.text = ""
|
||
self.d3.text = ""
|
||
self.d4.text = ""
|
||
return self.dialog1(check)
|
||
|
||
else:
|
||
check = "Sorry! Try again later."
|
||
self.root.current = "login"
|
||
self.d1.text = ""
|
||
self.d2.text = ""
|
||
self.d3.text = ""
|
||
self.d4.text = ""
|
||
return self.dialog1(check)
|
||
|
||
#######################################################Borrow BOok######################################################
|
||
|
||
def get_book(self, isbn):
|
||
self.isbn.text = isbn
|
||
if not self.isbn.text:
|
||
check = "Please enter a valid ISBN."
|
||
return self.dialog1(check)
|
||
elif not len(self.isbn.text) == 13:
|
||
check = "Please enter a valid ISBN."
|
||
return self.dialog1(check)
|
||
else:
|
||
with open('data/Books.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
for row in rows:
|
||
if row["ISBN"] == self.isbn.text:
|
||
if row['Availability'] == "0":
|
||
check = "Your book is unavailable. "
|
||
return self.dialog1(check)
|
||
else:
|
||
self.otp_button_fun('2')
|
||
self.root.current = "otp"
|
||
self.send_otp(self.profile_number.text, )
|
||
|
||
def add_book(self):
|
||
with open('data/Books.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
|
||
for row in rows:
|
||
if row['ISBN'] == self.isbn.text:
|
||
try:
|
||
self.book_name = row['Name']
|
||
a = row['Availability']
|
||
row['Availability'] = str(int(a) - 1)
|
||
except KeyError:
|
||
pass
|
||
|
||
with open('data/Books.csv', newline="", mode="w", encoding="utf-8") as file:
|
||
headers = ["Name", "Author", "Publication Year", "Publisher", "ISBN",
|
||
"Availability"]
|
||
csv_writer = csv.DictWriter(file, fieldnames=headers)
|
||
csv_writer.writeheader()
|
||
csv_writer.writerows(rows)
|
||
|
||
self.date = datetime.now()
|
||
self.Due_date = self.date + timedelta(days=10)
|
||
|
||
details = [self.profile_prn.text, self.profile_number.text, self.book_name, self.isbn.text, self.date,
|
||
self.Due_date, ]
|
||
transaction_details = details + ["Not Returned"]
|
||
borrow_details = details + ["Not Renewed"]
|
||
|
||
files = ['data/borrowed_books.csv', 'data/all_book_transactions.csv']
|
||
for file1 in files:
|
||
with open(file1, "a", encoding="utf-8", newline='') as file:
|
||
csv_writer = csv.writer(file, delimiter=",")
|
||
if file1 == 'data/borrowed_books.csv':
|
||
csv_writer.writerow(borrow_details)
|
||
elif file1 == 'data/all_book_transactions.csv':
|
||
csv_writer.writerow(transaction_details)
|
||
|
||
check = "OTP Verified! \nBook Borrowed Successfully!"
|
||
return self.dialog1(check)
|
||
|
||
def fetch_borrowed_book(self):
|
||
with open('data/borrowed_books.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
self.books.clear()
|
||
for row in rows:
|
||
if row['User'] == self.profile_prn.text:
|
||
book = {'source': 'assets/sample_book_display.jpg', 'btn_text': 'Return Book', 'Book_name': row['Book_Name'],
|
||
'time': row['Due_Date'], 'Renew_status': row['Renew_status']}
|
||
self.books += [book]
|
||
print(self.books)
|
||
self.items = self.books
|
||
|
||
def fetch_renewable_books(self):
|
||
with open('data/borrowed_books.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
self.renewable_books.clear()
|
||
for row in rows:
|
||
a = datetime.strptime(row['Due_Date'], "%Y-%m-%d %H:%M:%S.%f")
|
||
a = a.strftime("%d-%m-%Y")
|
||
if row['User'] == self.profile_prn.text and row[
|
||
'Renew_status'] == "Not Renewed" and a == datetime.now().strftime("%d-%m-%Y"):
|
||
renew_book = {'source': 'assets/sample_book_display.jpg', 'btn_text': 'Renew Book', 'Book_name': row['Book_Name'],
|
||
'time': row['Due_Date'], 'Renew_status': row['Renew_status']}
|
||
self.renewable_books += [renew_book]
|
||
print(self.renewable_books)
|
||
self.renew = self.renewable_books
|
||
|
||
def return_book(self, obj):
|
||
if obj == 'Return':
|
||
self.fetch_borrowed_book()
|
||
self.image_label_grid.clear_widgets()
|
||
book_list = self.items
|
||
elif obj == 'Renew':
|
||
self.fetch_renewable_books()
|
||
self.renew_grid.clear_widgets()
|
||
book_list = self.renew
|
||
|
||
for item in book_list:
|
||
box = MDBoxLayout(orientation='vertical', size_hint_y=None, height="125dp")
|
||
anchor = AnchorLayout(anchor_x="center", anchor_y="center")
|
||
grid = GridLayout(cols=2, spacing=dp(20), size_hint_x=None, size_hint_y=None, size=[dp(320), dp(200)],
|
||
padding=dp(0))
|
||
|
||
img = Image(source=item['source'],
|
||
size_hint_x=None,
|
||
size_hint_y=None,
|
||
width=dp(100),
|
||
height=dp(125),
|
||
allow_stretch=True)
|
||
label = MDLabel(
|
||
text=item['Book_name'],
|
||
font_name="BPoppins",
|
||
size_hint_x=None,
|
||
size_hint_y=None,
|
||
bold=True,
|
||
size=[dp(215), dp(70)],
|
||
padding=dp(0),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
)
|
||
date11 = item['time']
|
||
date22 = "Due Date is "
|
||
for i in range(10):
|
||
date22 += date11[i]
|
||
|
||
label1 = MDLabel(
|
||
text=date22,
|
||
font_name="BPoppins",
|
||
size_hint_x=None,
|
||
size_hint_y=None,
|
||
size=[dp(215), dp(40)],
|
||
padding=dp(0),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
)
|
||
|
||
if item['btn_text'] == "Return Book":
|
||
btn = Button(
|
||
text=item['btn_text'],
|
||
font_name="BPoppins",
|
||
size_hint=(None, None),
|
||
size=(dp(200), dp(30)),
|
||
background_color=(0, 0, 1, 1),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
on_release=lambda instance, src=item['source'], txt=item['btn_text'], name=item['Book_name'],
|
||
time=item['time']: self.remove_book(src, txt, name, time),
|
||
)
|
||
elif item['btn_text'] == "Renew Book":
|
||
btn = Button(
|
||
text=item['btn_text'],
|
||
font_name="BPoppins",
|
||
size_hint=(None, None),
|
||
size=(dp(200), dp(30)),
|
||
background_color=(0, 0, 1, 1),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
on_release=lambda instance, src=item['source'], txt=item['btn_text'], name=item['Book_name'],
|
||
time=item['time']: self.renew_book(src, txt, name, time),
|
||
)
|
||
|
||
vertical_box = BoxLayout(orientation='vertical', size_hint_y=None, height=label.height + btn.height)
|
||
vertical_box.add_widget(label)
|
||
vertical_box.add_widget(label1)
|
||
vertical_box.add_widget(btn)
|
||
|
||
grid.add_widget(img)
|
||
grid.add_widget(vertical_box)
|
||
anchor.add_widget(grid)
|
||
box.add_widget(anchor)
|
||
if btn.text == "Return Book":
|
||
self.image_label_grid.add_widget(box)
|
||
elif btn.text == "Renew Book":
|
||
self.renew_grid.add_widget(box)
|
||
|
||
def remove_book(self, source, text, name, time):
|
||
with open('data/borrowed_books.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.reader(file, delimiter=",")
|
||
header = next(csv_reader)
|
||
rows = list(csv_reader)
|
||
|
||
new_rows = [row for row in rows if row[0] != self.profile_prn.text or row[2] != name or row[5] != time]
|
||
|
||
with open('data/borrowed_books.csv', mode="w", newline="", encoding="utf-8") as file:
|
||
csv_writer = csv.writer(file, delimiter=",")
|
||
csv_writer.writerow(header)
|
||
csv_writer.writerows(new_rows)
|
||
|
||
with open('data/all_book_transactions.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
|
||
return_date = datetime.now()
|
||
return_date = return_date.strftime("%d/%m/%Y")
|
||
|
||
for row in rows:
|
||
if row['User'] == self.profile_prn.text and row['Book_Name'] == name and row['Due_Date'] == time:
|
||
row["Return_Date"] = return_date
|
||
|
||
with open('data/all_book_transactions.csv', mode="w", newline="", encoding="utf-8") as file:
|
||
headers = ['User', 'User_No', 'Book_Name', 'ISBN', 'Date', 'Due_Date', 'Return_Date', ]
|
||
csv_writer = csv.DictWriter(file, fieldnames=headers)
|
||
csv_writer.writeheader()
|
||
csv_writer.writerows(rows)
|
||
|
||
with open('data/Books.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
|
||
for row in rows:
|
||
if row['Name'] == name:
|
||
try:
|
||
a = row['Availability']
|
||
row['Availability'] = str(int(a) + 1)
|
||
except KeyError:
|
||
pass
|
||
|
||
with open('data/Books.csv', newline="", mode="w", encoding="utf-8") as file:
|
||
headers = ["Name", "Author", "Publication Year", "Publisher", "ISBN",
|
||
"Availability"]
|
||
csv_writer = csv.DictWriter(file, fieldnames=headers)
|
||
csv_writer.writeheader()
|
||
csv_writer.writerows(rows)
|
||
|
||
self.items = [item for item in self.items if
|
||
not (item['source'] == source and item['btn_text'] == text and item['Book_name'] == name)]
|
||
|
||
check = "Book Returned Successfully!"
|
||
self.dialog1(check)
|
||
self.return_book("Return")
|
||
|
||
def fetch_book_history(self):
|
||
with open('data/all_book_transactions.csv', mode="r", encoding="utf-8") as file:
|
||
csv_reader = csv.DictReader(file, delimiter=",")
|
||
rows = [row for row in csv_reader]
|
||
self.books_history.clear()
|
||
for row in rows:
|
||
if row['User'] == self.profile_prn.text and row['Return_Date'] != 'Not Returned':
|
||
book = {'source': 'assets/sample_book_display.jpg', 'text': 'Rate Book', 'Book_name': row['Book_Name'],
|
||
'time': row['Date'], 'Return_Date': row['Return_Date']}
|
||
self.books_history += [book]
|
||
self.history = self.books_history
|
||
|
||
def book_history(self):
|
||
self.fetch_book_history()
|
||
self.history_grid.clear_widgets()
|
||
|
||
for item in self.history:
|
||
box = MDBoxLayout(orientation='vertical', size_hint_y=None, height="125.001dp")
|
||
anchor = AnchorLayout(anchor_x="center", anchor_y="center")
|
||
grid = GridLayout(cols=2, spacing=dp(20), size_hint_x=None, size_hint_y=None, size=[dp(320), dp(200)],
|
||
padding=dp(0))
|
||
|
||
img = Image(source=item['source'], size_hint_x=None, size_hint_y=None, width=dp(100), height=dp(125),
|
||
allow_stretch=True)
|
||
label = MDLabel(
|
||
text=item['Book_name'],
|
||
font_name="BPoppins",
|
||
size_hint_x=None,
|
||
size_hint_y=None,
|
||
bold=True,
|
||
size=[dp(215), dp(60)],
|
||
padding=dp(0),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
)
|
||
|
||
B_date = datetime.strptime(item['time'], '%Y-%m-%d %H:%M:%S.%f')
|
||
B_date = B_date.strftime("%d-%m-%Y")
|
||
|
||
formated_B = ""
|
||
for i in range(10):
|
||
formated_B += B_date[i]
|
||
|
||
R_date = datetime.strptime(item['Return_Date'], '%d/%m/%Y')
|
||
R_date = R_date.strftime("%d-%m-%Y")
|
||
formated_R = ""
|
||
for i in range(10):
|
||
formated_R += R_date[i]
|
||
|
||
date22 = f"""Borrow Date: {formated_B}\nReturn Date: {formated_R}"""
|
||
|
||
label1 = MDLabel(
|
||
text=date22,
|
||
font_name="BPoppins",
|
||
size_hint_x=None,
|
||
size_hint_y=None,
|
||
size=[dp(215), dp(50)],
|
||
padding=dp(0),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
)
|
||
|
||
btn = Button(
|
||
text=item['text'],
|
||
font_name="BPoppins",
|
||
size_hint=(None, None),
|
||
size=(dp(200), dp(30)),
|
||
background_color=(0, 0, 1, 1),
|
||
on_touch_down=lambda instance, touch: self.change_cursor(True),
|
||
on_touch_up=lambda instance, touch: self.change_cursor(False),
|
||
)
|
||
vertical_box = BoxLayout(orientation='vertical', size_hint_y=None, height=label.height + btn.height)
|
||
vertical_box.add_widget(label)
|
||
vertical_box.add_widget(label1)
|
||
vertical_box.add_widget(btn)
|
||
|
||
grid.add_widget(img)
|
||
grid.add_widget(vertical_box)
|
||
anchor.add_widget(grid)
|
||
box.add_widget(anchor)
|
||
self.history_grid.add_widget(box)
|
||
|
||
def data_load(self):
|
||
self.search_field.bind(text=self.search_books)
|
||
self.search_grid.clear_widgets()
|
||
self.data_tables = MDDataTable(
|
||
pos_hint={'center_x': 0.5, 'center_y': 0.4},
|
||
size_hint=(0.95, 0.5),
|
||
use_pagination=True,
|
||
padding=dp(0),
|
||
rows_num=7,
|
||
pagination_menu_pos='auto',
|
||
background_color_selected_cell=(0.8, 0.9, 1, 1),
|
||
column_data=[
|
||
("Book Name", dp(80)),
|
||
("Author", dp(50)),
|
||
("Publication Year", dp(30)),
|
||
("Publisher", dp(40)),
|
||
("ISBN", dp(30)),
|
||
("Availability", dp(30)),
|
||
],
|
||
row_data=get_books()
|
||
)
|
||
self.search_grid.add_widget(self.data_tables)
|
||
|
||
def search_books(self, instance, value):
|
||
all_data = get_books()
|
||
filtered_data = [row for row in all_data if (
|
||
value.lower() in row[0].lower() or value.lower() in row[1].lower() or value.lower() in row[4])]
|
||
self.data_tables.row_data = filtered_data
|
||
|
||
def get_recommendations(self):
|
||
book_title = self.book_input.text
|
||
recommendations = self.rec_book(book_title)
|
||
if isinstance(recommendations, str):
|
||
self.rec_label.text = recommendations
|
||
self.rec_grid.clear_widgets()
|
||
else:
|
||
self.display_rec_table(recommendations)
|
||
|
||
@staticmethod
|
||
def rec_book(book_title):
|
||
book_title_lower = book_title.lower()
|
||
if book_title_lower not in df["Name_lower"].values:
|
||
return f"{book_title} not in database"
|
||
index = df[df['Name_lower'] == book_title_lower].index[0]
|
||
|
||
distance, indices = knn.kneighbors(s_matrix[index].reshape(1, -1))
|
||
rec_title = df.iloc[indices.flatten()]["Name"].tolist()
|
||
aval = df.iloc[indices.flatten()]["Availability"].tolist()
|
||
isbn = df.iloc[indices.flatten()]["ISBN"].tolist()
|
||
|
||
recommendation = list(zip(rec_title, isbn, aval))
|
||
|
||
return recommendation
|
||
|
||
def display_rec_table(self, recommendations):
|
||
self.rec_grid.clear_widgets()
|
||
data_tables = MDDataTable(
|
||
pos_hint={'center_x': 0.5, 'center_y': 0.2},
|
||
size_hint=(0.95, 0.2),
|
||
use_pagination=True,
|
||
padding=dp(0),
|
||
rows_num=6,
|
||
pagination_menu_pos='auto',
|
||
background_color_selected_cell=(0.8, 0.9, 1, 1),
|
||
column_data=[
|
||
("Book Name", dp(80)),
|
||
("ISBN", dp(30)),
|
||
("Availability", dp(30)),
|
||
],
|
||
row_data=[(title, isbn, availability) for title, isbn, availability in recommendations]
|
||
)
|
||
self.rec_grid.add_widget(data_tables)
|
||
|
||
def where_is_book(self):
|
||
with open('data/book_positions.csv', 'r') as csvfile:
|
||
data = csv.reader(csvfile, delimiter=',')
|
||
rows = list(data)
|
||
a = self.book_pos_name.text.lower()
|
||
for row in rows:
|
||
if row[0].lower() == a:
|
||
pos = str(row[1])
|
||
self.book_pos.text = f"{a.upper()} Book is kept at {row[1]} location. Please Go and Borrow it!!\n({row[1]} means {pos[0]} th row, Left/Right side(L/R), {pos[2]} th shelf, {pos[3]} th shelf step )"
|
||
break
|
||
else:
|
||
self.book_pos.text = "Please check the Spell!"
|
||
|
||
|
||
# LabelBase.register(name="MPoppins", fn_regular="fonts/Poppins/Poppins-Medium.ttf")
|
||
# LabelBase.register(name="BPoppins", fn_regular="fonts/Poppins/Poppins-SemiBold.ttf")
|
||
# LabelBase.register(name="RRubik", fn_regular="fonts/Rubik_Vinyl/RubikVinyl-Regular.ttf")
|
||
# LabelBase.register(name="RCro", fn_regular="fonts/Croissant_One/CroissantOne-Regular.ttf")
|
||
# LabelBase.register(name="RPac", fn_regular="fonts/Pacifico/Pacifico-Regular.ttf")
|
||
|
||
|
||
|
||
if __name__ == '__main__':
|
||
app().run()
|
||
|
||
|
||
|