Example #1
0
 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)
Example #2
0
    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
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
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()))
Example #6
0
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()))