deja-dup-team team mailing list archive
-
deja-dup-team team
-
Mailing list archive
-
Message #00456
[Merge] lp:~deja-dup-hackers/deja-dup/tools into lp:deja-dup
Michael Terry has proposed merging lp:~deja-dup-hackers/deja-dup/tools into lp:deja-dup.
Requested reviews:
Ken VanDine (ken-vandine)
For more details, see:
https://code.launchpad.net/~deja-dup-hackers/deja-dup/tools/+merge/104155
Refactor duplicity backend into a libpeas plugin.
There is no change of functionality here. This is just for cleaner code separation and to get some experience before I do the same thing to the cloud backends.
--
https://code.launchpad.net/~deja-dup-hackers/deja-dup/tools/+merge/104155
Your team Déjà Dup Developers is subscribed to branch lp:deja-dup.
=== modified file 'Makefile.am'
--- Makefile.am 2011-10-07 16:57:12 +0000
+++ Makefile.am 2012-04-30 17:55:21 +0000
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
-SUBDIRS = data po vapi common widgets monitor preferences deja-dup nautilus help man tests
+SUBDIRS = data po vapi common tools widgets monitor preferences deja-dup nautilus help man tests
# Distribute pot file
update-pot:
=== modified file 'common/Backend.vala'
--- common/Backend.vala 2012-03-21 03:01:36 +0000
+++ common/Backend.vala 2012-04-30 17:55:21 +0000
@@ -46,7 +46,7 @@
// Arguments needed only when the particular mode is active
// If mode == INVALID, arguments needed any time the backup is referenced.
- public virtual void add_argv(Operation.Mode mode, ref List<string> argv) {}
+ public virtual void add_argv(ToolJob.Mode mode, ref List<string> argv) {}
public abstract Backend clone();
=== modified file 'common/BackendFile.vala'
--- common/BackendFile.vala 2012-03-22 14:44:44 +0000
+++ common/BackendFile.vala 2012-04-30 17:55:21 +0000
@@ -208,15 +208,15 @@
}
// will be mounted by this time
- public override void add_argv(Operation.Mode mode, ref List<string> argv)
+ public override void add_argv(ToolJob.Mode mode, ref List<string> argv)
{
- if (mode == Operation.Mode.BACKUP) {
+ if (mode == ToolJob.Mode.BACKUP) {
var file = get_file_from_settings();
if (file != null && file.is_native())
argv.prepend("--exclude=%s".printf(file.get_path()));
}
- if (mode == Operation.Mode.INVALID)
+ if (mode == ToolJob.Mode.INVALID)
argv.prepend("--gio");
}
=== modified file 'common/BackendS3.vala'
--- common/BackendS3.vala 2012-03-21 03:01:36 +0000
+++ common/BackendS3.vala 2012-04-30 17:55:21 +0000
@@ -38,8 +38,8 @@
return new BackendS3();
}
- public override void add_argv(Operation.Mode mode, ref List<string> argv) {
- if (mode == Operation.Mode.INVALID)
+ public override void add_argv(ToolJob.Mode mode, ref List<string> argv) {
+ if (mode == ToolJob.Mode.INVALID)
argv.append("--s3-use-new-style");
}
=== modified file 'common/CommonUtils.vala'
--- common/CommonUtils.vala 2012-03-22 14:44:44 +0000
+++ common/CommonUtils.vala 2012-04-30 17:55:21 +0000
@@ -228,11 +228,6 @@
settings.set_string(PROMPT_CHECK_KEY, cur_time_str);
}
-public string get_trash_path()
-{
- return Path.build_filename(Environment.get_user_data_dir(), "Trash");
-}
-
public string get_folder_key(SimpleSettings settings, string key)
{
string folder = settings.get_string(key);
@@ -245,53 +240,6 @@
return folder;
}
-public File? parse_dir(string dir)
-{
- string s = dir;
- if (s == "$HOME")
- s = Environment.get_home_dir();
- else if (s == "$DESKTOP")
- s = Environment.get_user_special_dir(UserDirectory.DESKTOP);
- else if (s == "$DOCUMENTS")
- s = Environment.get_user_special_dir(UserDirectory.DOCUMENTS);
- else if (s == "$DOWNLOAD")
- s = Environment.get_user_special_dir(UserDirectory.DOWNLOAD);
- else if (s == "$MUSIC")
- s = Environment.get_user_special_dir(UserDirectory.MUSIC);
- else if (s == "$PICTURES")
- s = Environment.get_user_special_dir(UserDirectory.PICTURES);
- else if (s == "$PUBLIC_SHARE")
- s = Environment.get_user_special_dir(UserDirectory.PUBLIC_SHARE);
- else if (s == "$TEMPLATES")
- s = Environment.get_user_special_dir(UserDirectory.TEMPLATES);
- else if (s == "$TRASH")
- s = get_trash_path();
- else if (s == "$VIDEOS")
- s = Environment.get_user_special_dir(UserDirectory.VIDEOS);
- else if (Uri.parse_scheme(s) == null && !Path.is_absolute(s))
- s = Path.build_filename(Environment.get_home_dir(), s);
- else
- return File.parse_name(s);
-
- if (s != null)
- return File.new_for_path(s);
- else
- return null;
-}
-
-public File[] parse_dir_list(string*[] dirs)
-{
- File[] rv = new File[0];
-
- foreach (string s in dirs) {
- var f = parse_dir(s);
- if (f != null)
- rv += f;
- }
-
- return rv;
-}
-
bool settings_read_only = false;
HashTable<string, SimpleSettings> settings_table = null;
public void set_settings_read_only(bool ro)
@@ -389,15 +337,53 @@
}
}
-public bool meet_requirements(out string header, out string msg)
-{
- return DuplicityInfo.get_default().check_duplicity_version(out header, out msg);
+ToolPlugin tool = null;
+void initialize_tool_plugin() throws Error
+{
+ var engine = new Peas.Engine ();
+
+ // For testing, we'll often point to in-tree tools
+ string search_path = Environment.get_variable("DEJA_DUP_TOOLS_PATH");
+ if (search_path == null || search_path == "")
+ search_path = Path.build_filename(Config.PKG_LIBEXEC_DIR, "tools");
+ engine.add_search_path(search_path, null);
+
+ var info = engine.get_plugin_info("libduplicity.so");
+ if (info == null)
+ throw new SpawnError.FAILED(_("Could not find backup tool in %s. Your installation is incomplete.").printf(search_path));
+ if (!engine.try_load_plugin(info))
+ throw new SpawnError.FAILED(_("Could not load backup tool. Your installation is incomplete."));
+
+ var extset = new Peas.ExtensionSet(engine, typeof(Peas.Activatable));
+ var ext = extset.get_extension(info);
+ tool = ext as ToolPlugin;
+ if (tool == null)
+ throw new SpawnError.FAILED(_("Backup tool is broken. Your installation is incomplete."));
+
+ tool.activate();
+}
+
+public ToolJob make_tool_job() throws Error
+{
+ if (tool == null)
+ initialize_tool_plugin();
+ return tool.create_job();
}
public bool initialize(out string header, out string msg)
{
- if (!meet_requirements(out header, out msg))
+ header = null;
+ msg = null;
+
+ // Get tool plugin to use
+ try {
+ initialize_tool_plugin();
+ }
+ catch (Error e) {
+ header = _("Could not start backup tool");
+ msg = e.message;
return false;
+ }
convert_ssh_to_file();
convert_s3_folder_to_hostname();
=== added file 'common/DirHandling.vala'
--- common/DirHandling.vala 1970-01-01 00:00:00 +0000
+++ common/DirHandling.vala 2012-04-30 17:55:21 +0000
@@ -0,0 +1,77 @@
+/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
+/*
+ This file is part of Déjà Dup.
+ For copyright information, see AUTHORS.
+
+ Déjà Dup is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Déjà Dup is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib;
+
+namespace DejaDup {
+
+public string get_trash_path()
+{
+ return Path.build_filename(Environment.get_user_data_dir(), "Trash");
+}
+
+public File? parse_dir(string dir)
+{
+ string s = dir;
+ if (s == "$HOME")
+ s = Environment.get_home_dir();
+ else if (s == "$DESKTOP")
+ s = Environment.get_user_special_dir(UserDirectory.DESKTOP);
+ else if (s == "$DOCUMENTS")
+ s = Environment.get_user_special_dir(UserDirectory.DOCUMENTS);
+ else if (s == "$DOWNLOAD")
+ s = Environment.get_user_special_dir(UserDirectory.DOWNLOAD);
+ else if (s == "$MUSIC")
+ s = Environment.get_user_special_dir(UserDirectory.MUSIC);
+ else if (s == "$PICTURES")
+ s = Environment.get_user_special_dir(UserDirectory.PICTURES);
+ else if (s == "$PUBLIC_SHARE")
+ s = Environment.get_user_special_dir(UserDirectory.PUBLIC_SHARE);
+ else if (s == "$TEMPLATES")
+ s = Environment.get_user_special_dir(UserDirectory.TEMPLATES);
+ else if (s == "$TRASH")
+ s = get_trash_path();
+ else if (s == "$VIDEOS")
+ s = Environment.get_user_special_dir(UserDirectory.VIDEOS);
+ else if (Uri.parse_scheme(s) == null && !Path.is_absolute(s))
+ s = Path.build_filename(Environment.get_home_dir(), s);
+ else
+ return File.parse_name(s);
+
+ if (s != null)
+ return File.new_for_path(s);
+ else
+ return null;
+}
+
+public File[] parse_dir_list(string*[] dirs)
+{
+ File[] rv = new File[0];
+
+ foreach (string s in dirs) {
+ var f = parse_dir(s);
+ if (f != null)
+ rv += f;
+ }
+
+ return rv;
+}
+
+} // end namespace
+
=== removed file 'common/DuplicityInfo.vala'
--- common/DuplicityInfo.vala 2011-09-26 05:15:03 +0000
+++ common/DuplicityInfo.vala 1970-01-01 00:00:00 +0000
@@ -1,128 +0,0 @@
-/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
-/*
- This file is part of Déjà Dup.
- For copyright information, see AUTHORS.
-
- Déjà Dup is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Déjà Dup is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-using GLib;
-
-namespace DejaDup {
-
-public class DuplicityInfo : Object
-{
- public static const int REQUIRED_MAJOR = 0;
- public static const int REQUIRED_MINOR = 6;
- public static const int REQUIRED_MICRO = 14;
-
- public bool reports_encryption {get; private set; default = false;}
-
- static DuplicityInfo info = null;
- public static DuplicityInfo get_default() {
- if (info == null)
- info = new DuplicityInfo();
- return info;
- }
-
- // Returns true if everything is OK. If false, program will close. A dialog
- // will already have been thrown up.
- public bool check_duplicity_version(out string header, out string msg) {
- string output;
-
- header = null;
- msg = null;
-
- try {
- Process.spawn_command_line_sync("duplicity --version", out output, null, null);
- }
- catch (Error e) {
- set_missing_duplicity_error(out header, out msg, e.message);
- return false;
- }
-
- var tokens = output.split(" ", 2);
- if (tokens == null || tokens[0] == null || tokens[1] == null) {
- set_missing_duplicity_error(out header, out msg, null);
- return false;
- }
-
- // First token is 'duplicity' and is ignorable. Second looks like '0.5.03'
- version_string = tokens[1].strip();
- var ver_tokens = version_string.split(".");
- if (ver_tokens == null || ver_tokens[0] == null) {
- set_missing_duplicity_error(out header, out msg, null);
- return false;
- }
- major = int.parse(ver_tokens[0]);
- // Don't error out if no minor or micro. Duplicity might not have them?
- if (ver_tokens[1] != null) {
- minor = int.parse(ver_tokens[1]);
- if (ver_tokens[2] != null)
- micro = int.parse(ver_tokens[2]);
- }
-
- var good_enough = meets_requirements();
- if (!good_enough) {
- set_bad_version_error(out header, out msg);
- return false;
- }
-
- //if (meets_version(0, 6, 15))
- // reports_encryption = true;
-
- return true;
- }
-
- string version_string = null;
- int major = 0;
- int minor = 0;
- int micro = 0;
-
- bool meets_version(int vmaj, int vmin, int vmic) {
- return (major > vmaj) ||
- (major == vmaj && minor > vmin) ||
- (major == vmaj && minor == vmin && micro >= vmic);
- }
-/*
- bool equals_version(int vmaj, int vmin, int vmic) {
- return major == vmaj && minor == vmin && micro == vmic;
- }
-*/
- // Doesn't yet handle a blacklist of versions. We'll cross that bridge when we come to it
- bool meets_requirements() {
- return meets_version(REQUIRED_MAJOR, REQUIRED_MINOR, REQUIRED_MICRO);
- }
-
- void set_missing_duplicity_error(out string header, out string msg, string? msg_in) {
- header = _("Could not run duplicity");
- msg = msg_in;
- if (msg != null)
- msg = msg.chomp() + "\n\n";
- else if (version_string == null)
- msg = _("Could not understand duplicity version.\n\n");
- else
- msg = _("Could not understand duplicity version ‘%s’.\n\n").printf(version_string);
-
- msg += _("Without duplicity, Déjà Dup Backup Tool cannot function. It will close now.");
- }
-
- void set_bad_version_error(out string header, out string msg) {
- header = _("Duplicity’s version is too old");
- msg = _("Déjà Dup Backup Tool requires at least version %d.%d.%.2d of duplicity, but only found version %d.%d.%.2d").printf(REQUIRED_MAJOR, REQUIRED_MINOR, REQUIRED_MICRO, major, minor, micro);
- }
-}
-
-} // end namespace
-
=== modified file 'common/Makefile.am'
--- common/Makefile.am 2012-02-02 18:56:52 +0000
+++ common/Makefile.am 2012-04-30 17:55:21 +0000
@@ -42,9 +42,7 @@
BackendU1.vala \
Checker.vala \
CommonUtils.vala \
- Duplicity.vala \
- DuplicityInfo.vala \
- DuplicityInstance.vala \
+ DirHandling.vala \
Network.vala \
Operation.vala \
OperationBackup.vala \
@@ -52,10 +50,8 @@
OperationStatus.vala \
OperationFiles.vala \
PythonChecker.vala \
- RecursiveDelete.vala \
- RecursiveMove.vala \
- RecursiveOp.vala \
- SimpleSettings.vala
+ SimpleSettings.vala \
+ ToolPlugin.vala
libcommon_la_SOURCES = \
chacks.c \
@@ -71,6 +67,7 @@
--pkg gio-2.0 \
--pkg gio-unix-2.0 \
--pkg gnome-keyring-1 \
+ --pkg libpeas-1.0 \
--pkg uriutils \
--pkg posix \
--pkg config
=== modified file 'common/Operation.vala'
--- common/Operation.vala 2012-04-10 19:35:31 +0000
+++ common/Operation.vala 2012-04-30 17:55:21 +0000
@@ -43,36 +43,26 @@
public bool needs_password {get; set;}
public Backend backend {get; private set;}
- public bool use_progress {get {return dup.use_progress;}
- set {dup.use_progress = value;}}
+ public bool use_progress {get {return (job.flags & ToolJob.Flags.NO_PROGRESS) == 0;}
+ set {
+ if (value)
+ job.flags = job.flags | ToolJob.Flags.NO_PROGRESS;
+ else
+ job.flags = job.flags ^ ToolJob.Flags.NO_PROGRESS;
+ }}
- public enum Mode {
- /*
- * Mode of operation of instance
- *
- * Every instance of class that inherit its methods and properties from
- * this class must define in which mode it operates. Based on this Duplicity
- * attaches appropriate argument.
- */
- INVALID,
- BACKUP,
- RESTORE,
- STATUS,
- LIST,
- FILEHISTORY
- }
- public Mode mode {get; construct; default = Mode.INVALID;}
+ public ToolJob.Mode mode {get; construct; default = ToolJob.Mode.INVALID;}
- public static string mode_to_string(Mode mode)
+ public static string mode_to_string(ToolJob.Mode mode)
{
switch (mode) {
- case Operation.Mode.BACKUP:
+ case ToolJob.Mode.BACKUP:
return _("Backing up…");
- case Operation.Mode.RESTORE:
+ case ToolJob.Mode.RESTORE:
return _("Restoring…");
- case Operation.Mode.STATUS:
+ case ToolJob.Mode.STATUS:
return _("Checking for backups…");
- case Operation.Mode.LIST:
+ case ToolJob.Mode.LIST:
return _("Listing files…");
default:
return _("Preparing…");
@@ -97,7 +87,7 @@
}
SimpleSettings settings;
- internal Duplicity dup;
+ internal ToolJob job;
protected string passphrase;
bool finished = false;
construct
@@ -136,16 +126,27 @@
settings = null;
}
- if (dup != null) {
- SignalHandler.disconnect_matched(dup, SignalMatchType.DATA,
+ if (job != null) {
+ SignalHandler.disconnect_matched(job, SignalMatchType.DATA,
0, 0, null, null, this);
- dup.stop();
- dup = null;
- }
-
- dup = new Duplicity(mode);
-
- connect_to_dup();
+ job.stop();
+ job = null;
+ }
+
+ try {
+ job = make_tool_job();
+ }
+ catch (Error e) {
+ raise_error(e.message, null);
+ done(false, false, null);
+ return;
+ }
+
+ job.mode = mode;
+ job.backend = backend;
+
+ make_argv();
+ connect_to_job();
ref(); // don't know what might happen in passphrase_required call
@@ -155,38 +156,38 @@
passphrase_required(); // will block and call set_passphrase when ready
}
else
- dup.encrypt_password = passphrase;
+ job.encrypt_password = passphrase;
if (!finished)
- continue_with_passphrase();
+ job.start();
unref();
}
public void cancel()
{
- dup.cancel();
+ job.cancel();
}
public void stop()
{
- dup.stop();
+ job.stop();
}
- protected virtual void connect_to_dup()
+ protected virtual void connect_to_job()
{
/*
* Connect Deja Dup to signals
*/
- dup.done.connect((d, o, c, detail) => {operation_finished(d, o, c, detail);});
- dup.raise_error.connect((d, s, detail) => {raise_error(s, detail);});
- dup.action_desc_changed.connect((d, s) => {action_desc_changed(s);});
- dup.action_file_changed.connect((d, f, b) => {action_file_changed(f, b);});
- dup.progress.connect((d, p) => {progress(p);});
- dup.question.connect((d, t, m) => {question(t, m);});
- dup.is_full.connect((first) => {is_full(first);});
- dup.bad_encryption_password.connect(() => {
- // If duplicity gives us a gpg error, we set needs_password so that
+ job.done.connect((d, o, c, detail) => {operation_finished(d, o, c, detail);});
+ job.raise_error.connect((d, s, detail) => {raise_error(s, detail);});
+ job.action_desc_changed.connect((d, s) => {action_desc_changed(s);});
+ job.action_file_changed.connect((d, f, b) => {action_file_changed(f, b);});
+ job.progress.connect((d, p) => {progress(p);});
+ job.question.connect((d, t, m) => {question(t, m);});
+ job.is_full.connect((first) => {is_full(first);});
+ job.bad_encryption_password.connect(() => {
+ // If tool gives us a gpg error, we set needs_password so that
// we will prompt for it.
needs_password = true;
passphrase = null;
@@ -198,55 +199,11 @@
{
needs_password = false;
this.passphrase = passphrase;
- if (dup != null)
- dup.encrypt_password = passphrase;
- }
-
- async void continue_with_passphrase()
- {
- /*
- * Continues with operation after passphrase has been acquired.
- */
- try {
- backend.envp_ready.connect(continue_with_envp);
- yield backend.get_envp();
- }
- catch (Error e) {
- raise_error(e.message, null);
- operation_finished(dup, false, false, null);
- }
- }
-
- void continue_with_envp(DejaDup.Backend b, bool success, List<string>? envp, string? error)
- {
- /*
- * Starts Duplicity backup with added enviroment variables
- *
- * Start Duplicity backup process with costum values for enviroment variables.
- */
- backend.envp_ready.disconnect(continue_with_envp);
-
- if (!success) {
- if (error != null)
- raise_error(error, null);
- operation_finished(dup, false, false, null);
- return;
- }
-
- try {
- List<string> argv = make_argv();
- backend.add_argv(mode, ref argv);
-
- dup.start(backend, argv, envp);
- }
- catch (Error e) {
- raise_error(e.message, null);
- operation_finished(dup, false, false, null);
- return;
- }
- }
-
- internal async virtual void operation_finished(Duplicity dup, bool success, bool cancelled, string? detail)
+ if (job != null)
+ job.encrypt_password = passphrase;
+ }
+
+ internal async virtual void operation_finished(ToolJob job, bool success, bool cancelled, string? detail)
{
finished = true;
@@ -255,7 +212,7 @@
done(success, cancelled, detail);
}
- protected virtual List<string>? make_argv() throws Error
+ protected virtual List<string>? make_argv()
{
/**
* Abstract method that prepares arguments that will be sent to duplicity
=== modified file 'common/OperationBackup.vala'
--- common/OperationBackup.vala 2012-04-10 02:22:06 +0000
+++ common/OperationBackup.vala 2012-04-30 17:55:21 +0000
@@ -24,19 +24,19 @@
public class OperationBackup : Operation
{
public OperationBackup() {
- Object(mode: Mode.BACKUP);
+ Object(mode: ToolJob.Mode.BACKUP);
}
- internal async override void operation_finished(Duplicity dup, bool success, bool cancelled, string? detail)
+ internal async override void operation_finished(ToolJob job, bool success, bool cancelled, string? detail)
{
/* If successfully completed, update time of last backup and run base operation_finished */
if (success)
DejaDup.update_last_run_timestamp(DejaDup.TimestampType.BACKUP);
- base.operation_finished(dup, success, cancelled, detail);
+ base.operation_finished(job, success, cancelled, detail);
}
- protected override List<string>? make_argv() throws Error
+ protected override List<string>? make_argv()
{
var settings = get_settings();
@@ -45,21 +45,19 @@
var exclude_val = settings.get_value(EXCLUDE_LIST_KEY);
var exclude_list = parse_dir_list(exclude_val.get_strv());
- List<string> rv = new List<string>();
-
// Exclude directories no one wants to backup
var always_excluded = get_always_excluded_dirs();
foreach (string dir in always_excluded)
- dup.excludes.prepend(File.new_for_path(dir));
+ job.excludes.prepend(File.new_for_path(dir));
foreach (File s in exclude_list)
- dup.excludes.prepend(s);
+ job.excludes.prepend(s);
foreach (File s in include_list)
- dup.includes.prepend(s);
-
- dup.local = File.new_for_path("/");
-
- return rv;
+ job.includes.prepend(s);
+
+ job.local = File.new_for_path("/");
+
+ return null;
}
List<string> get_always_excluded_dirs()
=== modified file 'common/OperationFiles.vala'
--- common/OperationFiles.vala 2012-04-10 02:22:06 +0000
+++ common/OperationFiles.vala 2012-04-30 17:55:21 +0000
@@ -27,28 +27,25 @@
public OperationFiles(Time? time_in,
File source) {
- Object(mode: Mode.LIST, source: source);
+ Object(mode: ToolJob.Mode.LIST, source: source);
if (time_in != null)
time = time_in;
}
- protected override void connect_to_dup()
+ protected override void connect_to_job()
{
- dup.listed_current_files.connect((d, date, file) => {listed_current_files(date, file);});
- base.connect_to_dup();
+ job.listed_current_files.connect((d, date, file) => {listed_current_files(date, file);});
+ base.connect_to_job();
}
- protected override List<string>? make_argv() throws Error
+ protected override List<string>? make_argv()
{
- List<string> argv = new List<string>();
- //if (time != null) - no need, we don't allow null anyway
- //stdout.printf("timedefault: %i", time.year);
if (time.format("%s") != "-1")
- argv.append("--time=%s".printf(time.format("%s")));
-
- dup.local = source;
-
- return argv;
+ job.time = time.format("%s");
+ else
+ job.time = null;
+ job.local = source;
+ return null;
}
}
}
=== modified file 'common/OperationRestore.vala'
--- common/OperationRestore.vala 2012-04-10 02:22:06 +0000
+++ common/OperationRestore.vala 2012-04-30 17:55:21 +0000
@@ -43,7 +43,7 @@
string? time_in = null,
List<File>? files_in = null) {
Object(dest: dest_in, time: time_in, restore_files: files_in,
- mode: Mode.RESTORE);
+ mode: ToolJob.Mode.RESTORE);
}
public async override void start()
@@ -52,29 +52,25 @@
base.start();
}
- protected override void connect_to_dup()
+ protected override void connect_to_job()
{
- base.connect_to_dup();
- dup.restore_files = restore_files;
+ base.connect_to_job();
+ job.restore_files = restore_files;
}
- protected override List<string>? make_argv() throws Error
+ protected override List<string>? make_argv()
{
- List<string> argv = new List<string>();
- if (time != null)
- argv.append("--restore-time=%s".printf(time));
-
- dup.local = File.new_for_path(dest);
-
- return argv;
+ job.time = time;
+ job.local = File.new_for_path(dest);
+ return null;
}
- internal async override void operation_finished(Duplicity dup, bool success, bool cancelled, string? detail)
+ internal async override void operation_finished(ToolJob job, bool success, bool cancelled, string? detail)
{
if (success)
DejaDup.update_last_run_timestamp(DejaDup.TimestampType.RESTORE);
- base.operation_finished(dup, success, cancelled, detail);
+ base.operation_finished(job, success, cancelled, detail);
}
}
=== modified file 'common/OperationStatus.vala'
--- common/OperationStatus.vala 2012-04-10 02:22:06 +0000
+++ common/OperationStatus.vala 2012-04-30 17:55:21 +0000
@@ -26,13 +26,13 @@
public signal void collection_dates(List<string>? dates);
public OperationStatus() {
- Object(mode: Mode.STATUS);
+ Object(mode: ToolJob.Mode.STATUS);
}
- protected override void connect_to_dup()
+ protected override void connect_to_job()
{
- dup.collection_dates.connect((d, dates) => {collection_dates(dates);});
- base.connect_to_dup();
+ job.collection_dates.connect((d, dates) => {collection_dates(dates);});
+ base.connect_to_job();
}
}
=== added file 'common/ToolPlugin.vala'
--- common/ToolPlugin.vala 1970-01-01 00:00:00 +0000
+++ common/ToolPlugin.vala 2012-04-30 17:55:21 +0000
@@ -0,0 +1,100 @@
+/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
+/*
+ This file is part of Déjà Dup.
+ For copyright information, see AUTHORS.
+
+ Déjà Dup is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Déjà Dup is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib;
+
+namespace DejaDup {
+
+public abstract class ToolJob : Object
+{
+ // life cycle signals
+ public signal void done(bool success, bool cancelled, string? detail);
+ public signal void raise_error(string errstr, string? detail);
+
+ // hints to UI
+ public signal void action_desc_changed(string action);
+ public signal void action_file_changed(File file, bool actual);
+ public signal void progress(double percent);
+ public signal void is_full(bool first);
+
+ // hints that interaction is needed
+ public signal void bad_encryption_password();
+ public signal void question(string title, string msg);
+
+ // type-specific signals
+ public signal void collection_dates(List<string>? dates); // HISTORY
+ public signal void listed_current_files(string date, string file); // LIST
+
+ // life cycle control
+ public abstract void start ();
+ public abstract void cancel (); // destroy progress so far
+ public abstract void stop (); // just abruptly stop
+ public abstract void pause (string? reason);
+ public abstract void resume ();
+
+ public enum Mode {
+ INVALID, BACKUP, RESTORE, STATUS, LIST, HISTORY,
+ }
+ public Mode mode {get; set; default = Mode.INVALID;}
+
+ public enum Flags {
+ NO_PROGRESS,
+ }
+ public Flags flags {get; set;}
+
+ public File local {get; set;}
+ public Backend backend {get; set;}
+ public string encrypt_password {get; set;}
+
+ public List<File> includes; // BACKUP
+ public List<File> excludes; // BACKUP
+
+ protected List<File> _restore_files;
+ public List<File> restore_files { // RESTORE
+ get {
+ return this._restore_files;
+ }
+ set {
+ // Deep copy
+ foreach (File f in this._restore_files)
+ f.unref();
+ this._restore_files = value.copy();
+ foreach (File f in this._restore_files)
+ f.ref();
+ }
+ }
+
+ public string time {get; set;} // RESTORE
+}
+
+public abstract class ToolPlugin : Peas.ExtensionBase, Peas.Activatable
+{
+ // Peas methods
+ public Object object {owned get; construct;}
+ public virtual void activate () {}
+ public virtual void deactivate () {}
+ public virtual void update_state () {}
+
+ // Deja Dup methods
+ public string name {get; protected set;}
+ public abstract ToolJob create_job () throws Error;
+}
+
+} // end namespace
+
=== modified file 'configure.ac'
--- configure.ac 2012-04-18 14:02:29 +0000
+++ configure.ac 2012-04-30 17:55:21 +0000
@@ -77,26 +77,31 @@
gio-2.0 >= $GIO_REQ_VER
gio-unix-2.0 >= $GIO_REQ_VER
gnome-keyring-1
+ libpeas-1.0
gmodule-2.0 >= $GLIB_REQ_VER
libnotify >= $NOTIFY_REQ_VER)
PKG_CHECK_MODULES(PREF,
$GTK_MODULE >= $GTK_REQ_VER
- gio-2.0 >= $GIO_REQ_VER)
+ gio-2.0 >= $GIO_REQ_VER
+ libpeas-1.0)
PKG_CHECK_MODULES(COMMON,
gio-2.0 >= $GIO_REQ_VER
gio-unix-2.0 >= $GIO_REQ_VER
gnome-keyring-1
+ libpeas-1.0
gmodule-2.0 >= $GLIB_REQ_VER)
PKG_CHECK_MODULES(WIDGETS,
gmodule-2.0 >= $GLIB_REQ_VER
$GTK_MODULE >= $GTK_REQ_VER
+ libpeas-1.0
libnotify >= $NOTIFY_REQ_VER)
PKG_CHECK_MODULES(MONITOR,
gio-2.0 >= $GIO_REQ_VER
+ libpeas-1.0
libnotify >= $NOTIFY_REQ_VER)
AC_ARG_WITH([extensiondir],
@@ -181,6 +186,8 @@
tests/runner/Makefile
tests/scripts/Makefile
tests/unit/Makefile
+ tools/Makefile
+ tools/duplicity/Makefile
vapi/Makefile
widgets/Makefile])
AC_OUTPUT
=== modified file 'deja-dup/Makefile.am'
--- deja-dup/Makefile.am 2012-04-10 02:36:52 +0000
+++ deja-dup/Makefile.am 2012-04-30 17:55:21 +0000
@@ -56,6 +56,7 @@
--pkg @GTK_MODULE@ \
--pkg gio-2.0 \
--pkg gnome-keyring-1 \
+ --pkg libpeas-1.0 \
--pkg libnotify \
--pkg libcommon \
--pkg libwidgets \
=== modified file 'deja-dup/StatusIcon.vala'
--- deja-dup/StatusIcon.vala 2011-12-23 18:36:10 +0000
+++ deja-dup/StatusIcon.vala 2012-04-30 17:55:21 +0000
@@ -121,7 +121,7 @@
}
}
- if (success && !cancelled && op.mode == DejaDup.Operation.Mode.BACKUP) {
+ if (success && !cancelled && op.mode == DejaDup.ToolJob.Mode.BACKUP) {
string msg = _("Backup completed");
string more = null;
@@ -198,7 +198,7 @@
{
Dbusmenu.Menuitem menu = null;
- if (op.mode == DejaDup.Operation.Mode.BACKUP) {
+ if (op.mode == DejaDup.ToolJob.Mode.BACKUP) {
menu = new Dbusmenu.Menuitem();
var item = new Dbusmenu.Menuitem();
@@ -227,7 +227,7 @@
}
construct {
- if (automatic && op.mode == DejaDup.Operation.Mode.BACKUP) {
+ if (automatic && op.mode == DejaDup.ToolJob.Mode.BACKUP) {
Notify.init(_("Backup"));
note = new Notify.Notification(_("Starting scheduled backup"), null,
"deja-dup");
@@ -286,7 +286,7 @@
progressitem.activate.connect((i) => {show_window();});
menu.append(progressitem);
- if (op.mode == DejaDup.Operation.Mode.BACKUP) {
+ if (op.mode == DejaDup.ToolJob.Mode.BACKUP) {
Gtk.MenuItem item;
menu.append(new Gtk.SeparatorMenuItem());
=== modified file 'monitor/Makefile.am'
--- monitor/Makefile.am 2012-02-02 18:56:52 +0000
+++ monitor/Makefile.am 2012-04-30 17:55:21 +0000
@@ -42,6 +42,7 @@
$(SHARED_VALAFLAGS) \
--pkg config \
--pkg gio-2.0 \
+ --pkg libpeas-1.0 \
--pkg libcommon \
--pkg libnotify
=== modified file 'nautilus/NautilusExtension.c'
--- nautilus/NautilusExtension.c 2011-10-07 15:26:41 +0000
+++ nautilus/NautilusExtension.c 2012-04-30 17:55:21 +0000
@@ -18,7 +18,7 @@
along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "CommonUtils.c"
+#include "DirHandling.c"
#include "NautilusExtension.h"
#include "config.h"
@@ -57,10 +57,8 @@
if (settings == NULL)
return;
- gchar **includes_strv = g_settings_get_strv(settings,
- DEJA_DUP_INCLUDE_LIST_KEY);
- gchar **excludes_strv = g_settings_get_strv(settings,
- DEJA_DUP_EXCLUDE_LIST_KEY);
+ gchar **includes_strv = g_settings_get_strv(settings, "include-list");
+ gchar **excludes_strv = g_settings_get_strv(settings, "exclude-list");
gchar **p;
for (p = includes_strv; p && *p; p++) {
@@ -318,9 +316,9 @@
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
settings = g_settings_new("org.gnome.DejaDup");
- g_signal_connect(settings, "changed::" DEJA_DUP_INCLUDE_LIST_KEY,
+ g_signal_connect(settings, "changed::include-list",
update_include_excludes, NULL);
- g_signal_connect(settings, "changed::" DEJA_DUP_EXCLUDE_LIST_KEY,
+ g_signal_connect(settings, "changed::exclude-list",
update_include_excludes, NULL);
g_idle_add(update_include_excludes_idle_cb, NULL);
}
=== modified file 'po/POTFILES.in'
--- po/POTFILES.in 2011-10-11 14:03:56 +0000
+++ po/POTFILES.in 2012-04-30 17:55:21 +0000
@@ -17,18 +17,12 @@
common/BackendU1.vala
common/Backend.vala
common/CommonUtils.vala
-common/DuplicityInfo.vala
-common/DuplicityInstance.vala
-common/Duplicity.vala
common/Network.vala
common/OperationBackup.vala
common/OperationFiles.vala
common/OperationRestore.vala
common/OperationStatus.vala
common/Operation.vala
-common/RecursiveDelete.vala
-common/RecursiveMove.vala
-common/RecursiveOp.vala
common/SimpleSettings.vala
deja-dup/AssistantBackup.vala
deja-dup/AssistantOperation.vala
@@ -42,6 +36,12 @@
monitor/monitor.vala
preferences/Preferences.vala
preferences/preferences-main.vala
+tools/duplicity/DuplicityInstance.vala
+tools/duplicity/DuplicityJob.vala
+tools/duplicity/DuplicityPlugin.vala
+tools/duplicity/RecursiveDelete.vala
+tools/duplicity/RecursiveMove.vala
+tools/duplicity/RecursiveOp.vala
widgets/ConfigBool.vala
widgets/ConfigChoice.vala
widgets/ConfigDelete.vala
=== modified file 'po/POTFILES.skip'
--- po/POTFILES.skip 2011-06-12 05:00:21 +0000
+++ po/POTFILES.skip 2012-04-30 17:55:21 +0000
@@ -6,18 +6,12 @@
common/BackendU1.c
common/Backend.c
common/CommonUtils.c
-common/DuplicityInfo.c
-common/DuplicityInstance.c
-common/Duplicity.c
common/Network.c
common/OperationBackup.c
common/OperationFiles.c
common/OperationRestore.c
common/OperationStatus.c
common/Operation.c
-common/RecursiveDelete.c
-common/RecursiveMove.c
-common/RecursiveOp.c
common/SimpleSettings.c
deja-dup/AssistantBackup.c
deja-dup/AssistantOperation.c
@@ -31,6 +25,12 @@
monitor/monitor.c
preferences/Preferences.c
preferences/preferences-main.c
+tools/duplicity/DuplicityInstance.c
+tools/duplicity/DuplicityJob.c
+tools/duplicity/DuplicityPlugin.c
+tools/duplicity/RecursiveDelete.c
+tools/duplicity/RecursiveMove.c
+tools/duplicity/RecursiveOp.c
widgets/ConfigBool.c
widgets/ConfigChoice.c
widgets/ConfigDelete.c
=== modified file 'po/deja-dup.pot'
--- po/deja-dup.pot 2012-01-19 22:40:33 +0000
+++ po/deja-dup.pot 2012-04-30 17:55:21 +0000
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: mike@xxxxxxxxxxx\n"
-"POT-Creation-Date: 2012-01-17 23:17-0500\n"
+"POT-Creation-Date: 2012-04-29 23:17-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -322,21 +322,21 @@
msgid "Scanning…"
msgstr ""
-#: ../nautilus/NautilusExtension.c:176
+#: ../nautilus/NautilusExtension.c:174
msgid "Restore Missing Files…"
msgstr ""
-#: ../nautilus/NautilusExtension.c:177
+#: ../nautilus/NautilusExtension.c:175
msgid "Restore deleted files from backup"
msgstr ""
-#: ../nautilus/NautilusExtension.c:219
+#: ../nautilus/NautilusExtension.c:217
msgid "Revert to Previous Version…"
msgid_plural "Revert to Previous Versions…"
msgstr[0] ""
msgstr[1] ""
-#: ../nautilus/NautilusExtension.c:223
+#: ../nautilus/NautilusExtension.c:221
msgid "Restore file from backup"
msgid_plural "Restore files from backup"
msgstr[0] ""
@@ -344,72 +344,68 @@
#. Translators: %2$s is the name of a removable drive, %1$s is a folder
#. on that removable drive.
-#: ../common/BackendFile.vala:86 ../common/CommonUtils.vala:447
+#: ../common/BackendFile.vala:135 ../common/CommonUtils.vala:433
#, c-format
msgid "%1$s on %2$s"
msgstr ""
-#: ../common/BackendFile.vala:124
+#: ../common/BackendFile.vala:168
#, c-format
msgid "Backup will begin when %s becomes connected."
msgstr ""
-#: ../common/BackendFile.vala:131 ../common/BackendRackspace.vala:49
+#: ../common/BackendFile.vala:175 ../common/BackendRackspace.vala:49
#: ../common/BackendS3.vala:59 ../common/BackendU1.vala:150
msgid "Backup will begin when a network connection becomes available."
msgstr ""
-#: ../common/BackendFile.vala:357 ../common/BackendFile.vala:421
+#: ../common/BackendFile.vala:384 ../common/BackendFile.vala:448
msgid "Backup location not available"
msgstr ""
-#: ../common/BackendFile.vala:358
+#: ../common/BackendFile.vala:385
msgid "Waiting for a network connection…"
msgstr ""
-#: ../common/BackendFile.vala:421
+#: ../common/BackendFile.vala:448
#, c-format
msgid "Waiting for ‘%s’ to become connected…"
msgstr ""
-#: ../common/BackendRackspace.vala:58
-msgid "You must specify a Rackspace container in your preferences."
-msgstr ""
-
-#: ../common/BackendRackspace.vala:67 ../widgets/ConfigLocation.vala:194
+#: ../common/BackendRackspace.vala:69 ../widgets/ConfigLocation.vala:194
msgid "Rackspace Cloud Files"
msgstr ""
#. Translators: %s is a folder.
-#: ../common/BackendRackspace.vala:70
+#: ../common/BackendRackspace.vala:72
#, c-format
msgid "%s on Rackspace Cloud Files"
msgstr ""
-#: ../common/BackendRackspace.vala:117 ../common/BackendS3.vala:172
+#: ../common/BackendRackspace.vala:119 ../common/BackendS3.vala:172
msgid "Permission denied"
msgstr ""
-#: ../common/BackendRackspace.vala:138
+#: ../common/BackendRackspace.vala:140
#, c-format
msgid ""
"You can sign up for a Rackspace Cloud Files account <a href=\"%s\">online</"
"a>."
msgstr ""
-#: ../common/BackendRackspace.vala:139
+#: ../common/BackendRackspace.vala:141
msgid "Connect to Rackspace Cloud Files"
msgstr ""
-#: ../common/BackendRackspace.vala:140
+#: ../common/BackendRackspace.vala:142
msgid "_API access key"
msgstr ""
-#: ../common/BackendRackspace.vala:141
+#: ../common/BackendRackspace.vala:143
msgid "S_how API access key"
msgstr ""
-#: ../common/BackendRackspace.vala:142
+#: ../common/BackendRackspace.vala:144
msgid "_Remember API access key"
msgstr ""
@@ -466,208 +462,68 @@
msgid "Sign into Ubuntu One…"
msgstr ""
+#: ../common/CommonUtils.vala:353
+#, c-format
+msgid "Could not find backup tool in %s. Your installation is incomplete."
+msgstr ""
+
+#: ../common/CommonUtils.vala:355
+msgid "Could not load backup tool. Your installation is incomplete."
+msgstr ""
+
+#: ../common/CommonUtils.vala:361
+msgid "Backup tool is broken. Your installation is incomplete."
+msgstr ""
+
+#: ../common/CommonUtils.vala:383
+msgid "Could not start backup tool"
+msgstr ""
+
#. Translators: this is the home folder and %s is the user's username
-#: ../common/CommonUtils.vala:498
+#: ../common/CommonUtils.vala:484
#, c-format
msgid "Home (%s)"
msgstr ""
#. Translators: this is the home folder
-#: ../common/CommonUtils.vala:503
+#: ../common/CommonUtils.vala:489
msgid "Home"
msgstr ""
#. Translators: this is the trash folder
-#: ../common/CommonUtils.vala:508
+#: ../common/CommonUtils.vala:494
msgid "Trash"
msgstr ""
-#: ../common/DuplicityInfo.vala:109
-msgid "Could not run duplicity"
-msgstr ""
-
-#: ../common/DuplicityInfo.vala:114
-msgid ""
-"Could not understand duplicity version.\n"
-"\n"
-msgstr ""
-
-#: ../common/DuplicityInfo.vala:116
-#, c-format
-msgid ""
-"Could not understand duplicity version ‘%s’.\n"
-"\n"
-msgstr ""
-
-#: ../common/DuplicityInfo.vala:118
-msgid ""
-"Without duplicity, Déjà Dup Backup Tool cannot function. It will close now."
-msgstr ""
-
-#: ../common/DuplicityInfo.vala:122
-msgid "Duplicity’s version is too old"
-msgstr ""
-
-#: ../common/DuplicityInfo.vala:123
-#, c-format
-msgid ""
-"Déjà Dup Backup Tool requires at least version %d.%d.%.2d of duplicity, but "
-"only found version %d.%d.%.2d"
-msgstr ""
-
-#: ../common/Duplicity.vala:135 ../common/Duplicity.vala:198
-msgid "Paused (no network)"
-msgstr ""
-
-#: ../common/Duplicity.vala:405 ../common/Duplicity.vala:412
-#: ../common/Duplicity.vala:431 ../common/Duplicity.vala:436
-#: ../common/Operation.vala:79 ../common/Operation.vala:111
-msgid "Preparing…"
-msgstr ""
-
-#. Was not even a file path (maybe something goofy like computer://)
-#: ../common/Duplicity.vala:463
-#, c-format
-msgid "Could not restore ‘%s’: Not a valid file location"
-msgstr ""
-
-#. Tiny backup location. Suggest they get a larger one.
-#: ../common/Duplicity.vala:529
-msgid "Backup location is too small. Try using one with more space."
-msgstr ""
-
-#: ../common/Duplicity.vala:551
-msgid "Backup location does not have enough free space."
-msgstr ""
-
-#: ../common/Duplicity.vala:570 ../common/Duplicity.vala:584
-msgid "Cleaning up…"
-msgstr ""
-
-#. OK, we succeeded yay! But some files didn't make it into the backup
-#. because we couldn't read them. So tell the user so they don't think
-#. everything is hunky dory.
-#: ../common/Duplicity.vala:679
-msgid ""
-"Could not back up the following files. Please make sure you are able to "
-"open them."
-msgstr ""
-
-#: ../common/Duplicity.vala:700 ../common/Duplicity.vala:1089
-#: ../deja-dup/AssistantOperation.vala:537
-msgid "Failed with an unknown error."
-msgstr ""
-
-#: ../common/Duplicity.vala:929
-#, c-format
-msgid "Could not restore ‘%s’: File not found in backup"
-msgstr ""
-
-#. notify upper layers, if they want to do anything
-#. Duplicity tried to ask the user what the encryption password is.
-#. notify upper layers, if they want to do anything
-#: ../common/Duplicity.vala:935 ../common/Duplicity.vala:1037
-#: ../common/Duplicity.vala:1041
-msgid "Bad encryption password."
-msgstr ""
-
-#: ../common/Duplicity.vala:940
-msgid "Computer name changed"
-msgstr ""
-
-#: ../common/Duplicity.vala:940
-#, c-format
-msgid ""
-"The existing backup is of a computer named %s, but the current computer’s "
-"name is %s. If this is unexpected, you should back up to a different "
-"location."
-msgstr ""
-
-#: ../common/Duplicity.vala:975
-#, c-format
-msgid "Permission denied when trying to create ‘%s’."
-msgstr ""
-
-#. assume error is on backend side
-#: ../common/Duplicity.vala:979 ../common/Duplicity.vala:983
-#, c-format
-msgid "Permission denied when trying to read ‘%s’."
-msgstr ""
-
-#: ../common/Duplicity.vala:987
-#, c-format
-msgid "Permission denied when trying to delete ‘%s’."
-msgstr ""
-
-#: ../common/Duplicity.vala:994
-#, c-format
-msgid "Backup location ‘%s’ does not exist."
-msgstr ""
-
-#: ../common/Duplicity.vala:1000 ../common/Duplicity.vala:1060
-msgid "No space left."
-msgstr ""
-
-#: ../common/Duplicity.vala:1014
-msgid "Invalid ID."
-msgstr ""
-
-#: ../common/Duplicity.vala:1016
-msgid "Invalid secret key."
-msgstr ""
-
-#: ../common/Duplicity.vala:1018
-msgid "Your Amazon Web Services account is not signed up for the S3 service."
-msgstr ""
-
-#: ../common/Duplicity.vala:1031
-msgid "S3 bucket name is not available."
-msgstr ""
-
-#: ../common/Duplicity.vala:1045
-#, c-format
-msgid "Error reading file ‘%s’."
-msgstr ""
-
-#: ../common/Duplicity.vala:1047
-#, c-format
-msgid "Error writing file ‘%s’."
-msgstr ""
-
-#: ../common/Duplicity.vala:1062
-#, c-format
-msgid "No space left in ‘%s’."
-msgstr ""
-
-#: ../common/Duplicity.vala:1070
-msgid "No backup files found"
-msgstr ""
-
-#: ../common/Duplicity.vala:1120
-msgid "Uploading…"
-msgstr ""
-
-#: ../common/OperationRestore.vala:52
+#: ../common/OperationRestore.vala:51
msgid "Restoring files…"
msgstr ""
-#: ../common/Operation.vala:71
+#: ../common/Operation.vala:60
msgid "Backing up…"
msgstr ""
-#: ../common/Operation.vala:73 ../deja-dup/AssistantRestore.vala:484
+#: ../common/Operation.vala:62 ../deja-dup/AssistantRestore.vala:484
msgid "Restoring…"
msgstr ""
-#: ../common/Operation.vala:75
+#: ../common/Operation.vala:64
msgid "Checking for backups…"
msgstr ""
-#: ../common/Operation.vala:77
+#: ../common/Operation.vala:66
msgid "Listing files…"
msgstr ""
-#: ../common/Operation.vala:281
+#: ../common/Operation.vala:68 ../common/Operation.vala:100
+#: ../tools/duplicity/DuplicityJob.vala:386
+#: ../tools/duplicity/DuplicityJob.vala:393
+#: ../tools/duplicity/DuplicityJob.vala:412
+#: ../tools/duplicity/DuplicityJob.vala:417
+msgid "Preparing…"
+msgstr ""
+
+#: ../common/Operation.vala:237
msgid "Another backup operation is already running"
msgstr ""
@@ -681,11 +537,11 @@
msgid "_Back Up"
msgstr ""
+#: ../deja-dup/AssistantBackup.vala:49
+msgid "Creating the first backup. This may take a while."
+msgstr ""
+
#: ../deja-dup/AssistantBackup.vala:50
-msgid "Creating the first backup. This may take a while."
-msgstr ""
-
-#: ../deja-dup/AssistantBackup.vala:51
msgid ""
"Creating a fresh backup to protect against backup corruption. This will "
"take longer than normal."
@@ -693,19 +549,19 @@
#. Translators: This is the phrase 'Backing up' in the larger phrase
#. "Backing up '%s'". %s is a filename.
-#: ../deja-dup/AssistantBackup.vala:81
+#: ../deja-dup/AssistantBackup.vala:80
msgid "Backing up:"
msgstr ""
-#: ../deja-dup/AssistantBackup.vala:90
+#: ../deja-dup/AssistantBackup.vala:89
msgid "Backup Failed"
msgstr ""
-#: ../deja-dup/AssistantBackup.vala:93
+#: ../deja-dup/AssistantBackup.vala:92
msgid "Backup Finished"
msgstr ""
-#: ../deja-dup/AssistantBackup.vala:101
+#: ../deja-dup/AssistantBackup.vala:100
msgid "Backing Up…"
msgstr ""
@@ -753,6 +609,12 @@
msgid "Summary"
msgstr ""
+#: ../deja-dup/AssistantOperation.vala:537
+#: ../tools/duplicity/DuplicityJob.vala:694
+#: ../tools/duplicity/DuplicityJob.vala:1076
+msgid "Failed with an unknown error."
+msgstr ""
+
#: ../deja-dup/AssistantOperation.vala:730
msgid "Require Password?"
msgstr ""
@@ -823,7 +685,7 @@
#. Translators: This is the word 'Restoring' in the phrase
#. "Restoring '%s'". %s is a filename.
-#: ../deja-dup/AssistantRestore.vala:307
+#: ../deja-dup/AssistantRestore.vala:306
msgid "Restoring:"
msgstr ""
@@ -831,38 +693,38 @@
#. This will be in a list with other strings that just have %x (the
#. current date). So make sure if you change this, it still makes
#. sense in that context.
-#: ../deja-dup/AssistantRestore.vala:349
+#: ../deja-dup/AssistantRestore.vala:348
#, c-format
msgid "%x %X"
msgstr ""
-#: ../deja-dup/AssistantRestore.vala:362
+#: ../deja-dup/AssistantRestore.vala:361
msgid "No backups to restore"
msgstr ""
-#: ../deja-dup/AssistantRestore.vala:439
+#: ../deja-dup/AssistantRestore.vala:437
msgid "Original location"
msgstr ""
-#: ../deja-dup/AssistantRestore.vala:450
+#: ../deja-dup/AssistantRestore.vala:448
msgid "File to restore"
msgid_plural "Files to restore"
msgstr[0] ""
msgstr[1] ""
+#: ../deja-dup/AssistantRestore.vala:469
+msgid "Restore Failed"
+msgstr ""
+
#: ../deja-dup/AssistantRestore.vala:471
-msgid "Restore Failed"
-msgstr ""
-
-#: ../deja-dup/AssistantRestore.vala:473
msgid "Restore Finished"
msgstr ""
-#: ../deja-dup/AssistantRestore.vala:475
+#: ../deja-dup/AssistantRestore.vala:474
msgid "Your files were successfully restored."
msgstr ""
-#: ../deja-dup/AssistantRestore.vala:478
+#: ../deja-dup/AssistantRestore.vala:477
msgid "Your file was successfully restored."
msgid_plural "Your files were successfully restored."
msgstr[0] ""
@@ -906,7 +768,7 @@
msgstr[0] ""
msgstr[1] ""
-#: ../deja-dup/AssistantRestoreMissing.vala:455
+#: ../deja-dup/AssistantRestoreMissing.vala:454
msgid "Scanning finished"
msgstr ""
@@ -990,20 +852,20 @@
msgid "S_how password"
msgstr ""
-#: ../deja-dup/MountOperationAssistant.vala:82
+#: ../deja-dup/MountOperationAssistant.vala:80
msgid "Location not available"
msgstr ""
-#: ../deja-dup/MountOperationAssistant.vala:168
+#: ../deja-dup/MountOperationAssistant.vala:166
msgid "Connect _anonymously"
msgstr ""
-#: ../deja-dup/MountOperationAssistant.vala:172
+#: ../deja-dup/MountOperationAssistant.vala:170
msgid "Connect as u_ser"
msgstr ""
#. Translators: this is a Windows networking domain
-#: ../deja-dup/MountOperationAssistant.vala:215
+#: ../deja-dup/MountOperationAssistant.vala:213
msgid "_Domain"
msgstr ""
@@ -1140,6 +1002,157 @@
msgid "Categories"
msgstr ""
+#: ../tools/duplicity/DuplicityJob.vala:89
+#: ../tools/duplicity/DuplicityJob.vala:173
+msgid "Paused (no network)"
+msgstr ""
+
+#. Was not even a file path (maybe something goofy like computer://)
+#: ../tools/duplicity/DuplicityJob.vala:444
+#, c-format
+msgid "Could not restore ‘%s’: Not a valid file location"
+msgstr ""
+
+#. Tiny backup location. Suggest they get a larger one.
+#: ../tools/duplicity/DuplicityJob.vala:510
+msgid "Backup location is too small. Try using one with more space."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:532
+msgid "Backup location does not have enough free space."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:551
+#: ../tools/duplicity/DuplicityJob.vala:565
+msgid "Cleaning up…"
+msgstr ""
+
+#. OK, we succeeded yay! But some files didn't make it into the backup
+#. because we couldn't read them. So tell the user so they don't think
+#. everything is hunky dory.
+#: ../tools/duplicity/DuplicityJob.vala:661
+msgid ""
+"Could not back up the following files. Please make sure you are able to "
+"open them."
+msgstr ""
+
+#. OK, we succeeded yay! But some files didn't actually restore
+#. because we couldn't write to them. So tell the user so they
+#. don't think everything is hunky dory.
+#: ../tools/duplicity/DuplicityJob.vala:677
+msgid ""
+"Could not restore the following files. Please make sure you are able to "
+"write to them."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:924
+#, c-format
+msgid "Could not restore ‘%s’: File not found in backup"
+msgstr ""
+
+#. notify upper layers, if they want to do anything
+#. Duplicity tried to ask the user what the encryption password is.
+#. notify upper layers, if they want to do anything
+#: ../tools/duplicity/DuplicityJob.vala:930
+#: ../tools/duplicity/DuplicityJob.vala:1028
+#: ../tools/duplicity/DuplicityJob.vala:1032
+msgid "Bad encryption password."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:935
+msgid "Computer name changed"
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:935
+#, c-format
+msgid ""
+"The existing backup is of a computer named %s, but the current computer’s "
+"name is %s. If this is unexpected, you should back up to a different "
+"location."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:970
+#, c-format
+msgid "Permission denied when trying to create ‘%s’."
+msgstr ""
+
+#. assume error is on backend side
+#: ../tools/duplicity/DuplicityJob.vala:974
+#: ../tools/duplicity/DuplicityJob.vala:978
+#, c-format
+msgid "Permission denied when trying to read ‘%s’."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:982
+#, c-format
+msgid "Permission denied when trying to delete ‘%s’."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:989
+#, c-format
+msgid "Backup location ‘%s’ does not exist."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:995
+#: ../tools/duplicity/DuplicityJob.vala:1047
+msgid "No space left."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1009
+msgid "Invalid ID."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1011
+msgid "Invalid secret key."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1013
+msgid "Your Amazon Web Services account is not signed up for the S3 service."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1022
+msgid "S3 bucket name is not available."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1036
+#, c-format
+msgid "Error reading file ‘%s’."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1038
+#, c-format
+msgid "Error writing file ‘%s’."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1049
+#, c-format
+msgid "No space left in ‘%s’."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1057
+msgid "No backup files found"
+msgstr ""
+
+#: ../tools/duplicity/DuplicityJob.vala:1107
+msgid "Uploading…"
+msgstr ""
+
+#: ../tools/duplicity/DuplicityPlugin.vala:41
+msgid "Could not understand duplicity version."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityPlugin.vala:47
+#, c-format
+msgid "Could not understand duplicity version ‘%s’."
+msgstr ""
+
+#: ../tools/duplicity/DuplicityPlugin.vala:64
+#, c-format
+msgid ""
+"Déjà Dup Backup Tool requires at least version %d.%d.%.2d of duplicity, but "
+"only found version %d.%d.%.2d"
+msgstr ""
+
#: ../widgets/ConfigDelete.vala:43
msgid "At least a month"
msgstr ""
@@ -1301,7 +1314,7 @@
msgid "Local Folder"
msgstr ""
-#: ../widgets/ConfigLocationCustom.vala:31
+#: ../widgets/ConfigLocationCustom.vala:33
msgid "_URI"
msgstr ""
@@ -1320,17 +1333,17 @@
msgstr ""
#: ../widgets/ConfigLocationDAV.vala:46 ../widgets/ConfigLocationFTP.vala:38
-#: ../widgets/ConfigLocationFile.vala:44 ../widgets/ConfigLocationS3.vala:33
+#: ../widgets/ConfigLocationFile.vala:45 ../widgets/ConfigLocationS3.vala:33
#: ../widgets/ConfigLocationSMB.vala:34 ../widgets/ConfigLocationSSH.vala:37
-#: ../widgets/ConfigLocationU1.vala:31 ../widgets/ConfigLocationVolume.vala:31
+#: ../widgets/ConfigLocationU1.vala:33 ../widgets/ConfigLocationVolume.vala:33
msgid "_Folder"
msgstr ""
-#: ../widgets/ConfigLocationFile.vala:38
+#: ../widgets/ConfigLocationFile.vala:39
msgid "_Choose Folder…"
msgstr ""
-#: ../widgets/ConfigLocationFile.vala:49
+#: ../widgets/ConfigLocationFile.vala:50
msgid "Choose Folder"
msgstr ""
=== modified file 'preferences/Makefile.am'
--- preferences/Makefile.am 2012-02-02 18:56:52 +0000
+++ preferences/Makefile.am 2012-04-30 17:55:21 +0000
@@ -67,6 +67,7 @@
$(SHARED_VALAFLAGS) \
--pkg @GTK_MODULE@ \
--pkg gio-2.0 \
+ --pkg libpeas-1.0 \
--pkg libcommon \
--pkg libwidgets \
--pkg config
=== modified file 'tests/runner/Makefile.am'
--- tests/runner/Makefile.am 2012-04-24 00:14:48 +0000
+++ tests/runner/Makefile.am 2012-04-30 17:55:21 +0000
@@ -45,6 +45,7 @@
$(NETWORKMONITOR_VALAFLAGS) \
--pkg config \
--pkg gio-2.0 \
+ --pkg libpeas-1.0 \
--pkg posix \
--pkg libcommon
=== modified file 'tests/runner/mock/duplicity'
--- tests/runner/mock/duplicity 2012-04-18 02:24:54 +0000
+++ tests/runner/mock/duplicity 2012-04-30 17:55:21 +0000
@@ -46,6 +46,10 @@
import sys, os, shlex, getpass, time
+if sys.argv[1] == '--version':
+ print 'duplicity 9.9.99'
+ sys.exit(0)
+
if not os.path.exists(os.environ['DEJA_DUP_TEST_MOCKSCRIPT']):
print >> logfd, "TESTFAIL: no mockscript"
sys.exit(-1)
=== modified file 'tests/runner/runner.vala'
--- tests/runner/runner.vala 2012-04-18 13:52:15 +0000
+++ tests/runner/runner.vala 2012-04-30 17:55:21 +0000
@@ -45,6 +45,7 @@
var cachedir = Path.build_filename(dir, "cache");
DirUtils.create_with_parents(Path.build_filename(cachedir, "deja-dup"), 0700);
+ Environment.set_variable("DEJA_DUP_TOOLS_PATH", "../../tools/duplicity", true);
Environment.set_variable("DEJA_DUP_TEST_MOCKSCRIPT", Path.build_filename(dir, "mockscript"), true);
Environment.set_variable("XDG_CACHE_HOME", cachedir, true);
Environment.set_variable("PATH", "./mock:" + Environment.get_variable("PATH"), true);
=== modified file 'tests/unit/Makefile.am'
--- tests/unit/Makefile.am 2012-04-24 00:14:48 +0000
+++ tests/unit/Makefile.am 2012-04-30 17:55:21 +0000
@@ -50,6 +50,7 @@
$(NETWORKMONITOR_VALAFLAGS) \
--pkg config \
--pkg gio-2.0 \
+ --pkg libpeas-1.0 \
--pkg posix \
--pkg libcommon
=== added directory 'tools'
=== added file 'tools/Makefile.am'
--- tools/Makefile.am 1970-01-01 00:00:00 +0000
+++ tools/Makefile.am 2012-04-30 17:55:21 +0000
@@ -0,0 +1,20 @@
+# -*- Mode: Makefile; indent-tabs-mode: t; tab-width: 2 -*-
+#
+# This file is part of Déjà Dup.
+# For copyright information, see AUTHORS.
+#
+# Déjà Dup is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Déjà Dup is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
+
+SUBDIRS = duplicity
+
=== added directory 'tools/duplicity'
=== renamed file 'common/DuplicityInstance.vala' => 'tools/duplicity/DuplicityInstance.vala'
--- common/DuplicityInstance.vala 2012-03-19 15:27:18 +0000
+++ tools/duplicity/DuplicityInstance.vala 2012-04-30 17:55:21 +0000
@@ -19,8 +19,6 @@
using GLib;
-namespace DejaDup {
-
internal class DuplicityInstance : Object
{
public signal void done(bool success, bool cancelled);
@@ -38,8 +36,8 @@
verbose = true;
if (as_root) {
- var settings = get_settings();
- if (!settings.get_boolean(ROOT_PROMPT_KEY))
+ var settings = DejaDup.get_settings();
+ if (!settings.get_boolean(DejaDup.ROOT_PROMPT_KEY))
as_root = false;
}
@@ -591,5 +589,3 @@
}
}
-} // end namespace
-
=== renamed file 'common/Duplicity.vala' => 'tools/duplicity/DuplicityJob.vala'
--- common/Duplicity.vala 2012-03-22 14:44:44 +0000
+++ tools/duplicity/DuplicityJob.vala 2012-04-30 17:55:21 +0000
@@ -19,57 +19,12 @@
using GLib;
-namespace DejaDup {
-
-internal class Duplicity : Object
+internal class DuplicityJob : DejaDup.ToolJob
{
- /*
- * Vala implementation of various methods for accessing duplicity
- *
- * Vala implementation of various methods for accessing duplicity from
- * vala withot the need of manually running duplicity command.
- */
+ DejaDup.ToolJob.Mode original_mode {get; private set;}
+ bool error_issued {get; private set; default = false;}
+ bool was_stopped {get; private set; default = false;}
- public signal void done(bool success, bool cancelled, string? detail);
- public signal void raise_error(string errstr, string? detail);
- public signal void action_desc_changed(string action);
- public signal void action_file_changed(File file, bool actual);
- public signal void progress(double percent);
- /*
- * Signal emitted when collection dates are retrieved from duplicity
- */
- public signal void collection_dates(List<string>? dates);
- public signal void listed_current_files(string date, string file);
- public signal void question(string title, string msg);
- public signal void is_full(bool first);
- public signal void bad_encryption_password();
-
- public Operation.Mode original_mode {get; construct;}
- public Operation.Mode mode {get; private set; default = Operation.Mode.INVALID;}
- public bool error_issued {get; private set; default = false;}
- public bool was_stopped {get; private set; default = false;}
-
- public File local {get; set;}
- public Backend backend {get; set;}
- public List<File> includes;
- public List<File> excludes;
- public bool use_progress {get; set; default = true;}
- public string encrypt_password {private get; set; default = null;}
-
- private List<File> _restore_files;
- public List<File> restore_files {
- get {
- return this._restore_files;
- }
- set {
- foreach (File f in this._restore_files)
- f.unref();
- this._restore_files = value.copy();
- foreach (File f in this._restore_files)
- f.ref();
- }
- }
-
protected enum State {
NORMAL,
DRY_RUN, // used when backing up, and we need to first get time estimate
@@ -128,16 +83,12 @@
void network_changed()
{
- if (Network.get().connected)
+ if (DejaDup.Network.get().connected)
resume();
else
pause(_("Paused (no network)"));
}
- public Duplicity(Operation.Mode mode) {
- Object(original_mode: mode);
- }
-
construct {
if (slash == null) {
slash = File.new_for_path("/");
@@ -157,34 +108,67 @@
}
~Duplicity() {
- Network.get().notify["connected"].disconnect(network_changed);
+ DejaDup.Network.get().notify["connected"].disconnect(network_changed);
}
- public virtual void start(Backend backend,
- List<string>? argv, List<string>? envp)
+ public override void start()
{
// save arguments for calling duplicity again later
+ if (original_mode == DejaDup.ToolJob.Mode.INVALID)
+ original_mode = mode;
mode = original_mode;
- this.backend = backend;
saved_argv = new List<string>();
saved_envp = new List<string>();
backend_argv = new List<string>();
- foreach (string s in argv) saved_argv.append(s);
- foreach (string s in envp) saved_envp.append(s);
- backend.add_argv(Operation.Mode.INVALID, ref backend_argv);
+ backend.add_argv(DejaDup.ToolJob.Mode.INVALID, ref backend_argv);
+ backend.add_argv(mode, ref saved_argv);
- if (mode == Operation.Mode.BACKUP)
+ if (mode == DejaDup.ToolJob.Mode.BACKUP)
process_include_excludes();
- var settings = get_settings();
- delete_age = settings.get_int(DELETE_AFTER_KEY);
+ var settings = DejaDup.get_settings();
+ delete_age = settings.get_int(DejaDup.DELETE_AFTER_KEY);
+
+ get_envp();
+ }
+
+ async void get_envp()
+ {
+ try {
+ backend.envp_ready.connect(continue_with_envp);
+ yield backend.get_envp();
+ }
+ catch (Error e) {
+ raise_error(e.message, null);
+ done(false, false, null);
+ }
+ }
+
+ void continue_with_envp(DejaDup.Backend b, bool success, List<string>? envp, string? error)
+ {
+ /*
+ * Starts Duplicity backup with added enviroment variables
+ *
+ * Start Duplicity backup process with costum values for enviroment variables.
+ */
+ backend.envp_ready.disconnect(continue_with_envp);
+
+ if (!success) {
+ if (error != null)
+ raise_error(error, null);
+ done(false, false, null);
+ return;
+ }
+
+ foreach (string s in envp)
+ saved_envp.append(s);
if (!restart())
done(false, false, null);
if (!backend.is_native()) {
- Network.get().notify["connected"].connect(network_changed);
- if (!Network.get().connected) {
+ DejaDup.Network.get().notify["connected"].connect(network_changed);
+ if (!DejaDup.Network.get().connected) {
debug("No connection found. Postponing the backup.");
pause(_("Paused (no network)"));
}
@@ -337,11 +321,11 @@
saved_argv.append("--exclude=**");
}
- public void cancel() {
+ public override void cancel() {
var prev_mode = mode;
- mode = Operation.Mode.INVALID;
+ mode = DejaDup.ToolJob.Mode.INVALID;
- if (prev_mode == Operation.Mode.BACKUP && state == State.NORMAL) {
+ if (prev_mode == DejaDup.ToolJob.Mode.BACKUP && state == State.NORMAL) {
if (cleanup())
return;
}
@@ -349,14 +333,14 @@
cancel_inst();
}
- public void stop() {
+ public override void stop() {
// just abruptly stop, without a cleanup, duplicity will resume
was_stopped = true;
- mode = Operation.Mode.INVALID;
+ mode = DejaDup.ToolJob.Mode.INVALID;
cancel_inst();
}
- public void pause(string? reason)
+ public override void pause(string? reason)
{
if (inst != null) {
inst.pause();
@@ -365,7 +349,7 @@
}
}
- public void resume()
+ public override void resume()
{
if (inst != null) {
inst.resume();
@@ -385,7 +369,7 @@
if (restore_files == null) // only clear if we're not in middle of restore sequence
local_error_files = null;
- if (mode == Operation.Mode.INVALID)
+ if (mode == DejaDup.ToolJob.Mode.INVALID)
return false;
var extra_argv = new List<string>();
@@ -393,18 +377,18 @@
File custom_local = null;
switch (original_mode) {
- case Operation.Mode.BACKUP:
+ case DejaDup.ToolJob.Mode.BACKUP:
// We need to first check the backup status to see if we need to start
// a full backup and to see if we should use encryption.
if (!checked_collection_info) {
- mode = Operation.Mode.STATUS;
+ mode = DejaDup.ToolJob.Mode.STATUS;
state = State.STATUS;
action_desc = _("Preparing…");
}
// If we're backing up, and the version of duplicity supports it, we should
// first run using --dry-run to get the total size of the backup, to make
// accurate progress bars.
- else if (use_progress && !has_progress_total) {
+ else if ((flags & DejaDup.ToolJob.Flags.NO_PROGRESS) == 0 && !has_progress_total) {
state = State.DRY_RUN;
action_desc = _("Preparing…");
extra_argv.append("--dry-run");
@@ -419,16 +403,16 @@
}
break;
- case Operation.Mode.RESTORE:
+ case DejaDup.ToolJob.Mode.RESTORE:
// We need to first check the backup status to see if we should use
// encryption.
if (!checked_collection_info) {
- mode = Operation.Mode.STATUS;
+ mode = DejaDup.ToolJob.Mode.STATUS;
state = State.STATUS;
action_desc = _("Preparing…");
}
else if (!has_checked_contents) {
- mode = Operation.Mode.LIST;
+ mode = DejaDup.ToolJob.Mode.LIST;
state = State.CHECK_CONTENTS;
action_desc = _("Preparing…");
}
@@ -494,7 +478,7 @@
// Send appropriate description for what we're about to do. Is often
// very quickly overridden by a message like "Backing up file X"
if (action_desc == null)
- action_desc = Operation.mode_to_string(mode);
+ action_desc = DejaDup.Operation.mode_to_string(mode);
set_status(action_desc);
connect_and_start(extra_argv, null, null, custom_local);
@@ -633,7 +617,7 @@
/* Set full backup threshold and determine whether we should trigger
a full backup. */
- if (mode == Operation.Mode.BACKUP && got_collection_info) {
+ if (mode == DejaDup.ToolJob.Mode.BACKUP && got_collection_info) {
Date threshold = DejaDup.get_full_backup_threshold_date();
Date full_backup = Date();
foreach (DateInfo info in collection_info) {
@@ -661,7 +645,7 @@
break;
case State.NORMAL:
- if (mode == Operation.Mode.RESTORE && restore_files != null) {
+ if (mode == DejaDup.ToolJob.Mode.RESTORE && restore_files != null) {
_restore_files.delete_link(_restore_files);
if (restore_files != null) {
if (restart())
@@ -669,7 +653,7 @@
}
}
- if (mode == Operation.Mode.BACKUP) {
+ if (mode == DejaDup.ToolJob.Mode.BACKUP) {
if (local_error_files != null) {
// OK, we succeeded yay! But some files didn't make it into the backup
// because we couldn't read them. So tell the user so they don't think
@@ -681,11 +665,11 @@
}
}
- mode = Operation.Mode.INVALID; // mark 'done' so when we delete, we don't restart
+ mode = DejaDup.ToolJob.Mode.INVALID; // mark 'done' so when we delete, we don't restart
if (delete_files_if_needed())
return;
}
- else if (mode == Operation.Mode.RESTORE) {
+ else if (mode == DejaDup.ToolJob.Mode.RESTORE) {
if (local_error_files != null) {
// OK, we succeeded yay! But some files didn't actually restore
// because we couldn't write to them. So tell the user so they
@@ -899,7 +883,7 @@
{
disconnect_inst();
question(t, m);
- var rv = mode != Operation.Mode.INVALID; // return whether we were canceled
+ var rv = mode != DejaDup.ToolJob.Mode.INVALID; // return whether we were canceled
if (!rv)
handle_done(null, false, true);
return rv;
@@ -964,7 +948,7 @@
// If it's still bad, we'll do a full cleanup and try again.
// If it's *still* bad, tell the user, but I'm not sure what they can
// do about it.
- if (mode == Operation.Mode.BACKUP) {
+ if (mode == DejaDup.ToolJob.Mode.BACKUP) {
// strip date info from volume (after cleanup below, we'll get new date)
var this_volume = parse_duplicity_file(firstline[2], 2);
if (last_bad_volume != this_volume) {
@@ -1030,7 +1014,7 @@
break;
case "S3CreateError":
if (text.contains("<Code>BucketAlreadyExists</Code>")) {
- if (((BackendS3)backend).bump_bucket()) {
+ if (((DejaDup.BackendS3)backend).bump_bucket()) {
if (restart()) // get_remote() will eventually grab new bucket name
return;
}
@@ -1048,14 +1032,14 @@
show_error(_("Bad encryption password."));
else if (text.contains("[Errno 5]") && // I/O Error
last_touched_file != null) {
- if (mode == Operation.Mode.BACKUP)
+ if (mode == DejaDup.ToolJob.Mode.BACKUP)
show_error(_("Error reading file ‘%s’.").printf(last_touched_file.get_parse_name()));
else
show_error(_("Error writing file ‘%s’.").printf(last_touched_file.get_parse_name()));
}
else if (text.contains("[Errno 28]")) { // No space left on device
string where = null;
- if (mode == Operation.Mode.BACKUP)
+ if (mode == DejaDup.ToolJob.Mode.BACKUP)
where = backend.get_location_pretty();
else
where = local.get_path();
@@ -1138,8 +1122,8 @@
if (firstline.length > 1) {
switch (int.parse(firstline[1])) {
case DEBUG_GENERIC:
- if (mode == Operation.Mode.STATUS &&
- !DuplicityInfo.get_default().reports_encryption &&
+ if (mode == DejaDup.ToolJob.Mode.STATUS &&
+ /*!DuplicityInfo.get_default().reports_encryption &&*/
!detected_encryption) {
if (gpg_regex != null && gpg_regex.match(text)) {
detected_encryption = true;
@@ -1153,7 +1137,7 @@
void process_file_stat(string date, string file, List<string> data, string text)
{
- if (mode != Operation.Mode.LIST)
+ if (mode != DejaDup.ToolJob.Mode.LIST)
return;
if (state == State.CHECK_CONTENTS) {
var gfile = make_file_obj(file);
@@ -1223,7 +1207,7 @@
* this all up and report back to caller via a signal.
* We're really only interested in the list of entries in the complete chain.
*/
- if (mode != Operation.Mode.STATUS || got_collection_info)
+ if (mode != DejaDup.ToolJob.Mode.STATUS || got_collection_info)
return;
var timeval = TimeVal();
@@ -1247,6 +1231,7 @@
info.full = tokens[1] == "full";
infos.append(info);
+/*
if (DuplicityInfo.get_default().reports_encryption &&
!detected_encryption &&
tokens.length > 4) {
@@ -1255,6 +1240,7 @@
detected_encryption = true;
existing_encrypted = tokens[4] == "enc";
}
+*/
}
}
else if (in_chain)
@@ -1283,7 +1269,7 @@
// up before we continue. We don't want to wait until we finish to
// clean them up, since we may want that space, and if there's a bug
// in ourselves, we may never get to it.
- if (mode == Operation.Mode.BACKUP && !this.cleaned_up_once)
+ if (mode == DejaDup.ToolJob.Mode.BACKUP && !this.cleaned_up_once)
cleanup(); // stops current backup, cleans up, then resumes
break;
@@ -1349,7 +1335,7 @@
//
// For local filesystems, we'll choose large volsize.
// For remote FSs, we'll go smaller.
- if (in_testing_mode())
+ if (DejaDup.in_testing_mode())
return 1;
else if (backend.is_native())
return 50;
@@ -1403,24 +1389,26 @@
if (argv_entire == null) {
// add operation, local, and remote args
switch (mode) {
- case Operation.Mode.BACKUP:
+ case DejaDup.ToolJob.Mode.BACKUP:
if (is_full_backup)
argv.prepend("full");
argv.append("--volsize=%d".printf(get_volsize()));
argv.append(local_arg.get_path());
argv.append(get_remote());
break;
- case Operation.Mode.RESTORE:
+ case DejaDup.ToolJob.Mode.RESTORE:
argv.prepend("restore");
+ if (time != null)
+ argv.append("--time=%s".printf(time));
argv.append("--force");
argv.append(get_remote());
argv.append(local_arg.get_path());
break;
- case Operation.Mode.STATUS:
+ case DejaDup.ToolJob.Mode.STATUS:
argv.prepend("collection-status");
argv.append(get_remote());
break;
- case Operation.Mode.LIST:
+ case DejaDup.ToolJob.Mode.LIST:
argv.prepend("list-current-files");
argv.append(get_remote());
break;
@@ -1462,5 +1450,3 @@
}
}
-} // end namespace
-
=== added file 'tools/duplicity/DuplicityPlugin.vala'
--- tools/duplicity/DuplicityPlugin.vala 1970-01-01 00:00:00 +0000
+++ tools/duplicity/DuplicityPlugin.vala 2012-04-30 17:55:21 +0000
@@ -0,0 +1,84 @@
+/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
+/*
+ This file is part of Déjà Dup.
+ For copyright information, see AUTHORS.
+
+ Déjà Dup is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Déjà Dup is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib;
+
+public class DuplicityPlugin : DejaDup.ToolPlugin
+{
+ bool has_been_setup = false;
+
+ construct
+ {
+ name = "Duplicity";
+ }
+
+ static const int REQUIRED_MAJOR = 0;
+ static const int REQUIRED_MINOR = 6;
+ static const int REQUIRED_MICRO = 14;
+ void do_initial_setup () throws Error
+ {
+ string output;
+ Process.spawn_command_line_sync("duplicity --version", out output, null, null);
+
+ var tokens = output.split(" ", 2);
+ if (tokens == null || tokens[0] == null || tokens[1] == null)
+ throw new SpawnError.FAILED(_("Could not understand duplicity version."));
+
+ // First token is 'duplicity' and is ignorable. Second looks like '0.5.03'
+ var version_string = tokens[1].strip();
+ var ver_tokens = version_string.split(".");
+ if (ver_tokens == null || ver_tokens[0] == null)
+ throw new SpawnError.FAILED(_("Could not understand duplicity version ‘%s’.").printf(version_string));
+
+ int major = 0;
+ int minor = 0;
+ int micro = 0;
+ major = int.parse(ver_tokens[0]);
+ // Don't error out if no minor or micro. Duplicity might not have them?
+ if (ver_tokens[1] != null) {
+ minor = int.parse(ver_tokens[1]);
+ if (ver_tokens[2] != null)
+ micro = int.parse(ver_tokens[2]);
+ }
+
+ var meets = (major > REQUIRED_MAJOR) ||
+ (major == REQUIRED_MAJOR && minor > REQUIRED_MINOR) ||
+ (major == REQUIRED_MAJOR && minor == REQUIRED_MINOR && micro >= REQUIRED_MICRO);
+ if (!meets)
+ throw new SpawnError.FAILED(_("Déjà Dup Backup Tool requires at least version %d.%d.%.2d of duplicity, but only found version %d.%d.%.2d").printf(REQUIRED_MAJOR, REQUIRED_MINOR, REQUIRED_MICRO, major, minor, micro));
+ }
+
+ public override DejaDup.ToolJob create_job () throws Error
+ {
+ if (!has_been_setup) {
+ do_initial_setup();
+ has_been_setup = true;
+ }
+ return new DuplicityJob();
+ }
+}
+
+[ModuleInit]
+public void peas_register_types (GLib.TypeModule module)
+{
+ var objmodule = module as Peas.ObjectModule;
+ objmodule.register_extension_type (typeof (Peas.Activatable),
+ typeof (DuplicityPlugin));
+}
+
=== added file 'tools/duplicity/Makefile.am'
--- tools/duplicity/Makefile.am 1970-01-01 00:00:00 +0000
+++ tools/duplicity/Makefile.am 2012-04-30 17:55:21 +0000
@@ -0,0 +1,63 @@
+# -*- Mode: Makefile; indent-tabs-mode: t; tab-width: 2 -*-
+#
+# This file is part of Déjà Dup.
+# For copyright information, see AUTHORS.
+#
+# Déjà Dup is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Déjà Dup is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
+
+toolsdir = $(pkglibexecdir)/tools
+tools_LTLIBRARIES = libduplicity.la
+
+libduplicity_la_CFLAGS = \
+ -I$(top_srcdir)/common \
+ $(COMMON_CFLAGS) \
+ $(DEBUG_CFLAGS) \
+ -DPKG_LIBEXEC_DIR=\"$(pkglibexecdir)\" \
+ -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
+
+libduplicity_la_LDFLAGS = -module -avoid-version
+
+libduplicity_la_LIBADD = \
+ $(COMMON_LIBS) \
+ @INTLLIBS@
+
+libduplicity_la_VALASOURCES = \
+ DuplicityInstance.vala \
+ DuplicityJob.vala \
+ DuplicityPlugin.vala \
+ RecursiveDelete.vala \
+ RecursiveMove.vala \
+ RecursiveOp.vala
+
+libduplicity_la_SOURCES = \
+ $(libduplicity_la_VALASOURCES)
+
+AM_VALAFLAGS = \
+ --library=libduplicity \
+ --vapidir $(top_srcdir)/common \
+ --vapidir=$(top_srcdir)/vapi \
+ $(SHARED_VALAFLAGS) \
+ --pkg gio-2.0 \
+ --pkg libpeas-1.0 \
+ --pkg gio-unix-2.0 \
+ --pkg posix \
+ --pkg libcommon \
+ --pkg config
+
+libduplicity_la_vala.stamp: $(top_srcdir)/config.h
+
+dist-hook:
+ cd $(distdir) && rm -f $(libduplicity_la_VALASOURCES:.vala=.c) \
+ libduplicity_la_vala.stamp
+
=== renamed file 'common/RecursiveDelete.vala' => 'tools/duplicity/RecursiveDelete.vala'
--- common/RecursiveDelete.vala 2011-11-06 01:16:05 +0000
+++ tools/duplicity/RecursiveDelete.vala 2012-04-30 17:55:21 +0000
@@ -19,8 +19,6 @@
using GLib;
-namespace DejaDup {
-
internal class RecursiveDelete : RecursiveOp
{
public RecursiveDelete(File source)
@@ -59,5 +57,3 @@
}
}
-} // end namespace
-
=== renamed file 'common/RecursiveMove.vala' => 'tools/duplicity/RecursiveMove.vala'
--- common/RecursiveMove.vala 2011-11-06 01:16:05 +0000
+++ tools/duplicity/RecursiveMove.vala 2012-04-30 17:55:21 +0000
@@ -19,8 +19,6 @@
using GLib;
-namespace DejaDup {
-
/**
* Recursively moves one directory into another, merging files. And by merge,
* I mean it overwrites. It skips any files it can't move and reports an
@@ -164,5 +162,3 @@
}
}
-} // end namespace
-
=== renamed file 'common/RecursiveOp.vala' => 'tools/duplicity/RecursiveOp.vala'
--- common/RecursiveOp.vala 2012-03-22 14:44:44 +0000
+++ tools/duplicity/RecursiveOp.vala 2012-04-30 17:55:21 +0000
@@ -19,8 +19,6 @@
using GLib;
-namespace DejaDup {
-
internal abstract class RecursiveOp : Object
{
public signal void done();
@@ -131,5 +129,3 @@
}
}
-} // end namespace
-
=== added file 'tools/duplicity/duplicity.plugin'
--- tools/duplicity/duplicity.plugin 1970-01-01 00:00:00 +0000
+++ tools/duplicity/duplicity.plugin 2012-04-30 17:55:21 +0000
@@ -0,0 +1,8 @@
+[Plugin]
+Loader=c
+Module=libduplicity.so
+Name=Duplicity Backend
+Description=Backs up with duplicity
+Authors=Michael Terry <michael.terry@xxxxxxxxxxxxx>
+Copyright=Copyright © 2012 Canonical Ltd
+Website=https://launchpad.net/deja-dup
=== modified file 'widgets/Makefile.am'
--- widgets/Makefile.am 2012-02-02 18:56:52 +0000
+++ widgets/Makefile.am 2012-04-30 17:55:21 +0000
@@ -78,6 +78,7 @@
$(UNITY_VALAFLAGS) \
--pkg libcommon \
--pkg @GTK_MODULE@ \
+ --pkg libpeas-1.0 \
--pkg uriutils \
--pkg libnotify \
--pkg config
Follow ups