commit f27feb8f80119a91cee01e9f5a656568d5cfde92
parent e76843a741019a37a7af5c2034d836edb873d87c
Author: Vetle Haflan <vetle@haflan.dev>
Date: Sun, 24 Jan 2021 00:48:08 +0100
Add predir.py and make server store files sent to it from presenter
predir - present directory: For sharing the contents of a directory.
All files created, deleted or modified will be synced with the viewer.
Diffstat:
3 files changed, 76 insertions(+), 4 deletions(-)
diff --git a/index.html b/index.html
@@ -22,6 +22,7 @@
function connect(roomCode, present, openCallback) {
let url = "ws://" + document.location.host + (present ? "/pres/" : "/view/") + roomCode
window.ws = new WebSocket(url)
+ window.files = {}
ws.onclose = () => {
setStatus("No connection to the given room")
}
@@ -30,7 +31,9 @@
openCallback()
}
ws.onmessage = (msg) => {
- setCode(msg.data)
+ let fileReceived = JSON.parse(msg.data)
+ window.files[fileReceived.name] = fileReceived.contents
+ setCode(fileReceived.contents)
hljs.highlightBlock(document.getElementById("viewer"))
}
}
diff --git a/lipre.go b/lipre.go
@@ -1,6 +1,7 @@
package main
import (
+ "encoding/json"
"fmt"
"io/ioutil"
"log"
@@ -10,13 +11,15 @@ import (
"github.com/gorilla/websocket"
)
+// Not used - either read password from config / flag or define the valid rooms in a file on server
const temporaryCorrectRoomCode = "tester"
type Room struct {
code string
presenter *websocket.Conn
- // TODO:
- viewers []*websocket.Conn
+ viewers []*websocket.Conn
+ // Store files so that they can be sent to new viewers upon connection
+ files map[string][]byte
}
// TODO: Lock on this for concurrency?
@@ -32,6 +35,17 @@ func (room *Room) listen() {
delete(rooms, room.code)
return
}
+ file := struct {
+ Name string `json:"name"`
+ Contents string `json:"contents"`
+ }{}
+ err = json.Unmarshal(message, &file)
+ if err != nil {
+ log.Printf("error: %v", err)
+ // TODO: Send info to presenter
+ return
+ }
+ room.files[file.Name] = message
for _, viewerConn := range room.viewers {
if viewerConn == nil {
break
@@ -68,7 +82,7 @@ func presentHandler(w http.ResponseWriter, r *http.Request) {
log.Println(err)
return
}
- room := &Room{code: roomCode, presenter: conn}
+ room := &Room{code: roomCode, presenter: conn, files: make(map[string][]byte)}
rooms[roomCode] = room
go room.listen()
}
@@ -85,6 +99,9 @@ func viewHandler(w http.ResponseWriter, r *http.Request) {
return
}
room.viewers = append(rooms[roomCode].viewers, conn)
+ for _, filedata := range room.files {
+ conn.WriteMessage(websocket.TextMessage, filedata)
+ }
}
func main() {
diff --git a/predir.py b/predir.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python3
+
+from os import listdir
+from os.path import isfile, basename
+import pyinotify
+import json
+import sys
+import websocket
+
+def send_file(filename, contents):
+ fileobj = {
+ "name": filename,
+ "contents": contents
+ }
+ print(f'Sending {filename}')
+ ws.send(json.dumps(fileobj))
+
+
+program = sys.argv[0]
+if len(sys.argv) <= 1:
+ print(f"Use: {program} <room code>")
+ exit(1)
+room_code = sys.argv[1]
+
+HOST="localhost:8080"
+
+ws = websocket.WebSocket()
+ws.connect(f"ws://{HOST}/pres/{room_code}")
+
+# Initial file upload
+filenames = [fn for fn in listdir() if isfile(fn)]
+for fn in filenames:
+ send_file(fn, open(fn).read())
+
+# Listen for changes
+class EventHandler(pyinotify.ProcessEvent):
+ def process_IN_CREATE(self, event):
+ fn = basename(event.pathname)
+ send_file(fn, open(fn).read())
+ def process_IN_DELETE(self, event):
+ fn = basename(event.pathname)
+ send_file(fn, None)
+ def process_IN_MODIFY(self, event):
+ self.process_IN_CREATE(event)
+
+wm = pyinotify.WatchManager()
+handler = EventHandler()
+notifier = pyinotify.Notifier(wm, handler)
+mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_MODIFY
+wm.add_watch('.', mask)
+notifier.loop() +
\ No newline at end of file