def setOptions(self, options): self.verboseLevel = getattr(options,'verboseLevel',0) self.notification = LNotificationItem() facility = getattr(options,'facility',NOTIFICATION_FACILITY_CHOICES[0]) self.notification.setFacility(facility) title = getattr(options,'title', NOTIFICATION_TITLE) self.notification.setTitle(title) body = getattr(options,'body', NOTIFICATION_TITLE) self.notification.setBody(body) socketId = getattr(options,'socketId',NOTIFIER_SOCKET_ID) self.setSocketId(socketId)
class LNotifierProcess(QObject): started = pyqtSignal() finished = pyqtSignal(int,int) error = pyqtSignal(int) def __init__(self, parent=None): super(LNotifierProcess,self).__init__(parent) self.debug = (DEBUG & THREADS) self.nextBlockSize = 0 self.request = None self.started.connect(self.on_process_started) self.finished.connect(self.on_process_finished) @LInAndOut(DEBUG & THREADS) def issuePyObject(self, pyobject): ''' Note that an Item needs to of class object and not class QObject !!! ''' self.request = QByteArray() stream = QDataStream(self.request, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_2) stream.writeUInt16(0) qVariant = QVariant(pyobject) if self.debug: print pyobject print qVariant.toPyObject() # <-- Works because it knows the qVariant type (class!!) # Indeed it uses the correct __str__ rountine!!! stream.writeQVariant(qVariant) stream.device().seek(0) nextBlockSize = self.request.size() - SIZEOF_UINT16 if self.debug: print "nextBlockSize = %d " % nextBlockSize stream.writeUInt16(nextBlockSize) if self.protocol == 'udp' : self.udpSocket = QUdpSocket() datagram = self.request self.udpSocket.bytesWritten.connect(self.on_udpSocket_bytesWritten) self.udpSocket.writeDatagram(datagram, QHostAddress(QHostAddress.Broadcast), self.portNumber) elif self.protocol == 'tcp': self.tcpSocket = QTcpSocket() self.connect(self.tcpSocket, SIGNAL("connected()"), self.on_tcpSocket_connected) self.connect(self.tcpSocket, SIGNAL("disconnected()"), self.on_tcpSocket_disconnected) self.connect(self.tcpSocket, SIGNAL("readyRead()"), self.on_tcpSocket_readyRead) self.connect(self.tcpSocket, SIGNAL("error(QAbstractSocket::SocketError)"), self.on_tcpSocket_error) self.connect(self.tcpSocket, SIGNAL("hostFound()"), self.on_tcpSocket_hostFound) if self.tcpSocket.isOpen(): self.tcpSocket.close() self.tcpSocket.connectToHost(self.serverName, self.portNumber) else: pass @LInAndOut(DEBUG & THREADS) def on_udpSocket_bytesWritten(self, nBytes): if self.debug: print "Wrote %d bytes" % nBytes self.quit() @LInAndOut(DEBUG & THREADS) def on_tcpSocket_hostFound(self): if self.verboseLevel : print "Found host!" @LInAndOut(DEBUG & THREADS) def on_tcpSocket_connected(self): ''' Once TCP connection is established ''' if self.verboseLevel : print "Sending packets..." self.nextBlockSize = 0 self.tcpSocket.write(self.request) self.request = None @LInAndOut(DEBUG & THREADS) def on_tcpSocket_readyRead(self): ''' Make sure acknowledgement is received ''' stream = QDataStream(self.tcpSocket) stream.setVersion(QDataStream.Qt_4_2) if self.verboseLevel : print "bytesAvailable on entry = %d" % self.tcpSocket.bytesAvailable() print "nextBlockSize on entry = %d" % self.nextBlockSize # 0 !!! while True: if self.nextBlockSize == 0: if self.tcpSocket.bytesAvailable() < SIZEOF_UINT16: if self.debug: print "Entire packet has been read and processed!" break self.nextBlockSize = stream.readUInt16() if self.debug: print "nextBlockSize (initialized) = %d" % self.nextBlockSize if self.tcpSocket.bytesAvailable() < self.nextBlockSize: if self.debug : print "Continue waiting for entire block..." break messageType = QString() stream >> messageType if messageType == "ACK": if self.verboseLevel: print "Acknowlegment received!" else: raise Exception("No ACK received!","Received %s" % messageType) self.nextBlockSize = 0 self.quit() # Close on success @LInAndOut(DEBUG & THREADS) def on_tcpSocket_disconnected(self): ''' Server has stopped ''' self.tcpSocket.close() @LInAndOut(DEBUG & THREADS) def on_tcpSocket_error(self, error): ''' Server has errors. If server not started -> Connection refused! ''' print "Error: %s" % ( self.tcpSocket.errorString() ) self.tcpSocket.close() self.quit() @LInAndOut(DEBUG & THREADS) def on_process_started(self): pass @LInAndOut(DEBUG & THREADS) def on_process_finished(self,exitCode,exitStatus): ''' process finished before socket is closed! ''' #qApp.quit() # No effect! pass @LInAndOut(DEBUG & THREADS) def on_process_error(self, error): self.quit() # Close on error #---------------------------------------------------------------------- @LInAndOut(DEBUG & THREADS) def setOptions(self, options): self.verboseLevel = getattr(options,'verboseLevel',0) self.notification = LNotificationItem() facility = getattr(options,'facility',NOTIFICATION_FACILITY_CHOICES[0]) self.notification.setFacility(facility) title = getattr(options,'title', NOTIFICATION_TITLE) self.notification.setTitle(title) body = getattr(options,'body', NOTIFICATION_TITLE) self.notification.setBody(body) socketId = getattr(options,'socketId',NOTIFIER_SOCKET_ID) self.setSocketId(socketId) @LInAndOut(DEBUG & THREADS) def setSocketId(self,socketId): socketArgs = socketId.split(':') self.serverName = socketArgs[0] self.portNumber = NOTIFIER_PORT_NUMBER self.protocol = NOTIFIER_PROTOCOL if len(socketArgs)>1 : self.portNumber = int(socketArgs[1]) if len(socketArgs)>2 : self.protocol = socketArgs[2] if self.verboseLevel: print "Connecting to server %s:%d using %s..." % (self.serverName, self.portNumber,self.protocol.upper()) #---------------------------------------------------------------------- @LInAndOut(DEBUG & THREADS) def start(self): self.signalStarted() exception = None try: self.issuePyObject(self.notification) except Exception as e: #Connection issue print e finally: exitCode = 0 exitStatus = 0 self.signalFinished(exitCode,exitStatus) def quit(self): QTimer.singleShot(250,qApp,SLOT(quit())) #---------------------------------------------------------------------- # Signals def signalStarted(self): self.started.emit() def signalFinished(self,exitCode,exitStatus): self.finished.emit(exitCode,exitStatus)