Merge branch 'pr/1649'
[collectd.git] / src / notify_desktop.c
1 /**
2  * collectd - src/notify_desktop.c
3  * Copyright (C) 2008       Sebastian Harl
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *   Sebastian Harl <sh at tokkee.org>
25  **/
26
27 /*
28  * This plugin sends desktop notifications to a notification daemon.
29  */
30
31 #include "collectd.h"
32
33 #include "common.h"
34 #include "plugin.h"
35
36 #include <glib.h>
37 #include <libnotify/notify.h>
38
39 #ifndef NOTIFY_CHECK_VERSION
40 # define NOTIFY_CHECK_VERSION(x,y,z) 0
41 #endif
42
43 #define log_info(...) INFO ("notify_desktop: " __VA_ARGS__)
44 #define log_warn(...) WARNING ("notify_desktop: " __VA_ARGS__)
45 #define log_err(...) ERROR ("notify_desktop: " __VA_ARGS__)
46
47 #define DEFAULT_TIMEOUT 5000
48
49 static int okay_timeout = DEFAULT_TIMEOUT;
50 static int warn_timeout = DEFAULT_TIMEOUT;
51 static int fail_timeout = DEFAULT_TIMEOUT;
52
53 static int set_timeout (oconfig_item_t *ci, int *timeout)
54 {
55         if ((0 != ci->children_num) || (1 != ci->values_num)
56                         || (OCONFIG_TYPE_NUMBER != ci->values[0].type)) {
57                 log_err ("%s expects a single number argument.", ci->key);
58                 return 1;
59         }
60
61         *timeout = (int)ci->values[0].value.number;
62         if (0 > *timeout)
63                 *timeout = DEFAULT_TIMEOUT;
64         return 0;
65 } /* set_timeout */
66
67 static int c_notify_config (oconfig_item_t *ci)
68 {
69         for (int i = 0; i < ci->children_num; ++i) {
70                 oconfig_item_t *c = ci->children + i;
71
72                 if (0 == strcasecmp (c->key, "OkayTimeout"))
73                         set_timeout (c, &okay_timeout);
74                 else if (0 == strcasecmp (c->key, "WarningTimeout"))
75                         set_timeout (c, &warn_timeout);
76                 else if (0 == strcasecmp (c->key, "FailureTimeout"))
77                         set_timeout (c, &fail_timeout);
78         }
79         return 0;
80 } /* c_notify_config */
81
82 static int c_notify (const notification_t *n,
83                 user_data_t __attribute__((unused)) *user_data)
84 {
85         NotifyNotification *notification = NULL;
86         NotifyUrgency       urgency      = NOTIFY_URGENCY_LOW;
87         int                 timeout      = okay_timeout;
88
89         char summary[1024];
90
91         if (NOTIF_WARNING == n->severity) {
92                 urgency = NOTIFY_URGENCY_NORMAL;
93                 timeout = warn_timeout;
94         }
95         else if (NOTIF_FAILURE == n->severity) {
96                 urgency = NOTIFY_URGENCY_CRITICAL;
97                 timeout = fail_timeout;
98         }
99
100         ssnprintf (summary, sizeof (summary), "collectd %s notification",
101                         (NOTIF_FAILURE == n->severity) ? "FAILURE"
102                                 : (NOTIF_WARNING == n->severity) ? "WARNING"
103                                 : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN");
104
105         notification = notify_notification_new (summary, n->message, NULL
106 #if NOTIFY_CHECK_VERSION (0, 7, 0)
107         );
108 #else
109         , NULL);
110 #endif
111         if (NULL == notification) {
112                 log_err ("Failed to create a new notification.");
113                 return -1;
114         }
115
116         notify_notification_set_urgency (notification, urgency);
117         notify_notification_set_timeout (notification, timeout);
118
119         if (! notify_notification_show (notification, NULL))
120                 log_err ("Failed to display notification.");
121
122         g_object_unref (G_OBJECT (notification));
123         return 0;
124 } /* c_notify */
125
126 static int c_notify_shutdown (void)
127 {
128         plugin_unregister_init ("notify_desktop");
129         plugin_unregister_notification ("notify_desktop");
130         plugin_unregister_shutdown ("notify_desktop");
131
132         if (notify_is_initted ())
133                 notify_uninit ();
134         return 0;
135 } /* c_notify_shutdown */
136
137 static int c_notify_init (void)
138 {
139         char *name         = NULL;
140         char *vendor       = NULL;
141         char *version      = NULL;
142         char *spec_version = NULL;
143
144         if (! notify_init (PACKAGE_STRING)) {
145                 log_err ("Failed to initialize libnotify.");
146                 return -1;
147         }
148
149         if (! notify_get_server_info (&name, &vendor, &version, &spec_version))
150                 log_warn ("Failed to get the notification server info. "
151                                 "Check if you have a notification daemon running.");
152         else {
153                 log_info ("Found notification daemon: %s (%s) %s (spec version %s)",
154                                 name, vendor, version, spec_version);
155                 free (name);
156                 free (vendor);
157                 free (version);
158                 free (spec_version);
159         }
160
161         plugin_register_notification ("notify_desktop", c_notify,
162                         /* user_data = */ NULL);
163         plugin_register_shutdown ("notify_desktop", c_notify_shutdown);
164         return 0;
165 } /* c_notify_init */
166
167 void module_register (void)
168 {
169         plugin_register_complex_config ("notify_desktop", c_notify_config);
170         plugin_register_init ("notify_desktop", c_notify_init);
171         return;
172 } /* module_register */
173
174 /* vim: set sw=4 ts=4 tw=78 noexpandtab : */
175