You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
4 years ago
|
# -*- coding: utf-8 -*-
|
||
|
import json
|
||
|
import socket
|
||
|
import threading
|
||
|
import messages
|
||
|
import model
|
||
|
import view
|
||
|
|
||
|
|
||
|
BUFFER_SIZE = 2 ** 10
|
||
|
|
||
|
|
||
|
class Application(object):
|
||
|
|
||
|
instance = None
|
||
|
|
||
|
def __init__(self, args):
|
||
|
self.args = args
|
||
|
self.closing = False
|
||
|
self.host = None
|
||
|
self.port = None
|
||
|
self.receive_worker = None
|
||
|
self.sock = None
|
||
|
self.username = None
|
||
|
self.ui = view.EzChatUI(self)
|
||
|
Application.instance = self
|
||
|
|
||
|
def execute(self):
|
||
|
if not self.ui.show():
|
||
|
return
|
||
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
|
try:
|
||
|
self.sock.connect((self.host, self.port))
|
||
|
except (socket.error, OverflowError):
|
||
|
self.ui.alert(messages.ERROR, messages.CONNECTION_ERROR)
|
||
|
return
|
||
|
self.receive_worker = threading.Thread(target=self.receive)
|
||
|
self.receive_worker.start()
|
||
|
self.ui.loop()
|
||
|
|
||
|
def receive(self):
|
||
|
while True:
|
||
|
try:
|
||
|
message = model.Message(**json.loads(self.receive_all()))
|
||
|
except (ConnectionAbortedError, ConnectionResetError):
|
||
|
if not self.closing:
|
||
|
self.ui.alert(messages.ERROR, messages.CONNECTION_ERROR)
|
||
|
return
|
||
|
self.ui.show_message(message)
|
||
|
|
||
|
def receive_all(self):
|
||
|
buffer = ""
|
||
|
while not buffer.endswith(model.END_CHARACTER):
|
||
|
buffer += self.sock.recv(BUFFER_SIZE).decode(model.TARGET_ENCODING)
|
||
|
return buffer[:-1]
|
||
|
|
||
|
def send(self, event=None):
|
||
|
message = self.ui.message.get()
|
||
|
if len(message) == 0:
|
||
|
return
|
||
|
self.ui.message.set("")
|
||
|
message = model.Message(username=self.username, message=message, quit=False)
|
||
|
try:
|
||
|
self.sock.sendall(message.marshal())
|
||
|
except (ConnectionAbortedError, ConnectionResetError):
|
||
|
if not self.closing:
|
||
|
self.ui.alert(messages.ERROR, messages.CONNECTION_ERROR)
|
||
|
|
||
|
def exit(self):
|
||
|
self.closing = True
|
||
|
try:
|
||
|
self.sock.sendall(model.Message(username=self.username, message="", quit=True).marshal())
|
||
|
except (ConnectionResetError, ConnectionAbortedError, OSError):
|
||
|
print(messages.CONNECTION_ERROR)
|
||
|
finally:
|
||
|
self.sock.close()
|