Compare commits

...

10 Commits

Author SHA1 Message Date
emdee b1f0ad4bd8 README.md 2023-12-12 06:09:47 +00:00
emdee ba73b0ac36 Convert to PyQt5 2022-11-20 03:41:26 +00:00
Sébastien Helleu 82e0d92056 Update copyright dates 2022-01-12 23:52:09 +01:00
Sébastien Helleu 001244e9ab Add tests with Python 3.10 2021-12-02 08:17:39 +01:00
Sébastien Helleu 99fe78515c Rename default option "server" to "hostname" 2021-11-14 19:53:15 +01:00
Sébastien Helleu 2a814055fe Ignore bandit security error about possible hardcoded password
Bandit reports this error:

>> Issue: [B105:hardcoded_password_string] Possible hardcoded password: 'init password=%(password)s%(totp)s

The password is of course never hardcoded there.
2021-11-14 19:00:55 +01:00
Sébastien Helleu 0dffebcf24 Remove unused import 2021-11-14 18:57:25 +01:00
Sébastien Helleu 0feac51b53 Rename variable _PROTO_SYNC to _PROTO_SYNC_CMDS 2021-11-14 18:56:48 +01:00
Sébastien Helleu ae648fd7f6 Rename option/field "server" to "hostname" 2021-11-14 18:54:48 +01:00
Sébastien Helleu c05ab0e534 Replace freenode by libera 2021-11-14 18:46:47 +01:00
23 changed files with 102 additions and 83 deletions

View File

@ -14,6 +14,7 @@ jobs:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-20.04

View File

