Skip to content

Commit

Permalink
Implement human-readable variant of RuleList
Browse files Browse the repository at this point in the history
The old variant will stay in place, but is just reachable when the flag
is given.
  • Loading branch information
zappolowski committed Jan 20, 2024
1 parent 4221e15 commit f63eebd
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 7 deletions.
9 changes: 5 additions & 4 deletions contrib/dunstctl.fishcomp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
if command -q jq
function __fish_dunstctl_info
dunstctl $argv[1] | jq -r ".data[][] | \"\(.$argv[2].data)\t\(.$argv[3].data)\""
dunstctl (string split ' ' $argv[1]) | jq -r ".data[][] | \"\(.$argv[2].data)\t\(.$argv[3].data)\""
end
else
function __fish_dunstctl_info
dunstctl $argv[1] | awk -vpattern="\"$argv[2]\" :" '$0 ~ pattern {getline; getline; gsub("\"", "", $3); print $3}'
dunstctl (string split ' ' $argv[1]) | awk -vpattern="\"$argv[2]\" :" '$0 ~ pattern {getline; getline; gsub("\"", "", $3); print $3}'
end
end

function __fish_dunstctl_rule_complete
set -l parts (string split ' ' $argv[1])
if test (count $parts[-1]) -eq 0 || test $parts[-2] = rule
__fish_dunstctl_info rules name enabled
__fish_dunstctl_info 'rules --json' name enabled
return
end
# TODO? enable disable might not make sense when the rule is already in the correct state
Expand All @@ -30,7 +30,7 @@ complete -c dunstctl -f -n __fish_use_subcommand -a history-pop -d 'Pop the late
complete -c dunstctl -f -n __fish_use_subcommand -a history-rm -d 'Remove the notification from history with given ID'
complete -c dunstctl -f -n __fish_use_subcommand -a is-paused -d 'Check if dunst is running or paused'
complete -c dunstctl -f -n __fish_use_subcommand -a set-paused -d 'Set the pause status'
complete -c dunstctl -f -n __fish_use_subcommand -a rules -d 'Displays configured rules (in JSON)'
complete -c dunstctl -f -n __fish_use_subcommand -a rules -d 'Displays configured rules (optionally in JSON)'
complete -c dunstctl -f -n __fish_use_subcommand -a rule -d 'Enable or disable a rule by its name'
complete -c dunstctl -f -n __fish_use_subcommand -a debug -d 'Print debugging information'
complete -c dunstctl -f -n __fish_use_subcommand -a help -d 'Show this help'
Expand All @@ -41,5 +41,6 @@ complete -c dunstctl -x -n '__fish_seen_subcommand_from count' -a 'displayed his
complete -c dunstctl -x -n '__fish_seen_subcommand_from history-pop history-rm' -a '(__fish_dunstctl_info history id appname)'
complete -c dunstctl -x -n '__fish_seen_subcommand_from set-paused' -a 'true false toggle'
complete -c dunstctl -x -n '__fish_seen_subcommand_from rule' -a '(__fish_dunstctl_rule_complete (commandline -c))'
complete -c dunstctl -x -n '__fish_seen_subcommand_from rules' -a --json

# ex: filetype=fish
17 changes: 14 additions & 3 deletions dunstctl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ show_help() {
get-pause-level Get the current pause level
set-pause-level level Set the pause level
rule name enable|disable|toggle Enable or disable a rule by its name
rules Displays configured rules (in JSON)
rules [--json] Displays configured rules (optionally
in JSON)
debug Print debugging information
help Show this help
EOH
Expand Down Expand Up @@ -125,8 +126,18 @@ case "${1:-}" in
fi
;;
"rules")
busctl --user --json=pretty --no-pager call org.freedesktop.Notifications /org/freedesktop/Notifications org.dunstproject.cmd0 RuleList 2>/dev/null \
|| die "Dunst is not running."
case "${2:-}" in
"")
method_call "${DBUS_IFAC_DUNST}.RuleListHumanReadable" | sed '1s/^[[:space:]]\+//'
;;
--json)
busctl --user --json=pretty --no-pager call "${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_DUNST}" RuleList 2>/dev/null \
|| die "Dunst is not running."
;;
*)
die "Unknown format \"${2}\". Please use either \"as-json\" or \"human-readable\"."
;;
esac
;;
"rule")
[ "${2:-}" ] \
Expand Down
141 changes: 141 additions & 0 deletions src/dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ static const char *introspection_xml =
" <method name=\"RuleList\">"
" <arg direction=\"out\" name=\"rules\" type=\"aa{sv}\"/>"
" </method>"
" <method name=\"RuleListHumanReadable\">"
" <arg direction=\"out\" name=\"rules\" type=\"s\"/>"
" </method>"
" <method name=\"Ping\" />"

