23
23
class Monitor : Object {
25
static const string GCONF_DIR = "/apps/deja-dup";
26
static const string LAST_RUN_KEY = "/apps/deja-dup/last-run";
27
static const string PERIODIC_KEY = "/apps/deja-dup/periodic";
28
static const string PERIODIC_PERIOD_KEY = "/apps/deja-dup/periodic-period";
29
static const string BACKEND_KEY = "/apps/deja-dup/backend";
30
static const string FILE_PATH_KEY = "/apps/deja-dup/file/path";
31
static const uint32 NM_STATE_CONNECTED = 3;
33
25
static MainLoop loop;
34
26
static uint timeout_id;
36
static bool connected = true;
28
static bool reactive_check;
37
29
static bool testing;
39
31
static bool show_version = false;
46
static dynamic DBus.Object network_manager;
48
static void init_dbus_to_network_manager() throws DBus.Error, GLib.Error
50
//Set up the DBus connection to network manager
51
DBus.Connection conn = DBus.Bus.get(DBus.BusType.SYSTEM);
52
network_manager = conn.get_object(
53
"org.freedesktop.NetworkManager",
54
"/org/freedesktop/NetworkManager",
55
"org.freedesktop.NetworkManager");
57
//Retrieve the network manager connection state.
58
uint32 network_manager_state = network_manager.State;
59
connected = network_manager_state == NM_STATE_CONNECTED;
61
//Dbus signal when the state of the connection is changed.
62
network_manager.StateChanged += network_manager_state_changed;
65
static void network_manager_state_changed(DBus.Object obj, uint32 new_state)
38
static Notify.Notification note;
40
static void network_changed(DejaDup.NetworkManager nm, bool connected)
67
connected = new_state == NM_STATE_CONNECTED;
42
reactive_check = true;
73
static bool is_native()
75
//Detect a remote backend such as Amazon S3 or SSH.
76
bool native_path = true;
44
prepare_next_run(); // in case network manager was blocking us
45
reactive_check = false;
48
static void volume_added(VolumeMonitor vm, Volume vol)
50
reactive_check = true;
51
prepare_next_run(); // in case missing volume was blocking us
52
reactive_check = false;
55
static bool is_ready(out string when)
78
var client = GConf.Client.get_default();
79
string backend_name = client.get_string(BACKEND_KEY);
81
if (backend_name == "s3")
83
else if (backend_name == "file")
85
string path = client.get_string(FILE_PATH_KEY);
86
var backend_file = File.parse_name(path);
87
native_path = backend_file.is_native();
90
catch (GLib.Error e) {
91
warning("%s", e.message);
58
return DejaDup.Backend.get_default().is_ready(out when);
97
65
static bool handle_options(out int status)
144
periodic = client.get_bool(PERIODIC_KEY);
145
last_run_string = client.get_string(LAST_RUN_KEY);
146
period_days = client.get_int(PERIODIC_PERIOD_KEY);
112
periodic = client.get_bool(DejaDup.PERIODIC_KEY);
113
last_run_string = client.get_string(DejaDup.LAST_RUN_KEY);
114
period_days = client.get_int(DejaDup.PERIODIC_PERIOD_KEY);
148
116
catch (Error e) {
149
117
error("%s", e.message);
187
static void notify_delay(string header, string reason)
190
Notify.init(Environment.get_application_name());
191
note = new Notify.Notification(header, reason,
192
"deja-dup-backup", null);
193
note.closed.connect((n) => {note = null;});
196
note.update(header, reason, "deja-dup-backup");
202
warning("%s\n", e.message);
219
206
static bool kickoff()
231
// Now we secretly schedule another kickoff tomorrow, in case something
232
// goes wrong with this run (or user chooses to ignore for now)
233
// If this run is successful, it will change 'last-run' key and this will
234
// get rescheduled anyway.
237
if (!is_native() && !connected) {
238
debug("No connection found. Postponing the backup.");
242
// Don't run right now if an applet is already running
218
if (!reactive_check) {
219
// Now we secretly schedule another kickoff tomorrow, in case something
220
// goes wrong with this run (or user chooses to ignore for now)
221
// If this run is successful, it will change 'last-run' key and this will
222
// get rescheduled anyway.
227
if (!is_ready(out when)) {
228
debug("Postponing the backup.");
230
notify_delay(_("Scheduled backup delayed"), when);
234
// Don't run right now if an instance is already running
235
if (pid == (Pid)0 && !DejaDup.test_bus_claimed("operation")) {
245
237
string[] argv = new string[3];
246
238
argv[0] = "deja-dup";
314
306
var client = GConf.Client.get_default();
317
client.add_dir(GCONF_DIR, GConf.ClientPreloadType.NONE);
318
client.notify_add(LAST_RUN_KEY, prepare_next_run);
319
client.notify_add(PERIODIC_KEY, prepare_next_run);
320
client.notify_add(PERIODIC_PERIOD_KEY, prepare_next_run);
309
client.add_dir(DejaDup.GCONF_DIR, GConf.ClientPreloadType.NONE);
310
client.notify_add(DejaDup.LAST_RUN_KEY, prepare_next_run);
311
client.notify_add(DejaDup.PERIODIC_KEY, prepare_next_run);
312
client.notify_add(DejaDup.PERIODIC_PERIOD_KEY, prepare_next_run);
322
314
catch (Error e) {
323
315
warning("%s\n", e.message);
327
319
static int main(string[] args)
330
init_dbus_to_network_manager();
333
warning("%s\n\n%s", e.message, "Failed to initialize DBus\n");
336
321
GLib.Intl.textdomain(Config.GETTEXT_PACKAGE);
337
322
GLib.Intl.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALE_DIR);
338
323
GLib.Intl.bind_textdomain_codeset(Config.GETTEXT_PACKAGE, "UTF-8");
340
325
// Translators: Monitor in this sense means something akin to 'watcher', not
341
// a computer monitor. This program acts like a daemon that kicks off
326
// a computer screen. This program acts like a daemon that kicks off
342
327
// backups at scheduled times.
343
328
GLib.Environment.set_application_name(_("Déjà Dup Monitor"));
355
340
if (!handle_options(out status))
343
DejaDup.initialize();
344
DejaDup.NetworkManager.get().changed.connect(network_changed);
345
VolumeMonitor.get().volume_added.connect(volume_added);
358
347
loop = new MainLoop(null, false);
360
349
prepare_next_run();