~ubuntu-branches/ubuntu/saucy/deja-dup/saucy

« back to all changes in this revision

Viewing changes to .pc/support-new-u1backend.patch/common/BackendU1.vala

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2012-10-30 19:03:03 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20121030190303-w3fatge63ncm5uiw
Tags: 25.1.1-0ubuntu1
* New upstream release
* debian/control:
  - Use libsecret, not libgnome-keyring
  - Switch to valac-0.18
  - Add various deja-dup-backend-* metapackages to make seeding
    different ones easier for flavors
* debian/tests:
  - Add dep8 test to run upstream test suite against system install
* debian/patches/support-new-u1backend.patch:
  - Support new u1backend in duplicity 0.6.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
 
2
/*
 
3
    This file is part of Déjà Dup.
 
4
    For copyright information, see AUTHORS.
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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/>.
 
18
*/
 
19
 
 
20
using GLib;
 
21
 
 
22
namespace DejaDup {
 
23
 
 
24
public const string U1_ROOT = "U1";
 
25
public const string U1_FOLDER_KEY = "folder";
 
26
 
 
27
class Listener : Object
 
28
{
 
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;}
 
34
 
 
35
  public Listener(DBusProxy proxy, string method, Variant? args, Handler handler)
 
36
  {
 
37
    Object(proxy: proxy, method: method, args: args);
 
38
    this.handler = handler;
 
39
  }
 
40
 
 
41
  MainLoop loop;
 
42
  construct {
 
43
    loop = new MainLoop(null, false);
 
44
  }
 
45
 
 
46
  public void run()
 
47
  {
 
48
    Idle.add(() => {
 
49
      call_but_quit_on_fail.begin();
 
50
      return false;
 
51
    });
 
52
    proxy.g_signal.connect(handle_dbus_signal);
 
53
    loop.run();
 
54
    proxy.g_signal.disconnect(handle_dbus_signal);
 
55
  }
 
56
 
 
57
  async void call_but_quit_on_fail()
 
58
  {
 
59
    try {
 
60
      yield proxy.call(method, args, DBusCallFlags.NONE, -1, null);
 
61
    }
 
62
    catch (Error e) {
 
63
      warning("%s\n", e.message);
 
64
      loop.quit();
 
65
    }
 
66
  }
 
67
 
 
68
  void handle_dbus_signal(DBusProxy obj, string? sender, string name, Variant args)
 
69
  {
 
70
    // Stop on first signal
 
71
    handler(name, args);
 
72
    loop.quit();
 
73
  }
 
74
}
 
75
 
 
76
class U1Checker : Checker
 
77
{
 
78
  PythonChecker pyu1;
 
79
  construct {
 
80
    try {
 
81
      var proxy = BackendU1.get_creds_proxy();
 
82
      if (proxy.get_name_owner() == null) {
 
83
        available = false;
 
84
        complete = true;
 
85
      }
 
86
    }
 
87
    catch (Error e) {
 
88
      warning("%s\n", e.message);
 
89
      available = false;
 
90
      complete = true;
 
91
    }
 
92
 
 
93
    if (!complete) {
 
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");
 
98
      if (pyu1.complete) {
 
99
        available = pyu1.available;
 
100
        complete = pyu1.complete;
 
101
      }
 
102
      else {
 
103
        pyu1.notify["complete"].connect(() => {
 
104
          available = pyu1.available;
 
105
          complete = pyu1.complete;
 
106
          pyu1 = null;
 
107
        });
 
108
      }
 
109
    }
 
110
  }
 
111
}
 
112
 
 
113
public class BackendU1 : Backend
 
114
{
 
115
  ulong button_handler = 0;
 
116
 
 
117
  static Checker checker_instance = null;
 
118
  public static Checker get_checker()
 
119
  {
 
120
    if (checker_instance == null)
 
121
      checker_instance = new U1Checker();
 
122
    return checker_instance;
 
123
  }
 
124
 
 
125
  public override Backend clone() {
 
126
    return new BackendU1();
 
127
  }
 
128
 
 
129
  ~BackendU1()
 
130
  {
 
131
    if (button_handler > 0) {
 
132
      mount_op.disconnect(button_handler);
 
133
      button_handler = 0;
 
134
    }
 
135
  }
 
136
 
 
137
  public override bool is_native() {
 
138
    return false;
 
139
  }
 
140
 
 
141
  public override bool space_can_be_infinite() {
 
142
    return false;
 
143
  }
 
144
 
 
145
  public override Icon? get_icon() {
 
146
    return new ThemedIcon.from_names({"ubuntuone", "ubuntuone-installer", "deja-dup-cloud"});
 
147
  }
 
148
 
 
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/");
 
152
  }
 
