diff --git a/App/Waybill/cache/__init__.py b/App/Waybill/cache/__init__.py new file mode 100644 index 0000000..d902592 --- /dev/null +++ b/App/Waybill/cache/__init__.py @@ -0,0 +1,42 @@ +import json +from redis import Redis, ConnectionError, DataError + +class RedisCache: + def __init__(self, config: dict): + self.config = config + self.conn = self._connect() + + def _connect(self): + try: + conn = Redis(**self.config) + return conn + except DataError as err: + print(err) + return None + + def set_value(self, name: str, value_dict: dict, ttl: int): + try: + value_js = json.dumps(value_dict) + self.conn.set(name=name, value=value_js) + if ttl > 0: + self.conn.expire(name, ttl) + return True + except ConnectionError as err: + print(err) + return False + + def get_value(self, name: str): + try: + value_js = self.conn.get(name) + except: + return None + value_js = self.conn.get(name) + if value_js: + value_dict = json.loads(value_js) + return value_dict + else: + return None + + def __exit__(self, exc_type, exc_val, exc_tb): + self.conn.close() + return True \ No newline at end of file diff --git a/App/Waybill/cache/wrapper.py b/App/Waybill/cache/wrapper.py new file mode 100644 index 0000000..ff38803 --- /dev/null +++ b/App/Waybill/cache/wrapper.py @@ -0,0 +1,26 @@ +from functools import wraps +from Waybill.cache import RedisCache + +def fetch_from_cache(cache_name: str, cache_config: dict): + cache_conn = RedisCache(cache_config['redis']) + ttl = cache_config['ttl'] + def decorator(f): + # как оно работает + # лезем в кэш и смотрим, есть ли там что-то + # если есть, то возвращаем кэшированную информацию + # если нет, то запускаем декорируемую функцию + # достаём оттуда информацию + # заносим её в кэш + # возвращаем кэшированную информацию + @wraps(f) + def wrapper(*args, **kwargs): + cached_value = cache_conn.get_value(cache_name) + print("cached_value=", cached_value) + if cached_value: + return cached_value + response = f(*args, **kwargs) + print("response=", response) + cache_conn.set_value(cache_name,response,ttl) + return response + return wrapper + return decorator \ No newline at end of file diff --git a/App/Waybill/model.py b/App/Waybill/model.py index a1eda22..eddd553 100644 --- a/App/Waybill/model.py +++ b/App/Waybill/model.py @@ -1,7 +1,11 @@ from .db.sql_provider import SQLProvider from .db.work import select_list +from db.DBconnect import DBContextManager + from flask import current_app, session from dataclasses import dataclass +from datetime import date +from .cache.wrapper import fetch_from_cache import os @dataclass @@ -23,4 +27,100 @@ def workpiece_list() -> InfoRespronse: return InfoRespronse((), error_message = 'Ошибка в подключении к базе данных. Свяжитесь с администратором', status=False) - return InfoRespronse(result, error_message='', status=True) \ No newline at end of file + return InfoRespronse(result, error_message='', status=True) + +def form_basket() -> list: + current_basket = session.get('basket',{}) + basket = [] + for k,v in current_basket.items(): + _sql = sql_provider.get('one_good.sql', dict(prod_id=k)) + product = select_list(current_app.config['db_config'], _sql)[0] + product['amount'] = v + basket.append(product) + return basket + +def index_basket() -> list: + db_config = current_app.config['db_config'] + cache_config = current_app.config['cache_config'] + + cache_select = fetch_from_cache('items_cached', cache_config)(select_list) + _sql = sql_provider.get('all_goods.sql', {}) + products = cache_select(db_config, _sql) + + return products + +def button_click(request): + db_config = current_app.config['db_config'] + data = dict(prod_id=int(request.form['product_display'])) + + _sql = sql_provider.get('one_good.sql', data) + result = select_list(db_config, _sql) + if result == None: + return False + + product = result[0] + + if request.form.get('buy'): + if 'basket' not in session: + session['basket'] = dict() + + if str(product['prod_id']) in session['basket']: + pr_id = product['prod_id'] + amount = int(session['basket'][str(pr_id)]) + session['basket'][str(pr_id)] = str(amount+1) + session.modified = True + else: + print("NEW PRODUCT") + pr_id = product['prod_id'] + session['basket'][str(pr_id)] = '1' + print(session['basket']) + session.modified = True + + elif request.form.get('product_display_plus'): + # increasing count in basket + + amount = int(session['basket'][str(product['prod_id'])]) + session['basket'][str(product['prod_id'])] = str(amount + 1) + session.modified = True + + elif request.form.get('product_display_minus'): + # decreasing count in basket + + amount = int(session['basket'][str(product['prod_id'])]) + if amount == 1: + session['basket'].pop(str(product['prod_id'])) + else: + session['basket'][str(product['prod_id'])] = str(amount-1) + session.modified = True + return True + +def transaction_order_model(user_id: int, current_date: date): + + db_config = current_app.config['db_config'] + basket = session.get('basket',{}) + + # Чтобы всё это шло как одна транзакция + with DBContextManager(db_config) as cursor: + + data = dict(e_user_id=user_id, e_order_date=current_date) + + _sql = sql_provider.get('create_order.sql', data) + try: + cursor.execute(_sql) + except: + return InfoRespronse(tuple(), error_message="Заказ не был создан", status=False) + + order_id = cursor.lastrowid + for key, value in basket.items(): + _sql = sql_provider.get('insert_order_line.sql', + dict(e_order_id = order_id, + e_prod_id = int(key), + e_amount = int(value))) + try: + cursor.execute(_sql) + except: + return InfoRespronse(tuple(), error_message="Заказ не был создан", status=False) + + result = tuple([order_id]) + clear() + return InfoRespronse(result, error_message="", status=True) \ No newline at end of file diff --git a/App/app.py b/App/app.py index cd4ad61..fe5e3d3 100644 --- a/App/app.py +++ b/App/app.py @@ -10,7 +10,8 @@ app.secret_key = 'suplex' app.config.update( db_config=json.load(open(os.path.join(os.path.dirname(__file__), 'data/config.json'))), - db_access=json.load(open(os.path.join(os.path.dirname(__file__), 'data/db_access.json'))) + db_access=json.load(open(os.path.join(os.path.dirname(__file__), 'data/db_access.json'))), + cache_config=json.load(open(os.path.join(os.path.dirname(__file__), 'data/redis_config.json'))) ) app.register_blueprint(requests_bp, url_prefix='/requests') diff --git a/App/data/redis_config.json b/App/data/redis_config.json new file mode 100644 index 0000000..c334cca --- /dev/null +++ b/App/data/redis_config.json @@ -0,0 +1,8 @@ +{ + "redis": { + "host" :"127.0.0.1", + "port": 6379, + "db" : 0 + }, + "ttl": 60 +} \ No newline at end of file