diff --git a/API/rok.py b/API/rok.py index cffd6db..c244eb4 100644 --- a/API/rok.py +++ b/API/rok.py @@ -29,6 +29,7 @@ def tokens(): return access_token access_token = tokens() +# print(access_token) def get_orders(access_token, page=1, page_size=25): url = f"{BASE_URL}/orders" @@ -57,7 +58,7 @@ def download_products(user_name): print("Каталог продуктов скачан.") -# download_products(user_name) + # get_orders(access_token) @@ -74,7 +75,78 @@ def download_prices(partner_code): print("Каталог цен скачан.") -download_prices(partner) - +def create_order(access_token, sku, quantity, unit_price, partner_order_id): + url = f"{BASE_URL}/orders" + + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + + payload = { + "items": [ + { + "sku": sku, + "quantity": quantity, + "unitPrice": unit_price + } + ], + "partnerOrderId": partner_order_id + } + + response = requests.post(url, headers=headers, json=payload) + response.raise_for_status() + + return response.json() + +def get_orders(access_token, page=1, page_size=25): + url = f"{BASE_URL}/orders" + + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + + payload = { + "page": page, + "pageSize": page_size + } + + response = requests.get(url, headers=headers, json=payload) + response.raise_for_status() + + return response.json() + + +def get_order_content(order_id): + url = f"{BASE_URL}/orders/{order_id}/content" + + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + + response = requests.get(url, headers=headers) + response.raise_for_status() + data = response.json() + con = data['orderContentItems'] + for c in con: + content = c['content'] + return content + + +content = get_order_content(5379484) +print(content) + +# orders = get_orders(access_token) +# print(orders) + + +# order = create_order(access_token, 22774, 1, 21.17, "my-test-order-123") +# print(order) + + +# download_prices(partner) +# download_products(user_name) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 89a0392..1159c83 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ WORKDIR /app RUN uv sync --frozen # Expose port 8000 -EXPOSE 8005 +EXPOSE 5205 # Presuming there is a `my_app` command provided by the project uvicorn main:app --reload diff --git a/app/__pycache__/routes.cpython-313.pyc b/app/__pycache__/routes.cpython-313.pyc index 097773f..4ca4aea 100644 Binary files a/app/__pycache__/routes.cpython-313.pyc and b/app/__pycache__/routes.cpython-313.pyc differ diff --git a/app/routes.py b/app/routes.py index c511c49..3d49a10 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,5 +1,8 @@ -from flask import Blueprint +from flask import Blueprint, request, jsonify # from services.rokky import ones +from API.rok import get_order_content +import logging + main = Blueprint("main", __name__) @@ -16,4 +19,26 @@ def index1(): @main.route("/sales", methods=["POST", "GET"]) def index2(): - return "Hello GET" \ No newline at end of file + return "Hello GET" + + +@main.route("/newOrder", methods=["POST"]) +def new_order(): + if not request.is_json: + return jsonify({"error": "Invalid content type"}), 400 + + data = request.get_json() + print(data) + order_id = data.get("orderId") + if order_id is None: + return jsonify({"error": "orderId is required"}), 400 + + if not isinstance(order_id, int): + return jsonify({"error": "orderId must be int"}), 400 + + # TODO: обработка заказа + print(f"New order received: {order_id}") + logging.warn(get_order_content(order_id)) + logging.warn(f"newOrder: {order_id}") + + return jsonify({"status": "ok"}), 200 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 6876c3d..ec5dbe1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,25 @@ version: '3.8' services: + nginx: + image: nginx:latest + container_name: nginx + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/conf.d:/etc/nginx/conf.d + - ./nginx/certbot/www:/var/www/certbot + - ./nginx/certbot/conf:/etc/letsencrypt + depends_on: + - flask + restart: always + web: build: . container_name: flask-dev ports: - - "5000:5000" # Пробрасываем порт наружу + - "5205:5205" # Пробрасываем порт наружу volumes: # Главная строка: монтируем текущую папку с кодом (.) # в папку /app внутри контейнера diff --git a/main.py b/main.py index 97be195..1974654 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,18 @@ from app import create_app from services.tim import start_scheduler +import logging + + +logging.basicConfig( + filename="./logs/logss.log", + level=logging.WARN, + # format="%(asctime)s - %(message)s", + format="%(asctime)s [%(filename)s:%(lineno)d] - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + # encoding='utf-8' # Указание кодировки UTF-8 + +) + app = create_app() start_scheduler() diff --git a/models/mod.py b/models/mod.py index bd68127..f6062d5 100644 --- a/models/mod.py +++ b/models/mod.py @@ -7,6 +7,7 @@ cursor.execute(""" CREATE TABLE IF NOT EXISTS products ( id INTEGER PRIMARY KEY AUTOINCREMENT, sku INTEGER UNIQUE, + product_type TEXT, product_id INTEGER, name TEXT, developer TEXT, @@ -14,7 +15,10 @@ CREATE TABLE IF NOT EXISTS products ( cover TEXT, release_date TEXT, genres TEXT, - price TEXT + price TEXT, + price_gg TEXT, + price_sales TEXT, + price_salesgg TEXT ) """) diff --git a/models/orders.py b/models/orders.py index 0a98cc3..83b3b6a 100644 --- a/models/orders.py +++ b/models/orders.py @@ -8,7 +8,8 @@ CREATE TABLE IF NOT EXISTS orders ( id INTEGER PRIMARY KEY AUTOINCREMENT, sku INTEGER UNIQUE, product_id INTEGER, - price TEXT + price TEXT, + content TEXT ) """) diff --git a/services/gg.py b/services/gg.py deleted file mode 100644 index f5bbca2..0000000 --- a/services/gg.py +++ /dev/null @@ -1,258 +0,0 @@ -import requests -import time -import json -import hashlib -from dotenv import load_dotenv -import os -load_dotenv() - -TOKEN = os.getenv('GGTOKEN') -SELLER_ID = os.getenv('SELLER_ID') -API_KEY = os.getenv('GGTOKEN') - - - - -TOKEN_FILE = "./files/ggsel_token.json" - - -def save_token(token): - with open(TOKEN_FILE, "w") as f: - json.dump({"token": token}, f) - - -def load_token(): - if not os.path.exists(TOKEN_FILE): - return None - - with open(TOKEN_FILE) as f: - try: - data = json.load(f) - return data.get("token") - except json.JSONDecodeError: - return None - - -def safe_json(response): - if not response.text: - raise Exception("Empty response from API") - - try: - return response.json() - except json.JSONDecodeError: - print("Invalid JSON response:") - print(response.text) - raise - - -def get_token(): - timestamp = str(int(time.time())) - sign_string = API_KEY + timestamp - sign = hashlib.sha256(sign_string.encode()).hexdigest() - - url = "https://seller.ggsel.com/api_sellers/api/apilogin" - - payload = { - "seller_id": SELLER_ID, - "timestamp": timestamp, - "sign": sign - } - - headers = { - "Content-Type": "application/json", - "Accept": "application/json" - } - - response = requests.post(url, json=payload, headers=headers) - - print(response.status_code) - res = response.json() - token = res['token'] - - save_token(token) - print(token) - return token - - -def balans(): - token = load_token() - - if not token: - token = get_token() - - url = "https://seller.ggsel.com/api_sellers/api/sellers/account/balance/info" - - headers = {"Accept": "application/json"} - params = {"token": token} - - r = requests.get(url, params=params, headers=headers) - print(r.status_code) - - # если токен умер - if r.status_code in (401, 403): - token = get_token() - params["token"] = token - r = requests.get(url, params=params, headers=headers) - - return r.json() - -def last_sales(top=10, group=False): - token = load_token() - - if not token: - token = get_token() - - url = "https://seller.ggsel.com/api_sellers/api/seller-last-sales" - - headers = { - "Accept": "application/json", - "locale": "ru" - } - - params = { - "token": token, - "seller_id": SELLER_ID, - "top": top, - "group": str(group).lower() - } - - r = requests.get(url, params=params, headers=headers) - print(r.status_code) - - # если токен умер - if r.status_code in (401, 403): - token = get_token() - params["token"] = token - r = requests.get(url, params=params, headers=headers) - - return r.json() - - -# print(last_sales()) - -def get_messages(id_i, id_from=None, id_to=None, newer=None, count=50): - token = load_token() - - if not token: - token = get_token() - - url = "https://seller.ggsel.com/api_sellers/api/debates/v2" - - headers = { - "Accept": "application/json" - } - - params = { - "token": token, - "id_i": id_i, - "count": min(count, 100) - } - - if id_from: - params["id_from"] = id_from - - if id_to: - params["id_to"] = id_to - - if newer: - params["newer"] = newer - - r = requests.get(url, params=params, headers=headers) - print(r.status_code) - - # если токен умер - if r.status_code in (401, 403): - token = get_token() - params["token"] = token - r = requests.get(url, params=params, headers=headers) - - return r.json() - - -# пример -print(get_messages(id_i=18840912)) - - -def get_chats(page=1, pagesize=20, filter_new=None, email=None, id_ds=None): - token = load_token() - - if not token: - token = get_token() - - url = "https://seller.ggsel.com/api_sellers/api/debates/v2/chats" - - headers = { - "Accept": "application/json" - } - - params = { - "token": token, - "page": page, - "pagesize": pagesize - } - - if filter_new is not None: - params["filter_new"] = filter_new - - if email: - params["email"] = email - - if id_ds: - params["id_ds"] = id_ds - - r = requests.get(url, params=params, headers=headers) - print(r.status_code) - - # если токен умер - if r.status_code in (401, 403): - token = get_token() - params["token"] = token - r = requests.get(url, params=params, headers=headers) - - return r.json() - - -# пример -# print(get_chats()) -# def tokens(): - -# timestamp = str(int(time.time())) -# sign_string = API_KEY + timestamp -# sign = hashlib.sha256(sign_string.encode()).hexdigest() - -# url = "https://seller.ggsel.com/api_sellers/api/apilogin" - -# payload = { -# "seller_id": SELLER_ID, -# "timestamp": timestamp, -# "sign": sign -# } - -# headers = { -# "Content-Type": "application/json", -# "Accept": "application/json" -# } - -# response = requests.post(url, json=payload, headers=headers) - -# print(response.status_code) -# res = response.json() -# token = res['token'] -# return token - - -# def balans(): -# url = "https://seller.ggsel.com/api_sellers/api/sellers/account/balance/info" - -# params = { -# "token": tokens() -# } - -# headers = { -# "Accept": "application/json" -# } - -# response = requests.get(url, params=params, headers=headers) - -# print(response.status_code) -# print(response.json()) \ No newline at end of file diff --git a/services/rokky.py b/services/rokky.py index 1d878d5..09122a2 100644 --- a/services/rokky.py +++ b/services/rokky.py @@ -44,21 +44,43 @@ def decrypt_file(input_file, output_file, password): print("Расшифровано:", output_file) - - -decrypt_file( - "./files/prices.json.gz.enc", - "./files/prices.json.gz", - password -) -def archive(): - with gzip.open("./files/prices.json.gz", "rb") as f_in: - with open("./files/prices.json", "wb") as f_out: + + +def decrypt_and_unpack(name, password): + enc = f"./files/{name}.json.gz.enc" + gz = f"./files/{name}.json.gz" + json_file = f"./files/{name}.json" + + decrypt_file(enc, gz, password) + + with gzip.open(gz, "rb") as f_in: + with open(json_file, "wb") as f_out: shutil.copyfileobj(f_in, f_out) + + print(f"Готово: {json_file}") + + + + +# decrypt_file( +# "./files/prices.json.gz.enc", +# "./files/prices.json.gz", +# password +# ) +# def archive(): +# with gzip.open("./files/prices.json.gz", "rb") as f_in: +# with open("./files/prices.json", "wb") as f_out: +# shutil.copyfileobj(f_in, f_out) -archive() -with open("./files/prices.json", "r", encoding="utf-8") as f: - products = json.load(f) +# archive() + + + + +def prices(): + + with open("./files/prices.json", "r", encoding="utf-8") as f: + products = json.load(f) def get_title(product, lang="RU"): for title in product["titles"]: @@ -78,6 +100,7 @@ def save_product(conn, product): INSERT INTO products ( sku, product_id, + product_type, name, developer, publisher, @@ -85,9 +108,10 @@ def save_product(conn, product): release_date, genres ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(sku) DO UPDATE SET product_id=excluded.product_id, + product_type = excluded.product_type, name=excluded.name, developer=excluded.developer, publisher=excluded.publisher, @@ -97,6 +121,7 @@ def save_product(conn, product): """, ( product["sku"], product["product_id"], + product["product_type"], product["name"], product["developer"], product["publisher"], @@ -109,6 +134,8 @@ def save_product(conn, product): def add_product(): + with open("./files/products.json", "r", encoding="utf-8") as f: + products = json.load(f) parsed_products = [] @@ -118,6 +145,7 @@ def add_product(): parsed = { "sku": product["sku"], "product_id": product["product_id"], + "product_type":product["product_type"], "name": get_title(product, "RU"), "developer": product["developer"], "publisher": product["publisher"], @@ -129,7 +157,7 @@ def add_product(): parsed_products.append(parsed) for product in parsed_products: save_product(conn, product) - # print(parsed_products[10]) + print(parsed_products[3]) print("Всего продуктов:", len(products)) @@ -152,5 +180,7 @@ def update_prices(conn): conn.commit() -# add_product() +decrypt_and_unpack("prices", password) +decrypt_and_unpack("products", password) +add_product() update_prices(conn) \ No newline at end of file