@@ -180,25 +180,29 @@ def create_file():
180
180
@script .command ()
181
181
@click .option ('--force' , '-f' , is_flag = True , default = False ,
182
182
help = 'Force push files from the local working directory onto the server' )
183
+ @click .option ('--watch' , '-w' , is_flag = True , default = False ,
184
+ help = "Watch for file changes in the script folder and push them to the server" )
183
185
@click .pass_context
184
- def push (ctx : click .Context , force : bool ):
186
+ def push (ctx : click .Context , force : bool , watch : bool ):
185
187
"""
186
188
Push contents of working_dir to server.
187
189
"""
190
+
188
191
check_session (ctx )
189
192
Request .COOKIES = cookiejar_from_dict (Config ().get ("cookies" , {}))
190
193
191
194
from .scriptor .module import TreeModule
192
195
tree = TreeModule ("script" )
193
196
194
- async def main ():
197
+ async def main (file_path : str = None ):
195
198
await tree .structure ("node" )
196
-
197
199
working_dir = Config ().get ("working_dir" )
198
200
_files = glob .glob (f"{ working_dir } /**/*" , recursive = True )
199
-
200
201
for file in _files :
201
202
_real_file = file
203
+ if file_path and file_path != _real_file :
204
+ # only push a single file
205
+ continue
202
206
parent = os .path .dirname (file )
203
207
_type = "leaf"
204
208
if os .path .isdir (file ):
@@ -224,27 +228,26 @@ async def main():
224
228
225
229
if hashlib .sha256 (entry ["script" ].encode ("utf-8" )).digest () \
226
230
!= hashlib .sha256 (file_content .encode ("utf-8" )).digest ():
227
- _state = force
228
- if not _state :
229
- _state = click .confirm (f"Content of { file } changed. Overwrite?" )
231
+ can_push = force
232
+ if not can_push :
233
+ can_push = click .confirm (f"Content of { file } changed. Overwrite?" )
230
234
231
- if _state :
235
+ if can_push :
232
236
click .echo (f"Push { _real_file } " )
233
237
await tree .edit (_type , entry ["key" ], {
234
238
"script" : file_content
235
239
})
236
240
237
241
except StopAsyncIteration :
238
- _state = False
239
242
text = "folder"
240
243
if _type == "leaf" :
241
244
text = "file"
242
245
243
- _state = force
244
- if not _state :
245
- _state = click .confirm (f"There is no { text } named { file } . Create it?" )
246
+ can_push = force
247
+ if not can_push :
248
+ can_push = click .confirm (f"There is no { text } named { file } . Create it?" )
246
249
247
- if _state :
250
+ if can_push :
248
251
root_node_entry = (await tree .list_root_nodes ())[0 ]
249
252
250
253
if not parent .endswith ("/" ):
@@ -286,6 +289,53 @@ async def main():
286
289
click .echo (f"Push { _real_file } " )
287
290
await tree .add (_type , args )
288
291
292
+
293
+
294
+ if watch :
295
+ print ("Watching..." )
296
+ def watch_loop ():
297
+ from watchdog .events import RegexMatchingEventHandler
298
+ from watchdog .observers import Observer
299
+ import time
300
+ modified_files = {}
301
+ def on_modified (event ):
302
+ # check for tmp file
303
+ if event .src_path .endswith ("~" ):
304
+ return
305
+ if event .src_path not in modified_files :
306
+ modified_files [event .src_path ] = os .path .getmtime (event .src_path )
307
+ elif os .path .getmtime (event .src_path ) == modified_files [event .src_path ]:
308
+ return
309
+ modified_files [event .src_path ] = os .path .getmtime (event .src_path )
310
+ asyncio .new_event_loop ().run_until_complete (main (event .src_path ))
311
+
312
+
313
+ regexes = [r".*\.py" ]
314
+ ignore_regexes = []
315
+ ignore_directories = True
316
+ case_sensitive = False
317
+ event_handler = RegexMatchingEventHandler (
318
+ regexes = regexes ,
319
+ ignore_regexes = ignore_regexes ,
320
+ ignore_directories = ignore_directories ,
321
+ case_sensitive = case_sensitive
322
+ )
323
+ event_handler .on_modified = on_modified
324
+
325
+
326
+
327
+ observer = Observer ()
328
+ observer .schedule (event_handler , Config ().get ("working_dir" ), recursive = True )
329
+ observer .start ()
330
+ try :
331
+ while True :
332
+ time .sleep (1 )
333
+ finally :
334
+ observer .stop ()
335
+ observer .join ()
336
+
337
+ asyncio .new_event_loop ().run_until_complete (watch_loop ())
338
+ return
289
339
asyncio .new_event_loop ().run_until_complete (main ())
290
340
291
341
0 commit comments