You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
6.4 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import uuid
import psycopg2
from datetime import timedelta
from psycopg2 import IntegrityError
from utils import *
from type import *
from const import *
def update_token_expiry_date(token: str, expiry_date: date) -> None:
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
expiry_date_str = expiry_date.strftime("%Y.%m.%d")
try:
cursor.execute(
"UPDATE users SET token_expiry_date = %s WHERE token = %s",
(expiry_date_str, token)
)
connection.commit()
except Exception as e:
connection.rollback()
print("Ошибка при обновлении токена:", e)
raise
finally:
cursor.close()
connection.close()
def validate_token(token: str) -> bool:
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
try:
return check_token(cursor, token)
except Exception as e:
connection.rollback()
print("Ошибка при проверке токена:", e)
raise
finally:
cursor.close()
connection.close()
def login(email: str, password: str) :
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
try:
cursor.execute("SELECT password,token FROM users WHERE email = %s", (email,))
result = cursor.fetchone()
if result is None:
raise AuthError("Неверный email или пароль")
print(result)
stored_hash, token = result
if not bcrypt.checkpw(password.encode('utf-8'), stored_hash.encode('utf-8')):
raise AuthError("Неверный email или пароль")
if token is None:
# Опционально: можно сгенерировать новый токен здесь
raise AuthError("У пользователя отсутствует токен")
token_live_time = timedelta(days=TOKEN_LIVE_TIME)
update_token_expiry_date(token, date.today() + token_live_time)
return token
finally:
cursor.close()
def logout(token):
try:
# Обновляем token_expiry_date на текущую дату (как в регистрации)
today = date.today()
update_token_expiry_date(token, today)
print(f"Пользователь {token} вышел из системы")
except Exception as e:
print("Ошибка при выходе:", e)
raise
def registration(nickname: str, password: str, email: str) -> str:
# Хэшируем пароль
hashed = hash_password(password)
token = str(uuid.uuid4())
today = date.today().strftime("%Y.%m.%d")
token_live_time = timedelta(days=TOKEN_LIVE_TIME)
token_expiry_date = date.today() + token_live_time
token_expiry_date_str = token_expiry_date.strftime("%Y.%m.%d")
money = "100"
histories_id = "{}"
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
try:
cursor.execute(
"INSERT INTO users (nickname, email, password, token, token_expiry_date, money, histories_id) "
"VALUES (%s, %s, %s, %s, %s, %s, %s)",
(nickname, email, hashed, token, token_expiry_date_str, money, histories_id)
)
connection.commit()
print("Пользователь успешно создан")
return token
except IntegrityError as e:
connection.rollback()
if "email_uniq" in str(e) or "users_email_key" in str(e):
print("Ошибка: пользователь с таким email уже существует")
raise AuthError("Пользователь с таким email уже существует") from e
else:
print("Другая ошибка базы данных:", e)
raise
finally:
cursor.close()
def get_products() -> list[dict]:
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
res = None
try:
res = fetch_table_as_json(cursor, "shop")
except psycopg2.Error as e:
print("Ошибка при работе с PostgreSQL:", e)
finally:
cursor.close()
connection.close()
return res
def get_product(product_id: int):
connection = None
cursor = None
res = None
try:
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
res = fetch_row_as_json(cursor, "shop", product_id)
except psycopg2.Error as e:
print("Ошибка при работе с PostgreSQL:", e)
finally:
cursor.close()
connection.close()
return res
def get_basket(token: str):
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
res = None
try:
if not check_token(cursor, token):
raise AuthError("Пользователь не авторизован")
res = fetch_table_as_json(cursor, "basket")
except psycopg2.Error as e:
print("Ошибка при работе с PostgreSQL:", e)
raise
finally:
cursor.close()
connection.close()
return res
def get_history(token: str):
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
res = None
try:
if not check_token(cursor, token):
raise AuthError("Пользователь не авторизован")
res = fetch_table_as_json(cursor, "history")
except psycopg2.Error as e:
print("Ошибка при работе с PostgreSQL:", e)
raise
finally:
cursor.close()
connection.close()
return res
def add_product_to_basket(token: str, product_id: int) -> None:
connection = psycopg2.connect(**DB_CONFIG)
cursor = connection.cursor()
try:
if not check_token(cursor, token):
raise AuthError("Пользователь не авторизован")
user_id: int = get_user_id(cursor, token)
cursor.execute(
"UPDATE basket SET products_id = array_append(products_id, %s) WHERE user_id = %s",
(product_id, user_id)
)
if cursor.rowcount == 0:
raise ValueError("Пользователь не найден")
connection.commit()
except psycopg2.Error as e:
print("Ошибка при работе с PostgreSQL:", e)
raise
finally:
cursor.close()
connection.close()