" <property name=\"paused\" type=\"b\" access=\"readwrite\">"
Expand Down Expand Up @@ -191,6 +194,7 @@ DBUS_METHOD(dunst_NotificationRemoveFromHistory);
DBUS_METHOD(dunst_NotificationShow);
DBUS_METHOD(dunst_RuleEnable);
DBUS_METHOD(dunst_RuleList);
DBUS_METHOD(dunst_RuleListHumanReadable);
DBUS_METHOD(dunst_Ping);
static struct dbus_method methods_dunst[] = {
{"ContextMenuCall", dbus_cb_dunst_ContextMenuCall},
Expand All @@ -205,6 +209,7 @@ static struct dbus_method methods_dunst[] = {
{"Ping", dbus_cb_dunst_Ping},
{"RuleEnable", dbus_cb_dunst_RuleEnable},
{"RuleList", dbus_cb_dunst_RuleList},
{"RuleListHumanReadable", dbus_cb_dunst_RuleListHumanReadable},
};

void dbus_cb_dunst_methods(GDBusConnection *connection,
Expand Down Expand Up @@ -634,6 +639,142 @@ static void dbus_cb_dunst_RuleList(GDBusConnection *connection,
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}

static char *add_rule_entry_bool(char *old, const char *name, int value)
{
return (value > -1)
? string_append(old, g_strdup_printf(" %s = %s", name, value ? "yes" : "no"), "\n")
: old;
}

static char *add_rule_entry_string(char *old, const char *name, const char *value)
{
return value ? string_append(old, g_strdup_printf(" %s = %s", name, value), "\n") : old;
}

static void dbus_cb_dunst_RuleListHumanReadable(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
LOG_D("CMD: Listing all configured rules in human readable format");

char *answer = g_strdup("");

for (GSList *iter = rules; iter; iter = iter->next) {
struct rule *r = iter->data;

if (is_special_section(r->name)) {
continue;
}

answer = string_append(answer, g_strdup_printf("[%s]", r->name), "\n");

// filters - order according to rule_matches_notification
answer = string_append(answer, g_strdup_printf(" enabled = %s", r->enabled ? "yes" : "no"), "\n");
// undocumented filter?
if (r->match_dbus_timeout > -1)
answer = string_append(answer,
g_strdup_printf(" match_dbus_timeout = %ld", r->match_dbus_timeout),
"\n");
if (r->msg_urgency != URG_NONE)
answer = string_append(answer,
g_strdup_printf(" msg_urgency = %s",
enum_to_string(urgency_enum_data, r->msg_urgency)),
"\n");
answer = add_rule_entry_bool(answer, "match_transient", r->match_transient);
answer = add_rule_entry_string(answer, "appname", r->appname);
answer = add_rule_entry_string(answer, "desktop_entry", r->desktop_entry);
answer = add_rule_entry_string(answer, "summary", r->summary);
answer = add_rule_entry_string(answer, "body", r->body);
answer = add_rule_entry_string(answer, "category", r->category);
answer = add_rule_entry_string(answer, "stack_tag", r->stack_tag);

// settings to apply - order according to rule_apply
if (r->timeout != -1)
answer = string_append(answer, g_strdup_printf(" timeout = %ld", r->timeout), "\n");
if (r->override_dbus_timeout != -1)
answer = string_append(answer,
g_strdup_printf(" override_dbus_timeout = %ld",
r->override_dbus_timeout),
"\n");
if (r->urgency != URG_NONE)
answer = string_append(answer,
g_strdup_printf(" urgency = %s",
enum_to_string(urgency_enum_data, r->urgency)),
"\n");
if (r->fullscreen != FS_NULL)
answer = string_append(answer,
g_strdup_printf(" fullscreen = %s",
enum_to_string(fullscreen_enum_data, r->fullscreen)),
"\n");
answer = add_rule_entry_bool(answer, "history_ignore", r->history_ignore);
answer = add_rule_entry_bool(answer, "set_transient", r->set_transient);
answer = add_rule_entry_bool(answer, "skip_display", r->skip_display);
answer = add_rule_entry_bool(answer, "word_wrap", r->word_wrap);
if (r->ellipsize != -1)
answer = string_append(answer,
g_strdup_printf(" ellipsize = %s",
enum_to_string(ellipsize_enum_data, r->ellipsize)),
"\n");
if (r->alignment != -1)
answer = string_append(answer,
g_strdup_printf(" alignment = %s",
enum_to_string(horizontal_alignment_enum_data,
r->alignment)),
"\n");
answer = add_rule_entry_bool(answer, "hide_text", r->hide_text);
if (r->progress_bar_alignment != -1)
answer = string_append(answer,
g_strdup_printf(" progress_bar_alignment = %s",
enum_to_string(horizontal_alignment_enum_data,
r->progress_bar_alignment)),
"\n");
if (r->min_icon_size != -1)
answer = string_append(answer,
g_strdup_printf(" min_icon_size = %d", r->min_icon_size),
"\n");
if (r->max_icon_size != -1)
answer = string_append(answer,
g_strdup_printf(" max_icon_size = %d", r->max_icon_size),
"\n");
answer = add_rule_entry_string(answer, "action_name", r->action_name);
answer = add_rule_entry_string(answer, "set_category", r->set_category);
if (r->markup != MARKUP_NULL)
answer = string_append(answer,
g_strdup_printf(" markup = %s",
enum_to_string(markup_mode_enum_data,
r->markup)),
"\n");
if (r->icon_position != -1)
answer = string_append(answer,
g_strdup_printf(" icon_position = %s",
enum_to_string(icon_position_enum_data,
r->icon_position)),
"\n");
answer = add_rule_entry_string(answer, "fg", r->fg);
answer = add_rule_entry_string(answer, "bg", r->bg);
answer = add_rule_entry_string(answer, "highlight", r->highlight);
answer = add_rule_entry_string(answer, "fc", r->fc);
answer = add_rule_entry_string(answer, "format", r->format);
answer = add_rule_entry_string(answer, "default_icon", r->default_icon);
answer = add_rule_entry_string(answer, "new_icon", r->new_icon);
answer = add_rule_entry_string(answer, "script", r->script);
answer = add_rule_entry_string(answer, "set_stack_tag", r->set_stack_tag);
if (r->override_pause_level != -1)
answer = string_append(answer,
g_strdup_printf(" override_pause_level = %d",
r->override_pause_level),
"\n");

// add an empty line after each rule to make it easier to read
answer = string_append(answer, "\n", NULL);
}

g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", answer));
g_dbus_connection_flush(connection, NULL, NULL, NULL);
g_free(answer);
}

static void dbus_cb_dunst_RuleEnable(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
Expand Down

0 comments on commit f63eebd

Please sign in to comment.