Skip to content

Commit 0a9ab25

Browse files
committed
Fix route preview images in user namespace deployments
1 parent 077f442 commit 0a9ab25

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

.github/workflows/github-pages.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ jobs:
106106
- name: Generate route OpenGraph images
107107
if: steps.cache-route-images.outputs.cache-hit != 'true'
108108
run: make og-route-images
109+
env:
110+
URL_BASE_PATH: ${{ steps.pages.outputs.base_path }}
109111

110112
- name: Save OpenGraph route images to cache
111113
if: steps.cache-route-images.outputs.cache-hit != 'true'

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ check-schedules: $(SCHEDULE)
8686
check: check-images check-html check-javascript check-schedules
8787

8888
og-route-images:
89-
python _bin/generate_route_images.py
89+
python _bin/generate_route_images.py $(if $(URL_BASE_PATH),--base-path $(URL_BASE_PATH),)
9090

9191
serve: rcc.ics $(ROUTES_YML) $(ROUTE_GEOJSON_FILES)
9292
ls _config.yml | entr -r bundle exec jekyll serve --watch --drafts --host=0.0.0.0 $(JEKYLL_FLAGS)

_bin/generate_route_images.py

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
parser.add_argument('--port', type=int, default=0, help='Port for local server (0 = auto-select)')
4141
parser.add_argument('--incremental', action='store_true', help='Only generate images for new/changed routes')
4242
parser.add_argument('--workers', type=int, default=4, help='Number of parallel workers')
43+
parser.add_argument('--base-path', type=str, default='', help='Base path for serving content (e.g., __rcr__)')
4344
args = parser.parse_args()
4445

4546
os.makedirs(args.output_dir, exist_ok=True)
@@ -64,18 +65,49 @@ def find_free_port():
6465
s.close()
6566
return port
6667

67-
def start_http_server(directory, port):
68+
def start_http_server(directory, port, base_path=''):
6869
"""Start a local HTTP server in a separate thread"""
6970
os.chdir(directory)
70-
handler = http.server.SimpleHTTPRequestHandler
7171

72-
class QuietHTTPRequestHandler(handler):
72+
# Create a custom handler that can handle base path
73+
class BasePathHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
74+
def translate_path(self, path):
75+
"""
76+
Translate request path to actual file path, handling base path if present
77+
"""
78+
# Handle the root case first
79+
if path == '/':
80+
return super().translate_path('/')
81+
82+
# Special case: If base_path is just '/', all paths are served from root
83+
if base_path == '/':
84+
return super().translate_path(path)
85+
86+
# If base_path is specified and not empty
87+
if base_path:
88+
# Handle exact path match (with or without trailing slash)
89+
if path == f'/{base_path}' or path == f'/{base_path}/':
90+
return super().translate_path('/')
91+
92+
# Handle subpaths - make sure there's a / after base_path
93+
prefix = f'/{base_path}/'
94+
if path.startswith(prefix):
95+
# Remove the base path prefix and provide the rest to the parent method
96+
path = '/' + path[len(prefix):]
97+
98+
# Use the standard translation method from parent class
99+
return super().translate_path(path)
100+
73101
def log_message(self, format, *args):
74102
# Suppress server logs to avoid cluttering the output
75103
pass
76104

77-
with socketserver.TCPServer(("", port), handler) as httpd:
78-
logger.info(f"Started local server at http://localhost:{port}")
105+
with socketserver.TCPServer(("", port), BasePathHTTPRequestHandler) as httpd:
106+
base_url = f"http://localhost:{port}"
107+
if base_path:
108+
logger.info(f"Started local server at {base_url}/{base_path}")
109+
else:
110+
logger.info(f"Started local server at {base_url}")
79111
httpd.serve_forever()
80112

81113
@dataclass
@@ -106,6 +138,10 @@ def initialize(self):
106138
args=[
107139
"--disable-web-security", # Disable CORS
108140
"--enable-webgl",
141+
"--ignore-certificate-errors",
142+
"--allow-insecure-localhost",
143+
"--enable-unsafe-webgl",
144+
"--enable-unsafe-swiftshader"
109145
]
110146
)
111147
self.page = self.browser.new_page(viewport={"width": 1920, "height": 1080})
@@ -145,7 +181,7 @@ def process_route(task: RouteTask, quality: int) -> Optional[pathlib.Path]:
145181
logger.info(f"Processing {task.route_key} from {task.url}")
146182

147183
page.goto(task.url, wait_until="networkidle", timeout=30000)
148-
page.wait_for_selector("#map.loading-complete", timeout=10000)
184+
page.wait_for_selector("#map.loading-complete", timeout=60000)
149185
page.evaluate("""
150186
() => {
151187
const container = document.getElementById('route-map');
@@ -185,10 +221,14 @@ def generate_route_images():
185221
port = find_free_port()
186222
original_dir = os.getcwd()
187223

224+
base_path = args.base_path
225+
if base_path and base_path != '/':
226+
base_path = base_path.strip('/')
227+
188228
# Start HTTP server in a separate thread
189229
server_thread = threading.Thread(
190230
target=start_http_server,
191-
args=(args.site_dir, port),
231+
args=(args.site_dir, port, base_path),
192232
daemon=True
193233
)
194234
server_thread.start()
@@ -217,7 +257,12 @@ def generate_route_images():
217257
logger.info(f"Skipping {route_key} (unchanged)")
218258
continue
219259

220-
url = f"http://localhost:{port}/routes/{route_key}/"
260+
if base_path == '/' or not base_path:
261+
# If base_path is just '/', no need to add it
262+
url = f"http://localhost:{port}/routes/{route_key}/"
263+
else:
264+
url = f"http://localhost:{port}/{base_path}/routes/{route_key}/"
265+
221266
tasks.append(RouteTask(route_key, gpx_file, output_path, url))
222267

223268
if not tasks:

0 commit comments

Comments
 (0)