More suffernig
This commit is contained in:
@@ -42,6 +42,7 @@ from .auth import generate_unique_id, validate_api_key
|
||||
from .config_loader import load_config
|
||||
from .const import CONF_GOOGLE_ACCOUNT, CONF_HOTEL_ID, CONF_META_ACCOUNT, HttpStatusCode
|
||||
from .conversion_service import ConversionService
|
||||
from .csv_import import CSVImporter
|
||||
from .customer_service import CustomerService
|
||||
from .db import Base, ResilientAsyncSession, SessionMaker, create_database_engine
|
||||
from .db import Customer as DBCustomer
|
||||
@@ -1154,6 +1155,72 @@ async def handle_wix_form_test(
|
||||
raise HTTPException(status_code=500, detail="Error processing test data")
|
||||
|
||||
|
||||
@api_router.post("/admin/import-csv")
|
||||
@limiter.limit(BURST_RATE_LIMIT)
|
||||
async def import_csv_endpoint(
|
||||
request: Request,
|
||||
csv_file_path: str,
|
||||
hotel_code: str | None = None,
|
||||
credentials: tuple = Depends(validate_basic_auth),
|
||||
db_session=Depends(get_async_session),
|
||||
):
|
||||
"""Import reservations from a CSV file (landing_page_form.csv format).
|
||||
|
||||
This endpoint allows importing historical form data into the system.
|
||||
It creates customers and reservations, avoiding duplicates based on:
|
||||
- Name, email, reservation dates
|
||||
- fbclid/gclid tracking IDs
|
||||
|
||||
Requires basic authentication.
|
||||
|
||||
Args:
|
||||
csv_file_path: Path to CSV file (relative to app root)
|
||||
hotel_code: Optional hotel code to override CSV values
|
||||
credentials: Basic auth credentials
|
||||
|
||||
Returns:
|
||||
Import statistics including created/skipped counts and any errors
|
||||
"""
|
||||
try:
|
||||
# Validate file path to prevent path traversal
|
||||
if ".." in csv_file_path or csv_file_path.startswith("/"):
|
||||
raise HTTPException(status_code=400, detail="Invalid file path")
|
||||
|
||||
# Check if file exists
|
||||
csv_path = Path(csv_file_path)
|
||||
if not csv_path.exists():
|
||||
# Try relative to app root
|
||||
csv_path = Path() / csv_file_path
|
||||
if not csv_path.exists():
|
||||
raise HTTPException(
|
||||
status_code=404, detail=f"CSV file not found: {csv_file_path}"
|
||||
)
|
||||
|
||||
_LOGGER.info(
|
||||
"Starting CSV import from %s (user: %s)", csv_file_path, credentials[0]
|
||||
)
|
||||
|
||||
# Create importer and import
|
||||
importer = CSVImporter(db_session, request.app.state.config)
|
||||
stats = await importer.import_csv_file(str(csv_path), hotel_code, dryrun=False)
|
||||
|
||||
_LOGGER.info("CSV import completed: %s", stats)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "CSV import completed",
|
||||
"stats": stats,
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
except FileNotFoundError as e:
|
||||
_LOGGER.error("CSV file not found: %s", e)
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
except Exception as e:
|
||||
_LOGGER.exception("Error during CSV import")
|
||||
raise HTTPException(status_code=500, detail=f"Error processing CSV: {str(e)}")
|
||||
|
||||
|
||||
@api_router.post("/webhook/generic")
|
||||
@webhook_limiter.limit(WEBHOOK_RATE_LIMIT)
|
||||
async def handle_generic_webhook(
|
||||
|
||||
Reference in New Issue
Block a user