[triggers] Port to Gtk4

This commit is contained in:
Philipp Hörist
2025-01-26 18:48:25 +01:00
parent fd5d9fd33c
commit 1692ecda41
5 changed files with 401 additions and 672 deletions

View File

@@ -22,7 +22,6 @@ exclude = [
".venv", ".venv",
"openpgp/*", "openpgp/*",
"pgp/*", "pgp/*",
"triggers/*",
] ]
[tool.ruff] [tool.ruff]

View File

@@ -17,16 +17,16 @@
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any
from typing import cast
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from pathlib import Path from pathlib import Path
from gi.repository import Gdk
from gi.repository import Gtk from gi.repository import Gtk
from gajim.common import app
from gajim.common.helpers import play_sound_file from gajim.common.helpers import play_sound_file
from gajim.common.util.status import get_uf_show from gajim.common.util.status import get_uf_show
from gajim.gtk.widgets import GajimAppWindow
from gajim.plugins.helpers import get_builder from gajim.plugins.helpers import get_builder
from gajim.plugins.plugins_i18n import _ from gajim.plugins.plugins_i18n import _
@@ -40,98 +40,139 @@ EVENTS: dict[str, Any] = {
RECIPIENT_TYPES = ["contact", "group", "groupchat", "all"] RECIPIENT_TYPES = ["contact", "group", "groupchat", "all"]
class ConfigDialog(Gtk.ApplicationWindow): class ConfigBuilder(Gtk.Builder):
liststore1: Gtk.ListStore
liststore2: Gtk.ListStore
box: Gtk.Box
rules_box: Gtk.Box
conditions_treeview: Gtk.TreeView
up_button: Gtk.Button
down_button: Gtk.Button
new_button: Gtk.Button
delete_button: Gtk.Button
config_box: Gtk.Box
event_combobox: Gtk.ComboBox
recipient_type_combobox: Gtk.ComboBox
recipient_list_entry: Gtk.Entry
all_status_rb: Gtk.CheckButton
special_status_rb: Gtk.CheckButton
status_expander: Gtk.Expander
online_cb: Gtk.CheckButton
away_cb: Gtk.CheckButton
xa_cb: Gtk.CheckButton
dnd_cb: Gtk.CheckButton
tab_opened_cb: Gtk.CheckButton
has_focus_cb: Gtk.CheckButton
not_tab_opened_cb: Gtk.CheckButton
not_has_focus_cb: Gtk.CheckButton
use_popup_cb: Gtk.CheckButton
disable_popup_cb: Gtk.CheckButton
use_sound_cb: Gtk.CheckButton
sound_file_box: Gtk.Box
play_button: Gtk.Button
disable_sound_cb: Gtk.CheckButton
run_command_cb: Gtk.CheckButton
command_entry: Gtk.Entry
one_shot_cb: Gtk.CheckButton
class ConfigDialog(GajimAppWindow):
def __init__(self, plugin: Triggers, transient: Gtk.Window) -> None: def __init__(self, plugin: Triggers, transient: Gtk.Window) -> None:
Gtk.ApplicationWindow.__init__(self)
self.set_application(app.app) GajimAppWindow.__init__(
self.set_show_menubar(False) self,
self.set_title(_("Triggers Configuration")) name="TriggersConfigDialog",
self.set_transient_for(transient) title=_("Triggers Configuration"),
self.set_default_size(600, 800) default_width=600,
self.set_type_hint(Gdk.WindowTypeHint.DIALOG) default_height=800,
self.set_modal(True) transient_for=transient,
self.set_destroy_with_parent(True) modal=True,
)
ui_path = Path(__file__).parent ui_path = Path(__file__).parent
self._ui = get_builder(str(ui_path.resolve() / "config.ui")) self._ui = cast(
ConfigBuilder, get_builder(str(ui_path.resolve() / "config.ui"))
)
self._plugin = plugin self._plugin = plugin
self.add(self._ui.box) self.set_child(self._ui.box)
self.show_all()
self._active_num = -1 self._active_num = -1
self._config: dict[int, Any] = {} self._config: dict[int, Any] = {}
self._initialize() self._initialize()
self._ui.connect_signals(self) self._connect(
self.connect("destroy", self._on_destroy) self._ui.conditions_treeview,
"cursor-changed",
self._on_conditions_treeview_cursor_changed,
)
self._connect(self._ui.up_button, "clicked", self._on_up_button_clicked)
self._connect(self._ui.down_button, "clicked", self._on_down_button_clicked)
self._connect(self._ui.new_button, "clicked", self._on_new_button_clicked)
self._connect(self._ui.delete_button, "clicked", self._on_delete_button_clicked)
self._connect(
self._ui.event_combobox, "changed", self._on_event_combobox_changed
)
self._connect(
self._ui.recipient_type_combobox,
"changed",
self._on_recipient_type_combobox_changed,
)
self._connect(
self._ui.recipient_list_entry,
"changed",
self._on_recipient_list_entry_changed,
)
self._connect(
self._ui.all_status_rb, "toggled", self._on_status_radiobutton_toggled
)
self._connect(self._ui.online_cb, "toggled", self._on_status_cb_toggled)
self._connect(self._ui.away_cb, "toggled", self._on_status_cb_toggled)
self._connect(self._ui.xa_cb, "toggled", self._on_status_cb_toggled)
self._connect(self._ui.dnd_cb, "toggled", self._on_status_cb_toggled)
self._connect(self._ui.tab_opened_cb, "toggled", self._on_tab_opened_cb_toggled)
self._connect(self._ui.has_focus_cb, "toggled", self._on_has_focus_cb_toggled)
self._connect(
self._ui.not_tab_opened_cb, "toggled", self._on_not_tab_opened_cb_toggled
)
self._connect(
self._ui.not_has_focus_cb, "toggled", self._on_not_has_focus_cb_toggled
)
self._connect(self._ui.use_popup_cb, "toggled", self._on_use_popup_cb_toggled)
self._connect(
self._ui.disable_popup_cb, "toggled", self._on_disable_popup_cb_toggled
)
self._connect(self._ui.use_sound_cb, "toggled", self._on_use_sound_cb_toggled)
self._connect(self._ui.play_button, "clicked", self._on_play_button_clicked)
self._connect(
self._ui.disable_sound_cb, "toggled", self._on_disable_sound_cb_toggled
)
self._connect(
self._ui.run_command_cb, "toggled", self._on_run_command_cb_toggled
)
self._connect(self._ui.command_entry, "changed", self._on_command_entry_changed)
self._connect(self._ui.one_shot_cb, "toggled", self._on_one_shot_cb_toggled)
self._connect(self.window, "close-request", self._on_close_request)
def _on_destroy(self, *args: Any) -> None: self.show()
def _cleanup(self) -> None:
pass
def _on_close_request(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) -> None: def _initialize(self) -> None:
# Fill window
widgets = [
"conditions_treeview",
"config_box",
"event_combobox",
"recipient_type_combobox",
"recipient_list_entry",
"delete_button",
"online_cb",
"away_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._config = {} self._config = {}
for num in self._plugin.config.keys(): for num in self._plugin.config:
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): model = cast(Gtk.ListStore, self._ui.conditions_treeview.get_model())
# Window never opened
model = Gtk.ListStore(int, str)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
self._ui.conditions_treeview.set_model(model)
# '#' Means number
col = Gtk.TreeViewColumn(_("#"))
self._ui.conditions_treeview.append_column(col)
renderer = Gtk.CellRendererText()
col.pack_start(renderer, expand=False)
col.add_attribute(renderer, "text", 0)
col = Gtk.TreeViewColumn(_("Condition"))
self._ui.conditions_treeview.append_column(col)
renderer = Gtk.CellRendererText()
col.pack_start(renderer, expand=True)
col.add_attribute(renderer, "text", 1)
else:
model = self._ui.conditions_treeview.get_model()
model.clear()
# Fill conditions_treeview # Fill conditions_treeview
num = 0 num = 0
@@ -152,16 +193,16 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.down_button.set_sensitive(False) self._ui.down_button.set_sensitive(False)
self._ui.up_button.set_sensitive(False) self._ui.up_button.set_sensitive(False)
filter_ = Gtk.FileFilter() # filter_ = Gtk.FileFilter()
filter_.set_name(_("All Files")) # filter_.set_name(_("All Files"))
filter_.add_pattern("*") # filter_.add_pattern("*")
self._ui.filechooser.add_filter(filter_) # self._ui.filechooser.add_filter(filter_)
filter_ = Gtk.FileFilter() # filter_ = Gtk.FileFilter()
filter_.set_name(_("Wav Sounds")) # filter_.set_name(_("Wav Sounds"))
filter_.add_pattern("*.wav") # filter_.add_pattern("*.wav")
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) -> None: def _initiate_rule_state(self) -> None:
""" """
@@ -202,11 +243,11 @@ class ConfigDialog(Gtk.ApplicationWindow):
else: else:
self._ui.special_status_rb.set_active(True) self._ui.special_status_rb.set_active(True)
values = value.split() values = value.split()
for val in ("online", "away", "xa", "dnd"): for st in ("online", "away", "xa", "dnd"):
if val in values: if st in values:
self._ui.__dict__[val + "_cb"].set_active(True) getattr(self._ui, f"{st}_cb").set_active(True)
else: else:
self._ui.__dict__[val + "_cb"].set_active(False) getattr(self._ui, f"{st}_cb").set_active(False)
self._on_status_radiobutton_toggled(self._ui.all_status_rb) self._on_status_radiobutton_toggled(self._ui.all_status_rb)
@@ -230,24 +271,25 @@ class ConfigDialog(Gtk.ApplicationWindow):
elif value == "yes": elif value == "yes":
self._ui.not_has_focus_cb.set_active(False) self._ui.not_has_focus_cb.set_active(False)
# TODO
# sound_file # sound_file
value = self._config[self._active_num]["sound_file"] # value = self._config[self._active_num]["sound_file"]
if value is None: # if value is None:
self._ui.filechooser.unselect_all() # self._ui.filechooser.unselect_all()
else: # else:
self._ui.filechooser.set_filename(value) # self._ui.filechooser.set_filename(value)
# sound, popup, auto_open, systray, roster # sound, popup, auto_open, systray, roster
for option in ("sound", "popup"): for option in ("sound", "popup"):
value = self._config[self._active_num][option] value = self._config[self._active_num][option]
if value == "yes": if value == "yes":
self._ui.__dict__["use_" + option + "_cb"].set_active(True) getattr(self._ui, f"use_{option}_cb").set_active(True)
else: else:
self._ui.__dict__["use_" + option + "_cb"].set_active(False) getattr(self._ui, f"use_{option}_cb").set_active(False)
if value == "no": if value == "no":
self._ui.__dict__["disable_" + option + "_cb"].set_active(True) getattr(self._ui, f"disable_{option}_cb").set_active(True)
else: else:
self._ui.__dict__["disable_" + option + "_cb"].set_active(False) getattr(self._ui, f"disable_{option}_cb").set_active(False)
# run_command # run_command
value = self._config[self._active_num]["run_command"] value = self._config[self._active_num]["run_command"]
@@ -258,10 +300,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.command_entry.set_text(value) self._ui.command_entry.set_text(value)
# one shot # one shot
if "one_shot" in self._config[self._active_num]: value = self._config[self._active_num].get("one_shot", False)
value = self._config[self._active_num]["one_shot"]
else:
value = False
self._ui.one_shot_cb.set_active(value) self._ui.one_shot_cb.set_active(value)
def _set_treeview_string(self) -> None: def _set_treeview_string(self) -> None:
@@ -269,15 +308,21 @@ class ConfigDialog(Gtk.ApplicationWindow):
(model, iter_) = selection.get_selected() (model, iter_) = selection.get_selected()
if not iter_: if not iter_:
return return
ind = self._ui.event_combobox.get_active()
event = "" event = ""
ind = self._ui.event_combobox.get_active()
if ind > -1: if ind > -1:
event = self._ui.event_combobox.get_model()[ind][0] event_model = self._ui.event_combobox.get_model()
assert event_model is not None
event = event_model[ind][0]
ind = self._ui.recipient_type_combobox.get_active() ind = self._ui.recipient_type_combobox.get_active()
recipient_type = "" recipient_type = ""
if ind > -1: if ind > -1:
recipient_type_model = self._ui.recipient_type_combobox.get_model() recipient_type_model = self._ui.recipient_type_combobox.get_model()
assert recipient_type_model is not None
recipient_type = recipient_type_model[ind][0] recipient_type = recipient_type_model[ind][0]
recipient = "" recipient = ""
if recipient_type != "everybody": if recipient_type != "everybody":
recipient = self._ui.recipient_list_entry.get_text() recipient = self._ui.recipient_list_entry.get_text()
@@ -286,8 +331,9 @@ class ConfigDialog(Gtk.ApplicationWindow):
else: else:
status = _("and I am ") status = _("and I am ")
for st in ("online", "away", "xa", "dnd"): for st in ("online", "away", "xa", "dnd"):
if self._ui.__dict__[st + "_cb"].get_active(): if getattr(self._ui, f"{st}_cb").get_active():
status += get_uf_show(st) + " " status += get_uf_show(st) + " "
model[iter_][1] = _( model[iter_][1] = _(
"%(event)s (%(recipient_type)s) %(recipient)s %(status)s" "%(event)s (%(recipient_type)s) %(recipient)s %(status)s"
) % { ) % {
@@ -298,7 +344,6 @@ class ConfigDialog(Gtk.ApplicationWindow):
} }
def _on_conditions_treeview_cursor_changed(self, widget: Gtk.TreeView) -> None: 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 = -1 self._active_num = -1
@@ -320,8 +365,9 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._ui.delete_button.set_sensitive(True) self._ui.delete_button.set_sensitive(True)
def _on_new_button_clicked(self, _button: Gtk.Button) -> None: def _on_new_button_clicked(self, _button: Gtk.Button) -> None:
model = self._ui.conditions_treeview.get_model() model = cast(Gtk.ListStore, self._ui.conditions_treeview.get_model())
num = self._ui.conditions_treeview.get_model().iter_n_children(None) assert model is not None
num = model.iter_n_children(None)
self._config[num] = { self._config[num] = {
"event": "message_received", "event": "message_received",
"recipient_type": "all", "recipient_type": "all",
@@ -336,6 +382,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
"command": "", "command": "",
"one_shot": False, "one_shot": False,
} }
iter_ = model.append((num, "")) iter_ = model.append((num, ""))
path = model.get_path(iter_) path = model.get_path(iter_)
self._ui.conditions_treeview.set_cursor(path) self._ui.conditions_treeview.set_cursor(path)
@@ -346,8 +393,10 @@ class ConfigDialog(Gtk.ApplicationWindow):
def _on_delete_button_clicked(self, button: Gtk.Button) -> None: 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()
assert isinstance(model, Gtk.ListStore)
if not iter_: if not iter_:
return return
# up all others # up all others
iter2 = model.iter_next(iter_) iter2 = model.iter_next(iter_)
num = self._active_num num = self._active_num
@@ -356,6 +405,7 @@ class ConfigDialog(Gtk.ApplicationWindow):
model[iter2][0] = num - 1 model[iter2][0] = num - 1
self._config[num - 1] = self._config[num].copy() self._config[num - 1] = self._config[num].copy()
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 = -1 self._active_num = -1
@@ -367,8 +417,10 @@ class ConfigDialog(Gtk.ApplicationWindow):
def _on_up_button_clicked(self, _button: Gtk.Button) -> None: 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()
assert isinstance(model, Gtk.ListStore)
if not iter_: if not iter_:
return return
conf = self._config[self._active_num].copy() conf = self._config[self._active_num].copy()
self._config[self._active_num] = self._config[self._active_num - 1] self._config[self._active_num] = self._config[self._active_num - 1]
self._config[self._active_num - 1] = conf self._config[self._active_num - 1] = conf
@@ -383,14 +435,17 @@ class ConfigDialog(Gtk.ApplicationWindow):
def _on_down_button_clicked(self, _button: Gtk.Button) -> None: 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()
assert isinstance(model, Gtk.ListStore)
if not iter_: if not iter_:
return return
conf = self._config[self._active_num].copy() conf = self._config[self._active_num].copy()
self._config[self._active_num] = self._config[self._active_num + 1] self._config[self._active_num] = self._config[self._active_num + 1]
self._config[self._active_num + 1] = conf self._config[self._active_num + 1] = conf
model[iter_][0] = self._active_num + 1 model[iter_][0] = self._active_num + 1
iter_ = model.iter_next(iter_) iter_ = model.iter_next(iter_)
assert iter_ is not None
model[iter_][0] = self._active_num model[iter_][0] = self._active_num
self._on_conditions_treeview_cursor_changed(self._ui.conditions_treeview) self._on_conditions_treeview_cursor_changed(self._ui.conditions_treeview)
@@ -432,14 +487,14 @@ class ConfigDialog(Gtk.ApplicationWindow):
return return
status = "" status = ""
for st in ("online", "away", "xa", "dnd"): for st in ("online", "away", "xa", "dnd"):
if self._ui.__dict__[st + "_cb"].get_active(): if getattr(self._ui, f"{st}_cb").get_active():
status += st + " " status += st + " "
if status: if status:
status = status[:-1] status = status[:-1]
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: Gtk.RadioButton) -> None: def _on_status_radiobutton_toggled(self, _widget: Gtk.CheckButton) -> 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():
@@ -447,13 +502,13 @@ class ConfigDialog(Gtk.ApplicationWindow):
self._config[self._active_num]["status"] = "all" self._config[self._active_num]["status"] = "all"
# 'All status' clicked # 'All status' clicked
for st in ("online", "away", "xa", "dnd"): for st in ("online", "away", "xa", "dnd"):
self._ui.__dict__[st + "_cb"].set_sensitive(False) getattr(self._ui, f"{st}_cb").set_sensitive(False)
else: else:
self._ui.status_expander.set_expanded(True) self._ui.status_expander.set_expanded(True)
self._set_status_config() self._set_status_config()
# 'special status' clicked # 'special status' clicked
for st in ("online", "away", "xa", "dnd"): for st in ("online", "away", "xa", "dnd"):
self._ui.__dict__[st + "_cb"].set_sensitive(True) getattr(self._ui, f"{st}_cb").set_sensitive(True)
self._set_treeview_string() self._set_treeview_string()

