Skip to content

Commit f8136bb

Browse files
committed
Enhance screenshot capture functionality: improve Chrome initialization, add dynamic content loading, and ensure temporary directory permissions.
1 parent b68547c commit f8136bb

File tree

1 file changed

+98
-26
lines changed

1 file changed

+98
-26
lines changed

src/modules/apps/__init__.py

+98-26
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
from selenium import webdriver
55
from selenium.webdriver.chrome.options import Options
66
from selenium.webdriver.chrome.service import Service
7+
from selenium.webdriver.support.ui import WebDriverWait
8+
from selenium.webdriver.support import expected_conditions as EC
79
from subprocess import PIPE, STDOUT
10+
import traceback
11+
812
print("Gradio app loaded.")
913

1014
def capture_page(url: str, output_file: str = "screenshot.png"):
@@ -15,54 +19,122 @@ def capture_page(url: str, output_file: str = "screenshot.png"):
1519
:param output_file: The filename to save the screenshot.
1620
"""
1721
options = Options()
22+
# Basic options
1823
options.add_argument('--headless')
1924
options.add_argument('--no-sandbox') # Required in Docker
2025
options.add_argument('--disable-dev-shm-usage') # Required in Docker
26+
27+
# Performance and stability options
2128
options.add_argument('--disable-gpu') # Required in Docker
2229
options.add_argument('--disable-software-rasterizer')
23-
options.add_argument('--window-size=1920,1080')
2430
options.add_argument('--disable-extensions')
2531
options.add_argument('--disable-infobars')
2632

33+
# Resource configuration
34+
options.add_argument('--window-size=1920,1080')
35+
options.add_argument('--remote-debugging-port=9222') # Fix DevTools port issue
36+
options.add_argument('--disable-features=site-per-process') # Reduce memory usage
37+
options.add_argument('--memory-pressure-off') # Prevent memory-related crashes
38+
39+
# Additional stability options
40+
options.add_argument('--ignore-certificate-errors')
41+
options.add_argument('--allow-insecure-localhost')
42+
options.add_argument('--disable-setuid-sandbox')
43+
options.add_argument('--disable-web-security')
44+
2745
# Set up Chrome service with explicit path to chromedriver and logging
2846
service = Service(
2947
executable_path='/usr/local/bin/chromedriver',
30-
log_output=PIPE # Redirect logs to pipe
31-
)
32-
33-
# Initialize Chrome with the service and options
34-
driver = webdriver.Chrome(
35-
service=service,
36-
options=options
48+
log_output=PIPE, # Redirect logs to pipe
49+
service_args=['--verbose'] # Enable verbose logging
3750
)
3851

3952
try:
40-
driver.get(url)
41-
# Add a small delay to ensure page loads completely
42-
driver.implicitly_wait(5)
43-
driver.save_screenshot(output_file)
44-
print(f"Screenshot saved: {output_file}")
45-
finally:
46-
driver.quit()
53+
print("Initializing Chrome...")
54+
driver = webdriver.Chrome(
55+
service=service,
56+
options=options
57+
)
58+
59+
print("Chrome initialized successfully")
60+
61+
try:
62+
print(f"Navigating to URL: {url}")
63+
driver.get(url)
64+
65+
# Wait for page load
66+
print("Waiting for page to load...")
67+
driver.implicitly_wait(10) # Increased wait time
68+
69+
# Additional wait for dynamic content
70+
from selenium.webdriver.support.ui import WebDriverWait
71+
from selenium.webdriver.support import expected_conditions as EC
72+
WebDriverWait(driver, 10).until(
73+
lambda d: d.execute_script('return document.readyState') == 'complete'
74+
)
75+
76+
print("Taking screenshot...")
77+
driver.save_screenshot(output_file)
78+
print(f"Screenshot saved: {output_file}")
79+
return True
80+
81+
except Exception as e:
82+
print(f"Error during page capture: {str(e)}")
83+
raise
84+
finally:
85+
print("Closing Chrome...")
86+
driver.quit()
87+
88+
except Exception as e:
89+
print(f"Error initializing Chrome: {str(e)}")
90+
raise Exception(f"Failed to initialize Chrome: {str(e)}")
4791

4892
def capture_and_show(url: str):
4993
"""Capture webpage and return the image"""
5094
try:
5195
# Get the temporary directory path (defaulting to /tmp if TMPDIR is not set)
5296
temp_dir = os.getenv('TMPDIR', '/tmp')
53-
os.makedirs(temp_dir, exist_ok=True)
54-
55-
# Create temporary file in the specified directory
56-
temp_path = os.path.join(temp_dir, f"screenshot_{os.urandom(8).hex()}.png")
5797

58-
# Capture the webpage
59-
capture_page(url, temp_path)
60-
61-
# Return the image path
62-
return temp_path
98+
try:
99+
# Ensure temp directory exists and has correct permissions
100+
os.makedirs(temp_dir, mode=0o777, exist_ok=True)
101+
print(f"Using temp directory: {temp_dir}")
102+
103+
# Verify directory is writable
104+
if not os.access(temp_dir, os.W_OK):
105+
print(f"Warning: Temp directory {temp_dir} is not writable")
106+
# Try to create a user-specific temp directory instead
107+
temp_dir = os.path.join('/tmp', f'chrome_screenshots_{os.getuid()}')
108+
os.makedirs(temp_dir, mode=0o777, exist_ok=True)
109+
print(f"Created user-specific temp directory: {temp_dir}")
110+
111+
# Create temporary file in the specified directory
112+
temp_path = os.path.join(temp_dir, f"screenshot_{os.urandom(8).hex()}.png")
113+
print(f"Temp file path: {temp_path}")
114+
115+
# Capture the webpage
116+
success = capture_page(url, temp_path)
117+
if not success:
118+
print("Screenshot capture returned False")
119+
return None
120+
121+
# Verify file was created
122+
if not os.path.exists(temp_path):
123+
print("Screenshot file was not created")
124+
return None
125+
126+
print("Screenshot captured successfully")
127+
return temp_path
128+
129+
except OSError as e:
130+
print(f"OS Error: {str(e)}")
131+
print(f"Stack trace: {traceback.format_exc()}")
132+
return None
133+
63134
except Exception as e:
64-
print(f"Error in capture_and_show: {str(e)}") # Add detailed logging
65-
return None # Return None instead of error string to handle gracefully
135+
print(f"Error in capture_and_show: {str(e)}")
136+
print(f"Stack trace: {traceback.format_exc()}")
137+
return None
66138

67139
def create_gradio_app():
68140
"""Create the main Gradio application with all components"""

0 commit comments

Comments
 (0)