From 424e15b31c099a2fb8c4da56a74c6c29c4a9f12c Mon Sep 17 00:00:00 2001 From: emdee Date: Sun, 20 Nov 2022 18:16:31 +0000 Subject: [PATCH] add third_party --- toxygen/third_party/qweechat/about.py.diff | 27 - toxygen/third_party/qweechat/about.py.dst | 61 -- toxygen/third_party/qweechat/buffer.py.diff | 27 - toxygen/third_party/qweechat/buffer.py.dst | 248 -------- toxygen/third_party/qweechat/chat.py.diff | 27 - toxygen/third_party/qweechat/chat.py.dst | 142 ----- toxygen/third_party/qweechat/config.py.dst | 136 ----- .../third_party/qweechat/connection.py.diff | 27 - .../third_party/qweechat/connection.py.dst | 122 ---- toxygen/third_party/qweechat/debug.py.diff | 27 - toxygen/third_party/qweechat/debug.py.dst | 51 -- toxygen/third_party/qweechat/input.py.diff | 27 - toxygen/third_party/qweechat/input.py.dst | 95 --- toxygen/third_party/qweechat/network.py.diff | 27 - toxygen/third_party/qweechat/network.py.dst | 356 ------------ .../third_party/qweechat/preferences.py.diff | 27 - .../third_party/qweechat/preferences.py.dst | 57 -- toxygen/third_party/qweechat/qweechat.py.diff | 27 - toxygen/third_party/qweechat/qweechat.py.dst | 542 ------------------ 19 files changed, 2053 deletions(-) delete mode 100644 toxygen/third_party/qweechat/about.py.diff delete mode 100644 toxygen/third_party/qweechat/about.py.dst delete mode 100644 toxygen/third_party/qweechat/buffer.py.diff delete mode 100644 toxygen/third_party/qweechat/buffer.py.dst delete mode 100644 toxygen/third_party/qweechat/chat.py.diff delete mode 100644 toxygen/third_party/qweechat/chat.py.dst delete mode 100644 toxygen/third_party/qweechat/config.py.dst delete mode 100644 toxygen/third_party/qweechat/connection.py.diff delete mode 100644 toxygen/third_party/qweechat/connection.py.dst delete mode 100644 toxygen/third_party/qweechat/debug.py.diff delete mode 100644 toxygen/third_party/qweechat/debug.py.dst delete mode 100644 toxygen/third_party/qweechat/input.py.diff delete mode 100644 toxygen/third_party/qweechat/input.py.dst delete mode 100644 toxygen/third_party/qweechat/network.py.diff delete mode 100644 toxygen/third_party/qweechat/network.py.dst delete mode 100644 toxygen/third_party/qweechat/preferences.py.diff delete mode 100644 toxygen/third_party/qweechat/preferences.py.dst delete mode 100644 toxygen/third_party/qweechat/qweechat.py.diff delete mode 100644 toxygen/third_party/qweechat/qweechat.py.dst diff --git a/toxygen/third_party/qweechat/about.py.diff b/toxygen/third_party/qweechat/about.py.diff deleted file mode 100644 index 9fbe245..0000000 --- a/toxygen/third_party/qweechat/about.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** about.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- about.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 20,30 **** - # along with QWeeChat. If not, see . - # - - """About dialog box.""" - -! from PySide6 import QtCore, QtWidgets as QtGui - - from qweechat.version import qweechat_version - - - class AboutDialog(QtGui.QDialog): ---- 20,30 ---- - # along with QWeeChat. If not, see . - # - - """About dialog box.""" - -! from PyQt5 import QtCore, QtWidgets as QtGui - - from qweechat.version import qweechat_version - - - class AboutDialog(QtGui.QDialog): diff --git a/toxygen/third_party/qweechat/about.py.dst b/toxygen/third_party/qweechat/about.py.dst deleted file mode 100644 index 01b7605..0000000 --- a/toxygen/third_party/qweechat/about.py.dst +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# -# about.py - about dialog box -# -# Copyright (C) 2011-2022 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 . -# - -"""About dialog box.""" - -from PySide6 import QtCore, QtWidgets as QtGui - -from qweechat.version import qweechat_version - - -class AboutDialog(QtGui.QDialog): - """About dialog.""" - - def __init__(self, app_name, author, weechat_site, *args): - QtGui.QDialog.__init__(*(self,) + args) - self.setModal(True) - self.setWindowTitle('About') - - close_button = QtGui.QPushButton('Close') - close_button.pressed.connect(self.close) - - hbox = QtGui.QHBoxLayout() - hbox.addStretch(1) - hbox.addWidget(close_button) - hbox.addStretch(1) - - vbox = QtGui.QVBoxLayout() - messages = [ - f'{app_name} {qweechat_version()}', - f'© 2011-2022 {author}', - '', - f'{weechat_site}', - '', - ] - for msg in messages: - label = QtGui.QLabel(msg) - label.setAlignment(QtCore.Qt.AlignHCenter) - vbox.addWidget(label) - vbox.addLayout(hbox) - - self.setLayout(vbox) - self.show() diff --git a/toxygen/third_party/qweechat/buffer.py.diff b/toxygen/third_party/qweechat/buffer.py.diff deleted file mode 100644 index 2965c6f..0000000 --- a/toxygen/third_party/qweechat/buffer.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** buffer.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- buffer.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 22,32 **** - - """Management of WeeChat buffers/nicklist.""" - - from pkg_resources import resource_filename - -! from PySide6 import QtCore, QtGui, QtWidgets - - from qweechat.chat import ChatTextEdit - from qweechat.input import InputLineEdit - from qweechat.weechat import color - ---- 22,32 ---- - - """Management of WeeChat buffers/nicklist.""" - - from pkg_resources import resource_filename - -! from PyQt5 import QtCore, QtGui, QtWidgets - - from qweechat.chat import ChatTextEdit - from qweechat.input import InputLineEdit - from qweechat.weechat import color - diff --git a/toxygen/third_party/qweechat/buffer.py.dst b/toxygen/third_party/qweechat/buffer.py.dst deleted file mode 100644 index 2f6e32f..0000000 --- a/toxygen/third_party/qweechat/buffer.py.dst +++ /dev/null @@ -1,248 +0,0 @@ -# -*- coding: utf-8 -*- -# -# buffer.py - management of WeeChat buffers/nicklist -# -# Copyright (C) 2011-2022 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 . -# - -"""Management of WeeChat buffers/nicklist.""" - -from pkg_resources import resource_filename - -from PySide6 import QtCore, QtGui, QtWidgets - -from qweechat.chat import ChatTextEdit -from qweechat.input import InputLineEdit -from qweechat.weechat import color - - -class GenericListWidget(QtWidgets.QListWidget): - """Generic QListWidget with dynamic size.""" - - def __init__(self, *args): - super().__init__(*args) - self.setMaximumWidth(100) - self.setTextElideMode(QtCore.Qt.ElideNone) - self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.setFocusPolicy(QtCore.Qt.NoFocus) - pal = self.palette() - pal.setColor(QtGui.QPalette.Highlight, QtGui.QColor('#ddddff')) - pal.setColor(QtGui.QPalette.HighlightedText, QtGui.QColor('black')) - self.setPalette(pal) - - def auto_resize(self): - size = self.sizeHintForColumn(0) - if size > 0: - size += 4 - self.setMaximumWidth(size) - - def clear(self, *args): - """Re-implement clear to set dynamic size after clear.""" - QtWidgets.QListWidget.clear(*(self,) + args) - self.auto_resize() - - def addItem(self, *args): - """Re-implement addItem to set dynamic size after add.""" - QtWidgets.QListWidget.addItem(*(self,) + args) - self.auto_resize() - - def insertItem(self, *args): - """Re-implement insertItem to set dynamic size after insert.""" - QtWidgets.QListWidget.insertItem(*(self,) + args) - self.auto_resize() - - -class BufferListWidget(GenericListWidget): - """Widget with list of buffers.""" - - def switch_prev_buffer(self): - if self.currentRow() > 0: - self.setCurrentRow(self.currentRow() - 1) - else: - self.setCurrentRow(self.count() - 1) - - def switch_next_buffer(self): - if self.currentRow() < self.count() - 1: - self.setCurrentRow(self.currentRow() + 1) - else: - self.setCurrentRow(0) - - -class BufferWidget(QtWidgets.QWidget): - """ - Widget with (from top to bottom): - title, chat + nicklist (optional) + prompt/input. - """ - - def __init__(self, display_nicklist=False): - super().__init__() - - # title - self.title = QtWidgets.QLineEdit() - self.title.setFocusPolicy(QtCore.Qt.NoFocus) - - # splitter with chat + nicklist - 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() - if not display_nicklist: - self.nicklist.setVisible(False) - self.chat_nicklist.addWidget(self.nicklist) - - # prompt + input - 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 = QtWidgets.QWidget() - prompt_input.setLayout(self.hbox_edit) - - # vbox with title + chat/nicklist + prompt/input - vbox = QtWidgets.QVBoxLayout() - vbox.setContentsMargins(0, 0, 0, 0) - vbox.setSpacing(0) - vbox.addWidget(self.title) - vbox.addWidget(self.chat_nicklist) - vbox.addWidget(prompt_input) - - self.setLayout(vbox) - - def set_title(self, title): - """Set buffer title.""" - self.title.clear() - if title is not None: - self.title.setText(title) - - def set_prompt(self, prompt): - """Set prompt.""" - if self.hbox_edit.count() > 1: - self.hbox_edit.takeAt(0) - if prompt is not None: - label = QtWidgets.QLabel(prompt) - label.setContentsMargins(0, 0, 5, 0) - self.hbox_edit.insertWidget(0, label) - - -class Buffer(QtCore.QObject): - """A WeeChat buffer.""" - - bufferInput = QtCore.Signal(str, str) - - def __init__(self, data=None): - QtCore.QObject.__init__(self) - self.data = data or {} - self.nicklist = {} - self.widget = BufferWidget(display_nicklist=self.data.get('nicklist', - 0)) - self.update_title() - self.update_prompt() - self.widget.input.textSent.connect(self.input_text_sent) - - def pointer(self): - """Return pointer on buffer.""" - return self.data.get('__path', [''])[0] - - def update_title(self): - """Update title.""" - try: - self.widget.set_title( - 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 Exception: # noqa: E722 - self.widget.set_prompt(None) - - def input_text_sent(self, text): - """Called when text has to be sent to buffer.""" - if self.data: - self.bufferInput.emit(self.data['full_name'], text) - - def nicklist_add_item(self, parent, group, prefix, name, visible): - """Add a group/nick in nicklist.""" - if group: - self.nicklist[name] = { - 'visible': visible, - 'nicks': [] - } - else: - self.nicklist[parent]['nicks'].append({ - 'prefix': prefix, - 'name': name, - 'visible': visible, - }) - - def nicklist_remove_item(self, parent, group, name): - """Remove a group/nick from nicklist.""" - if group: - if name in self.nicklist: - del self.nicklist[name] - else: - if parent in self.nicklist: - self.nicklist[parent]['nicks'] = [ - nick for nick in self.nicklist[parent]['nicks'] - if nick['name'] != name - ] - - def nicklist_update_item(self, parent, group, prefix, name, visible): - """Update a group/nick in nicklist.""" - if group: - if name in self.nicklist: - self.nicklist[name]['visible'] = visible - else: - if parent in self.nicklist: - for nick in self.nicklist[parent]['nicks']: - if nick['name'] == name: - nick['prefix'] = prefix - nick['visible'] = visible - break - - def nicklist_refresh(self): - """Refresh nicklist.""" - self.widget.nicklist.clear() - for group in sorted(self.nicklist): - for nick in sorted(self.nicklist[group]['nicks'], - key=lambda n: n['name']): - prefix_color = { - '': '', - ' ': '', - '+': 'yellow', - } - col = prefix_color.get(nick['prefix'], 'green') - if col: - icon = QtGui.QIcon( - resource_filename(__name__, - 'data/icons/bullet_%s_8x8.png' % - col)) - else: - pixmap = QtGui.QPixmap(8, 8) - pixmap.fill() - icon = QtGui.QIcon(pixmap) - item = QtWidgets.QListWidgetItem(icon, nick['name']) - self.widget.nicklist.addItem(item) - self.widget.nicklist.setVisible(True) diff --git a/toxygen/third_party/qweechat/chat.py.diff b/toxygen/third_party/qweechat/chat.py.diff deleted file mode 100644 index bab42bc..0000000 --- a/toxygen/third_party/qweechat/chat.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** chat.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- chat.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 22,32 **** - - """Chat area.""" - - import datetime - -! from PySide6 import QtCore, QtWidgets, QtGui - - from qweechat import config - from qweechat.weechat import color - - ---- 22,32 ---- - - """Chat area.""" - - import datetime - -! from PyQt5 import QtCore, QtWidgets, QtGui - - from qweechat import config - from qweechat.weechat import color - - diff --git a/toxygen/third_party/qweechat/chat.py.dst b/toxygen/third_party/qweechat/chat.py.dst deleted file mode 100644 index b8a3788..0000000 --- a/toxygen/third_party/qweechat/chat.py.dst +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -# -# chat.py - chat area -# -# Copyright (C) 2011-2022 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 . -# - -"""Chat area.""" - -import datetime - -from PySide6 import QtCore, QtWidgets, QtGui - -from qweechat import config -from qweechat.weechat import color - - -class ChatTextEdit(QtWidgets.QTextEdit): - """Chat area.""" - - def __init__(self, debug, *args): - QtWidgets.QTextEdit.__init__(*(self,) + args) - self.debug = debug - self.readOnly = True - self.setFocusPolicy(QtCore.Qt.NoFocus) - self.setFontFamily('monospace') - self._textcolor = self.textColor() - self._bgcolor = QtGui.QColor('#FFFFFF') - self._setcolorcode = { - 'F': (self.setTextColor, self._textcolor), - 'B': (self.setTextBackgroundColor, self._bgcolor) - } - self._setfont = { - '*': self.setFontWeight, - '_': self.setFontUnderline, - '/': self.setFontItalic - } - self._fontvalues = { - False: { - '*': QtGui.QFont.Normal, - '_': False, - '/': False - }, - True: { - '*': QtGui.QFont.Bold, - '_': True, - '/': True - } - } - self._color = color.Color(config.color_options(), self.debug) - - def display(self, time, prefix, text, forcecolor=None): - if time == 0: - now = datetime.datetime.now() - else: - now = datetime.datetime.fromtimestamp(float(time)) - self.setTextColor(QtGui.QColor('#999999')) - self.insertPlainText(now.strftime('%H:%M ')) - prefix = self._color.convert(prefix) - text = self._color.convert(text) - if forcecolor: - if prefix: - prefix = '\x01(F%s)%s' % (forcecolor, prefix) - text = '\x01(F%s)%s' % (forcecolor, text) - if prefix: - self._display_with_colors(prefix + ' ') - if text: - self._display_with_colors(text) - if text[-1:] != '\n': - self.insertPlainText('\n') - else: - self.insertPlainText('\n') - self.scroll_bottom() - - def _display_with_colors(self, string): - self.setTextColor(self._textcolor) - self.setTextBackgroundColor(self._bgcolor) - self._reset_attributes() - items = string.split('\x01') - for i, item in enumerate(items): - if i > 0 and item.startswith('('): - pos = item.find(')') - if pos >= 2: - action = item[1] - code = item[2:pos] - if action == '+': - # set attribute - self._set_attribute(code[0], True) - elif action == '-': - # remove attribute - self._set_attribute(code[0], False) - else: - # reset attributes and color - if code == 'r': - self._reset_attributes() - self._setcolorcode[action][0]( - self._setcolorcode[action][1]) - else: - # set attributes + color - while code.startswith(('*', '!', '/', '_', '|', - 'r')): - if code[0] == 'r': - self._reset_attributes() - elif code[0] in self._setfont: - self._set_attribute( - code[0], - not self._font[code[0]]) - code = code[1:] - if code: - self._setcolorcode[action][0]( - QtGui.QColor(code)) - item = item[pos+1:] - if len(item) > 0: - self.insertPlainText(item) - - def _reset_attributes(self): - self._font = {} - for attr in self._setfont: - self._set_attribute(attr, False) - - def _set_attribute(self, attr, value): - self._font[attr] = value - self._setfont[attr](self._fontvalues[self._font[attr]][attr]) - - def scroll_bottom(self): - scroll = self.verticalScrollBar() - scroll.setValue(scroll.maximum()) diff --git a/toxygen/third_party/qweechat/config.py.dst b/toxygen/third_party/qweechat/config.py.dst deleted file mode 100644 index 42fbba4..0000000 --- a/toxygen/third_party/qweechat/config.py.dst +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -# -# config.py - configuration for QWeeChat -# -# Copyright (C) 2011-2022 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 . -# - -"""Configuration for QWeeChat.""" - -import configparser -import os - -from pathlib import Path - -CONFIG_DIR = '%s/.config/qweechat' % os.getenv('HOME') -CONFIG_FILENAME = '%s/qweechat.conf' % CONFIG_DIR - -CONFIG_DEFAULT_RELAY_LINES = 50 - -CONFIG_DEFAULT_SECTIONS = ('relay', 'look', 'color') -CONFIG_DEFAULT_OPTIONS = (('relay.hostname', ''), - ('relay.port', ''), - ('relay.ssl', 'off'), - ('relay.password', ''), - ('relay.autoconnect', 'off'), - ('relay.lines', str(CONFIG_DEFAULT_RELAY_LINES)), - ('look.debug', 'off'), - ('look.statusbar', 'off')) - -# Default colors for WeeChat color options (option name, #rgb value) -CONFIG_DEFAULT_COLOR_OPTIONS = ( - ('separator', '#000066'), # 0 - ('chat', '#000000'), # 1 - ('chat_time', '#999999'), # 2 - ('chat_time_delimiters', '#000000'), # 3 - ('chat_prefix_error', '#FF6633'), # 4 - ('chat_prefix_network', '#990099'), # 5 - ('chat_prefix_action', '#000000'), # 6 - ('chat_prefix_join', '#00CC00'), # 7 - ('chat_prefix_quit', '#CC0000'), # 8 - ('chat_prefix_more', '#CC00FF'), # 9 - ('chat_prefix_suffix', '#330099'), # 10 - ('chat_buffer', '#000000'), # 11 - ('chat_server', '#000000'), # 12 - ('chat_channel', '#000000'), # 13 - ('chat_nick', '#000000'), # 14 - ('chat_nick_self', '*#000000'), # 15 - ('chat_nick_other', '#000000'), # 16 - ('', '#000000'), # 17 (nick1 -- obsolete) - ('', '#000000'), # 18 (nick2 -- obsolete) - ('', '#000000'), # 19 (nick3 -- obsolete) - ('', '#000000'), # 20 (nick4 -- obsolete) - ('', '#000000'), # 21 (nick5 -- obsolete) - ('', '#000000'), # 22 (nick6 -- obsolete) - ('', '#000000'), # 23 (nick7 -- obsolete) - ('', '#000000'), # 24 (nick8 -- obsolete) - ('', '#000000'), # 25 (nick9 -- obsolete) - ('', '#000000'), # 26 (nick10 -- obsolete) - ('chat_host', '#666666'), # 27 - ('chat_delimiters', '#9999FF'), # 28 - ('chat_highlight', '#3399CC'), # 29 - ('chat_read_marker', '#000000'), # 30 - ('chat_text_found', '#000000'), # 31 - ('chat_value', '#000000'), # 32 - ('chat_prefix_buffer', '#000000'), # 33 - ('chat_tags', '#000000'), # 34 - ('chat_inactive_window', '#000000'), # 35 - ('chat_inactive_buffer', '#000000'), # 36 - ('chat_prefix_buffer_inactive_buffer', '#000000'), # 37 - ('chat_nick_offline', '#000000'), # 38 - ('chat_nick_offline_highlight', '#000000'), # 39 - ('chat_nick_prefix', '#000000'), # 40 - ('chat_nick_suffix', '#000000'), # 41 - ('emphasis', '#000000'), # 42 - ('chat_day_change', '#000000'), # 43 -) -config_color_options = [] - - -def read(): - """Read config file.""" - global config_color_options - config = configparser.RawConfigParser() - if os.path.isfile(CONFIG_FILENAME): - config.read(CONFIG_FILENAME) - - # add missing sections/options - for section in CONFIG_DEFAULT_SECTIONS: - if not config.has_section(section): - config.add_section(section) - for option in reversed(CONFIG_DEFAULT_OPTIONS): - section, name = option[0].split('.', 1) - if not config.has_option(section, name): - config.set(section, name, option[1]) - section = 'color' - for option in reversed(CONFIG_DEFAULT_COLOR_OPTIONS): - if option[0] and not config.has_option(section, option[0]): - config.set(section, option[0], option[1]) - - # build list of color options - config_color_options = [] - for option in CONFIG_DEFAULT_COLOR_OPTIONS: - if option[0]: - config_color_options.append(config.get('color', option[0])) - else: - config_color_options.append('#000000') - - return config - - -def write(config): - """Write config file.""" - Path(CONFIG_DIR).mkdir(mode=0o0700, parents=True, exist_ok=True) - with open(CONFIG_FILENAME, 'w') as cfg: - config.write(cfg) - - -def color_options(): - """Return color options.""" - global config_color_options - return config_color_options diff --git a/toxygen/third_party/qweechat/connection.py.diff b/toxygen/third_party/qweechat/connection.py.diff deleted file mode 100644 index b7ca776..0000000 --- a/toxygen/third_party/qweechat/connection.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** connection.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- connection.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 20,30 **** - # along with QWeeChat. If not, see . - # - - """Connection window.""" - -! from PySide6 import QtGui, QtWidgets - - - class ConnectionDialog(QtWidgets.QDialog): - """Connection window.""" - ---- 20,30 ---- - # along with QWeeChat. If not, see . - # - - """Connection window.""" - -! from PyQt5 import QtGui, QtWidgets - - - class ConnectionDialog(QtWidgets.QDialog): - """Connection window.""" - diff --git a/toxygen/third_party/qweechat/connection.py.dst b/toxygen/third_party/qweechat/connection.py.dst deleted file mode 100644 index c9631ff..0000000 --- a/toxygen/third_party/qweechat/connection.py.dst +++ /dev/null @@ -1,122 +0,0 @@ -# -*- coding: utf-8 -*- -# -# connection.py - connection window -# -# Copyright (C) 2011-2022 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 . -# - -"""Connection window.""" - -from PySide6 import QtGui, QtWidgets - - -class ConnectionDialog(QtWidgets.QDialog): - """Connection window.""" - - def __init__(self, values, *args): - super().__init__(*args) - self.values = values - self.setModal(True) - self.setWindowTitle('Connect to WeeChat') - - grid = QtWidgets.QGridLayout() - grid.setSpacing(10) - - self.fields = {} - focus = None - - # hostname - grid.addWidget(QtWidgets.QLabel('Hostname'), 0, 0) - line_edit = QtWidgets.QLineEdit() - line_edit.setFixedWidth(200) - value = self.values.get('hostname', '') - line_edit.insert(value) - grid.addWidget(line_edit, 0, 1) - self.fields['hostname'] = line_edit - if not focus and not value: - focus = 'hostname' - - # port / SSL - grid.addWidget(QtWidgets.QLabel('Port'), 1, 0) - line_edit = QtWidgets.QLineEdit() - line_edit.setFixedWidth(200) - value = self.values.get('port', '') - line_edit.insert(value) - grid.addWidget(line_edit, 1, 1) - self.fields['port'] = line_edit - if not focus and not value: - focus = 'port' - - ssl = QtWidgets.QCheckBox('SSL') - ssl.setChecked(self.values['ssl'] == 'on') - grid.addWidget(ssl, 1, 2) - self.fields['ssl'] = ssl - - # password - grid.addWidget(QtWidgets.QLabel('Password'), 2, 0) - line_edit = QtWidgets.QLineEdit() - line_edit.setFixedWidth(200) - line_edit.setEchoMode(QtWidgets.QLineEdit.Password) - value = self.values.get('password', '') - line_edit.insert(value) - grid.addWidget(line_edit, 2, 1) - self.fields['password'] = line_edit - if not focus and not value: - focus = 'password' - - # TOTP (Time-Based One-Time Password) - label = QtWidgets.QLabel('TOTP') - label.setToolTip('Time-Based One-Time Password (6 digits)') - grid.addWidget(label, 3, 0) - line_edit = QtWidgets.QLineEdit() - line_edit.setPlaceholderText('6 digits') - validator = QtGui.QIntValidator(0, 999999, self) - line_edit.setValidator(validator) - line_edit.setFixedWidth(80) - value = self.values.get('totp', '') - line_edit.insert(value) - grid.addWidget(line_edit, 3, 1) - self.fields['totp'] = line_edit - if not focus and not value: - focus = 'totp' - - # lines - grid.addWidget(QtWidgets.QLabel('Lines'), 4, 0) - line_edit = QtWidgets.QLineEdit() - line_edit.setFixedWidth(200) - validator = QtGui.QIntValidator(0, 2147483647, self) - line_edit.setValidator(validator) - line_edit.setFixedWidth(80) - value = self.values.get('lines', '') - line_edit.insert(value) - grid.addWidget(line_edit, 4, 1) - self.fields['lines'] = line_edit - if not focus and not value: - focus = 'lines' - - self.dialog_buttons = QtWidgets.QDialogButtonBox() - self.dialog_buttons.setStandardButtons( - QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) - self.dialog_buttons.rejected.connect(self.close) - - grid.addWidget(self.dialog_buttons, 5, 0, 1, 2) - self.setLayout(grid) - self.show() - - if focus: - self.fields[focus].setFocus() diff --git a/toxygen/third_party/qweechat/debug.py.diff b/toxygen/third_party/qweechat/debug.py.diff deleted file mode 100644 index 7201803..0000000 --- a/toxygen/third_party/qweechat/debug.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** debug.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- debug.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 20,30 **** - # along with QWeeChat. If not, see . - # - - """Debug window.""" - -! from PySide6 import QtWidgets - - from qweechat.chat import ChatTextEdit - from qweechat.input import InputLineEdit - - ---- 20,30 ---- - # along with QWeeChat. If not, see . - # - - """Debug window.""" - -! from PyQt5 import QtWidgets - - from qweechat.chat import ChatTextEdit - from qweechat.input import InputLineEdit - - diff --git a/toxygen/third_party/qweechat/debug.py.dst b/toxygen/third_party/qweechat/debug.py.dst deleted file mode 100644 index 3267adc..0000000 --- a/toxygen/third_party/qweechat/debug.py.dst +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# -# debug.py - debug window -# -# Copyright (C) 2011-2022 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 . -# - -"""Debug window.""" - -from PySide6 import QtWidgets - -from qweechat.chat import ChatTextEdit -from qweechat.input import InputLineEdit - - -class DebugDialog(QtWidgets.QDialog): - """Debug dialog.""" - - def __init__(self, *args): - QtWidgets.QDialog.__init__(*(self,) + args) - self.resize(1024, 768) - self.setWindowTitle('Debug console') - - self.chat = ChatTextEdit(debug=True) - self.input = InputLineEdit(self.chat) - - vbox = QtWidgets.QVBoxLayout() - vbox.addWidget(self.chat) - vbox.addWidget(self.input) - - self.setLayout(vbox) - self.show() - - def display_lines(self, lines): - for line in lines: - self.chat.display(*line[0], **line[1]) diff --git a/toxygen/third_party/qweechat/input.py.diff b/toxygen/third_party/qweechat/input.py.diff deleted file mode 100644 index 1b4c420..0000000 --- a/toxygen/third_party/qweechat/input.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** input.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- input.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 20,30 **** - # along with QWeeChat. If not, see . - # - - """Input line for chat and debug window.""" - -! from PySide6 import QtCore, QtWidgets - - - class InputLineEdit(QtWidgets.QLineEdit): - """Input line.""" - ---- 20,30 ---- - # along with QWeeChat. If not, see . - # - - """Input line for chat and debug window.""" - -! from PyQt5 import QtCore, QtWidgets - - - class InputLineEdit(QtWidgets.QLineEdit): - """Input line.""" - diff --git a/toxygen/third_party/qweechat/input.py.dst b/toxygen/third_party/qweechat/input.py.dst deleted file mode 100644 index 1ec3d3d..0000000 --- a/toxygen/third_party/qweechat/input.py.dst +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -# -# input.py - input line for chat and debug window -# -# Copyright (C) 2011-2022 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 . -# - -"""Input line for chat and debug window.""" - -from PySide6 import QtCore, QtWidgets - - -class InputLineEdit(QtWidgets.QLineEdit): - """Input line.""" - - bufferSwitchPrev = QtCore.Signal() - bufferSwitchNext = QtCore.Signal() - textSent = QtCore.Signal(str) - - def __init__(self, scroll_widget): - super().__init__() - self.scroll_widget = scroll_widget - self._history = [] - self._history_index = -1 - self.returnPressed.connect(self._input_return_pressed) - - def keyPressEvent(self, event): - key = event.key() - modifiers = event.modifiers() - scroll = self.scroll_widget.verticalScrollBar() - if modifiers == QtCore.Qt.ControlModifier: - if key == QtCore.Qt.Key_PageUp: - self.bufferSwitchPrev.emit() - elif key == QtCore.Qt.Key_PageDown: - self.bufferSwitchNext.emit() - else: - QtWidgets.QLineEdit.keyPressEvent(self, event) - elif modifiers == QtCore.Qt.AltModifier: - if key in (QtCore.Qt.Key_Left, QtCore.Qt.Key_Up): - self.bufferSwitchPrev.emit() - elif key in (QtCore.Qt.Key_Right, QtCore.Qt.Key_Down): - self.bufferSwitchNext.emit() - elif key == QtCore.Qt.Key_PageUp: - scroll.setValue(scroll.value() - (scroll.pageStep() / 10)) - elif key == QtCore.Qt.Key_PageDown: - scroll.setValue(scroll.value() + (scroll.pageStep() / 10)) - elif key == QtCore.Qt.Key_Home: - scroll.setValue(scroll.minimum()) - elif key == QtCore.Qt.Key_End: - scroll.setValue(scroll.maximum()) - else: - QtWidgets.QLineEdit.keyPressEvent(self, event) - elif key == QtCore.Qt.Key_PageUp: - scroll.setValue(scroll.value() - scroll.pageStep()) - elif key == QtCore.Qt.Key_PageDown: - scroll.setValue(scroll.value() + scroll.pageStep()) - elif key == QtCore.Qt.Key_Up: - self._history_navigate(-1) - elif key == QtCore.Qt.Key_Down: - self._history_navigate(1) - else: - QtWidgets.QLineEdit.keyPressEvent(self, event) - - def _input_return_pressed(self): - self._history.append(self.text()) - self._history_index = len(self._history) - self.textSent.emit(self.text()) - self.clear() - - def _history_navigate(self, direction): - if self._history: - self._history_index += direction - if self._history_index < 0: - self._history_index = 0 - return - if self._history_index > len(self._history) - 1: - self._history_index = len(self._history) - self.clear() - return - self.setText(self._history[self._history_index]) diff --git a/toxygen/third_party/qweechat/network.py.diff b/toxygen/third_party/qweechat/network.py.diff deleted file mode 100644 index 026d69c..0000000 --- a/toxygen/third_party/qweechat/network.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** network.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- network.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 24,34 **** - - import hashlib - import secrets - import struct - -! from PySide6 import QtCore, QtNetwork - - from qweechat import config - from qweechat.debug import DebugDialog - - ---- 24,34 ---- - - import hashlib - import secrets - import struct - -! from PyQt5 import QtCore, QtNetwork - - from qweechat import config - from qweechat.debug import DebugDialog - - diff --git a/toxygen/third_party/qweechat/network.py.dst b/toxygen/third_party/qweechat/network.py.dst deleted file mode 100644 index b7d802c..0000000 --- a/toxygen/third_party/qweechat/network.py.dst +++ /dev/null @@ -1,356 +0,0 @@ -# -*- coding: utf-8 -*- -# -# network.py - I/O with WeeChat/relay -# -# Copyright (C) 2011-2022 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 . -# - -"""I/O with WeeChat/relay.""" - -import hashlib -import secrets -import struct - -from PySide6 import QtCore, QtNetwork - -from qweechat import config -from qweechat.debug import DebugDialog - - -# list of supported hash algorithms on our side -# (the hash algorithm will be negotiated with the remote WeeChat) -_HASH_ALGOS_LIST = [ - 'plain', - 'sha256', - 'sha512', - 'pbkdf2+sha256', - 'pbkdf2+sha512', -] -_HASH_ALGOS = ':'.join(_HASH_ALGOS_LIST) - -# handshake with remote WeeChat (before init) -_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' # 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_CMDS = [ - # get buffers - '(listbuffers) hdata buffer:gui_buffers(*) number,full_name,short_name,' - 'type,nicklist,title,local_variables', - # get lines - '(listlines) hdata buffer:gui_buffers(*)/own_lines/last_line(-%(lines)d)/' - 'data date,displayed,prefix,message', - # get nicklist for all buffers - '(nicklist) nicklist', - # enable synchronization - 'sync', -] - -STATUS_DISCONNECTED = 'disconnected' -STATUS_CONNECTING = 'connecting' -STATUS_AUTHENTICATING = 'authenticating' -STATUS_CONNECTED = 'connected' - -NETWORK_STATUS = { - STATUS_DISCONNECTED: { - 'label': 'Disconnected', - 'color': '#aa0000', - 'icon': 'dialog-close.png', - }, - STATUS_CONNECTING: { - 'label': 'Connecting…', - 'color': '#dd5f00', - 'icon': 'dialog-warning.png', - }, - STATUS_AUTHENTICATING: { - 'label': 'Authenticating…', - 'color': '#007fff', - 'icon': 'dialog-password.png', - }, - STATUS_CONNECTED: { - 'label': 'Connected', - 'color': 'green', - 'icon': 'dialog-ok-apply.png', - }, -} - - -class Network(QtCore.QObject): - """I/O with WeeChat/relay.""" - - statusChanged = QtCore.Signal(str, str) - messageFromWeechat = QtCore.Signal(QtCore.QByteArray) - - def __init__(self, *args): - super().__init__(*args) - self._init_connection() - self.debug_lines = [] - self.debug_dialog = None - self._lines = config.CONFIG_DEFAULT_RELAY_LINES - self._buffer = QtCore.QByteArray() - self._socket = QtNetwork.QSslSocket() - self._socket.connected.connect(self._socket_connected) - self._socket.readyRead.connect(self._socket_read) - self._socket.disconnected.connect(self._socket_disconnected) - - def _init_connection(self): - self.status = STATUS_DISCONNECTED - self._hostname = None - self._port = None - self._ssl = None - self._password = None - self._totp = None - self._handshake_received = False - self._handshake_timer = None - self._handshake_timer = False - self._pwd_hash_algo = None - self._pwd_hash_iter = 0 - self._server_nonce = None - - def set_status(self, status): - """Set current status.""" - self.status = status - self.statusChanged.emit(status, None) - - def pbkdf2(self, hash_name, salt): - """Return hashed password with PBKDF2-HMAC.""" - return hashlib.pbkdf2_hmac( - hash_name, - password=self._password.encode('utf-8'), - salt=salt, - iterations=self._pwd_hash_iter, - ).hex() - - def _build_init_command(self): - """Build the init command to send to WeeChat.""" - totp = f',totp={self._totp}' if self._totp else '' - if self._pwd_hash_algo == 'plain': - cmd = _PROTO_INIT_PWD % { - 'password': self._password, - 'totp': totp, - } - else: - client_nonce = secrets.token_bytes(16) - salt = self._server_nonce + client_nonce - pwd_hash = None - iterations = '' - if self._pwd_hash_algo == 'pbkdf2+sha512': - pwd_hash = self.pbkdf2('sha512', salt) - iterations = f':{self._pwd_hash_iter}' - elif self._pwd_hash_algo == 'pbkdf2+sha256': - pwd_hash = self.pbkdf2('sha256', salt) - iterations = f':{self._pwd_hash_iter}' - elif self._pwd_hash_algo == 'sha512': - pwd = salt + self._password.encode('utf-8') - pwd_hash = hashlib.sha512(pwd).hexdigest() - elif self._pwd_hash_algo == 'sha256': - pwd = salt + self._password.encode('utf-8') - pwd_hash = hashlib.sha256(pwd).hexdigest() - if not pwd_hash: - return None - cmd = _PROTO_INIT_HASH % { - 'algo': self._pwd_hash_algo, - 'salt': bytearray(salt).hex(), - 'iter': iterations, - 'hash': pwd_hash, - 'totp': totp, - } - return cmd - - def _build_sync_command(self): - """Build the sync commands to send to WeeChat.""" - cmd = '\n'.join(_PROTO_SYNC_CMDS) + '\n' - return cmd % {'lines': self._lines} - - def handshake_timer_expired(self): - if self.status == STATUS_AUTHENTICATING: - self._pwd_hash_algo = 'plain' - self.send_to_weechat(self._build_init_command()) - self.sync_weechat() - self.set_status(STATUS_CONNECTED) - - def _socket_connected(self): - """Slot: socket connected.""" - self.set_status(STATUS_AUTHENTICATING) - self.send_to_weechat(_PROTO_HANDSHAKE) - self._handshake_timer = QtCore.QTimer() - self._handshake_timer.setSingleShot(True) - self._handshake_timer.setInterval(2000) - self._handshake_timer.timeout.connect(self.handshake_timer_expired) - self._handshake_timer.start() - - def _socket_read(self): - """Slot: data available on socket.""" - data = self._socket.readAll() - self._buffer.append(data) - while len(self._buffer) >= 4: - remainder = None - length = struct.unpack('>i', self._buffer[0:4].data())[0] - if len(self._buffer) < length: - # partial message, just wait for end of message - break - # more than one message? - if length < len(self._buffer): - # save beginning of another message - remainder = self._buffer[length:] - self._buffer = self._buffer[0:length] - self.messageFromWeechat.emit(self._buffer) - if not self.is_connected(): - return - self._buffer.clear() - if remainder: - self._buffer.append(remainder) - - def _socket_disconnected(self): - """Slot: socket disconnected.""" - if self._handshake_timer: - self._handshake_timer.stop() - self._init_connection() - self.set_status(STATUS_DISCONNECTED) - - def is_connected(self): - """Return True if the socket is connected, False otherwise.""" - return self._socket.state() == QtNetwork.QAbstractSocket.ConnectedState - - def is_ssl(self): - """Return True if SSL is used, False otherwise.""" - return self._ssl - - def connect_weechat(self, hostname, port, ssl, password, totp, lines): - """Connect to WeeChat.""" - self._hostname = hostname - try: - self._port = int(port) - except ValueError: - self._port = 0 - self._ssl = ssl - self._password = password - self._totp = totp - try: - self._lines = int(lines) - except ValueError: - self._lines = config.CONFIG_DEFAULT_RELAY_LINES - if self._socket.state() == QtNetwork.QAbstractSocket.ConnectedState: - return - if self._socket.state() != QtNetwork.QAbstractSocket.UnconnectedState: - self._socket.abort() - if self._ssl: - self._socket.ignoreSslErrors() - self._socket.connectToHostEncrypted(self._hostname, self._port) - else: - self._socket.connectToHost(self._hostname, self._port) - self.set_status(STATUS_CONNECTING) - - def disconnect_weechat(self): - """Disconnect from WeeChat.""" - if self._socket.state() == QtNetwork.QAbstractSocket.UnconnectedState: - self.set_status(STATUS_DISCONNECTED) - return - if self._socket.state() == QtNetwork.QAbstractSocket.ConnectedState: - self.send_to_weechat('quit\n') - self._socket.waitForBytesWritten(1000) - else: - self.set_status(STATUS_DISCONNECTED) - self._socket.abort() - - def send_to_weechat(self, message): - """Send a message to WeeChat.""" - self.debug_print(0, '<==', message, forcecolor='#AA0000') - self._socket.write(message.encode('utf-8')) - - def init_with_handshake(self, response): - """Initialize with WeeChat using the handshake response.""" - self._pwd_hash_algo = response['password_hash_algo'] - self._pwd_hash_iter = int(response['password_hash_iterations']) - self._server_nonce = bytearray.fromhex(response['nonce']) - if self._pwd_hash_algo: - cmd = self._build_init_command() - if cmd: - self.send_to_weechat(cmd) - self.sync_weechat() - self.set_status(STATUS_CONNECTED) - return - # failed to initialize: disconnect - self.disconnect_weechat() - - def desync_weechat(self): - """Desynchronize from WeeChat.""" - self.send_to_weechat('desync\n') - - def sync_weechat(self): - """Synchronize with WeeChat.""" - self.send_to_weechat(self._build_sync_command()) - - def status_label(self, status): - """Return the label for a given status.""" - return NETWORK_STATUS.get(status, {}).get('label', '') - - def status_color(self, status): - """Return the color for a given status.""" - return NETWORK_STATUS.get(status, {}).get('color', 'black') - - def status_icon(self, status): - """Return the name of icon for a given status.""" - return NETWORK_STATUS.get(status, {}).get('icon', '') - - def get_options(self): - """Get connection options.""" - return { - 'hostname': self._hostname, - 'port': self._port, - 'ssl': 'on' if self._ssl else 'off', - 'password': self._password, - 'lines': str(self._lines), - } - - def debug_print(self, *args, **kwargs): - """Display a debug message.""" - self.debug_lines.append((args, kwargs)) - if self.debug_dialog: - self.debug_dialog.chat.display(*args, **kwargs) - - def _debug_dialog_closed(self, result): - """Called when debug dialog is closed.""" - self.debug_dialog = None - - def debug_input_text_sent(self, text): - """Send debug buffer input to WeeChat.""" - if self.network.is_connected(): - text = str(text) - pos = text.find(')') - if text.startswith('(') and pos >= 0: - text = '(debug_%s)%s' % (text[1:pos], text[pos+1:]) - else: - text = '(debug) %s' % text - self.network.debug_print(0, '<==', text, forcecolor='#AA0000') - self.network.send_to_weechat(text + '\n') - - def open_debug_dialog(self): - """Open a dialog with debug messages.""" - if not self.debug_dialog: - self.debug_dialog = DebugDialog() - self.debug_dialog.input.textSent.connect( - self.debug_input_text_sent) - self.debug_dialog.finished.connect(self._debug_dialog_closed) - self.debug_dialog.display_lines(self.debug_lines) - self.debug_dialog.chat.scroll_bottom() diff --git a/toxygen/third_party/qweechat/preferences.py.diff b/toxygen/third_party/qweechat/preferences.py.diff deleted file mode 100644 index 17a298b..0000000 --- a/toxygen/third_party/qweechat/preferences.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** preferences.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- preferences.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 20,30 **** - # along with QWeeChat. If not, see . - # - - """Preferences dialog box.""" - -! from PySide6 import QtCore, QtWidgets as QtGui - - - class PreferencesDialog(QtGui.QDialog): - """Preferences dialog.""" - ---- 20,30 ---- - # along with QWeeChat. If not, see . - # - - """Preferences dialog box.""" - -! from PyQt5 import QtCore, QtWidgets as QtGui - - - class PreferencesDialog(QtGui.QDialog): - """Preferences dialog.""" - diff --git a/toxygen/third_party/qweechat/preferences.py.dst b/toxygen/third_party/qweechat/preferences.py.dst deleted file mode 100644 index f760bbc..0000000 --- a/toxygen/third_party/qweechat/preferences.py.dst +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -# -# preferences.py - preferences dialog box -# -# Copyright (C) 2011-2022 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 . -# - -"""Preferences dialog box.""" - -from PySide6 import QtCore, QtWidgets as QtGui - - -class PreferencesDialog(QtGui.QDialog): - """Preferences dialog.""" - - def __init__(self, *args): - QtGui.QDialog.__init__(*(self,) + args) - self.setModal(True) - self.setWindowTitle('Preferences') - - close_button = QtGui.QPushButton('Close') - close_button.pressed.connect(self.close) - - hbox = QtGui.QHBoxLayout() - hbox.addStretch(1) - hbox.addWidget(close_button) - hbox.addStretch(1) - - vbox = QtGui.QVBoxLayout() - - label = QtGui.QLabel('Not yet implemented!') - label.setAlignment(QtCore.Qt.AlignHCenter) - vbox.addWidget(label) - - label = QtGui.QLabel('') - label.setAlignment(QtCore.Qt.AlignHCenter) - vbox.addWidget(label) - - vbox.addLayout(hbox) - - self.setLayout(vbox) - self.show() diff --git a/toxygen/third_party/qweechat/qweechat.py.diff b/toxygen/third_party/qweechat/qweechat.py.diff deleted file mode 100644 index 76db51a..0000000 --- a/toxygen/third_party/qweechat/qweechat.py.diff +++ /dev/null @@ -1,27 +0,0 @@ -*** qweechat.py.dst 2022-11-19 18:31:51.000000000 +0000 ---- qweechat.py 2022-11-19 18:32:41.000000000 +0000 -*************** -*** 35,45 **** - - import sys - import traceback - from pkg_resources import resource_filename - -! from PySide6 import QtCore, QtGui, QtWidgets - - from qweechat import config - from qweechat.about import AboutDialog - from qweechat.buffer import BufferListWidget, Buffer - from qweechat.connection import ConnectionDialog ---- 35,45 ---- - - import sys - import traceback - from pkg_resources import resource_filename - -! 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 diff --git a/toxygen/third_party/qweechat/qweechat.py.dst b/toxygen/third_party/qweechat/qweechat.py.dst deleted file mode 100644 index f58d920..0000000 --- a/toxygen/third_party/qweechat/qweechat.py.dst +++ /dev/null @@ -1,542 +0,0 @@ -# -*- coding: utf-8 -*- -# -# qweechat.py - WeeChat remote GUI using Qt toolkit -# -# Copyright (C) 2011-2022 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 . -# - -""" -QWeeChat is a WeeChat remote GUI using Qt toolkit. - -It requires requires WeeChat 0.3.7 or newer, running on local or remote host. -""" - -# -# History: -# -# 2011-05-27, Sébastien Helleu : -# start dev -# - -import sys -import traceback -from pkg_resources import resource_filename - -from PySide6 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 -from qweechat.preferences import PreferencesDialog -from qweechat.weechat import protocol - - -APP_NAME = 'QWeeChat' -AUTHOR = 'Sébastien Helleu' -WEECHAT_SITE = 'https://weechat.org/' - - -class MainWindow(QtWidgets.QMainWindow): - """Main window.""" - - def __init__(self, *args): - super().__init__(*args) - - self.config = config.read() - - self.resize(1000, 600) - self.setWindowTitle(APP_NAME) - - self.about_dialog = None - self.connection_dialog = None - self.preferences_dialog = None - - # network - self.network = Network() - self.network.statusChanged.connect(self._network_status_changed) - self.network.messageFromWeechat.connect(self._network_weechat_msg) - - # list of buffers - self.list_buffers = BufferListWidget() - self.list_buffers.currentRowChanged.connect(self._buffer_switch) - - # default buffer - self.buffers = [Buffer()] - self.stacked_buffers = QtWidgets.QStackedWidget() - self.stacked_buffers.addWidget(self.buffers[0].widget) - - # splitter with buffers + chat/input - splitter = QtWidgets.QSplitter() - splitter.addWidget(self.list_buffers) - splitter.addWidget(self.stacked_buffers) - - self.setCentralWidget(splitter) - - if self.config.getboolean('look', 'statusbar'): - self.statusBar().visible = True - - # actions for menu and toolbar - actions_def = { - 'connect': [ - 'network-connect.png', - 'Connect to WeeChat', - 'Ctrl+O', - self.open_connection_dialog, - ], - 'disconnect': [ - 'network-disconnect.png', - 'Disconnect from WeeChat', - 'Ctrl+D', - self.network.disconnect_weechat, - ], - 'debug': [ - 'edit-find.png', - 'Open debug console window', - 'Ctrl+B', - self.network.open_debug_dialog, - ], - 'preferences': [ - 'preferences-other.png', - 'Change preferences', - 'Ctrl+P', - self.open_preferences_dialog, - ], - 'about': [ - 'help-about.png', - 'About QWeeChat', - 'Ctrl+H', - self.open_about_dialog, - ], - 'save connection': [ - 'document-save.png', - 'Save connection configuration', - 'Ctrl+S', - self.save_connection, - ], - 'quit': [ - 'application-exit.png', - 'Quit application', - 'Ctrl+Q', - self.close, - ], - } - self.actions = {} - for name, action in list(actions_def.items()): - self.actions[name] = QtGui.QAction( - QtGui.QIcon( - resource_filename(__name__, 'data/icons/%s' % action[0])), - name.capitalize(), self) - self.actions[name].setToolTip(f'{action[1]} ({action[2]})') - self.actions[name].setShortcut(action[2]) - self.actions[name].triggered.connect(action[3]) - - # menu - self.menu = self.menuBar() - menu_file = self.menu.addMenu('&File') - menu_file.addActions([self.actions['connect'], - self.actions['disconnect'], - self.actions['preferences'], - self.actions['save connection'], - self.actions['quit']]) - menu_window = self.menu.addMenu('&Window') - menu_window.addAction(self.actions['debug']) - menu_help = self.menu.addMenu('&Help') - menu_help.addAction(self.actions['about']) - self.network_status = QtWidgets.QLabel() - self.network_status.setFixedHeight(20) - 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) - 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']]) - - self.buffers[0].widget.input.setFocus() - - # open debug dialog - if self.config.getboolean('look', 'debug'): - self.network.open_debug_dialog() - - # auto-connect to relay - if self.config.getboolean('relay', 'autoconnect'): - self.network.connect_weechat( - 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', fallback=''), - ) - - self.show() - - def _buffer_switch(self, index): - """Switch to a buffer.""" - if index >= 0: - self.stacked_buffers.setCurrentIndex(index) - self.stacked_buffers.widget(index).input.setFocus() - - def buffer_input(self, full_name, text): - """Send buffer input to WeeChat.""" - if self.network.is_connected(): - message = 'input %s %s\n' % (full_name, text) - self.network.send_to_weechat(message) - self.network.debug_print(0, '<==', message, forcecolor='#AA0000') - - def open_preferences_dialog(self): - """Open a dialog with preferences.""" - # TODO: implement the preferences dialog box - self.preferences_dialog = PreferencesDialog(self) - - def save_connection(self): - """Save connection configuration.""" - if self.network: - options = self.network.get_options() - for option in options: - self.config.set('relay', option, options[option]) - - def open_about_dialog(self): - """Open a dialog with info about QWeeChat.""" - self.about_dialog = AboutDialog(APP_NAME, AUTHOR, WEECHAT_SITE, self) - - def open_connection_dialog(self): - """Open a dialog with connection settings.""" - values = {} - 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) - - def connect_weechat(self): - """Connect to WeeChat.""" - self.network.connect_weechat( - 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(), - totp=self.connection_dialog.fields['totp'].text(), - lines=int(self.connection_dialog.fields['lines'].text()), - ) - self.connection_dialog.close() - - def _network_status_changed(self, status, extra): - """Called when the network status has changed.""" - if self.config.getboolean('look', 'statusbar'): - self.statusBar().showMessage(status) - self.network.debug_print(0, '', status, forcecolor='#0000AA') - self.network_status_set(status) - - def network_status_set(self, status): - """Set the network status.""" - pal = self.network_status.palette() - pal.setColor(self.network_status.foregroundRole(), - self.network.status_color(status)) - ssl = ' (SSL)' if status != STATUS_DISCONNECTED \ - and self.network.is_ssl() else '' - self.network_status.setPalette(pal) - icon = self.network.status_icon(status) - if icon: - self.network_status.setText( - ' %s' % - (resource_filename(__name__, 'data/icons/%s' % icon), - self.network.status_label(status) + ssl)) - else: - self.network_status.setText(status.capitalize()) - if status == STATUS_DISCONNECTED: - self.actions['connect'].setEnabled(True) - self.actions['disconnect'].setEnabled(False) - else: - self.actions['connect'].setEnabled(False) - self.actions['disconnect'].setEnabled(True) - - def _network_weechat_msg(self, message): - """Called when a message is received from WeeChat.""" - self.network.debug_print( - 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()) - if message.uncompressed: - self.network.debug_print( - 0, '==>', - 'message uncompressed (%d bytes):\n%s' - % (message.size_uncompressed, - protocol.hex_and_ascii(message.uncompressed, 20)), - forcecolor='#008800') - self.network.debug_print(0, '', 'Message: %s' % message) - self.parse_message(message) - except Exception: # noqa: E722 - print('Error while decoding message from WeeChat:\n%s' - % traceback.format_exc()) - self.network.disconnect_weechat() - - def _parse_handshake(self, message): - """Parse a WeeChat message with handshake response.""" - for obj in message.objects: - if obj.objtype != 'htb': - continue - self.network.init_with_handshake(obj.value) - break - - def _parse_listbuffers(self, message): - """Parse a WeeChat message with list of buffers.""" - for obj in message.objects: - if obj.objtype != 'hda' or obj.value['path'][-1] != 'buffer': - continue - self.list_buffers.clear() - while self.stacked_buffers.count() > 0: - buf = self.stacked_buffers.widget(0) - self.stacked_buffers.removeWidget(buf) - self.buffers = [] - for item in obj.value['items']: - buf = self.create_buffer(item) - self.insert_buffer(len(self.buffers), buf) - self.list_buffers.setCurrentRow(0) - self.buffers[0].widget.input.setFocus() - - def _parse_line(self, message): - """Parse a WeeChat message with a buffer line.""" - for obj in message.objects: - lines = [] - if obj.objtype != 'hda' or obj.value['path'][-1] != 'line_data': - continue - for item in obj.value['items']: - if message.msgid == 'listlines': - ptrbuf = item['__path'][0] - else: - ptrbuf = item['buffer'] - index = [i for i, b in enumerate(self.buffers) - if b.pointer() == ptrbuf] - if index: - lines.append( - (index[0], - (item['date'], item['prefix'], - item['message'])) - ) - if message.msgid == 'listlines': - lines.reverse() - for line in lines: - self.buffers[line[0]].widget.chat.display(*line[1]) - - def _parse_nicklist(self, message): - """Parse a WeeChat message with a buffer nicklist.""" - buffer_refresh = {} - for obj in message.objects: - if obj.objtype != 'hda' or \ - obj.value['path'][-1] != 'nicklist_item': - continue - group = '__root' - for item in obj.value['items']: - index = [i for i, b in enumerate(self.buffers) - if b.pointer() == item['__path'][0]] - if index: - if not index[0] in buffer_refresh: - self.buffers[index[0]].nicklist = {} - buffer_refresh[index[0]] = True - if item['group']: - group = item['name'] - self.buffers[index[0]].nicklist_add_item( - group, item['group'], item['prefix'], item['name'], - item['visible']) - for index in buffer_refresh: - self.buffers[index].nicklist_refresh() - - def _parse_nicklist_diff(self, message): - """Parse a WeeChat message with a buffer nicklist diff.""" - buffer_refresh = {} - for obj in message.objects: - if obj.objtype != 'hda' or \ - obj.value['path'][-1] != 'nicklist_item': - continue - group = '__root' - for item in obj.value['items']: - index = [i for i, b in enumerate(self.buffers) - if b.pointer() == item['__path'][0]] - if not index: - continue - buffer_refresh[index[0]] = True - if item['_diff'] == ord('^'): - group = item['name'] - elif item['_diff'] == ord('+'): - self.buffers[index[0]].nicklist_add_item( - group, item['group'], item['prefix'], item['name'], - item['visible']) - elif item['_diff'] == ord('-'): - self.buffers[index[0]].nicklist_remove_item( - group, item['group'], item['name']) - elif item['_diff'] == ord('*'): - self.buffers[index[0]].nicklist_update_item( - group, item['group'], item['prefix'], item['name'], - item['visible']) - for index in buffer_refresh: - self.buffers[index].nicklist_refresh() - - def _parse_buffer_opened(self, message): - """Parse a WeeChat message with a new buffer (opened).""" - for obj in message.objects: - if obj.objtype != 'hda' or obj.value['path'][-1] != 'buffer': - continue - for item in obj.value['items']: - buf = self.create_buffer(item) - index = self.find_buffer_index_for_insert(item['next_buffer']) - self.insert_buffer(index, buf) - - def _parse_buffer(self, message): - """Parse a WeeChat message with a buffer event - (anything except a new buffer). - """ - for obj in message.objects: - if obj.objtype != 'hda' or obj.value['path'][-1] != 'buffer': - continue - for item in obj.value['items']: - index = [i for i, b in enumerate(self.buffers) - if b.pointer() == item['__path'][0]] - if not index: - continue - index = index[0] - if message.msgid == '_buffer_type_changed': - self.buffers[index].data['type'] = item['type'] - elif message.msgid in ('_buffer_moved', '_buffer_merged', - '_buffer_unmerged'): - buf = self.buffers[index] - buf.data['number'] = item['number'] - self.remove_buffer(index) - index2 = self.find_buffer_index_for_insert( - item['next_buffer']) - self.insert_buffer(index2, buf) - elif message.msgid == '_buffer_renamed': - self.buffers[index].data['full_name'] = item['full_name'] - self.buffers[index].data['short_name'] = item['short_name'] - elif message.msgid == '_buffer_title_changed': - self.buffers[index].data['title'] = item['title'] - self.buffers[index].update_title() - elif message.msgid == '_buffer_cleared': - self.buffers[index].widget.chat.clear() - elif message.msgid.startswith('_buffer_localvar_'): - self.buffers[index].data['local_variables'] = \ - item['local_variables'] - self.buffers[index].update_prompt() - elif message.msgid == '_buffer_closing': - self.remove_buffer(index) - - def parse_message(self, message): - """Parse a WeeChat message.""" - if message.msgid.startswith('debug'): - self.network.debug_print(0, '', '(debug message, ignored)') - elif message.msgid == 'handshake': - self._parse_handshake(message) - elif message.msgid == 'listbuffers': - self._parse_listbuffers(message) - elif message.msgid in ('listlines', '_buffer_line_added'): - self._parse_line(message) - elif message.msgid in ('_nicklist', 'nicklist'): - self._parse_nicklist(message) - elif message.msgid == '_nicklist_diff': - self._parse_nicklist_diff(message) - elif message.msgid == '_buffer_opened': - self._parse_buffer_opened(message) - elif message.msgid.startswith('_buffer_'): - self._parse_buffer(message) - elif message.msgid == '_upgrade': - 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.""" - buf = Buffer(item) - buf.bufferInput.connect(self.buffer_input) - buf.widget.input.bufferSwitchPrev.connect( - self.list_buffers.switch_prev_buffer) - buf.widget.input.bufferSwitchNext.connect( - self.list_buffers.switch_next_buffer) - return buf - - def insert_buffer(self, index, buf): - """Insert a buffer in list.""" - self.buffers.insert(index, buf) - self.list_buffers.insertItem(index, '%s' - % (buf.data['local_variables']['name'])) - self.stacked_buffers.insertWidget(index, buf.widget) - - def remove_buffer(self, index): - """Remove a buffer.""" - if self.list_buffers.currentRow == index and index > 0: - self.list_buffers.setCurrentRow(index - 1) - self.list_buffers.takeItem(index) - self.stacked_buffers.removeWidget(self.stacked_buffers.widget(index)) - self.buffers.pop(index) - - def find_buffer_index_for_insert(self, next_buffer): - """Find position to insert a buffer in list.""" - index = -1 - if next_buffer == '0x0': - index = len(self.buffers) - else: - index = [i for i, b in enumerate(self.buffers) - if b.pointer() == next_buffer] - if index: - index = index[0] - if index < 0: - print('Warning: unable to find position for buffer, using end of ' - 'list by default') - index = len(self.buffers) - return index - - def closeEvent(self, event): - """Called when QWeeChat window is closed.""" - self.network.disconnect_weechat() - if self.network.debug_dialog: - self.network.debug_dialog.close() - config.write(self.config) - QtWidgets.QMainWindow.closeEvent(self, event) - - -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_win = MainWindow() - main_win.show() - sys.exit(app.exec_()) - - -if __name__ == '__main__': - main()