kltn20133118 commited on
Commit
f7b9e98
·
verified ·
1 Parent(s): 725f2e6

Upload 203 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. auth/__pycache__/authentication.cpython-310.pyc +0 -0
  3. auth/__pycache__/authentication.cpython-311.pyc +0 -0
  4. auth/authentication.py +133 -0
  5. controller/ChatController.py +36 -0
  6. controller/DefaultController.py +62 -0
  7. controller/FileController.py +64 -0
  8. controller/LoginController.py +144 -0
  9. controller/MySQLController.py +70 -0
  10. controller/OTPController.py +37 -0
  11. controller/__pycache__/ChatController.cpython-310.pyc +0 -0
  12. controller/__pycache__/ChatController.cpython-311.pyc +0 -0
  13. controller/__pycache__/ChatController.py +35 -0
  14. controller/__pycache__/DefaultController.cpython-310.pyc +0 -0
  15. controller/__pycache__/DefaultController.cpython-311.pyc +0 -0
  16. controller/__pycache__/FileController.cpython-310.pyc +0 -0
  17. controller/__pycache__/FileController.cpython-311.pyc +0 -0
  18. controller/__pycache__/LoginController.cpython-310.pyc +0 -0
  19. controller/__pycache__/LoginController.cpython-311.pyc +0 -0
  20. controller/__pycache__/MySQLController.cpython-310.pyc +0 -0
  21. controller/__pycache__/MySQLController.cpython-311.pyc +0 -0
  22. controller/__pycache__/OTPController.cpython-310.pyc +0 -0
  23. controller/__pycache__/OTPController.cpython-311.pyc +0 -0
  24. entity/Database_Entity.py +68 -0
  25. entity/__pycache__/Database_Entity.cpython-310.pyc +0 -0
  26. entity/__pycache__/Database_Entity.cpython-311.pyc +0 -0
  27. entity/__pycache__/__init__.cpython-310.pyc +0 -0
  28. function/__pycache__/chatbot.cpython-310.pyc +0 -0
  29. function/__pycache__/chatbot.cpython-311.pyc +0 -0
  30. function/__pycache__/dropbox.cpython-310.pyc +0 -0
  31. function/__pycache__/dropbox.cpython-311.pyc +0 -0
  32. function/__pycache__/support_function.cpython-310.pyc +0 -0
  33. function/__pycache__/support_function.cpython-311.pyc +0 -0
  34. function/chatbot.py +685 -0
  35. function/dropbox.py +155 -0
  36. function/support_function.py +129 -0
  37. repository/ChatHistoryRepository.py +237 -0
  38. repository/ConfigDatabase.py +42 -0
  39. repository/DetailChatRepository.py +115 -0
  40. repository/OTPRepository.py +82 -0
  41. repository/UserInfoRepository.py +139 -0
  42. repository/UserLoginRepository.py +135 -0
  43. repository/UserRepository.py +356 -0
  44. repository/__pycache__/ChatHistoryRepository.cpython-310.pyc +0 -0
  45. repository/__pycache__/ChatHistoryRepository.cpython-311.pyc +0 -0
  46. repository/__pycache__/ConfigDatabase.cpython-310.pyc +0 -0
  47. repository/__pycache__/ConfigDatabase.cpython-311.pyc +0 -0
  48. repository/__pycache__/DetailChatRepository.cpython-310.pyc +0 -0
  49. repository/__pycache__/DetailChatRepository.cpython-311.pyc +0 -0
  50. repository/__pycache__/OTPRepository.cpython-310.pyc +0 -0
.gitattributes CHANGED
@@ -36,3 +36,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
36
  tests/test_controller/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text
37
  tests/test_service/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text
38
  tests/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text
 
 
 
36
  tests/test_controller/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text
37
  tests/test_service/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text
38
  tests/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text
39
+ vector_database/vonhuy5112002@gmail.com/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
40
+ vector_database/vonhuy777@gmail.com/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
auth/__pycache__/authentication.cpython-310.pyc ADDED
Binary file (4.65 kB). View file
 
auth/__pycache__/authentication.cpython-311.pyc ADDED
Binary file (8.37 kB). View file
 
