lipre

Stream text files for live (coding) representations
Log | Files | Refs

lipre.py (2185B)


      1 #!/usr/bin/python3
      2 
      3 from os import listdir, getenv
      4 from os.path import isfile, basename
      5 import pyinotify
      6 import json
      7 import re
      8 import sys
      9 import websocket
     10 
     11 IGNOREFILE='.lpignore'
     12 ignorefilelist = []
     13 
     14 def should_ignore(filename):
     15     for to_ignore in ignorefilelist:
     16         # Make a regex from the asterix
     17         match = re.search(to_ignore.replace("*", ".*"), filename)
     18         if match:
     19             return True
     20     return False
     21 
     22 def send_file(filename):
     23     if should_ignore(filename):
     24         return
     25     if isfile(filename):
     26         contents = open(filename).read()
     27     else:
     28         contents = None
     29     fileobj = {
     30             'name': filename,
     31             'contents': contents
     32     }
     33     print(f'Sending {filename}')
     34     ws.send(json.dumps(fileobj))
     35 
     36 def closed():
     37     print('Connection closed')
     38     exit()
     39 
     40 program = sys.argv[0]
     41 if len(sys.argv) <= 1:
     42     print(f'Use: {program} <room code> [host]')
     43     exit(1)
     44 room_code = sys.argv[1]
     45 
     46 if getenv('LPHOST'):
     47     HOST = getenv('LPHOST')
     48 elif len(sys.argv) >= 3:
     49     HOST = sys.argv[2]
     50 else:
     51     HOST = 'ws://localhost:8080'
     52 
     53 if ':' in room_code:
     54     code, linger = room_code = room_code.split(':')
     55     url = f'{HOST}/ws/pres/{code}?linger={linger}'
     56 else:
     57     url = f'{HOST}/ws/pres/{room_code}'
     58 
     59 if isfile(IGNOREFILE):
     60     ignorefilelist = [fn for fn in open(IGNOREFILE).read().split('\n') if fn]
     61 
     62 
     63 # Listen for changes
     64 class EventHandler(pyinotify.ProcessEvent):
     65     def process_IN_CREATE(self, event):
     66         fn = basename(event.pathname)
     67         send_file(fn)
     68     def process_IN_DELETE(self, event):
     69         fn = basename(event.pathname)
     70         send_file(fn)
     71     def process_IN_MODIFY(self, event):
     72         self.process_IN_CREATE(event)
     73 
     74 def present():
     75     # Initial file upload
     76     filenames = [fn for fn in listdir() if isfile(fn)]
     77     for fn in filenames:
     78         send_file(fn)
     79     # Continously watch for changes
     80     wm = pyinotify.WatchManager()
     81     handler = EventHandler()
     82     notifier = pyinotify.Notifier(wm, handler)
     83     mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_MODIFY
     84     wm.add_watch('.', mask)
     85     notifier.loop()
     86 
     87 ws = websocket.WebSocket()
     88 ws.connect(url)
     89 ws.on_close = closed
     90 present()