Skip to content

Commit 9557103

Browse files
committed
pure python live reload server
1 parent 9a6f1a9 commit 9557103

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

bin.Darwin/lrs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
3+
# Live Reload Server
4+
5+
import argparse
6+
import os
7+
import http.server
8+
import socket
9+
import socketserver
10+
11+
def parse_arguments():
12+
parser = argparse.ArgumentParser(description='Run a live reload HTTP server for static files.')
13+
parser.add_argument('--port', type=int, default=8000, help='Specify the port number (default: 8000).')
14+
parser.add_argument('--dir', default=os.getcwd(), help='Specify the directory to serve (default: current directory).')
15+
parser.add_argument('--mode', default="", help='Specify the mode to monitor changes (options are html, js, css, or a combination such as html,css. Default: empty, to monitor all changes).')
16+
parser.add_argument('--verbose', action='store_true', help='Output verbose message.')
17+
return parser.parse_args()
18+
19+
class RequestHandler(http.server.SimpleHTTPRequestHandler):
20+
def __init__(self, *args, mode=None, **kwargs):
21+
self.mode = mode
22+
super().__init__(*args, **kwargs)
23+
24+
def translate_path(self, path):
25+
path = http.server.SimpleHTTPRequestHandler.translate_path(self, path)
26+
if os.path.isdir(path):
27+
for ext in "html", "htm":
28+
index = f'{path}index.{ext}'
29+
if os.path.exists(index):
30+
return index
31+
return path
32+
33+
def end_headers(self):
34+
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate')
35+
self.send_header('Pragma', 'no-cache')
36+
self.send_header('Expires', '0')
37+
super().end_headers()
38+
39+
def do_GET(self):
40+
file_path = self.translate_path(self.path)
41+
if file_path.endswith((".html", ".htm")):
42+
with open(file_path, 'r', encoding='utf-8') as f:
43+
content = f.read()
44+
45+
reload_mode = '#' + self.mode if self.mode else '';
46+
# Not valid HTML here, but works, acceptable for development only
47+
content += f'<script src="//livejs.com/live.js{reload_mode}"></script>';
48+
self.send_response(200)
49+
self.send_header("Content-type", "text/html")
50+
self.end_headers()
51+
self.wfile.write(content.encode('utf-8'))
52+
else:
53+
super().do_GET()
54+
55+
if __name__ == "__main__":
56+
cmd_args = parse_arguments()
57+
class Handler(RequestHandler):
58+
def __init__(self, *args, **kwargs):
59+
super().__init__(*args, mode=cmd_args.mode, directory=cmd_args.dir, **kwargs)
60+
61+
def log_message(self, format, *args):
62+
if cmd_args.verbose:
63+
super().log_message(format, *args)
64+
else:
65+
pass
66+
67+
socketserver.TCPServer.allow_reuse_address = True
68+
with socketserver.TCPServer(("", cmd_args.port), Handler) as httpd:
69+
print(f"Serving on http://127.0.0.1:{cmd_args.port}")
70+
httpd.serve_forever()

0 commit comments

Comments
 (0)