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
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/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..4320fdd 100644
--- a/qweechat/buffer.py
+++ b/qweechat/buffer.py
@@ -19,22 +19,20 @@
# You should have received a copy of the GNU General Public License
# along with QWeeChat. If not, see .
#
-
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 qweechat.chat import ChatTextEdit
+from qweechat.input import InputLineEdit
+from qweechat.weechat import color
+
+from PySide6 import QtCore, QtGui, QtWidgets
-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 +50,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 +68,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 +83,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 +108,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 +137,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 +145,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)
@@ -167,15 +165,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: # 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: # noqa: E722
self.widget.set_prompt(None)
def input_text_sent(self, text):
@@ -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..2d5f47e 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
+from qweechat import config
+from qweechat.weechat import 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..c1107f2 100644
--- a/qweechat/connection.py
+++ b/qweechat/connection.py
@@ -20,29 +20,27 @@
# along with QWeeChat. If not, see .
#
-import qt_compat
-
-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 +49,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..b5f4d85 100644
--- a/qweechat/debug.py
+++ b/qweechat/debug.py
@@ -20,25 +20,24 @@
# along with QWeeChat. If not, see .
#
-import qt_compat
-from chat import ChatTextEdit
-from input import InputLineEdit
+from qweechat.chat import ChatTextEdit
+from qweechat.input import InputLineEdit
-QtGui = qt_compat.import_module('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 5bde922..9d81c1f 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
-class InputLineEdit(QtGui.QLineEdit):
+class InputLineEdit(QtWidgets.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__()
self.scroll_widget = scroll_widget
self._history = []
self._history_index = -1
@@ -50,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()
@@ -65,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:
@@ -75,10 +73,10 @@ 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().encode('utf-8'))
+ self._history.append(self.text())
self._history_index = len(self._history)
self.textSent.emit(self.text())
self.clear()
diff --git a/qweechat/network.py b/qweechat/network.py
index 8c497ea..889c424 100644
--- a/qweechat/network.py
+++ b/qweechat/network.py
@@ -21,11 +21,11 @@
#
import struct
-import qt_compat
-import config
-QtCore = qt_compat.import_module('QtCore')
-QtNetwork = qt_compat.import_module('QtNetwork')
+from PySide6 import QtCore, QtNetwork
+
+from qweechat import config
+
_PROTO_INIT_CMD = ['init password=%(password)s']
@@ -47,11 +47,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 = QtCore.Signal(str, str)
+ messageFromWeechat = QtCore.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,7 +63,7 @@ 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)
@@ -87,7 +87,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 +108,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):
@@ -136,11 +136,12 @@ 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)
+ 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..cc181c3 100644
--- a/qweechat/qweechat.py
+++ b/qweechat/qweechat.py
@@ -36,18 +36,18 @@ 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 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
-QtCore = qt_compat.import_module('QtCore')
-QtGui = qt_compat.import_module('QtGui')
+from PySide6 import QtGui, QtWidgets, QtCore
+
+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
+
NAME = 'QWeeChat'
AUTHOR = 'Sébastien Helleu'
@@ -58,11 +58,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 +87,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 +146,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)
@@ -249,8 +249,7 @@ class MainWindow(QtGui.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),
@@ -315,11 +314,11 @@ class MainWindow(QtGui.QMainWindow):
self.debug_display(0, '==>',
'message (%d bytes):\n%s'
% (len(message),
- protocol.hex_and_ascii(message, 20)),
+ protocol.hex_and_ascii(message.data(), 20)),
forcecolor='#008800')
try:
proto = protocol.Protocol()
- message = proto.decode(str(message))
+ message = proto.decode(message.data())
if message.uncompressed:
self.debug_display(
0, '==>',
@@ -329,7 +328,7 @@ class MainWindow(QtGui.QMainWindow):
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()
@@ -495,6 +494,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."""
@@ -509,9 +510,8 @@ class MainWindow(QtGui.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'].decode('utf-8')))
+ self.list_buffers.insertItem(index, '%s'
+ % (buf.data['local_variables']['name']))
self.stacked_buffers.insertWidget(index, buf.widget)
def remove_buffer(self, index):
@@ -544,12 +544,18 @@ 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.setWindowIcon(QtGui.QIcon(
- resource_filename(__name__, 'data/icons/weechat.png')))
-main = MainWindow()
-sys.exit(app.exec_())
+def main():
+ app = QtWidgets.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()
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 79b24c1..4e1514d 100644
--- a/qweechat/weechat/protocol.py
+++ b/qweechat/weechat/protocol.py
@@ -34,15 +34,11 @@ 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 +147,7 @@ class Protocol:
if len(self.data) < 3:
self.data = ''
return ''
- objtype = str(self.data[0:3])
+ objtype = self.data[0:3].decode()
self.data = self.data[3:]
return objtype
@@ -196,14 +192,14 @@ 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)
+ if value in ("", None):
+ return ""
+ return value.decode()
def _obj_buffer(self):
"""Read a buffer in data (length on 4 bytes + data)."""
@@ -214,14 +210,14 @@ 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):
"""
@@ -314,8 +310,8 @@ class Protocol:
if compression:
uncompressed = zlib.decompress(self.data[5:])
size_uncompressed = len(uncompressed) + 5
- uncompressed = '%s%s%s' % (struct.pack('>i', size_uncompressed),
- struct.pack('b', 0), uncompressed)
+ uncompressed = b'%s%s%s' % (struct.pack('>i', size_uncompressed),
+ struct.pack('b', 0), uncompressed)
self.data = uncompressed
else:
uncompressed = self.data[:]
@@ -344,13 +340,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):
+ # 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..76a7aed 100644
--- a/qweechat/weechat/testproto.py
+++ b/qweechat/weechat/testproto.py
@@ -24,8 +24,6 @@
Command-line program for testing WeeChat/relay protocol.
"""
-from __future__ import print_function
-
import argparse
import os
import select
@@ -36,8 +34,9 @@ import sys
import time
import traceback
-import protocol # WeeChat/relay protocol
-from .. version import qweechat_version
+from qweechat.weechat import protocol
+
+qweechat_version = '0.1'
NAME = 'qweechat-testproto'
@@ -61,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):
@@ -75,11 +75,12 @@ 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:
@@ -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')
@@ -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/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',
+ ]
)