auth/authentication.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from typing import Dict
3
+ import jwt
4
+ import secrets
5
+ import logging
6
+ from fastapi import Depends, HTTPException
7
+ import base64
8
+ from datetime import datetime, timedelta
9
+ from repository import UserRepository, UserLoginRepository
10
+ import string, random
11
+
12
+ def check_token_is_valid(token):
13
+ check = UserRepository.getEmailUserByAccessToken(token)
14
+ if check is None:
15
+ return False
16
+ return True
17
+
18
+ def unique_string(byte: int = 8) -> str:
19
+ return secrets.token_urlsafe(byte)
20
+ JWT_SECRET = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
21
+ JWT_ALGORITHM = "HS512"
22
+ SECRET_KEY="8deadce9449770680910741063cd0a3fe0acb62a8978661f421bbcbb66dc41f1"
23
+
24
+ def token_response(token: str):
25
+ return {
26
+ "access_token": token
27
+ }
28
+ def str_encode(string: str) -> str:
29
+ return base64.b85encode(string.encode('ascii')).decode('ascii')
30
+
31
+ def get_token_payload(token: str, secret: str, algo: str):
32
+ try:
33
+ payload = jwt.decode(token, secret, algorithms=algo)
34
+ except Exception as jwt_exec:
35
+ logging.debug(f"JWT Error: {str(jwt_exec)}")
36
+ payload = None
37
+ return payload
38
+
39
+ from datetime import datetime
40
+ def generate_token(payload: dict, secret: str, algo: str, expiry: timedelta):
41
+ expire = datetime.now() + expiry
42
+ payload.update({"exp": expire})
43
+ return jwt.encode(payload, secret, algorithm=algo)
44
+
45
+ def str_decode(string: str) -> str:
46
+ return base64.b85decode(string.encode('ascii')).decode('ascii')
47
+
48
+ def generate_random_string(length=12):
49
+ characters = string.ascii_letters + string.digits
50
+ random_string = ''.join(random.choice(characters) for i in range(length))
51
+ return random_string
52
+
53
+ import pytz
54
+ from datetime import datetime
55
+ def signJWT(user_email: str) -> Dict[str, str]:
56
+ rt_expires = timedelta(minutes=3)
57
+ refresh_key = unique_string(100)
58
+ access_key = unique_string(50)
59
+ at_expires = timedelta(minutes=2)
60
+ at_payload = {
61
+ "sub": str_encode(str(user_email)),
62
+ 'a': access_key,
63
+ }
64
+ access_token = generate_token(at_payload, JWT_SECRET, JWT_ALGORITHM, at_expires)
65
+ rt_payload = {"sub": str_encode(str(user_email)), "t": refresh_key, 'a': access_key}
66
+ refresh_token = generate_token(rt_payload, SECRET_KEY,JWT_ALGORITHM, rt_expires)
67
+ expires_in = at_expires.seconds
68
+ vn_timezone = pytz.timezone('Asia/Ho_Chi_Minh')
69
+ current_time = datetime.now().replace(tzinfo=pytz.utc).astimezone(vn_timezone) + timedelta(seconds=expires_in)
70
+ formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S ')
71
+ existing_user = UserRepository.getUserByEmail(user_email)
72
+ if existing_user is None:
73
+ UserRepository.addUser(user_email, access_token, refresh_token, formatted_time)
74
+ else:
75
+ UserRepository.updateUserLogin(user_email, access_token, refresh_token, formatted_time)
76
+ user_record = UserRepository.getUserByEmail(user_email)
77
+ session_id = ""
78
+ if user_record:
79
+ session_id = generate_random_string()
80
+ existing_userlogin = UserLoginRepository.getUserLogin(user_email)
81
+ if existing_userlogin is None:
82
+ UserLoginRepository.addUserLogin(user_email,session_id=session_id)
83
+ else:
84
+ UserLoginRepository.updateUserLogin(user_email, session_id)
85
+ return {
86
+ "access_token": access_token,
87
+ "refresh_token": refresh_token,
88
+ "expires_in": at_expires.seconds,
89
+ "session_id": session_id
90
+ }
91
+
92
+ def returnAccessToken(user_email: str, refresh_token: str) -> Dict[str, str]:
93
+ access_key = unique_string(50)
94
+ at_expires = timedelta(minutes=2)
95
+ at_payload = {
96
+ "sub": str_encode(str(user_email)),
97
+ 'a': access_key,
98
+ }
99
+ access_token = generate_token(at_payload, JWT_SECRET, JWT_ALGORITHM, at_expires)
100
+ user_record = UserRepository.getUserByEmail(user_email)
101
+ session_id = ""
102
+ if user_record:
103
+ email1 = user_record.email
104
+ if email1:
105
+ session_id = generate_random_string()
106
+ existing_userlogin = UserLoginRepository.getUserLogin(user_email)
107
+ if existing_userlogin is None:
108
+ UserLoginRepository.addUserLogin(user_email,session_id=session_id)
109
+ else:
110
+ UserLoginRepository.updateUserLogin(user_email,session_id)
111
+ return {
112
+ "access_token": access_token,
113
+ "refresh_token": refresh_token,
114
+ "expires_in": at_expires.seconds,
115
+ "session_id": session_id
116
+ }
117
+
118
+ def decodeJWT(token: str) -> dict:
119
+ try:
120
+ decoded_token = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
121
+ return decoded_token if decoded_token["exp"] >= time.time() else None
122
+ except:
123
+ return {}
124
+
125
+ def get_refresh_token(refresh_token,token_now, email):
126
+ token_payload = get_token_payload(refresh_token, SECRET_KEY, JWT_ALGORITHM)
127
+ if not token_payload:
128
+ raise HTTPException(status_code=400, detail="Invalid Request.")
129
+ exp = token_payload.get('exp')
130
+ if exp >= time.time() and token_payload:
131
+ return returnAccessToken(email,refresh_token)
132
+ elif not token_payload:
133
+ return signJWT(email)
controller/ChatController.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Form, Request
2
+ from service import ChatService
3
+ from request import RequestChat
4
+ from typing import Optional
5
+ from fastapi.requests import Request
6
+ from function import support_function
7
+ from response import ResponseChat as res
8
+ router = APIRouter()
9
+
10
+ @router.post("/chatbot/query/", tags=["Chat"])
11
+ async def handle_query2_upgrade_old(request: Request,
12
+ user_id: str = Form(None),
13
+ text_all: str = Form(...),
14
+ question: Optional[str] = Form(None),
15
+ chat_name: Optional[str] = Form(None)):
16
+ check = support_function.check_value_user_id_controller(user_id)
17
+ if check is not True:
18
+ return check
19
+ request = RequestChat.RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name)
20
+ return ChatService.query2_upgrade_old(request)
21
+
22
+ @router.get("/chatbot/extract_file/", tags=["Chat"])
23
+ async def extract_file(user_id: str):
24
+ check = support_function.check_value_user_id_controller(user_id)
25
+ if check is not True:
26
+ return check
27
+ request = RequestChat.RequestExtractFile(user_id=user_id)
28
+ return ChatService.extract_file(request)
29
+
30
+ @router.get("/chatbot/generate_question/",tags=["Chat"])
31
+ async def generate_question(user_id: str):
32
+ check = support_function.check_value_user_id_controller(user_id)
33
+ if check is not True:
34
+ return check
35
+ request = RequestChat.RequestGenerateQuestion(user_id=user_id)
36
+ return ChatService.generate_question(request)
controller/DefaultController.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import HTTPException, Depends, Query,APIRouter
2
+ from service import DefaultService
3
+ from request import RequestDefault
4
+ from request import RequestDefault as req
5
+ from function import support_function
6
+ from auth.authentication import decodeJWT
7
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
8
+ from fastapi.responses import JSONResponse
9
+ from auth import authentication
10
+ from fastapi.requests import Request
11
+ from response import ResponseDefault as res
12
+ from fastapi import File, UploadFile, Form
13
+ router = APIRouter()
14
+
15
+ @router.get("/is_me/", tags=["Default"])
16
+ async def is_me(token: str = Query(...)):
17
+ if token.strip() == "" or token is None:
18
+ return res.ReponseError(status=400,
19
+ data=res.Message(message="Token field is required."))
20
+ if token.lower() == "none":
21
+ return res.ReponseError(status=400,
22
+ data=res.Message(message="Token cannot be None."))
23
+ if not isinstance(token, str):
24
+ return res.ReponseError(status=400,
25
+ data=res.Message(message="Token must be a non-empty string."))
26
+ try:
27
+ float(token)
28
+ return res.ReponseError(status=400,
29
+ data=res.Message(message="Token must be a string, not a number."))
30
+ except ValueError:
31
+ pass
32
+ request = RequestDefault.RequestIsMe(token=token)
33
+ return DefaultService.is_me(request)
34
+
35
+ @router.post('/create_firebase_user_google', tags=["Default"])
36
+ async def get_or_create_firebase_user(request: RequestDefault.RequestCreateFireBaseUserGoogle):
37
+ email = request.email
38
+ check = support_function.check_value_email_controller(request.email)
39
+ if check is not True:
40
+ return check
41
+ return DefaultService.create_firebase_user(request)
42
+
43
+ @router.get("/info_user", tags=["Default"])
44
+ async def get_user(user_id: str = Query(None)):
45
+ check = support_function.check_value_user_id_controller(user_id)
46
+ if check is not True:
47
+ return check
48
+ request = RequestDefault.RequestInfoUser(user_id=user_id)
49
+ return DefaultService.info_user(request)
50
+
51
+ ALLOWED_IMAGE_EXTENSIONS = {"jpeg", "jpg", "png"}
52
+
53
+ def allowed_file(filename: str) -> bool:
54
+ return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_IMAGE_EXTENSIONS
55
+
56
+ @router.post("/upload_image/", tags=["Default"])
57
+ async def upload_image(user_id: str = Form(None), file: UploadFile = File(...)):
58
+ check = support_function.check_value_user_id_controller(user_id)
59
+ if check is not True:
60
+ return check
61
+ request = req.RequestUpLoadImage(user_id=user_id, files= file)
62
+ return DefaultService.upload_image_service(request)
controller/FileController.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Form, File, UploadFile,Query
2
+ from typing import List,Optional
3
+ from service import FileService
4
+ from function import support_function
5
+ from fastapi import HTTPException
6
+ from response import ResponseFile as res
7
+ from request import RequestFile
8
+ router = APIRouter()
9
+
10
+ ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json', 'html'}
11
+ def allowed_file(filename):
12
+ return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
13
+
14
+ @router.delete("/delete_all_file/", tags=["File"])
15
+ async def delete_folder(request: RequestFile.RequestDeleteAllFile):
16
+ check = support_function.check_value_user_id_controller(request.user_id)
17
+ if check is not True:
18
+ return check
19
+ # request = RequestFile.RequestDeleteAllFile(user_id=user_id)
20
+ return FileService.deleteAllFile(request)
21
+
22
+ @router.get("/list_name_files/", tags=["File"])
23
+ async def get_name(user_id: str):
24
+ check = support_function.check_value_user_id_controller(user_id)
25
+ if check is not True:
26
+ return check
27
+ request = RequestFile.RequestGetNameFile(user_id=user_id)
28
+ return FileService.listNameFiles(request)
29
+
30
+ @router.delete("/delete_one_file/", tags=["File"])
31
+ async def delete_one_file(request: RequestFile.RequestDeleteFile):
32
+ user_id = request.user_id
33
+ check = support_function.check_value_user_id_controller(user_id)
34
+ if check is not True:
35
+ return check
36
+ name_file = request.name_file
37
+ if name_file is None or name_file.strip() == "":
38
+ return res.ReponseError(status=400,
39
+ data=res.Message(message="Name file is required."))
40
+ return FileService.deleteFile(request)
41
+
42
+ @router.post("/chatbot/download_folder/", tags=["File"])
43
+ async def download_folder_from_dropbox(request: RequestFile.RequestDownLoadFolder):
44
+ user_id = request.user_id
45
+ check = support_function.check_value_user_id_controller(user_id)
46
+ if check is not True:
47
+ return check
48
+ return FileService.download_folder(request)
49
+
50
+ @router.post("/chatbot/download_files/", tags=["File"])
51
+ async def download_file_by_id(request: RequestFile.RequestDownLoadFile):
52
+ user_id = request.user_id
53
+ check = support_function.check_value_user_id_controller(user_id)
54
+ if check is not True:
55
+ return check
56
+ return FileService.download_file(request)
57
+
58
+ @router.post("/upload_files/", tags=["File"])
59
+ async def upload_files_dropbox(user_id: str = Form(None), files: Optional[List[UploadFile]] = File(None)):
60
+ check = support_function.check_value_user_id_controller(user_id)
61
+ if check is not True:
62
+ return check
63
+ request = RequestFile.RequestUploadFile(files=files, user_id=user_id)
64
+ return FileService.upload_files(request)
controller/LoginController.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Query
2
+ from request import RequestLogin
3
+ from response import ResponseLogin as res
4
+ from service import LoginService
5
+ from function import support_function
6
+ from fastapi import HTTPException
7
+ from response import ResponseLogin as res
8
+ router = APIRouter()
9
+
10
+ @router.post('/login', tags=["Login"])
11
+ async def login(request: RequestLogin.RequestLoginEmail):
12
+ email = request.email
13
+ check = support_function.check_value_email_controller(email)
14
+ if check is not True:
15
+ return check
16
+ password = request.password
17
+ if password is None or password.strip() == "":
18
+ return res.ReponseError(status=400,
19
+ data=res.Message(message="Password is required."))
20
+ return LoginService.login(request)
21
+
22
+ @router.post('/login_google', tags=["Login"])
23
+ async def login_google(request: RequestLogin.RequestLoginGoogle):
24
+ email = request.email
25
+ token_google = request.token_google
26
+ check = support_function.check_value_email_controller(email)
27
+ if check is not True:
28
+ return check
29
+ if token_google is None or token_google.strip() == "":
30
+ return res.ReponseError(status=400,
31
+ data=res.Message(message="token_google oauth2 is required."))
32
+ if token_google.isdigit():
33
+ return res.ReponseError(status=400,
34
+ data=res.Message(message="token_google must be a string, not a number."))
35
+ return LoginService.login_google(request)
36
+
37
+ @router.post("/update_user_info", tags=["Login"])
38
+ async def update_user_info(request: RequestLogin.RequestUpdateUserInfo):
39
+ user_id = request.user_id
40
+ check = support_function.check_value_user_id_controller(user_id)
41
+ if check is not True:
42
+ return check
43
+ uid = request.uid
44
+ email = request.email
45
+ display_name = request.display_name
46
+ photo_url = request.photo_url
47
+ if uid is None or uid.strip() == "":
48
+ return res.ReponseError(status=400,
49
+ data=res.Message(message="uid field is required."))
50
+ if email is None or email.strip() == "":
51
+ return res.ReponseError(status=400,
52
+ data=res.Message(message="email field is required."))
53
+ if display_name is None or display_name.strip() == "":
54
+ return res.ReponseError(status=400,
55
+ data=res.Message(message="display_name field is required."))
56
+ if photo_url is None or photo_url.strip() == "":
57
+ return res.ReponseError(status=400,
58
+ data=res.Message(message="photo_url field is required."))
59
+ return LoginService.update_user_info(request)
60
+
61
+ @router.get('/check_info_google', tags=["Login"])
62
+ async def check_info_google(user_id: str = Query(None)):
63
+ check = support_function.check_value_user_id_controller(user_id)
64
+ if check is not True:
65
+ return check
66
+ request = RequestLogin.RequestCheckInfoGoogle(user_id=user_id)
67
+ return LoginService.check_info_google(request)
68
+
69
+ @router.get('/check_info_google_signup', tags=["Login"])
70
+ async def check_info_google_signup(email: str = None):
71
+ check = support_function.check_value_email_controller(email)
72
+ if check is not True:
73
+ return check
74
+ request = RequestLogin.RequestCheckInfoGoogleEmail(email=email)
75
+ return LoginService.check_info_google_email(request)
76
+
77
+ @router.get('/check_state_login', tags=["Login"])
78
+ async def check_state_login(user_id: str = Query(None), session_id_now: str = Query(None)):
79
+ check = support_function.check_value_user_id_controller(user_id)
80
+ if check is not True:
81
+ return check
82
+ if session_id_now is None or session_id_now.strip() == "":
83
+ return res.ReponseError(status=400,
84
+ data=res.Message(message="Session Id is required."))
85
+ try:
86
+ int(session_id_now)
87
+ return res.ReponseError(status=400,
88
+ data=res.Message(message="Session Id must be a string, not a number."))
89
+ except ValueError:
90
+ pass
91
+ request = RequestLogin.RequestCheckStateLogin(user_id=user_id, session_id_now=session_id_now)
92
+ return LoginService.check_state_login(request)
93
+
94
+ @router.post('/sign_up', tags=["Login"])
95
+ async def signup(request: RequestLogin.RequestSignUp):
96
+ email = request.email
97
+ check = support_function.check_value_email_controller(email)
98
+ if check is not True:
99
+ return check
100
+ password = request.password
101
+ if password is None or password.strip( )== "":
102
+ return res.ReponseError(status=400,
103
+ data=res.Message(message="Password is required."))
104
+ return LoginService.sign_up(request)
105
+
106
+ @router.post('/reset_password', tags=["Login"])
107
+ async def reset_password(request: RequestLogin.RequestResetPassword):
108
+ email = request.email
109
+ check = support_function.check_value_email_controller(email)
110
+ if check is not True:
111
+ return check
112
+ return LoginService.reset_password(request)
113
+
114
+ @router.put('/change_password', tags=["Login"])
115
+ async def reset_password_firebase(request: RequestLogin.RequestChangePassword):
116
+ user_id = request.user_id
117
+ check = support_function.check_value_user_id_controller(user_id)
118
+ if check is not True:
119
+ return check
120
+ new_password = request.new_password
121
+ current_password = request.current_password
122
+ if new_password is None or new_password.strip() == "":
123
+ return res.ReponseError(status=400,
124
+ data=res.Message(message="New password field is required."))
125
+ if current_password is None or current_password.strip() == "":
126
+ return res.ReponseError(status=400,
127
+ data=res.Message(message="Current password field is required."))
128
+ return LoginService.change_password(request)
129
+
130
+ @router.post('/refresh_token/', tags=["Login"])
131
+ async def refresh_token_account(request: RequestLogin.RequestRefreshTokenLogin):
132
+ user_id = request.user_id
133
+ check = support_function.check_value_user_id_controller(user_id)
134
+ if check is not True:
135
+ return check
136
+ token = request.token
137
+ if token is None or token.strip() == "":
138
+ return res.ReponseError(status=400,
139
+ data=res.Message(message="token is required."))
140
+ elif token.isdigit():
141
+ return res.ReponseError(status=400,
142
+ data=res.Message(message="token must be string"))
143
+
144
+ return LoginService.refresh_token(request)
controller/MySQLController.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import Query, APIRouter
2
+ from service import MySQLService
3
+ from request import RequestMySQL
4
+ from response import ResponseMySQL as res
5
+ from typing import Optional
6
+ from request import RequestMySQL as req
7
+ from function import support_function
8
+ from fastapi import HTTPException
9
+ router = APIRouter()
10
+
11
+ @router.get("/render_chat_history", tags=["MySQL"])
12
+ async def render_chat(user_id: Optional[str] = Query(None)):
13
+ check = support_function.check_value_user_id_controller(user_id)
14
+ if check is not True:
15
+ return check
16
+ request = RequestMySQL.RequestRenderChatHistory(user_id=user_id)
17
+ return MySQLService.render_chat_history(request)
18
+
19
+ @router.get("/data_relevant", tags=["MySQL"])
20
+ async def render_chat_1(chat_detail_id: str):
21
+ if chat_detail_id is None or chat_detail_id.strip() == "":
22
+ return res.ReponseError(status=400,
23
+ data=res.Message(message="Id field is required."))
24
+ chat_detail_id = chat_detail_id.strip("'").strip('"')
25
+ try:
26
+ chat_detail_id_int = int(chat_detail_id)
27
+ except ValueError:
28
+ return res.ReponseError(status=400,
29
+ data=res.Message(message="Value must be an integer"))
30
+ if not support_function.is_positive_integer(chat_detail_id_int):
31
+ return res.ReponseError(status=400,
32
+ data=res.Message(message="Value must be greater than 0"))
33
+ request = req.RequestGetChatDetails(id=chat_detail_id)
34
+ return MySQLService.get_detail_chat_by_chat_id(request)
35
+
36
+ @router.get("/load_chat_history", tags=["MySQL"])
37
+ async def load_chat(chat_id: Optional[str] = Query(None), user_id: Optional[str] = Query(None)):
38
+ check = support_function.check_value_user_id_controller(user_id)
39
+ if check is not True:
40
+ return check
41
+ if chat_id is None or chat_id.strip() == "":
42
+ return res.ReponseError(status=400,
43
+ data=res.Message(message="Chat id field is required."))
44
+ chat_id = chat_id.strip("'").strip('"')
45
+ try:
46
+ chat_id_int = int(chat_id)
47
+ except ValueError:
48
+ return res.ReponseError(status=400,
49
+ data=res.Message(message="Value must be an integer"))
50
+ if not support_function.is_positive_integer(chat_id_int):
51
+ return res.ReponseError(status=400,
52
+ data=res.Message(message="Value must be greater than 0"))
53
+ request = req.RequestLoadChatHistory(chat_id=chat_id,user_id = user_id)
54
+ return MySQLService.load_chat_history(request)
55
+
56
+ @router.put("/edit_chat/", tags=["MySQL"])
57
+ async def edit_chat(request: RequestMySQL.RequestEditNameChat):
58
+ user_id = request.user_id
59
+ check = support_function.check_value_user_id_controller(user_id)
60
+ if check is not True:
61
+ return check
62
+ return MySQLService.edit_chat(request)
63
+
64
+ @router.delete("/delete_chat/", tags=["MySQL"])
65
+ async def delete_chat(request: RequestMySQL.RequestDeleteChat):
66
+ user_id = request.user_id
67
+ check = support_function.check_value_user_id_controller(user_id)
68
+ if check is not True:
69
+ return check
70
+ return MySQLService.delete_chat(request)
controller/OTPController.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter
2
+ from function import support_function
3
+ from request import RequestOTP
4
+ from service import OTPService
5
+ from fastapi import HTTPException
6
+ from pydantic.error_wrappers import ErrorWrapper
7
+ from pydantic import BaseModel
8
+ from response import ResponseOTP as res
9
+ router = APIRouter()
10
+
11
+ @router.post('/create_otp', tags=["OTP"])
12
+ async def create_otp(request: RequestOTP.RequestCreateOTP):
13
+ email = request.email
14
+ check = support_function.check_value_email_controller(email)
15
+ if check is not True:
16
+ return check
17
+ return OTPService.createOTP(request)
18
+
19
+ @router.post('/verify_otp', tags=["OTP"])
20
+ async def verify_otp(request: RequestOTP.RequestVerifyOTP):
21
+ check = support_function.check_value_email_controller(request.email)
22
+ if check is not True:
23
+ return check
24
+ check_otp = support_function.check_value_otp(request.otp)
25
+ if check_otp is not True:
26
+ return check_otp
27
+ return OTPService.verifyOTP(request)
28
+
29
+ @router.post('/verify_otp_reset_password', tags=["OTP"])
30
+ async def verify_otp_reset(request: RequestOTP.RequestVerifyOTP):
31
+ check = support_function.check_value_email_controller(request.email)
32
+ if check is not True:
33
+ return check
34
+ check_otp = support_function.check_value_otp(request.otp)
35
+ if check_otp is not True:
36
+ return check_otp
37
+ return OTPService.verifyOTPReset(request)
controller/__pycache__/ChatController.cpython-310.pyc ADDED
Binary file (1.5 kB). View file
 
controller/__pycache__/ChatController.cpython-311.pyc ADDED
Binary file (2.63 kB). View file
 
controller/__pycache__/ChatController.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Form, Request
2
+ from service import ChatService
3
+ from request import RequestChat
4
+ from typing import Optional
5
+ from fastapi.requests import Request
6
+ from function import support_function
7
+ from response import ResponseChat as res
8
+ router = APIRouter()
9
+
10
+ @router.post("/chatbot/query/", tags=["Chat"])
11
+ async def handle_query2_upgrade_old(request: Request,
12
+ user_id: str = Form(None),
13
+ text_all: str = Form(...), question: Optional[str] = Form(None),
14
+ chat_name: Optional[str] = Form(None)):
15
+ check = support_function.check_value_user_id_controller(user_id)
16
+ if check is not True:
17
+ return check
18
+ request = RequestChat.RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name)
19
+ return ChatService.query2_upgrade_old(request)
20
+
21
+ @router.get("/chatbot/extract_file/", tags=["Chat"])
22
+ async def extract_file(user_id: str):
23
+ check = support_function.check_value_user_id_controller(user_id)
24
+ if check is not True:
25
+ return check
26
+ request = RequestChat.RequestExtractFile(user_id=user_id)
27
+ return ChatService.extract_file(request)
28
+
29
+ @router.get("/chatbot/generate_question/",tags=["Chat"])
30
+ async def generate_question(user_id: str):
31
+ check = support_function.check_value_user_id_controller(user_id)
32
+ if check is not True:
33
+ return check
34
+ request = RequestChat.RequestGenerateQuestion(user_id=user_id)
35
+ return ChatService.generate_question(request)
controller/__pycache__/DefaultController.cpython-310.pyc ADDED
Binary file (2.73 kB). View file
 
