Merge lp:~mterry/deja-dup/nag into lp:deja-dup/24

Proposed by Michael Terry on 2012-08-20
Status: Merged
Merged at revision: 1379
Proposed branch: lp:~mterry/deja-dup/nag
Merge into: lp:deja-dup/24
Prerequisite: lp:~mterry/deja-dup/verify
Diff against target: 1485 lines (+521/-156)
14 files modified
common/CommonUtils.vala (+50/-3)
common/Operation.vala (+18/-7)
common/OperationVerify.vala (+24/-0)
common/ToolPlugin.vala (+1/-0)
data/org.gnome.DejaDup.gschema.xml.in (+6/-1)
deja-dup/Assistant.vala (+13/-3)
deja-dup/AssistantBackup.vala (+4/-1)
deja-dup/AssistantOperation.vala (+118/-22)
po/deja-dup.pot (+156/-108)
tests/runner/mock/duplicity (+12/-0)
tests/runner/runner.vala (+39/-9)
tests/scripts/nag.test (+58/-0)
tools/duplicity/DuplicityInstance.vala (+4/-1)
tools/duplicity/DuplicityJob.vala (+18/-1)
To merge this branch: bzr merge lp:~mterry/deja-dup/nag
Reviewer Review Type Date Requested Status
Robert Bruce Park (community) Approve on 2012-08-21
Ken VanDine 2012-08-20 Pending
Review via email: mp+120312@code.launchpad.net

Description of the change

Adds a nag page to occasionally test the verify check without any cache/saved-passwords.

To test:

test/interactive
deja-dup-preferences (set up as needed)
gsettings set org.gnome.DejaDup nag-check '1970-01-01T00:32:08.916885Z'
deja-dup --backup

To post a comment you must log in.
Robert Bruce Park (robru) wrote :

The nag screen looks good, but after verifying the backup it just disappears, it does not give any indication of whether the verification was successful or not. The window should stay open and then say whether it was successful or not, and then allow the user to acknowledge and close the window.

review: Needs Fixing
Robert Bruce Park (robru) wrote :

Also, why did you delete that .pot file? Seems unrelated to the rest of this branch, kinda sloppy.

lp:~mterry/deja-dup/nag updated on 2012-08-21
1379. By Michael Terry on 2012-08-21

add back dropped pot file, whoops

1380. By Michael Terry on 2012-08-21

leave window up when we just tested the restore and asked for the password

1381. By Michael Terry on 2012-08-21

merge from trunk

1382. By Michael Terry on 2012-08-21

uncomment deleting the test directory; that wasn't supposed to be committed

1383. By Michael Terry on 2012-08-21

same for dropping valac-0.18 support

1384. By Michael Terry on 2012-08-21

try again to fix deja-dup.pot

Michael Terry (mterry) wrote :

OK, now the window stays up on successful backup+nag. On error, an error window will appear, as it would before.

As for the deja-dup.pot file, it was an accidental deletion. I tried to update it, not delete it, but apparently screwed that up.

Robert Bruce Park (robru) wrote :

