From 1f27a20e9ec4818476a1ad0f4bf2dc711a2eb485 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Mon, 31 May 2021 21:02:25 -0700 Subject: [PATCH 01/14] Migration to Qt6 using PySide6 and Python 3. This is a bulk migraton of the codebase to work with Python3 and latest version of Qt framework i.e. Qt6. --- qweechat/about.py | 8 +- qweechat/buffer.py | 42 ++--- qweechat/chat.py | 13 +- qweechat/config.py | 6 +- qweechat/connection.py | 23 +-- qweechat/debug.py | 3 +- qweechat/input.py | 14 +- qweechat/network.py | 29 ++-- qweechat/qt_compat.py | 55 ------- qweechat/qweechat.py | 54 ++++--- qweechat/weechat/protocol.py | 58 ++++--- qweechat/weechat/testproto.py | 40 ++--- qweechat/weechat/testproto.py.bak | 253 ++++++++++++++++++++++++++++++ 13 files changed, 408 insertions(+), 190 deletions(-) delete mode 100644 qweechat/qt_compat.py create mode 100644 qweechat/weechat/testproto.py.bak diff --git a/qweechat/about.py b/qweechat/about.py index b5c397e..88dd027 100644 --- a/qweechat/about.py +++ b/qweechat/about.py @@ -20,10 +20,8 @@ # along with QWeeChat. If not, see . # -import qt_compat - -QtCore = qt_compat.import_module('QtCore') -QtGui = qt_compat.import_module('QtGui') +from PySide6 import QtCore +from PySide6 import QtWidgets as QtGui class AboutDialog(QtGui.QDialog): @@ -44,7 +42,7 @@ class AboutDialog(QtGui.QDialog): vbox = QtGui.QVBoxLayout() for msg in messages: - label = QtGui.QLabel(msg.decode('utf-8')) + label = QtGui.QLabel(msg) label.setAlignment(QtCore.Qt.AlignHCenter) vbox.addWidget(label) vbox.addLayout(hbox) diff --git a/qweechat/buffer.py b/qweechat/buffer.py index 81aa4b7..e581f8b 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -21,20 +21,20 @@ # from pkg_resources import resource_filename -import qt_compat from chat import ChatTextEdit from input import InputLineEdit import weechat.color as color -QtCore = qt_compat.import_module('QtCore') -QtGui = qt_compat.import_module('QtGui') +from PySide6 import QtCore +from PySide6 import QtWidgets +from PySide6 import QtGui -class GenericListWidget(QtGui.QListWidget): +class GenericListWidget(QtWidgets.QListWidget): """Generic QListWidget with dynamic size.""" def __init__(self, *args): - QtGui.QListWidget.__init__(*(self,) + args) + super().__init__(*args) self.setMaximumWidth(100) self.setTextElideMode(QtCore.Qt.ElideNone) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) @@ -52,17 +52,17 @@ class GenericListWidget(QtGui.QListWidget): def clear(self, *args): """Re-implement clear to set dynamic size after clear.""" - QtGui.QListWidget.clear(*(self,) + args) + QtWidgets.QListWidget.clear(*(self,) + args) self.auto_resize() def addItem(self, *args): """Re-implement addItem to set dynamic size after add.""" - QtGui.QListWidget.addItem(*(self,) + args) + QtWidgets.QListWidget.addItem(*(self,) + args) self.auto_resize() def insertItem(self, *args): """Re-implement insertItem to set dynamic size after insert.""" - QtGui.QListWidget.insertItem(*(self,) + args) + QtWidgets.QListWidget.insertItem(*(self,) + args) self.auto_resize() @@ -70,7 +70,7 @@ class BufferListWidget(GenericListWidget): """Widget with list of buffers.""" def __init__(self, *args): - GenericListWidget.__init__(*(self,) + args) + super().__init__(*args) def switch_prev_buffer(self): if self.currentRow() > 0: @@ -85,23 +85,23 @@ class BufferListWidget(GenericListWidget): self.setCurrentRow(0) -class BufferWidget(QtGui.QWidget): +class BufferWidget(QtWidgets.QWidget): """ Widget with (from top to bottom): title, chat + nicklist (optional) + prompt/input. """ def __init__(self, display_nicklist=False): - QtGui.QWidget.__init__(self) + super().__init__() # title - self.title = QtGui.QLineEdit() + self.title = QtWidgets.QLineEdit() self.title.setFocusPolicy(QtCore.Qt.NoFocus) # splitter with chat + nicklist - self.chat_nicklist = QtGui.QSplitter() - self.chat_nicklist.setSizePolicy(QtGui.QSizePolicy.Expanding, - QtGui.QSizePolicy.Expanding) + self.chat_nicklist = QtWidgets.QSplitter() + self.chat_nicklist.setSizePolicy(QtWidgets.QSizePolicy.Expanding, + QtWidgets.QSizePolicy.Expanding) self.chat = ChatTextEdit(debug=False) self.chat_nicklist.addWidget(self.chat) self.nicklist = GenericListWidget() @@ -110,16 +110,16 @@ class BufferWidget(QtGui.QWidget): self.chat_nicklist.addWidget(self.nicklist) # prompt + input - self.hbox_edit = QtGui.QHBoxLayout() + self.hbox_edit = QtWidgets.QHBoxLayout() self.hbox_edit.setContentsMargins(0, 0, 0, 0) self.hbox_edit.setSpacing(0) self.input = InputLineEdit(self.chat) self.hbox_edit.addWidget(self.input) - prompt_input = QtGui.QWidget() + prompt_input = QtWidgets.QWidget() prompt_input.setLayout(self.hbox_edit) # vbox with title + chat/nicklist + prompt/input - vbox = QtGui.QVBoxLayout() + vbox = QtWidgets.QVBoxLayout() vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(self.title) @@ -139,7 +139,7 @@ class BufferWidget(QtGui.QWidget): if self.hbox_edit.count() > 1: self.hbox_edit.takeAt(0) if prompt is not None: - label = QtGui.QLabel(prompt) + label = QtWidgets.QLabel(prompt) label.setContentsMargins(0, 0, 5, 0) self.hbox_edit.insertWidget(0, label) @@ -147,7 +147,7 @@ class BufferWidget(QtGui.QWidget): class Buffer(QtCore.QObject): """A WeeChat buffer.""" - bufferInput = qt_compat.Signal(str, str) + bufferInput = QtCore.Signal(str, str) def __init__(self, data={}): QtCore.QObject.__init__(self) @@ -243,6 +243,6 @@ class Buffer(QtCore.QObject): pixmap = QtGui.QPixmap(8, 8) pixmap.fill() icon = QtGui.QIcon(pixmap) - item = QtGui.QListWidgetItem(icon, nick['name']) + item = QtWidgets.QListWidgetItem(icon, nick['name']) self.widget.nicklist.addItem(item) self.widget.nicklist.setVisible(True) diff --git a/qweechat/chat.py b/qweechat/chat.py index b8cf8d5..bd339ac 100644 --- a/qweechat/chat.py +++ b/qweechat/chat.py @@ -21,19 +21,18 @@ # import datetime -import qt_compat import config import weechat.color as color -QtCore = qt_compat.import_module('QtCore') -QtGui = qt_compat.import_module('QtGui') +from PySide6 import QtCore +from PySide6 import QtWidgets, QtGui -class ChatTextEdit(QtGui.QTextEdit): +class ChatTextEdit(QtWidgets.QTextEdit): """Chat area.""" def __init__(self, debug, *args): - QtGui.QTextEdit.__init__(*(self,) + args) + QtWidgets.QTextEdit.__init__(*(self,) + args) self.debug = debug self.readOnly = True self.setFocusPolicy(QtCore.Qt.NoFocus) @@ -77,9 +76,9 @@ class ChatTextEdit(QtGui.QTextEdit): prefix = '\x01(F%s)%s' % (forcecolor, prefix) text = '\x01(F%s)%s' % (forcecolor, text) if prefix: - self._display_with_colors(str(prefix).decode('utf-8') + ' ') + self._display_with_colors(prefix + ' ') if text: - self._display_with_colors(str(text).decode('utf-8')) + self._display_with_colors(text) if text[-1:] != '\n': self.insertPlainText('\n') else: diff --git a/qweechat/config.py b/qweechat/config.py index 1613860..8fcc901 100644 --- a/qweechat/config.py +++ b/qweechat/config.py @@ -20,7 +20,7 @@ # along with QWeeChat. If not, see . # -import ConfigParser +import configparser import os CONFIG_DIR = '%s/.qweechat' % os.getenv('HOME') @@ -91,7 +91,7 @@ config_color_options = [] def read(): """Read config file.""" global config_color_options - config = ConfigParser.RawConfigParser() + config = configparser.RawConfigParser() if os.path.isfile(CONFIG_FILENAME): config.read(CONFIG_FILENAME) @@ -123,7 +123,7 @@ def write(config): """Write config file.""" if not os.path.exists(CONFIG_DIR): os.mkdir(CONFIG_DIR, 0o0755) - with open(CONFIG_FILENAME, 'wb') as cfg: + with open(CONFIG_FILENAME, 'w') as cfg: config.write(cfg) diff --git a/qweechat/connection.py b/qweechat/connection.py index 8a0ee71..4529ae5 100644 --- a/qweechat/connection.py +++ b/qweechat/connection.py @@ -20,29 +20,30 @@ # along with QWeeChat. If not, see . # -import qt_compat +# import qt_compat -QtGui = qt_compat.import_module('QtGui') +# QtGui = qt_compat.import_module('QtGui') +from PySide6 import QtGui, QtWidgets -class ConnectionDialog(QtGui.QDialog): +class ConnectionDialog(QtWidgets.QDialog): """Connection window.""" def __init__(self, values, *args): - QtGui.QDialog.__init__(*(self,) + args) + super().__init__(*args) self.values = values self.setModal(True) - grid = QtGui.QGridLayout() + grid = QtWidgets.QGridLayout() grid.setSpacing(10) self.fields = {} for line, field in enumerate(('server', 'port', 'password', 'lines')): - grid.addWidget(QtGui.QLabel(field.capitalize()), line, 0) - line_edit = QtGui.QLineEdit() + grid.addWidget(QtWidgets.QLabel(field.capitalize()), line, 0) + line_edit = QtWidgets.QLineEdit() line_edit.setFixedWidth(200) if field == 'password': - line_edit.setEchoMode(QtGui.QLineEdit.Password) + line_edit.setEchoMode(QtWidgets.QLineEdit.Password) if field == 'lines': validator = QtGui.QIntValidator(0, 2147483647, self) line_edit.setValidator(validator) @@ -51,14 +52,14 @@ class ConnectionDialog(QtGui.QDialog): grid.addWidget(line_edit, line, 1) self.fields[field] = line_edit if field == 'port': - ssl = QtGui.QCheckBox('SSL') + ssl = QtWidgets.QCheckBox('SSL') ssl.setChecked(self.values['ssl'] == 'on') grid.addWidget(ssl, line, 2) self.fields['ssl'] = ssl - self.dialog_buttons = QtGui.QDialogButtonBox() + self.dialog_buttons = QtWidgets.QDialogButtonBox() self.dialog_buttons.setStandardButtons( - QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) + QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) self.dialog_buttons.rejected.connect(self.close) grid.addWidget(self.dialog_buttons, 4, 0, 1, 2) diff --git a/qweechat/debug.py b/qweechat/debug.py index 3dd37d5..3261beb 100644 --- a/qweechat/debug.py +++ b/qweechat/debug.py @@ -20,11 +20,10 @@ # along with QWeeChat. If not, see . # -import qt_compat from chat import ChatTextEdit from input import InputLineEdit -QtGui = qt_compat.import_module('QtGui') +from PySide6 import QtWidgets as QtGui class DebugDialog(QtGui.QDialog): diff --git a/qweechat/input.py b/qweechat/input.py index 5bde922..7c85caf 100644 --- a/qweechat/input.py +++ b/qweechat/input.py @@ -20,21 +20,19 @@ # along with QWeeChat. If not, see . # -import qt_compat - -QtCore = qt_compat.import_module('QtCore') -QtGui = qt_compat.import_module('QtGui') +from PySide6 import QtCore +from PySide6 import QtWidgets as QtGui class InputLineEdit(QtGui.QLineEdit): """Input line.""" - bufferSwitchPrev = qt_compat.Signal() - bufferSwitchNext = qt_compat.Signal() - textSent = qt_compat.Signal(str) + bufferSwitchPrev = QtCore.Signal() + bufferSwitchNext = QtCore.Signal() + textSent = QtCore.Signal(str) def __init__(self, scroll_widget): - QtGui.QLineEdit.__init__(self) + super().__init__(scroll_widget) self.scroll_widget = scroll_widget self._history = [] self._history_index = -1 diff --git a/qweechat/network.py b/qweechat/network.py index 8c497ea..362bb36 100644 --- a/qweechat/network.py +++ b/qweechat/network.py @@ -21,11 +21,12 @@ # import struct -import qt_compat import config +from PySide6 import QtCore, QtNetwork +from PySide6.QtCore import QObject, Signal -QtCore = qt_compat.import_module('QtCore') -QtNetwork = qt_compat.import_module('QtNetwork') +# QtCore = qt_compat.import_module('QtCore') +# QtNetwork = qt_compat.import_module('QtNetwork') _PROTO_INIT_CMD = ['init password=%(password)s'] @@ -47,11 +48,11 @@ _PROTO_SYNC_CMDS = [ class Network(QtCore.QObject): """I/O with WeeChat/relay.""" - statusChanged = qt_compat.Signal(str, str) - messageFromWeechat = qt_compat.Signal(QtCore.QByteArray) + statusChanged = Signal(str, str) + messageFromWeechat = Signal(QtCore.QByteArray) def __init__(self, *args): - QtCore.QObject.__init__(*(self,) + args) + super().__init__(*args) self.status_disconnected = 'disconnected' self.status_connecting = 'connecting...' self.status_connected = 'connected' @@ -63,13 +64,14 @@ class Network(QtCore.QObject): self._buffer = QtCore.QByteArray() self._socket = QtNetwork.QSslSocket() self._socket.connected.connect(self._socket_connected) - self._socket.error.connect(self._socket_error) + # self._socket.error.connect(self._socket_error) self._socket.readyRead.connect(self._socket_read) self._socket.disconnected.connect(self._socket_disconnected) def _socket_connected(self): """Slot: socket connected.""" self.statusChanged.emit(self.status_connected, None) + print('Connected, now sending password.') if self._password: self.send_to_weechat('\n'.join(_PROTO_INIT_CMD + _PROTO_SYNC_CMDS) % {'password': str(self._password), @@ -87,7 +89,7 @@ class Network(QtCore.QObject): self._buffer.append(data) while len(self._buffer) >= 4: remainder = None - length = struct.unpack('>i', self._buffer[0:4])[0] + length = struct.unpack('>i', self._buffer[0:4].data())[0] if len(self._buffer) < length: # partial message, just wait for end of message break @@ -108,7 +110,7 @@ class Network(QtCore.QObject): self._server = None self._port = None self._ssl = None - self._password = None + self._password = "" self.statusChanged.emit(self.status_disconnected, None) def is_connected(self): @@ -122,6 +124,7 @@ class Network(QtCore.QObject): def connect_weechat(self, server, port, ssl, password, lines): """Connect to WeeChat.""" self._server = server + print(f'Connecting to server {self._server}') try: self._port = int(port) except ValueError: @@ -136,11 +139,13 @@ class Network(QtCore.QObject): return if self._socket.state() != QtNetwork.QAbstractSocket.UnconnectedState: self._socket.abort() - self._socket.connectToHost(self._server, self._port) if self._ssl: self._socket.ignoreSslErrors() - self._socket.startClientEncryption() - self.statusChanged.emit(self.status_connecting, None) + self._socket.connectToHostEncrypted(self._server, self._port) + else: + self._socket.connectToHost(self._server, self._port) + print('Got SSL connection') + self.statusChanged.emit(self.status_connecting, "") def disconnect_weechat(self): """Disconnect from WeeChat.""" diff --git a/qweechat/qt_compat.py b/qweechat/qt_compat.py deleted file mode 100644 index 8940288..0000000 --- a/qweechat/qt_compat.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# -# File downloaded from: -# https://github.com/epage/PythonUtils/blob/master/util/qt_compat.py -# Author: epage -# License: LGPL 2.1 -# - -from __future__ import with_statement -from __future__ import division - -_TRY_PYSIDE = True -uses_pyside = False - -try: - if not _TRY_PYSIDE: - raise ImportError() - import PySide.QtCore as _QtCore - QtCore = _QtCore - uses_pyside = True -except ImportError: - import sip - sip.setapi('QString', 2) - sip.setapi('QVariant', 2) - import PyQt4.QtCore as _QtCore - QtCore = _QtCore - uses_pyside = False - - -def _pyside_import_module(moduleName): - pyside = __import__('PySide', globals(), locals(), [moduleName], -1) - return getattr(pyside, moduleName) - - -def _pyqt4_import_module(moduleName): - pyside = __import__('PyQt4', globals(), locals(), [moduleName], -1) - return getattr(pyside, moduleName) - - -if uses_pyside: - import_module = _pyside_import_module - - Signal = QtCore.Signal - Slot = QtCore.Slot - Property = QtCore.Property -else: - import_module = _pyqt4_import_module - - Signal = QtCore.pyqtSignal - Slot = QtCore.pyqtSlot - Property = QtCore.pyqtProperty - - -if __name__ == "__main__": - pass diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 49e6b91..33e210a 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -36,7 +36,7 @@ It requires requires WeeChat 0.3.7 or newer, running on local or remote host. import sys import traceback from pkg_resources import resource_filename -import qt_compat +# import qt_compat import config import weechat.protocol as protocol from network import Network @@ -46,8 +46,14 @@ from debug import DebugDialog from about import AboutDialog from version import qweechat_version -QtCore = qt_compat.import_module('QtCore') -QtGui = qt_compat.import_module('QtGui') +from PySide6.QtWidgets import ( + QApplication, QLabel, QPushButton, QVBoxLayout, QWidget) +from PySide6.QtCore import Qt, Slot +from PySide6 import QtGui, QtWidgets, QtCore + + +# QtCore = qt_compat.import_module('QtCore') +# QtGui = qt_compat.import_module('QtGui') NAME = 'QWeeChat' AUTHOR = 'Sébastien Helleu' @@ -58,11 +64,11 @@ WEECHAT_SITE = 'https://weechat.org/' DEBUG_NUM_LINES = 50 -class MainWindow(QtGui.QMainWindow): +class MainWindow(QtWidgets.QMainWindow): """Main window.""" def __init__(self, *args): - QtGui.QMainWindow.__init__(*(self,) + args) + super().__init__() self.config = config.read() @@ -87,11 +93,11 @@ class MainWindow(QtGui.QMainWindow): # default buffer self.buffers = [Buffer()] - self.stacked_buffers = QtGui.QStackedWidget() + self.stacked_buffers = QtWidgets.QStackedWidget() self.stacked_buffers.addWidget(self.buffers[0].widget) # splitter with buffers + chat/input - splitter = QtGui.QSplitter() + splitter = QtWidgets.QSplitter() splitter.addWidget(self.list_buffers) splitter.addWidget(self.stacked_buffers) @@ -146,7 +152,7 @@ class MainWindow(QtGui.QMainWindow): menu_window.addAction(self.actions['debug']) menu_help = self.menu.addMenu('&Help') menu_help.addAction(self.actions['about']) - self.network_status = QtGui.QLabel() + self.network_status = QtWidgets.QLabel() self.network_status.setFixedHeight(20) self.network_status.setFixedWidth(200) self.network_status.setContentsMargins(0, 0, 10, 0) @@ -312,24 +318,24 @@ class MainWindow(QtGui.QMainWindow): def _network_weechat_msg(self, message): """Called when a message is received from WeeChat.""" - self.debug_display(0, '==>', - 'message (%d bytes):\n%s' - % (len(message), - protocol.hex_and_ascii(message, 20)), - forcecolor='#008800') + # self.debug_display(0, '==>', + # 'message (%d bytes):\n%s' + # % (len(message), + # protocol.hex_and_ascii(message, 20)), + # forcecolor='#008800') try: proto = protocol.Protocol() - message = proto.decode(str(message)) + message = proto.decode(message.data()) if message.uncompressed: self.debug_display( 0, '==>', 'message uncompressed (%d bytes):\n%s' % (message.size_uncompressed, protocol.hex_and_ascii(message.uncompressed, 20)), - forcecolor='#008800') + forcecolor='#008800') self.debug_display(0, '', 'Message: %s' % message) self.parse_message(message) - except: # noqa: E722 + except Exception: # noqa: E722 print('Error while decoding message from WeeChat:\n%s' % traceback.format_exc()) self.network.disconnect_weechat() @@ -339,6 +345,7 @@ class MainWindow(QtGui.QMainWindow): for obj in message.objects: if obj.objtype != 'hda' or obj.value['path'][-1] != 'buffer': continue + print('listbuffers object', obj.objtype, obj.value['path']) self.list_buffers.clear() while self.stacked_buffers.count() > 0: buf = self.stacked_buffers.widget(0) @@ -346,6 +353,7 @@ class MainWindow(QtGui.QMainWindow): self.buffers = [] for item in obj.value['items']: buf = self.create_buffer(item) + print(f'Creating buffer for {item}') self.insert_buffer(len(self.buffers), buf) self.list_buffers.setCurrentRow(0) self.buffers[0].widget.input.setFocus() @@ -477,6 +485,7 @@ class MainWindow(QtGui.QMainWindow): def parse_message(self, message): """Parse a WeeChat message.""" + print(f'message.msgid = {message.msgid}') if message.msgid.startswith('debug'): self.debug_display(0, '', '(debug message, ignored)') elif message.msgid == 'listbuffers': @@ -495,6 +504,8 @@ class MainWindow(QtGui.QMainWindow): self.network.desync_weechat() elif message.msgid == '_upgrade_ended': self.network.sync_weechat() + else: + print(f"Unknown message with id {message.msgid}") def create_buffer(self, item): """Create a new buffer.""" @@ -511,7 +522,7 @@ class MainWindow(QtGui.QMainWindow): self.buffers.insert(index, buf) self.list_buffers.insertItem(index, '%d. %s' % (buf.data['number'], - buf.data['full_name'].decode('utf-8'))) + buf.data['full_name'])) self.stacked_buffers.insertWidget(index, buf.widget) def remove_buffer(self, index): @@ -544,12 +555,13 @@ class MainWindow(QtGui.QMainWindow): if self.debug_dialog: self.debug_dialog.close() config.write(self.config) - QtGui.QMainWindow.closeEvent(self, event) + QtWidgets.QMainWindow.closeEvent(self, event) -app = QtGui.QApplication(sys.argv) -app.setStyle(QtGui.QStyleFactory.create('Cleanlooks')) +app = QApplication(sys.argv) +app.setStyle(QtWidgets.QStyleFactory.create('Cleanlooks')) app.setWindowIcon(QtGui.QIcon( - resource_filename(__name__, 'data/icons/weechat.png'))) + resource_filename(__name__, 'data/icons/weechat.png'))) main = MainWindow() +main.show() sys.exit(app.exec_()) diff --git a/qweechat/weechat/protocol.py b/qweechat/weechat/protocol.py index 79b24c1..6283b2b 100644 --- a/qweechat/weechat/protocol.py +++ b/qweechat/weechat/protocol.py @@ -34,15 +34,10 @@ import collections import struct import zlib -if hasattr(collections, 'OrderedDict'): - # python >= 2.7 - class WeechatDict(collections.OrderedDict): - def __str__(self): - return '{%s}' % ', '.join( - ['%s: %s' % (repr(key), repr(self[key])) for key in self]) -else: - # python <= 2.6 - WeechatDict = dict +class WeechatDict(collections.OrderedDict): + def __str__(self): + return '{%s}' % ', '.join( + ['%s: %s' % (repr(key), repr(self[key])) for key in self]) class WeechatObject: @@ -151,7 +146,7 @@ class Protocol: if len(self.data) < 3: self.data = '' return '' - objtype = str(self.data[0:3]) + objtype = bytes(self.data[0:3]) self.data = self.data[3:] return objtype @@ -196,14 +191,17 @@ class Protocol: value = self._obj_len_data(1) if value is None: return None - return int(str(value)) + return int(value) def _obj_str(self): """Read a string in data (length on 4 bytes + content).""" value = self._obj_len_data(4) if value is None: return None - return str(value) + try: + return value.decode() + except AttributeError: + return value def _obj_buffer(self): """Read a buffer in data (length on 4 bytes + data).""" @@ -214,22 +212,22 @@ class Protocol: value = self._obj_len_data(1) if value is None: return None - return '0x%s' % str(value) + return '0x%s' % value def _obj_time(self): """Read a time in data (length on 1 byte + value as string).""" value = self._obj_len_data(1) if value is None: return None - return int(str(value)) + return int(value) def _obj_hashtable(self): """ Read a hashtable in data (type for keys + type for values + count + items). """ - type_keys = self._obj_type() - type_values = self._obj_type() + type_keys = self._obj_type().decode() + type_values = self._obj_type().decode() count = self._obj_int() hashtable = WeechatDict() for _ in range(count): @@ -248,7 +246,7 @@ class Protocol: keys_types = [] dict_keys = WeechatDict() for key in list_keys: - items = key.split(':') + items = list(item for item in key.split(':')) keys_types.append(items) dict_keys[items[0]] = items[1] items = [] @@ -259,6 +257,7 @@ class Protocol: for _ in enumerate(list_path): pointers.append(self._obj_ptr()) for key, objtype in keys_types: + objtype = objtype item[key] = self._obj_cb[objtype]() item['__path'] = pointers items.append(item) @@ -296,7 +295,7 @@ class Protocol: def _obj_array(self): """Read an array of values in data.""" - type_values = self._obj_type() + type_values = self._obj_type().decode() count_values = self._obj_int() values = [] for _ in range(count_values): @@ -314,7 +313,7 @@ class Protocol: if compression: uncompressed = zlib.decompress(self.data[5:]) size_uncompressed = len(uncompressed) + 5 - uncompressed = '%s%s%s' % (struct.pack('>i', size_uncompressed), + uncompressed = b'%s%s%s' % (struct.pack('>i', size_uncompressed), struct.pack('b', 0), uncompressed) self.data = uncompressed else: @@ -328,7 +327,7 @@ class Protocol: # read objects objects = WeechatObjects(separator=separator) while len(self.data) > 0: - objtype = self._obj_type() + objtype = self._obj_type().decode() value = self._obj_cb[objtype]() objects.append(WeechatObject(objtype, value, separator=separator)) return WeechatMessage(size, size_uncompressed, compression, @@ -344,13 +343,20 @@ def hex_and_ascii(data, bytes_per_line=10): for i in range(num_lines): str_hex = [] str_ascii = [] - for char in data[i*bytes_per_line:(i*bytes_per_line)+bytes_per_line]: + for j in range(bytes_per_line): # data[i*bytes_per_line:(i*bytes_per_line)+bytes_per_line]: + # We can't easily iterate over individual bytes, so we are going to + # do it this way. + index = (i*bytes_per_line) + j + char = data[index:index+1] + if not char: + char = b'x' byte = struct.unpack('B', char)[0] - str_hex.append('%02X' % int(byte)) + str_hex.append(b'%02X' % int(byte)) if byte >= 32 and byte <= 127: str_ascii.append(char) else: - str_ascii.append('.') - fmt = '%%-%ds %%s' % ((bytes_per_line * 3) - 1) - lines.append(fmt % (' '.join(str_hex), ''.join(str_ascii))) - return '\n'.join(lines) + str_ascii.append(b'.') + fmt = b'%%-%ds %%s' % ((bytes_per_line * 3) - 1) + lines.append(fmt % (b' '.join(str_hex), + b''.join(str_ascii))) + return b'\n'.join(lines) diff --git a/qweechat/weechat/testproto.py b/qweechat/weechat/testproto.py index c90d538..06a0b53 100644 --- a/qweechat/weechat/testproto.py +++ b/qweechat/weechat/testproto.py @@ -24,7 +24,7 @@ Command-line program for testing WeeChat/relay protocol. """ -from __future__ import print_function + import argparse import os @@ -37,7 +37,8 @@ import time import traceback import protocol # WeeChat/relay protocol -from .. version import qweechat_version +# from .. version import qweechat_version +qweechat_version = '1.1' NAME = 'qweechat-testproto' @@ -75,11 +76,11 @@ class TestProto(object): Return True if OK, False if error. """ try: - for msg in messages.split('\n'): - if msg == 'quit': + for msg in messages.split(b'\n'): + if msg == b'quit': self.has_quit = True - self.sock.sendall(msg + '\n') - print('\x1b[33m<-- ' + msg + '\x1b[0m') + self.sock.sendall(msg + b'\n') + sys.stdout.write((b'\x1b[33m<-- ' + msg + b'\x1b[0m\n').decode()) except: # noqa: E722 traceback.print_exc() print('Failed to send message') @@ -94,7 +95,7 @@ class TestProto(object): try: proto = protocol.Protocol() msgd = proto.decode(message, - separator='\n' if self.args.debug > 0 + separator=b'\n' if self.args.debug > 0 else ', ') print('') if self.args.debug >= 2 and msgd.uncompressed: @@ -136,10 +137,10 @@ class TestProto(object): """ if self.has_quit: return 0 - message = '' - recvbuf = '' - prompt = '\x1b[36mrelay> \x1b[0m' - sys.stdout.write(prompt) + message = b'' + recvbuf = b'' + prompt = b'\x1b[36mrelay> \x1b[0m' + sys.stdout.write(prompt.decode()) sys.stdout.flush() try: while not self.has_quit: @@ -149,13 +150,14 @@ class TestProto(object): buf = os.read(_file.fileno(), 4096) if buf: message += buf - if '\n' in message: - messages = message.split('\n') - msgsent = '\n'.join(messages[:-1]) + if b'\n' in message: + messages = message.split(b'\n') + msgsent = b'\n'.join(messages[:-1]) if msgsent and not self.send(msgsent): return 4 message = messages[-1] - sys.stdout.write(prompt + message) + sys.stdout.write((prompt + message).decode()) + # sys.stdout.write(prompt + message) sys.stdout.flush() else: buf = _file.recv(4096) @@ -178,12 +180,12 @@ class TestProto(object): if remainder: recvbuf = remainder else: - recvbuf = '' - sys.stdout.write(prompt + message) + recvbuf = b'' + sys.stdout.write((prompt + message).decode()) sys.stdout.flush() except: # noqa: E722 traceback.print_exc() - self.send('quit') + self.send(b'quit') return 0 def __del__(self): @@ -220,7 +222,7 @@ The script returns: help='debug mode: long objects view ' '(-dd: display raw messages)') parser.add_argument('-v', '--version', action='version', - version=qweechat_version()) + version=qweechat_version) parser.add_argument('hostname', help='hostname (or IP address) of machine running ' 'WeeChat/relay') diff --git a/qweechat/weechat/testproto.py.bak b/qweechat/weechat/testproto.py.bak new file mode 100644 index 0000000..af8a396 --- /dev/null +++ b/qweechat/weechat/testproto.py.bak @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- +# +# testproto.py - command-line program for testing WeeChat/relay protocol +# +# Copyright (C) 2013-2021 Sébastien Helleu +# +# This file is part of QWeeChat, a Qt remote GUI for WeeChat. +# +# QWeeChat is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# QWeeChat is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with QWeeChat. If not, see . +# + +""" +Command-line program for testing WeeChat/relay protocol. +""" + +from __future__ import print_function + +import argparse +import os +import select +import shlex +import socket +import struct +import sys +import time +import traceback + +import protocol # WeeChat/relay protocol +# from .. version import qweechat_version +qweechat_version = '1.1' + +NAME = 'qweechat-testproto' + + +class TestProto(object): + """Test of WeeChat/relay protocol.""" + + def __init__(self, args): + self.args = args + self.sock = None + self.has_quit = False + self.address = '{self.args.hostname}/{self.args.port} ' \ + '(IPv{0})'.format(6 if self.args.ipv6 else 4, self=self) + + def connect(self): + """ + Connect to WeeChat/relay. + Return True if OK, False if error. + """ + inet = socket.AF_INET6 if self.args.ipv6 else socket.AF_INET + try: + self.sock = socket.socket(inet, socket.SOCK_STREAM) + self.sock.connect((self.args.hostname, self.args.port)) + except: # noqa: E722 + if self.sock: + self.sock.close() + print('Failed to connect to', self.address) + return False + print('Connected to', self.address) + return True + + def send(self, messages): + """ + Send a text message to WeeChat/relay. + Return True if OK, False if error. + """ + try: + for msg in messages.split('\n'): + if msg == 'quit': + self.has_quit = True + self.sock.sendall(msg + '\n') + print('\x1b[33m<-- ' + msg + '\x1b[0m') + except: # noqa: E722 + traceback.print_exc() + print('Failed to send message') + return False + return True + + def decode(self, message): + """ + Decode a binary message received from WeeChat/relay. + Return True if OK, False if error. + """ + try: + proto = protocol.Protocol() + msgd = proto.decode(message, + separator='\n' if self.args.debug > 0 + else ', ') + print('') + if self.args.debug >= 2 and msgd.uncompressed: + # display raw message + print('\x1b[32m--> message uncompressed ({0} bytes):\n' + '{1}\x1b[0m' + ''.format(msgd.size_uncompressed, + protocol.hex_and_ascii(msgd.uncompressed, 20))) + # display decoded message + print('\x1b[32m--> {0}\x1b[0m'.format(msgd)) + except: # noqa: E722 + traceback.print_exc() + print('Error while decoding message from WeeChat') + return False + return True + + def send_stdin(self): + """ + Send commands from standard input if some data is available. + Return True if OK (it's OK if stdin has no commands), + False if error. + """ + inr = select.select([sys.stdin], [], [], 0)[0] + if inr: + data = os.read(sys.stdin.fileno(), 4096) + if data: + if not self.send(data.strip()): + # self.sock.close() + return False + # open stdin to read user commands + sys.stdin = open('/dev/tty') + return True + + def mainloop(self): + """ + Main loop: read keyboard, send commands, read socket, + decode/display binary messages received from WeeChat/relay. + Return 0 if OK, 4 if send error, 5 if decode error. + """ + if self.has_quit: + return 0 + message = '' + recvbuf = '' + prompt = '\x1b[36mrelay> \x1b[0m' + sys.stdout.write(prompt) + sys.stdout.flush() + try: + while not self.has_quit: + inr = select.select([sys.stdin, self.sock], [], [], 1)[0] + for _file in inr: + if _file == sys.stdin: + buf = os.read(_file.fileno(), 4096) + if buf: + message += buf + if '\n' in message: + messages = message.split('\n') + msgsent = '\n'.join(messages[:-1]) + if msgsent and not self.send(msgsent): + return 4 + message = messages[-1] + sys.stdout.write(prompt + message) + sys.stdout.flush() + else: + buf = _file.recv(4096) + if buf: + recvbuf += buf + while len(recvbuf) >= 4: + remainder = None + length = struct.unpack('>i', recvbuf[0:4])[0] + if len(recvbuf) < length: + # partial message, just wait for the + # end of message + break + # more than one message? + if length < len(recvbuf): + # save beginning of another message + remainder = recvbuf[length:] + recvbuf = recvbuf[0:length] + if not self.decode(recvbuf): + return 5 + if remainder: + recvbuf = remainder + else: + recvbuf = '' + sys.stdout.write(prompt + message) + sys.stdout.flush() + except: # noqa: E722 + traceback.print_exc() + self.send('quit') + return 0 + + def __del__(self): + print('Closing connection with', self.address) + time.sleep(0.5) + self.sock.close() + + +def main(): + """Main function.""" + # parse command line arguments + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + fromfile_prefix_chars='@', + description='Command-line program for testing WeeChat/relay protocol.', + epilog=''' +Environment variable "QWEECHAT_PROTO_OPTIONS" can be set with default options. +Argument "@file.txt" can be used to read default options in a file. + +Some commands can be piped to the script, for example: + echo "init password=xxxx" | {name} localhost 5000 + {name} localhost 5000 < commands.txt + +The script returns: + 0: OK + 2: wrong arguments (command line) + 3: connection error + 4: send error (message sent to WeeChat) + 5: decode error (message received from WeeChat) +'''.format(name=NAME)) + parser.add_argument('-6', '--ipv6', action='store_true', + help='connect using IPv6') + parser.add_argument('-d', '--debug', action='count', default=0, + help='debug mode: long objects view ' + '(-dd: display raw messages)') + parser.add_argument('-v', '--version', action='version', + version=qweechat_version) + parser.add_argument('hostname', + help='hostname (or IP address) of machine running ' + 'WeeChat/relay') + parser.add_argument('port', type=int, + help='port of machine running WeeChat/relay') + if len(sys.argv) == 1: + parser.print_help() + sys.exit(0) + _args = parser.parse_args( + shlex.split(os.getenv('QWEECHAT_PROTO_OPTIONS') or '') + sys.argv[1:]) + + test = TestProto(_args) + + # connect to WeeChat/relay + if not test.connect(): + sys.exit(3) + + # send commands from standard input if some data is available + if not test.send_stdin(): + sys.exit(4) + + # main loop (wait commands, display messages received) + returncode = test.mainloop() + del test + sys.exit(returncode) + + +if __name__ == "__main__": + main() From 0ee7d2e92f326ee0528a86088b6190c6be759ed9 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Mon, 31 May 2021 21:16:22 -0700 Subject: [PATCH 02/14] Fix the imports to support Python3 style absolute imports. --- qweechat/buffer.py | 6 +++--- qweechat/chat.py | 4 ++-- qweechat/debug.py | 4 ++-- qweechat/network.py | 2 +- qweechat/qweechat.py | 19 ++++++++----------- setup.py | 5 ++++- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/qweechat/buffer.py b/qweechat/buffer.py index e581f8b..2ccd6e7 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -21,9 +21,9 @@ # from pkg_resources import resource_filename -from chat import ChatTextEdit -from input import InputLineEdit -import weechat.color as color +from qweechat.chat import ChatTextEdit +from qweechat.input import InputLineEdit +import qweechat.weechat.color as color from PySide6 import QtCore from PySide6 import QtWidgets diff --git a/qweechat/chat.py b/qweechat/chat.py index bd339ac..2d5f47e 100644 --- a/qweechat/chat.py +++ b/qweechat/chat.py @@ -21,8 +21,8 @@ # import datetime -import config -import weechat.color as color +from qweechat import config +from qweechat.weechat import color from PySide6 import QtCore from PySide6 import QtWidgets, QtGui diff --git a/qweechat/debug.py b/qweechat/debug.py index 3261beb..d00c46b 100644 --- a/qweechat/debug.py +++ b/qweechat/debug.py @@ -20,8 +20,8 @@ # along with QWeeChat. If not, see . # -from chat import ChatTextEdit -from input import InputLineEdit +from qweechat.chat import ChatTextEdit +from qweechat.input import InputLineEdit from PySide6 import QtWidgets as QtGui diff --git a/qweechat/network.py b/qweechat/network.py index 362bb36..52e190c 100644 --- a/qweechat/network.py +++ b/qweechat/network.py @@ -21,7 +21,7 @@ # import struct -import config +from qweechat import config from PySide6 import QtCore, QtNetwork from PySide6.QtCore import QObject, Signal diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 33e210a..5e14bbc 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -37,14 +37,14 @@ import sys import traceback from pkg_resources import resource_filename # import qt_compat -import config -import weechat.protocol as protocol -from network import Network -from connection import ConnectionDialog -from buffer import BufferListWidget, Buffer -from debug import DebugDialog -from about import AboutDialog -from version import qweechat_version +from qweechat import config +from qweechat.weechat import protocol +from qweechat.network import Network +from qweechat.connection import ConnectionDialog +from qweechat.buffer import BufferListWidget, Buffer +from qweechat.debug import DebugDialog +from qweechat.about import AboutDialog +from qweechat.version import qweechat_version from PySide6.QtWidgets import ( QApplication, QLabel, QPushButton, QVBoxLayout, QWidget) @@ -345,7 +345,6 @@ class MainWindow(QtWidgets.QMainWindow): for obj in message.objects: if obj.objtype != 'hda' or obj.value['path'][-1] != 'buffer': continue - print('listbuffers object', obj.objtype, obj.value['path']) self.list_buffers.clear() while self.stacked_buffers.count() > 0: buf = self.stacked_buffers.widget(0) @@ -353,7 +352,6 @@ class MainWindow(QtWidgets.QMainWindow): self.buffers = [] for item in obj.value['items']: buf = self.create_buffer(item) - print(f'Creating buffer for {item}') self.insert_buffer(len(self.buffers), buf) self.list_buffers.setCurrentRow(0) self.buffers[0].widget.input.setFocus() @@ -485,7 +483,6 @@ class MainWindow(QtWidgets.QMainWindow): def parse_message(self, message): """Parse a WeeChat message.""" - print(f'message.msgid = {message.msgid}') if message.msgid.startswith('debug'): self.debug_display(0, '', '(debug message, ignored)') elif message.msgid == 'listbuffers': diff --git a/setup.py b/setup.py index c6edcbe..d22cf9f 100644 --- a/setup.py +++ b/setup.py @@ -54,5 +54,8 @@ setup( 'console_scripts': [ 'qweechat-testproto = qweechat.weechat.testproto:main', ] - } + }, + install_requires = [ + 'PySide6', + ] ) From b8a96ada1fdbc5f65fb8fc41615af750878bd3c6 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Mon, 31 May 2021 21:39:29 -0700 Subject: [PATCH 03/14] Fix the about dialog. --- qweechat/qweechat.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 5e14bbc..0b38226 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -255,8 +255,7 @@ class MainWindow(QtWidgets.QMainWindow): '© 2011-2020 %s <%s>' % (AUTHOR, AUTHOR_MAIL, AUTHOR_MAIL), '', - 'Running with %s' % ('PySide' if qt_compat.uses_pyside - else 'PyQt4'), + 'Running with PySide6', '', 'WeeChat site: %s' % (WEECHAT_SITE, WEECHAT_SITE), @@ -554,11 +553,15 @@ class MainWindow(QtWidgets.QMainWindow): config.write(self.config) QtWidgets.QMainWindow.closeEvent(self, event) +def main(): + app = QApplication(sys.argv) + app.setStyle(QtWidgets.QStyleFactory.create('Cleanlooks')) + app.setWindowIcon(QtGui.QIcon( + resource_filename(__name__, 'data/icons/weechat.png'))) + main = MainWindow() + main.show() + sys.exit(app.exec_()) -app = QApplication(sys.argv) -app.setStyle(QtWidgets.QStyleFactory.create('Cleanlooks')) -app.setWindowIcon(QtGui.QIcon( - resource_filename(__name__, 'data/icons/weechat.png'))) -main = MainWindow() -main.show() -sys.exit(app.exec_()) + +if __name__ == '__main__': + main() From eedb06f0edac71b172345630114c831a73419b90 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Mon, 31 May 2021 21:53:54 -0700 Subject: [PATCH 04/14] Fix set the title of the thread. --- qweechat/buffer.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qweechat/buffer.py b/qweechat/buffer.py index 2ccd6e7..88e403e 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -19,6 +19,7 @@ # You should have received a copy of the GNU General Public License # along with QWeeChat. If not, see . # +import traceback from pkg_resources import resource_filename from qweechat.chat import ChatTextEdit @@ -167,15 +168,17 @@ class Buffer(QtCore.QObject): """Update title.""" try: self.widget.set_title( - color.remove(self.data['title'].decode('utf-8'))) - except: # noqa: E722 + color.remove(self.data['title'])) + except Exception as e: # noqa: E722 + # TODO: Debug print the exception to be fixed. + # traceback.print_exc() self.widget.set_title(None) def update_prompt(self): """Update prompt.""" try: self.widget.set_prompt(self.data['local_variables']['nick']) - except: # noqa: E722 + except Exception as e: # noqa: E722 self.widget.set_prompt(None) def input_text_sent(self, text): From 7a3a48a56fa6504550295eb4709001556dd8d485 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Mon, 31 May 2021 22:43:37 -0700 Subject: [PATCH 05/14] A bunch of more fixes. - Update README - Remove some spurious comments here and there - Fix flake8 errors. --- README.adoc | 6 +++--- qweechat/buffer.py | 6 ++---- qweechat/network.py | 4 +--- qweechat/qweechat.py | 17 ++++++++++------- qweechat/weechat/protocol.py | 5 +++-- qweechat/weechat/testproto.py | 5 ++--- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/README.adoc b/README.adoc index c3378b0..074dc3d 100644 --- a/README.adoc +++ b/README.adoc @@ -25,13 +25,13 @@ Following packages are *required*: * WeeChat (version >= 0.3.7) on local or remote machine, with relay plugin enabled and listening on a port with protocol "weechat" -* Python 2.x >= 2.6 -* PySide (recommended, packages: python.pyside.*) or PyQt4 (python-qt4) +* Python 3.7+ +* PySide6 === Install via source distribution ---- -$ python setup.py install +$ pip install . ---- == WeeChat setup diff --git a/qweechat/buffer.py b/qweechat/buffer.py index 88e403e..c501d48 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -19,8 +19,6 @@ # You should have received a copy of the GNU General Public License # along with QWeeChat. If not, see . # -import traceback - from pkg_resources import resource_filename from qweechat.chat import ChatTextEdit from qweechat.input import InputLineEdit @@ -169,7 +167,7 @@ class Buffer(QtCore.QObject): try: self.widget.set_title( color.remove(self.data['title'])) - except Exception as e: # noqa: E722 + except Exception: # noqa: E722 # TODO: Debug print the exception to be fixed. # traceback.print_exc() self.widget.set_title(None) @@ -178,7 +176,7 @@ class Buffer(QtCore.QObject): """Update prompt.""" try: self.widget.set_prompt(self.data['local_variables']['nick']) - except Exception as e: # noqa: E722 + except Exception: # noqa: E722 self.widget.set_prompt(None) def input_text_sent(self, text): diff --git a/qweechat/network.py b/qweechat/network.py index 52e190c..fe64d0f 100644 --- a/qweechat/network.py +++ b/qweechat/network.py @@ -23,10 +23,8 @@ import struct from qweechat import config from PySide6 import QtCore, QtNetwork -from PySide6.QtCore import QObject, Signal +from PySide6.QtCore import Signal -# QtCore = qt_compat.import_module('QtCore') -# QtNetwork = qt_compat.import_module('QtNetwork') _PROTO_INIT_CMD = ['init password=%(password)s'] diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 0b38226..76db5a4 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -46,9 +46,7 @@ from qweechat.debug import DebugDialog from qweechat.about import AboutDialog from qweechat.version import qweechat_version -from PySide6.QtWidgets import ( - QApplication, QLabel, QPushButton, QVBoxLayout, QWidget) -from PySide6.QtCore import Qt, Slot +from PySide6.QtWidgets import QApplication from PySide6 import QtGui, QtWidgets, QtCore @@ -331,7 +329,7 @@ class MainWindow(QtWidgets.QMainWindow): 'message uncompressed (%d bytes):\n%s' % (message.size_uncompressed, protocol.hex_and_ascii(message.uncompressed, 20)), - forcecolor='#008800') + forcecolor='#008800') self.debug_display(0, '', 'Message: %s' % message) self.parse_message(message) except Exception: # noqa: E722 @@ -516,10 +514,14 @@ class MainWindow(QtWidgets.QMainWindow): def insert_buffer(self, index, buf): """Insert a buffer in list.""" self.buffers.insert(index, buf) - self.list_buffers.insertItem(index, '%d. %s' - % (buf.data['number'], - buf.data['full_name'])) + self.list_buffers.insertItem(index, '%s' + % (buf.data['local_variables']['name'])) self.stacked_buffers.insertWidget(index, buf.widget) + self._reorder_buffers() + + def _reorder_buffers(self): + """Order buffers by server.""" + pass def remove_buffer(self, index): """Remove a buffer.""" @@ -553,6 +555,7 @@ class MainWindow(QtWidgets.QMainWindow): config.write(self.config) QtWidgets.QMainWindow.closeEvent(self, event) + def main(): app = QApplication(sys.argv) app.setStyle(QtWidgets.QStyleFactory.create('Cleanlooks')) diff --git a/qweechat/weechat/protocol.py b/qweechat/weechat/protocol.py index 6283b2b..4a69378 100644 --- a/qweechat/weechat/protocol.py +++ b/qweechat/weechat/protocol.py @@ -34,6 +34,7 @@ import collections import struct import zlib + class WeechatDict(collections.OrderedDict): def __str__(self): return '{%s}' % ', '.join( @@ -314,7 +315,7 @@ class Protocol: uncompressed = zlib.decompress(self.data[5:]) size_uncompressed = len(uncompressed) + 5 uncompressed = b'%s%s%s' % (struct.pack('>i', size_uncompressed), - struct.pack('b', 0), uncompressed) + struct.pack('b', 0), uncompressed) self.data = uncompressed else: uncompressed = self.data[:] @@ -343,7 +344,7 @@ def hex_and_ascii(data, bytes_per_line=10): for i in range(num_lines): str_hex = [] str_ascii = [] - for j in range(bytes_per_line): # data[i*bytes_per_line:(i*bytes_per_line)+bytes_per_line]: + for j in range(bytes_per_line): # We can't easily iterate over individual bytes, so we are going to # do it this way. index = (i*bytes_per_line) + j diff --git a/qweechat/weechat/testproto.py b/qweechat/weechat/testproto.py index 06a0b53..54cd2c8 100644 --- a/qweechat/weechat/testproto.py +++ b/qweechat/weechat/testproto.py @@ -24,8 +24,6 @@ Command-line program for testing WeeChat/relay protocol. """ - - import argparse import os import select @@ -80,7 +78,8 @@ class TestProto(object): if msg == b'quit': self.has_quit = True self.sock.sendall(msg + b'\n') - sys.stdout.write((b'\x1b[33m<-- ' + msg + b'\x1b[0m\n').decode()) + sys.stdout.write( + (b'\x1b[33m<-- ' + msg + b'\x1b[0m\n').decode()) except: # noqa: E722 traceback.print_exc() print('Failed to send message') From cb2f9d28c1f6ad8d706945fcb904e40dd54d5255 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Mon, 31 May 2021 22:49:00 -0700 Subject: [PATCH 06/14] Use Python 3.7+ in testing. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 03f3e81..ebaca86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ language: python python: - - "2.7" + - "3.7" + - "3.8" + - "3.9" install: - pip install flake8 From e7b0dbced518e839ec8ede5afe88602245c531da Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 09:58:02 -0700 Subject: [PATCH 07/14] Use the text in history instead of bytes. --- qweechat/input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qweechat/input.py b/qweechat/input.py index 7c85caf..192e5d4 100644 --- a/qweechat/input.py +++ b/qweechat/input.py @@ -76,7 +76,7 @@ class InputLineEdit(QtGui.QLineEdit): QtGui.QLineEdit.keyPressEvent(self, event) def _input_return_pressed(self): - self._history.append(self.text().encode('utf-8')) + self._history.append(self.text()) self._history_index = len(self._history) self.textSent.emit(self.text()) self.clear() From 8e15c19fb25c4b7b9008067b41536f306aa7e677 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 10:09:48 -0700 Subject: [PATCH 08/14] More fixes. - Cleanup some un-used comments. - Use QtWidgets instead of renaming it to QtGui - Remove print statements. - Fix the debug print of data from weechat. - Delete the backup file added by mistake. --- qweechat/connection.py | 3 - qweechat/debug.py | 8 +- qweechat/input.py | 10 +- qweechat/network.py | 13 +- qweechat/qweechat.py | 23 ++- qweechat/weechat/testproto.py.bak | 253 ------------------------------ 6 files changed, 24 insertions(+), 286 deletions(-) delete mode 100644 qweechat/weechat/testproto.py.bak diff --git a/qweechat/connection.py b/qweechat/connection.py index 4529ae5..c1107f2 100644 --- a/qweechat/connection.py +++ b/qweechat/connection.py @@ -20,9 +20,6 @@ # along with QWeeChat. If not, see . # -# import qt_compat - -# QtGui = qt_compat.import_module('QtGui') from PySide6 import QtGui, QtWidgets diff --git a/qweechat/debug.py b/qweechat/debug.py index d00c46b..b5f4d85 100644 --- a/qweechat/debug.py +++ b/qweechat/debug.py @@ -23,21 +23,21 @@ from qweechat.chat import ChatTextEdit from qweechat.input import InputLineEdit -from PySide6 import QtWidgets as QtGui +from PySide6 import QtWidgets -class DebugDialog(QtGui.QDialog): +class DebugDialog(QtWidgets.QDialog): """Debug dialog.""" def __init__(self, *args): - QtGui.QDialog.__init__(*(self,) + args) + QtWidgets.QDialog.__init__(*(self,) + args) self.resize(640, 480) self.setWindowTitle('Debug console') self.chat = ChatTextEdit(debug=True) self.input = InputLineEdit(self.chat) - vbox = QtGui.QVBoxLayout() + vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.chat) vbox.addWidget(self.input) diff --git a/qweechat/input.py b/qweechat/input.py index 192e5d4..1ee7bd9 100644 --- a/qweechat/input.py +++ b/qweechat/input.py @@ -21,10 +21,10 @@ # from PySide6 import QtCore -from PySide6 import QtWidgets as QtGui +from PySide6 import QtWidgets -class InputLineEdit(QtGui.QLineEdit): +class InputLineEdit(QtWidgets.QLineEdit): """Input line.""" bufferSwitchPrev = QtCore.Signal() @@ -48,7 +48,7 @@ class InputLineEdit(QtGui.QLineEdit): elif key == QtCore.Qt.Key_PageDown: self.bufferSwitchNext.emit() else: - QtGui.QLineEdit.keyPressEvent(self, event) + QtWidgets.QLineEdit.keyPressEvent(self, event) elif modifiers == QtCore.Qt.AltModifier: if key in (QtCore.Qt.Key_Left, QtCore.Qt.Key_Up): self.bufferSwitchPrev.emit() @@ -63,7 +63,7 @@ class InputLineEdit(QtGui.QLineEdit): elif key == QtCore.Qt.Key_End: bar.setValue(bar.maximum()) else: - QtGui.QLineEdit.keyPressEvent(self, event) + QtWidgets.QLineEdit.keyPressEvent(self, event) elif key == QtCore.Qt.Key_PageUp: bar.setValue(bar.value() - bar.pageStep()) elif key == QtCore.Qt.Key_PageDown: @@ -73,7 +73,7 @@ class InputLineEdit(QtGui.QLineEdit): elif key == QtCore.Qt.Key_Down: self._history_navigate(1) else: - QtGui.QLineEdit.keyPressEvent(self, event) + QtWidgets.QLineEdit.keyPressEvent(self, event) def _input_return_pressed(self): self._history.append(self.text()) diff --git a/qweechat/network.py b/qweechat/network.py index fe64d0f..952c02a 100644 --- a/qweechat/network.py +++ b/qweechat/network.py @@ -21,9 +21,11 @@ # import struct -from qweechat import config + from PySide6 import QtCore, QtNetwork -from PySide6.QtCore import Signal + +from qweechat import config + _PROTO_INIT_CMD = ['init password=%(password)s'] @@ -46,8 +48,8 @@ _PROTO_SYNC_CMDS = [ class Network(QtCore.QObject): """I/O with WeeChat/relay.""" - statusChanged = Signal(str, str) - messageFromWeechat = Signal(QtCore.QByteArray) + statusChanged = QtCore.Signal(str, str) + messageFromWeechat = QtCore.Signal(QtCore.QByteArray) def __init__(self, *args): super().__init__(*args) @@ -69,7 +71,6 @@ class Network(QtCore.QObject): def _socket_connected(self): """Slot: socket connected.""" self.statusChanged.emit(self.status_connected, None) - print('Connected, now sending password.') if self._password: self.send_to_weechat('\n'.join(_PROTO_INIT_CMD + _PROTO_SYNC_CMDS) % {'password': str(self._password), @@ -122,7 +123,6 @@ class Network(QtCore.QObject): def connect_weechat(self, server, port, ssl, password, lines): """Connect to WeeChat.""" self._server = server - print(f'Connecting to server {self._server}') try: self._port = int(port) except ValueError: @@ -142,7 +142,6 @@ class Network(QtCore.QObject): self._socket.connectToHostEncrypted(self._server, self._port) else: self._socket.connectToHost(self._server, self._port) - print('Got SSL connection') self.statusChanged.emit(self.status_connecting, "") def disconnect_weechat(self): diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 76db5a4..89d43c5 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -36,7 +36,10 @@ It requires requires WeeChat 0.3.7 or newer, running on local or remote host. import sys import traceback from pkg_resources import resource_filename -# import qt_compat + +from PySide6.QtWidgets import QApplication +from PySide6 import QtGui, QtWidgets, QtCore + from qweechat import config from qweechat.weechat import protocol from qweechat.network import Network @@ -46,9 +49,6 @@ from qweechat.debug import DebugDialog from qweechat.about import AboutDialog from qweechat.version import qweechat_version -from PySide6.QtWidgets import QApplication -from PySide6 import QtGui, QtWidgets, QtCore - # QtCore = qt_compat.import_module('QtCore') # QtGui = qt_compat.import_module('QtGui') @@ -315,11 +315,11 @@ class MainWindow(QtWidgets.QMainWindow): def _network_weechat_msg(self, message): """Called when a message is received from WeeChat.""" - # self.debug_display(0, '==>', - # 'message (%d bytes):\n%s' - # % (len(message), - # protocol.hex_and_ascii(message, 20)), - # forcecolor='#008800') + self.debug_display(0, '==>', + 'message (%d bytes):\n%s' + % (len(message), + protocol.hex_and_ascii(message.data(), 20)), + forcecolor='#008800') try: proto = protocol.Protocol() message = proto.decode(message.data()) @@ -517,11 +517,6 @@ class MainWindow(QtWidgets.QMainWindow): self.list_buffers.insertItem(index, '%s' % (buf.data['local_variables']['name'])) self.stacked_buffers.insertWidget(index, buf.widget) - self._reorder_buffers() - - def _reorder_buffers(self): - """Order buffers by server.""" - pass def remove_buffer(self, index): """Remove a buffer.""" diff --git a/qweechat/weechat/testproto.py.bak b/qweechat/weechat/testproto.py.bak deleted file mode 100644 index af8a396..0000000 --- a/qweechat/weechat/testproto.py.bak +++ /dev/null @@ -1,253 +0,0 @@ -# -*- coding: utf-8 -*- -# -# testproto.py - command-line program for testing WeeChat/relay protocol -# -# Copyright (C) 2013-2021 Sébastien Helleu -# -# This file is part of QWeeChat, a Qt remote GUI for WeeChat. -# -# QWeeChat is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# QWeeChat is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with QWeeChat. If not, see . -# - -""" -Command-line program for testing WeeChat/relay protocol. -""" - -from __future__ import print_function - -import argparse -import os -import select -import shlex -import socket -import struct -import sys -import time -import traceback - -import protocol # WeeChat/relay protocol -# from .. version import qweechat_version -qweechat_version = '1.1' - -NAME = 'qweechat-testproto' - - -class TestProto(object): - """Test of WeeChat/relay protocol.""" - - def __init__(self, args): - self.args = args - self.sock = None - self.has_quit = False - self.address = '{self.args.hostname}/{self.args.port} ' \ - '(IPv{0})'.format(6 if self.args.ipv6 else 4, self=self) - - def connect(self): - """ - Connect to WeeChat/relay. - Return True if OK, False if error. - """ - inet = socket.AF_INET6 if self.args.ipv6 else socket.AF_INET - try: - self.sock = socket.socket(inet, socket.SOCK_STREAM) - self.sock.connect((self.args.hostname, self.args.port)) - except: # noqa: E722 - if self.sock: - self.sock.close() - print('Failed to connect to', self.address) - return False - print('Connected to', self.address) - return True - - def send(self, messages): - """ - Send a text message to WeeChat/relay. - Return True if OK, False if error. - """ - try: - for msg in messages.split('\n'): - if msg == 'quit': - self.has_quit = True - self.sock.sendall(msg + '\n') - print('\x1b[33m<-- ' + msg + '\x1b[0m') - except: # noqa: E722 - traceback.print_exc() - print('Failed to send message') - return False - return True - - def decode(self, message): - """ - Decode a binary message received from WeeChat/relay. - Return True if OK, False if error. - """ - try: - proto = protocol.Protocol() - msgd = proto.decode(message, - separator='\n' if self.args.debug > 0 - else ', ') - print('') - if self.args.debug >= 2 and msgd.uncompressed: - # display raw message - print('\x1b[32m--> message uncompressed ({0} bytes):\n' - '{1}\x1b[0m' - ''.format(msgd.size_uncompressed, - protocol.hex_and_ascii(msgd.uncompressed, 20))) - # display decoded message - print('\x1b[32m--> {0}\x1b[0m'.format(msgd)) - except: # noqa: E722 - traceback.print_exc() - print('Error while decoding message from WeeChat') - return False - return True - - def send_stdin(self): - """ - Send commands from standard input if some data is available. - Return True if OK (it's OK if stdin has no commands), - False if error. - """ - inr = select.select([sys.stdin], [], [], 0)[0] - if inr: - data = os.read(sys.stdin.fileno(), 4096) - if data: - if not self.send(data.strip()): - # self.sock.close() - return False - # open stdin to read user commands - sys.stdin = open('/dev/tty') - return True - - def mainloop(self): - """ - Main loop: read keyboard, send commands, read socket, - decode/display binary messages received from WeeChat/relay. - Return 0 if OK, 4 if send error, 5 if decode error. - """ - if self.has_quit: - return 0 - message = '' - recvbuf = '' - prompt = '\x1b[36mrelay> \x1b[0m' - sys.stdout.write(prompt) - sys.stdout.flush() - try: - while not self.has_quit: - inr = select.select([sys.stdin, self.sock], [], [], 1)[0] - for _file in inr: - if _file == sys.stdin: - buf = os.read(_file.fileno(), 4096) - if buf: - message += buf - if '\n' in message: - messages = message.split('\n') - msgsent = '\n'.join(messages[:-1]) - if msgsent and not self.send(msgsent): - return 4 - message = messages[-1] - sys.stdout.write(prompt + message) - sys.stdout.flush() - else: - buf = _file.recv(4096) - if buf: - recvbuf += buf - while len(recvbuf) >= 4: - remainder = None - length = struct.unpack('>i', recvbuf[0:4])[0] - if len(recvbuf) < length: - # partial message, just wait for the - # end of message - break - # more than one message? - if length < len(recvbuf): - # save beginning of another message - remainder = recvbuf[length:] - recvbuf = recvbuf[0:length] - if not self.decode(recvbuf): - return 5 - if remainder: - recvbuf = remainder - else: - recvbuf = '' - sys.stdout.write(prompt + message) - sys.stdout.flush() - except: # noqa: E722 - traceback.print_exc() - self.send('quit') - return 0 - - def __del__(self): - print('Closing connection with', self.address) - time.sleep(0.5) - self.sock.close() - - -def main(): - """Main function.""" - # parse command line arguments - parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - fromfile_prefix_chars='@', - description='Command-line program for testing WeeChat/relay protocol.', - epilog=''' -Environment variable "QWEECHAT_PROTO_OPTIONS" can be set with default options. -Argument "@file.txt" can be used to read default options in a file. - -Some commands can be piped to the script, for example: - echo "init password=xxxx" | {name} localhost 5000 - {name} localhost 5000 < commands.txt - -The script returns: - 0: OK - 2: wrong arguments (command line) - 3: connection error - 4: send error (message sent to WeeChat) - 5: decode error (message received from WeeChat) -'''.format(name=NAME)) - parser.add_argument('-6', '--ipv6', action='store_true', - help='connect using IPv6') - parser.add_argument('-d', '--debug', action='count', default=0, - help='debug mode: long objects view ' - '(-dd: display raw messages)') - parser.add_argument('-v', '--version', action='version', - version=qweechat_version) - parser.add_argument('hostname', - help='hostname (or IP address) of machine running ' - 'WeeChat/relay') - parser.add_argument('port', type=int, - help='port of machine running WeeChat/relay') - if len(sys.argv) == 1: - parser.print_help() - sys.exit(0) - _args = parser.parse_args( - shlex.split(os.getenv('QWEECHAT_PROTO_OPTIONS') or '') + sys.argv[1:]) - - test = TestProto(_args) - - # connect to WeeChat/relay - if not test.connect(): - sys.exit(3) - - # send commands from standard input if some data is available - if not test.send_stdin(): - sys.exit(4) - - # main loop (wait commands, display messages received) - returncode = test.mainloop() - del test - sys.exit(returncode) - - -if __name__ == "__main__": - main() From 35136f99b09fd81580e5f9fc5c0265a2a136bc56 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 10:32:45 -0700 Subject: [PATCH 09/14] More fixes. - Use logging instead of print to silence errors when possible. - Parse object types as string instead of bytes. --- qweechat/input.py | 2 +- qweechat/weechat/color.py | 10 +++++++--- qweechat/weechat/protocol.py | 22 +++++++++------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/qweechat/input.py b/qweechat/input.py index 1ee7bd9..9d81c1f 100644 --- a/qweechat/input.py +++ b/qweechat/input.py @@ -32,7 +32,7 @@ class InputLineEdit(QtWidgets.QLineEdit): textSent = QtCore.Signal(str) def __init__(self, scroll_widget): - super().__init__(scroll_widget) + super().__init__() self.scroll_widget = scroll_widget self._history = [] self._history_index = -1 diff --git a/qweechat/weechat/color.py b/qweechat/weechat/color.py index d732006..b11bffc 100644 --- a/qweechat/weechat/color.py +++ b/qweechat/weechat/color.py @@ -21,6 +21,7 @@ # import re +import logging RE_COLOR_ATTRS = r'[*!/_|]*' RE_COLOR_STD = r'(?:%s\d{2})' % RE_COLOR_ATTRS @@ -75,6 +76,9 @@ WEECHAT_BASIC_COLORS = ( ('white', 0)) +log = logging.getLogger(__name__) + + class Color(): def __init__(self, color_options, debug=False): self.color_options = color_options @@ -92,7 +96,7 @@ class Color(): index = int(color) return '\x01(Fr%s)' % self.color_options[index] except: # noqa: E722 - print('Error decoding WeeChat color "%s"' % color) + log.debug('Error decoding WeeChat color "%s"' % color) return '' def _convert_terminal_color(self, fg_bg, attrs, color): @@ -100,7 +104,7 @@ class Color(): index = int(color) return '\x01(%s%s#%s)' % (fg_bg, attrs, self._rgb_color(index)) except: # noqa: E722 - print('Error decoding terminal color "%s"' % color) + log.debug('Error decoding terminal color "%s"' % color) return '' def _convert_color_attr(self, fg_bg, color): @@ -123,7 +127,7 @@ class Color(): return self._convert_terminal_color(fg_bg, attrs, WEECHAT_BASIC_COLORS[index][1]) except: # noqa: E722 - print('Error decoding color "%s"' % color) + log.debug('Error decoding color "%s"' % color) return '' def _attrcode_to_char(self, code): diff --git a/qweechat/weechat/protocol.py b/qweechat/weechat/protocol.py index 4a69378..4e1514d 100644 --- a/qweechat/weechat/protocol.py +++ b/qweechat/weechat/protocol.py @@ -147,7 +147,7 @@ class Protocol: if len(self.data) < 3: self.data = '' return '' - objtype = bytes(self.data[0:3]) + objtype = self.data[0:3].decode() self.data = self.data[3:] return objtype @@ -197,12 +197,9 @@ class Protocol: def _obj_str(self): """Read a string in data (length on 4 bytes + content).""" value = self._obj_len_data(4) - if value is None: - return None - try: - return value.decode() - except AttributeError: - return value + if value in ("", None): + return "" + return value.decode() def _obj_buffer(self): """Read a buffer in data (length on 4 bytes + data).""" @@ -227,8 +224,8 @@ class Protocol: Read a hashtable in data (type for keys + type for values + count + items). """ - type_keys = self._obj_type().decode() - type_values = self._obj_type().decode() + type_keys = self._obj_type() + type_values = self._obj_type() count = self._obj_int() hashtable = WeechatDict() for _ in range(count): @@ -247,7 +244,7 @@ class Protocol: keys_types = [] dict_keys = WeechatDict() for key in list_keys: - items = list(item for item in key.split(':')) + items = key.split(':') keys_types.append(items) dict_keys[items[0]] = items[1] items = [] @@ -258,7 +255,6 @@ class Protocol: for _ in enumerate(list_path): pointers.append(self._obj_ptr()) for key, objtype in keys_types: - objtype = objtype item[key] = self._obj_cb[objtype]() item['__path'] = pointers items.append(item) @@ -296,7 +292,7 @@ class Protocol: def _obj_array(self): """Read an array of values in data.""" - type_values = self._obj_type().decode() + type_values = self._obj_type() count_values = self._obj_int() values = [] for _ in range(count_values): @@ -328,7 +324,7 @@ class Protocol: # read objects objects = WeechatObjects(separator=separator) while len(self.data) > 0: - objtype = self._obj_type().decode() + objtype = self._obj_type() value = self._obj_cb[objtype]() objects.append(WeechatObject(objtype, value, separator=separator)) return WeechatMessage(size, size_uncompressed, compression, From 4de105682e5b2f5c9bc7c7701a58a050918d642c Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 10:51:59 -0700 Subject: [PATCH 10/14] Fix testproto. --- qweechat/weechat/testproto.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/qweechat/weechat/testproto.py b/qweechat/weechat/testproto.py index 54cd2c8..76a7aed 100644 --- a/qweechat/weechat/testproto.py +++ b/qweechat/weechat/testproto.py @@ -34,9 +34,9 @@ import sys import time import traceback -import protocol # WeeChat/relay protocol -# from .. version import qweechat_version -qweechat_version = '1.1' +from qweechat.weechat import protocol + +qweechat_version = '0.1' NAME = 'qweechat-testproto' @@ -60,12 +60,13 @@ class TestProto(object): try: self.sock = socket.socket(inet, socket.SOCK_STREAM) self.sock.connect((self.args.hostname, self.args.port)) - except: # noqa: E722 + except Exception: if self.sock: self.sock.close() print('Failed to connect to', self.address) return False - print('Connected to', self.address) + + print(f'Connected to {self.address} socket {self.sock}') return True def send(self, messages): @@ -122,7 +123,7 @@ class TestProto(object): data = os.read(sys.stdin.fileno(), 4096) if data: if not self.send(data.strip()): - # self.sock.close() + self.sock.close() return False # open stdin to read user commands sys.stdin = open('/dev/tty') From 80f4f34c8781446a4e3526e028e41bb51384c60e Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 11:00:55 -0700 Subject: [PATCH 11/14] Remove import of QApplication. --- qweechat/qweechat.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 89d43c5..b39c717 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -37,7 +37,6 @@ import sys import traceback from pkg_resources import resource_filename -from PySide6.QtWidgets import QApplication from PySide6 import QtGui, QtWidgets, QtCore from qweechat import config @@ -552,7 +551,7 @@ class MainWindow(QtWidgets.QMainWindow): def main(): - app = QApplication(sys.argv) + app = QtWidgets.QApplication(sys.argv) app.setStyle(QtWidgets.QStyleFactory.create('Cleanlooks')) app.setWindowIcon(QtGui.QIcon( resource_filename(__name__, 'data/icons/weechat.png'))) From 5b2c72442b95768824e08fafd06cbf4c30bfb2d0 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 11:03:55 -0700 Subject: [PATCH 12/14] Fix some more imports. --- qweechat/buffer.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/qweechat/buffer.py b/qweechat/buffer.py index c501d48..4320fdd 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -20,13 +20,12 @@ # along with QWeeChat. If not, see . # from pkg_resources import resource_filename + from qweechat.chat import ChatTextEdit from qweechat.input import InputLineEdit -import qweechat.weechat.color as color +from qweechat.weechat import color -from PySide6 import QtCore -from PySide6 import QtWidgets -from PySide6 import QtGui +from PySide6 import QtCore, QtGui, QtWidgets class GenericListWidget(QtWidgets.QListWidget): From 8429c111b02fa7b8eaafad93c46d45da1e41208f Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 11:04:26 -0700 Subject: [PATCH 13/14] Fix flake8. --- qweechat/network.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qweechat/network.py b/qweechat/network.py index 952c02a..889c424 100644 --- a/qweechat/network.py +++ b/qweechat/network.py @@ -27,7 +27,6 @@ from PySide6 import QtCore, QtNetwork from qweechat import config - _PROTO_INIT_CMD = ['init password=%(password)s'] _PROTO_SYNC_CMDS = [ From dd2d55e8b65c8cbfd7c3a6fc49bc57b77fb866f1 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Sat, 5 Jun 2021 11:06:15 -0700 Subject: [PATCH 14/14] Remove more comments. --- qweechat/qweechat.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index b39c717..cc181c3 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -49,9 +49,6 @@ from qweechat.about import AboutDialog from qweechat.version import qweechat_version -# QtCore = qt_compat.import_module('QtCore') -# QtGui = qt_compat.import_module('QtGui') - NAME = 'QWeeChat' AUTHOR = 'Sébastien Helleu' AUTHOR_MAIL = 'flashcode@flashtux.org'