def _parse(self): if self.buffer.bytesAvailable() >= 4: stream = QDataStream(self.buffer) msg = Message.fromInt(stream.readInt32()) if msg == None: return args = [] bytesRead = 4 for aType in msg.argTypes: if aType == str: if self.buffer.bytesAvailable() < 4: return length = stream.readInt32() if self.buffer.bytesAvailable() < length: return args.append(stream.readRawData(length)) bytesRead += 4 + length elif aType == int: if self.buffer.bytesAvailable() < 4: return args.append(stream.readInt32()) bytesRead += 4 elif aType == long: if self.buffer.bytesAvailable() < 8: return args.append(stream.readInt64()) bytesRead += 8 return (msg, args, bytesRead)
def _onReadyRead(self): while self._socket.bytesAvailable() >= 4: ds = QDataStream(self._socket) ds.setByteOrder(QDataStream.LittleEndian) # Header packet if self.header is None: size, = unpack('=l', self._socket.peek(4)) if self._socket.bytesAvailable() < size + 4: return #Omit size ds.readUInt32() self.header = ds.readRawData(size).decode() # Chunks packet else: if self.nchunks == -1: self.nchunks = ds.readUInt32() self.chunks = [] while len(self.chunks) < self.nchunks: chunk = self._readLuaVal(ds) if chunk is None: return self.chunks.append(chunk) # Packet pair reading done. self._logger.info("GC >> : %s : %s", self.header, self.chunks) self.messageReceived.emit(self.header, self.chunks) self.header = None self.nchunks = -1 self.chunks = None
def unpackPrnFile(self): fileName = QFileDialog.getOpenFileName(self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open',QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadOnly): QMessageBox.warning(self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) file_name = QFileInfo(file).fileName() headerVersion = int.from_bytes(data.readRawData(4), 'little', signed=False) self.status.showMessage("Header Type: {:#X}".format(headerVersion)) if headerVersion == self.NEW_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) name = b'\xff\xfe' + data.readRawData(512) name = name.decode('utf-16').replace(chr(0), '') zero = data.readInt32() elif headerVersion == self.STD_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' elif headerVersion == self.CALDERA_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' else: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colors = {} for color in colorList: colors[color] = {} for level in range(1, 2**bitsperdrop): colors[color][level] = QImage(imgw, imgh , QImage.Format_Mono) colors[color][level].setColor(0, qRgb(255, 255, 255)) colors[color][level].setColor(1, qRgb(0, 0, 0)) colors[color][level].fill(0) pd = QProgressDialog('Analyze file ...', 'Cancel', 0, imgh-1, self) pd.setWindowTitle('Analyze ...') pd.open() mask = 0xFF>>(8-bitsperdrop) # Получаем маску для текущего количества бит на каплю for row in range(imgh): for color in colorList: for bytenum in range(0, bpl, bitsperdrop): # Получаем номер байта, с которого будем читать byte = int.from_bytes(data.readRawData(bitsperdrop), 'big') for pix in range(8): shift = (7 - pix)*bitsperdrop pixel = (byte>>shift)&mask if pixel > 0: numofpix = 8*bytenum/bitsperdrop + pix if numofpix < imgw: colors[color][pixel].setPixel(numofpix, row, 1) pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() catalog = QFileDialog.getExistingDirectory(self, directory=self.settings.value('unpacker/dir_save',QDir.currentPath())) if catalog is None: return self.settings.setValue('unpacker/dir_save', catalog) file = QFile("{}\{}_{}.txt".format(catalog, file_name, colorOrder)) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, "Prn creator", "Unable create file {}:\n{}.".format(name, file.errorString())) return text = QTextStream(file) text << "Filename: {}\n".format(file_name) text << "Test Name: {}\n\n".format(name) text << "X Resolution: {} dpi\n".format(xdpi) text << "Y Resolution: {} dpi\n".format(ydpi) text << "Image Width: {} pix\n".format(imgw) text << "Image Height: {} pix\n\n".format(imgh) text << "Bits Per Drop: {}\n".format(bitsperdrop) text << "Bytes Per Line: {}\n\n".format(bpl) text << "Number Of Colors: {}\n".format(colnum) text << "Order Of Colors: {}\n\n".format(colorOrder) text << "Paper Width: {}\n".format(ppw) for color in colorList: for level in range(1, 2**bitsperdrop): colors[color][level].save("{}\{}.{}.gs{}.tif".format(catalog, file_name, "{}".format(color) if color.isupper() else "_{}".format(color), level)) self.status.showMessage("Unpacking finished", 7000)
def unpackPrnFile(self): fileName = QFileDialog.getOpenFileName( self, 'Load .prn file', directory=self.settings.value('unpacker/dir_open', QDir.currentPath()), filter='PRN files (*.prn *.bin);;All (*)') if not fileName: return file = QFile(fileName) if not file.open(QFile.ReadOnly): QMessageBox.warning( self, "Unpacker .prn", "Unable load file {}:\n{}.".format(fileName, file.errorString())) return self.settings.setValue('unpacker/dir_open', QFileInfo(file).path()) data = QDataStream(file) data.setByteOrder(QDataStream.LittleEndian) file_name = QFileInfo(file).fileName() headerVersion = int.from_bytes(data.readRawData(4), 'little', signed=False) self.status.showMessage("Header Type: {:#X}".format(headerVersion)) if headerVersion == self.NEW_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) name = b'\xff\xfe' + data.readRawData(512) name = name.decode('utf-16').replace(chr(0), '') zero = data.readInt32() elif headerVersion == self.STD_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' elif headerVersion == self.CALDERA_RIP_FILE: xdpi = data.readInt32() ydpi = data.readInt32() bpl = data.readInt32() imgh = data.readInt32() imgw = data.readInt32() ppw = data.readInt32() colnum = data.readInt32() bitsperdrop = data.readInt32() if not bitsperdrop: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colorOrder = data.readRawData(16).decode().replace(chr(0), '') colorList = list(colorOrder) zero = data.readInt32() name = 'Not used in this format' else: QMessageBox.warning(self, "Unpacker .prn", "File format not supported") return colors = {} for color in colorList: colors[color] = {} for level in range(1, 2**bitsperdrop): colors[color][level] = QImage(imgw, imgh, QImage.Format_Mono) colors[color][level].setColor(0, qRgb(255, 255, 255)) colors[color][level].setColor(1, qRgb(0, 0, 0)) colors[color][level].fill(0) pd = QProgressDialog('Analyze file ...', 'Cancel', 0, imgh - 1, self) pd.setWindowTitle('Analyze ...') pd.open() mask = 0xFF >> ( 8 - bitsperdrop ) # Получаем маску для текущего количества бит на каплю for row in range(imgh): for color in colorList: for bytenum in range( 0, bpl, bitsperdrop ): # Получаем номер байта, с которого будем читать byte = int.from_bytes(data.readRawData(bitsperdrop), 'big') for pix in range(8): shift = (7 - pix) * bitsperdrop pixel = (byte >> shift) & mask if pixel > 0: numofpix = 8 * bytenum / bitsperdrop + pix if numofpix < imgw: colors[color][pixel].setPixel(numofpix, row, 1) pd.setValue(row) if pd.wasCanceled(): pd.close() file.close() return pd.close() file.close() catalog = QFileDialog.getExistingDirectory( self, directory=self.settings.value('unpacker/dir_save', QDir.currentPath())) if catalog is None: return self.settings.setValue('unpacker/dir_save', catalog) file = QFile("{}\{}_{}.txt".format(catalog, file_name, colorOrder)) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning( self, "Prn creator", "Unable create file {}:\n{}.".format(name, file.errorString())) return text = QTextStream(file) text << "Filename: {}\n".format(file_name) text << "Test Name: {}\n\n".format(name) text << "X Resolution: {} dpi\n".format(xdpi) text << "Y Resolution: {} dpi\n".format(ydpi) text << "Image Width: {} pix\n".format(imgw) text << "Image Height: {} pix\n\n".format(imgh) text << "Bits Per Drop: {}\n".format(bitsperdrop) text << "Bytes Per Line: {}\n\n".format(bpl) text << "Number Of Colors: {}\n".format(colnum) text << "Order Of Colors: {}\n\n".format(colorOrder) text << "Paper Width: {}\n".format(ppw) for color in colorList: for level in range(1, 2**bitsperdrop): colors[color][level].save("{}\{}.{}.gs{}.tif".format( catalog, file_name, "{}".format(color) if color.isupper() else "_{}".format(color), level)) self.status.showMessage("Unpacking finished", 7000)
class TcpClient(timedthread.TimedThread): """ TCP-клиент в отдельном потоке, """ # Константы TCPP_CONNECTTIMEOUT = 5000 # таймаут подключения (ms) # Сигналы: connectionFailed = pyqtSignal(str) tcpClientError = pyqtSignal(str) connected = pyqtSignal() disconnected = pyqtSignal() incomingMessage = pyqtSignal() def __init__(self): super(TcpClient, self).__init__("tcp_client") # Mutex и буферы для приема и отправки сообщений из всех потоков log.debug("Создан TCP-клиент") # Введена ПОТЕНЦИАЛЬНАЯ возможность восстанавливать связь при разрыве # Параметры для подключения self._m_HostaAddr = QHostAddress() self._socket = None self._stream = None # Переменные состояния self.m_bConnected = False self.m_bShouldConnect = False self.m_bShouldDisconnect = False self.m_bError = False self.pingCounter = 0 def connectToHost(self, addr, port=9110): # Функция подключения к принтеру. if self.m_bConnected: # Если уже подключены - ничего не делаем return 2 if not self._m_HostaAddr.setAddress(addr): print('"{}"'.format(addr)) # Если адрес указан неверно, выходим со знаком минус и выводим сообщение в лог print("Невенро указан адрес подключения!") return 0 try: self._m_Port = int(port) except ValueError as e: print("Неверно задан номер порта (не числовое значение): {}!".format( e)) self.m_bShouldConnect = True self.m_bConnected = False self.m_bShouldDisconnect = False self.m_bError = False if not self.isRunning(): self.start() return 1 def disconnectFromHost(self, waitTime): # Функция отключения от принтера. Время ожидания не обрабатывается, поэтому переменную состояния отключения выставляем сразу log.debug('Should disconnect') self.m_bShouldDisconnect = True def workThread(self): """ Основная функция треда Не учитывается время с последней отправки и с последнего приема """ super(TcpClient, self).workThread() if self._socket is not None and self.m_bConnected: if self._socket.error() != -1 and not self.m_bError: self.m_bError = True # Требуется отключение if self.m_bError: # Сообщаем, что произошла ошибка и в сигнале передаем описание self.onSocketError() elif self.m_bShouldDisconnect and self.m_bConnected: log.debug('try disconnect') if self._socket.isOpen(): self._socket.disconnectFromHost() self._socket.close() self._socket.disconnected.disconnect(self.disconnected) self._socket.connected.disconnect(self.connected) self.m_bShouldDisconnect = False self.m_bConnected = False log.debug('Отключаемся от принтера по адресу {}:{}'.format(self._m_HostaAddr.toString(), self._m_Port)) # Требуется подключение elif self.m_bShouldConnect and not self.m_bConnected: self.m_bShouldConnect = False # Если сокет уже открыт, а подключения нет, то лучше его убить и создать новый if self._socket is None: self._socket = QTcpSocket() elif self._socket.isOpen(): self._socket.disconnectFromHost() self._socket.close() del self._socket self._socket = QTcpSocket() self._stream = QDataStream(self._socket) # Обрабатываем изменения состояния сокета и его ошибки. self._socket.disconnected.connect(self.disconnected) self._socket.connected.connect(self.connected) log.debug("Начинаем подключение к принтеру {}:{}".format(self._m_HostaAddr.toString(), self._m_Port)) # Подключаемся к принтеру self._socket.connectToHost(self._m_HostaAddr, self._m_Port) # Если время ожидания истекло, то отправляем сигнал об этом if not self._socket.waitForConnected(self.TCPP_CONNECTTIMEOUT): self.m_bConnected = False self.m_bError = True # log.warning(self._langManager.getString(__name__, "timeout")) log.debug("Время ожидания истекло. Соединение не установлено!") self._socket.disconnected.disconnect(self.disconnected) self._socket.connected.disconnect(self.connected) self.connectionFailed.emit('TimeOut') else: self.m_bConnected = True self.m_bError = False log.debug('Установлено подключение с {}:{}'.format(self._m_HostaAddr.toString(), self._m_Port)) #self.connected.emit('Установлено подключение с принтером по адресу {0}:{1}'.format(self._m_HostaAddr.toString(), self._m_Port)) # Прием и отправка пакетов elif self.m_bConnected: packetCounter = 0 # Получение пкаетов while self._socket.bytesAvailable()>16: if packetCounter > 255: break # Если принято больше 255 пакетов, то приостанавливаем прием, чтоб другим дать возможность поработать ^_^ # Распаковываем данные из сокета: тип, длина, 2байта время, 4байта ID, 8байт данных byteInfo = self._stream.readRawData(8) byteCommand = self._stream.readRawData(2) byteData = self._stream.readRawData(6) canPacket = CanPacket() canPacket.unpackData(struct.unpack('<2BHL' ,byteInfo), struct.unpack('<2B', byteCommand), struct.unpack('<HBBBB', byteData), byteData) # запихиваем пакет в буфер logCan.info("{}".format(canPacket)) packetCounter += 1 return True def onSocketError(self): self.m_bConnected = False self.m_bShouldConnect = False self.m_bShouldDisconnect = False self.m_bError = False self.tcpClientError.emit('{}'.format(self._socket.errorString())) print('{}: [{}] {}'.format('Connection error', self._socket.error(), self._socket.errorString()))
class TcpClient(timedthread.TimedThread): """ TCP-клиент в отдельном потоке, """ # Константы TCPP_CONNECTTIMEOUT = 5000 # таймаут подключения (ms) # Сигналы: connectionFailed = pyqtSignal(str) tcpClientError = pyqtSignal(str) connected = pyqtSignal() disconnected = pyqtSignal() incomingMessage = pyqtSignal() def __init__(self): super(TcpClient, self).__init__("tcp_client") # Mutex и буферы для приема и отправки сообщений из всех потоков log.debug("Создан TCP-клиент") # Введена ПОТЕНЦИАЛЬНАЯ возможность восстанавливать связь при разрыве # Параметры для подключения self._m_HostaAddr = QHostAddress() self._socket = None self._stream = None # Переменные состояния self.m_bConnected = False self.m_bShouldConnect = False self.m_bShouldDisconnect = False self.m_bError = False self.pingCounter = 0 def connectToHost(self, addr, port=9110): # Функция подключения к принтеру. if self.m_bConnected: # Если уже подключены - ничего не делаем return 2 if not self._m_HostaAddr.setAddress(addr): print('"{}"'.format(addr)) # Если адрес указан неверно, выходим со знаком минус и выводим сообщение в лог print("Невенро указан адрес подключения!") return 0 try: self._m_Port = int(port) except ValueError as e: print( "Неверно задан номер порта (не числовое значение): {}!".format( e)) self.m_bShouldConnect = True self.m_bConnected = False self.m_bShouldDisconnect = False self.m_bError = False if not self.isRunning(): self.start() return 1 def disconnectFromHost(self, waitTime): # Функция отключения от принтера. Время ожидания не обрабатывается, поэтому переменную состояния отключения выставляем сразу log.debug('Should disconnect') self.m_bShouldDisconnect = True def workThread(self): """ Основная функция треда Не учитывается время с последней отправки и с последнего приема """ super(TcpClient, self).workThread() if self._socket is not None and self.m_bConnected: if self._socket.error() != -1 and not self.m_bError: self.m_bError = True # Требуется отключение if self.m_bError: # Сообщаем, что произошла ошибка и в сигнале передаем описание self.onSocketError() elif self.m_bShouldDisconnect and self.m_bConnected: log.debug('try disconnect') if self._socket.isOpen(): self._socket.disconnectFromHost() self._socket.close() self._socket.disconnected.disconnect(self.disconnected) self._socket.connected.disconnect(self.connected) self.m_bShouldDisconnect = False self.m_bConnected = False log.debug('Отключаемся от принтера по адресу {}:{}'.format( self._m_HostaAddr.toString(), self._m_Port)) # Требуется подключение elif self.m_bShouldConnect and not self.m_bConnected: self.m_bShouldConnect = False # Если сокет уже открыт, а подключения нет, то лучше его убить и создать новый if self._socket is None: self._socket = QTcpSocket() elif self._socket.isOpen(): self._socket.disconnectFromHost() self._socket.close() del self._socket self._socket = QTcpSocket() self._stream = QDataStream(self._socket) # Обрабатываем изменения состояния сокета и его ошибки. self._socket.disconnected.connect(self.disconnected) self._socket.connected.connect(self.connected) log.debug("Начинаем подключение к принтеру {}:{}".format( self._m_HostaAddr.toString(), self._m_Port)) # Подключаемся к принтеру self._socket.connectToHost(self._m_HostaAddr, self._m_Port) # Если время ожидания истекло, то отправляем сигнал об этом if not self._socket.waitForConnected(self.TCPP_CONNECTTIMEOUT): self.m_bConnected = False self.m_bError = True # log.warning(self._langManager.getString(__name__, "timeout")) log.debug("Время ожидания истекло. Соединение не установлено!") self._socket.disconnected.disconnect(self.disconnected) self._socket.connected.disconnect(self.connected) self.connectionFailed.emit('TimeOut') else: self.m_bConnected = True self.m_bError = False log.debug('Установлено подключение с {}:{}'.format( self._m_HostaAddr.toString(), self._m_Port)) #self.connected.emit('Установлено подключение с принтером по адресу {0}:{1}'.format(self._m_HostaAddr.toString(), self._m_Port)) # Прием и отправка пакетов elif self.m_bConnected: packetCounter = 0 # Получение пкаетов while self._socket.bytesAvailable() > 16: if packetCounter > 255: break # Если принято больше 255 пакетов, то приостанавливаем прием, чтоб другим дать возможность поработать ^_^ # Распаковываем данные из сокета: тип, длина, 2байта время, 4байта ID, 8байт данных byteInfo = self._stream.readRawData(8) byteCommand = self._stream.readRawData(2) byteData = self._stream.readRawData(6) canPacket = CanPacket() canPacket.unpackData(struct.unpack('<2BHL', byteInfo), struct.unpack('<2B', byteCommand), struct.unpack('<HBBBB', byteData), byteData) # запихиваем пакет в буфер logCan.info("{}".format(canPacket)) packetCounter += 1 return True def onSocketError(self): self.m_bConnected = False self.m_bShouldConnect = False self.m_bShouldDisconnect = False self.m_bError = False self.tcpClientError.emit('{}'.format(self._socket.errorString())) print('{}: [{}] {}'.format('Connection error', self._socket.error(), self._socket.errorString()))