@ -20,5 +20,5 @@ Alphabetically:
Developers are connected to IRC:
* server: 'irc.freenode.net'
* channels: '#weechat' (English) and '#weechat-fr' (French)
* server: irc.libera.chat
* channels: #weechat (English) and #weechat-fr (French)

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2021-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -20,7 +20,7 @@ Homepage: https://weechat.org/
QWeeChat requires:
- Python ≥ 3.7
- [PySide6](https://pypi.org/project/PySide6/)
- PyQt5
- [WeeChat](https://weechat.org) ≥ 0.3.7, on local or remote machine, with relay plugin enabled and listening on a port with protocol "weechat"
### Install via source distribution
@ -42,7 +42,7 @@ You have to add a relay port in WeeChat, for example on port 1234:
In QWeeChat, click on connect and enter fields:
- `server`: the IP address or hostname of your machine with WeeChat running
- `hostname`: the IP address or hostname of your machine with WeeChat running
- `port`: the relay port (defined in WeeChat)
- `password`: the relay password (defined in WeeChat)
- `totp`: the Time-Based One-Time Password (optional, to set if required by WeeChat)
@ -51,7 +51,7 @@ Options can be changed in file `~/.config/qweechat/qweechat.conf`.
## Copyright
Copyright © 2011-2021 [Sébastien Helleu](https://github.com/flashcode)
Copyright © 2011-2022 [Sébastien Helleu](https://github.com/flashcode)
This file is part of QWeeChat, a Qt remote GUI for WeeChat.

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -2,7 +2,7 @@
#
# about.py - about dialog box
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -22,7 +22,7 @@
"""About dialog box."""
from PySide6 import QtCore, QtWidgets as QtGui
from PyQt5 import QtCore, QtWidgets as QtGui
from qweechat.version import qweechat_version
@ -46,7 +46,7 @@ class AboutDialog(QtGui.QDialog):
vbox = QtGui.QVBoxLayout()
messages = [
f'<b>{app_name}</b> {qweechat_version()}',
f'© 2011-2021 {author}',
f'© 2011-2022 {author}',
'',
f'<a href="{weechat_site}">{weechat_site}</a>',
'',

View File

@ -2,7 +2,7 @@
#
# buffer.py - management of WeeChat buffers/nicklist
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -24,7 +24,9 @@
from pkg_resources import resource_filename
from PySide6 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal
Signal = pyqtSignal
from qweechat.chat import ChatTextEdit
from qweechat.input import InputLineEdit
@ -145,7 +147,7 @@ class BufferWidget(QtWidgets.QWidget):
class Buffer(QtCore.QObject):
"""A WeeChat buffer."""
bufferInput = QtCore.Signal(str, str)
bufferInput = Signal(str, str)
def __init__(self, data=None):
QtCore.QObject.__init__(self)

View File

@ -2,7 +2,7 @@
#
# chat.py - chat area
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -24,7 +24,7 @@
import datetime
from PySide6 import QtCore, QtWidgets, QtGui
from PyQt5 import QtCore, QtWidgets, QtGui
from qweechat import config
from qweechat.weechat import color

View File

@ -2,7 +2,7 @@
#
# config.py - configuration for QWeeChat
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -33,14 +33,14 @@ CONFIG_FILENAME = '%s/qweechat.conf' % CONFIG_DIR
CONFIG_DEFAULT_RELAY_LINES = 50
CONFIG_DEFAULT_SECTIONS = ('relay', 'look', 'color')
CONFIG_DEFAULT_OPTIONS = (('relay.server', ''),
('relay.port', ''),
CONFIG_DEFAULT_OPTIONS = (('relay.hostname', '127.0.0.1'),
('relay.port', '9000'),
('relay.ssl', 'off'),
('relay.password', ''),
('relay.autoconnect', 'off'),
('relay.lines', str(CONFIG_DEFAULT_RELAY_LINES)),
('look.debug', 'off'),
('look.statusbar', 'off'))
('look.statusbar', 'on'))
# Default colors for WeeChat color options (option name, #rgb value)
CONFIG_DEFAULT_COLOR_OPTIONS = (

View File

@ -2,7 +2,7 @@
#
# connection.py - connection window
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -22,7 +22,7 @@
"""Connection window."""
from PySide6 import QtGui, QtWidgets
from PyQt5 import QtGui, QtWidgets
class ConnectionDialog(QtWidgets.QDialog):
@ -40,16 +40,16 @@ class ConnectionDialog(QtWidgets.QDialog):
self.fields = {}
focus = None
# server
grid.addWidget(QtWidgets.QLabel('<b>Server</b>'), 0, 0)
# hostname
grid.addWidget(QtWidgets.QLabel('<b>Hostname</b>'), 0, 0)
line_edit = QtWidgets.QLineEdit()
line_edit.setFixedWidth(200)
value = self.values.get('server', '')
value = self.values.get('hostname', '')
line_edit.insert(value)
grid.addWidget(line_edit, 0, 1)
self.fields['server'] = line_edit
self.fields['hostname'] = line_edit
if not focus and not value:
focus = 'server'
focus = 'hostname'
# port / SSL
grid.addWidget(QtWidgets.QLabel('<b>Port</b>'), 1, 0)

View File

@ -4,7 +4,7 @@ Copyright and license for images
Files: weechat.png, bullet_green_8x8.png, bullet_yellow_8x8.png
Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
Released under GPLv3.

View File

@ -2,7 +2,7 @@
#
# debug.py - debug window
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -22,7 +22,7 @@
"""Debug window."""
from PySide6 import QtWidgets
from PyQt5 import QtWidgets
from qweechat.chat import ChatTextEdit
from qweechat.input import InputLineEdit

View File

@ -2,7 +2,7 @@
#
# input.py - input line for chat and debug window
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -22,15 +22,16 @@
"""Input line for chat and debug window."""
from PySide6 import QtCore, QtWidgets
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSignal
Signal = pyqtSignal
class InputLineEdit(QtWidgets.QLineEdit):
"""Input line."""
bufferSwitchPrev = QtCore.Signal()
bufferSwitchNext = QtCore.Signal()
textSent = QtCore.Signal(str)
bufferSwitchPrev = Signal()
bufferSwitchNext = Signal()
textSent = Signal(str)
def __init__(self, scroll_widget):
super().__init__()

View File

@ -2,7 +2,7 @@
#
# network.py - I/O with WeeChat/relay
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -26,7 +26,9 @@ import hashlib
import secrets
import struct
from PySide6 import QtCore, QtNetwork
from PyQt5 import QtCore, QtNetwork
from PyQt5.QtCore import pyqtSignal
Signal = pyqtSignal
from qweechat import config
from qweechat.debug import DebugDialog
@ -47,13 +49,13 @@ _HASH_ALGOS = ':'.join(_HASH_ALGOS_LIST)
_PROTO_HANDSHAKE = f'(handshake) handshake password_hash_algo={_HASH_ALGOS}\n'
# initialize with the password (plain text)
_PROTO_INIT_PWD = 'init password=%(password)s%(totp)s\n'
_PROTO_INIT_PWD = 'init password=%(password)s%(totp)s\n' # nosec
# initialize with the hashed password
_PROTO_INIT_HASH = ('init password_hash='
'%(algo)s:%(salt)s%(iter)s:%(hash)s%(totp)s\n')
_PROTO_SYNC = [
_PROTO_SYNC_CMDS = [
# get buffers
'(listbuffers) hdata buffer:gui_buffers(*) number,full_name,short_name,'
'type,nicklist,title,local_variables',
@ -98,8 +100,8 @@ NETWORK_STATUS = {
class Network(QtCore.QObject):
"""I/O with WeeChat/relay."""
statusChanged = QtCore.Signal(str, str)
messageFromWeechat = QtCore.Signal(QtCore.QByteArray)
statusChanged = Signal(str, str)
messageFromWeechat = Signal(QtCore.QByteArray)
def __init__(self, *args):
super().__init__(*args)
@ -115,7 +117,7 @@ class Network(QtCore.QObject):
def _init_connection(self):
self.status = STATUS_DISCONNECTED
self._server = None
self._hostname = None
self._port = None
self._ssl = None
self._password = None
@ -179,7 +181,7 @@ class Network(QtCore.QObject):
def _build_sync_command(self):
"""Build the sync commands to send to WeeChat."""
cmd = '\n'.join(_PROTO_SYNC) + '\n'
cmd = '\n'.join(_PROTO_SYNC_CMDS) + '\n'
return cmd % {'lines': self._lines}
def handshake_timer_expired(self):
@ -236,9 +238,9 @@ class Network(QtCore.QObject):
"""Return True if SSL is used, False otherwise."""
return self._ssl
def connect_weechat(self, server, port, ssl, password, totp, lines):
def connect_weechat(self, hostname, port, ssl, password, totp, lines):
"""Connect to WeeChat."""
self._server = server
self._hostname = hostname
try:
self._port = int(port)
except ValueError:
@ -256,9 +258,9 @@ class Network(QtCore.QObject):
self._socket.abort()
if self._ssl:
self._socket.ignoreSslErrors()
self._socket.connectToHostEncrypted(self._server, self._port)
self._socket.connectToHostEncrypted(self._hostname, self._port)
else:
self._socket.connectToHost(self._server, self._port)
self._socket.connectToHost(self._hostname, self._port)
self.set_status(STATUS_CONNECTING)
def disconnect_weechat(self):
@ -316,7 +318,7 @@ class Network(QtCore.QObject):
def get_options(self):
"""Get connection options."""
return {
'server': self._server,
'hostname': self._hostname,
'port': self._port,
'ssl': 'on' if self._ssl else 'off',
'password': self._password,

View File

@ -2,7 +2,7 @@
#
# preferences.py - preferences dialog box
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -22,7 +22,7 @@
"""Preferences dialog box."""
from PySide6 import QtCore, QtWidgets as QtGui
from PyQt5 import QtCore, QtWidgets as QtGui
class PreferencesDialog(QtGui.QDialog):

View File

@ -2,7 +2,7 @@
#
# qweechat.py - WeeChat remote GUI using Qt toolkit
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#
@ -37,13 +37,13 @@ import sys
import traceback
from pkg_resources import resource_filename
from PySide6 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
from qweechat import config
from qweechat.about import AboutDialog
from qweechat.buffer import BufferListWidget, Buffer
from qweechat.connection import ConnectionDialog
from qweechat.network import Network, STATUS_DISCONNECTED, NETWORK_STATUS
from qweechat.network import Network, STATUS_DISCONNECTED
from qweechat.preferences import PreferencesDialog
from qweechat.weechat import protocol
@ -52,7 +52,7 @@ APP_NAME = 'QWeeChat'
AUTHOR = 'Sébastien Helleu'
WEECHAT_SITE = 'https://weechat.org/'
# not QFrame
class MainWindow(QtWidgets.QMainWindow):
"""Main window."""
@ -87,10 +87,16 @@ class MainWindow(QtWidgets.QMainWindow):
splitter.addWidget(self.list_buffers)
splitter.addWidget(self.stacked_buffers)
self.list_buffers.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
QtWidgets.QSizePolicy.Preferred)
self.stacked_buffers.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
# MainWindow
self.setCentralWidget(splitter)
if self.config.getboolean('look', 'statusbar'):
self.statusBar().visible = True
self.statusBar().visible = True
# actions for menu and toolbar
actions_def = {
@ -139,7 +145,7 @@ class MainWindow(QtWidgets.QMainWindow):
}
self.actions = {}
for name, action in list(actions_def.items()):
self.actions[name] = QtGui.QAction(
self.actions[name] = QtWidgets.QAction(
QtGui.QIcon(
resource_filename(__name__, 'data/icons/%s' % action[0])),
name.capitalize(), self)
@ -164,20 +170,22 @@ class MainWindow(QtWidgets.QMainWindow):
self.network_status.setFixedWidth(200)
self.network_status.setContentsMargins(0, 0, 10, 0)
self.network_status.setAlignment(QtCore.Qt.AlignRight)
if hasattr(self.menu, 'setCornerWidget'):
self.menu.setCornerWidget(self.network_status,
QtCore.Qt.TopRightCorner)
if hasattr(self, 'menuBar'):
if hasattr(self.menu, 'setCornerWidget'):
self.menu.setCornerWidget(self.network_status,
QtCore.Qt.TopRightCorner)
self.network_status_set(STATUS_DISCONNECTED)
# toolbar
toolbar = self.addToolBar('toolBar')
toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
toolbar.addActions([self.actions['connect'],
self.actions['disconnect'],
self.actions['debug'],
self.actions['preferences'],
self.actions['about'],
self.actions['quit']])
if hasattr(self, 'addToolBar'):
toolbar = self.addToolBar('toolBar')
toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
toolbar.addActions([self.actions['connect'],
self.actions['disconnect'],
self.actions['debug'],
self.actions['preferences'],
self.actions['about'],
self.actions['quit']])
self.buffers[0].widget.input.setFocus()
@ -188,12 +196,12 @@ class MainWindow(QtWidgets.QMainWindow):
# auto-connect to relay
if self.config.getboolean('relay', 'autoconnect'):
self.network.connect_weechat(
server=self.config.get('relay', 'server'),
port=self.config.get('relay', 'port'),
ssl=self.config.getboolean('relay', 'ssl'),
password=self.config.get('relay', 'password'),
hostname=self.config.get('relay', 'hostname', fallback=''),
port=self.config.get('relay', 'port', fallback=''),
ssl=self.config.getboolean('relay', 'ssl', fallback=''),
password=self.config.get('relay', 'password', fallback=''),
totp=None,
lines=self.config.get('relay', 'lines'),
lines=self.config.get('relay', 'lines', fallback=''),
)
self.show()
@ -230,8 +238,8 @@ class MainWindow(QtWidgets.QMainWindow):
def open_connection_dialog(self):
"""Open a dialog with connection settings."""
values = {}
for option in ('server', 'port', 'ssl', 'password', 'lines'):
values[option] = self.config.get('relay', option)
for option in ('hostname', 'port', 'ssl', 'password', 'lines'):
values[option] = self.config.get('relay', option, fallback='')
self.connection_dialog = ConnectionDialog(values, self)
self.connection_dialog.dialog_buttons.accepted.connect(
self.connect_weechat)
@ -239,7 +247,7 @@ class MainWindow(QtWidgets.QMainWindow):
def connect_weechat(self):
"""Connect to WeeChat."""
self.network.connect_weechat(
server=self.connection_dialog.fields['server'].text(),
hostname=self.connection_dialog.fields['hostname'].text(),
port=self.connection_dialog.fields['port'].text(),
ssl=self.connection_dialog.fields['ssl'].isChecked(),
password=self.connection_dialog.fields['password'].text(),
@ -258,8 +266,12 @@ class MainWindow(QtWidgets.QMainWindow):
def network_status_set(self, status):
"""Set the network status."""
pal = self.network_status.palette()
pal.setColor(self.network_status.foregroundRole(),
try:
pal.setColor(self.network_status.foregroundRole(),
self.network.status_color(status))
except:
# dunno
pass
ssl = ' (SSL)' if status != STATUS_DISCONNECTED \
and self.network.is_ssl() else ''
self.network_status.setPalette(pal)
@ -525,7 +537,7 @@ class MainWindow(QtWidgets.QMainWindow):
if self.network.debug_dialog:
self.network.debug_dialog.close()
config.write(self.config)
QtWidgets.QMainWindow.closeEvent(self, event)
QtWidgets.QFrame.closeEvent(self, event)
def main():

View File

@ -2,7 +2,7 @@
#
# version.py - version of QWeeChat
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -2,7 +2,7 @@
#
# color.py - remove/replace colors in WeeChat strings
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -2,7 +2,7 @@
#
# protocol.py - decode binary messages received from WeeChat/relay
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -2,7 +2,7 @@
#
# testproto.py - command-line program for testing WeeChat/relay protocol
#
# Copyright (C) 2013-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2013-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#

View File

@ -1 +1,2 @@
PySide6
PyQt5

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2011-2022 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of QWeeChat, a Qt remote GUI for WeeChat.
#