1818 print ("Missing required dependency 'PyYAML'. Install with: pip install pyyaml" , file = sys .stderr )
1919 sys .exit (1 )
2020
21- try :
22- from watchdog .observers import Observer
23- from watchdog .events import FileSystemEventHandler
24- except Exception :
25- Observer = None
26- FileSystemEventHandler = None
27-
2821
2922def parse_playbook (playbook_path : Path ):
3023 data = yaml .safe_load (playbook_path .read_text (encoding = 'utf-8' )) or {}
@@ -69,106 +62,6 @@ def clean_site(site_dir: Path):
6962 print ('Nothing to remove at' , site_dir )
7063
7164
72- def serve_dir (site_dir : Path , host : str , port : int ):
73- handler = http .server .SimpleHTTPRequestHandler
74- os .chdir (site_dir )
75- with socketserver .ThreadingTCPServer ((host , port ), handler ) as httpd :
76- print (f'Serving { site_dir } at http://{ host } :{ port } /' )
77- try :
78- httpd .serve_forever ()
79- except KeyboardInterrupt :
80- pass
81-
82-
83- def preview (playbook : Path , site_dir : Path , paths_to_watch , interval , host , port ):
84- if Observer is None or FileSystemEventHandler is None :
85- print ("Missing optional dependency 'watchdog'. Install with: pip3 install watchdog" , file = sys .stderr )
86- sys .exit (1 )
87-
88- if not site_dir .exists ():
89- run_build (playbook )
90- chosen_site = site_dir
91-
92- class Handler (FileSystemEventHandler ):
93- def __init__ (self , build_cb , debounce = 0.5 ):
94- self .build_cb = build_cb
95- self .debounce = debounce
96- self ._timer = None
97- self ._lock = threading .Lock ()
98-
99- def _trigger_build (self ):
100- try :
101- self .build_cb ()
102- finally :
103- with self ._lock :
104- self ._timer = None
105-
106- def _debounce (self ):
107- with self ._lock :
108- if self ._timer :
109- self ._timer .cancel ()
110- t = threading .Timer (self .debounce , self ._trigger_build )
111- self ._timer = t
112- t .daemon = True
113- t .start ()
114-
115- # Trigger rebuild on create/delete/move/modify for files
116- def on_created (self , event ):
117- if not event .is_directory :
118- self ._debounce ()
119-
120- def on_deleted (self , event ):
121- if not event .is_directory :
122- self ._debounce ()
123-
124- def on_moved (self , event ):
125- if not event .is_directory :
126- self ._debounce ()
127-
128- def on_modified (self , event ):
129- if not event .is_directory :
130- self ._debounce ()
131-
132- observer = Observer ()
133- handler = Handler (lambda * args : run_build (playbook ), debounce = interval )
134- for p in paths_to_watch :
135- if p .exists () and p .is_dir ():
136- target = p
137- elif p .exists ():
138- target = p .parent
139- else :
140- target = p
141- try :
142- print (p , paths_to_watch )
143- observer .schedule (handler , str (target ), recursive = True )
144- except Exception :
145- print (f'Warning: failed to watch { target } ' )
146-
147- os .chdir (chosen_site )
148- httpd = socketserver .ThreadingTCPServer ((host , port ), http .server .SimpleHTTPRequestHandler )
149- server_thread = threading .Thread (target = httpd .serve_forever )
150- server_thread .start ()
151- observer .start ()
152-
153- try :
154- while True :
155- time .sleep (1 )
156- except KeyboardInterrupt :
157- print ('Shutting down...' )
158- observer .stop ()
159- observer .join ()
160- try :
161- httpd .shutdown ()
162- except Exception :
163- pass
164- server_thread .join ()
165- try :
166- httpd .server_close ()
167- except Exception :
168- pass
169- print ('Stopping preview' )
170-
171-
17265def find_site_dir (base : Path ):
17366 if (path := base / 'build' / 'site' ).exists ():
17467 return path
@@ -182,11 +75,7 @@ def main():
18275 sub = parser .add_subparsers (dest = 'cmd' )
18376 sub .add_parser ('build' )
18477 sub .add_parser ('clean' )
185- preview_p = sub .add_parser ('preview' )
186- preview_p .add_argument ('--interval' , type = float , default = 1.0 )
187- preview_p .add_argument ('--host' , default = '0.0.0.0' )
188- preview_p .add_argument ('--port' , type = int , default = 8000 )
189-
78+
19079 args = parser .parse_args ()
19180 playbook = args .playbook
19281 if not playbook .exists ():
@@ -198,9 +87,6 @@ def main():
19887 run_build (playbook )
19988 elif args .cmd == 'clean' :
20089 clean_site (site_dir )
201- elif args .cmd == 'preview' :
202- paths = parse_playbook (playbook )
203- preview (playbook , site_dir , paths , args .interval , args .host , args .port )
20490 else :
20591 parser .print_help ()
20692
0 commit comments