1
/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
3
This file is part of Déjà Dup.
4
For copyright information, see AUTHORS.
6
Déjà Dup is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
11
Déjà Dup is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
24
public const string U1_ROOT = "U1";
25
public const string U1_FOLDER_KEY = "folder";
27
class Listener : Object
29
public delegate void Handler(string name, Variant args);
30
public DBusProxy proxy {get; construct;}
31
public string method {get; construct;}
32
public Variant args {get; construct;}
33
public unowned Handler handler {get; set;}
35
public Listener(DBusProxy proxy, string method, Variant? args, Handler handler)
37
Object(proxy: proxy, method: method, args: args);
38
this.handler = handler;
43
loop = new MainLoop(null, false);
49
call_but_quit_on_fail.begin();
52
proxy.g_signal.connect(handle_dbus_signal);
54
proxy.g_signal.disconnect(handle_dbus_signal);
57
async void call_but_quit_on_fail()
60
yield proxy.call(method, args, DBusCallFlags.NONE, -1, null);
63
warning("%s\n", e.message);
68
void handle_dbus_signal(DBusProxy obj, string? sender, string name, Variant args)
70
// Stop on first signal
76
class U1Checker : Checker
81
var proxy = BackendU1.get_creds_proxy();
82
if (proxy.get_name_owner() == null) {
88
warning("%s\n", e.message);
94
// A bit of abstraction leakage here; we have to keep these imports in
95
// line with what duplicity uses. Maybe we should add to duplicity a way
96
// to ask 'can I use this backend?'
97
pyu1 = PythonChecker.get_checker("ubuntuone.platform.credentials, ubuntuone.couch.auth");
99
available = pyu1.available;
100
complete = pyu1.complete;
103
pyu1.notify["complete"].connect(() => {
104
available = pyu1.available;
105
complete = pyu1.complete;
113
public class BackendU1 : Backend
115
ulong button_handler = 0;
117
static Checker checker_instance = null;
118
public static Checker get_checker()
120
if (checker_instance == null)
121
checker_instance = new U1Checker();
122
return checker_instance;
125
public override Backend clone() {
126
return new BackendU1();
131
if (button_handler > 0) {
132
mount_op.disconnect(button_handler);
137
public override bool is_native() {
141
public override bool space_can_be_infinite() {
145
public override Icon? get_icon() {
146
return new ThemedIcon.from_names({"ubuntuone", "ubuntuone-installer", "deja-dup-cloud"});
149
public override async bool is_ready(out string when) {
150
when = _("Backup will begin when a network connection becomes available.");
151
return yield Network.get().can_reach ("https://one.ubuntu.com/");
154
public override string get_location(ref bool as_root)
156
// The UI backend for duplicity needs to talk to our session dbus, but it
160
var settings = get_settings(U1_ROOT);
161
var folder = get_folder_key(settings, U1_FOLDER_KEY);
162
return "u1+http://%s".printf(folder);
165
public override string get_location_pretty()
167
var settings = get_settings(U1_ROOT);
168
var folder = get_folder_key(settings, U1_FOLDER_KEY);
170
return _("Ubuntu One");
172
// Translators: %s is a folder.
173
return _("%s on Ubuntu One").printf(folder);
176
public override async uint64 get_space(bool free = true)
178
DBusProxy obj = null;
180
obj = get_prefs_proxy();
183
warning("%s\n", e.message);
184
return INFINITE_SPACE;
187
if (obj.get_name_owner() == null)
188
return INFINITE_SPACE;
190
uint64 total = INFINITE_SPACE;
192
var listener = new Listener(obj, "account_info", null, (name, args) => {
193
if (name == "AccountInfoReady") {
195
args.get("(a{ss})", out iter);
197
while (iter.next("{ss}", out key, out val)) {
198
if (key == "quota_total")
199
total = uint64.parse(val);
200
else if (key == "quota_used")
201
used = uint64.parse(val);
208
return (total > used) ? (total - used) : 0;
213
public override async void get_envp() throws Error
216
var obj = get_creds_proxy();
217
if (obj.get_name_owner() == null) {
222
var listener = new Listener(obj, "find_credentials", null, (name, args) => {
223
if (name == "CredentialsFound")
229
envp_ready(true, null);
234
void button_clicked()
239
void ask_password() {
240
mount_op.set("label_title", _("Connect to Ubuntu One"));
241
mount_op.set("label_button", _("Sign into Ubuntu One…"));
242
if (button_handler == 0)
243
button_handler = Signal.connect_swapped(mount_op, "button-clicked",
244
(Callback)button_clicked, this);
245
mount_op.ask_password("", "", "", 0);
251
var obj = get_creds_proxy();
252
if (obj.get_name_owner() == null) {
253
envp_ready(false, null);
257
var listener = new Listener(obj, "login", new Variant("(a{ss})", null),
259
if (name == "CredentialsFound") {
260
mount_op.set("go_forward", true);
261
envp_ready(true, null);
267
warning("%s\n", e.message);
268
envp_ready(false, null);
272
public static DBusProxy get_creds_proxy() throws Error
274
DBusProxy creds_proxy;
275
creds_proxy = new DBusProxy.for_bus_sync(BusType.SESSION,
276
DBusProxyFlags.NONE, null,
277
"com.ubuntuone.Credentials",
279
"com.ubuntuone.CredentialsManagement",
284
public static DBusProxy get_prefs_proxy() throws Error
286
DBusProxy prefs_proxy;
287
prefs_proxy = new DBusProxy.for_bus_sync(BusType.SESSION,
288
DBusProxyFlags.NONE, null,
289
"com.ubuntuone.controlpanel",
291
"com.ubuntuone.controlpanel.Preferences",