Compare commits

...

9 Commits
main ... 185

48 changed files with 783 additions and 140 deletions

Binary file not shown.

View File

@ -1,8 +1,11 @@
from dotenv import load_dotenv
import os
load_dotenv()
import sqlite3
import requests
conn = sqlite3.connect("./files/rokky.db")
partner = os.getenv('partner')
user_name = os.getenv('userName')
password = os.getenv('password')
@ -23,14 +26,15 @@ json_data = {
def tokens():
response = requests.post('https://partner.rokky.com/api/v1/tokens', headers=headers, json=json_data)
# print(response.json())
print(response.json())
data = response.json()
access_token = data["accessToken"]
return access_token
access_token = tokens()
# access_token = tokens()
def get_orders(access_token, page=1, page_size=25):
def get_orders(page=1, page_size=25):
access_token = tokens()
url = f"{BASE_URL}/orders"
headers = {
@ -78,8 +82,11 @@ def download_prices():
print("Каталог цен скачан.")
def create_order(sku, quantity, unit_price, partner_order_id):
def create_order(sku, unit_price, partner_order_id):
# try:
access_token = tokens()
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
url = f"{BASE_URL}/orders"
headers = {
@ -91,7 +98,7 @@ def create_order(sku, quantity, unit_price, partner_order_id):
"items": [
{
"sku": int(sku),
"quantity": int(quantity),
"quantity": 1,
"unitPrice": float(unit_price)
}
],
@ -117,7 +124,18 @@ def create_order(sku, quantity, unit_price, partner_order_id):
response.raise_for_status() # Всё равно выбрасываем исключение
return response.json()
r = response.json()
order_id = r["orderId"]
print(partner_order_id)
print(order_id)
cursor.execute("""
UPDATE orders
SET orders_rokky = ?
WHERE id_i = ?
""", (order_id, partner_order_id))
conn.commit()
conn.close()
except requests.exceptions.RequestException as e:
print(f"🌐 Сетевая ошибка: {e}")
@ -127,6 +145,7 @@ def create_order(sku, quantity, unit_price, partner_order_id):
# return response.json()
def get_orders(page=1, page_size=25):
access_token = tokens()
url = f"{BASE_URL}/orders"
headers = {
@ -146,6 +165,10 @@ def get_orders(page=1, page_size=25):
def get_order_content(order_id):
access_token = tokens()
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
url = f"{BASE_URL}/orders/{order_id}/content"
headers = {
@ -156,20 +179,31 @@ def get_order_content(order_id):
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
con = data['orderContentItems']
for c in con:
content = c['content']
cursor.execute("""
UPDATE orders
SET key = ?
WHERE orders_rokky = ?
""", (content, order_id))
conn.commit()
conn.close()
return content
# content = get_order_content(5379499)
# content = get_order_content(5390872)
# print(content)
# orders = get_orders()
# print(orders)
# order = create_order(22774, 1, 21.3, "my-test-order-12w3")
# order = create_order(2197, 0.13, "sss22289522")
# print(order)

View File

@ -16,6 +16,42 @@ password = os.getenv('password')
conn = sqlite3.connect("./files/rokky.db")
def update_prices():
with open("./files/prices.json", "r") as f:
prices = json.load(f)
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
data = []
for item in prices:
sku = item["sku"]
price = item.get("price")
price_gg = item.get("baseSuggestedRetailPrice")
price_sales = item.get("discountPercentage")
is_sale = item.get("isSale")
data.append((
price,
price_gg,
price_sales,
is_sale,
sku,
))
cursor.executemany("""
UPDATE products
SET
price = ?,
price_gg = ?,
price_sales = ?,
insale = ?
WHERE sku = ?
""", data)
print("Обновил цены")
conn.commit()
def decrypt_file(input_file, output_file, password):
with open(input_file, "rb") as f:
encrypted = f.read()
@ -56,8 +92,10 @@ def decrypt_and_unpack(name):
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}")
@ -94,6 +132,7 @@ def get_genres(product):
def save_product(conn, product):
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
cursor.execute("""
@ -164,39 +203,7 @@ def add_product():
def update_prices():
with open("./files/prices.json", "r") as f:
prices = json.load(f)
cursor = conn.cursor()
data = []
for item in prices:
sku = item["sku"]
price = item.get("basePrice")
price_gg = item.get("baseSuggestedRetailPrice")
price_sales =item.get("discountPercentage")
is_sale = item.get("isSale")
data.append((
price,
price_gg,
price_sales,
is_sale,
sku
))
cursor.executemany("""
UPDATE products
SET
price = ?,
price_gg = ?,
price_sales = ?,
insale = ?
WHERE sku = ?
""", data)
conn.commit()
# decrypt_and_unpack("prices")
# decrypt_and_unpack("products")

View File

@ -1,29 +1,29 @@
FROM python:3.12-slim-bookworm
# The installer requires curl (and certificates) to download the release archive
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates nano
# Download the latest installer
ADD https://astral.sh/uv/install.sh /uv-installer.sh
# Run the installer then remove it
RUN sh /uv-installer.sh && rm /uv-installer.sh
# Ensure the installed binary is on the `PATH`
ENV PATH="/root/.local/bin/:$PATH"
# Copy the project into the image
ADD . /app
# Sync the project into a new environment, using the frozen lockfile
WORKDIR /app
RUN uv sync --frozen
# Expose port 8000
EXPOSE 5205
# Presuming there is a `my_app` command provided by the project uvicorn main:app --reload
FROM python:3.12-slim-bookworm
# The installer requires curl (and certificates) to download the release archive
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates nano
# Download the latest installer
ADD https://astral.sh/uv/install.sh /uv-installer.sh
# Run the installer then remove it
RUN sh /uv-installer.sh && rm /uv-installer.sh
# Ensure the installed binary is on the `PATH`
ENV PATH="/root/.local/bin/:$PATH"
# Copy the project into the image
ADD . /app
# Sync the project into a new environment, using the frozen lockfile
WORKDIR /app
RUN uv sync --frozen
# Expose port 8000
EXPOSE 5205
# Presuming there is a `my_app` command provided by the project uvicorn main:app --reload
CMD ["uv", "run", "main.py"]

View File

@ -4,9 +4,13 @@ import os
import sqlite3
import json
# from services.rokky import ones
from API.rok import create_order
from API.rok import create_order, get_order_content, get_orders
from API.TG import send_telegram
from services.orders import get_sku
from services.gg import get_product, create_messagea
from services.send_mai import send_html_flow
# from services.orders_rokky import rok_orders
import logging
@ -18,7 +22,9 @@ IMAGE_FOLDER = os.path.join(BASE_DIR, 'images')
@main.route("/")
def index():
return "Hello wstkeys!!!"
print(get_orders())
return "Hello wstkeys! Hello1"
@main.route("/images/<filename>")
def get_image(filename):
@ -26,21 +32,30 @@ def get_image(filename):
@main.route("/orders/api_payments", methods=["POST", "GET"])
def index1():
DB_PATH = "./files/rokky.db"
# Получаем все GET-параметры
params = request.args.to_dict()
logging.warn(f"newOrder: {params}")
# Просто выводим на экран (в ответ клиенту)
# парсим данные
sku = params.get("id_d")
product_id = params.get("id_i")
id_d = params.get("id_d")
id_i = params.get("id_i")
email = params.get("email")
price = params.get("amount")
amount = params.get("amount")
currency = params.get("currency")
date = params.get("date")
# всё остальное сохраняем как JSON
content = json.dumps(params, ensure_ascii=False)
db_sku, db_price = get_sku(sku)
create_order(db_sku, price, db_price, f"my-test-order-{product_id}")
# send_telegram(content)
send_telegram(content)
message = f"🔹 Спасибо за покупку в WST Keys (West Store Trusted Keys)\n\n⏳ Ваш заказ обрабатывается и будет доставлен автоматически"
create_messagea(id_i, message)
#
sku_rokky, price_rokky = get_sku(id_d)
send_telegram(content)
name_p, im = get_product(id_d)
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
@ -48,9 +63,9 @@ def index1():
try:
cursor.execute("""
INSERT INTO orders (sku, product_id, email, price, content)
VALUES (?, ?, ?, ?, ?)
""", (sku, product_id, email, price, content))
INSERT INTO orders (id_i, id_d, email,name_p, im, amount, content, currency, date, sku_rokky, price_rokky)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)
""", (id_i, id_d, email, name_p, im, amount, content, currency, date, sku_rokky, price_rokky))
conn.commit()
except Exception as e:
@ -58,18 +73,17 @@ def index1():
return jsonify({"error": str(e)}), 500
conn.close()
send_telegram(create_order(sku_rokky, price_rokky, id_i))
return jsonify({"success": True}), 200
# return "Hello GET"
@main.route("/sales", methods=["POST", "GET"])
def index2():
return "Hello GET!!!++!!ss"
@main.route("/newOrder", methods=["POST"])
def new_order():
if not request.is_json:
return jsonify({"error": "Invalid content type"}), 400
@ -84,9 +98,13 @@ def new_order():
# TODO: обработка заказа
print(f"New order received: {order_id}")
send_telegram(data)
# logging.warn(get_order_content(order_id))
send_telegram(order_id)
logging.warn(f"newOrder: {order_id}")
# get_order_content(int(order_id))
send_html_flow(order_id)
return jsonify({"status": "ok"}), 200
@ -119,7 +137,7 @@ def sku():
def product_update():
# получаем параметры
sku = request.args.get("rokky")
ggsale = request.args.get("ggsale")
ggsale = request.args.get("ggsel")
if not sku or not ggsale:
return jsonify({"error": "Missing parameters"}), 400

View File

@ -17,6 +17,7 @@ services:
web:
build: .
container_name: flask-dev
privileged: true # ✅ Даёт все права
ports:
- "5205:5205" # Пробрасываем порт наружу
volumes:
@ -25,4 +26,12 @@ services:
- .:/app
environment:
- FLASK_DEBUG=1 # Дополнительная страховка для включения дебага
- PYTHONUNBUFFERED=1 # Чтобы логи выводились сразу, а не кэшировались
- PYTHONUNBUFFERED=1 # Чтобы логи выводились сразу, а не кэшировались
- eKCPpyzkcCTS=${eKCPpyzkcCTS:-}
restart: always
cap_add:
- NET_ADMIN
- SYS_MODULE
devices:
- /dev/net/tun:/dev/net/tun
depends_on: []

9
models/del_s.py Normal file
View File

@ -0,0 +1,9 @@
import sqlite3
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
cursor.execute("DROP TABLE IF EXISTS orders")
conn.commit()
conn.close()

View File

@ -6,10 +6,19 @@ cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sku INTEGER UNIQUE,
product_id INTEGER,
id_i INTEGER UNIQUE,
id_d INTEGER,
name_p TEXT,
im TEXT,
email TEXT,
price TEXT,
chat_id TEXT,
currency TEXT,
amount TEXT,
date TEXT,
sku_rokky TEXT,
price_rokky TEXT,
orders_rokky TEXT,
key TEXT,
content TEXT
)
""")

View File

@ -0,0 +1 @@
{"creation_dt": "2026-03-19T08:29:34Z", "creation_host": "c9d15910341c"}

View File

@ -0,0 +1 @@
{"n": "yBq2Uju0sDvIcExzaLnTOt-Kf0lyH8lUhTZ1qS7bOSS2mUiFySawp0ONluxJmeyq1oNoMEKb_TS3047fh6argtGL9Ty5LziCrUHsSPzsJeEK7viMu7bjVRjpPRyRk-TggK0H1NLObKkyNlOWDA8wWbFvNcoddhzvpeMeVMFy1jpBYXDTJc8GvPgv0ubs2zTaYplu6ru9TWNd8QkESdhm6DH_iU1Ph4ALtPRIIbF43xi8GHlSYnbDTKqVNph-i0tIymXCbIMvR-dNMsjA4VuoQeiu9-lKEAT1ytapKshTzOl9cIPpbD3e_70tx5BKtL1L-o3rn4g2zNuWpEPgBhQJ4w", "e": "AQAB", "d": "Eh0c6Pe_pP5caBH7lnzPyrIGmvweiRMUBBUIdJ6puJQCtYBzn-BROGrsi79q8DSUyGNP0KKO9U5K36s8v85OE0L9vN7Y0pX2elGP3pGKnOkwsK4uKyXkkUT2hBIseWtMCUngfhrxFbQBOBq75-6ODWh67S8VGKaI6QbUrY5vY0XsocU4fARL2WihenO9Rajkz0MbvEzRePksAySKelJYLbR8h7I5PX0WxuJaekkzaGf1XeboWCCxZ_DVcwEBp9xGeignLmCrKNkwta6hqRCB5vgIyCUoybuyjr95tSYuC5iN-LDFN2rzg0T4xNw2Z8dxuyah5mpw75G-umo0WRhAaQ", "p": "9Dx8RANkz70StHJEKuLXN-ElexVnOHwXVjGACp97sSykY_3GdE7cHO2iz9HYibH1oyS7ycvzkfJPbFwoZ4gM2k7EM6mQgDB9M76sHDjzzBDAZAQVyNNrW5DH1H3rtMcRFc2ZWX5knY8sdKP5g5QvsQCdI0eS5p_RaWHDxi03qAs", "q": "0b4Qv39qzZz-GuhGbI4Np1T8-26arCNduSeSkkdmgWMQBlaymACt7ryRV1DrItisLhTC8EJoSTXWy5C8ZcVjZfwh67A0cjmC2DwQapaTnilvl0JdmDLDDyDVhtLMIPEmSqCpcx3vORoRSxY2beOQaOpu6gAK6s-mlyXvxG-m1Ik", "dp": "kKTlv233HWTPmBh4MKHpbgmkJfH2EKjFNWHZf_EV00cqEKHyD13I1EUUgFm6EUpYvIb7xDZKiSvlR7qIn1AetIejgSkyEAknjSamTYyZLkjZeCJHOImlcjQbdMgieQzQHIaIBE1rjziEzotyMS_o0r4XUhaIdJc_8VZaGJsc9CM", "dq": "FUAckkpml86AMFm4SOdbmsiRmSfro-UxacEIqKlzSUiwJvRBxATNmpKgZyhbqnwpdcHEvnL7_e7mhFl1vRnyqDKTfT2tEqWhDCeJwkLfUfcAx2KB-RmriazZ9X8GD5BfQNBmWrN9uVtaxTDK8vdLelXGRw8aDBBd4JKHaG-nh4E", "qi": "A8sTN4oiNeWkKX-rWr1LGJ_VfvCX4nBQ_Psa24HWJnWk6ATNcnf8otZCXAssNeb-vwBrBqy09C5ynX8k3w1OBcWKh12mBezhUPvPAHfeazfGNZTPYKDpn80uTsd0RZaDvmisJW6Obwh9Thorqkstnc2VypPUom66mx-fMjgF90M", "kty": "RSA"}

View File

@ -0,0 +1 @@
{"body": {}, "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/3159531281"}

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDizCCAxGgAwIBAgISBRYz4Bp7cHMTbq0c38ztlZeeMAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
NzAeFw0yNjAzMTkwNzMyNDVaFw0yNjA2MTcwNzMyNDRaMBYxFDASBgNVBAMTC3dz
dGtleXMudG9wMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEryQBD4A2GWx5ULjC
MVzq3ZWtNPs+pn7MJdxMDrow8iUGXwziGnx/wxBpbclZX/YpMNEI3P0bz3EYY/AA
FqS93KOCAiEwggIdMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSQJvBEWpjHj8hKAPwf0c+cs46v3DAf
BgNVHSMEGDAWgBSuSJ7chx1EoG/aouVgdAR4wpwAgDAyBggrBgEFBQcBAQQmMCQw
IgYIKwYBBQUHMAKGFmh0dHA6Ly9lNy5pLmxlbmNyLm9yZy8wJwYDVR0RBCAwHoIL
d3N0a2V5cy50b3CCD3d3dy53c3RrZXlzLnRvcDATBgNVHSAEDDAKMAgGBmeBDAEC
ATAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vZTcuYy5sZW5jci5vcmcvMzEuY3Js
MIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHYAyzj3FYl8hKFEX1vB3fvJbvKaWc1H
CmkFhbDLFMMUWOcAAAGdBThnlAAABAMARzBFAiAjcv9Q+47Trx1Fe7suICYtcGOo
6djSjFXh/D1GYMEs0AIhAOGS/AK6bbruaDxI6andmUmT5xOp74iEb2ruMiXL/Syu
AHcADleUvPOuqT4zGyyZB7P3kN+bwj1xMiXdIaklrGHFTiEAAAGdBThngwAABAMA
SDBGAiEA+w9/Fhyj/90p6oZwHueRBNBy3J9bPw3iV9GRDihRhMoCIQDsajI6Rqw/
aAwKk973OcO5AMrscxas1srtCAy91UUz4jAKBggqhkjOPQQDAwNoADBlAjEAzkMS
iMiP9sxr4EIizawwqDCN/8JAI4tezI0ApN4RLZOjHPbi7enMKmR3MAs/NfZzAjBG
LqlZPyjCJGtH6Mhrlit600hhdwO5xy0NEYtwfduqZ27uEYoA+evnixMohcEL5VA=
-----END CERTIFICATE-----

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDijCCAw+gAwIBAgISBkwIWOQucqJm2bNjQTqXfH08MAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
NzAeFw0yNjAzMTkwNzM0NDVaFw0yNjA2MTcwNzM0NDRaMBYxFDASBgNVBAMTC3dz
dGtleXMudG9wMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECLsDi9ZXQt5hZbjc
TKJYPY/kIdDAMgCqnrt4tV78AnGf+xIolYA96sPc+RRDQWoHgpT3e++wHxqNDkT5
wBaegaOCAh8wggIbMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQxgifvZUFsI6vK/RxK5tZImjRkijAf
BgNVHSMEGDAWgBSuSJ7chx1EoG/aouVgdAR4wpwAgDAyBggrBgEFBQcBAQQmMCQw
IgYIKwYBBQUHMAKGFmh0dHA6Ly9lNy5pLmxlbmNyLm9yZy8wJwYDVR0RBCAwHoIL
d3N0a2V5cy50b3CCD3d3dy53c3RrZXlzLnRvcDATBgNVHSAEDDAKMAgGBmeBDAEC
ATAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vZTcuYy5sZW5jci5vcmcvNjEuY3Js
MIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHUAlpdkv1VYl633Q4doNwhCd+nwOtX2
pPM2bkakPw/KqcYAAAGdBTo6vAAABAMARjBEAiBPmlA/U/CZOVdw/3rJN3hH9+jA
TBihCfnrSMdNC1xWQAIgNE1FOpS2PURTh8jP6Tu8jytR1x9X2g986d4reUyMqEwA
dgDRbqmlaAd+ZjWgPzel3bwDpTxBEhTUiBj16TGzI8uVBAAAAZ0FOjtiAAAEAwBH
MEUCIQCFS+VZqF0mkieuw5YkmxJcC7pq5Gr6KxDs3pq44hfbfAIgFkQYYNoTOLBJ
Cbrzz4sVB40E06n+rfKFZ/k5fCz/FS4wCgYIKoZIzj0EAwMDaQAwZgIxAL5J/AeW
g+PSdeF3Ndfp5TTl1lzFcAxFMgm68jlk4eAC+I4u9ZYyhKxpeNIonG6utgIxAPCF
LEvxoUCvlUIbmFV6xk+MQn6/FKuaYyRMBHObM5hsSZI7DkH44RRM2/9DIWX6bw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRAKp18eYrjwoiCWbTi7/UuqEwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCRTcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB6AST
CFh/vjcwDMCgQer+VtqEkz7JANurZxLP+U9TCeioL6sp5Z8VRvRbYk4P1INBmbef
QHJFHCxcSjKmwtvGBWpl/9ra8HW0QDsUaJW2qOJqceJ0ZVFT3hbUHifBM/2jgfgw
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSuSJ7chx1EoG/aouVgdAR4
wpwAgDAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAjx66fDdLk5ywFn3CzA1w1qfylHUD
aEf0QZpXcJseddJGSfbUUOvbNR9N/QQ16K1lXl4VFyhmGXDT5Kdfcr0RvIIVrNxF
h4lqHtRRCP6RBRstqbZ2zURgqakn/Xip0iaQL0IdfHBZr396FgknniRYFckKORPG
yM3QKnd66gtMst8I5nkRQlAg/Jb+Gc3egIvuGKWboE1G89NTsN9LTDD3PLj0dUMr
OIuqVjLB8pEC6yk9enrlrqjXQgkLEYhXzq7dLafv5Vkig6Gl0nuuqjqfp0Q1bi1o
yVNAlXe6aUXw92CcghC9bNsKEO1+M52YY5+ofIXlS/SEQbvVYYBLZ5yeiglV6t3S
M6H+vTG0aP9YHzLn/KVOHzGQfXDP7qM5tkf+7diZe7o2fw6O7IvN6fsQXEQQj8TJ
UXJxv2/uJhcuy/tSDgXwHM8Uk34WNbRT7zGTGkQRX0gsbjAea/jYAoWv0ZvQRwpq
Pe79D/i7Cep8qWnA+7AE/3B3S/3dEEYmc0lpe1366A/6GEgk3ktr9PEoQrLChs6I
tu3wnNLB2euC8IKGLQFpGtOO/2/hiAKjyajaBP25w1jF0Wl8Bbqne3uZ2q1GyPFJ
YRmT7/OXpmOH/FVLtwS+8ng1cAmpCujPwteJZNcDG0sF2n/sc0+SQf49fdyUK0ty
+VUwFj9tmWxyR/M=
-----END CERTIFICATE-----

View File

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRAKp18eYrjwoiCWbTi7/UuqEwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCRTcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB6AST
CFh/vjcwDMCgQer+VtqEkz7JANurZxLP+U9TCeioL6sp5Z8VRvRbYk4P1INBmbef
QHJFHCxcSjKmwtvGBWpl/9ra8HW0QDsUaJW2qOJqceJ0ZVFT3hbUHifBM/2jgfgw
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSuSJ7chx1EoG/aouVgdAR4
wpwAgDAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAjx66fDdLk5ywFn3CzA1w1qfylHUD
aEf0QZpXcJseddJGSfbUUOvbNR9N/QQ16K1lXl4VFyhmGXDT5Kdfcr0RvIIVrNxF
h4lqHtRRCP6RBRstqbZ2zURgqakn/Xip0iaQL0IdfHBZr396FgknniRYFckKORPG
yM3QKnd66gtMst8I5nkRQlAg/Jb+Gc3egIvuGKWboE1G89NTsN9LTDD3PLj0dUMr
OIuqVjLB8pEC6yk9enrlrqjXQgkLEYhXzq7dLafv5Vkig6Gl0nuuqjqfp0Q1bi1o
yVNAlXe6aUXw92CcghC9bNsKEO1+M52YY5+ofIXlS/SEQbvVYYBLZ5yeiglV6t3S
M6H+vTG0aP9YHzLn/KVOHzGQfXDP7qM5tkf+7diZe7o2fw6O7IvN6fsQXEQQj8TJ
UXJxv2/uJhcuy/tSDgXwHM8Uk34WNbRT7zGTGkQRX0gsbjAea/jYAoWv0ZvQRwpq
Pe79D/i7Cep8qWnA+7AE/3B3S/3dEEYmc0lpe1366A/6GEgk3ktr9PEoQrLChs6I
tu3wnNLB2euC8IKGLQFpGtOO/2/hiAKjyajaBP25w1jF0Wl8Bbqne3uZ2q1GyPFJ
YRmT7/OXpmOH/FVLtwS+8ng1cAmpCujPwteJZNcDG0sF2n/sc0+SQf49fdyUK0ty
+VUwFj9tmWxyR/M=
-----END CERTIFICATE-----

View File

@ -0,0 +1,47 @@
-----BEGIN CERTIFICATE-----
MIIDizCCAxGgAwIBAgISBRYz4Bp7cHMTbq0c38ztlZeeMAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
NzAeFw0yNjAzMTkwNzMyNDVaFw0yNjA2MTcwNzMyNDRaMBYxFDASBgNVBAMTC3dz
dGtleXMudG9wMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEryQBD4A2GWx5ULjC
MVzq3ZWtNPs+pn7MJdxMDrow8iUGXwziGnx/wxBpbclZX/YpMNEI3P0bz3EYY/AA
FqS93KOCAiEwggIdMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSQJvBEWpjHj8hKAPwf0c+cs46v3DAf
BgNVHSMEGDAWgBSuSJ7chx1EoG/aouVgdAR4wpwAgDAyBggrBgEFBQcBAQQmMCQw
IgYIKwYBBQUHMAKGFmh0dHA6Ly9lNy5pLmxlbmNyLm9yZy8wJwYDVR0RBCAwHoIL
d3N0a2V5cy50b3CCD3d3dy53c3RrZXlzLnRvcDATBgNVHSAEDDAKMAgGBmeBDAEC
ATAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vZTcuYy5sZW5jci5vcmcvMzEuY3Js
MIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHYAyzj3FYl8hKFEX1vB3fvJbvKaWc1H
CmkFhbDLFMMUWOcAAAGdBThnlAAABAMARzBFAiAjcv9Q+47Trx1Fe7suICYtcGOo
6djSjFXh/D1GYMEs0AIhAOGS/AK6bbruaDxI6andmUmT5xOp74iEb2ruMiXL/Syu
AHcADleUvPOuqT4zGyyZB7P3kN+bwj1xMiXdIaklrGHFTiEAAAGdBThngwAABAMA
SDBGAiEA+w9/Fhyj/90p6oZwHueRBNBy3J9bPw3iV9GRDihRhMoCIQDsajI6Rqw/
aAwKk973OcO5AMrscxas1srtCAy91UUz4jAKBggqhkjOPQQDAwNoADBlAjEAzkMS
iMiP9sxr4EIizawwqDCN/8JAI4tezI0ApN4RLZOjHPbi7enMKmR3MAs/NfZzAjBG
LqlZPyjCJGtH6Mhrlit600hhdwO5xy0NEYtwfduqZ27uEYoA+evnixMohcEL5VA=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRAKp18eYrjwoiCWbTi7/UuqEwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCRTcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB6AST
CFh/vjcwDMCgQer+VtqEkz7JANurZxLP+U9TCeioL6sp5Z8VRvRbYk4P1INBmbef
QHJFHCxcSjKmwtvGBWpl/9ra8HW0QDsUaJW2qOJqceJ0ZVFT3hbUHifBM/2jgfgw
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSuSJ7chx1EoG/aouVgdAR4
wpwAgDAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAjx66fDdLk5ywFn3CzA1w1qfylHUD
aEf0QZpXcJseddJGSfbUUOvbNR9N/QQ16K1lXl4VFyhmGXDT5Kdfcr0RvIIVrNxF
h4lqHtRRCP6RBRstqbZ2zURgqakn/Xip0iaQL0IdfHBZr396FgknniRYFckKORPG
yM3QKnd66gtMst8I5nkRQlAg/Jb+Gc3egIvuGKWboE1G89NTsN9LTDD3PLj0dUMr
OIuqVjLB8pEC6yk9enrlrqjXQgkLEYhXzq7dLafv5Vkig6Gl0nuuqjqfp0Q1bi1o
yVNAlXe6aUXw92CcghC9bNsKEO1+M52YY5+ofIXlS/SEQbvVYYBLZ5yeiglV6t3S
M6H+vTG0aP9YHzLn/KVOHzGQfXDP7qM5tkf+7diZe7o2fw6O7IvN6fsQXEQQj8TJ
UXJxv2/uJhcuy/tSDgXwHM8Uk34WNbRT7zGTGkQRX0gsbjAea/jYAoWv0ZvQRwpq
Pe79D/i7Cep8qWnA+7AE/3B3S/3dEEYmc0lpe1366A/6GEgk3ktr9PEoQrLChs6I
tu3wnNLB2euC8IKGLQFpGtOO/2/hiAKjyajaBP25w1jF0Wl8Bbqne3uZ2q1GyPFJ
YRmT7/OXpmOH/FVLtwS+8ng1cAmpCujPwteJZNcDG0sF2n/sc0+SQf49fdyUK0ty
+VUwFj9tmWxyR/M=
-----END CERTIFICATE-----

View File

@ -0,0 +1,47 @@
-----BEGIN CERTIFICATE-----
MIIDijCCAw+gAwIBAgISBkwIWOQucqJm2bNjQTqXfH08MAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
NzAeFw0yNjAzMTkwNzM0NDVaFw0yNjA2MTcwNzM0NDRaMBYxFDASBgNVBAMTC3dz
dGtleXMudG9wMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECLsDi9ZXQt5hZbjc
TKJYPY/kIdDAMgCqnrt4tV78AnGf+xIolYA96sPc+RRDQWoHgpT3e++wHxqNDkT5
wBaegaOCAh8wggIbMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQxgifvZUFsI6vK/RxK5tZImjRkijAf
BgNVHSMEGDAWgBSuSJ7chx1EoG/aouVgdAR4wpwAgDAyBggrBgEFBQcBAQQmMCQw
IgYIKwYBBQUHMAKGFmh0dHA6Ly9lNy5pLmxlbmNyLm9yZy8wJwYDVR0RBCAwHoIL
d3N0a2V5cy50b3CCD3d3dy53c3RrZXlzLnRvcDATBgNVHSAEDDAKMAgGBmeBDAEC
ATAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vZTcuYy5sZW5jci5vcmcvNjEuY3Js
MIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHUAlpdkv1VYl633Q4doNwhCd+nwOtX2
pPM2bkakPw/KqcYAAAGdBTo6vAAABAMARjBEAiBPmlA/U/CZOVdw/3rJN3hH9+jA
TBihCfnrSMdNC1xWQAIgNE1FOpS2PURTh8jP6Tu8jytR1x9X2g986d4reUyMqEwA
dgDRbqmlaAd+ZjWgPzel3bwDpTxBEhTUiBj16TGzI8uVBAAAAZ0FOjtiAAAEAwBH
MEUCIQCFS+VZqF0mkieuw5YkmxJcC7pq5Gr6KxDs3pq44hfbfAIgFkQYYNoTOLBJ
Cbrzz4sVB40E06n+rfKFZ/k5fCz/FS4wCgYIKoZIzj0EAwMDaQAwZgIxAL5J/AeW
g+PSdeF3Ndfp5TTl1lzFcAxFMgm68jlk4eAC+I4u9ZYyhKxpeNIonG6utgIxAPCF
LEvxoUCvlUIbmFV6xk+MQn6/FKuaYyRMBHObM5hsSZI7DkH44RRM2/9DIWX6bw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRAKp18eYrjwoiCWbTi7/UuqEwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCRTcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB6AST
CFh/vjcwDMCgQer+VtqEkz7JANurZxLP+U9TCeioL6sp5Z8VRvRbYk4P1INBmbef
QHJFHCxcSjKmwtvGBWpl/9ra8HW0QDsUaJW2qOJqceJ0ZVFT3hbUHifBM/2jgfgw
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSuSJ7chx1EoG/aouVgdAR4
wpwAgDAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAjx66fDdLk5ywFn3CzA1w1qfylHUD
aEf0QZpXcJseddJGSfbUUOvbNR9N/QQ16K1lXl4VFyhmGXDT5Kdfcr0RvIIVrNxF
h4lqHtRRCP6RBRstqbZ2zURgqakn/Xip0iaQL0IdfHBZr396FgknniRYFckKORPG
yM3QKnd66gtMst8I5nkRQlAg/Jb+Gc3egIvuGKWboE1G89NTsN9LTDD3PLj0dUMr
OIuqVjLB8pEC6yk9enrlrqjXQgkLEYhXzq7dLafv5Vkig6Gl0nuuqjqfp0Q1bi1o
yVNAlXe6aUXw92CcghC9bNsKEO1+M52YY5+ofIXlS/SEQbvVYYBLZ5yeiglV6t3S
M6H+vTG0aP9YHzLn/KVOHzGQfXDP7qM5tkf+7diZe7o2fw6O7IvN6fsQXEQQj8TJ
UXJxv2/uJhcuy/tSDgXwHM8Uk34WNbRT7zGTGkQRX0gsbjAea/jYAoWv0ZvQRwpq
Pe79D/i7Cep8qWnA+7AE/3B3S/3dEEYmc0lpe1366A/6GEgk3ktr9PEoQrLChs6I
tu3wnNLB2euC8IKGLQFpGtOO/2/hiAKjyajaBP25w1jF0Wl8Bbqne3uZ2q1GyPFJ
YRmT7/OXpmOH/FVLtwS+8ng1cAmpCujPwteJZNcDG0sF2n/sc0+SQf49fdyUK0ty
+VUwFj9tmWxyR/M=
-----END CERTIFICATE-----

View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgorFGbpc7J0PQoiQ3
1TLMzFZr5j6udFmO+ubn0sd0sfOhRANCAASvJAEPgDYZbHlQuMIxXOrdla00+z6m
fswl3EwOujDyJQZfDOIafH/DEGltyVlf9ikw0Qjc/RvPcRhj8AAWpL3c
-----END PRIVATE KEY-----

View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsi25k5YNZWoobY+
5Em3YEW2JC0GBqGee2Z+DAX15QWhRANCAAQIuwOL1ldC3mFluNxMolg9j+Qh0MAy
AKqeu3i1XvwCcZ/7EiiVgD3qw9z5FENBageClPd777AfGo0ORPnAFp6B
-----END PRIVATE KEY-----

View File

@ -0,0 +1,14 @@
This directory contains your keys and certificates.
`[cert name]/privkey.pem` : the private key for your certificate.
`[cert name]/fullchain.pem`: the certificate file used in most server software.
`[cert name]/chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
`[cert name]/cert.pem` : will break many server configurations, and should not be used
without reading further documentation (see link below).
WARNING: DO NOT MOVE OR RENAME THESE FILES!
Certbot expects these files to remain in this location in order
to function properly!
We recommend not moving these files. For more information, see the Certbot
User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.

View File

@ -0,0 +1,14 @@
This directory contains your keys and certificates.
`privkey.pem` : the private key for your certificate.
`fullchain.pem`: the certificate file used in most server software.
`chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
`cert.pem` : will break many server configurations, and should not be used
without reading further documentation (see link below).
WARNING: DO NOT MOVE OR RENAME THESE FILES!
Certbot expects these files to remain in this location in order
to function properly!
We recommend not moving these files. For more information, see the Certbot
User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.

View File

@ -0,0 +1 @@
../../archive/wstkeys.top/cert2.pem

View File

@ -0,0 +1 @@
../../archive/wstkeys.top/chain2.pem

View File

@ -0,0 +1 @@
../../archive/wstkeys.top/fullchain2.pem

View File

@ -0,0 +1 @@
../../archive/wstkeys.top/privkey2.pem

View File

@ -0,0 +1,17 @@
version = 5.4.0
archive_dir = /etc/letsencrypt/archive/wstkeys.top
cert = /etc/letsencrypt/live/wstkeys.top/cert.pem
privkey = /etc/letsencrypt/live/wstkeys.top/privkey.pem
chain = /etc/letsencrypt/live/wstkeys.top/chain.pem
fullchain = /etc/letsencrypt/live/wstkeys.top/fullchain.pem
[renewalparams]
account = 826d0805fbbb9268ecf8b23b8c211217
authenticator = webroot
webroot_path = /var/www/certbot,
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsa
[[webroot_map]]
wstkeys.top = /var/www/certbot
www.wstkeys.top = /var/www/certbot
[acme_renewal_info]
ari_retry_after = 2026-03-19T14:46:28

16
nginx/conf.d/default.conf Normal file
View File

@ -0,0 +1,16 @@
server {
listen 80;
server_name wstkeys.top www.wstkeys.top;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
proxy_pass http://host.docker.internal:5205;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View File

@ -212,9 +212,9 @@ def get_chats(page=1, pagesize=20, filter_new=None, email=None, id_ds=None):
return r.json()
def get_product():
def get_product(product_id):
token = load_token()
product_id = 102182541
# product_id = 102180432
url = f"https://seller.ggsel.com/api_sellers/api/products/{product_id}/data"
@ -229,10 +229,14 @@ def get_product():
r = requests.get(url, headers=headers, params=params)
print(r.status_code)
return r.json()
prud = r.json()
name = prud["product"]["name"]
im = prud["product"]["preview_imgs"][0]["url"]
return name, im
# return r.json()
# print(get_product())
# print(get_product(102184895))
def create_message(id_i: int):
@ -268,10 +272,91 @@ def create_message(id_i: int):
}
# пример вызова
create_message(18094706)
# create_message(18094706)
def create_messagea(id_i: int, message):
print("SEND MESSAGE CALLED", id_i)
token = load_token()
# message = "Спасибо за покупку в WST Keys"
url = "https://seller.ggsel.com/api_sellers/api/debates/v2"
params = {
"token": token,
"id_i": id_i
}
payload = {
"message": message
}
r = requests.post(url, params=params, json=payload)
print("STATUS:", r.status_code)
return r.text
# message = f"🔹Спасибо за покупку в WST Keys (West Store Trusted Keys)\n\n"
# create_messagea(22289522, message)
# пример
# print(get_chats())
def get_chats_by_email(email):
token = load_token()
message = (
f""
)
url = "https://seller.ggsel.com/api_sellers/api/debates/v2/chats"
params = {
"token": token,
'email': email,
'pagesize': 100,
'page': 1
}
payload = {
"message": message
}
r = requests.get(url, params=params)
print(r.text)
if r.status_code == 200:
return {"success": True}
return {
"success": False,
"status": r.status_code,
"response": r.text
}
# get_chats_by_email('fenomenplayerok@gmail.com')
def get_order_info(invoice_id: int, locale: str = "ru"):
token = load_token()
url = f"https://seller.ggsel.com/api_sellers/api/purchase/info/{invoice_id}"
headers = {
"Accept": "application/json",
"locale": locale
}
params = {
"token": token
}
r = requests.get(url, headers=headers, params=params)
return r.json() # или r.text если нужен сырой ответ
# # пример использования
# invoice_id = 22228752
# info = get_order_info(invoice_id)
# print(info)
# print(get_chats(email='fenomenplayerok@gmail.com'))
# def tokens():
# timestamp = str(int(time.time()))
@ -313,4 +398,24 @@ create_message(18094706)
# response = requests.get(url, params=params, headers=headers)
# print(response.status_code)
# print(response.json())
# print(response.json())
# def create_debate(order_id):
# token = load_token()
# url = "https://seller.ggsel.com/api_sellers/api/debates/v2"
# params = {
# "token": token,
# "id_i": order_id
# }
# json = {
# "message": "Спасибо за покупку в WST Keys"
# }
# r = requests.post(url, params=params, json=json)
# return r.json()
# print(create_debate("22257737"))

View File

@ -3,7 +3,7 @@ import smtplib
from email.message import EmailMessage
from dotenv import load_dotenv
from utils import build_items_html, build_keys_html, render_template
from services.utils import build_items_html, build_keys_html, render_template
load_dotenv()

58
services/orders_rokky.py Normal file
View File

@ -0,0 +1,58 @@
import sqlite3
from API.rok import get_order_content
import requests
# from send_mai import send_html_flow
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
def rok_orders():
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
cursor.execute("""
SELECT * FROM orders
WHERE key IS NULL OR key = ''
""")
rows = cursor.fetchall()
for row in rows:
order_id = row[12] # ✅ id (а не 12!)
id_i = row[1]
print(f"Обработка заказа {order_id}")
try:
# пример:
new_key = get_order_content(int(order_id))
cursor.execute("""
UPDATE orders
SET key = ?
WHERE id = ?
""", (new_key, order_id))
url = "https://wstkeys.top/newOrder"
# url = "http://0.0.0.0:5205/newOrder"
payload = {"orderId": int(order_id), "partnerSchemaId": 209}
headers = {
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
except Exception as a:
print(a)
print(response.status_code)
print(response.text)
conn.commit()
conn.close()

View File

@ -1,17 +1,43 @@
import datetime
from API.rok import download_products, download_prices
from API.rokky import decrypt_and_unpack, add_product, update_prices
from services.orders_rokky import rok_orders
def run_task():
print("REDs start download_prices:!", datetime.datetime.now())
download_prices()
decrypt_and_unpack("prices")
print("START update_prices")
update_prices()
print("REDs download_prices:", datetime.datetime.now())
print("END update_prices", datetime.datetime.now())
print("REDs download_prices:!", datetime.datetime.now())
def run_task1():
print("START download_products")
download_products()
print("START decrypt_and_unpack")
decrypt_and_unpack("products")
print("START add_product")
add_product()
print("END-s add_product!!!")
print("REDs download__product:", datetime.datetime.now())
def run_task2():
try:
print("START run_task2")
rok_orders()
print("END run_task2", datetime.datetime.now())
except Exception as e:
print("ERROR run_task2:", e)
def run_task3():
try:
print("START run_task3")
update_prices()
print("END run_task3", datetime.datetime.now())
except Exception as e:
print("ERROR run_task3:", e)

View File

@ -1,5 +1,8 @@
import sys
from mailer import send_plain_email, send_html_email
from services.mailer import send_plain_email, send_html_email
import sqlite3
from datetime import datetime
from services.gg import create_messagea
def read_multiline(prompt: str) -> str:
@ -24,43 +27,59 @@ def send_text_flow():
send_plain_email(to_addr, subject, body)
def send_html_flow():
to_addr = input("Receiver email: ").strip()
def send_html_flow(ids):
# to_addr = input("Receiver email: ").strip()
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
sku = ids
cursor.execute("""
SELECT *
FROM orders
WHERE orders_rokky = ?
""", (sku,))
rows = cursor.fetchall()
for row in rows:
print(row)
s = row[9]
s = s.replace(" ", "+", 1) # только первое вхождение после времени
dt = datetime.fromisoformat(s)
dates = dt.strftime("%Y-%m-%d %H:%M:%S")
data = {
"company_name": "wstkeys",
"order_id": "123",
"customer_name": "4321",
"currency": "USD",
# "company_name": "wstkeys",
"order_id": row[1],
# "customer_name": "4321",
"currency": row[7],
"items": [
{"name": "Game 1333", "quantity": 1, "price": 1330},
{"name": row[3], "quantity": 1, "price": row[8]},
],
"date": "23.03.2026 14:02",
"product_name": "Railroads Online - Pioneer DLC",
"product_image": "https://s3.ggsel.com/gsellers-imgs-prod/e05c8d1f28e18f56334bf8e7e9f7b547.jpeg",
"total_price": 20,
"key": 'XXXX-XXXX-YYY23',
"date": dates,
"product_name": row[3],
"product_image": row[4],
"total_price": row[8],
"key": row[13],
"support_email": "wstkeys@gmail.com",
"year": 2026
}
to_addr = row[5]
send_html_email(to_addr, data)
message = (
f"🔑 Ваш ключ: {row[13]}\n\n"
"📩 Копия ключа отправлена на вашу электронную почту.\n"
"💬 Если у вас возникнут вопросы — напишите нам.\n"
"⭐️ Нам очень важно ваше мнение, пожалуйста, оставьте отзыв."
)
create_messagea(row[1], message )
conn.close()
def main():
print("1 - Send plain email")
print("2 - Send HTML email")
choice = input("Choose: ").strip()
if choice == "1":
send_text_flow()
elif choice == "2":
send_html_flow()
else:
print("Invalid choice")
if __name__ == "__main__":
main()
# send_html_flow(5388351)

4
services/test.py Normal file
View File

@ -0,0 +1,4 @@
import requests
ip = requests.get("https://api.ipify.org").text
print(ip)

View File

@ -1,14 +1,24 @@
from apscheduler.schedulers.background import BackgroundScheduler
from services.red import run_task
import datetime
import time
from services.red import run_task, run_task1, run_task2,run_task3
def start_scheduler():
scheduler = BackgroundScheduler()
# каждые 10 секунд
scheduler.add_job(run_task, 'interval', minutes=10)
# Раз в сутки (24 часа)
scheduler.add_job(run_task, 'interval', days=1)
scheduler.start()
scheduler.add_job(run_task2, 'interval', minutes=1, next_run_time=datetime.datetime.now())
scheduler.add_job(run_task, 'interval', minutes=5)
scheduler.add_job(run_task1, 'interval', days=1, next_run_time=datetime.datetime.now())
# scheduler.add_job(
# run_task3,
# 'interval',
# minutes=2,
# next_run_time=datetime.datetime.now() # 🔥 сразу запуск
# )
scheduler.start()

8
start.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
# Поднимаем WireGuard (игнорируем ошибки resolvconf)
wg-quick up ./wireguard/wg_confs/wg0.conf || true
# Запускаем приложение
uv run main.py

6
wg/coredns/Corefile Normal file
View File

@ -0,0 +1,6 @@
. {
loop
errors
health
forward . /etc/resolv.conf
}

11
wg/templates/peer.conf Normal file
View File

@ -0,0 +1,11 @@
[Interface]
Address = ${CLIENT_IP}
PrivateKey = $(cat /config/${PEER_ID}/privatekey-${PEER_ID})
ListenPort = 51820
DNS = ${PEERDNS}
[Peer]
PublicKey = $(cat /config/server/publickey-server)
PresharedKey = $(cat /config/${PEER_ID}/presharedkey-${PEER_ID})
Endpoint = ${SERVERURL}:${SERVERPORT}
AllowedIPs = ${ALLOWEDIPS}

6
wg/templates/server.conf Normal file
View File

@ -0,0 +1,6 @@
[Interface]
Address = ${INTERFACE}.1
ListenPort = 51820
PrivateKey = $(cat /config/server/privatekey-server)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

View File

@ -0,0 +1,6 @@
. {
loop
errors
health
forward . /etc/resolv.conf
}

View File

@ -0,0 +1,11 @@
[Interface]
Address = ${CLIENT_IP}
PrivateKey = $(cat /config/${PEER_ID}/privatekey-${PEER_ID})
ListenPort = 51820
DNS = ${PEERDNS}
[Peer]
PublicKey = $(cat /config/server/publickey-server)
PresharedKey = $(cat /config/${PEER_ID}/presharedkey-${PEER_ID})
Endpoint = ${SERVERURL}:${SERVERPORT}
AllowedIPs = ${ALLOWEDIPS}

View File

@ -0,0 +1,6 @@
[Interface]
Address = ${INTERFACE}.1
ListenPort = 51820
PrivateKey = $(cat /config/server/privatekey-server)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

View File

@ -0,0 +1,15 @@
[Interface]
PrivateKey = yNlGhRShhVe9Jf+9PYA5cL1OcQq2K2rT8KsPGPfG50o=
Address = 10.66.66.15/32,fd42:42:42::15/128
DNS = 1.1.1.1,1.0.0.1
# Uncomment the next line to set a custom MTU
# This might impact performance, so use it only if you know what you are doing
# See https://github.com/nitred/nr-wg-mtu-finder to find your optimal MTU
# MTU = 1420
[Peer]
PublicKey = bcJDrYlhWls25zz9+bJcWiONw8Qfx1tai504+vKLcgQ=
PresharedKey = 40DSkC0TTySjBFyUj19++ngCdYxAHZaLnsrz8Ck9R2Q=
Endpoint = 85.208.110.167:50395
AllowedIPs = 0.0.0.0/0,::/0