fstream/fstream-server.py
2021-04-14 01:15:11 +02:00

151 lines
3.0 KiB
Python

#!/usr/bin/env python3
import sys
oldexcepthook = sys.excepthook
def newexcepthook(type,value,traceback):
oldexcepthook(type,value,traceback)
input("Press ENTER to quit.")
sys.excepthook = newexcepthook
import os
p = os.path.join
pUp = os.path.dirname
s = False
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
s = os.path.realpath(sys.executable)
else:
s = os.path.realpath(__file__)
sp = pUp(s)
# script start
import threading
import queue
import socket
import subprocess
outThreads = {}
inThreads = {}
threadId = 0
threadsLock = threading.Lock()
serverAddr = ("127.0.0.1",12000)
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
bufferSize = 1000 # buffer size in bytes
def commandToList(cmd):
args = []
cArg = ""
escape = False
quoted = False
for letter in cmd:
if escape == True:
cArg += letter
escape = False
continue
if letter == "\\":
escape = True
continue
#if quoted == False and letter == ",":
if letter == ",":
if cArg == "": continue
args.append(cArg)
cArg = ""
continue
#if letter == '"':
# quoted = not quoted
# continue
cArg += letter
args.append(cArg)
return args
class outThread(threading.Thread):
def __init__(self,threadId,connection,address,user):
threading.Thread.__init__(self)
self.threadId = threadId
self.queue = queue.Queue()
self.connection = connection
self.address = address
self.user = user
def closeThread(self):
with threadsLock:
del outThreads[str(self.threadId)]
def run(self):
try:
while True:
data = self.queue.get()
self.connection.sendall(data)
self.closeThread()
except:
self.closeThread()
raise
class inThread(threading.Thread):
def __init__(self,threadId,connection,address):
threading.Thread.__init__(self)
self.threadId = threadId
self.connection = connection
self.address = address
def closeThread(self):
with threadsLock:
del inThreads[str(self.threadId)]
def run(self):
try:
global threadId
data = self.connection.recv(1000).decode("utf-8")
while data[-1] == " ": data = data[:-1]
args = commandToList(data)
cmd = args.pop(0)
user = args[0]
self.user = user
if len(args) > 1: self.password = args[1]
if cmd == "watch":
with threadsLock:
thread = outThread(self.threadId,self.connection,self.address,self.user)
outThreads[str(threadId)] = thread
thread.start()
return
if cmd == "broadcast":
while True:
data = self.connection.recv(bufferSize)
with threadsLock:
for thread in outThreads:
thread = outThreads[thread]
if thread.user == user:
thread.queue.put(data)
self.closeThread()
except:
self.closeThread()
raise
def main():
global threadId
serverSocket.bind(serverAddr)
serverSocket.listen(1024)
while True:
connection, address = serverSocket.accept()
connection.settimeout(15)
with threadsLock:
threadId += 1
thread = inThread(threadId,connection,address)
inThreads[str(threadId)] = thread
thread.start()
if __name__ == '__main__':
main()