Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
I'm currently using a static site generator (SSG) to convert a large collection of Markdown notes to a personal HTML/CSS wiki, but I decided to replace it with a Python script so I can fully custom...
#1: Initial revision
Python http.server how can I programatically refresh the browser page?
I'm currently using a static site generator (SSG) to convert a large collection of Markdown notes to a personal HTML/CSS wiki, but I decided to replace it with a Python script so I can fully customize every aspect of the site generation and my workflow. It's also something of a programming challenge/learning exercise for me.
I've already figured out how to create a local HTTP server and simultaneously watch the input files for changes (the actual site construction isn't implemented yet). However, my SSG also refreshes the browser page whenever the content updates so I don't have to do so manually, a convenience I'd like to include in my script. But I'm at a bit of a loss on how that can be done.
Here's my code so far:
```
# Import dependencies
import sys, signal
import _thread as thread
from http.server import HTTPServer, SimpleHTTPRequestHandler
from PyQt6.QtCore import QFileSystemWatcher, QTimer
from PyQt6.QtWidgets import QApplication
# Define server address and important directories
host = 'localhost'
port = 8000
contentDirectory = '/path/to/content'
siteDirectory = '/path/to/site'
# Define input paths for the filesystem watcher to periodically check for changes
paths = [
'/path/1',
'/path/2',
'/path/3',
]
# Define some colors with ANSI escape sequences
class color():
red = '\033[91m'
yellow = '\033[93m'
green = '\033[92m'
cyan = '\033[96m'
blue = '\033[94m'
magenta = '\033[95m'
white = '\033[97m'
end = '\033[0m'
# Function to be called when the input changes
def changeDetected(path):
print('Directory changed: ' + path)
# Handler for the SIGINT signal
def sigintHandler(*args):
QApplication.quit()
print(color.red + "\nServer stopped" + color.end)
# Function for closing the server on demand
def serverStopped():
server.server_close()
# Subclass SimpleHTTPRequestHandler so we can serve a specific directory
class Handler(SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=siteDirectory, **kwargs)
# Final setup
if __name__ == "__main__":
# Create the core app and the filesystem watcher
app = QApplication(sys.argv)
filesystemWatcher = QFileSystemWatcher(paths)
filesystemWatcher.directoryChanged.connect(changeDetected) # Run some code whenever the input changes
# Listen for signals - particularly Ctrl+C - in the terminal (needed for quitting the QApplication on demand)
signal.signal(signal.SIGINT, sigintHandler) # Implement custom handling for the SIGINT signal
timer = QTimer()
timer.start(500) # NOTE: Change time as needed
timer.timeout.connect(lambda: None) # Let the interpreter run every 500 milliseconds so signals come through
# Create and start the server
def startServer(): # Setup stuff here...
server = HTTPServer((host, port), Handler) # Create the server object
try: # Run the server until...
server.serve_forever()
except KeyboardInterrupt: # ...someone presses Ctrl+C
serverStopped()
thread.start_new_thread(startServer, ()) # Run it in a separate thread for concurrency with other code (particularly the filesystem watcher)
print(color.blue + f'Server started at http://{host}:{port} (Ctrl+C to stop)' + color.end)
# Run the event loop for the watcher
app.exec()
```
