This commit is contained in:
zman 2025-02-21 11:46:50 -05:00
parent 721b26ce97
commit 1bf255d0fe
12 changed files with 425 additions and 91 deletions

3
.gitignore vendored
View File

@ -173,4 +173,5 @@ cython_debug/
temp/ temp/
.DS_Store .DS_Store
*.db-journal *.db-journal
cookies/ cookies/
alembic/versions/*

View File

@ -328,6 +328,41 @@ class TCGPlayerGroups(Base):
modified_on = Column(String) modified_on = Column(String)
category_id = Column(Integer) category_id = Column(Integer)
class Orders(Base):
__tablename__ = 'orders'
id = Column(String, primary_key=True)
order_id = Column(String, unique=True)
buyer_name = Column(String)
recipient_name = Column(String)
recipient_address_one = Column(String)
recipient_address_two = Column(String)
recipient_city = Column(String)
recipient_state = Column(String)
recipient_zip = Column(String)
recipient_country = Column(String)
order_date = Column(String)
status = Column(String)
num_products = Column(Integer)
num_cards = Column(Integer)
product_amount = Column(Float)
shipping_amount = Column(Float)
gross_amount = Column(Float)
fee_amount = Column(Float)
net_amount = Column(Float)
direct_fee_amount = Column(Float)
date_created = Column(DateTime, default=datetime.now)
date_modified = Column(DateTime, default=datetime.now, onupdate=datetime.now)
class OrderProducts(Base):
__tablename__ = 'order_products'
id = Column(String, primary_key=True)
order_id = Column(String, ForeignKey('orders.id'))
product_id = Column(String, ForeignKey('products.id'))
quantity = Column(Integer)
unit_price = Column(Float)
# enums # enums
class RarityEnum(str, Enum): class RarityEnum(str, Enum):

View File

@ -10,6 +10,7 @@ from app.services.product import ProductService
from app.services.inventory import InventoryService from app.services.inventory import InventoryService
from app.services.task import TaskService from app.services.task import TaskService
from app.services.storage import StorageService from app.services.storage import StorageService
from app.services.tcgplayer_api import TCGPlayerAPIService
from app.db.database import get_db from app.db.database import get_db
from app.schemas.file import CreateFileRequest from app.schemas.file import CreateFileRequest
from app.schemas.box import CreateBoxRequest, UpdateBoxRequest, CreateOpenBoxRequest from app.schemas.box import CreateBoxRequest, UpdateBoxRequest, CreateOpenBoxRequest
@ -18,6 +19,10 @@ from app.schemas.box import CreateBoxRequest, UpdateBoxRequest, CreateOpenBoxReq
DB = Annotated[Session, Depends(get_db)] DB = Annotated[Session, Depends(get_db)]
# Base Services (no dependencies besides DB) # Base Services (no dependencies besides DB)
def get_tcgplayer_api_service(db: DB) -> TCGPlayerAPIService:
"""TCGPlayerAPIService with only database dependency"""
return TCGPlayerAPIService(db)
def get_file_service(db: DB) -> FileService: def get_file_service(db: DB) -> FileService:
"""FileService with only database dependency""" """FileService with only database dependency"""
return FileService(db) return FileService(db)

View File

@ -25,10 +25,12 @@ from app.schemas.box import (
CreateOpenBoxResponse, CreateOpenBoxResponse,
OpenBoxSchema OpenBoxSchema
) )
from app.schemas.orders import ProcessOrdersResponse
from app.services.file import FileService from app.services.file import FileService
from app.services.box import BoxService from app.services.box import BoxService
from app.services.task import TaskService from app.services.task import TaskService
from app.services.pricing import PricingService from app.services.pricing import PricingService
from app.services.tcgplayer_api import TCGPlayerAPIService
from app.dependencies import ( from app.dependencies import (
get_file_service, get_file_service,
get_box_service, get_box_service,
@ -37,7 +39,8 @@ from app.dependencies import (
get_box_data, get_box_data,
get_box_update_data, get_box_update_data,
get_open_box_data, get_open_box_data,
get_pricing_service get_pricing_service,
get_tcgplayer_api_service
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -313,3 +316,23 @@ async def update_cookies(
status_code=500, status_code=500,
detail=f"Failed to update cookies: {str(e)}" detail=f"Failed to update cookies: {str(e)}"
) )
class TCGPlayerOrderRequest(BaseModel):
order_ids: List[str]
@router.post("/processOrders", response_model=ProcessOrdersResponse)
async def process_orders(
body: TCGPlayerOrderRequest,
tcgplayer_api_service: TCGPlayerAPIService = Depends(get_tcgplayer_api_service),
) -> ProcessOrdersResponse:
"""Process TCGPlayer orders."""
try:
orders = tcgplayer_api_service.process_orders(body.order_ids)
return ProcessOrdersResponse(
status_code=200,
success=True,
orders=orders
)
except Exception as e:
logger.error(f"Process orders failed: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))

View File

@ -1,19 +0,0 @@
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional
from datetime import datetime
# FILE
class OrderSchema(BaseModel):
id: str = Field(..., title="id")
filename: str = Field(..., title="filename")
type: str = Field(..., title="type")
filesize_kb: float = Field(..., title="filesize_kb")
source: str = Field(..., title="source")
status: str = Field(..., title="status")
service: Optional[str] = Field(None, title="service")
date_created: datetime = Field(..., title="date_created")
date_modified: datetime = Field(..., title="date_modified")
# This enables ORM mode
model_config = ConfigDict(from_attributes=True)

9
app/schemas/orders.py Normal file
View File

@ -0,0 +1,9 @@
from pydantic import BaseModel
class OrderSchema(BaseModel):
order_id: str
class ProcessOrdersResponse(BaseModel):
status_code: int
success: bool
orders: list[str]

View File

@ -10,7 +10,7 @@ import io
# Printer settings # Printer settings
printer_model = "QL-1100" printer_model = "QL-1100"
backend = 'pyusb' # Changed from network to USB backend = 'pyusb'
printer = 'usb://0x04f9:0x20a7' printer = 'usb://0x04f9:0x20a7'
def convert_pdf_to_image(pdf_path): def convert_pdf_to_image(pdf_path):
@ -45,6 +45,8 @@ def create_address_label(input_data, font_size=30, is_pdf=False):
font = ImageFont.truetype("C:\\Windows\\Fonts\\arial.ttf", size=font_size) font = ImageFont.truetype("C:\\Windows\\Fonts\\arial.ttf", size=font_size)
elif platform.system() == 'Darwin': elif platform.system() == 'Darwin':
font = ImageFont.truetype("/Library/Fonts/Arial.ttf", size=font_size) font = ImageFont.truetype("/Library/Fonts/Arial.ttf", size=font_size)
elif platform.system() == 'Linux':
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/arial.ttf", size=font_size)
margin = 20 margin = 20
lines = input_data.split('\n') lines = input_data.split('\n')
@ -71,10 +73,8 @@ def print_address_label(input_data, font_size=30, is_pdf=False, label_size='29x9
if not image: if not image:
raise Exception("Failed to create label image") raise Exception("Failed to create label image")
# For 4x6 shipping labels from Pirate Ship
if label_size == '4x6': if label_size == '4x6':
# Resize image to fit 4x6 format if needed target_width = 1164
target_width = 1164 # Adjusted for 4x6 format
target_height = 1660 target_height = 1660
image = image.resize((target_width, target_height), Image.LANCZOS) image = image.resize((target_width, target_height), Image.LANCZOS)
@ -92,7 +92,6 @@ def print_address_label(input_data, font_size=30, is_pdf=False, label_size='29x9
red=False, red=False,
dpi_600=False, dpi_600=False,
hq=True, hq=True,
#cut=True
cut=False cut=False
) )
@ -135,34 +134,24 @@ def process_tcg_shipping_export(file_path, require_input=False, font_size=60, pr
else: else:
sleep(1) sleep(1)
# Example usage
if __name__ == "__main__": if __name__ == "__main__":
# Example for regular address label
address = """John Doe
123 Main Street
Apt 4B
City, State 12345"""
# Example for TCG Player export
shipping_export_file = "_TCGplayer_ShippingExport_20250201_115949.csv"
# Example for Pirate Ship PDF
pirate_ship_pdf = "C:\\Users\\joshu\\Downloads\\2025-02-10---greg-creek---9400136208070411592215.pdf"
# Choose which type to process # Choose which type to process
label_type = input("Enter label type (1 for regular, 2 for TCG, 3 for Pirate Ship): ") label_type = input("Enter label type (1 for regular, 2 for TCG, 3 for Pirate Ship): ")
if label_type == "1": if label_type == "1":
address = input("Enter the address to print: ")
preview_label(address, font_size=60) preview_label(address, font_size=60)
user_input = input("Press 'p' to print the label or any other key to cancel: ") user_input = input("Press 'p' to print the label or any other key to cancel: ")
if user_input.lower() == 'p': if user_input.lower() == 'p':
print_address_label(address, font_size=60) print_address_label(address, font_size=60)
elif label_type == "2": elif label_type == "2":
shipping_export_file = input("Enter the path to the TCG Player shipping export CSV file: ")
process_tcg_shipping_export(shipping_export_file, font_size=60, preview=False) process_tcg_shipping_export(shipping_export_file, font_size=60, preview=False)
elif label_type == "3": elif label_type == "3":
pirate_ship_pdf = input("Enter the path to the Pirate Ship PDF file: ")
process_pirate_ship_pdf(pirate_ship_pdf, preview=True) process_pirate_ship_pdf(pirate_ship_pdf, preview=True)
user_input = input("Press 'p' to print the label or any other key to cancel: ") user_input = input("Press 'p' to print the label or any other key to cancel: ")
if user_input.lower() == 'p': if user_input.lower() == 'p':
process_pirate_ship_pdf(pirate_ship_pdf, preview=False) process_pirate_ship_pdf(pirate_ship_pdf, preview=False)

View File

@ -21,6 +21,7 @@ import pandas as pd
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from app.schemas.file import CreateFileRequest from app.schemas.file import CreateFileRequest
import os import os
from app.services.util._docker import DockerUtil
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -53,6 +54,7 @@ class TCGPlayerService:
self.previous_request_time = None self.previous_request_time = None
self.df_util = DataframeUtil() self.df_util = DataframeUtil()
self.file_service = file_service self.file_service = file_service
self.docker_util = DockerUtil()
def _insert_groups(self, groups): def _insert_groups(self, groups):
for group in groups: for group in groups:
@ -118,47 +120,6 @@ class TCGPlayerService:
except Exception as e: except Exception as e:
logger.error(f"Failed to get browser cookies: {str(e)}") logger.error(f"Failed to get browser cookies: {str(e)}")
return None return None
def is_in_docker(self) -> bool:
"""Check if we're running inside a Docker container using multiple methods"""
# Method 1: Check cgroup
try:
with open('/proc/1/cgroup', 'r') as f:
content = f.read().lower()
if any(container_id in content for container_id in ['docker', 'containerd', 'kubepods']):
logger.debug("Docker detected via cgroup")
return True
except Exception as e:
logger.debug(f"Could not read cgroup file: {e}")
# Method 2: Check /.dockerenv file
if os.path.exists('/.dockerenv'):
logger.debug("Docker detected via /.dockerenv file")
return True
# Method 3: Check environment variables
docker_env = any(os.environ.get(var, False) for var in [
'DOCKER_CONTAINER',
'IN_DOCKER',
'KUBERNETES_SERVICE_HOST', # For k8s
'DOCKER_HOST'
])
if docker_env:
logger.debug("Docker detected via environment variables")
return True
# Method 4: Check container runtime
try:
with open('/proc/self/mountinfo', 'r') as f:
content = f.read().lower()
if any(rt in content for rt in ['docker', 'containerd', 'kubernetes']):
logger.debug("Docker detected via mountinfo")
return True
except Exception as e:
logger.debug(f"Could not read mountinfo: {e}")
logger.debug("No Docker environment detected")
return False
def _send_request(self, url: str, method: str, data=None, except_302=False) -> requests.Response: def _send_request(self, url: str, method: str, data=None, except_302=False) -> requests.Response:
"""Send a request with the specified cookies""" """Send a request with the specified cookies"""
@ -173,7 +134,7 @@ class TCGPlayerService:
# Move cookie initialization outside and make it more explicit # Move cookie initialization outside and make it more explicit
if not self.cookies: if not self.cookies:
if self.is_in_docker(): if self.docker_util.is_in_docker():
logger.debug("Running in Docker - using cookies from file") logger.debug("Running in Docker - using cookies from file")
self.cookies = self.get_cookies_from_file() self.cookies = self.get_cookies_from_file()
else: else:

View File

@ -0,0 +1,105 @@
from dataclasses import dataclass
import logging
from app.db.models import Orders, OrderProducts, CardTCGPlayer
from app.services.util._requests import RequestsUtil
from app.services.util._docker import DockerUtil
from app.db.utils import db_transaction
from sqlalchemy.orm import Session
from uuid import uuid4 as uuid
logger = logging.getLogger(__name__)
@dataclass
class TCGPlayerAPIConfig:
"""Configuration for TCGPlayer API"""
ORDER_BASE_URL: str = "https://order-management-api.tcgplayer.com/orders"
API_VERSION: str = "?api-version=2.0"
class TCGPlayerAPIService:
def __init__(self, db: Session):
self.db = db
self.docker_util = DockerUtil()
self.requests_util = RequestsUtil()
self.is_in_docker = self.docker_util.is_in_docker()
self.config = TCGPlayerAPIConfig()
self.cookies = self.get_cookies()
def get_cookies(self) -> dict:
if self.is_in_docker:
return self.requests_util.get_tcgplayer_cookies_from_file()
else:
return self.requests_util.get_tcgplayer_browser_cookies()
def get_order(self, order_id: str) -> dict:
url = f"{self.config.ORDER_BASE_URL}/{order_id}{self.config.API_VERSION}"
response = self.requests_util.send_request(url, method='GET', cookies=self.cookies)
if response:
return response.json()
return None
def get_product_ids_from_sku(self, sku_ids: list[str]) -> dict:
"""Get product IDs from TCGPlayer SKU IDs"""
tcg_cards = self.db.query(CardTCGPlayer).filter(CardTCGPlayer.tcgplayer_id.in_(sku_ids)).all()
return {card.tcgplayer_id: card.product_id for card in tcg_cards}
def save_order(self, order: dict):
# check if order exists by order number
order_number = order['orderNumber']
existing_order = self.db.query(Orders).filter(Orders.order_id == order_number).first()
if existing_order:
logger.info(f"Order {order_number} already exists in database")
return existing_order
transaction = order['transaction']
shipping = order['shippingAddress']
products = order['products']
with db_transaction(self.db):
db_order = Orders(
id = str(uuid()),
order_id=order_number,
buyer_name=order['buyerName'],
recipient_name=shipping['recipientName'],
recipient_address_one=shipping['addressOne'],
recipient_address_two=shipping['addressTwo'] if 'addressTwo' in shipping else '',
recipient_city=shipping['city'],
recipient_state=shipping['territory'],
recipient_zip=shipping['postalCode'],
recipient_country=shipping['country'],
order_date=order['createdAt'],
status=order['status'],
num_products=len(products),
num_cards=sum([product['quantity'] for product in products]),
product_amount=transaction['productAmount'],
shipping_amount=transaction['shippingAmount'],
gross_amount=transaction['grossAmount'],
fee_amount=transaction['feeAmount'],
net_amount=transaction['netAmount'],
direct_fee_amount=transaction['directFeeAmount']
)
self.db.add(db_order)
product_ids = [product['skuId'] for product in products]
sku_to_product_id_mapping = self.get_product_ids_from_sku(product_ids)
order_products = []
for product in products:
product_id = sku_to_product_id_mapping.get(product['skuId'])
if product_id:
order_products.append(
OrderProducts(
id=str(uuid()),
order_id=db_order.id,
product_id=product_id,
quantity=product['quantity'],
unit_price=product['unitPrice']
)
)
self.db.add_all(order_products)
return db_order
def process_orders(self, orders: list[str]):
processed_orders = []
for order_id in orders:
order = self.get_order(order_id)
if order:
self.save_order(order)
processed_orders.append(order_id)
return processed_orders

View File

@ -0,0 +1,49 @@
import os
import logging
logger = logging.getLogger(__name__)
class DockerUtil:
def __init__(self):
pass
def is_in_docker(self) -> bool:
"""Check if we're running inside a Docker container using multiple methods"""
# Method 1: Check cgroup
try:
with open('/proc/1/cgroup', 'r') as f:
content = f.read().lower()
if any(container_id in content for container_id in ['docker', 'containerd', 'kubepods']):
logger.debug("Docker detected via cgroup")
return True
except Exception as e:
logger.debug(f"Could not read cgroup file: {e}")
# Method 2: Check /.dockerenv file
if os.path.exists('/.dockerenv'):
logger.debug("Docker detected via /.dockerenv file")
return True
# Method 3: Check environment variables
docker_env = any(os.environ.get(var, False) for var in [
'DOCKER_CONTAINER',
'IN_DOCKER',
'KUBERNETES_SERVICE_HOST', # For k8s
'DOCKER_HOST'
])
if docker_env:
logger.debug("Docker detected via environment variables")
return True
# Method 4: Check container runtime
try:
with open('/proc/self/mountinfo', 'r') as f:
content = f.read().lower()
if any(rt in content for rt in ['docker', 'containerd', 'kubernetes']):
logger.debug("Docker detected via mountinfo")
return True
except Exception as e:
logger.debug(f"Could not read mountinfo: {e}")
logger.debug("No Docker environment detected")
return False

View File

@ -0,0 +1,172 @@
from typing import Dict, Optional
from app.services.util._docker import DockerUtil
from enum import Enum
import browser_cookie3
import os
import json
import requests
import time
from datetime import datetime
import logging
logger = logging.getLogger(__name__)
class Browser(Enum):
"""Supported browser types for cookie extraction"""
BRAVE = "brave"
CHROME = "chrome"
FIREFOX = "firefox"
class Method(Enum):
"""Supported HTTP methods"""
GET = "GET"
POST = "POST"
class TCGPlayerEndpoints(Enum):
"""Supported TCGPlayer API endpoints"""
ORDERS = "https://order-management-api.tcgplayer.com/orders"
class Headers:
ACCEPT = 'application/json, text/plain, */*'
ACCEPT_ENCODING = 'gzip, deflate, br, zstd'
ACCEPT_LANGUAGE = 'en-US,en;q=0.8'
PRIORITY = 'u=1, i'
SECCHUA = '"Not(A:Brand";v="99", "Brave";v="133", "Chromium";v="133"'
SECCHUA_MOBILE = '?0'
SECCHUA_PLATFORM = '"macOS"'
SEC_FETCH_DEST = 'empty'
SEC_FETCH_MODE = 'cors'
SEC_FETCH_SITE = 'same-site'
SEC_GPC = '1'
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36'
SELLER_ORIGIN = 'https://sellerportal.tcgplayer.com'
SELLER_REFERER = 'https://sellerportal.tcgplayer.com/'
class RequestHeaders:
BASE_HEADERS = {
'accept': Headers.ACCEPT,
'accept-encoding': Headers.ACCEPT_ENCODING,
'accept-language': Headers.ACCEPT_LANGUAGE,
'priority': Headers.PRIORITY,
'sec-ch-ua': Headers.SECCHUA,
'sec-ch-ua-mobile': Headers.SECCHUA_MOBILE,
'sec-ch-ua-platform': Headers.SECCHUA_PLATFORM,
'sec-fetch-dest': Headers.SEC_FETCH_DEST,
'sec-fetch-mode': Headers.SEC_FETCH_MODE,
'sec-fetch-site': Headers.SEC_FETCH_SITE,
'sec-gpc': Headers.SEC_GPC,
'user-agent': Headers.USER_AGENT
}
SELLER_HEADERS = {
'origin': Headers.SELLER_ORIGIN,
'referer': Headers.SELLER_REFERER
}
class URLHeaders:
# combine base and seller headers
ORDER_HEADERS = {**RequestHeaders.BASE_HEADERS, **RequestHeaders.SELLER_HEADERS}
class RequestsUtil:
def __init__(self, browser_type: Browser = Browser.BRAVE):
self.browser_type = browser_type
self.docker_util = DockerUtil()
def get_tcgplayer_cookies_from_file(self) -> Dict:
# check if cookies file exists
if not os.path.exists('cookies/tcg_cookies.json'):
raise ValueError("Cookies file not found")
with open('cookies/tcg_cookies.json', 'r') as f:
logger.debug("Loading cookies from file")
cookies = json.load(f)
return cookies
def get_tcgplayer_browser_cookies(self) -> Optional[Dict]:
"""Retrieve cookies from the specified browser"""
try:
cookie_getter = getattr(browser_cookie3, self.browser_type.value, None)
if not cookie_getter:
raise ValueError(f"Unsupported browser type: {self.browser_type.value}")
return cookie_getter()
except Exception as e:
logger.error(f"Failed to get browser cookies: {str(e)}")
return None
def rate_limit(self, time_between_requests: int = 10):
"""Rate limit requests by waiting for a specified time between requests"""
time_diff = (datetime.now() - self.previous_request_time).total_seconds()
if time_diff < time_between_requests:
# logger.info(f"Waiting {time_between_requests - time_diff} seconds before next request...")
time.sleep(time_between_requests - time_diff)
def send_request(self, url: str, method: str, cookies: dict, data=None) -> requests.Response:
"""Send a request with the specified cookies"""
headers = self.set_headers(url)
if not headers:
raise ValueError("Headers not set")
try:
response = requests.request(method, url, headers=headers, cookies=cookies, data=data)
response.raise_for_status()
self.previous_request_time = datetime.now()
return response
except requests.RequestException as e:
logger.error(f"Request failed: {str(e)}")
return None
def set_headers(self, url: str):
# use tcgplayerendpoints enum to set headers where url partially matches enum value
for endpoint in TCGPlayerEndpoints:
if endpoint.value in url:
return URLHeaders.ORDER_HEADERS
else:
raise ValueError(f"Endpoint not found in TCGPlayerEndpoints: {url}")
def old_set_headers(self, method: str) -> Dict:
base_headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
'accept-language': 'en-US,en;q=0.8',
'priority': 'u=0, i',
'referer': 'https://store.tcgplayer.com/admin/pricing',
'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'sec-fetch-user': '?1',
'sec-gpc': '1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
}
if method == 'POST':
post_headers = {
'cache-control': 'max-age=0',
'content-type': 'application/x-www-form-urlencoded',
'origin': 'https://store.tcgplayer.com'
}
base_headers.update(post_headers)
return base_headers
"""
curl 'https://order-management-api.tcgplayer.com/orders/E576ED4C-38871F-B0277?api-version=2.0' \
-H 'accept: application/json, text/plain, */*' \
-H 'accept-language: en-US,en;q=0.8' \
-b 'tcgpartner=PK=TRADECARDS&M=1; valid=set=true; product-display-settings=sort=price+shipping&size=10; TCG_Data=M=1&SearchGameNameID=magic; tcg-uuid=ab16b5f8-dd66-446d-b217-d394328a5cf1; setting=CD=US&M=1; tracking-preferences={%22version%22:1%2C%22destinations%22:{%22Actions%20Amplitude%22:false%2C%22AdWords%22:false%2C%22Google%20AdWords%20New%22:false%2C%22Google%20Enhanced%20Conversions%22:false%2C%22Google%20Tag%20Manager%22:false%2C%22Impact%20Partnership%20Cloud%22:false%2C%22Optimizely%22:false}%2C%22custom%22:{%22advertising%22:false%2C%22functional%22:false%2C%22marketingAndAnalytics%22:false}}; OAuthLoginSessionId=63b1a89d-1ac2-43f7-8e79-55a9ca5e761d; TCGAuthTicket_Production=F453BFF2FA3FAA3D1ACA23F319314F8273713DECEB06C69BB7C208A77C81559B46E1AA22A7E70FABC8D7F681A423C86870FAE318B76048CDE7BF6D73D220631B899BEBA86C422E1EBBF2ACD1921E0846F708AFE203C844031364E13B047465E7B41CB6460E4F4AAB278B614445B93E722E976688; BuyerRevalidationKey=; ASP.NET_SessionId=oouwzrh3jkhdrmaioooqhr4k; TCG_VisitorKey=431efcca-2d5b-404d-a04f-3ae979696051; __RequestVerificationToken_L2FkbWlu0=Lw1sfWh823UeJ7zRux0b1ZTI4Vg4i_dFt97a55aQpf-qBURVuwWDCJyuCxSwgLNLe9nPlfDSc1AMV5nyqhY4Q4jurxs1; fileDownloadToken=1740145585435; spDisabledUIFeatures=' \
-H 'origin: https://sellerportal.tcgplayer.com' \
-H 'priority: u=1, i' \
-H 'referer: https://sellerportal.tcgplayer.com/' \
-H 'sec-ch-ua: "Not(A:Brand";v="99", "Brave";v="133", "Chromium";v="133"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "macOS"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: same-site' \
-H 'sec-gpc: 1' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36'
"""

