diff --git a/big_chat/Client/authorization.py b/big_chat/Client/authorization.py index b1be7bc..760a0d5 100644 --- a/big_chat/Client/authorization.py +++ b/big_chat/Client/authorization.py @@ -1,14 +1,11 @@ from PyQt4 import Qt from PyQt4 import QtCore -import sys class AuthorizationWidget(object): - def __init__(self, validationFunc): if __name__ == "authorization": self.validationFunc = validationFunc - self.app = Qt.QApplication(sys.argv) self.window = Qt.QWidget() self.window.setWindowTitle("authorization") @@ -22,7 +19,6 @@ def __init__(self, validationFunc): self.layout.addWidget(self.label1) self.editNickname = Qt.QLineEdit() -# self.editNickname.setMaxLength(15) self.layout.addWidget(self.editNickname) self.label2 = Qt.QLabel("Enter your password:") @@ -31,9 +27,19 @@ def __init__(self, validationFunc): self.editPassword = Qt.QLineEdit() self.editPassword.setEchoMode(2) -# self.editPassword.setMaxLength(15) self.layout.addWidget(self.editPassword) + self.serverListLayout = Qt.QHBoxLayout() + self.serverListLabel = Qt.QLabel("Server:") + self.serverListLabel.setFixedWidth(35) + self.serverList = Qt.QComboBox() + servers = QtCore.QStringList(["gmail.com", "vkmessenger.com", "localhost"]) + self.serverList.addItems(servers) + self.serverListLayout.addWidget(self.serverListLabel) + self.serverListLayout.addWidget(self.serverList) + + self.layout.addLayout(self.serverListLayout) + self.bt1 = Qt.QPushButton("Ok") self.layout.addWidget(self.bt1) @@ -47,7 +53,8 @@ def __init__(self, validationFunc): Qt.QObject.connect(self.editPassword, Qt.SIGNAL("returnPressed()"), self.okBtListener) def okBtListener(self): - result = self.validationFunc(str(self.editNickname.text()), str(self.editPassword.text())) + result = self.validationFunc(str(self.editNickname.text()), str(self.editPassword.text()), + str(self.serverList.itemText(self.serverList.currentIndex()))) if result != True: self.labelError.setText('%s' % result) self.labelError.show() @@ -60,4 +67,4 @@ def close(self): def show(self): self.window.show() - self.app.exec_() + diff --git a/big_chat/Client/client.py b/big_chat/Client/client.py index 9147eeb..abcf602 100644 --- a/big_chat/Client/client.py +++ b/big_chat/Client/client.py @@ -1,28 +1,35 @@ from authorization import AuthorizationWidget from view import View from model import Model +from PyQt4 import Qt +import sys class Client(object): - def __init__(self): + self.app = Qt.QApplication(sys.argv) self.__authWidget = AuthorizationWidget(self.authValidator) - self.__view = View() + self.__view = View(self.app) self.__authWidget.show() + self.app.exec_() - def authValidator(self, login, password): + def authValidator(self, login, password, server): if login == "": - return "login is blank" + return "login is empty" if password == "": - return "password is blank" - - if login.replace(' ','') == "": - return "login contains only space" + return "password is empty" + if login.replace(' ', '') == "": + return "login contains only spaces" - # server = "gmail.com" - server = "localhost" - #server = "vkmessenger.com" + if server == "vkmessenger.com": + login += "@vk.com" + else: + if server == "gmail.com": + login += "@gmail.com" + else: + if server == "localhost": + login += "@localhost.ru" self.__model = Model() self.__view.setModel(self.__model) @@ -30,7 +37,7 @@ def authValidator(self, login, password): if self.__model.auth(login, password, server): self.__model.connect(login, password, server) else: - return "login or password is bad" + return "login or password is invalid" self.__authWidget.close() self.__view.show() diff --git a/big_chat/Client/model.py b/big_chat/Client/model.py index 80aff57..1bd254b 100644 --- a/big_chat/Client/model.py +++ b/big_chat/Client/model.py @@ -1,12 +1,10 @@ -# -*- coding: iso-8859-15 -*- - import xmpp import threading class Model: def __init__(self): self.presence = dict() - self.mess="a" + self.mess = "a" def connect(self, user, password, server): self.user = user @@ -14,12 +12,12 @@ def connect(self, user, password, server): self.connection.RegisterHandler('presence', self.presence_handler) self.connection.RegisterHandler('message', self.message_handler) self.connection.sendInitPresence() - t1 = threading.Thread(target=self.handlerThread,args=(self.connection,)) - t1.start() + self.t1 = threading.Thread(target=self.handlerThread, args=(self.connection,)) + self.t1.start() print self.presence - def auth(self,login,password,server): - self.connection = xmpp.Client(server,debug=['socket']) + def auth(self, login, password, server): + self.connection = xmpp.Client(server, debug=['socket']) self.connection.connect() jid = xmpp.JID(login) result = self.connection.auth(jid.getNode(), password, "LFY-client") @@ -27,26 +25,24 @@ def auth(self,login,password,server): return True return False - def addPresence(self,login): - self.presence[login]=1 + def addPresence(self, login): + self.presence[login] = 1 self.view.userCome(login) - print "add ",login + print "add ", login - def deletePresence(self,login): - # self.presence.remove(login) - print self.presence + def deletePresence(self, login): + self.presence.pop(login) self.view.userLeave(login) - def presence_handler(self,connect_object, message_node): - pp = message_node - to = pp.attrs.get('to') - frm = pp.attrs.get('from') - if(message_node.getType()=='unavailable'): + def presence_handler(self, connect_object, message_node): + to = message_node.attrs.get('to') + frm = message_node.attrs.get('from') + if(message_node.getType() == 'unavailable'): entry = str(frm.getStripped()) in self.presence if entry == False: return if str(frm.getStripped()) in self.presence: - self.presence[str(frm.getStripped())]-=1 + self.presence[str(frm.getStripped())] -= 1 if self.presence[str(frm.getStripped())] == 0: self.deletePresence(str(frm.getStripped())) else: @@ -56,31 +52,28 @@ def presence_handler(self,connect_object, message_node): if entry is False: self.addPresence(str(frm.getStripped())) else: - self.presence[str(str(frm.getStripped()))]+= 1 + self.presence[str(str(frm.getStripped()))] += 1 - def message_handler(self,connect_object, message_node): + def message_handler(self, connect_object, message_node): if message_node.getTag('active') is not None and message_node.getBody() is not None: self.view.receiveMessage(message_node.getFrom().getStripped(), message_node.getBody()) - def handlerThread(self,connection): + def handlerThread(self, connection): while connection.Process(1): pass - def sendMessage(self,user,mess): - mymsg = xmpp.protocol.Message(user,mess,"chat") + def sendMessage(self, user, mess): + mymsg = xmpp.protocol.Message(user, mess, "chat") self.connection.send(mymsg) - def send(self,user,mess): - self.mess=mess - self.sendMessage(user,self.mess) - + def send(self, user, mess): + self.mess = mess + self.sendMessage(user, self.mess) - def sendAll(self,mess): + def sendAll(self, mess): for user in self.presence: - self.send(user,mess) + self.send(user, mess) - def setView(self,_view): + def setView(self, _view): self.view = _view - - diff --git a/big_chat/Client/view.py b/big_chat/Client/view.py index e12d7e2..6fee8ac 100644 --- a/big_chat/Client/view.py +++ b/big_chat/Client/view.py @@ -1,15 +1,17 @@ from PyQt4 import Qt +from PyQt4 import QtGui import datetime -class View(object): - def __init__(self): +class View(QtGui.QWidget): + def __init__(self, app, parent=None): if __name__ == "view": - self.window = Qt.QWidget() - self.window.setMinimumSize(450, 300) - self.window.setWindowTitle("prototype client v0.03") + self.app = app + QtGui.QWidget.__init__(self, parent) + self.setMinimumSize(450, 300) + self.setWindowTitle("big_chat client v0.05") self.rootHBoxLayout = Qt.QHBoxLayout() - self.window.setLayout(self.rootHBoxLayout) + self.setLayout(self.rootHBoxLayout) self.chatVBoxLayout = Qt.QVBoxLayout() self.usersVBoxLayout = Qt.QVBoxLayout() @@ -64,22 +66,26 @@ def userLeave(self, login): def sendListener(self): if self.messageEdit.text() == "": - self.textEdit.append(" you can't send empty message
") + self.textEdit.append(" You can't send empty message
") + return + if self.userList.count() == 0: + self.textEdit.append(" Your friends are not online
") + return + if self.userList.currentItem() == None: + self.textEdit.append(" Select interlocutor or 'Send all'
") + return + + dt = datetime.datetime.now() + time = dt.strftime("%H:%M:%S") + if self.checkSendAll.isChecked(): + self.textEdit.append( + "I'm to all [" + time + ']
' + self.messageEdit.text()) + self.model.sendAll(self.messageEdit.text()) else: - dt = datetime.datetime.now() - time = dt.strftime("%H:%M:%S") - if self.checkSendAll.isChecked(): - self.textEdit.append("I'm to all [" + time + ']
' + self.messageEdit.text()) - self.model.sendAll(self.messageEdit.text()) - else: - if self.userList.currentItem() == None: - self.userList.setCurrentItem(self.userList.item(0)) - self.model.send(str(self.userList.currentItem().text()), self.messageEdit.text()) - self.textEdit.append("To " + self.userList.currentItem().text() + " [" + time + ']
' + self.messageEdit.text()) - self.messageEdit.clear() - - def show(self): - self.window.show() + self.model.send(str(self.userList.currentItem().text()), self.messageEdit.text()) + self.textEdit.append( + "To " + self.userList.currentItem().text() + " [" + time + ']
' + self.messageEdit.text()) + self.messageEdit.clear() def setModel(self, _model): self.model = _model @@ -87,4 +93,12 @@ def setModel(self, _model): def receiveMessage(self, login, message): dt = datetime.datetime.now() time = dt.strftime("%H:%M:%S") - self.textEdit.append('' + login + ' [' + time + ']
' + message) \ No newline at end of file + self.textEdit.append('' + login + ' [' + time + ']
' + message) + + def closeEvent(self, event): + reply = QtGui.QMessageBox.question(self, 'Message', "Are you sure?", QtGui.QMessageBox.Yes, + QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.Yes: + event.accept() + else: + event.ignore() \ No newline at end of file diff --git a/big_chat/README b/big_chat/README new file mode 100644 index 0000000..63b0674 --- /dev/null +++ b/big_chat/README @@ -0,0 +1,5 @@ +Для запуска клиента необходимо запустить client.py. Клиент подходит для различных xmpp-серверов. +Для запуска потребуется ввести логин(в формате "login@host") и пароль, а также выбрать домен сервера. +Также есть возможность общения через свой сервер, +для этого необходимо запустить start_server.py и прописать домен запущенного сервера в код клиента(по умолчанию можно протестировать на localhost). +Необходимые библиотеки : xmpp, twisted, pyqt4. \ No newline at end of file diff --git a/big_chat/Server/server.py b/big_chat/Server/server.py index 25eea30..d36b10f 100644 --- a/big_chat/Server/server.py +++ b/big_chat/Server/server.py @@ -1,10 +1,9 @@ -from twisted.internet import reactor from twisted.internet.protocol import ServerFactory from twisted.web.sux import XMLParser import base64 from stanza import Stanza import logging -#todo decorator + def get_step(number): file = open("Steps/step" + str(number) + ".xml") res = file.read() @@ -18,7 +17,6 @@ def __init__(self): self.realm = None self.login_res = None self.login = None - self.id = None self.stack_stanzas = [] self.success_auth = False @@ -28,7 +26,6 @@ def get_user_name(self): return self.username def gotTagStart(self, name, attributes): - # XMLParser.gotTagStart(self, name, attributes) stanza = Stanza(name, attributes) self.stack_stanzas.append(stanza) self.__handle_() @@ -76,7 +73,6 @@ def __handle_presence_(self, stanza): if client[0] != self.username: client[1].report_presence(self) - def __handle_message_(self, stanza): attrs = stanza.get_attrs() to = attrs['to'].split("@")[0] @@ -105,7 +101,6 @@ def handle_response(self, stanza): else: self.__send_(get_step(5)) - def handle_query(self, stanza): attrs = stanza.get_attrs() id = attrs["id"] @@ -157,8 +152,6 @@ def handle_query(self, stanza): def connectionLost(self, reason): self.report_presence_unavailable() self.factory.remove_user(self.username) - # XMLParser.connectionLost(self,reason) - def report_presence(self, other_user): stanza = Stanza("presence", {'from': other_user.login, 'to': self.login_res}) @@ -169,22 +162,17 @@ def report_presence_unavailable(self): stanza = Stanza("presence", {'from': self.login, 'to': user[1].login_res, 'type': 'unavailable'}) user[1].__send_(stanza.to_xml()) - def add_user(self): self.factory.add_client(self) - def gotTagEnd(self, name): - # XMLParser.gotTagEnd(self, name) stack = self.stack_stanzas stanza = stack.pop() stanza.close() stack.append(stanza) self.__handle_() - def gotText(self, data): - # XMLParser.gotText(self, data) length = len(self.stack_stanzas) if length > 0: self.stack_stanzas[length - 1].add_text(data) @@ -193,7 +181,6 @@ def gotText(self, data): class ChatProtocolFactory(ServerFactory): protocol = XMLChatProtocol - def __init__(self, host): self.__clients_ = {} #user_name - > XMLChatProtocol todo add support resourses self.__host_ = host diff --git a/big_chat/Server/start_server.py b/big_chat/Server/start_server.py index c59102f..80b39ca 100644 --- a/big_chat/Server/start_server.py +++ b/big_chat/Server/start_server.py @@ -2,12 +2,12 @@ import logging from server import ChatProtocolFactory -def start(host = 'localhost',port = 5222): - logging.info( "Starting Server in " + host +":"+`port`) +def start(host='localhost', port=5222): + logging.info("Starting Server in " + host + ":" + `port`) factory = ChatProtocolFactory(host) reactor.listenTCP(port, factory) reactor.run() -if __name__=="__main__": - logging.basicConfig(level = logging.DEBUG) +if __name__ == "__main__": + logging.basicConfig(level=logging.DEBUG) start() \ No newline at end of file