Looks good now!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'common/CommonUtils.vala'
2--- common/CommonUtils.vala 2012-06-21 15:45:56 +0000
3+++ common/CommonUtils.vala 2012-08-21 01:36:28 +0000
4@@ -30,6 +30,7 @@
5 public const string LAST_BACKUP_KEY = "last-backup";
6 public const string LAST_RESTORE_KEY = "last-restore";
7 public const string PROMPT_CHECK_KEY = "prompt-check";
8+public const string NAG_CHECK_KEY = "nag-check";
9 public const string PERIODIC_KEY = "periodic";
10 public const string PERIODIC_PERIOD_KEY = "periodic-period";
11 public const string DELETE_AFTER_KEY = "delete-after";
12@@ -209,11 +210,11 @@
13 run_deja_dup("--prompt");
14 }
15
16-public void update_prompt_time(bool cancel = false)
17+private void update_time_key(string key, bool cancel)
18 {
19 var settings = DejaDup.get_settings();
20
21- if (settings.get_string(PROMPT_CHECK_KEY) == "disabled")
22+ if (settings.get_string(key) == "disabled")
23 return; // never re-enable
24
25 string cur_time_str;
26@@ -226,7 +227,53 @@
27 cur_time_str = cur_time.to_iso8601();
28 }
29
30- settings.set_string(PROMPT_CHECK_KEY, cur_time_str);
31+ settings.set_string(key, cur_time_str);
32+}
33+
34+public void update_prompt_time(bool cancel = false)
35+{
36+ update_time_key(PROMPT_CHECK_KEY, cancel);
37+}
38+
39+public void update_nag_time(bool cancel = false)
40+{
41+ update_time_key(NAG_CHECK_KEY, cancel);
42+}
43+
44+// In seconds
45+public int get_nag_delay()
46+{
47+ TimeSpan span = 0;
48+ if (DejaDup.in_testing_mode())
49+ span = TimeSpan.MINUTE * 2;
50+ else
51+ span = TimeSpan.DAY * 30 * 2;
52+ return (int)(span / TimeSpan.SECOND);
53+}
54+
55+// This makes the check of whether we should remind user about their password.
56+public bool is_nag_time()
57+{
58+ var settings = DejaDup.get_settings();
59+ var nag = settings.get_string(NAG_CHECK_KEY);
60+ var last_run_string = last_run_date(TimestampType.BACKUP);
61+
62+ if (nag == "disabled" || last_run_string == "")
63+ return false;
64+ else if (nag == "") {
65+ update_nag_time();
66+ return false;
67+ }
68+
69+ TimeVal last_check_tval = TimeVal();
70+ if (!last_check_tval.from_iso8601(nag))
71+ return false;
72+
73+ var last_check = new DateTime.from_timeval_local(last_check_tval);
74+ last_check = last_check.add_seconds(get_nag_delay());
75+
76+ var now = new DateTime.now_local();
77+ return (last_check.compare(now) <= 0);
78 }
79
80 public string get_folder_key(SimpleSettings settings, string key)
81
82=== modified file 'common/Operation.vala'
83--- common/Operation.vala 2012-08-13 19:59:00 +0000
84+++ common/Operation.vala 2012-08-21 01:36:28 +0000
85@@ -41,6 +41,7 @@
86 public signal void question(string title, string msg);
87 public signal void is_full(bool first);
88
89+ public bool use_cached_password {get; protected set; default = true;}
90 public bool needs_password {get; set;}
91 public Backend backend {get; private set;}
92 public bool use_progress {get {return (job.flags & ToolJob.Flags.NO_PROGRESS) == 0;}
93@@ -91,6 +92,7 @@
94 protected string passphrase;
95 bool finished = false;
96 string saved_detail = null;
97+ Operation chained_op = null;
98 construct
99 {
100 backend = Backend.get_default();
101@@ -168,12 +170,18 @@
102
103 public void cancel()
104 {
105- job.cancel();
106+ if (chained_op != null)
107+ chained_op.cancel();
108+ else
109+ job.cancel();
110 }
111
112 public void stop()
113 {
114- job.stop();
115+ if (chained_op != null)
116+ chained_op.stop();
117+ else
118+ job.stop();
119 }
120
121 protected virtual void connect_to_job()
122@@ -246,23 +254,26 @@
123 * Sometimes an operation wants to chain to a separate operation.
124 * Here is the glue to make that happen.
125 */
126- subop.ref();
127+ assert(chained_op == null);
128+
129+ chained_op = subop;
130 subop.done.connect((s, c, d) => {
131 done(s, c, combine_details(saved_detail, d));
132- subop.unref();
133+ chained_op = null;
134 });
135 subop.raise_error.connect((e, d) => {raise_error(e, d);});
136 subop.progress.connect((p) => {progress(p);});
137 subop.passphrase_required.connect(() => {
138+ needs_password = true;
139 passphrase_required();
140- subop.needs_password = needs_password;
141- subop.passphrase = passphrase;
142+ if (!needs_password)
143+ subop.set_passphrase(passphrase);
144 });
145 subop.question.connect((t, m) => {question(t, m);});
146
147+ use_cached_password = subop.use_cached_password;
148 saved_detail = combine_details(saved_detail, detail);
149 subop.set_state(get_state());
150- job = subop.job;
151
152 action_desc_changed(desc);
153 progress(0);
154
155=== modified file 'common/OperationVerify.vala'
156--- common/OperationVerify.vala 2012-08-10 18:33:29 +0000
157+++ common/OperationVerify.vala 2012-08-21 01:36:28 +0000
158@@ -28,19 +28,40 @@
159 {
160 File metadir;
161 File destdir;
162+ bool nag;
163
164 public OperationVerify() {
165 Object(mode: ToolJob.Mode.RESTORE);
166 }
167
168+ construct {
169+ // Should we nag user about password, etc? What this really means is that
170+ // we try to do our normal verification routine in as close an emulation
171+ // to a fresh restore after a disaster as possible. So fresh cache, no
172+ // saved password, etc. We do *not* explicitly unmount the backend,
173+ // because we may not be the only consumers.
174+ if (is_nag_time()) {
175+ use_cached_password = false;
176+ nag = true;
177+ }
178+ }
179+
180 public async override void start(bool try_claim_bus = true)
181 {
182+ if (nag) {
183+ var fake_state = new State();
184+ fake_state.backend = backend.clone();
185+ set_state(fake_state);
186+ }
187 action_desc_changed(_("Verifying backup…"));
188 yield base.start(try_claim_bus);
189 }
190
191 protected override void connect_to_job()
192 {
193+ if (nag)
194+ job.flags |= ToolJob.Flags.NO_CACHE;
195+
196 string cachedir = Environment.get_user_cache_dir();
197 metadir = File.new_for_path(Path.build_filename(cachedir, Config.PACKAGE, "metadata"));
198 job.restore_files.append(metadir);
199@@ -73,6 +94,9 @@
200 raise_error(_("Your backup appears to be corrupted. You should delete the backup and try again."), null);
201 success = false;
202 }
203+
204+ if (nag)
205+ update_nag_time();
206 }
207
208 new RecursiveDelete(metadir).start();
209
210=== modified file 'common/ToolPlugin.vala'
211--- common/ToolPlugin.vala 2012-04-30 00:23:37 +0000
212+++ common/ToolPlugin.vala 2012-08-21 01:36:28 +0000
213@@ -55,6 +55,7 @@
214
215 public enum Flags {
216 NO_PROGRESS,
217+ NO_CACHE,
218 }
219 public Flags flags {get; set;}
220
221
222=== modified file 'data/org.gnome.DejaDup.gschema.xml.in'
223--- data/org.gnome.DejaDup.gschema.xml.in 2012-06-21 15:45:56 +0000
224+++ data/org.gnome.DejaDup.gschema.xml.in 2012-08-21 01:36:28 +0000
225@@ -47,9 +47,14 @@
226 </key>
227 <key name="prompt-check" type="s">
228 <default>''</default>
229- <_summary>The first time Déjà Dup checked whether it should prompt about backing up</_summary>
230+ <_summary>The last time Déjà Dup checked whether it should prompt about backing up</_summary>
231 <_description>When a user logs in, the Déjà Dup monitor checks whether it should prompt about backing up. This is used to increase discoverability for users that don’t know about backups. This time should be either ‘disabled’ to turn off this check or in ISO 8601 format.</_description>
232 </key>
233+ <key name="nag-check" type="s">
234+ <default>''</default>
235+ <_summary>The last time Déjà Dup checked whether it should prompt about your password</_summary>
236+ <_description>In order to prevent you from forgetting your passwords, Déjà Dup will occasionally notify you to confirm the password. This time should be either ‘disabled’ to turn off this check or in ISO 8601 format.</_description>
237+ </key>
238 <key name="delete-after" type="i">
239 <default>0</default>
240 <_summary>How long to keep backup files</_summary>
241
242=== modified file 'deja-dup/Assistant.vala'
243--- deja-dup/Assistant.vala 2012-08-06 22:41:13 +0000
244+++ deja-dup/Assistant.vala 2012-08-21 01:36:28 +0000
245@@ -39,7 +39,7 @@
246 public bool last_op_was_back {get; private set; default = false;}
247
248 public enum Type {
249- NORMAL, INTERRUPT, SUMMARY, PROGRESS, FINISH
250+ NORMAL, INTERRUPT, CHECK, SUMMARY, PROGRESS, FINISH
251 }
252
253 Gtk.Label header_title;
254@@ -165,6 +165,11 @@
255 go_forward();
256 }
257
258+ static bool is_interrupt_type(Type type)
259+ {
260+ return type == Type.INTERRUPT || type == Type.CHECK;
261+ }
262+
263 public void go_back()
264 {
265 weak List<PageInfo> next;
266@@ -172,7 +177,7 @@
267 next = interrupted.prev;
268 else {
269 next = current.prev;
270- while (next != null && next.data.type == Type.INTERRUPT)
271+ while (next != null && is_interrupt_type(next.data.type))
272 next = next.prev;
273 }
274
275@@ -194,7 +199,7 @@
276 }
277 else {
278 next = (current == null) ? infos : current.next;
279- while (next != null && next.data.type == Type.INTERRUPT)
280+ while (next != null && is_interrupt_type(next.data.type))
281 next = next.next;
282 }
283
284@@ -309,6 +314,11 @@
285 forward_text = _("Co_ntinue");
286 }
287 break;
288+ case Type.CHECK:
289+ show_close = true;
290+ show_forward = true;
291+ forward_text = C_("verb", "_Test");
292+ break;
293 case Type.PROGRESS:
294 show_cancel = true;
295 show_resume = true;
296
297=== modified file 'deja-dup/AssistantBackup.vala'
298--- deja-dup/AssistantBackup.vala 2012-04-10 02:22:06 +0000
299+++ deja-dup/AssistantBackup.vala 2012-08-21 01:36:28 +0000
300@@ -91,8 +91,11 @@
301 else {
302 set_page_title(page, _("Backup Finished"));
303
304+ // Also leave ourselves up if we just finished a restore test.
305+ if (nagged)
306+ summary_label.label = _("Your files were successfully backed up and tested.");
307 // If we don't have a special message to show the user, just bail.
308- if (!detail_widget.get_visible())
309+ else if (!detail_widget.get_visible())
310 Idle.add(() => {do_close(); return false;});
311 }
312 }
313
314=== modified file 'deja-dup/AssistantOperation.vala'
315--- deja-dup/AssistantOperation.vala 2012-08-06 22:41:13 +0000
316+++ deja-dup/AssistantOperation.vala 2012-08-21 01:36:28 +0000
317@@ -45,11 +45,14 @@
318 protected StatusIcon status_icon;
319 protected bool succeeded = false;
320
321+ Gtk.Entry nag_entry;
322 Gtk.Entry encrypt_entry;
323 Gtk.Entry encrypt_confirm_entry;
324 Gtk.RadioButton encrypt_enabled;
325 Gtk.CheckButton encrypt_remember;
326 protected Gtk.Widget password_page {get; private set;}
327+ protected Gtk.Widget nag_page {get; private set;}
328+ protected bool nagged;
329 List<Gtk.Widget> first_password_widgets;
330 MainLoop password_ask_loop;
331 MainLoop password_find_loop;
332@@ -94,6 +97,7 @@
333 add_setup_pages();
334 add_confirm_page();
335 add_password_page();
336+ add_nag_page();
337 add_question_page();
338 add_progress_page();
339 add_summary_page();
340@@ -384,6 +388,59 @@
341 return page;
342 }
343
344+ protected Gtk.Widget make_nag_page()
345+ {
346+ int rows = 0;
347+ Gtk.Widget w, label;
348+
349+ var page = new Gtk.Grid();
350+ page.set("row-spacing", 6,
351+ "column-spacing", 6,
352+ "border-width", 12);
353+
354+ w = new Gtk.Label(_("In order to check that you will be able to retrieve your files in the case of an emergency, please enter your encryption password again to perform a brief restore test."));
355+ w.set("xalign", 0.0f,
356+ "max-width-chars", 25,
357+ "wrap", true);
358+ page.attach(w, 0, rows, 3, 1);
359+ w.hide();
360+ ++rows;
361+
362+ w = new Gtk.Entry();
363+ w.set("visibility", false,
364+ "hexpand", true,
365+ "activates-default", true);
366+ ((Gtk.Entry)w).changed.connect((entry) => {check_nag_validity();});
367+ label = new Gtk.Label(_("E_ncryption password"));
368+ label.set("mnemonic-widget", w,
369+ "use-underline", true,
370+ "xalign", 1.0f);
371+ page.attach(label, 1, rows, 1, 1);
372+ page.attach(w, 2, rows, 1, 1);
373+ nag_entry = w as Gtk.Entry;
374+ ++rows;
375+
376+ w = new Gtk.CheckButton.with_mnemonic(_("_Show password"));
377+ ((Gtk.CheckButton)w).toggled.connect((button) => {
378+ nag_entry.visibility = button.get_active();
379+ });
380+ page.attach(w, 2, rows, 1, 1);
381+ ++rows;
382+
383+ w = new Gtk.CheckButton.with_mnemonic(_("Test every two _months"));
384+ page.attach(w, 0, rows, 3, 1);
385+ w.hide();
386+ ((Gtk.CheckButton)w).active = true;
387+ w.vexpand = true;
388+ w.valign = Gtk.Align.END;
389+ ((Gtk.CheckButton)w).toggled.connect((button) => {
390+ DejaDup.update_nag_time(!button.get_active());
391+ });
392+ ++rows;
393+
394+ return page;
395+ }
396+
397 protected Gtk.Widget make_question_page()
398 {
399 int rows = 0;
400@@ -462,6 +519,14 @@
401 password_page = page;
402 }
403
404+ void add_nag_page()
405+ {
406+ var page = make_nag_page();
407+ append_page(page, Type.CHECK);
408+ set_page_title(page, _("Restore Test"));
409+ nag_page = page;
410+ }
411+
412 void add_question_page()
413 {
414 var page = make_question_page();
415@@ -588,7 +653,7 @@
416 else if (op == null)
417 do_apply.begin();
418 }
419- else if (page == password_page)
420+ else if (page == password_page || page == nag_page)
421 set_header_icon(Gtk.Stock.DIALOG_AUTHENTICATION);
422 }
423
424@@ -677,8 +742,8 @@
425
426 protected void get_passphrase()
427 {
428- // DEJA_DUP_TESTING only set when we are in test suite
429- if (!searched_for_passphrase && !DejaDup.in_testing_mode()) {
430+ if (!searched_for_passphrase && !DejaDup.in_testing_mode() &&
431+ op.use_cached_password) {
432 // First, try user's keyring
433 GnomeKeyring.find_password(PASSPHRASE_SCHEMA,
434 found_passphrase,
435@@ -730,14 +795,31 @@
436 set_page_title(password_page, _("Require Password?"));
437 else
438 set_page_title(password_page, _("Encryption Password Needed"));
439- foreach (Gtk.Widget w in first_password_widgets) {
440+
441+ foreach (Gtk.Widget w in first_password_widgets)
442 w.visible = first;
443- }
444+
445 check_password_validity();
446 encrypt_entry.select_region(0, -1);
447 encrypt_entry.grab_focus();
448 }
449
450+ void check_nag_validity()
451+ {
452+ var passphrase = nag_entry.get_text();
453+ if (passphrase == "")
454+ allow_forward(false);
455+ else
456+ allow_forward(true);
457+ }
458+
459+ void configure_nag_page()
460+ {
461+ check_nag_validity();
462+ nag_entry.set_text("");
463+ nag_entry.grab_focus();
464+ }
465+
466 void stop_password_loop(Assistant dlg, int resp)
467 {
468 Idle.add(() => {
469@@ -751,8 +833,15 @@
470 protected void ask_passphrase(bool first = false)
471 {
472 op.needs_password = true;
473- interrupt(password_page);
474- configure_password_page(first);
475+ if (op.use_cached_password) {
476+ interrupt(password_page);
477+ configure_password_page(first);
478+ }
479+ else {
480+ interrupt(nag_page);
481+ configure_nag_page();
482+ nagged = true;
483+ }
484 force_visible(false);
485 // pause until we can provide password by entering new main loop
486 password_ask_loop = new MainLoop(null);
487@@ -764,22 +853,29 @@
488 {
489 var passphrase = "";
490
491- if (encrypt_enabled.active) {
492- passphrase = encrypt_entry.get_text().strip();
493+ if (op.use_cached_password) {
494+ if (encrypt_enabled.active) {
495+ passphrase = encrypt_entry.get_text().strip();
496+ if (passphrase == "") // all whitespace password? allow it...
497+ passphrase = encrypt_entry.get_text();
498+ }
499+
500+ if (passphrase != "") {
501+ // Save it
502+ if (encrypt_remember.active) {
503+ GnomeKeyring.store_password(PASSPHRASE_SCHEMA,
504+ GnomeKeyring.DEFAULT,
505+ _("Backup encryption password"),
506+ passphrase, save_password_callback,
507+ "owner", Config.PACKAGE,
508+ "type", "passphrase");
509+ }
510+ }
511+ }
512+ else {
513+ passphrase = nag_entry.get_text().strip();
514 if (passphrase == "") // all whitespace password? allow it...
515- passphrase = encrypt_entry.get_text();
516- }
517-
518- if (passphrase != "") {
519- // Save it
520- if (encrypt_remember.active) {
521- GnomeKeyring.store_password(PASSPHRASE_SCHEMA,
522- GnomeKeyring.DEFAULT,
523- _("Backup encryption password"),
524- passphrase, save_password_callback,
525- "owner", Config.PACKAGE,
526- "type", "passphrase");
527- }
528+ passphrase = nag_entry.get_text();
529 }
530
531 op.set_passphrase(passphrase);
532
533=== modified file 'po/deja-dup.pot'
534--- po/deja-dup.pot 2012-07-20 23:42:14 +0000
535+++ po/deja-dup.pot 2012-08-21 01:36:28 +0000
536@@ -8,7 +8,7 @@
537 msgstr ""
538 "Project-Id-Version: PACKAGE VERSION\n"
539 "Report-Msgid-Bugs-To: mike@mterry.name\n"
540-"POT-Creation-Date: 2012-07-20 19:31-0400\n"
541+"POT-Creation-Date: 2012-08-20 21:34-0400\n"
542 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
543 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
544 "Language-Team: LANGUAGE <LL@li.org>\n"
545@@ -33,7 +33,7 @@
546 #. context is itself a reference to both the underlying command line tool
547 #. "duplicity" and the act of duplicating data for backup. As a whole, the
548 #. phrase "Déjà Dup" may not be very translatable.
549-#: ../data/deja-dup.desktop.in.h:2 ../common/CommonUtils.vala:89
550+#: ../data/deja-dup.desktop.in.h:2 ../common/CommonUtils.vala:90
551 #: ../deja-dup/main.vala:78 ../preferences/Preferences.vala:88
552 #, c-format
553 msgid "Déjà Dup Backup Tool"
554@@ -154,7 +154,7 @@
555
556 #: ../data/org.gnome.DejaDup.gschema.xml.in.h:18
557 msgid ""
558-"The first time Déjà Dup checked whether it should prompt about backing up"
559+"The last time Déjà Dup checked whether it should prompt about backing up"
560 msgstr ""
561
562 #: ../data/org.gnome.DejaDup.gschema.xml.in.h:19
563@@ -166,161 +166,173 @@
564 msgstr ""
565
566 #: ../data/org.gnome.DejaDup.gschema.xml.in.h:20
567+msgid ""
568+"The last time Déjà Dup checked whether it should prompt about your password"
569+msgstr ""
570+
571+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:21
572+msgid ""
573+"In order to prevent you from forgetting your passwords, Déjà Dup will "
574+"occasionally notify you to confirm the password. This time should be either "
575+"‘disabled’ to turn off this check or in ISO 8601 format."
576+msgstr ""
577+
578+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:22
579 msgid "How long to keep backup files"
580 msgstr ""
581
582-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:21
583+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:23
584 msgid ""
585 "The number of days to keep backup files on the backup location. A value of 0 "
586 "means forever. This is a minimum number of days; the files may be kept "
587 "longer."
588 msgstr ""
589
590-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:22
591+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:24
592 msgid "How long to wait between full backups"
593 msgstr ""
594
595-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:23
596+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:25
597 msgid ""
598 "Déjà Dup needs to occasionally make fresh full backups. This is the number "
599 "of days to wait between full backups."
600 msgstr ""
601
602-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:24
603+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:26
604 msgid "Type of location to store backup"
605 msgstr ""
606
607-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:25
608+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:27
609 msgid ""
610 "The type of backup location. If ‘auto’, a default will be chosen based on "
611 "what is available."
612 msgstr ""
613
614-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:26
615+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:28
616 msgid "Amazon S3 Access Key ID"
617 msgstr ""
618
619-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:27
620+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:29
621 msgid "Your Amazon S3 Access Key Identifier. This acts as your S3 username."
622 msgstr ""
623
624-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:28
625+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:30
626 msgid "The Amazon S3 bucket name to use"
627 msgstr ""
628
629-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:29
630+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:31
631 msgid ""
632 "Which Amazon S3 bucket to store files in. This does not need to exist "
633 "already. Only legal hostname strings are valid."
634 msgstr ""
635
636 #. Left this way for historical reasons, should be '$HOSTNAME'. See convert_s3_folder_to_hostname()
637-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:31
638+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:33
639 msgid "The Amazon S3 folder"
640 msgstr ""
641
642-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:32
643+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:34
644 msgid ""
645 "An optional folder name to store files in. This folder will be created in "
646 "the chosen bucket."
647 msgstr ""
648
649-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:33
650+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:35
651 msgid "The Rackspace Cloud Files container"
652 msgstr ""
653
654-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:34
655+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:36
656 msgid ""
657 "Which Rackspace Cloud Files container to store files in. This does not need "
658 "to exist already. Only legal hostname strings are valid."
659 msgstr ""
660
661-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:35
662+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:37
663 msgid "Your Rackspace username"
664 msgstr ""
665
666-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:36
667+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:38
668 msgid "This is your username for the Rackspace Cloud Files service."
669 msgstr ""
670
671-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:37
672+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:39
673 msgid "The Ubuntu One folder"
674 msgstr ""
675
676-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:38
677+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:40
678 msgid ""
679 "The folder name to store files in. If ‘$HOSTNAME’, it will default to a "
680 "folder based on the name of the computer."
681 msgstr ""
682
683-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:39
684+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:41
685 #: ../deja-dup/AssistantRestore.vala:221 ../preferences/Preferences.vala:151
686 msgid "Backup location"
687 msgstr ""
688
689-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:40
690+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:42
691 msgid "Location in which to hold the backup files."
692 msgstr ""
693
694-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:41
695+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:43
696 msgid "Folder type"
697 msgstr ""
698
699-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:42
700+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:44
701 msgid ""
702 "Whether the backup location is a mounted external volume or a normal folder."
703 msgstr ""
704
705-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:43
706+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:45
707 msgid "Relative path under the external volume"
708 msgstr ""
709
710-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:44
711+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:46
712 msgid ""
713 "If the backup location is on an external volume, this is the path of the "
714 "folder on that volume."
715 msgstr ""
716
717-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:45
718+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:47
719 msgid "Unique ID of the external volume"
720 msgstr ""
721
722-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:46
723+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:48
724 msgid ""
725 "If the backup location is on an external volume, this is its unique "
726 "filesystem identifier."
727 msgstr ""
728
729-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:47
730+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:49
731 msgid "Full name of the external volume"
732 msgstr ""
733
734-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:48
735+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:50
736 msgid ""
737 "If the backup location is on an external volume, this is the volume’s longer "
738 "descriptive name."
739 msgstr ""
740
741-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:49
742+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:51
743 msgid "Short name of the external volume"
744 msgstr ""
745
746-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:50
747+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:52
748 msgid ""
749 "If the backup location is on an external volume, this is the volume’s "
750 "shorter name."
751 msgstr ""
752
753-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:51
754+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:53
755 msgid "Icon of the external volume"
756 msgstr ""
757
758-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:52
759+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:54
760 msgid ""
761 "If the backup location is on an external volume, this is the volume’s icon."
762 msgstr ""
763
764-#: ../data/org.gnome.DejaDup.gschema.xml.in.h:53
765+#: ../data/org.gnome.DejaDup.gschema.xml.in.h:55
766 msgid "Obsolete"
767 msgstr ""
768
769@@ -328,7 +340,7 @@
770 msgid "Folder"
771 msgstr ""
772
773-#: ../data/ui/restore-missing.ui.h:2 ../deja-dup/AssistantOperation.vala:175
774+#: ../data/ui/restore-missing.ui.h:2 ../deja-dup/AssistantOperation.vala:179
775 msgid "Scanning…"
776 msgstr ""
777
778@@ -354,7 +366,7 @@
779
780 #. Translators: %2$s is the name of a removable drive, %1$s is a folder
781 #. on that removable drive.
782-#: ../common/BackendFile.vala:135 ../common/CommonUtils.vala:434
783+#: ../common/BackendFile.vala:135 ../common/CommonUtils.vala:481
784 #, c-format
785 msgid "%1$s on %2$s"
786 msgstr ""
787@@ -454,86 +466,96 @@
788 msgid "_Remember secret access key"
789 msgstr ""
790
791-#: ../common/BackendU1.vala:166 ../widgets/ConfigLocation.vala:186
792+#: ../common/BackendU1.vala:170 ../widgets/ConfigLocation.vala:186
793 msgid "Ubuntu One"
794 msgstr ""
795
796 #. Translators: %s is a folder.
797-#: ../common/BackendU1.vala:169
798+#: ../common/BackendU1.vala:173
799 #, c-format
800 msgid "%s on Ubuntu One"
801 msgstr ""
802
803-#: ../common/BackendU1.vala:236
804+#: ../common/BackendU1.vala:240
805 msgid "Connect to Ubuntu One"
806 msgstr ""
807
808-#: ../common/BackendU1.vala:237
809+#: ../common/BackendU1.vala:241
810 msgid "Sign into Ubuntu One…"
811 msgstr ""
812
813-#: ../common/CommonUtils.vala:354
814+#: ../common/CommonUtils.vala:401
815 #, c-format
816 msgid "Could not find backup tool in %s. Your installation is incomplete."
817 msgstr ""
818
819-#: ../common/CommonUtils.vala:356
820+#: ../common/CommonUtils.vala:403
821 msgid "Could not load backup tool. Your installation is incomplete."
822 msgstr ""
823
824-#: ../common/CommonUtils.vala:362
825+#: ../common/CommonUtils.vala:409
826 msgid "Backup tool is broken. Your installation is incomplete."
827 msgstr ""
828
829-#: ../common/CommonUtils.vala:384
830+#: ../common/CommonUtils.vala:431
831 msgid "Could not start backup tool"
832 msgstr ""
833
834 #. Translators: this is the home folder and %s is the user's username
835-#: ../common/CommonUtils.vala:485
836+#: ../common/CommonUtils.vala:532
837 #, c-format
838 msgid "Home (%s)"
839 msgstr ""
840
841 #. Translators: this is the home folder
842-#: ../common/CommonUtils.vala:490
843+#: ../common/CommonUtils.vala:537
844 msgid "Home"
845 msgstr ""
846
847 #. Translators: this is the trash folder
848-#: ../common/CommonUtils.vala:495
849+#: ../common/CommonUtils.vala:542
850 msgid "Trash"
851 msgstr ""
852
853+#: ../common/OperationBackup.vala:42 ../common/OperationVerify.vala:56
854+msgid "Verifying backup…"
855+msgstr ""
856+
857 #: ../common/OperationRestore.vala:51
858 msgid "Restoring files…"
859 msgstr ""
860
861-#: ../common/Operation.vala:60
862+#: ../common/OperationVerify.vala:94
863+msgid ""
864+"Your backup appears to be corrupted. You should delete the backup and try "
865+"again."
866+msgstr ""
867+
868+#: ../common/Operation.vala:61
869 msgid "Backing up…"
870 msgstr ""
871
872-#: ../common/Operation.vala:62 ../deja-dup/AssistantRestore.vala:484
873+#: ../common/Operation.vala:63 ../deja-dup/AssistantRestore.vala:484
874 msgid "Restoring…"
875 msgstr ""
876
877-#: ../common/Operation.vala:64
878+#: ../common/Operation.vala:65
879 msgid "Checking for backups…"
880 msgstr ""
881
882-#: ../common/Operation.vala:66
883+#: ../common/Operation.vala:67
884 msgid "Listing files…"
885 msgstr ""
886
887-#: ../common/Operation.vala:68 ../common/Operation.vala:100
888-#: ../tools/duplicity/DuplicityJob.vala:386
889-#: ../tools/duplicity/DuplicityJob.vala:393
890-#: ../tools/duplicity/DuplicityJob.vala:412
891-#: ../tools/duplicity/DuplicityJob.vala:417
892+#: ../common/Operation.vala:69 ../common/Operation.vala:103
893+#: ../tools/duplicity/DuplicityJob.vala:400
894+#: ../tools/duplicity/DuplicityJob.vala:407
895+#: ../tools/duplicity/DuplicityJob.vala:426
896+#: ../tools/duplicity/DuplicityJob.vala:431
897 msgid "Preparing…"
898 msgstr ""
899
900-#: ../common/Operation.vala:237
901+#: ../common/Operation.vala:295
902 msgid "Another backup operation is already running"
903 msgstr ""
904
905@@ -571,69 +593,90 @@
906 msgid "Backup Finished"
907 msgstr ""
908
909-#: ../deja-dup/AssistantBackup.vala:100
910+#: ../deja-dup/AssistantBackup.vala:96
911+msgid "Your files were successfully backed up and tested."
912+msgstr ""
913+
914+#: ../deja-dup/AssistantBackup.vala:103
915 msgid "Backing Up…"
916 msgstr ""
917
918-#: ../deja-dup/AssistantOperation.vala:174
919+#: ../deja-dup/AssistantOperation.vala:178
920 msgid "Scanning:"
921 msgstr ""
922
923-#: ../deja-dup/AssistantOperation.vala:256
924+#: ../deja-dup/AssistantOperation.vala:260
925 msgid "_Details"
926 msgstr ""
927
928-#: ../deja-dup/AssistantOperation.vala:304
929+#: ../deja-dup/AssistantOperation.vala:308
930 msgid "_Allow restoring without a password"
931 msgstr ""
932
933-#: ../deja-dup/AssistantOperation.vala:310
934+#: ../deja-dup/AssistantOperation.vala:314
935 msgid "_Password-protect your backup"
936 msgstr ""
937
938-#: ../deja-dup/AssistantOperation.vala:324
939+#: ../deja-dup/AssistantOperation.vala:328
940 #, c-format
941 msgid ""
942 "You will need your password to restore your files. You might want to write "
943 "it down."
944 msgstr ""
945
946-#: ../deja-dup/AssistantOperation.vala:339
947+#: ../deja-dup/AssistantOperation.vala:343
948+#: ../deja-dup/AssistantOperation.vala:414
949 msgid "E_ncryption password"
950 msgstr ""
951
952-#: ../deja-dup/AssistantOperation.vala:356
953+#: ../deja-dup/AssistantOperation.vala:360
954 msgid "Confir_m password"
955 msgstr ""
956
957-#: ../deja-dup/AssistantOperation.vala:369
958+#: ../deja-dup/AssistantOperation.vala:373
959+#: ../deja-dup/AssistantOperation.vala:423
960 msgid "_Show password"
961 msgstr ""
962
963-#: ../deja-dup/AssistantOperation.vala:378
964+#: ../deja-dup/AssistantOperation.vala:382
965 #: ../deja-dup/MountOperationAssistant.vala:40
966 msgid "_Remember password"
967 msgstr ""
968
969-#: ../deja-dup/AssistantOperation.vala:447
970+#: ../deja-dup/AssistantOperation.vala:401
971+msgid ""
972+"In order to check that you will be able to retrieve your files in the case "
973+"of an emergency, please enter your encryption password again to perform a "
974+"brief restore test."
975+msgstr ""
976+
977+#: ../deja-dup/AssistantOperation.vala:430
978+msgid "Test every two _months"
979+msgstr ""
980+
981+#: ../deja-dup/AssistantOperation.vala:504
982 msgid "Summary"
983 msgstr ""
984
985-#: ../deja-dup/AssistantOperation.vala:537
986-#: ../tools/duplicity/DuplicityJob.vala:694
987-#: ../tools/duplicity/DuplicityJob.vala:1076
988+#: ../deja-dup/AssistantOperation.vala:526
989+msgid "Restore Test"
990+msgstr ""
991+
992+#: ../deja-dup/AssistantOperation.vala:602
993+#: ../tools/duplicity/DuplicityJob.vala:710
994+#: ../tools/duplicity/DuplicityJob.vala:1092
995 msgid "Failed with an unknown error."
996 msgstr ""
997
998-#: ../deja-dup/AssistantOperation.vala:730
999+#: ../deja-dup/AssistantOperation.vala:795
1000 msgid "Require Password?"
1001 msgstr ""
1002
1003-#: ../deja-dup/AssistantOperation.vala:732
1004+#: ../deja-dup/AssistantOperation.vala:797
1005 msgid "Encryption Password Needed"
1006 msgstr ""
1007
1008-#: ../deja-dup/AssistantOperation.vala:778
1009+#: ../deja-dup/AssistantOperation.vala:868
1010 msgid "Backup encryption password"
1011 msgstr ""
1012
1013@@ -782,11 +825,16 @@
1014 msgid "Scanning finished"
1015 msgstr ""
1016
1017-#: ../deja-dup/Assistant.vala:309
1018+#: ../deja-dup/Assistant.vala:314
1019 msgid "Co_ntinue"
1020 msgstr ""
1021
1022-#: ../deja-dup/Assistant.vala:347 ../deja-dup/StatusIcon.vala:93
1023+#: ../deja-dup/Assistant.vala:320
1024+msgctxt "verb"
1025+msgid "_Test"
1026+msgstr ""
1027+
1028+#: ../deja-dup/Assistant.vala:357 ../deja-dup/StatusIcon.vala:93
1029 msgid "_Resume Later"
1030 msgstr ""
1031
1032@@ -1012,35 +1060,35 @@
1033 msgid "Categories"
1034 msgstr ""
1035
1036-#: ../tools/duplicity/DuplicityJob.vala:89
1037-#: ../tools/duplicity/DuplicityJob.vala:173
1038+#: ../tools/duplicity/DuplicityJob.vala:90
1039+#: ../tools/duplicity/DuplicityJob.vala:187
1040 msgid "Paused (no network)"
1041 msgstr ""
1042
1043 #. Was not even a file path (maybe something goofy like computer://)
1044-#: ../tools/duplicity/DuplicityJob.vala:444
1045+#: ../tools/duplicity/DuplicityJob.vala:458
1046 #, c-format
1047 msgid "Could not restore ‘%s’: Not a valid file location"
1048 msgstr ""
1049
1050 #. Tiny backup location. Suggest they get a larger one.
1051-#: ../tools/duplicity/DuplicityJob.vala:510
1052+#: ../tools/duplicity/DuplicityJob.vala:524
1053 msgid "Backup location is too small. Try using one with more space."
1054 msgstr ""
1055
1056-#: ../tools/duplicity/DuplicityJob.vala:532
1057+#: ../tools/duplicity/DuplicityJob.vala:547
1058 msgid "Backup location does not have enough free space."
1059 msgstr ""
1060
1061-#: ../tools/duplicity/DuplicityJob.vala:551
1062-#: ../tools/duplicity/DuplicityJob.vala:565
1063+#: ../tools/duplicity/DuplicityJob.vala:567
1064+#: ../tools/duplicity/DuplicityJob.vala:581
1065 msgid "Cleaning up…"
1066 msgstr ""
1067
1068 #. OK, we succeeded yay! But some files didn't make it into the backup
1069 #. because we couldn't read them. So tell the user so they don't think
1070 #. everything is hunky dory.
1071-#: ../tools/duplicity/DuplicityJob.vala:661
1072+#: ../tools/duplicity/DuplicityJob.vala:677
1073 msgid ""
1074 "Could not back up the following files. Please make sure you are able to "
1075 "open them."
1076@@ -1049,13 +1097,13 @@
1077 #. OK, we succeeded yay! But some files didn't actually restore
1078 #. because we couldn't write to them. So tell the user so they
1079 #. don't think everything is hunky dory.
1080-#: ../tools/duplicity/DuplicityJob.vala:677
1081+#: ../tools/duplicity/DuplicityJob.vala:693
1082 msgid ""
1083 "Could not restore the following files. Please make sure you are able to "
1084 "write to them."
1085 msgstr ""
1086
1087-#: ../tools/duplicity/DuplicityJob.vala:924
1088+#: ../tools/duplicity/DuplicityJob.vala:940
1089 #, c-format
1090 msgid "Could not restore ‘%s’: File not found in backup"
1091 msgstr ""
1092@@ -1063,17 +1111,17 @@
1093 #. notify upper layers, if they want to do anything
1094 #. Duplicity tried to ask the user what the encryption password is.
1095 #. notify upper layers, if they want to do anything
1096-#: ../tools/duplicity/DuplicityJob.vala:930
1097-#: ../tools/duplicity/DuplicityJob.vala:1028
1098-#: ../tools/duplicity/DuplicityJob.vala:1032
1099+#: ../tools/duplicity/DuplicityJob.vala:946
1100+#: ../tools/duplicity/DuplicityJob.vala:1044
1101+#: ../tools/duplicity/DuplicityJob.vala:1048
1102 msgid "Bad encryption password."
1103 msgstr ""
1104
1105-#: ../tools/duplicity/DuplicityJob.vala:935
1106+#: ../tools/duplicity/DuplicityJob.vala:951
1107 msgid "Computer name changed"
1108 msgstr ""
1109
1110-#: ../tools/duplicity/DuplicityJob.vala:935
1111+#: ../tools/duplicity/DuplicityJob.vala:951
1112 #, c-format
1113 msgid ""
1114 "The existing backup is of a computer named %s, but the current computer’s "
1115@@ -1081,69 +1129,69 @@
1116 "location."
1117 msgstr ""
1118
1119-#: ../tools/duplicity/DuplicityJob.vala:970
1120+#: ../tools/duplicity/DuplicityJob.vala:986
1121 #, c-format
1122 msgid "Permission denied when trying to create ‘%s’."
1123 msgstr ""
1124
1125 #. assume error is on backend side
1126-#: ../tools/duplicity/DuplicityJob.vala:974
1127-#: ../tools/duplicity/DuplicityJob.vala:978
1128+#: ../tools/duplicity/DuplicityJob.vala:990
1129+#: ../tools/duplicity/DuplicityJob.vala:994
1130 #, c-format
1131 msgid "Permission denied when trying to read ‘%s’."
1132 msgstr ""
1133
1134-#: ../tools/duplicity/DuplicityJob.vala:982
1135+#: ../tools/duplicity/DuplicityJob.vala:998
1136 #, c-format
1137 msgid "Permission denied when trying to delete ‘%s’."
1138 msgstr ""
1139
1140-#: ../tools/duplicity/DuplicityJob.vala:989
1141+#: ../tools/duplicity/DuplicityJob.vala:1005
1142 #, c-format
1143 msgid "Backup location ‘%s’ does not exist."
1144 msgstr ""
1145
1146-#: ../tools/duplicity/DuplicityJob.vala:995
1147-#: ../tools/duplicity/DuplicityJob.vala:1047
1148+#: ../tools/duplicity/DuplicityJob.vala:1011
1149+#: ../tools/duplicity/DuplicityJob.vala:1063
1150 msgid "No space left."
1151 msgstr ""
1152
1153-#: ../tools/duplicity/DuplicityJob.vala:1009
1154+#: ../tools/duplicity/DuplicityJob.vala:1025
1155 msgid "Invalid ID."
1156 msgstr ""
1157
1158-#: ../tools/duplicity/DuplicityJob.vala:1011
1159+#: ../tools/duplicity/DuplicityJob.vala:1027
1160 msgid "Invalid secret key."
1161 msgstr ""
1162
1163-#: ../tools/duplicity/DuplicityJob.vala:1013
1164+#: ../tools/duplicity/DuplicityJob.vala:1029
1165 msgid "Your Amazon Web Services account is not signed up for the S3 service."
1166 msgstr ""
1167
1168-#: ../tools/duplicity/DuplicityJob.vala:1022
1169+#: ../tools/duplicity/DuplicityJob.vala:1038
1170 msgid "S3 bucket name is not available."
1171 msgstr ""
1172
1173-#: ../tools/duplicity/DuplicityJob.vala:1036
1174+#: ../tools/duplicity/DuplicityJob.vala:1052
1175 #, c-format
1176 msgid "Error reading file ‘%s’."
1177 msgstr ""
1178
1179-#: ../tools/duplicity/DuplicityJob.vala:1038
1180+#: ../tools/duplicity/DuplicityJob.vala:1054
1181 #, c-format
1182 msgid "Error writing file ‘%s’."
1183 msgstr ""
1184
1185-#: ../tools/duplicity/DuplicityJob.vala:1049
1186+#: ../tools/duplicity/DuplicityJob.vala:1065
1187 #, c-format
1188 msgid "No space left in ‘%s’."
1189 msgstr ""
1190
1191-#: ../tools/duplicity/DuplicityJob.vala:1057
1192+#: ../tools/duplicity/DuplicityJob.vala:1073
1193 msgid "No backup files found"
1194 msgstr ""
1195
1196-#: ../tools/duplicity/DuplicityJob.vala:1107
1197+#: ../tools/duplicity/DuplicityJob.vala:1123
1198 msgid "Uploading…"
1199 msgstr ""
1200
1201
1202=== modified file 'tests/runner/mock/duplicity'
1203--- tests/runner/mock/duplicity 2012-08-13 23:03:55 +0000
1204+++ tests/runner/mock/duplicity 2012-08-21 01:36:28 +0000
1205@@ -77,6 +77,7 @@
1206 delay = 0
1207 script = ''
1208 passphrase = None
1209+tmp_archive = False
1210
1211 while len(lines) > curline and lines[curline].strip():
1212 tokens = lines[curline].split()
1213@@ -90,8 +91,19 @@
1214 script = ' '.join(tokens[1:])
1215 elif tokens[0] == 'PASSPHRASE:':
1216 passphrase = tokens[1] if len(tokens) > 1 else ''
1217+ elif lines[curline].strip() == 'TMP_ARCHIVE':
1218+ tmp_archive = True
1219 curline += 1
1220
1221+if tmp_archive:
1222+ for i in xrange(len(sys.argv)):
1223+ split = sys.argv[i].split('=', 1)
1224+ if len(split) > 1 and split[0] == "--archive-dir":
1225+ if split[1].find("/cache/") != -1:
1226+ print >> logfd, "TESTFAIL: expected random /tmp archive dir"
1227+ sys.exit(-1)
1228+ sys.argv[i] = "--archive-dir=?"
1229+
1230 if expected_args != sys.argv[1:]:
1231 print >> logfd, "TESTFAIL: expected\n%s\nvs\n%s" % (expected_args, sys.argv[1:])
1232 sys.exit(-1)
1233
1234=== modified file 'tests/runner/runner.vala'
1235--- tests/runner/runner.vala 2012-08-13 23:44:06 +0000
1236+++ tests/runner/runner.vala 2012-08-21 01:36:28 +0000
1237@@ -103,21 +103,23 @@
1238 LIST,
1239 }
1240
1241-string default_args(BackupRunner br, Mode mode = Mode.NONE, bool encrypted = false, string extra = "")
1242+string default_args(BackupRunner br, Mode mode = Mode.NONE, bool encrypted = false, string extra = "", bool tmp_archive = false)
1243 {
1244 var cachedir = Environment.get_variable("XDG_CACHE_HOME");
1245 var test_home = Environment.get_variable("DEJA_DUP_TEST_HOME");
1246 var backupdir = Path.build_filename(test_home, "backup");
1247 var restoredir = Path.build_filename(test_home, "restore");
1248
1249+ var archive = tmp_archive ? "?" : "%s/deja-dup".printf(cachedir);
1250+
1251 if (mode == Mode.CLEANUP)
1252- return "cleanup '--force' 'file://%s' '--gio' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(backupdir, encrypted ? "" : "'--no-encryption' ", cachedir);
1253+ return "cleanup '--force' 'file://%s' '--gio' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s' '--log-fd=?'".printf(backupdir, encrypted ? "" : "'--no-encryption' ", archive);
1254 else if (mode == Mode.RESTORE)
1255- return "'restore' '--gio' '--force' 'file://%s' '%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(backupdir, restoredir, encrypted ? "" : "'--no-encryption' ", cachedir);
1256+ return "'restore' '--gio' '--force' 'file://%s' '%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s' '--log-fd=?'".printf(backupdir, restoredir, encrypted ? "" : "'--no-encryption' ", archive);
1257 else if (mode == Mode.VERIFY)
1258- return "'restore' '--file-to-restore=%s/deja-dup/metadata' '--gio' '--force' 'file://%s' '%s/deja-dup/metadata' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(cachedir.substring(1), backupdir, cachedir, encrypted ? "" : "'--no-encryption' ", cachedir);
1259+ return "'restore' '--file-to-restore=%s/deja-dup/metadata' '--gio' '--force' 'file://%s' '%s/deja-dup/metadata' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s' '--log-fd=?'".printf(cachedir.substring(1), backupdir, cachedir, encrypted ? "" : "'--no-encryption' ", archive);
1260 else if (mode == Mode.LIST)
1261- return "'list-current-files' '--gio' 'file://%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(backupdir, encrypted ? "" : "'--no-encryption' ", cachedir);
1262+ return "'list-current-files' '--gio' 'file://%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s' '--log-fd=?'".printf(backupdir, encrypted ? "" : "'--no-encryption' ", archive);
1263
1264 string source_str = "";
1265 if (mode == Mode.DRY || mode == Mode.BACKUP)
1266@@ -164,7 +166,7 @@
1267 args += "'--exclude=%s/deja-dup' '--exclude=%s' '--exclude=**' ".printf(cachedir, cachedir);
1268 }
1269
1270- args += "%s%s'--gio' %s'file://%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(extra, dry_str, source_str, backupdir, enc_str, cachedir);
1271+ args += "%s%s'--gio' %s'file://%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s' '--log-fd=?'".printf(extra, dry_str, source_str, backupdir, enc_str, archive);
1272
1273 return args;
1274 }
1275@@ -297,14 +299,20 @@
1276 {
1277 var home = Environment.get_home_dir();
1278 var cachedir = Environment.get_variable("XDG_CACHE_HOME");
1279- return in.replace("@HOME@", home).replace("@XDG_CACHE_HOME@", cachedir);
1280+ var test_home = Environment.get_variable("DEJA_DUP_TEST_HOME");
1281+ return in.replace("@HOME@", home).
1282+ replace("@XDG_CACHE_HOME@", cachedir).
1283+ replace("@TEST_HOME@", test_home);
1284 }
1285
1286 string run_script(string in)
1287 {
1288 string output;
1289+ string errstr;
1290 try {
1291- Process.spawn_sync(null, {"/bin/sh", "-c", in}, null, 0, null, out output, null, null);
1292+ Process.spawn_sync(null, {"/bin/sh", "-c", in}, null, 0, null, out output, out errstr, null);
1293+ if (errstr != null && errstr != "")
1294+ warning("Error running script: %s", errstr);
1295 }
1296 catch (SpawnError e) {
1297 warning(e.message);
1298@@ -343,6 +351,22 @@
1299 br.error_detail = keyfile.get_string(group, "ErrorDetail");
1300 if (keyfile.has_key(group, "Passphrases"))
1301 br.passphrases = keyfile.get_integer(group, "Passphrases");
1302+ if (keyfile.has_key(group, "Settings")) {
1303+ var settings_list = keyfile.get_string_list(group, "Settings");
1304+ var settings = DejaDup.get_settings();
1305+ foreach (var setting in settings_list) {
1306+ try {
1307+ var tokens = setting.split("=");
1308+ var key = tokens[0];
1309+ var val = Variant.parse(null, tokens[1]);
1310+ settings.set_value(key, val);
1311+ }
1312+ catch (Error e) {
1313+ warning("%s\n", e.message);
1314+ assert_not_reached();
1315+ }
1316+ }
1317+ }
1318 }
1319
1320 void process_duplicity_run_block(KeyFile keyfile, string run, BackupRunner br) throws Error
1321@@ -353,6 +377,7 @@
1322 bool cancel = false;
1323 bool stop = false;
1324 bool passphrase = false;
1325+ bool tmp_archive = false;
1326 string script = null;
1327 Mode mode = Mode.NONE;
1328
1329@@ -361,6 +386,8 @@
1330 var group = "Duplicity " + run;
1331
1332 if (keyfile.has_group(group)) {
1333+ if (keyfile.has_key(group, "ArchiveDirIsTmp"))
1334+ tmp_archive = keyfile.get_boolean(group, "ArchiveDirIsTmp");
1335 if (keyfile.has_key(group, "Cancel"))
1336 cancel = keyfile.get_boolean(group, "Cancel");
1337 if (keyfile.has_key(group, "Encrypted"))
1338@@ -403,7 +430,10 @@
1339
1340 var cachedir = Environment.get_variable("XDG_CACHE_HOME");
1341
1342- var dupscript = "ARGS: " + default_args(br, mode, encrypted, extra_args);
1343+ var dupscript = "ARGS: " + default_args(br, mode, encrypted, extra_args, tmp_archive);
1344+
1345+ if (tmp_archive)
1346+ dupscript += "\n" + "TMP_ARCHIVE";
1347
1348 if (cancel) {
1349 dupscript += "\n" + "DELAY: 10";
1350
1351=== added file 'tests/scripts/nag.test'
1352--- tests/scripts/nag.test 1970-01-01 00:00:00 +0000
1353+++ tests/scripts/nag.test 2012-08-21 01:36:28 +0000
1354@@ -0,0 +1,58 @@
1355+# Tests whether we correctly nag the user about their password during some
1356+# verify checks.
1357+
1358+[Operation]
1359+Type=backup
1360+Settings=nag-check='1970-01-01T00:32:08.916885Z'
1361+Passphrases=2
1362+
1363+[Duplicity]
1364+Runs=status 1;status 2;dry;backup;status-restore 1;status-restore 2;list;verify;
1365+
1366+[Duplicity status 1]
1367+#DEBUG 1
1368+#. ['duplicity.gpg']
1369+#
1370+#ERROR 31
1371+Output=true
1372+
1373+[Duplicity status 2]
1374+#DEBUG 1
1375+#. ['duplicity.gpg']
1376+Output=true
1377+Encrypted=true
1378+Passphrase=true
1379+
1380+[Duplicity dry]
1381+Encrypted=true
1382+Passphrase=true
1383+
1384+[Duplicity backup]
1385+Encrypted=true
1386+Passphrase=true
1387+
1388+[Duplicity status-restore 1]
1389+#DEBUG 1
1390+#. ['duplicity.gpg']
1391+#
1392+#ERROR 31
1393+Output=true
1394+ArchiveDirIsTmp=true
1395+
1396+[Duplicity status-restore 2]
1397+#DEBUG 1
1398+#. ['duplicity.gpg']
1399+Output=true
1400+Encrypted=true
1401+Passphrase=true
1402+ArchiveDirIsTmp=true
1403+
1404+[Duplicity list]
1405+Encrypted=true
1406+Passphrase=true
1407+ArchiveDirIsTmp=true
1408+
1409+[Duplicity verify]
1410+Encrypted=true
1411+Passphrase=true
1412+ArchiveDirIsTmp=true
1413
1414=== modified file 'tools/duplicity/DuplicityInstance.vala'
1415--- tools/duplicity/DuplicityInstance.vala 2012-08-10 18:33:29 +0000
1416+++ tools/duplicity/DuplicityInstance.vala 2012-08-21 01:36:28 +0000
1417@@ -27,6 +27,7 @@
1418 string user_text);
1419
1420 public bool verbose {get; private set; default = false;}
1421+ public string forced_cache_dir {get; set; default = null;}
1422
1423 public virtual void start(List<string> argv_in, List<string>? envp_in,
1424 bool as_root = false) throws Error
1425@@ -71,7 +72,9 @@
1426 argv.append("--gpg-options=--no-use-agent");
1427
1428 // Cache signature files
1429- var cache_dir = Environment.get_user_cache_dir();
1430+ var cache_dir = forced_cache_dir;
1431+ if (cache_dir == null)
1432+ cache_dir = Environment.get_user_cache_dir();
1433 if (cache_dir != null) {
1434 bool add_dir = false;
1435 var cache_file = File.new_for_path(cache_dir);
1436
1437=== modified file 'tools/duplicity/DuplicityJob.vala'
1438--- tools/duplicity/DuplicityJob.vala 2012-08-21 00:49:25 +0000
1439+++ tools/duplicity/DuplicityJob.vala 2012-08-21 01:36:28 +0000
1440@@ -80,6 +80,7 @@
1441 int delete_age = 0;
1442
1443 File last_touched_file = null;
1444+ string forced_cache_dir = null;
1445
1446 void network_changed()
1447 {
1448@@ -109,6 +110,9 @@
1449
1450 ~DuplicityJob() {
1451 DejaDup.Network.get().notify["connected"].disconnect(network_changed);
1452+
1453+ if (forced_cache_dir != null)
1454+ new DejaDup.RecursiveDelete(File.new_for_path(forced_cache_dir)).start_async.begin();
1455 }
1456
1457 public override void start()
1458@@ -125,7 +129,17 @@
1459
1460 if (mode == DejaDup.ToolJob.Mode.BACKUP)
1461 process_include_excludes();
1462-
1463+
1464+ /* Fake cache dir if we need to */
1465+ if ((flags & DejaDup.ToolJob.Flags.NO_CACHE) != 0) {
1466+ try {
1467+ forced_cache_dir = DirUtils.make_tmp("deja-dup-XXXXXX");
1468+ }
1469+ catch (Error e) {
1470+ warning("%s\n", e.message);
1471+ }
1472+ }
1473+
1474 var settings = DejaDup.get_settings();
1475 delete_age = settings.get_int(DejaDup.DELETE_AFTER_KEY);
1476
1477@@ -1372,6 +1386,9 @@
1478 inst = new DuplicityInstance();
1479 inst.done.connect(handle_done);
1480
1481+ if (forced_cache_dir != null)
1482+ inst.forced_cache_dir = forced_cache_dir;
1483+
1484 /* As duplicity's data is returned via a signal, handle_message begins post-raw stream processing */
1485 inst.message.connect(handle_message);
1486

Subscribers

People subscribed via source and target branches