tails-additional-software-notify 3.57 KB
Newer Older
Alan's avatar
Alan committed
1 2 3
#!/usr/bin/env python3

import gettext
4
import os
Alan's avatar
Alan committed
5
import os.path
6
import subprocess
Alan's avatar
Alan committed
7 8
import sys

anonym's avatar
anonym committed
9 10
from tailslib.gnome import gnome_env_vars

Alan's avatar
Alan committed
11 12 13 14 15 16 17 18 19 20 21 22 23
import gi

from gi.repository import GLib

gi.require_version('Notify', '0.7')
from gi.repository import Notify                                # NOQA: E402

_ = gettext.gettext


class ASPNotifier(object):
    """Display a notification and exit with a meaningful code."""

24
    def __init__(self, title, body, accept_label=None, deny_label=None,
25
                 documentation_target=None, urgent=False):
26 27 28 29
        """Shows a notification with two optional action buttons.

        If there are no buttons, exit straight away with a meaningful code.
        """
Alan's avatar
Alan committed
30 31 32 33 34 35
        Notify.init("org.boum.tails.additional-software-packages")

        # We need to hold a reference to the notification until the callbacks
        # are called. That's why we use an instance variable.
        self.notification = Notify.Notification.new(
                title, body, icon="package-x-generic")
36 37
        if urgent:
            self.notification.set_urgency(Notify.Urgency.CRITICAL)
38
        if documentation_target:
39
            self.notification.add_action("documentation", _("Documentation"),
40 41
                                         self.cb_notification_clicked,
                                         documentation_target)
Alan's avatar
Alan committed
42 43 44 45 46 47 48 49
        if deny_label:
            self.notification.add_action("deny", deny_label,
                                         self.cb_notification_clicked, None)
        if accept_label:
            self.notification.add_action("accept", accept_label,
                                         self.cb_notification_clicked, None)
        self.notification.connect("closed", self.cb_notification_closed)
        self.notification.show()
50
        sys.stdout.write("id=%i" % self.notification.props.id)
51
        if not (accept_label or deny_label or documentation_target):
Alan's avatar
Alan committed
52
            sys.exit(2)
Alan's avatar
Alan committed
53 54 55 56 57 58

    def cb_notification_clicked(self, notification, action, user_data=None):
        """Exit the program with a meaningful code on action triggering."""
        if action == "accept":
            sys.exit(0)
        elif action == "deny":
59
            sys.exit(3)
60
        elif action == "documentation":
anonym's avatar
anonym committed
61 62 63
            subprocess.Popen(
                ["env", *gnome_env_vars(), "tails-documentation", user_data]
            )
64
            sys.exit(5)
Alan's avatar
Alan committed
65 66 67

    def cb_notification_closed(self, notification):
        """Exit the program with a meaningful code on notification close."""
68
        sys.exit(4)
Alan's avatar
Alan committed
69 70 71 72 73 74 75


def print_help():
    """The subcommand which displays help
    """
    program_name = os.path.basename(sys.argv[0])
    sys.stderr.write(
76
        "Usage: %s <summary> <body> [<accept_label> [<deny_label> "
77
        "[documentation_target [<urgent>]]]]\n" % program_name)
Alan's avatar
Alan committed
78
    sys.stderr.write(
79
        "Shows a notification with <summary>, <body> and optional "
Alan's avatar
Alan committed
80 81
        "buttons.\n"
        "\n"
82
        "Returns: 0 if the button with <accept_label> is selected\n"
Alan's avatar
Alan committed
83
        "         2 if the arguments are wrong\n"
84 85 86 87
        "         3 if the button with <deny_label> is selected\n"
        "         4 if the notification is closed another way\n",
        "         5 if the documentation button is selected and the"
        "           documentation helper is launched.\n")
Alan's avatar
Alan committed
88 89 90


if __name__ == "__main__":
91 92
    os.environ["DBUS_SESSION_BUS_ADDRESS"] = \
        "unix:path=/run/user/{uid}/bus".format(uid=os.getuid())
Alan's avatar
Alan committed
93 94 95

    gettext.install("tails")

96
    if not 3 <= len(sys.argv) <= 7:
Alan's avatar
Alan committed
97 98 99 100 101 102
        print_help()
        sys.exit(2)

    mainloop = GLib.MainLoop.new(None, False)
    ASPNotifier(*sys.argv[1:])
    mainloop.run()