summaryrefslogtreecommitdiffstats
path: root/nikola/plugins/command/auto/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'nikola/plugins/command/auto/__init__.py')
-rw-r--r--nikola/plugins/command/auto/__init__.py46
1 files changed, 30 insertions, 16 deletions
diff --git a/nikola/plugins/command/auto/__init__.py b/nikola/plugins/command/auto/__init__.py
index b13b645..d272c23 100644
--- a/nikola/plugins/command/auto/__init__.py
+++ b/nikola/plugins/command/auto/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2022 Chris Warrick, Roberto Alsina and others.
+# Copyright © 2012-2024 Chris Warrick, Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -35,6 +35,7 @@ import stat
import subprocess
import sys
import typing
+import urllib.parse
import webbrowser
import blinker
@@ -67,6 +68,17 @@ if sys.platform == 'win32':
asyncio.set_event_loop(asyncio.ProactorEventLoop())
+def base_path_from_siteuri(siteuri: str) -> str:
+ """Extract the path part from a URI such as site['SITE_URL'].
+
+ The path never ends with a "/". (If only "/" is intended, it is empty.)
+ """
+ path = urllib.parse.urlsplit(siteuri).path
+ if path.endswith("/"):
+ path = path[:-1]
+ return path
+
+
class CommandAuto(Command):
"""Automatic rebuilds for Nikola."""
@@ -239,8 +251,10 @@ class CommandAuto(Command):
# Server can be disabled (Issue #1883)
self.has_server = not options['no-server']
+ base_path = base_path_from_siteuri(self.site.config['SITE_URL'])
+
if self.has_server:
- loop.run_until_complete(self.set_up_server(host, port, out_folder))
+ loop.run_until_complete(self.set_up_server(host, port, base_path, out_folder))
# Run an initial build so we are up-to-date. The server is running, but we are not watching yet.
loop.run_until_complete(self.run_initial_rebuild())
@@ -293,9 +307,12 @@ class CommandAuto(Command):
if browser:
# Some browsers fail to load 0.0.0.0 (Issue #2755)
if host == '0.0.0.0':
- server_url = "http://127.0.0.1:{0}/".format(port)
- self.logger.info("Opening {0} in the default web browser...".format(server_url))
- webbrowser.open(server_url)
+ browser_url = "http://127.0.0.1:{0}/{1}".format(port, base_path.lstrip("/"))
+ else:
+ # server_url always ends with a "/":
+ browser_url = "{0}{1}".format(server_url, base_path.lstrip("/"))
+ self.logger.info("Opening {0} in the default web browser...".format(browser_url))
+ webbrowser.open(browser_url)
# Run the event loop forever and handle shutdowns.
try:
@@ -320,13 +337,13 @@ class CommandAuto(Command):
self.wd_observer.join()
loop.close()
- async def set_up_server(self, host: str, port: int, out_folder: str) -> None:
+ async def set_up_server(self, host: str, port: int, base_path: str, out_folder: str) -> None:
"""Set up aiohttp server and start it."""
webapp = web.Application()
webapp.router.add_get('/livereload.js', self.serve_livereload_js)
webapp.router.add_get('/robots.txt', self.serve_robots_txt)
webapp.router.add_route('*', '/livereload', self.websocket_handler)
- resource = IndexHtmlStaticResource(True, self.snippet, '', out_folder)
+ resource = IndexHtmlStaticResource(True, self.snippet, base_path, out_folder)
webapp.router.register_resource(resource)
webapp.on_shutdown.append(self.remove_websockets)
@@ -587,13 +604,11 @@ class NikolaEventHandler:
self.function = function
self.loop = loop
- async def on_any_event(self, event):
- """Handle all file events."""
- await self.function(event)
-
def dispatch(self, event):
"""Dispatch events to handler."""
- self.loop.call_soon_threadsafe(asyncio.ensure_future, self.on_any_event(event))
+ if event.event_type in {"opened", "closed"}:
+ return
+ self.loop.call_soon_threadsafe(asyncio.ensure_future, self.function(event))
class ConfigEventHandler(NikolaEventHandler):
@@ -601,11 +616,10 @@ class ConfigEventHandler(NikolaEventHandler):
def __init__(self, configuration_filename, function, loop):
"""Initialize the handler."""
+ super().__init__(function, loop)
self.configuration_filename = configuration_filename
- self.function = function
- self.loop = loop
- async def on_any_event(self, event):
+ def dispatch(self, event):
"""Handle file events if they concern the configuration file."""
if event._src_path == self.configuration_filename:
- await self.function(event)
+ super().dispatch(event)