fix(pagination): Fixed socket gevent (#95)
This commit is contained in:
4
app.py
4
app.py
@@ -1,6 +1,6 @@
|
||||
# This need to be first
|
||||
import eventlet
|
||||
eventlet.monkey_patch()
|
||||
import gevent.monkey
|
||||
gevent.monkey.patch_all()
|
||||
|
||||
import logging # noqa: E402
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ from flask_socketio import SocketIO
|
||||
|
||||
from .instructions import BrickInstructions
|
||||
from .instructions_list import BrickInstructionsList
|
||||
from .peeron_instructions import PeeronPage
|
||||
from .peeron_pdf import PeeronPDF
|
||||
from .set import BrickSet
|
||||
from .socket_decorator import authenticated_socket, rebrickable_socket
|
||||
from .sql import close as sql_close
|
||||
@@ -18,6 +20,7 @@ MESSAGES: Final[dict[str, str]] = {
|
||||
'CONNECT': 'connect',
|
||||
'DISCONNECT': 'disconnect',
|
||||
'DOWNLOAD_INSTRUCTIONS': 'download_instructions',
|
||||
'DOWNLOAD_PEERON_PAGES': 'download_peeron_pages',
|
||||
'FAIL': 'fail',
|
||||
'IMPORT_SET': 'import_set',
|
||||
'LOAD_SET': 'load_set',
|
||||
@@ -70,7 +73,7 @@ class BrickSocket(object):
|
||||
*args,
|
||||
**kwargs,
|
||||
path=app.config['SOCKET_PATH'],
|
||||
async_mode='eventlet',
|
||||
async_mode='gevent',
|
||||
)
|
||||
|
||||
# Store the socket in the app config
|
||||
@@ -106,6 +109,56 @@ class BrickSocket(object):
|
||||
|
||||
BrickInstructionsList(force=True)
|
||||
|
||||
@self.socket.on(MESSAGES['DOWNLOAD_PEERON_PAGES'], namespace=self.namespace) # noqa: E501
|
||||
@authenticated_socket(self)
|
||||
def download_peeron_pages(data: dict[str, Any], /) -> None:
|
||||
logger.debug('Socket: DOWNLOAD_PEERON_PAGES={data} (from: {fr})'.format(
|
||||
data=data,
|
||||
fr=request.sid, # type: ignore
|
||||
))
|
||||
|
||||
try:
|
||||
# Extract data from the request
|
||||
set_number = data.get('set', '')
|
||||
pages_data = data.get('pages', [])
|
||||
|
||||
if not set_number:
|
||||
raise ValueError("Set number is required")
|
||||
|
||||
if not pages_data:
|
||||
raise ValueError("No pages selected")
|
||||
|
||||
# Parse set number
|
||||
if '-' in set_number:
|
||||
parts = set_number.split('-', 1)
|
||||
set_num = parts[0]
|
||||
version_num = parts[1] if len(parts) > 1 else '1'
|
||||
else:
|
||||
set_num = set_number
|
||||
version_num = '1'
|
||||
|
||||
# Convert page data to PeeronPage objects
|
||||
pages = []
|
||||
for page_data in pages_data:
|
||||
page = PeeronPage(
|
||||
page_number=page_data.get('page_number', ''),
|
||||
thumbnail_url=page_data.get('thumbnail_url', ''),
|
||||
image_url=page_data.get('image_url', ''),
|
||||
alt_text=page_data.get('alt_text', '')
|
||||
)
|
||||
pages.append(page)
|
||||
|
||||
# Create PDF generator and start download
|
||||
pdf_generator = PeeronPDF(set_num, version_num, pages, socket=self)
|
||||
pdf_generator.create_pdf()
|
||||
|
||||
# Refresh instructions list to include new PDF
|
||||
BrickInstructionsList(force=True)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in download_peeron_pages: {e}")
|
||||
self.fail(message=f"Error downloading Peeron pages: {e}")
|
||||
|
||||
@self.socket.on(MESSAGES['IMPORT_SET'], namespace=self.namespace)
|
||||
@rebrickable_socket(self)
|
||||
def import_set(data: dict[str, Any], /) -> None:
|
||||
|
||||
36
wsgi.py
36
wsgi.py
@@ -1,38 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
WSGI entry point for BrickTracker - Production Docker deployment
|
||||
This ensures proper gevent monkey patching for gunicorn
|
||||
This ensures proper gevent monkey patching before any imports
|
||||
"""
|
||||
|
||||
# CRITICAL: This must be the very first import
|
||||
# CRITICAL: Monkey patch must be first, before ANY other imports
|
||||
import gevent.monkey
|
||||
gevent.monkey.patch_all()
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
# Now import the regular app factory
|
||||
from app import create_app
|
||||
|
||||
# Add the current directory to Python path
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
# Create the application - this will be a BrickSocket instance
|
||||
app_instance = create_app()
|
||||
|
||||
# Import Flask and BrickTracker modules directly
|
||||
from flask import Flask
|
||||
from bricktracker.app import setup_app
|
||||
from bricktracker.socket import BrickSocket
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Create the Flask app directly (bypassing app.py to avoid double monkey patching)
|
||||
app = Flask(__name__)
|
||||
|
||||
# Setup the app
|
||||
setup_app(app)
|
||||
|
||||
# Create the socket
|
||||
socket_instance = BrickSocket(
|
||||
app,
|
||||
threaded=not app.config['NO_THREADED_SOCKET'],
|
||||
)
|
||||
|
||||
# Export the Flask app for gunicorn
|
||||
application = app
|
||||
# For gunicorn, we need the Flask app, not the BrickSocket wrapper
|
||||
application = app_instance.app if hasattr(app_instance, 'app') else app_instance
|
||||
Reference in New Issue
Block a user