View File

@ -2,16 +2,20 @@ curl -J http://192.168.1.41:8000/api/tcgplayer/inventory/update --remote-name
curl -J -X POST http://192.168.1.41:8000/api/tcgplayer/inventory/add \ curl -J -X POST http://192.168.1.41:8000/api/tcgplayer/inventory/add \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"open_box_ids": ["fb629d9d-13d2-405e-9a69-6c44294d55de"]}' \ -d '{"open_box_ids": ["02d14109-ad0c-41f9-b49f-24134f962c1a"]}' \
--remote-name --remote-name
curl -X POST http://192.168.1.41:8000/api/boxes \ curl -X POST http://192.168.1.41:8000/api/boxes \
-F "type=draft" \ -F "type=play" \
-F "set_code=CLB" \ -F "set_code=DFT" \
-F "sku=195166181127" \ -F "sku=195166278636" \
-F "num_cards_expected=480" -F "num_cards_expected=422"
curl -X POST "http://192.168.1.41:8000/api/boxes/0d31b9c3-3093-438a-9e8c-b6b70a2d437e/open" \ curl -X POST "http://192.168.1.41:8000/api/boxes/0d605f46-25b5-4784-8d45-38dec144ec8e/open" \
-F "product_id=0d31b9c3-3093-438a-9e8c-b6b70a2d437e" \ -F "product_id=0d605f46-25b5-4784-8d45-38dec144ec8e" \
-F "file_ids=bb4a022c-5427-49b5-b57c-0147b5e9c4a9" \ -F "file_ids=61124a9d-8db3-49aa-bf56-ec0d784ca817" \
-F "date_opened=2025-02-15" -F "date_opened=2025-02-17"
curl -X POST "http://127.0.0.1:8000/api/processOrders" \
-H "Content-Type: application/json" \
-d '{"order_ids": ["E576ED4C-A1117E-6904E"]}'