File diff suppressed because it is too large Load Diff

View File

@@ -18,12 +18,11 @@
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 cast
from typing import Union
import logging import logging
import subprocess import subprocess
from collections.abc import Callable
from functools import partial from functools import partial
from nbxmpp.protocol import JID from nbxmpp.protocol import JID
@@ -36,6 +35,7 @@ from gajim.common.events import MessageReceived
from gajim.common.events import Notification from gajim.common.events import Notification
from gajim.common.events import PresenceReceived from gajim.common.events import PresenceReceived
from gajim.common.helpers import play_sound_file from gajim.common.helpers import play_sound_file
from gajim.common.modules.contacts import BareContact
from gajim.plugins import GajimPlugin from gajim.plugins import GajimPlugin
from gajim.plugins.plugins_i18n import _ from gajim.plugins.plugins_i18n import _
@@ -45,7 +45,7 @@ from triggers.util import RuleResult
log = logging.getLogger("gajim.p.triggers") log = logging.getLogger("gajim.p.triggers")
ProcessableEventsT = Union[MessageReceived, Notification, PresenceReceived] ProcessableEventsT = MessageReceived | Notification | PresenceReceived
RuleT = dict[str, Any] RuleT = dict[str, Any]
@@ -106,14 +106,14 @@ class Triggers(GajimPlugin):
result = RuleResult() result = RuleResult()
rules_num = [int(item) for item in self.config.keys()] rules_num = [int(item) for item in self.config]
rules_num.sort() rules_num.sort()
to_remove: list[int] = [] to_remove: list[int] = []
for num in rules_num: for num in rules_num:
rule = cast(RuleT, 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 rule.get("one_shot"):
to_remove.append(num) to_remove.append(num)
decal = 0 decal = 0
@@ -136,31 +136,26 @@ class Triggers(GajimPlugin):
def _check_rule_apply_msg_received( def _check_rule_apply_msg_received(
self, event: MessageReceived, rule: RuleT self, event: MessageReceived, rule: RuleT
) -> bool: ) -> 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: PresenceReceived, 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( def _check_rule_apply_disconnected(
self, event: PresenceReceived, rule: RuleT self, event: PresenceReceived, rule: RuleT
) -> bool: ) -> 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( def _check_rule_apply_status_changed(
self, event: PresenceReceived, rule: RuleT self, event: PresenceReceived, rule: RuleT
) -> bool: ) -> 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, event: Notification, rule: RuleT) -> bool: def _check_rule_apply_notification(self, event: Notification, rule: RuleT) -> bool:
# Check notification type # Check notification type
notif_type = "" notif_type = ""
if event.type == "incoming-message": if event.type == "incoming-message":
@@ -181,7 +176,6 @@ class Triggers(GajimPlugin):
def _check_rule_all( def _check_rule_all(
self, notif_type: str, event: ProcessableEventsT, rule: RuleT self, notif_type: str, event: ProcessableEventsT, rule: RuleT
) -> bool: ) -> bool:
# Check notification type # Check notification type
if rule["event"] != notif_type: if rule["event"] != notif_type:
return False return False
@@ -207,7 +201,7 @@ class Triggers(GajimPlugin):
@log_result @log_result
def _check_rule_recipients(self, event: ProcessableEventsT, rule: RuleT) -> bool: def _check_rule_recipients(self, event: ProcessableEventsT, rule: RuleT) -> bool:
assert event.jid is not None
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:
@@ -218,7 +212,11 @@ class Triggers(GajimPlugin):
client = app.get_client(event.account) client = app.get_client(event.account)
contact = client.get_module("Contacts").get_contact(event.jid) contact = client.get_module("Contacts").get_contact(event.jid)
if contact.is_groupchat or not contact.is_in_roster: if contact.is_groupchat:
return False
assert isinstance(contact, BareContact)
if not contact.is_in_roster:
return False return False
group_found = False group_found = False
@@ -233,7 +231,6 @@ class Triggers(GajimPlugin):
@log_result @log_result
def _check_rule_status(self, event: ProcessableEventsT, 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:
@@ -243,7 +240,6 @@ class Triggers(GajimPlugin):
@log_result @log_result
def _check_rule_tab_opened(self, event: ProcessableEventsT, 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
@@ -259,7 +255,6 @@ class Triggers(GajimPlugin):
@log_result @log_result
def _check_rule_has_focus(self, event: ProcessableEventsT, 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":
@@ -311,7 +306,7 @@ class Triggers(GajimPlugin):
if result.command is not None: if result.command is not None:
try: try:
subprocess.Popen(f"{result.command} &", shell=True).wait() subprocess.Popen(f"{result.command} &", shell=True).wait() # noqa: S602
except Exception: except Exception:
pass pass

View File

@@ -15,10 +15,10 @@
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any
from typing import Callable
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import logging import logging
from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -31,7 +31,7 @@ log = logging.getLogger("gajim.p.triggers")
def log_result(func: Callable[..., Any]) -> Callable[..., bool]: def log_result(func: Callable[..., Any]) -> Callable[..., bool]:
def wrapper(self: Any, event: ProcessableEventsT, rule: RuleT): 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("%s -> %s -> %s", event.name, func.__name__, res)
return res return res
return wrapper return wrapper