controller/__pycache__/DefaultController.cpython-311.pyc ADDED
Binary file (4.91 kB). View file
 
controller/__pycache__/FileController.cpython-310.pyc ADDED
Binary file (2.67 kB). View file
 
controller/__pycache__/FileController.cpython-311.pyc ADDED
Binary file (4.8 kB). View file
 
controller/__pycache__/LoginController.cpython-310.pyc ADDED
Binary file (4.75 kB). View file
 
controller/__pycache__/LoginController.cpython-311.pyc ADDED
Binary file (9.92 kB). View file
 
controller/__pycache__/MySQLController.cpython-310.pyc ADDED
Binary file (2.6 kB). View file
 
controller/__pycache__/MySQLController.cpython-311.pyc ADDED
Binary file (5.35 kB). View file
 
controller/__pycache__/OTPController.cpython-310.pyc ADDED
Binary file (1.33 kB). View file
 
controller/__pycache__/OTPController.cpython-311.pyc ADDED
Binary file (2.4 kB). View file
 
entity/Database_Entity.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Column, String, Text, DateTime, Integer, ForeignKey, TIMESTAMP
2
+ from sqlalchemy.orm import relationship
3
+ from sqlalchemy.orm import DeclarativeBase
4
+ from sqlalchemy.sql import func
5
+ class Base(DeclarativeBase):
6
+ pass
7
+
8
+ class User(Base):
9
+ __tablename__ = 'users'
10
+ id = Column(Integer, primary_key=True, autoincrement=True)
11
+ email = Column(String(255))
12
+ access_token = Column(Text)
13
+ refresh_token = Column(Text)
14
+ expires_at = Column(DateTime)
15
+
16
+ chat_histories = relationship("ChatHistory", back_populates="user")
17
+ user_logins = relationship("UserLogin", back_populates="user")
18
+ user_infos = relationship("UserInfo", back_populates="user")
19
+
20
+ class ChatHistory(Base):
21
+ __tablename__ = 'chat_history'
22
+
23
+ id = Column(Integer, primary_key=True,autoincrement=True)
24
+ email = Column(String(255), ForeignKey('users.email'))
25
+ name_chat = Column(String(255), unique=True)
26
+
27
+ user = relationship("User", back_populates="chat_histories")
28
+ detail_chats = relationship("DetailChat", back_populates="chat_history")
29
+
30
+ class UserLogin(Base):
31
+ __tablename__ = 'user_login'
32
+
33
+ id = Column(Integer, primary_key=True,autoincrement=True)
34
+ user_email = Column(String(100), ForeignKey('users.email'), primary_key=True)
35
+ user_session_id = Column(String(100), primary_key=True)
36
+
37
+ user = relationship("User", back_populates="user_logins")
38
+
39
+ class UserInfo(Base):
40
+ __tablename__ = 'user_info'
41
+
42
+ id = Column(Integer, primary_key=True, autoincrement=True)
43
+ uid = Column(Text)
44
+ email = Column(String(255), ForeignKey('users.email'), unique=True)
45
+ display_name = Column(Text)
46
+ photo_url = Column(Text)
47
+
48
+ user = relationship("User", back_populates="user_infos")
49
+
50
+ class DetailChat(Base):
51
+ __tablename__ = 'detail_chat'
52
+
53
+ id = Column(Integer, primary_key=True, autoincrement=True)
54
+ chat_id = Column(Integer, ForeignKey('chat_history.id'))
55
+ YouMessage = Column(Text)
56
+ AiMessage = Column(Text)
57
+ data_relevant = Column(Text)
58
+ source_file = Column(Text)
59
+
60
+ chat_history = relationship("ChatHistory", back_populates="detail_chats")
61
+
62
+ class OTP(Base):
63
+ __tablename__ = 'otp'
64
+
65
+ id = Column(Integer, primary_key=True, autoincrement=True)
66
+ email = Column(String(255), nullable=False)
67
+ otp = Column(String(6), nullable=False)
68
+ created_at = Column(TIMESTAMP, server_default=func.now())
entity/__pycache__/Database_Entity.cpython-310.pyc ADDED
Binary file (2.8 kB). View file
 
entity/__pycache__/Database_Entity.cpython-311.pyc ADDED
Binary file (4.77 kB). View file
 
entity/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (168 Bytes). View file
 
function/__pycache__/chatbot.cpython-310.pyc ADDED
Binary file (22.5 kB). View file
 
function/__pycache__/chatbot.cpython-311.pyc ADDED
Binary file (42.3 kB). View file
 
function/__pycache__/dropbox.cpython-310.pyc ADDED
Binary file (6 kB). View file
 
function/__pycache__/dropbox.cpython-311.pyc ADDED
Binary file (12.4 kB). View file
 
function/__pycache__/support_function.cpython-310.pyc ADDED
Binary file (4.12 kB). View file
 
function/__pycache__/support_function.cpython-311.pyc ADDED
Binary file (7.76 kB). View file
 