153
 
 
154
  public override string get_location(ref bool as_root)
 
155
  {
 
156
    // The UI backend for duplicity needs to talk to our session dbus, but it
 
157
    // can't as root.
 
158
    as_root = false;
 
159
 
 
160
    var settings = get_settings(U1_ROOT);
 
161
    var folder = get_folder_key(settings, U1_FOLDER_KEY);
 
162
    return "u1+http://%s".printf(folder);
 
163
  }
 
164
 
 
165
  public override string get_location_pretty()
 
166
  {
 
167
    var settings = get_settings(U1_ROOT);
 
168
    var folder = get_folder_key(settings, U1_FOLDER_KEY);
 
169
    if (folder == "")
 
170
      return _("Ubuntu One");
 
171
    else
 
172
      // Translators: %s is a folder.
 
173
      return _("%s on Ubuntu One").printf(folder);
 
174
  }
 
175
 
 
176
  public override async uint64 get_space(bool free = true)
 
177
  {
 
178
    DBusProxy obj = null;
 
179
    try {
 
180
      obj = get_prefs_proxy();
 
181
    }
 
182
    catch (Error e) {
 
183
      warning("%s\n", e.message);
 
184
      return INFINITE_SPACE;
 
185
    }
 
186
 
 
187
    if (obj.get_name_owner() == null)
 
188
      return INFINITE_SPACE;
 
189
 
 
190
    uint64 total = INFINITE_SPACE;
 
191
    uint64 used = 0;
 
192
    var listener = new Listener(obj, "account_info", null, (name, args) => {
 
193
      if (name == "AccountInfoReady") {
 
194
        VariantIter iter;
 
195
        args.get("(a{ss})", out iter);
 
196
        string key, val;
 
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);
 
202
        }
 
203
      }
 
204
    });
 
205
    listener.run();
 
206
 
 
207
    if (free)
 
208
      return (total > used) ? (total - used) : 0;
 
209
    else
 
210
      return total;
 
211
  }
 
212
 
 
213
  public override async void get_envp() throws Error
 
214
  {
 
215
    bool found = false;
 
216
    var obj = get_creds_proxy();
 
217
    if (obj.get_name_owner() == null) {
 
218
      ask_password();
 
219
      return;
 
220
    }
 
221
 
 
222
    var listener = new Listener(obj, "find_credentials", null, (name, args) => {
 
223
      if (name == "CredentialsFound")
 
224
        found = true;
 
225
    });
 
226
    listener.run();
 
227
 
 
228
    if (found)
 
229
      envp_ready(true, null);
 
230
    else
 
231
      ask_password();
 
232
  }
 
233
 
 
234
  void button_clicked()
 
235
  {
 
236
    sign_in.begin();
 
237
  }
 
238
 
 
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);
 
246
  }
 
247
 
 
248
  async void sign_in()
 
249
  {
 
250
    try {
 
251
      var obj = get_creds_proxy();
 
252
      if (obj.get_name_owner() == null) {
 
253
        envp_ready(false, null);
 
254
        return;
 
255
      }
 
256
 
 
257
      var listener = new Listener(obj, "login", new Variant("(a{ss})", null),
 
258
                                  (name, args) => {
 
259
        if (name == "CredentialsFound") {
 
260
          mount_op.set("go_forward", true);
 
261
          envp_ready(true, null);
 
262
        }
 
263
      });
 
264
      listener.run();
 
265
    }
 
266
    catch (Error e) {
 
267
      warning("%s\n", e.message);
 
268
      envp_ready(false, null);
 
269
    }
 
270
  }
 
271
 
 
272
  public static DBusProxy get_creds_proxy() throws Error
 
273
  {
 
274
    DBusProxy creds_proxy;
 
275
    creds_proxy = new DBusProxy.for_bus_sync(BusType.SESSION,
 
276
                                             DBusProxyFlags.NONE, null, 
 
277
                                             "com.ubuntuone.Credentials",
 
278
                                             "/credentials",
 
279
                                             "com.ubuntuone.CredentialsManagement",
 
280
                                             null);
 
281
    return creds_proxy;
 
282
  }
 
283
 
 
284
  public static DBusProxy get_prefs_proxy() throws Error
 
285
  {
 
286
    DBusProxy prefs_proxy;
 
287
    prefs_proxy = new DBusProxy.for_bus_sync(BusType.SESSION,
 
288
                                             DBusProxyFlags.NONE, null, 
 
289
                                             "com.ubuntuone.controlpanel",
 
290
                                             "/preferences",
 
291
                                             "com.ubuntuone.controlpanel.Preferences",
 
292
                                             null);
 
293
    return prefs_proxy;
 
294
  }
 
295
}
 
296
 
 
297
} // end namespace
 
298