[triggers] Type annotations, linting

This commit is contained in:
wurstsalat
2022-11-29 19:36:05 +01:00
parent 220e670211
commit 067c233b4b
4 changed files with 193 additions and 86 deletions

View File

@@ -1 +1 @@
from .triggers import Triggers from .triggers import Triggers # type: ignore

View File

@@ -14,6 +14,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>. # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import Any
from typing import TYPE_CHECKING
from pathlib import Path from pathlib import Path
from gi.repository import Gtk from gi.repository import Gtk
@@ -26,7 +31,10 @@ from gajim.common.helpers import play_sound_file
from gajim.plugins.plugins_i18n import _ from gajim.plugins.plugins_i18n import _
from gajim.plugins.helpers import get_builder from gajim.plugins.helpers import get_builder
EVENTS = { if TYPE_CHECKING:
from ..triggers import Triggers
EVENTS: dict[str, Any] = {
'message_received': [], 'message_received': [],
} }
@@ -39,7 +47,7 @@ RECIPIENT_TYPES = [
class ConfigDialog(Gtk.ApplicationWindow): class ConfigDialog(Gtk.ApplicationWindow):
def __init__(self, plugin, transient): def __init__(self, plugin: Triggers, transient: Gtk.Window) -> None:
Gtk.ApplicationWindow.__init__(self) Gtk.ApplicationWindow.__init__(self)
self.set_application(app.app) self.set_application(app.app)
self.set_show_menubar(False) self.set_show_menubar(False)
@@ -51,41 +59,61 @@ class ConfigDialog(Gtk.ApplicationWindow):
self.set_destroy_with_parent(True) self.set_destroy_with_parent(True)
ui_path = Path(__file__).parent ui_path = Path(__file__).parent
self._ui = get_builder(ui_path.resolve() / 'config.ui') self._ui = get_builder(str(ui_path.resolve() / 'config.ui'))
self._plugin = plugin self._plugin = plugin
self.add(self._ui.box) self.add(self._ui.box)
self.show_all() self.show_all()
self._active_num = '' self._active_num = -1
self._config: dict[int, Any] = {}
self._initialize() self._initialize()
self._ui.connect_signals(self) self._ui.connect_signals(self)
self.connect('destroy', self._on_destroy) self.connect('destroy', self._on_destroy)
def _on_destroy(self, *args): def _on_destroy(self, *args: Any) -> None:
for num in list(self._plugin.config.keys()): for num in list(self._plugin.config.keys()):
del self._plugin.config[num] del self._plugin.config[num]
for num in self._config: for num in self._config:
self._plugin.config[str(num)] = self._config[num] self._plugin.config[str(num)] = self._config[num]
def _initialize(self): def _initialize(self) -> None:
# Fill window # Fill window
for widget in ( widgets = [
'conditions_treeview', 'config_box', 'event_combobox', 'conditions_treeview',
'recipient_type_combobox', 'recipient_list_entry', 'config_box',
'delete_button', 'online_cb', 'away_cb', 'xa_cb', 'dnd_cb', 'event_combobox',
'use_sound_cb', 'disable_sound_cb', 'use_popup_cb', 'recipient_type_combobox',
'disable_popup_cb', 'recipient_list_entry',
'tab_opened_cb', 'not_tab_opened_cb', 'has_focus_cb', 'delete_button',
'not_has_focus_cb', 'filechooser', 'sound_file_box', 'online_cb',
'up_button', 'down_button', 'run_command_cb', 'away_cb',
'command_entry', 'one_shot_cb'): 'xa_cb',
'dnd_cb',
'use_sound_cb',
'disable_sound_cb',
'use_popup_cb',
'disable_popup_cb',
'tab_opened_cb',
'not_tab_opened_cb',
'has_focus_cb',
'not_has_focus_cb',
'filechooser',
'sound_file_box',
'up_button',
'down_button',
'run_command_cb',
'command_entry',
'one_shot_cb'
]
for widget in widgets:
self._ui.__dict__[widget] = self._ui.get_object(widget) self._ui.__dict__[widget] = self._ui.get_object(widget)
self._config = {} self._config = {}
for num in self._plugin.config: for num in self._plugin.config.keys():
self._config[int(num)] = self._plugin.config[num] self._config[int(num)] = self._plugin.config[num]
if not self._ui.conditions_treeview.get_column(0): if not self._ui.conditions_treeview.get_column(0):
@@ -141,7 +169,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.filechooser.add_filter(filter_) self._ui.filechooser.add_filter(filter_)
self._ui.filechooser.set_filter(filter_) self._ui.filechooser.set_filter(filter_)
def _initiate_rule_state(self): def _initiate_rule_state(self) -> None:
""" """
Set values for all widgets Set values for all widgets
""" """
@@ -243,7 +271,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
value = False value = False
self._ui.one_shot_cb.set_active(value) self._ui.one_shot_cb.set_active(value)
def _set_treeview_string(self): def _set_treeview_string(self) -> None:
selection = self._ui.conditions_treeview.get_selection() selection = self._ui.conditions_treeview.get_selection()
(model, iter_) = selection.get_selected() (model, iter_) = selection.get_selected()
if not iter_: if not iter_:
@@ -274,17 +302,22 @@ class ConfigDialog(Gtk.ApplicationWindow):
'recipient': recipient, 'recipient': recipient,
'status': status} 'status': status}
def _on_conditions_treeview_cursor_changed(self, widget): def _on_conditions_treeview_cursor_changed(self,
widget: Gtk.TreeView
) -> None:
(model, iter_) = widget.get_selection().get_selected() (model, iter_) = widget.get_selection().get_selected()
if not iter_: if not iter_:
self._active_num = '' self._active_num = -1
return return
self._active_num = model[iter_][0] self._active_num = model[iter_][0]
if self._active_num == 0: if self._active_num == 0:
self._ui.up_button.set_sensitive(False) self._ui.up_button.set_sensitive(False)
else: else:
self._ui.up_button.set_sensitive(True) self._ui.up_button.set_sensitive(True)
_max = widget.get_model().iter_n_children(None) model = widget.get_model()
assert model is not None
_max = model.iter_n_children(None)
if self._active_num == _max - 1: if self._active_num == _max - 1:
self._ui.down_button.set_sensitive(False) self._ui.down_button.set_sensitive(False)
else: else:
@@ -293,7 +326,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.config_box.set_sensitive(True) self._ui.config_box.set_sensitive(True)
self._ui.delete_button.set_sensitive(True) self._ui.delete_button.set_sensitive(True)
def _on_new_button_clicked(self, _widget): def _on_new_button_clicked(self, _button: Gtk.Button) -> None:
model = self._ui.conditions_treeview.get_model() model = self._ui.conditions_treeview.get_model()
num = self._ui.conditions_treeview.get_model().iter_n_children(None) num = self._ui.conditions_treeview.get_model().iter_n_children(None)
self._config[num] = { self._config[num] = {
@@ -317,7 +350,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._set_treeview_string() self._set_treeview_string()
self._ui.config_box.set_sensitive(True) self._ui.config_box.set_sensitive(True)
def _on_delete_button_clicked(self, widget): def _on_delete_button_clicked(self, button: Gtk.Button) -> None:
selection = self._ui.conditions_treeview.get_selection() selection = self._ui.conditions_treeview.get_selection()
(model, iter_) = selection.get_selected() (model, iter_) = selection.get_selected()
if not iter_: if not iter_:
@@ -332,13 +365,13 @@ class ConfigDialog(Gtk.ApplicationWindow):
iter2 = model.iter_next(iter2) iter2 = model.iter_next(iter2)
model.remove(iter_) model.remove(iter_)
del self._config[num] del self._config[num]
self._active_num = '' self._active_num = -1
widget.set_sensitive(False) button.set_sensitive(False)
self._ui.up_button.set_sensitive(False) self._ui.up_button.set_sensitive(False)
self._ui.down_button.set_sensitive(False) self._ui.down_button.set_sensitive(False)
self._ui.config_box.set_sensitive(False) self._ui.config_box.set_sensitive(False)
def _on_up_button_clicked(self, _widget): def _on_up_button_clicked(self, _button: Gtk.Button) -> None:
selection = self._ui.conditions_treeview.get_selection() selection = self._ui.conditions_treeview.get_selection()
(model, iter_) = selection.get_selected() (model, iter_) = selection.get_selected()
if not iter_: if not iter_:
@@ -355,7 +388,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._on_conditions_treeview_cursor_changed( self._on_conditions_treeview_cursor_changed(
self._ui.conditions_treeview) self._ui.conditions_treeview)
def _on_down_button_clicked(self, _widget): def _on_down_button_clicked(self, _button: Gtk.Button) -> None:
selection = self._ui.conditions_treeview.get_selection() selection = self._ui.conditions_treeview.get_selection()
(model, iter_) = selection.get_selected() (model, iter_) = selection.get_selected()
if not iter_: if not iter_:
@@ -370,10 +403,10 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._on_conditions_treeview_cursor_changed( self._on_conditions_treeview_cursor_changed(
self._ui.conditions_treeview) self._ui.conditions_treeview)
def _on_event_combobox_changed(self, widget): def _on_event_combobox_changed(self, combo: Gtk.ComboBox) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
active = widget.get_active() active = combo.get_active()
if active == -1: if active == -1:
return return
event = list(EVENTS.keys())[active] event = list(EVENTS.keys())[active]
@@ -383,7 +416,10 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.__dict__[widget].set_state(False) self._ui.__dict__[widget].set_state(False)
self._set_treeview_string() self._set_treeview_string()
def _on_recipient_type_combobox_changed(self, widget): def _on_recipient_type_combobox_changed(self,
widget: Gtk.ComboBox
) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
recipient_type = RECIPIENT_TYPES[widget.get_active()] recipient_type = RECIPIENT_TYPES[widget.get_active()]
@@ -394,7 +430,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.recipient_list_entry.set_sensitive(True) self._ui.recipient_list_entry.set_sensitive(True)
self._set_treeview_string() self._set_treeview_string()
def _on_recipient_list_entry_changed(self, widget): def _on_recipient_list_entry_changed(self, widget: Gtk.Entry) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
recipients = widget.get_text() recipients = widget.get_text()
@@ -402,7 +438,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._config[self._active_num]['recipients'] = recipients self._config[self._active_num]['recipients'] = recipients
self._set_treeview_string() self._set_treeview_string()
def _set_status_config(self): def _set_status_config(self) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
status = '' status = ''
@@ -414,7 +450,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._config[self._active_num]['status'] = status self._config[self._active_num]['status'] = status
self._set_treeview_string() self._set_treeview_string()
def _on_status_radiobutton_toggled(self, _widget): def _on_status_radiobutton_toggled(self, _widget: Gtk.RadioButton) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
if self._ui.all_status_rb.get_active(): if self._ui.all_status_rb.get_active():
@@ -432,13 +468,13 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._set_treeview_string() self._set_treeview_string()
def _on_status_cb_toggled(self, _widget): def _on_status_cb_toggled(self, _widget: Gtk.CheckButton) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
self._set_status_config() self._set_status_config()
# tab_opened OR (not xor) not_tab_opened must be active # tab_opened OR (not xor) not_tab_opened must be active
def _on_tab_opened_cb_toggled(self, widget): def _on_tab_opened_cb_toggled(self, widget: Gtk.CheckButton) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
if widget.get_active(): if widget.get_active():
@@ -454,7 +490,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.not_tab_opened_cb.set_active(True) self._ui.not_tab_opened_cb.set_active(True)
self._config[self._active_num]['tab_opened'] = 'no' self._config[self._active_num]['tab_opened'] = 'no'
def _on_not_tab_opened_cb_toggled(self, widget): def _on_not_tab_opened_cb_toggled(self, widget: Gtk.CheckButton) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
if widget.get_active(): if widget.get_active():
@@ -467,7 +503,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._config[self._active_num]['tab_opened'] = 'yes' self._config[self._active_num]['tab_opened'] = 'yes'
# has_focus OR (not xor) not_has_focus must be active # has_focus OR (not xor) not_has_focus must be active
def _on_has_focus_cb_toggled(self, widget): def _on_has_focus_cb_toggled(self, widget: Gtk.CheckButton) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
if widget.get_active(): if widget.get_active():
@@ -479,7 +515,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.not_has_focus_cb.set_active(True) self._ui.not_has_focus_cb.set_active(True)
self._config[self._active_num]['has_focus'] = 'no' self._config[self._active_num]['has_focus'] = 'no'
def _on_not_has_focus_cb_toggled(self, widget): def _on_not_has_focus_cb_toggled(self, widget: Gtk.CheckButton) -> None:
if self._active_num < 0: if self._active_num < 0:
return return
if widget.get_active(): if widget.get_active():
@@ -491,7 +527,12 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.has_focus_cb.set_active(True) self._ui.has_focus_cb.set_active(True)
self._config[self._active_num]['has_focus'] = 'yes' self._config[self._active_num]['has_focus'] = 'yes'
def _on_use_it_toggled(self, widget, opposite_widget, option): def _on_use_it_toggled(self,
widget: Gtk.CheckButton,
opposite_widget: Gtk.CheckButton,
option: str
) -> None:
if widget.get_active(): if widget.get_active():
if opposite_widget.get_active(): if opposite_widget.get_active():
opposite_widget.set_active(False) opposite_widget.set_active(False)
@@ -501,7 +542,12 @@ class ConfigDialog(Gtk.ApplicationWindow):
else: else:
self._config[self._active_num][option] = '' self._config[self._active_num][option] = ''
def _on_disable_it_toggled(self, widget, opposite_widget, option): def _on_disable_it_toggled(self,
widget: Gtk.CheckButton,
opposite_widget: Gtk.CheckButton,
option: str
) -> None:
if widget.get_active(): if widget.get_active():
if opposite_widget.get_active(): if opposite_widget.get_active():
opposite_widget.set_active(False) opposite_widget.set_active(False)
@@ -511,38 +557,38 @@ class ConfigDialog(Gtk.ApplicationWindow):
else: else:
self._config[self._active_num][option] = '' self._config[self._active_num][option] = ''
def _on_use_sound_cb_toggled(self, widget): def _on_use_sound_cb_toggled(self, widget: Gtk.CheckButton) -> None:
self._on_use_it_toggled(widget, self._ui.disable_sound_cb, 'sound') self._on_use_it_toggled(widget, self._ui.disable_sound_cb, 'sound')
if widget.get_active(): if widget.get_active():
self._ui.sound_file_box.set_sensitive(True) self._ui.sound_file_box.set_sensitive(True)
else: else:
self._ui.sound_file_box.set_sensitive(False) self._ui.sound_file_box.set_sensitive(False)
def _on_sound_file_set(self, widget): def _on_sound_file_set(self, widget: Gtk.FileChooserButton) -> None:
self._config[self._active_num]['sound_file'] = widget.get_filename() self._config[self._active_num]['sound_file'] = widget.get_filename()
def _on_play_button_clicked(self, _widget): def _on_play_button_clicked(self, _button: Gtk.Button) -> None:
play_sound_file(self._ui.filechooser.get_filename()) play_sound_file(self._ui.filechooser.get_filename())
def _on_disable_sound_cb_toggled(self, widget): def _on_disable_sound_cb_toggled(self, widget: Gtk.CheckButton) -> None:
self._on_disable_it_toggled(widget, self._ui.use_sound_cb, 'sound') self._on_disable_it_toggled(widget, self._ui.use_sound_cb, 'sound')
def _on_use_popup_cb_toggled(self, widget): def _on_use_popup_cb_toggled(self, widget: Gtk.CheckButton) -> None:
self._on_use_it_toggled(widget, self._ui.disable_popup_cb, 'popup') self._on_use_it_toggled(widget, self._ui.disable_popup_cb, 'popup')
def _on_disable_popup_cb_toggled(self, widget): def _on_disable_popup_cb_toggled(self, widget: Gtk.CheckButton) -> None:
self._on_disable_it_toggled(widget, self._ui.use_popup_cb, 'popup') self._on_disable_it_toggled(widget, self._ui.use_popup_cb, 'popup')
def _on_run_command_cb_toggled(self, widget): def _on_run_command_cb_toggled(self, widget: Gtk.CheckButton) -> None:
self._config[self._active_num]['run_command'] = widget.get_active() self._config[self._active_num]['run_command'] = widget.get_active()
if widget.get_active(): if widget.get_active():
self._ui.command_entry.set_sensitive(True) self._ui.command_entry.set_sensitive(True)
else: else:
self._ui.command_entry.set_sensitive(False) self._ui.command_entry.set_sensitive(False)
def _on_command_entry_changed(self, widget): def _on_command_entry_changed(self, widget: Gtk.Entry) -> None:
self._config[self._active_num]['command'] = widget.get_text() self._config[self._active_num]['command'] = widget.get_text()
def _on_one_shot_cb_toggled(self, widget): def _on_one_shot_cb_toggled(self, widget: Gtk.CheckButton) -> None:
self._config[self._active_num]['one_shot'] = widget.get_active() self._config[self._active_num]['one_shot'] = widget.get_active()
self._ui.command_entry.set_sensitive(widget.get_active()) self._ui.command_entry.set_sensitive(widget.get_active())

View File

@@ -14,16 +14,19 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>. # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any
from typing import Callable
from typing import cast
from typing import Union from typing import Union
import logging import logging
from functools import partial from functools import partial
from nbxmpp.protocol import JID
from gajim.common import app from gajim.common import app
from gajim.common import ged from gajim.common import ged
from gajim.common.const import PROPAGATE_EVENT from gajim.common.const import PROPAGATE_EVENT
@@ -31,24 +34,26 @@ from gajim.common.const import STOP_EVENT
from gajim.common.events import Notification from gajim.common.events import Notification
from gajim.common.events import GcMessageReceived from gajim.common.events import GcMessageReceived
from gajim.common.events import MessageReceived from gajim.common.events import MessageReceived
from gajim.common.events import PresenceReceived
from gajim.common.helpers import exec_command from gajim.common.helpers import exec_command
from gajim.common.helpers import play_sound_file from gajim.common.helpers import play_sound_file
from gajim.plugins import GajimPlugin from gajim.plugins import GajimPlugin
from gajim.plugins.plugins_i18n import _ from gajim.plugins.plugins_i18n import _
from triggers.gtk.config import ConfigDialog
from triggers.util import log_result from triggers.util import log_result
from triggers.util import RuleResult from triggers.util import RuleResult
from triggers.gtk.config import ConfigDialog
log = logging.getLogger('gajim.p.triggers') log = logging.getLogger('gajim.p.triggers')
MessageEventsT = Union[GcMessageReceived, MessageReceived] MessageEventsT = Union[GcMessageReceived, MessageReceived]
ProcessableEventsT = Union[MessageEventsT, Notification, PresenceReceived]
RuleT = dict[str, Any] RuleT = dict[str, Any]
class Triggers(GajimPlugin): class Triggers(GajimPlugin):
def init(self): def init(self) -> None:
self.description = _( self.description = _(
'Configure Gajims behaviour with triggers for each contact') 'Configure Gajims behaviour with triggers for each contact')
self.config_dialog = partial(ConfigDialog, self) self.config_dialog = partial(ConfigDialog, self)
@@ -77,7 +82,7 @@ class Triggers(GajimPlugin):
log.info('Result: %s', result) log.info('Result: %s', result)
return self._excecute_message_rules(result) return self._excecute_message_rules(result)
def _on_presence_received(self, event): def _on_presence_received(self, event: PresenceReceived) -> None:
# TODO # TODO
return return
@@ -89,14 +94,19 @@ class Triggers(GajimPlugin):
check_func = self._check_rule_apply_status_changed check_func = self._check_rule_apply_status_changed
self._check_all(event, check_func, self._apply_rule) self._check_all(event, check_func, self._apply_rule)
def _check_all(self, event, check_func, apply_func) -> RuleResult: def _check_all(self,
event: ProcessableEventsT,
check_func: Callable[..., bool],
apply_func: Callable[..., Any]
) -> RuleResult:
result = RuleResult() result = RuleResult()
rules_num = [int(item) for item in self.config.keys()] rules_num = [int(item) for item in self.config.keys()]
rules_num.sort() rules_num.sort()
to_remove = [] to_remove: list[int] = []
for num in rules_num: for num in rules_num:
rule = self.config[str(num)] rule = cast(RuleT, self.config[str(num)])
if check_func(event, rule): if check_func(event, rule):
apply_func(result, rule) apply_func(result, rule)
if 'one_shot' in rule and rule['one_shot']: if 'one_shot' in rule and rule['one_shot']:
@@ -108,7 +118,8 @@ class Triggers(GajimPlugin):
if num + decal in to_remove: if num + decal in to_remove:
num2 = num num2 = num
while str(num2 + 1) in self.config: while str(num2 + 1) in self.config:
self.config[str(num2)] = self.config[str(num2 + 1)].copy() copy = self.config[str(num2 + 1)].copy() # type: ignore
self.config[str(num2)] = copy
num2 += 1 num2 += 1
del self.config[str(num2)] del self.config[str(num2)]
decal += 1 decal += 1
@@ -120,43 +131,64 @@ class Triggers(GajimPlugin):
@log_result @log_result
def _check_rule_apply_msg_received(self, def _check_rule_apply_msg_received(self,
event: MessageEventsT, event: MessageEventsT,
rule: RuleT) -> bool: rule: RuleT
) -> bool:
return self._check_rule_all('message_received', event, rule) return self._check_rule_all('message_received', event, rule)
@log_result @log_result
def _check_rule_apply_connected(self, event, rule: RuleT) -> bool: def _check_rule_apply_connected(self,
event: PresenceReceived,
rule: RuleT
) -> bool:
return self._check_rule_all('contact_connected', event, rule) return self._check_rule_all('contact_connected', event, rule)
@log_result @log_result
def _check_rule_apply_disconnected(self, event, rule: RuleT) -> bool: def _check_rule_apply_disconnected(self,
event: PresenceReceived,
rule: RuleT
) -> bool:
return self._check_rule_all('contact_disconnected', event, rule) return self._check_rule_all('contact_disconnected', event, rule)
@log_result @log_result
def _check_rule_apply_status_changed(self, event, rule: RuleT) -> bool: def _check_rule_apply_status_changed(self,
event: PresenceReceived,
rule: RuleT
) -> bool:
return self._check_rule_all('contact_status_change', event, rule) return self._check_rule_all('contact_status_change', event, rule)
@log_result @log_result
def _check_rule_apply_notification(self, def _check_rule_apply_notification(self,
event: Notification, event: Notification,
rule: RuleT) -> bool: rule: RuleT
) -> bool:
# Check notification type # Check notification type
notif_type = '' notif_type = ''
if event.type == 'incoming-message': if event.type == 'incoming-message':
notif_type = 'message_received' notif_type = 'message_received'
if event.type == 'pres': # if event.type == 'pres':
# TODO: # # TODO:
if (event.base_event.old_show < 2 and # if (event.base_event.old_show < 2 and
event.base_event.new_show > 1): # event.base_event.new_show > 1):
notif_type = 'contact_connected' # notif_type = 'contact_connected'
elif (event.base_event.old_show > 1 and # elif (event.base_event.old_show > 1 and
event.base_event.new_show < 2): # event.base_event.new_show < 2):
notif_type = 'contact_disconnected' # notif_type = 'contact_disconnected'
else: # else:
notif_type = 'contact_status_change' # notif_type = 'contact_status_change'
return self._check_rule_all(notif_type, event, rule) return self._check_rule_all(notif_type, event, rule)
def _check_rule_all(self, notif_type: str, event: Any, rule: RuleT) -> bool: def _check_rule_all(self,
notif_type: str,
event: ProcessableEventsT,
rule: RuleT
) -> bool:
# Check notification type # Check notification type
if rule['event'] != notif_type: if rule['event'] != notif_type:
return False return False
@@ -181,7 +213,11 @@ class Triggers(GajimPlugin):
return True return True
@log_result @log_result
def _check_rule_recipients(self, event, rule: RuleT) -> bool: def _check_rule_recipients(self,
event: ProcessableEventsT,
rule: RuleT
) -> bool:
rule_recipients = [t.strip() for t in rule['recipients'].split(',')] rule_recipients = [t.strip() for t in rule['recipients'].split(',')]
if rule['recipient_type'] == 'groupchat': if rule['recipient_type'] == 'groupchat':
if event.jid in rule_recipients: if event.jid in rule_recipients:
@@ -207,7 +243,11 @@ class Triggers(GajimPlugin):
return True return True
@log_result @log_result
def _check_rule_status(self, event, rule: RuleT) -> bool: def _check_rule_status(self,
event: ProcessableEventsT,
rule: RuleT
) -> bool:
rule_statuses = rule['status'].split() rule_statuses = rule['status'].split()
client = app.get_client(event.account) client = app.get_client(event.account)
if rule['status'] != 'all' and client.status not in rule_statuses: if rule['status'] != 'all' and client.status not in rule_statuses:
@@ -216,10 +256,15 @@ class Triggers(GajimPlugin):
return True return True
@log_result @log_result
def _check_rule_tab_opened(self, event, rule: RuleT) -> bool: def _check_rule_tab_opened(self,
event: ProcessableEventsT,
rule: RuleT
) -> bool:
if rule['tab_opened'] == 'both': if rule['tab_opened'] == 'both':
return True return True
tab_opened = False tab_opened = False
assert isinstance(event.jid, JID)
if app.window.chat_exists(event.account, event.jid): if app.window.chat_exists(event.account, event.jid):
tab_opened = True tab_opened = True
if tab_opened and rule['tab_opened'] == 'no': if tab_opened and rule['tab_opened'] == 'no':
@@ -230,12 +275,17 @@ class Triggers(GajimPlugin):
return True return True
@log_result @log_result
def _check_rule_has_focus(self, event, rule: RuleT) -> bool: def _check_rule_has_focus(self,
event: ProcessableEventsT,
rule: RuleT
) -> bool:
if rule['has_focus'] == 'both': if rule['has_focus'] == 'both':
return True return True
if rule['tab_opened'] == 'no': if rule['tab_opened'] == 'no':
# Does not apply in this case # Does not apply in this case
return True return True
assert isinstance(event.jid, JID)
chat_active = app.window.is_chat_active(event.account, event.jid) chat_active = app.window.is_chat_active(event.account, event.jid)
if chat_active and rule['has_focus'] == 'no': if chat_active and rule['has_focus'] == 'no':
return False return False
@@ -263,7 +313,9 @@ class Triggers(GajimPlugin):
def _excecute_notification_rules(self, def _excecute_notification_rules(self,
result: RuleResult, result: RuleResult,
event: Notification) -> bool: event: Notification
) -> bool:
if result.sound is False: if result.sound is False:
event.sound = None event.sound = None

View File

@@ -12,20 +12,29 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>. # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import Any
from typing import Callable
from typing import Optional from typing import Optional
from typing import TYPE_CHECKING
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
if TYPE_CHECKING:
from .triggers import ProcessableEventsT
from .triggers import RuleT
log = logging.getLogger('gajim.p.triggers') log = logging.getLogger('gajim.p.triggers')
def log_result(func): def log_result(func: Callable[..., Any]) -> Callable[..., bool]:
def wrapper(self, event, rule): def wrapper(self: Any, event: ProcessableEventsT, rule: RuleT):
res = func(self, event, rule) res = func(self, event, rule)
log.info(f'{event.name} -> {func.__name__} -> {res}') log.info(f'{event.name} -> {func.__name__} -> {res}')
return res return res
return wrapper return wrapper
@dataclass @dataclass