Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 118 additions & 20 deletions Messanger/.idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 78 additions & 28 deletions Messanger/client/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,81 @@
import logging
import jim
import settings
import dis

class ClientVerifier(type):

def __init__(self, clsname, bases, clsdict):
self.verify_class(clsname, clsdict)
type.__init__(self, clsname, bases, clsdict)

def verify_class(self, clsname, clsdict):

socket_argval = None
for key, value in clsdict.items():
assert not isinstance(value, socket.socket), 'Creating socket in class level is forbidden'

instructions_list = dis.get_instructions(value)
for instruction in instructions_list:
if instruction.argval == 'socket' and instruction.opname == 'LOAD_GLOBAL':
while instruction.opname != 'STORE_ATTR':
instruction = next(instructions_list)
if instruction.opname == 'LOAD_ATTR' and instruction.arg == 2:
assert instruction.argval == 'SOCK_STREAM', 'Only SOCK_STREAM sockets is available'
socket_argval = instruction.argval

if socket_argval:
for key, value in clsdict.items():
forbidden_procs = ['listen', 'accept']
instructions_list = dis.get_instructions(value)
for instruction in instructions_list:
if instruction.argval == socket_argval:
next_instruction = next(instructions_list)
assert not (next_instruction.argval in forbidden_procs and
next_instruction.opname == 'LOAD_ATTR'), \
f"{clsname} have forbidden method {next_instruction.argval}"


class Client(metaclass=ClientVerifier):
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = None

def make_connection(self):
self.sock = socket.socket()
self.sock.connect((self.host, self.port))
logger.info(f'Client started with {self.host}:{self.port}')
print(f'Client started with {self.host}:{self.port}')

def get_presence_msg(self, action, data):
time = datetime.datetime.now()
msg = {
"action": action,
"time": time.isoformat(),
"user": {
"account_name": "anonim",
"status": "Yep, I am here!"
},
"data": data
}

return jim.pack(msg)

def send_request(self):
while True:
action = input('Enter action to send:')
data = input('Enter data to send:')

msg = self.get_presence_msg(action, data)
self.sock.sendall(msg)

def get_presence_msg(action, data):
time = datetime.datetime.now()
msg = {
"action": action,
"time": time.isoformat(),
"user": {
"account_name": "anonim",
"status": "Yep, I am here!"
},
"data": data
}

return jim.pack(msg)
def recv_response(self):
while True:
response = self.sock.recv(settings.BUFFERSIZE)
response = jim.unpack(response)
logger.info(f'Got next response from server: {response}')
print(f'Got next response from server: {response}')


host = getattr(settings, 'HOST', '127.0.0.1')
Expand Down Expand Up @@ -47,24 +107,14 @@ def get_presence_msg(action, data):
logger.addHandler(handler)

try:
sock = socket.socket()
sock.connect((host, port))
logger.info(f'Client started with {host}:{port}')
print(f'Client started with {host}:{port}')

if args.mode == 'w':
while True:
action = input('Enter action to send:')
data = input('Enter data to send:')
clientObj = Client(host, port)
clientObj.make_connection()

msg = get_presence_msg(action, data)
sock.sendall(msg)
if args.mode == 'w':
clientObj.send_request()
else:
while True:
response = sock.recv(settings.BUFFERSIZE)
response = jim.unpack(response)
logger.info(f'Got next response from server: {response}')
print(f'Got next response from server: {response}')
clientObj.recv_response()

except KeyboardInterrupt:
logger.info('Client closed')
Expand Down
Loading