summaryrefslogtreecommitdiffstats
path: root/config/chroot_local-includes/usr/local/lib/tails-additional-software-notify
blob: e31e020fb853a3adbedb3bc6b23f4dbb8e98c688 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env python3

import gettext
import os
import os.path
import subprocess
import sys

from tailslib.gnome import gnome_env_vars

import gi

from gi.repository import GLib

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


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

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

        If there are no buttons, exit straight away with a meaningful code.
        """
        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")
        if urgent:
            self.notification.set_urgency(Notify.Urgency.CRITICAL)
        if documentation_target:
            self.notification.add_action("documentation", _("Documentation"),
                                         self.cb_notification_clicked,
                                         documentation_target)
        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()
        sys.stdout.write("id=%i" % self.notification.props.id)
        if not (accept_label or deny_label or documentation_target):
            sys.exit(2)

    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":
            sys.exit(3)
        elif action == "documentation":
            subprocess.Popen(
                ["env", *gnome_env_vars(), "tails-documentation", user_data]
            )
            sys.exit(5)

    def cb_notification_closed(self, notification):
        """Exit the program with a meaningful code on notification close."""
        sys.exit(4)


def print_help():
    """The subcommand which displays help
    """
    program_name = os.path.basename(sys.argv[0])
    sys.stderr.write(
        "Usage: %s <summary> <body> [<accept_label> [<deny_label> "
        "[documentation_target [<urgent>]]]]\n" % program_name)
    sys.stderr.write(
        "Shows a notification with <summary>, <body> and optional "
        "buttons.\n"
        "\n"
        "Returns: 0 if the button with <accept_label> is selected\n"
        "         2 if the arguments are wrong\n"
        "         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")


if __name__ == "__main__":
    os.environ["DBUS_SESSION_BUS_ADDRESS"] = \
        "unix:path=/run/user/{uid}/bus".format(uid=os.getuid())

    gettext.install("tails")

    if not 3 <= len(sys.argv) <= 7:
        print_help()
        sys.exit(2)

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