function/chatbot.py ADDED
@@ -0,0 +1,685 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.text_splitter import CharacterTextSplitter
2
+ import json
3
+ import os
4
+ import random
5
+ import re
6
+ from concurrent.futures import ThreadPoolExecutor, as_completed
7
+ import google.generativeai as genai
8
+ import nltk
9
+ import pandas as pd
10
+ from groq import Groq
11
+ from langchain.chains.summarize import load_summarize_chain
12
+ from langchain.docstore.document import Document
13
+ from langchain.prompts import PromptTemplate
14
+ from langchain.retrievers import BM25Retriever, EnsembleRetriever
15
+ from langchain.retrievers.contextual_compression import ContextualCompressionRetriever
16
+ from langchain.text_splitter import CharacterTextSplitter
17
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
18
+ from langchain_cohere import CohereRerank
19
+ from langchain_community.document_loaders import Docx2txtLoader
20
+ from langchain_community.document_loaders import TextLoader
21
+ from langchain_community.document_loaders import UnstructuredCSVLoader
22
+ from langchain_community.document_loaders import UnstructuredExcelLoader
23
+ from langchain_community.document_loaders import UnstructuredHTMLLoader
24
+ from langchain_community.document_loaders import UnstructuredMarkdownLoader
25
+ from langchain_community.document_loaders import UnstructuredPDFLoader
26
+ from langchain_community.document_loaders import UnstructuredPowerPointLoader
27
+ from langchain_community.document_loaders import UnstructuredXMLLoader
28
+ from langchain_community.document_loaders.csv_loader import CSVLoader
29
+ from langchain_community.llms import Cohere
30
+ from langchain_community.vectorstores import Chroma
31
+ from langchain_core.output_parsers.openai_tools import PydanticToolsParser
32
+ from langchain_core.prompts import ChatPromptTemplate
33
+ from langchain_core.pydantic_v1 import BaseModel, Field
34
+ from langchain_core.runnables import RunnablePassthrough
35
+ from langchain_openai import ChatOpenAI
36
+ from typing import List
37
+ nltk.download('punkt')
38
+
39
+ def process_json_file(file_path):
40
+ json_data = []
41
+ with open(file_path, 'r') as file:
42
+ for line in file:
43
+ try:
44
+ data = json.loads(line)
45
+ json_data.append(data)
46
+ except json.JSONDecodeError:
47
+ try:
48
+ data = json.loads(line[:-1])
49
+ json_data.append(data)
50
+ except json.JSONDecodeError as e:
51
+ print(f"Error decoding JSON: {e}")
52
+ return json_data
53
+
54
+
55
+ from dotenv import load_dotenv
56
+ import os
57
+ load_dotenv()
58
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
59
+ COHERE_API_KEY = os.getenv("COHERE_API_KEY")
60
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
61
+ GOOGLE_API_KEY1= os.getenv("GOOGLE_API_KEY_1")
62
+ GOOGLE_API_KEY= os.getenv("GOOGLE_API_KEY")
63
+ os.environ["COHERE_API_KEY"] = COHERE_API_KEY
64
+ os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
65
+ client = Groq(
66
+ api_key= GROQ_API_KEY,
67
+ )
68
+ genai.configure(api_key=GOOGLE_API_KEY1)
69
+ os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
70
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
71
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
72
+ llm = ChatGoogleGenerativeAI(model='gemini-pro',
73
+ max_output_tokens=2048,
74
+ temperature=0.3,
75
+ convert_system_message_to_human=True)
76
+ def extract_multi_metadata_content(texts, tests):
77
+ extracted_content = []
78
+ precomputed_metadata = [x.metadata['source'].lower() for x in texts]
79
+ for idx, test in enumerate(tests):
80
+ temp_content = []
81
+ test_terms = set(test.lower().split()) # Use set for faster lookup
82
+ for metadata_lower, x in zip(precomputed_metadata, texts):
83
+ if any(term in metadata_lower for term in test_terms):
84
+ temp_content.append(x.page_content)
85
+ if idx == 0:
86
+ extracted_content.append(f"Dữ liệu của {test}:\n{''.join(temp_content)}")
87
+ else:
88
+ extracted_content.append(''.join(temp_content))
89
+ return '\n'.join(extracted_content)
90
+
91
+ def find_matching_files_in_docs_12_id(text, id):
92
+ folder_path = f"./user_file/{id}"
93
+ search_terms = []
94
+ search_terms_old = []
95
+ matching_index = []
96
+ search_origin = re.findall(r'\b\w+\.\w+\b|\b\w+\b', text)
97
+ search_terms_origin = []
98
+ for word in search_origin:
99
+ if '.' in word:
100
+ search_terms_origin.append(word)
101
+ else:
102
+ search_terms_origin.extend(re.findall(r'\b\w+\b', word))
103
+
104
+ file_names_with_extension = re.findall(r'\b\w+\.\w+\b|\b\w+\b', text.lower())
105
+ file_names_with_extension_old = re.findall(r'\b(\w+\.\w+)\b', text)
106
+ for file_name in search_terms_origin:
107
+ if "." in file_name:
108
+ term_position = search_terms_origin.index(file_name)
109
+ search_terms_old.append(file_name)
110
+ for file_name in file_names_with_extension_old:
111
+ if "." in file_name:
112
+ search_terms_old.append(file_name)
113
+ for file_name in file_names_with_extension:
114
+ search_terms.append(file_name)
115
+ clean_text_old = text
116
+ clean_text = text.lower()
117
+ search_terms_old1 = list(set(search_terms_old))
118
+ for term in search_terms_old:
119
+ clean_text_old = clean_text_old.replace(term, '')
120
+ for term in search_terms:
121
+ clean_text = clean_text.replace(term, '')
122
+ words_old = re.findall(r'\b\w+\b', clean_text_old)
123
+ search_terms_old.extend(words_old)
124
+ matching_files = set()
125
+ matching_files_old = set()
126
+ for root, dirs, files in os.walk(folder_path):
127
+ for file in files:
128
+ for term in search_terms:
129
+ if term.lower() in file.lower():
130
+ term_position = search_terms.index(term)
131
+ term_value = search_terms_origin[term_position]
132
+ matching_files.add(file)
133
+ matching_index.append(term_position)
134
+ break
135
+ matching_files_old1 = []
136
+ matching_index.sort()
137
+ for x in matching_index:
138
+ matching_files_old1.append(search_terms_origin[x])
139
+ return matching_files, matching_files_old1
140
+
141
+ def convert_xlsx_to_csv(xlsx_file_path, csv_file_path):
142
+ df = pd.read_excel(xlsx_file_path)
143
+ df.to_csv(csv_file_path, index=False)
144
+
145
+ def save_list_CSV_id(file_list, id):
146
+ text = ""
147
+ for x in file_list:
148
+ if x.endswith('.xlsx'):
149
+ old = f"./user_file/{id}/{x}"
150
+ new = old.replace(".xlsx", ".csv")
151
+ convert_xlsx_to_csv(old, new)
152
+ x = x.replace(".xlsx", ".csv")
153
+ loader1 = CSVLoader(f"./user_file/{id}/{x}")
154
+ docs1 = loader1.load()
155
+ text += f"Dữ liệu file {x}:\n"
156
+ for z in docs1:
157
+ text += z.page_content + "\n"
158
+ return text
159
+
160
+ def merge_files(file_set, file_list):
161
+ """Hàm này ghép lại các tên file dựa trên điều kiện đã cho."""
162
+ merged_files = {}
163
+ for file_name in file_list:
164
+ name = file_name.split('.')[0]
165
+ for f in file_set:
166
+ if name in f:
167
+ merged_files[name] = f
168
+ break
169
+ return merged_files
170
+
171
+ def replace_keys_with_values(original_dict, replacement_dict):
172
+ new_dict = {}
173
+ for key, value in original_dict.items():
174
+ if key in replacement_dict:
175
+ new_key = replacement_dict[key]
176
+ new_dict[new_key] = value
177
+ else:
178
+ new_dict[key] = value
179
+ return new_dict
180
+
181
+ def aws1_csv_id(new_dict_csv, id):
182
+ text = ""
183
+ query_all = ""
184
+ keyword = []
185
+ for key, value in new_dict_csv.items():
186
+ print(key, value)
187
+ query_all += value
188
+ keyword.append(key)
189
+ test = save_list_CSV_id(keyword, id)
190
+ text += test
191
+ sources = ",".join(keyword)
192
+ return text, query_all, sources
193
+
194
+ def chat_llama3(prompt_query):
195
+ try:
196
+ chat_completion = client.chat.completions.create(
197
+ messages=[
198
+ {
199
+ "role": "system",
200
+ "content": "Bạn là một trợ lý trung thưc, trả lời dựa trên nội dung tài liệu được cung cấp. Chỉ trả lời liên quan đến câu hỏi một cách đầy đủ chính xác, không bỏ sót thông tin."
201
+ },
202
+ {
203
+ "role": "user",
204
+ "content": f"{prompt_query}",
205
+ }
206
+ ],
207
+ model="llama3-70b-8192",
208
+ temperature=0.0,
209
+ max_tokens=9000,
210
+ stop=None,
211
+ stream=False,
212
+ )
213
+ return chat_completion.choices[0].message.content
214
+ except Exception as error:
215
+ return False
216
+
217
+ def chat_gemini(prompt):
218
+ generation_config = {
219
+ "temperature": 0.0,
220
+ "top_p": 0.0,
221
+ "top_k": 0,
222
+ "max_output_tokens": 8192,
223
+ }
224
+ safety_settings = [
225
+ {
226
+ "category": "HARM_CATEGORY_HARASSMENT",
227
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
228
+ },
229
+ {
230
+ "category": "HARM_CATEGORY_HATE_SPEECH",
231
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
232
+ },
233
+ {
234
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
235
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
236
+ },
237
+ {
238
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
239
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
240
+ },
241
+ ]
242
+ model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest",
243
+ generation_config=generation_config,
244
+ safety_settings=safety_settings)
245
+ convo = model.start_chat(history=[])
246
+ convo.send_message(prompt)
247
+ return convo.last.text
248
+
249
+ def question_answer(question):
250
+ completion = chat_llama3(question)
251
+ if completion:
252
+ return completion
253
+ else:
254
+ answer = chat_gemini(question)
255
+ return answer
256
+
257
+ def check_persist_directory(id, file_name):
258
+ directory_path = f"./vector_database/{id}/{file_name}"
259
+ return os.path.exists(directory_path)
260
+
261
+ from langchain_community.vectorstores import FAISS
262
+
263
+ def check_path_exists(path):
264
+ return os.path.exists(path)
265
+ def aws1_all_id(new_dict, text_alls, id, thread_id):
266
+ answer = ""
267
+ COHERE_API_KEY1 = os.getenv("COHERE_API_KEY_1")
268
+ os.environ["COHERE_API_KEY"] = COHERE_API_KEY1
269
+ answer_relevant = ""
270
+ directory = ""
271
+
272
+ for key, value in new_dict.items():
273
+ query = value
274
+ keyword, keyword2 = find_matching_files_in_docs_12_id(query, id)
275
+ data = extract_multi_metadata_content(text_alls, keyword)
276
+ if keyword:
277
+ file_name = next(iter(keyword))
278
+ text_splitter = CharacterTextSplitter(chunk_size=3200, chunk_overlap=1500)
279
+ texts_data = text_splitter.split_text(data)
280
+
281
+ if check_persist_directory(id, file_name):
282
+ vectordb_query = Chroma(persist_directory=f"./vector_database/{id}/{file_name}", embedding_function=embeddings)
283
+ else:
284
+ vectordb_query = Chroma.from_texts(texts_data,
285
+ embedding=embeddings,
286
+ persist_directory=f"./vector_database/{id}/{file_name}")
287
+
288
+ k_1 = len(texts_data)
289
+ retriever = vectordb_query.as_retriever(search_kwargs={f"k": k_1})
290
+ bm25_retriever = BM25Retriever.from_texts(texts_data)
291
+ bm25_retriever.k = k_1
292
+ ensemble_retriever = EnsembleRetriever(retrievers=[bm25_retriever, retriever],
293
+ weights=[0.6, 0.4])
294
+ docs = ensemble_retriever.get_relevant_documents(f"{query}")
295
+
296
+ path = f"./vector_database/FAISS/{id}/{file_name}"
297
+ if check_path_exists(path):
298
+ docsearch = FAISS.load_local(path, embeddings, allow_dangerous_deserialization=True)
299
+ else:
300
+ docsearch = FAISS.from_documents(docs, embeddings)
301
+ docsearch.save_local(f"./vector_database/FAISS/{id}/{file_name}")
302
+ docsearch = FAISS.load_local(path, embeddings, allow_dangerous_deserialization=True)
303
+
304
+ k_2 = len(docs)
305
+ compressor = CohereRerank(top_n=5)
306
+ retrieve3 = docsearch.as_retriever(search_kwargs={f"k": k_2})
307
+ compression_retriever = ContextualCompressionRetriever(
308
+ base_compressor=compressor, base_retriever=retrieve3
309
+ )
310
+ compressed_docs = compression_retriever.get_relevant_documents(f"{query}")
311
+
312
+ if compressed_docs:
313
+ data = compressed_docs[0].page_content
314
+ text = ''.join(map(lambda x: x.page_content, compressed_docs))
315
+ prompt_document = f"Dựa vào nội dung sau:{text}. Hãy trả lời câu hỏi sau đây: {query}. Mà không thay đổi nội dung mà mình đã cung cấp"
316
+ answer_for = question_answer(prompt_document)
317
+ answer += answer_for + "\n"
318
+ answer_relevant = data
319
+ directory = file_name
320
+
321
+ return answer, answer_relevant, directory
322
+
323
+ def extract_content_between_keywords(query, keywords):
324
+ contents = {}
325
+ num_keywords = len(keywords)
326
+ keyword_positions = []
327
+ for i in range(num_keywords):
328
+ keyword = keywords[i]
329
+ keyword_position = query.find(keyword)
330
+ keyword_positions.append(keyword_position)
331
+ if keyword_position == -1:
332
+ continue
333
+ next_keyword_position = len(query)
334
+ for j in range(i + 1, num_keywords):
335
+ next_keyword = keywords[j]
336
+ next_keyword_position = query.find(next_keyword)
337
+ if next_keyword_position != -1:
338
+ break
339
+ if i == 0:
340
+ content_before = query[:keyword_position].strip()
341
+ else:
342
+ content_before = query[keyword_positions[i - 1] + len(keywords[i - 1]):keyword_position].strip()
343
+ if i == num_keywords - 1:
344
+ content_after = query[keyword_position + len(keyword):].strip()
345
+ else:
346
+ content_after = query[keyword_position + len(keyword):next_keyword_position].strip()
347
+ content = f"{content_before} {keyword} {content_after}"
348
+ contents[keyword] = content
349
+ return contents
350
+
351
+ def generate_random_questions(filtered_ques_list):
352
+ if len(filtered_ques_list) >= 2:
353
+ random_questions = random.sample(filtered_ques_list, 2)
354
+ else:
355
+ random_questions = filtered_ques_list
356
+ return random_questions
357
+
358
+ def generate_question_main(loader, name_file):
359
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=4500, chunk_overlap=2500)
360
+ texts = text_splitter.split_documents(loader)
361
+ question_gen = f"nội dung {name_file} : \n"
362
+ question_gen += texts[0].page_content
363
+ splitter_ques_gen = RecursiveCharacterTextSplitter(
364
+ chunk_size=4500,
365
+ chunk_overlap=2200
366
+ )
367
+ chunks_ques_gen = splitter_ques_gen.split_text(question_gen)
368
+ document_ques_gen = [Document(page_content=t) for t in chunks_ques_gen]
369
+ llm_ques_gen_pipeline = llm
370
+ prompt_template_vn = """
371
+ Bạn là một chuyên gia tạo câu hỏi dựa trên tài liệu và tài liệu hướng dẫn.
372
+ Bạn làm điều này bằng cách đặt các câu hỏi về đoạn văn bản dưới đây:
373
+
374
+ ------------
375
+ {text}
376
+ ------------
377
+
378
+ Hãy tạo ra các câu hỏi từ đoạn văn bản này.Nếu đoạn văn là tiếng Việt hãy tạo câu hỏi tiếng Việt. Nếu đoạn văn là tiếng Anh hãy tạo câu hỏi tiếng Anh.
379
+ Hãy chắc chắn không bỏ sót bất kỳ thông tin quan trọng nào. Và chỉ tạo với đoạn tài liệu đó tối đa 5 câu hỏi liên quan tới tài liệu cung cấp nhất.Nếu trong đoạn tài liệu có các tên liên quan đến file như demo1.pdf( nhiều file khác) thì phải kèm nó vào nội dung câu hỏi bạn tạo ra.
380
+
381
+ CÁC CÂU HỎI:
382
+ """
383
+
384
+ PROMPT_QUESTIONS_VN = PromptTemplate(template=prompt_template_vn, input_variables=["text"])
385
+ refine_template_vn = ("""
386
+ Bạn là một chuyên gia tạo câu hỏi thực hành dựa trên tài liệu và tài liệu hướng dẫn.
387
+ Mục tiêu của bạn là giúp người học chuẩn bị cho một kỳ thi.
388
+ Chúng tôi đã nhận được một số câu hỏi thực hành ở mức độ nào đó: {existing_answer}.
389
+ Chúng tôi có thể tinh chỉnh các câu hỏi hiện có hoặc thêm câu hỏi mới
390
+ (chỉ khi cần thiết) với một số ngữ cảnh bổ sung dưới đây.
391
+ ------------
392
+ {text}
393
+ ------------
394
+
395
+ Dựa trên ngữ cảnh mới, hãy tinh chỉnh các câu hỏi bằng tiếng Việt nếu đoạn văn đó cung cấp tiếng Việt. Nếu không hãy tinh chỉnh câu hỏi bằng tiếng Anh nếu đoạn đó cung cấp tiếng Anh.
396
+ Nếu ngữ cảnh không hữu ích, vui lòng cung cấp các câu hỏi gốc. Và chỉ tạo với đoạn tài liệu đó tối đa 5 câu hỏi liên quan tới tài liệu cung cấp nhất. Nếu trong đoạn tài liệu có các tên file thì phải kèm nó vào câu hỏi.
397
+ CÁC CÂU HỎI:
398
+ """
399
+ )
400
+
401
+ REFINE_PROMPT_QUESTIONS = PromptTemplate(
402
+ input_variables=["existing_answer", "text"],
403
+ template=refine_template_vn,
404
+ )
405
+ ques_gen_chain = load_summarize_chain(llm=llm_ques_gen_pipeline,
406
+ chain_type="refine",
407
+ verbose=True,
408
+ question_prompt=PROMPT_QUESTIONS_VN,
409
+ refine_prompt=REFINE_PROMPT_QUESTIONS)
410
+ ques = ques_gen_chain.run(document_ques_gen)
411
+ ques_list = ques.split("\n")
412
+ filtered_ques_list = ["{}: {}".format(name_file, re.sub(r'^\d+\.\s*', '', element)) for element in ques_list if
413
+ element.endswith('?') or element.endswith('.')]
414
+ return generate_random_questions(filtered_ques_list)
415
+
416
+ def load_file(loader):
417
+ return loader.load()
418
+
419
+ def extract_data2(id):
420
+ documents = []
421
+ directory_path = f"./user_file/{id}"
422
+ if not os.path.exists(directory_path) or not any(
423
+ os.path.isfile(os.path.join(directory_path, f)) for f in os.listdir(directory_path)):
424
+ return False
425
+ tasks = []
426
+ with ThreadPoolExecutor() as executor:
427
+ for file in os.listdir(directory_path):
428
+ if file.endswith(".pdf"):
429
+ pdf_path = os.path.join(directory_path, file)
430
+ loader = UnstructuredPDFLoader(pdf_path)
431
+ tasks.append(executor.submit(load_file, loader))
432
+ elif file.endswith('.docx') or file.endswith('.doc'):
433
+ doc_path = os.path.join(directory_path, file)
434
+ loader = Docx2txtLoader(doc_path)
435
+ tasks.append(executor.submit(load_file, loader))
436
+ elif file.endswith('.txt'):
437
+ txt_path = os.path.join(directory_path, file)
438
+ loader = TextLoader(txt_path, encoding="utf8")
439
+ tasks.append(executor.submit(load_file, loader))
440
+ elif file.endswith('.pptx'):
441
+ ppt_path = os.path.join(directory_path, file)
442
+ loader = UnstructuredPowerPointLoader(ppt_path)
443
+ tasks.append(executor.submit(load_file, loader))
444
+ elif file.endswith('.csv'):
445
+ csv_path = os.path.join(directory_path, file)
446
+ loader = UnstructuredCSVLoader(csv_path)
447
+ tasks.append(executor.submit(load_file, loader))
448
+ elif file.endswith('.xlsx'):
449
+ excel_path = os.path.join(directory_path, file)
450
+ loader = UnstructuredExcelLoader(excel_path)
451
+ tasks.append(executor.submit(load_file, loader))
452
+ elif file.endswith('.json'):
453
+ json_path = os.path.join(directory_path, file)
454
+ loader = TextLoader(json_path)
455
+ tasks.append(executor.submit(load_file, loader))
456
+ elif file.endswith('.md'):
457
+ md_path = os.path.join(directory_path, file)
458
+ loader = UnstructuredMarkdownLoader(md_path)
459
+ tasks.append(executor.submit(load_file, loader))
460
+ for future in as_completed(tasks):
461
+ result = future.result()
462
+ documents.extend(result)
463
+ text_splitter = CharacterTextSplitter(chunk_size=4500, chunk_overlap=2500)
464
+ texts = text_splitter.split_documents(documents)
465
+ Chroma.from_documents(documents=texts,
466
+ embedding=embeddings,
467
+ persist_directory=f"./vector_database/{id}")
468
+ return texts
469
+
470
+ def generate_question(id):
471
+ directory_path = f"./user_file/{id}"
472
+ if not os.path.exists(directory_path) or not any(
473
+ os.path.isfile(os.path.join(directory_path, f)) for f in os.listdir(directory_path)):
474
+ return False
475
+ all_questions = []
476
+ tasks = []
477
+ with ThreadPoolExecutor() as executor:
478
+ for file in os.listdir(directory_path):
479
+ if file.endswith(".pdf"):
480
+ pdf_path = os.path.join(directory_path, file)
481
+ loader = UnstructuredPDFLoader(pdf_path).load()
482
+ tasks.append(executor.submit(generate_question_main, loader, file))
483
+ elif file.endswith('.docx') or file.endswith('.doc'):
484
+ doc_path = os.path.join(directory_path, file)
485
+ loader = Docx2txtLoader(doc_path).load()
486
+ tasks.append(executor.submit(generate_question_main, loader, file))
487
+ elif file.endswith('.txt'):
488
+ txt_path = os.path.join(directory_path, file)
489
+ loader = TextLoader(txt_path, encoding="utf8").load()
490
+ tasks.append(executor.submit(generate_question_main, loader, file))
491
+ elif file.endswith('.pptx'):
492
+ ppt_path = os.path.join(directory_path, file)
493
+ loader = UnstructuredPowerPointLoader(ppt_path).load()
494
+ tasks.append(executor.submit(generate_question_main, loader, file))
495
+ elif file.endswith('.json'):
496
+ json_path = os.path.join(directory_path, file)
497
+ loader = TextLoader(json_path, encoding="utf8").load()
498
+ tasks.append(executor.submit(generate_question_main, loader, file))
499
+ elif file.endswith('.md'):
500
+ md_path = os.path.join(directory_path, file)
501
+ loader = UnstructuredMarkdownLoader(md_path).load()
502
+ tasks.append(executor.submit(generate_question_main, loader, file))
503
+ for future in as_completed(tasks):
504
+ result = future.result()
505
+ all_questions.extend(result)
506
+ return all_questions
507
+
508
+ class Search(BaseModel):
509
+ queries: List[str] = Field(
510
+ ...,
511
+ description="Truy vấn riêng biệt để tìm kiếm, giữ nguyên ý chính câu hỏi riêng biệt",
512
+ )
513
+
514
+ def query_analyzer(query):
515
+ output_parser = PydanticToolsParser(tools=[Search])
516
+ system = """Bạn có khả năng đưa ra các truy vấn tìm kiếm chính xác để lấy thông tin giúp trả lời các yêu cầu của người dùng. Các truy vấn của bạn phải chính xác, không được bỏ ngắn rút gọn.
517
+ Nếu bạn cần tra cứu hai hoặc nhiều thông tin riêng biệt, bạn có thể làm điều đó!. Trả lời câu hỏi bằng tiếng Việt(Vietnamese), không được dùng ngôn ngữ khác"""
518
+ prompt = ChatPromptTemplate.from_messages(
519
+ [
520
+ ("system", system),
521
+ ("human", "{question}"),
522
+ ]
523
+ )
524
+ llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0.0)
525
+ structured_llm = llm.with_structured_output(Search)
526
+ query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm
527
+ text = query_analyzer.invoke(query)
528
+ return text
529
+
530
+ def handle_query(question, text_all, compression_retriever, id, thread_id):
531
+ COHERE_API_KEY_3 = os.environ["COHERE_API_KEY_3"]
532
+ os.environ["COHERE_API_KEY"] = COHERE_API_KEY_3
533
+ query = question
534
+ x = query
535
+ keyword, key_words_old = find_matching_files_in_docs_12_id(query, id)
536
+ # if keyword == set() or key_words_old == list():
537
+ # return "Not found file"
538
+ file_list = keyword
539
+
540
+ if file_list:
541
+ list_keywords2 = list(key_words_old)
542
+ contents1 = extract_content_between_keywords(query, list_keywords2)
543
+ merged_result = merge_files(keyword, list_keywords2)
544
+ original_dict = contents1
545
+ replacement_dict = merged_result
546
+ new_dict = replace_keys_with_values(original_dict, replacement_dict)
547
+ files_to_remove = [filename for filename in new_dict.keys() if
548
+ filename.endswith('.xlsx') or filename.endswith('.csv')]
549
+ removed_files = {}
550
+ for filename in files_to_remove:
551
+ removed_files[filename] = new_dict[filename]
552
+ for filename in files_to_remove:
553
+ new_dict.pop(filename)
554
+ test_csv = ""
555
+ text_csv, query_csv, source = aws1_csv_id(removed_files, id)
556
+ prompt_csv = ""
557
+ answer_csv = ""
558
+ if test_csv:
559
+ prompt_csv = f"Dựa vào nội dung sau: {text_csv}. Hãy trả lời câu hỏi sau đây: {query_csv}.Bằng tiếng Việt"
560
+ answer_csv = question_answer(prompt_csv)
561
+ answer_document, data_relevant, source = aws1_all_id(new_dict, text_all, id, thread_id)
562
+ answer_all1 = answer_document + answer_csv
563
+ return answer_all1, data_relevant, source
564
+ else:
565
+ compressed_docs = compression_retriever.get_relevant_documents(f"{query}")
566
+ relevance_score_float = float(compressed_docs[0].metadata['relevance_score'])
567
+ print(relevance_score_float)
568
+ if relevance_score_float <= 0.15:
569
+ documents1 = []
570
+ for file in os.listdir(f"./user_file/{id}"):
571
+ if file.endswith('.csv'):
572
+ csv_path = f"./user_file/{id}/" + file
573
+ loader = UnstructuredCSVLoader(csv_path)
574
+ documents1.extend(loader.load())
575
+ elif file.endswith('.xlsx'):
576
+ excel_path = f"./user_file/{id}/" + file
577
+ loader = UnstructuredExcelLoader(excel_path)
578
+ documents1.extend(loader.load())
579
+ text_splitter_csv = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=2200, chunk_overlap=1500)
580
+ texts_csv = text_splitter_csv.split_documents(documents1)
581
+ vectordb_csv = Chroma.from_documents(documents=texts_csv,
582
+ embedding=embeddings, persist_directory=f'./vector_database/csv/{thread_id}')
583
+ k = len(texts_csv)
584
+ retriever_csv = vectordb_csv.as_retriever(search_kwargs={"k": k})
585
+ llm = Cohere(temperature=0)
586
+ compressor_csv = CohereRerank(top_n=3, model="rerank-english-v2.0")
587
+ compression_retriever_csv = ContextualCompressionRetriever(
588
+ base_compressor=compressor_csv, base_retriever=retriever_csv
589
+ )
590
+ compressed_docs_csv = compression_retriever_csv.get_relevant_documents(f"{query}")
591
+ file_path = compressed_docs_csv[0].metadata['source']
592
+ print(file_path)
593
+ if file_path.endswith('.xlsx'):
594
+ new = file_path.replace(".xlsx", ".csv")
595
+ convert_xlsx_to_csv(file_path, new)
596
+ loader1 = CSVLoader(new)
597
+ else:
598
+ loader1 = CSVLoader(file_path)
599
+ docs1 = loader1.load()
600
+ text = " "
601
+ for z in docs1:
602
+ text += z.page_content + "\n"
603
+ prompt_csv = f"Dựa vào nội dung sau: {text}. Hãy trả lời câu hỏi sau đây: {query}. Bằng tiếng Việt"
604
+ answer_csv = question_answer(prompt_csv)
605
+ return answer_csv
606
+ else:
607
+ file_path = compressed_docs[0].metadata['source']
608
+ file_path = file_path.replace('\\', '/')
609
+ print(file_path)
610
+ if file_path.endswith(".pdf"):
611
+ loader = UnstructuredPDFLoader(file_path)
612
+ elif file_path.endswith('.docx') or file_path.endswith('doc'):
613
+ loader = Docx2txtLoader(file_path)
614
+ elif file_path.endswith('.txt'):
615
+ loader = TextLoader(file_path, encoding="utf8")
616
+ elif file_path.endswith('.pptx'):
617
+ loader = UnstructuredPowerPointLoader(file_path)
618
+ elif file_path.endswith('.xml'):
619
+ loader = UnstructuredXMLLoader(file_path)
620
+ elif file_path.endswith('.html'):
621
+ loader = UnstructuredHTMLLoader(file_path)
622
+ elif file_path.endswith('.json'):
623
+ loader = TextLoader(file_path)
624
+ elif file_path.endswith('.md'):
625
+ loader = UnstructuredMarkdownLoader(file_path)
626
+ elif file_path.endswith('.xlsx'):
627
+ file_path_new = file_path.replace(".xlsx", ".csv")
628
+ convert_xlsx_to_csv(file_path, file_path_new)
629
+ loader = CSVLoader(file_path_new)
630
+ elif file_path.endswith('.csv'):
631
+ loader = CSVLoader(file_path)
632
+ text_splitter = CharacterTextSplitter(chunk_size=3200, chunk_overlap=1500)
633
+ texts = text_splitter.split_documents(loader.load())
634
+ k_1 = len(texts)
635
+ file_name = os.path.basename(file_path)
636
+ if check_persist_directory(id, file_name):
637
+ vectordb_file = Chroma(persist_directory=f"./vector_database/{id}/{file_name}",
638
+ embedding_function=embeddings)
639
+ else:
640
+ vectordb_file = Chroma.from_documents(texts,
641
+ embedding=embeddings,
642
+ persist_directory=f"./vector_database/{id}/{file_name}")
643
+ retriever_file = vectordb_file.as_retriever(search_kwargs={f"k": k_1})
644
+ compressor_file = CohereRerank(top_n=5, model="rerank-english-v2.0")
645
+ compression_retriever_file = ContextualCompressionRetriever(
646
+ base_compressor=compressor_file, base_retriever=retriever_file
647
+ )
648
+ compressed_docs_file = compression_retriever_file.get_relevant_documents(f"{x}")
649
+ query = question
650
+ text = ''.join(map(lambda x: x.page_content, compressed_docs_file))
651
+ prompt = f"Dựa vào nội dung sau:{text}. Hãy trả lời câu hỏi sau đây: {query}. Mà không thay đổi, chỉnh sửa nội dung mà mình đã cung cấp"
652
+ answer = question_answer(prompt)
653
+ list_relevant = compressed_docs_file[0].page_content
654
+ source = file_name
655
+ return answer, list_relevant, source
656
+
657
+ def handle_query_upgrade_keyword_old(query_all, text_all, id):
658
+ COHERE_API_KEY_2 = os.environ["COHERE_API_KEY_2"]
659
+ os.environ["COHERE_API_KEY"] = COHERE_API_KEY_2
660
+ test = query_analyzer(query_all)
661
+ test_string = str(test)
662
+ matches = re.findall(r"'([^']*)'", test_string)
663
+ vectordb = Chroma(persist_directory=f"./vector_database/{id}", embedding_function=embeddings)
664
+ k = len(text_all)
665
+ retriever = vectordb.as_retriever(search_kwargs={"k": k})
666
+ compressor = CohereRerank(top_n=5, model="rerank-english-v2.0")
667
+ compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever= retriever)
668
+ with ThreadPoolExecutor() as executor:
669
+ futures = {executor.submit(handle_query, query, text_all, compression_retriever, id, i): query for i, query in
670
+ enumerate(matches)}
671
+ results = []
672
+ data_relevant = []
673
+ sources = []
674
+ for future in as_completed(futures):
675
+ try:
676
+ result, list_data, list_source = future.result()
677
+ results.append(result)
678
+ data_relevant.append(list_data)
679
+ sources.append(list_source)
680
+ except Exception as e:
681
+ print(f'An error occurred: {e}')
682
+ answer_all = ''.join(results)
683
+ prompt1 = f"Dựa vào nội dung sau:{answer_all}. Hãy trả lời câu hỏi sau đây: {query_all}. Mà không thay đổi, chỉnh sửa nội dung mà mình đã cung cấp"
684
+ answer1 = question_answer(prompt1)
685
+ return answer1, data_relevant, sources
function/dropbox.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import dropbox.files
2
+ import os
3
+ import shutil
4
+ import requests, base64
5
+ from fastapi import HTTPException
6
+ from dotenv import load_dotenv
7
+ import os
8
+ load_dotenv()
9
+ DROPBOX_APP_KEY=os.getenv('DROPBOX_APP_KEY')
10
+ DROPBOX_APP_SECRET=os.getenv('DROPBOX_APP_SECRET')
11
+ DROPBOX_REFRESH_TOKEN=os.getenv('DROPBOX_REFRESH_TOKEN')
12
+
13
+ def refresh_token_dropbox():
14
+ app_key = DROPBOX_APP_KEY
15
+ app_secret = DROPBOX_APP_SECRET
16
+ refresh_token = DROPBOX_REFRESH_TOKEN
17
+ url = 'https://api.dropbox.com/oauth2/token'
18
+ auth_string = f"{app_key}:{app_secret}"
19
+ base64authorization = base64.b64encode(auth_string.encode()).decode('utf-8')
20
+ headers = {
21
+ 'Authorization': f'Basic {base64authorization}',
22
+ 'Content-Type': 'application/x-www-form-urlencoded'
23
+ }
24
+ data = {
25
+ 'refresh_token': refresh_token,
26
+ 'grant_type': 'refresh_token'
27
+ }
28
+ response = requests.post(url, headers=headers, data=data)
29
+ response_json = response.json()
30
+ access_token = response_json.get('access_token', None)
31
+ return access_token
32
+
33
+ def delete_file(id,name_file):
34
+ try:
35
+ TOKEN = refresh_token_dropbox()
36
+ dbx=dropbox.Dropbox(TOKEN)
37
+ file_path = f"/{id}/{name_file}"
38
+ dbx.files_delete_v2(file_path)
39
+ print(f"Xóa file '{file_path}' thành công.")
40
+ except dropbox.exceptions.ApiError as e:
41
+ print(f"Lỗi khi xóa file '{file_path}': {e}")
42
+
43
+ def list_files(id):
44
+ file_names = []
45
+ try:
46
+ TOKEN = refresh_token_dropbox()
47
+ dbx=dropbox.Dropbox(TOKEN)
48
+ result = dbx.files_list_folder(f"/{id}")
49
+ for entry in result.entries:
50
+ if isinstance(entry, dropbox.files.FileMetadata):
51
+ file_names.append(os.path.basename(entry.path_display))
52
+ except dropbox.exceptions.ApiError as e:
53
+ print(f"Error listing files: {e}")
54
+ return file_names
55
+
56
+ def upload_file_fix(local_path,cloud_path,token):
57
+ try:
58
+ TOKEN = refresh_token_dropbox()
59
+ dbx=dropbox.Dropbox(TOKEN)
60
+ with open(local_path, "rb") as f:
61
+ data = f.read()
62
+ dbx.files_upload(data, cloud_path)
63
+ print(f"Uploaded file '{local_path}' to '{cloud_path}'")
64
+ except dropbox.exceptions.ApiError as e:
65
+ print(f"Error uploading file '{local_path}': {e}")
66
+
67
+ def upload_file(local_path, cloud_path):
68
+ try:
69
+ TOKEN = refresh_token_dropbox()
70
+ dbx=dropbox.Dropbox(TOKEN)
71
+ with open(local_path, "rb") as f:
72
+ data = f.read()
73
+ dbx.files_upload(data, cloud_path)
74
+ print(f"Uploaded file '{local_path}' to '{cloud_path}'")
75
+ except dropbox.exceptions.ApiError as e:
76
+ upload_file_fix()
77
+
78
+ def clear_local_folder(path):
79
+ try:
80
+ for filename in os.listdir(path):
81
+ file_path = os.path.join(path, filename)
82
+ if os.path.isfile(file_path) or os.path.islink(file_path):
83
+ os.unlink(file_path)
84
+ elif os.path.isdir(file_path):
85
+ shutil.rmtree(file_path)
86
+ except Exception as e:
87
+ print(f"Failed to delete contents of {path}. Reason: {e}")
88
+
89
+ def download_folder(id):
90
+ try:
91
+ TOKEN = refresh_token_dropbox()
92
+ dbx = dropbox.Dropbox(TOKEN)
93
+ local_path = f"./user_file/{id}"
94
+ os.makedirs(local_path, exist_ok=True)
95
+ clear_local_folder(local_path)
96
+ result = dbx.files_list_folder(f"/{id}")
97
+ for entry in result.entries:
98
+ if isinstance(entry, dropbox.files.FileMetadata):
99
+ cloud_file_path = entry.path_display
100
+ file_name = os.path.basename(cloud_file_path)
101
+ local_file_path = os.path.join(local_path, file_name)
102
+ dbx.files_download_to_file(local_file_path, cloud_file_path)
103
+ print(f"Downloaded file '{file_name}' to '{local_file_path}'")
104
+ except dropbox.exceptions.ApiError as e:
105
+ print(f"Error downloading file '{id}': {e}")
106
+
107
+ def download_file_id(file_name, id):
108
+ try:
109
+ TOKEN = refresh_token_dropbox()
110
+ dbx = dropbox.Dropbox(TOKEN)
111
+ local_folder_path = f"./user_file/{id}"
112
+ os.makedirs(local_folder_path, exist_ok=True)
113
+ local_file_path = os.path.join(local_folder_path, file_name)
114
+ with open(local_file_path, "wb") as f:
115
+ metadata, response = dbx.files_download(f"/{id}/{file_name}")
116
+ f.write(response.content)
117
+ print(f"Downloaded file '{file_name}' to '{local_file_path}'")
118
+ except dropbox.exceptions.ApiError as e:
119
+ print(f"Error downloading file '{file_name}': {e}")
120
+ raise HTTPException(status_code=500, detail="Internal Server Error")
121
+
122
+ def search_and_download_file(start_char, id):
123
+ try:
124
+ TOKEN = refresh_token_dropbox()
125
+ dbx = dropbox.Dropbox(TOKEN)
126
+ result = dbx.files_list_folder(f"/{id}")
127
+ files_starting_with_char = [entry.name for entry in result.entries if entry.name.startswith(start_char)]
128
+ if len(files_starting_with_char) == 0:
129
+ print(f"No file found starting with '{start_char}' in folder '{id}'")
130
+ return
131
+ file_name = files_starting_with_char[0]
132
+ local_folder_path = f"./user_file/{id}"
133
+ os.makedirs(local_folder_path, exist_ok=True)
134
+ local_file_path = os.path.join(local_folder_path, file_name)
135
+ with open(local_file_path, "wb") as f:
136
+ metadata, response = dbx.files_download(f"/{id}/{file_name}")
137
+ f.write(response.content)
138
+ print(f"Downloaded file '{file_name}' to '{local_file_path}'")
139
+ except dropbox.exceptions.ApiError as e:
140
+ print(f"Error searching or downloading file: {e}")
141
+ raise HTTPException(status_code=500, detail="Internal Server Error")
142
+
143
+ def delete_all_files_in_folder(folder_id):
144
+ try:
145
+ TOKEN = refresh_token_dropbox()
146
+ dbx = dropbox.Dropbox(TOKEN)
147
+ result = dbx.files_list_folder(f"/{folder_id}")
148
+ for entry in result.entries:
149
+ if isinstance(entry, dropbox.files.FileMetadata):
150
+ file_path = entry.path_display
151
+ dbx.files_delete_v2(file_path)
152
+ print(f"Deleted file '{file_path}'")
153
+ print(f"All files in folder '{folder_id}' have been deleted.")
154
+ except dropbox.exceptions.ApiError as e:
155
+ print(f"Error deleting files: {e}")
function/support_function.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic.error_wrappers import ErrorWrapper
2
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
3
+ from service import MySQLService,LoginService,ChatService
4
+ from request import RequestMySQL,RequestLogin,RequestDefault
5
+ from auth.authentication import decodeJWT
6
+ from repository import UserRepository
7
+ from auth import authentication
8
+ from datetime import datetime, timedelta
9
+ from fastapi import Depends, HTTPException, Form, File, UploadFile
10
+ from typing import List
11
+ from service import FileService,DefaultService,LoginService
12
+ from request import RequestFile,RequestChat,RequestDefault
13
+ from fastapi import FastAPI, Request, HTTPException
14
+ from fastapi.responses import JSONResponse
15
+ from pydantic.error_wrappers import ErrorWrapper
16
+ import json
17
+ from function import support_function
18
+ from repository import UserRepository
19
+ from response import ResponseDefault as res
20
+ import re
21
+
22
+ def is_positive_integer(value):
23
+ if isinstance(value, int) and value > 0:
24
+ return True
25
+ else:
26
+ return False
27
+
28
+ def check_value_user_id_controller(user_id: str):
29
+ if user_id is None or user_id.strip() == "":
30
+ return res.ReponseError(status=400,
31
+ data=res.Message(message="user_id field is required."))
32
+ user_id = user_id.strip("'").strip('"')
33
+ try:
34
+ user_id_int = int(user_id)
35
+ except ValueError:
36
+ return res.ReponseError(status=400,
37
+ data=res.Message(message="user_id must be an integer"))
38
+
39
+ if not support_function.is_positive_integer(user_id_int):
40
+ return res.ReponseError(status=400,
41
+ data=res.Message(message="user_id must be greater than 0"))
42
+ return True
43
+
44
+ def check_value_user_id(user_id: str, current_user_email: str):
45
+ if user_id is None or user_id.strip() == "":
46
+ return res.ReponseError(status=400,
47
+ data=res.Message(message="user_id field is required."))
48
+ user_id = user_id.strip("'").strip('"')
49
+ try:
50
+ user_id_int = int(user_id)
51
+ except ValueError:
52
+ return res.ReponseError(status=400,
53
+ data=res.Message(message="user_id must be an integer"))
54
+
55
+ if not support_function.is_positive_integer(user_id_int):
56
+ return res.ReponseError(status=400,
57
+ data=res.Message(message="user_id must be greater than 0"))
58
+ email = UserRepository.getEmailUserByIdFix(user_id)
59
+ if email is None:
60
+ return res.ReponseError(status=400,
61
+ data=res.Message(message="user_id not exist"))
62
+ email = email[0]
63
+ if email != current_user_email:
64
+ return res.ReponseError(status=400,
65
+ data=res.Message(message="Sorry, you can't perform actions with this user id."))
66
+ return True
67
+
68
+ def check_value_email_controller(email: str):
69
+ if email is None or email.strip() == "":
70
+ return res.ReponseError(status = 400,
71
+ data = res.Message(message="Email is required."))
72
+ try:
73
+ int(email)
74
+ return res.ReponseError(status=400,
75
+ data=res.Message(message="Email must be a string, not a number."))
76
+ except ValueError:
77
+ pass
78
+ return True
79
+
80
+ def check_value_otp(otp: str):
81
+ if otp is None:
82
+ return res.ReponseError(status=400,
83
+ data=res.Message(message="OTP is required"))
84
+ if otp.isdigit():
85
+ return res.ReponseError(status=400,
86
+ data=res.Message(message="OTP must be a string, not a number."))
87
+ if len(otp) != 6:
88
+ return res.ReponseError(status=400,
89
+ data=res.Message(message="OTP max length is 6"))
90
+ return True
91
+
92
+ regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
93
+ def check_email(email):
94
+ if(re.fullmatch(regex, email)):
95
+ return True
96
+ else:
97
+ return False
98
+ def check_email_service(user_id: str):
99
+ email1 = UserRepository.getEmailUserByIdFix(user_id)
100
+ if email1 is None:
101
+ return res.ReponseError(
102
+ status=400,
103
+ data=res.Message(message="Id not exist")
104
+ )
105
+ email = email1[0]
106
+ if email is None:
107
+ return res.ReponseError(
108
+ status=400,
109
+ data=res.Message(message="Email is empty")
110
+ )
111
+ if check_email(email) == False:
112
+ return res.ReponseError(
113
+ status=400,
114
+ data=res.Message(message="Email invalid")
115
+ )
116
+ return email
117
+
118
+ def check_email_empty_invalid(email: str):
119
+ if email is None or email == "":
120
+ return res.ReponseError(
121
+ status=400,
122
+ data=res.Message(message="Email is empty")
123
+ )
124
+ if check_email(email) == False:
125
+ return res.ReponseError(
126
+ status=400,
127
+ data =res.Message(message="Email invalid")
128
+ )
129
+ return True
repository/ChatHistoryRepository.py ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.orm import sessionmaker
2
+ import sys
3
+ import os
4
+ app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
5
+ sys.path.insert(0, app_path)
6
+ from entity import Database_Entity
7
+ from repository import ConfigDatabase as cf
8
+ chat_history = Database_Entity.ChatHistory
9
+ users = Database_Entity.User
10
+ detail_chat = Database_Entity.DetailChat
11
+ from sqlalchemy.orm import sessionmaker
12
+ from functools import lru_cache
13
+ import sys
14
+ import os
15
+
16
+ def getIdChatHistoryByUserIdAndNameChat(user_id:int,name_old :str) -> chat_history.id:
17
+ try:
18
+ engine = cf.get_db_engine()
19
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
20
+ with Session() as session:
21
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
22
+ chat_id = session.query(chat_history.id).filter(chat_history.email == email, chat_history.name_chat == name_old).scalar()
23
+ session.commit()
24
+ if chat_id:
25
+ session.close()
26
+ return chat_id
27
+ else:
28
+ session.close()
29
+ return None
30
+ except:
31
+ engine = cf.get_db_engine1()
32
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
33
+ with Session() as session:
34
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
35
+ chat_id = session.query(chat_history.id).filter(chat_history.email == email, chat_history.name_chat == name_old).scalar()
36
+ session.commit()
37
+ if chat_id:
38
+ session.close()
39
+ return chat_id
40
+ else:
41
+ session.close()
42
+ return None
43
+
44
+ def getIdChatHistoryByUserIdAndNameChatNew(user_id:int,name_old :str) -> chat_history.id:
45
+ try:
46
+ engine = cf.get_db_engine()
47
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
48
+ with Session() as session:
49
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
50
+ chat_id = session.query(chat_history.id).filter(chat_history.email == email, chat_history.name_chat == name_old).scalar()
51
+ session.commit()
52
+ if chat_id:
53
+ session.close()
54
+ return chat_id
55
+ else:
56
+ session.close()
57
+ return None
58
+ except:
59
+ engine = cf.get_db_engine1()
60
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
61
+ with Session() as session:
62
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
63
+ chat_id = session.query(chat_history.id).filter(chat_history.email == email,
64
+ chat_history.name_chat == name_old).scalar()
65
+ session.commit()
66
+ if chat_id:
67
+ session.close()
68
+ return chat_id
69
+ else:
70
+ session.close()
71
+ return None
72
+
73
+ def updateNameChatHistory(user_id: int,name_old :str,name_new:str) -> bool:
74
+ try:
75
+ engine = cf.get_db_engine1()
76
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
77
+ with Session() as session:
78
+ try:
79
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
80
+ session.query(chat_history).filter(chat_history.email == email,chat_history.name_chat == name_old).update({chat_history.name_chat: name_new})
81
+ session.commit()
82
+ session.close()
83
+ return True
84
+ except:
85
+ session.rollback()
86
+ session.close()
87
+ return False
88
+ except:
89
+ engine = cf.get_db_engine()
90
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
91
+ with Session() as session:
92
+ try:
93
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
94
+ session.query(chat_history).filter(chat_history.email == email,chat_history.name_chat == name_old).update({chat_history.name_chat: name_new})
95
+ session.commit()
96
+ session.close()
97
+ return True
98
+ except:
99
+ session.rollback()
100
+ session.close()
101
+ return False
102
+
103
+ def deleteChatHistory(user_id,chat_name: str) -> bool:
104
+ try:
105
+ try:
106
+ engine = cf.get_db_engine1()
107
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
108
+ with Session() as session:
109
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
110
+ session.query(chat_history).filter(chat_history.email == email, chat_history.name_chat == chat_name).delete()
111
+ session.commit()
112
+ session.close()
113
+ return True
114
+ except Exception as e:
115
+ session.rollback()
116
+ session.close()
117
+ return False
118
+ except:
119
+ try:
120
+ engine = cf.get_db_engine()
121
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
122
+ with Session() as session:
123
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
124
+ session.query(chat_history).filter(chat_history.email == email, chat_history.name_chat == chat_name).delete()
125
+ session.commit()
126
+ session.close()
127
+ return True
128
+ except Exception as e:
129
+ session.rollback()
130
+ session.close()
131
+ return False
132
+
133
+
134
+ def getChatHistoryByEmail(email: str) -> chat_history:
135
+ try:
136
+ engine = cf.get_db_engine1()
137
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
138
+ with Session() as session:
139
+ chat_history1 = session.query(chat_history).filter(chat_history.email == email)
140
+ if chat_history1:
141
+ session.commit()
142
+ session.close()
143
+ return chat_history1
144
+ session.close()
145
+ return None
146
+ except:
147
+ engine = cf.get_db_engine()
148
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
149
+ with Session() as session:
150
+ chat_history1 = session.query(chat_history).filter(chat_history.email == email)
151
+ if chat_history1:
152
+ session.commit()
153
+ session.close()
154
+ return chat_history1
155
+ session.close()
156
+ return None
157
+
158
+ from sqlalchemy.orm import aliased
159
+
160
+ def getChatHistoryByChatIdAndUserId(chat_id: int, user_id: int) -> chat_history:
161
+ try:
162
+ engine = cf.get_db_engine()
163
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
164
+ with Session() as session:
165
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
166
+ chat_history1 = session.query(chat_history).filter(chat_history.id == chat_id,chat_history.email == email).one_or_none()
167
+ if chat_history1:
168
+ session.commit()
169
+ session.close()
170
+ return True
171
+ session.close()
172
+ return None
173
+ except:
174
+ engine = cf.get_db_engine1()
175
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
176
+ with Session() as session:
177
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
178
+ chat_history1 = session.query(chat_history).filter(chat_history.email == email)
179
+ if chat_history1:
180
+ session.commit()
181
+ session.close()
182
+ return True
183
+ session.close()
184
+ return None
185
+
186
+
187
+ def getChatHistoryById(id: int) -> chat_history:
188
+ try:
189
+ engine = cf.get_db_engine()
190
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
191
+ with Session() as session:
192
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
193
+ chat_history1 = session.query(chat_history).filter(chat_history.email == email)
194
+ if chat_history1:
195
+ session.commit()
196
+ session.close()
197
+ return chat_history1
198
+ session.close()
199
+ return None
200
+ except:
201
+ engine = cf.get_db_engine1()
202
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
203
+ with Session() as session:
204
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
205
+ chat_history1 = session.query(chat_history).filter(chat_history.email == email)
206
+ if chat_history1:
207
+ session.commit()
208
+ session.close()
209
+ return chat_history1
210
+ session.close()
211
+ return None
212
+
213
+ def addChatHistory(user_id: str, name_chat:str)->None:
214
+ try:
215
+ engine = cf.get_db_engine()
216
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
217
+ with Session() as session:
218
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
219
+ new_user = chat_history(
220
+ email = email,
221
+ name_chat = name_chat
222
+ )
223
+ session.add(new_user)
224
+ session.commit()
225
+ session.close()
226
+ except:
227
+ engine = cf.get_db_engine1()
228
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
229
+ with Session() as session:
230
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()[0]
231
+ new_user = chat_history(
232
+ email = email,
233
+ name_chat = name_chat
234
+ )
235
+ session.add(new_user)
236
+ session.commit()
237
+ session.close()
repository/ConfigDatabase.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import create_engine, URL
2
+ from sqlalchemy.orm import DeclarativeBase
3
+ Base = DeclarativeBase()
4
+ from sqlalchemy.engine import create_engine, URL
5
+ from dotenv import load_dotenv
6
+ import os
7
+ load_dotenv()
8
+ MYSQL_USER_NAME=os.getenv('MYSQL_USER_NAME')
9
+ MYSQL_PASSWORD=os.getenv('MYSQL_PASSWOR')
10
+ MYSQL_PORT=os.getenv('MYSQL_PORT')
11
+ MYSQL_DATABASE=os.getenv('MYSQL_DATABASE')
12
+ MYSQL_HOST=os.getenv('MYSQL_HOST')
13
+ #IF USE DOCKER HOST = host.docker.internal
14
+ def get_db_engine():
15
+ dsn = URL.create(
16
+ drivername="mysql+pymysql",
17
+ username=MYSQL_USER_NAME,
18
+ password=MYSQL_PASSWORD,
19
+ host=MYSQL_HOST,
20
+ port=MYSQL_PORT,
21
+ database=MYSQL_DATABASE
22
+ )
23
+ connect_args = {}
24
+ return create_engine(
25
+ dsn,
26
+ connect_args=connect_args,
27
+ )
28
+
29
+ def get_db_engine1():
30
+ dsn = URL.create(
31
+ drivername="mysql+pymysql",
32
+ username=MYSQL_USER_NAME,
33
+ password=MYSQL_PASSWORD,
34
+ host=MYSQL_HOST,
35
+ port=MYSQL_PORT,
36
+ database=MYSQL_DATABASE
37
+ )
38
+ connect_args = {}
39
+ return create_engine(
40
+ dsn,
41
+ connect_args=connect_args,
42
+ )
repository/DetailChatRepository.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.orm import sessionmaker
2
+ from entity import Database_Entity
3
+ from repository import ConfigDatabase as cf
4
+ detail_chat = Database_Entity.DetailChat
5
+ chat_history = Database_Entity.ChatHistory
6
+
7
+ def getListDetailChatByChatId(chat_id: int) -> detail_chat:
8
+ try:
9
+ engine = cf.get_db_engine1()
10
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
11
+ with Session() as session:
12
+ chat_record= session.query(detail_chat).filter(detail_chat.chat_id == chat_id)
13
+ session.commit()
14
+ if chat_record:
15
+ session.close()
16
+ return chat_record
17
+ else:
18
+ session.close()
19
+ return None
20
+ except:
21
+ engine = cf.get_db_engine()
22
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
23
+ with Session() as session:
24
+ chat_record= session.query(detail_chat).filter(detail_chat.chat_id == chat_id)
25
+ session.commit()
26
+ if chat_record:
27
+ session.close()
28
+ return chat_record
29
+ else:
30
+ session.close()
31
+ return None
32
+
33
+ def addDetailChat(chat_id: int, YouMessage: str, AiMessage: str, data_relevant: str, source_file: str) -> None:
34
+ try:
35
+ engine = cf.get_db_engine()
36
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
37
+ with Session() as session:
38
+ new_user = detail_chat(
39
+ chat_id = chat_id,
40
+ YouMessage = YouMessage,
41
+ AiMessage = AiMessage,
42
+ data_relevant = data_relevant,
43
+ source_file = source_file
44
+ )
45
+ session.add(new_user)
46
+ session.commit()
47
+ return new_user.id
48
+ session.close()
49
+ except:
50
+ engine = cf.get_db_engine1()
51
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
52
+ with Session() as session:
53
+ new_user = detail_chat(
54
+ chat_id=chat_id,
55
+ YouMessage=YouMessage,
56
+ AiMessage=AiMessage,
57
+ data_relevant=data_relevant,
58
+ source_file=source_file
59
+ )
60
+ session.add(new_user)
61
+ session.commit()
62
+ return new_user.id
63
+ session.close()
64
+
65
+ def getDetailChatByChatId(id: int) -> detail_chat:
66
+ try:
67
+ engine = cf.get_db_engine()
68
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
69
+ with Session() as session:
70
+ try:
71
+ chat = session.query(detail_chat).filter(detail_chat.id == id).one_or_none()
72
+ return chat
73
+ except:
74
+ session.close()
75
+ return False
76
+ except:
77
+ engine = cf.get_db_engine1()
78
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
79
+ with Session() as session:
80
+ try:
81
+ chat = session.query(detail_chat.id,detail_chat.data_relevant,detail_chat.source_file).filter(detail_chat.id == id).one_or_none()
82
+ session.commit()
83
+ session.close()
84
+ return chat
85
+ except:
86
+ session.close()
87
+ return False
88
+
89
+
90
+ def delete_chat_detail(chat_name: str) -> bool:
91
+ try:
92
+ engine = cf.get_db_engine()
93
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
94
+ with Session() as session:
95
+ try:
96
+ detail_chat2 = session.query(detail_chat).filter(detail_chat.chat_id == chat_history.id).filter(chat_history.name_chat == chat_name)
97
+ session.query(detail_chat).filter(detail_chat.chat_id == chat_history.id).filter(chat_history.name_chat == chat_name).delete(synchronize_session=False)
98
+ session.commit()
99
+ session.close()
100
+ return True
101
+ except:
102
+ session.close()
103
+ return False
104
+ except:
105
+ engine = cf.get_db_engine1()
106
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
107
+ with Session() as session:
108
+ try:
109
+ session.query(detail_chat).filter(detail_chat.chat_id == chat_history.id).filter(chat_history.name_chat == chat_name).delete(synchronize_session=False)
110
+ session.commit()
111
+ session.close()
112
+ return True
113
+ except:
114
+ session.close()
115
+ return False
repository/OTPRepository.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.orm import sessionmaker
2
+ from entity import Database_Entity
3
+ from repository import ConfigDatabase as cf
4
+ otp_user = Database_Entity.OTP
5
+ from sqlalchemy.orm import sessionmaker
6
+ from functools import lru_cache
7
+ import sys
8
+ import os
9
+
10
+ def getOtpByEmail(email: str) -> otp_user:
11
+ try:
12
+ engine = cf.get_db_engine()
13
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
14
+ with Session() as session:
15
+ user_record= session.query(otp_user).filter(otp_user.email == email).one_or_none()
16
+ if user_record:
17
+ session.close()
18
+ return user_record
19
+ else:
20
+ session.close()
21
+ return None
22
+ except:
23
+ engine = cf.get_db_engine1()
24
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
25
+ with Session() as session:
26
+ user_record= session.query(otp_user).filter(otp_user.email == email).one_or_none()
27
+ if user_record:
28
+ session.close()
29
+ return user_record
30
+ else:
31
+ session.close()
32
+ return None
33
+
34
+ def addOTP(email: str, otp: str) -> None:
35
+ try:
36
+ engine = cf.get_db_engine()
37
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
38
+ with Session() as session:
39
+ otp_record = session.query(otp_user).filter_by(email=email).first()
40
+ if otp_record:
41
+ session.delete(otp_record)
42
+ session.commit()
43
+ new_user = otp_user(
44
+ email = email,
45
+ otp= otp
46
+ )
47
+ session.add(new_user)
48
+ session.commit()
49
+ session.close()
50
+ except:
51
+ engine = cf.get_db_engine1()
52
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
53
+ with Session() as session:
54
+ otp_record = session.query(otp_user).filter_by(email=email).first()
55
+ if otp_record:
56
+ session.delete(otp_record)
57
+ session.commit()
58
+ new_user = otp_user(
59
+ email = email,
60
+ otp= otp
61
+ )
62
+ session.add(new_user)
63
+ session.commit()
64
+ session.close()
65
+
66
+ def deleteOTP(email: str, otp:str) -> None:
67
+ try:
68
+ engine = cf.get_db_engine()
69
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
70
+ with Session() as session:
71
+ otp_record = session.query(otp_user).filter_by(email=email, otp=otp).first()
72
+ if otp_record:
73
+ session.delete(otp_record)
74
+ session.commit()
75
+ except:
76
+ engine = cf.get_db_engine1()
77
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
78
+ with Session() as session:
79
+ otp_record = session.query(otp_user).filter_by(email=email, otp=otp).first()
80
+ if otp_record:
81
+ session.delete(otp_record)
82
+ session.commit()
repository/UserInfoRepository.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.orm import sessionmaker
2
+ from entity import Database_Entity
3
+ from repository import ConfigDatabase as cf
4
+ user_info = Database_Entity.UserInfo
5
+ users = Database_Entity.User
6
+ from sqlalchemy.orm import sessionmaker
7
+ import sys
8
+ import os
9
+
10
+ def getUserInfo(user_id: int) -> user_info:
11
+ try:
12
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()
13
+ if email:
14
+ email = email[0]
15
+ user_record= session.query(user_info).filter(user_info.email == email).one_or_none()
16
+ if user_record:
17
+ session.close()
18
+ return user_record
19
+ else:
20
+ session.close()
21
+ return None
22
+ except:
23
+ engine = cf.get_db_engine1()
24
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
25
+ with Session() as session:
26
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()
27
+ if email:
28
+ email = email[0]
29
+ user_record= session.query(user_info).filter(user_info.email == email).one_or_none()
30
+ if user_record:
31
+ session.close()
32
+ return user_record
33
+ else:
34
+ session.close()
35
+ return None
36
+
37
+ def getUserInfoByEmail(email:str) -> user_info:
38
+ try:
39
+ engine = cf.get_db_engine()
40
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
41
+ with Session() as session:
42
+ user_record= session.query(user_info).filter(user_info.email == email).one_or_none()
43
+ if user_record:
44
+ session.close()
45
+ return user_record
46
+ else:
47
+ session.close()
48
+ return None
49
+ except:
50
+ engine = cf.get_db_engine1()
51
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
52
+ with Session() as session:
53
+ user_record= session.query(user_info).filter(user_info.email == email).one_or_none()
54
+ if user_record:
55
+ session.close()
56
+ return user_record
57
+ else:
58
+ session.close()
59
+ return None
60
+
61
+
62
+
63
+ def addUserInfo(uid: str, email: str, display_name: str, photo_url: str) -> None:
64
+ try:
65
+ engine = cf.get_db_engine()
66
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
67
+ with Session() as session:
68
+ new_user = user_info(
69
+ uid = uid,
70
+ email = email,
71
+ display_name = display_name,
72
+ photo_url = photo_url
73
+ )
74
+ session.add(new_user)
75
+ session.commit()
76
+ session.close()
77
+ except:
78
+ engine = cf.get_db_engine1()
79
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
80
+ with Session() as session:
81
+ new_user = user_info(
82
+ uid = uid,
83
+ email = email,
84
+ display_name = display_name,
85
+ photo_url = photo_url
86
+ )
87
+ session.add(new_user)
88
+ session.commit()
89
+ session.close()
90
+
91
+ def updateUserInfo(user_id, uid: str, email: str, display_name: str, photo_url: str) -> None:
92
+ try:
93
+ engine = cf.get_db_engine()
94
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
95
+ with Session() as session:
96
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()
97
+ user_update= session.query(user_info).filter(user_info.email == email).one_or_none()
98
+ if user_update is not None:
99
+ user_update.uid = uid,
100
+ user_update.display_name = display_name,
101
+ user_update.photo_url = photo_url
102
+ session.commit()
103
+ session.close()
104
+ except:
105
+ engine = cf.get_db_engine1()
106
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
107
+ with Session() as session:
108
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()
109
+ user_update= session.query(user_info).filter(user_info.email == email).one_or_none()
110
+ if user_update is not None:
111
+ user_update.uid = uid,
112
+ user_update.display_name = display_name,
113
+ user_update.photo_url = photo_url
114
+ session.commit()
115
+ session.close()
116
+
117
+
118
+ def updateImage(user_id, photo_url: str) -> None:
119
+ try:
120
+ engine = cf.get_db_engine()
121
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
122
+ with Session() as session:
123
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()
124
+ user_update= session.query(user_info).filter(user_info.email == email).one_or_none()
125
+ if user_update is not None:
126
+ user_update.photo_url = photo_url
127
+ session.commit()
128
+ session.close()
129
+ except:
130
+ engine = cf.get_db_engine1()
131
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
132
+ with Session() as session:
133
+ email = session.query(users.email).filter(users.id == user_id).one_or_none()
134
+ user_update = session.query(user_info).filter(user_info.email == email).one_or_none()
135
+ if user_update is not None:
136
+ user_update.photo_url = photo_url
137
+ session.commit()
138
+ session.close()
139
+
repository/UserLoginRepository.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.orm import sessionmaker
2
+ from entity import Database_Entity
3
+ from repository import ConfigDatabase as cf
4
+ user_login = Database_Entity.UserLogin
5
+ users = Database_Entity.User
6
+
7
+ def getUserLogin(email: str) -> user_login:
8
+ try:
9
+ engine = cf.get_db_engine()
10
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
11
+ with Session() as session:
12
+ user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none()
13
+ if user_record:
14
+ session.close()
15
+ return user_record
16
+ else:
17
+ session.close()
18
+ return None
19
+ except:
20
+ engine = cf.get_db_engine1()
21
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
22
+ with Session() as session:
23
+ user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none()
24
+ if user_record:
25
+ session.close()
26
+ return user_record
27
+ else:
28
+ session.close()
29
+ return None
30
+
31
+
32
+ def getUserLoginById(id: int) -> user_login:
33
+ try:
34
+ engine = cf.get_db_engine()
35
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
36
+ with Session() as session:
37
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
38
+ user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none()
39
+ if user_record:
40
+ session.close()
41
+ return user_record
42
+ else:
43
+ session.close()
44
+ return None
45
+ except:
46
+ engine = cf.get_db_engine1()
47
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
48
+ with Session() as session:
49
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
50
+ user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none()
51
+ if user_record:
52
+ session.close()
53
+ return user_record
54
+ else:
55
+ session.close()
56
+ return None
57
+
58
+ def addUserLogin(user_email: str, session_id : str) -> None:
59
+ try:
60
+ engine = cf.get_db_engine()
61
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
62
+ with Session() as session:
63
+ new_user = user_login(
64
+ user_email = user_email,
65
+ user_session_id = session_id
66
+ )
67
+ session.add(new_user)
68
+ session.commit()
69
+ session.close()
70
+ except:
71
+ engine = cf.get_db_engine1()
72
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
73
+ with Session() as session:
74
+ new_user = user_login(
75
+ user_email = user_email,
76
+ user_session_id = session_id
77
+ )
78
+ session.add(new_user)
79
+ session.commit()
80
+ session.close()
81
+
82
+
83
+ def updateUserLogin(email: str, session_id : str ) -> None:
84
+ try:
85
+ engine = cf.get_db_engine()
86
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
87
+ with Session() as session:
88
+ user_update= session.query(user_login).filter(user_login.user_email == email).one_or_none()
89
+ if user_update is not None:
90
+ user_update.user_session_id = session_id
91
+ session.commit()
92
+ session.close()
93
+ except:
94
+ engine = cf.get_db_engine1()
95
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
96
+ with Session() as session:
97
+ user_update= session.query(user_login).filter(user_login.user_email == email).one_or_none()
98
+ if user_update is not None:
99
+ user_update.user_session_id = session_id
100
+ session.commit()
101
+ session.close()
102
+
103
+
104
+
105
+ def getUserSessionIdByUserEmail(id: int) -> user_login:
106
+ try:
107
+ engine = cf.get_db_engine()
108
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
109
+ with Session() as session:
110
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
111
+ session.commit()
112
+ user_record= session.query(user_login.user_session_id).filter(user_login.user_email == email).one_or_none()[0]
113
+ session.commit()
114
+ print(user_record)
115
+ if user_record:
116
+ session.close()
117
+ return user_record
118
+ else:
119
+ session.close()
120
+ return None
121
+ except:
122
+ engine = cf.get_db_engine1()
123
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
124
+ with Session() as session:
125
+ email = session.query(users.email).filter(users.id == id).one_or_none()[0]
126
+ session.commit()
127
+ user_record= session.query(user_login.user_session_id).filter(user_login.user_email == email).one_or_none()[0]
128
+ session.commit()
129
+ print(user_record)
130
+ if user_record:
131
+ session.close()
132
+ return user_record
133
+ else:
134
+ session.close()
135
+ return None
repository/UserRepository.py ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.orm import sessionmaker
2
+ from entity import Database_Entity
3
+ from repository import ConfigDatabase as cf
4
+ import pytz , datetime
5
+ from datetime import timedelta
6
+ user = Database_Entity.User
7
+
8
+ def getUserIdByAccessToken(token:str) -> int:
9
+ try:
10
+ engine = cf.get_db_engine()
11
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
12
+ with Session() as session:
13
+ user_record = session.query(user.id).filter(user.access_token == token).one_or_none()
14
+ session.close()
15
+ return user_record
16
+ except:
17
+ engine = cf.get_db_engine1()
18
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
19
+ with Session() as session:
20
+ user_record = session.query(user.id).filter(user.access_token == token).one_or_none()
21
+ session.close()
22
+ return user_record
23
+
24
+ def getUserIdByAccessTokenAndUserId(token:str,user_id: int) -> int:
25
+ try:
26
+ engine = cf.get_db_engine()
27
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
28
+ with Session() as session:
29
+ user_record = session.query(user.id).filter(user.access_token == token,user.id == user_id).one_or_none()
30
+ session.close()
31
+ return user_record
32
+ except:
33
+ engine = cf.get_db_engine1()
34
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
35
+ with Session() as session:
36
+ user_record = session.query(user.id).filter(user.access_token == token,user.id == user_id).one_or_none()
37
+ session.close()
38
+ return user_record
39
+
40
+ def getUserByEmail(email: str) -> user:
41
+ try:
42
+ engine = cf.get_db_engine()
43
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
44
+ with Session() as session:
45
+ user_record = session.query(user).filter(user.email == email).one_or_none()
46
+ session.close()
47
+ return user_record
48
+ except:
49
+ engine = cf.get_db_engine1()
50
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
51
+ with Session() as session:
52
+ user_record = session.query(user).filter(user.email == email).one_or_none()
53
+ session.close()
54
+ return user_record
55
+
56
+ def getUserIdByEmail(email: str) -> user.id:
57
+ try:
58
+ engine = cf.get_db_engine()
59
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
60
+ with Session() as session:
61
+ user_record = session.query(user.id).filter(user.email == email).one_or_none()[0]
62
+ session.close()
63
+ return user_record
64
+ except:
65
+ engine = cf.get_db_engine1()
66
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
67
+ with Session() as session:
68
+ user_record = session.query(user.id).filter(user.email == email).one_or_none()[0]
69
+ session.close()
70
+ return user_record
71
+
72
+ def getUserById(user_id: str) -> user:
73
+ try:
74
+ engine = cf.get_db_engine()
75
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
76
+ with Session() as session:
77
+ user_record = session.query(user).filter(user.id == user_id).one_or_none()
78
+ session.close()
79
+ return user_record
80
+ except:
81
+ engine = cf.get_db_engine1()
82
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
83
+ with Session() as session:
84
+ user_record = session.query(user).filter(user.id == user_id).one_or_none()
85
+ session.close()
86
+ return user_record
87
+
88
+ def getRefreshTokenUserByAccessToken(token: str) -> user.refresh_token:
89
+ try:
90
+ engine = cf.get_db_engine()
91
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
92
+ with Session() as session:
93
+ user_record = session.query(user.refresh_token).filter(user.access_token == token).one_or_none()
94
+ session.close()
95
+ return user_record
96
+ except:
97
+ engine = cf.get_db_engine1()
98
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
99
+ with Session() as session:
100
+ user_record = session.query(user.refresh_token).filter(user.access_token == token).one_or_none()
101
+ session.close()
102
+ return user_record
103
+
104
+ def getRefreshTokenUserByIdAndAccessToken(user_id: str,accessToken: str) -> user.refresh_token:
105
+ try:
106
+ engine = cf.get_db_engine()
107
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
108
+ with Session() as session:
109
+ user_record = session.query(user.refresh_token).filter(user.id == user_id,user.access_token == accessToken).one_or_none()[0]
110
+ session.close()
111
+ return user_record
112
+ except:
113
+ engine = cf.get_db_engine1()
114
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
115
+ with Session() as session:
116
+ user_record = session.query(user.refresh_token).filter(user.id == user_id).one_or_none()[0]
117
+ session.close()
118
+ return user_record
119
+
120
+ def getRefreshTokenUserById(user_id: str) -> user.refresh_token:
121
+ try:
122
+ engine = cf.get_db_engine()
123
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
124
+ with Session() as session:
125
+ user_record = session.query(user.refresh_token).filter(user.id == user_id).one_or_none()[0]
126
+ session.close()
127
+ return user_record
128
+ except:
129
+ engine = cf.get_db_engine1()
130
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
131
+ with Session() as session:
132
+ user_record = session.query(user.refresh_token).filter(user.id == user_id).one_or_none()[0]
133
+ session.close()
134
+ return user_record
135
+
136
+ def getEmailUser(email:str) -> user.email:
137
+ try:
138
+ engine = cf.get_db_engine()
139
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
140
+ with Session() as session:
141
+ user_email = session.query(user.email).filter(user.email == email).one_or_none()
142
+ session.close()
143
+ return user_email
144
+ except:
145
+ engine = cf.get_db_engine1()
146
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
147
+ with Session() as session:
148
+ user_email = session.query(user.email).filter(user.email == email).one_or_none()
149
+ session.close()
150
+ return user_email
151
+
152
+ def getEmailUserById(user_id:int) -> user.email:
153
+ try:
154
+ engine = cf.get_db_engine()
155
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
156
+ with Session() as session:
157
+ user_email = session.query(user.email).filter(user.id == user_id).one_or_none()[0]
158
+ session.close()
159
+ return user_email
160
+ except:
161
+ engine = cf.get_db_engine1()
162
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
163
+ with Session() as session:
164
+ user_email = session.query(user.email).filter(user.id == user_id).one_or_none()[0]
165
+ session.close()
166
+ return user_email
167
+
168
+ def getEmailUserByIdFix(user_id:int) -> user.email:
169
+ try:
170
+ engine = cf.get_db_engine()
171
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
172
+ with Session() as session:
173
+ user_email = session.query(user.email).filter(user.id == user_id).one_or_none()
174
+ session.close()
175
+ return user_email
176
+ except:
177
+ engine = cf.get_db_engine1()
178
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
179
+ with Session() as session:
180
+ user_email = session.query(user.email).filter(user.id == user_id).one_or_none()
181
+ session.close()
182
+ return user_email
183
+
184
+
185
+
186
+ def getEmailUserByAccessToken(token: str) -> user.email:
187
+ try:
188
+ engine = cf.get_db_engine()
189
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
190
+ with Session() as session:
191
+ user_email = session.query(user.email).filter(user.access_token == token).one_or_none()
192
+ session.close()
193
+ return user_email
194
+ except:
195
+ engine = cf.get_db_engine1()
196
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
197
+ with Session() as session:
198
+ user_email = session.query(user.email).filter(user.access_token == token).one_or_none()
199
+ session.close()
200
+ return user_email
201
+
202
+
203
+ def addUser(email: str, access_token: str, refresh_token: str, expires_at: datetime.datetime) -> None:
204
+ try:
205
+ engine = cf.get_db_engine()
206
+ Session = sessionmaker(bind=engine)
207
+ with Session() as session:
208
+ new_user = Database_Entity.User(
209
+ email=email,
210
+ access_token=access_token,
211
+ refresh_token=refresh_token,
212
+ expires_at=expires_at
213
+ )
214
+ session.add(new_user)
215
+ session.commit()
216
+ session.close()
217
+ except:
218
+ engine = cf.get_db_engine1()
219
+ Session = sessionmaker(bind=engine)
220
+ with Session() as session:
221
+ new_user = Database_Entity.User(
222
+ email=email,
223
+ access_token=access_token,
224
+ refresh_token=refresh_token,
225
+ expires_at=expires_at
226
+ )
227
+ session.add(new_user)
228
+ session.commit()
229
+ session.close()
230
+
231
+
232
+ def updateUserLogin(email: str, access_token: str, refresh_token: str, expires_at: datetime.datetime) -> bool:
233
+ try:
234
+ engine = cf.get_db_engine()
235
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
236
+ with Session() as session:
237
+ user_update = session.query(user).filter(user.email == email).one_or_none()
238
+ if user_update:
239
+ user_update.email = email
240
+ user_update.access_token = access_token
241
+ user_update.refresh_token = refresh_token
242
+ user_update.expires_at = expires_at
243
+ session.commit()
244
+ session.close()
245
+ return True
246
+ else:
247
+ session.close()
248
+ return False
249
+ except:
250
+ engine = cf.get_db_engine1()
251
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
252
+ with Session() as session:
253
+ user_update = session.query(user).filter(user.email == email).one_or_none()
254
+ if user_update:
255
+ user_update.email = email
256
+ user_update.access_token = access_token
257
+ user_update.refresh_token = refresh_token
258
+ user_update.expires_at = expires_at
259
+ session.commit()
260
+ session.close()
261
+ return True
262
+ else:
263
+ session.close()
264
+ return False
265
+
266
+
267
+ def updateAccessToken(user_id: int,access_token: str, expires_at: datetime.datetime) -> None:
268
+ try:
269
+ engine = cf.get_db_engine()
270
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
271
+ with Session() as session:
272
+ user_update = session.query(user).filter(user.id == user_id).one_or_none()
273
+ if user_update:
274
+ user_update.access_token = access_token
275
+ user_update.expires_at = expires_at
276
+ session.commit()
277
+ except:
278
+ engine = cf.get_db_engine1()
279
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
280
+ with Session() as session:
281
+ user_update = session.query(user).filter(user.id == user_id).one_or_none()
282
+ if user_update:
283
+ user_update.access_token = access_token
284
+ user_update.expires_at = expires_at
285
+ session.commit()
286
+
287
+ def updateAccessTokenById(id: int,access_token: str, expires_at: datetime.datetime) -> None:
288
+ try:
289
+ engine = cf.get_db_engine()
290
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
291
+ with Session() as session:
292
+ user_update = session.query(user).filter(user.id == id).one_or_none()
293
+ if user_update:
294
+ user_update.access_token = access_token
295
+ user_update.expires_at = expires_at
296
+ session.commit()
297
+ session.close()
298
+ except:
299
+ engine = cf.get_db_engine1()
300
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
301
+ with Session() as session:
302
+ user_update = session.query(user).filter(user.id == id).one_or_none()
303
+ if user_update:
304
+ user_update.access_token = access_token
305
+ user_update.expires_at = expires_at
306
+ session.commit()
307
+ session.close()
308
+
309
+
310
+ def UpdateAccessTokenRefreshToken(email: str, access_token: str, refresh_token: str, expires_at: datetime.datetime) -> None:
311
+ try:
312
+ engine = cf.get_db_engine()
313
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
314
+ with Session() as session:
315
+ user_update = session.query(user).filter(user.email == email).one_or_none()
316
+ if user_update:
317
+ user_update.access_token = access_token
318
+ user_update.refresh_token = refresh_token
319
+ user_update.expires_at = expires_at
320
+ session.commit()
321
+ session.close()
322
+ except:
323
+ engine = cf.get_db_engine1()
324
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
325
+ with Session() as session:
326
+ user_update = session.query(user).filter(user.email == email).one_or_none()
327
+ if user_update:
328
+ user_update.access_token = access_token
329
+ user_update.refresh_token = refresh_token
330
+ user_update.expires_at = expires_at
331
+ session.commit()
332
+ session.close()
333
+
334
+ def UpdateAccessTokenRefreshTokenById(user_id: int,access_token: str, refresh_token: str, expires_at: datetime.datetime) -> None:
335
+ try:
336
+ engine = cf.get_db_engine()
337
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
338
+ with Session() as session:
339
+ user_update = session.query(user).filter(user.id == user_id).one_or_none()
340
+ if user_update:
341
+ user_update.access_token = access_token
342
+ user_update.refresh_token = refresh_token
343
+ user_update.expires_at = expires_at
344
+ session.commit()
345
+ session.close()
346
+ except:
347
+ engine = cf.get_db_engine1()
348
+ Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
349
+ with Session() as session:
350
+ user_update = session.query(user).filter(user.id == user_id).one_or_none()
351
+ if user_update:
352
+ user_update.access_token = access_token
353
+ user_update.refresh_token = refresh_token
354
+ user_update.expires_at = expires_at
355
+ session.commit()
356
+ session.close()
repository/__pycache__/ChatHistoryRepository.cpython-310.pyc ADDED
Binary file (5.57 kB). View file
 
repository/__pycache__/ChatHistoryRepository.cpython-311.pyc ADDED
Binary file (19.8 kB). View file
 
repository/__pycache__/ConfigDatabase.cpython-310.pyc ADDED
Binary file (970 Bytes). View file
 
repository/__pycache__/ConfigDatabase.cpython-311.pyc ADDED
Binary file (1.78 kB). View file
 
repository/__pycache__/DetailChatRepository.cpython-310.pyc ADDED
Binary file (2.91 kB). View file
 
repository/__pycache__/DetailChatRepository.cpython-311.pyc ADDED
Binary file (8.13 kB). View file
 
repository/__pycache__/OTPRepository.cpython-310.pyc ADDED
Binary file (2.19 kB). View file