1 From bc155a50edc5fa3023e2fceebf432403e903ce02 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= <glen@delfi.ee>
3 Date: Sun, 6 Apr 2014 13:47:59 +0300
4 Subject: [PATCH] merge download changes from nautilus-dropbox-1.6.1/dropbox.in
6 http://linux.dropbox.com/packages/nautilus-dropbox-1.6.1.tar.bz2
8 caja-dropbox.in | 229 +++++++++++++++++++++++++++++++-------------------------
9 1 file changed, 128 insertions(+), 101 deletions(-)
11 diff --git a/caja-dropbox.in b/caja-dropbox.in
12 index abf7e82..8b063a4 100755
18 -# Copyright 2008 Evenflow, Inc.
19 +# Copyright (c) Dropbox, Inc.
22 # Dropbox frontend script
24 from __future__ import with_statement
31 @@ -35,8 +34,10 @@ import sys
43 @@ -47,9 +48,14 @@ from contextlib import closing, contextmanager
44 from posixpath import curdir, sep, pardir, join, abspath, commonprefix
46 INFO = u"Dropbox is the easiest way to share and store your files online. Want to learn more? Head to"
47 -LINK = u"http://www.dropbox.com/"
48 +LINK = u"https://www.dropbox.com/"
49 WARNING = u"In order to use Dropbox, you must download the proprietary daemon."
50 GPG_WARNING = u"Note: python-gpgme is not installed, we will not be able to verify binary signatures."
51 +ERROR_CONNECTING = u"Trouble connecting to Dropbox servers. Maybe your internet connection is down, or you need to set your http_proxy environment variable."
52 +ERROR_SIGNATURE = u"Downloaded binary does not match Dropbox signature, aborting install."
54 +DOWNLOAD_LOCATION_FMT = "https://www.dropbox.com/download?plat=%s"
55 +SIGNATURE_LOCATION_FMT = "https://www.dropbox.com/download?plat=%s&signature=1"
57 DOWNLOADING = u"Downloading Dropbox... %d%%"
58 UNPACKING = u"Unpacking Dropbox... %d%%"
59 @@ -60,7 +66,7 @@ DESKTOP_FILE = u"@DESKTOP_FILE_DIR@/dropbox.desktop"
61 enc = locale.getpreferredencoding()
63 -# Available from http://linux.dropbox.com/fedora/rpm-public-key.asc
64 +# Available from https://linux.dropbox.com/fedora/rpm-public-key.asc
65 DROPBOX_PUBLIC_KEY = """
66 -----BEGIN PGP PUBLIC KEY BLOCK-----
68 @@ -196,76 +202,58 @@ def gpgme_context(keys):
69 del os.environ['GNUPGHOME']
70 shutil.rmtree(_gpghome, ignore_errors=True)
72 +class SignatureVerifyError(Exception):
75 def verify_signature(key_file, sig_file, plain_file):
76 with gpgme_context([key_file]) as ctx:
77 sigs = ctx.verify(sig_file, plain_file, None)
78 return sigs[0].status == None
80 -def download_file_chunk(socket, buf, size):
81 +def download_file_chunk(url, buf):
82 + opener = urllib2.build_opener()
83 + opener.addheaders = [('User-Agent', "DropboxLinuxDownloader/@PACKAGE_VERSION@")]
84 + sock = opener.open(url)
86 + size = int(sock.info()['content-length'])
87 + bufsize = max(size / 200, 4096)
89 - with closing(socket) as f:
91 + with closing(sock) as f:
95 - chunk = os.read(f.fileno(), 4096)
96 + chunk = f.read(bufsize)
97 progress += len(chunk)
99 - yield (progress, True)
100 + yield (float(progress)/size, True)
104 if hasattr(e, 'errno') and e.errno == errno.EAGAIN:
105 # nothing left to read
106 - yield (progress, False)
107 + yield (float(progress)/size, False)
111 -def download_uri_to_buffer(uri):
113 - socket = urllib.urlopen(uri)
115 - FatalVisibleError("Trouble connecting to Dropbox servers. Maybe your internet connection is down, or you need to set your http_proxy environment variable.")
117 - fcntl.fcntl(socket, fcntl.F_SETFL, os.O_NONBLOCK)
118 - size = int(socket.info()['content-length'])
120 - buf = StringIO.StringIO()
121 - download_chunk = download_file_chunk(socket, buf, size)
123 - for _ in download_chunk:
129 -# This sets a custom User-Agent
130 -class DropboxURLopener(urllib.FancyURLopener):
131 - version = "DropboxLinuxDownloader/@PACKAGE_VERSION@"
132 -urllib._urlopener = DropboxURLopener()
134 class DownloadState(object):
137 - self.socket = urllib.urlopen("http://www.dropbox.com/download?plat=%s" % plat())
139 - FatalVisibleError("Trouble connecting to Dropbox servers. Maybe your internet connection is down, or you need to set your http_proxy environment variable")
141 - fcntl.fcntl(self.socket, fcntl.F_SETFL, os.O_NONBLOCK)
142 - self.size = int(self.socket.info()['content-length'])
144 self.local_file = StringIO.StringIO()
145 - self.download_chunk = download_file_chunk(self.socket, self.local_file, self.size)
148 - return self.download_chunk
149 + return download_file_chunk(DOWNLOAD_LOCATION_FMT % plat(), self.local_file)
153 - signature = download_uri_to_buffer("http://www.dropbox.com/download?plat=%s&signature=1" % plat())
155 + signature = StringIO.StringIO()
156 + for _ in download_file_chunk(SIGNATURE_LOCATION_FMT % plat(), signature):
159 self.local_file.seek(0)
162 if not verify_signature(StringIO.StringIO(DROPBOX_PUBLIC_KEY), signature, self.local_file):
163 - FatalVisibleError("Downloaded binary does not match Dropbox signature, aborting install.")
164 + raise SignatureVerifyError()
166 self.local_file.seek(0)
167 archive = tarfile.open(fileobj=self.local_file, mode='r:gz')
168 @@ -296,6 +284,8 @@ if GUI_AVAILABLE:
172 + gtk.gdk.threads_init()
174 load_serialized_images()
176 global FatalVisibleError
177 @@ -310,9 +300,40 @@ if GUI_AVAILABLE:
181 - def gtk_flush_events():
182 - while gtk.events_pending():
183 - gtk.main_iteration()
184 + class GeneratorTask(object):
185 + def __init__(self, generator, loop_callback, on_done=None, on_exception=None):
186 + self.generator = generator
187 + self.loop_callback = loop_callback
188 + self.on_done = on_done
189 + self.on_exception = on_exception
191 + def _run(self, *args, **kwargs):
192 + self._stopped = False
194 + for ret in self.generator(*args, **kwargs):
197 + if not isinstance(ret, tuple):
199 + gobject.idle_add(self.loop_callback, *ret)
203 + except Exception, ex:
205 + if self.on_exception is not None:
206 + gobject.idle_add(self.on_exception, ex)
208 + if self.on_done is not None:
209 + gobject.idle_add(self.on_done)
211 + def start(self, *args, **kwargs):
212 + t = threading.Thread(target=self._run, args=args, kwargs=kwargs)
217 + self._stopped = True
219 class DownloadDialog(gtk.Dialog):
220 def handle_delete_event(self, wid, ev, data=None):
221 @@ -322,8 +343,8 @@ if GUI_AVAILABLE:
222 reroll_autostart(not button.get_active())
224 def handle_cancel(self, button):
226 - gobject.source_remove(self.watch)
230 self.download.cancel()
232 @@ -333,51 +354,51 @@ if GUI_AVAILABLE:
235 self.download = DownloadState()
236 - self.one_chunk = self.download.copy_data()
237 - self.watch = gobject.io_add_watch(self.download.socket,
242 - self.handle_data_waiting)
245 - self.dont_show_again_align.hide()
246 + if self.dont_show_again_align is not None:
247 + self.dont_show_again_align.hide()
250 - def update_progress(self, text, fraction):
251 - self.progress.set_text(text % int(fraction*100))
252 - self.progress.set_fraction(fraction)
254 + def download_progress(progress, status):
257 + self.update_progress(DOWNLOADING, progress)
259 - def handle_data_waiting(self, fd, condition):
260 - if condition == gobject.IO_HUP:
261 - FatalVisibleError("Connection to server unexpectedly closed.")
262 - elif condition == gobject.IO_ERR:
263 - FatalVisibleError("Unexpected error occurred with download.")
266 - progress, status = self.one_chunk.next()
269 - self.update_progress(DOWNLOADING, float(progress)/self.download.size)
270 - except StopIteration:
272 self.update_progress(DOWNLOADING, 1.0)
273 self.unpack_dropbox()
276 - self.update_progress(DOWNLOADING, float(progress)/self.download.size)
280 + FatalVisibleError(ERROR_CONNECTING)
282 + self.update_progress(DOWNLOADING, 0)
283 + self.task = GeneratorTask(self.download.copy_data,
285 + finished, error).start()
287 + def update_progress(self, text, fraction):
288 + self.progress.set_text(text % int(fraction*100))
289 + self.progress.set_fraction(fraction)
291 def unpack_dropbox(self):
292 - one_member = self.download.unpack()
295 - name, i, total = one_member.next()
296 - self.update_progress(UNPACKING, float(i)/total)
297 - except StopIteration:
298 + def unpack_progress(name, i, total):
299 + self.update_progress(UNPACKING, float(i)/total)
302 self.update_progress(UNPACKING, 1.0)
306 + if isinstance(ex, SignatureVerifyError):
307 + FatalVisibleError(ERROR_SIGNATURE)
309 + FatalVisibleError(ERROR_CONNECTING)
311 + self.task = GeneratorTask(self.download.unpack,
313 + finished, error).start()
315 def mouse_down(self, widget, event):
317 self.clicked_link = True
318 @@ -406,7 +427,6 @@ if GUI_AVAILABLE:
319 title = "Dropbox Installation")
323 self.hovering = False
324 self.clicked_link = False
325 self.user_cancelled = False
326 @@ -458,6 +478,8 @@ if GUI_AVAILABLE:
328 self.vbox.add(self.hbox)
330 + self.dont_show_again_align = None
333 if can_reroll_autostart():
334 dont_show_again = gtk.CheckButton("_Don't show this again")
335 @@ -477,7 +499,6 @@ if GUI_AVAILABLE:
337 self.set_resizable(False)
340 traceback.print_exc()
343 @@ -526,24 +547,27 @@ else:
346 download = DownloadState()
347 - one_chunk = download.copy_data()
351 - progress = one_chunk.next()[0]
352 - setprogress(DOWNLOADING, float(progress)/download.size)
353 - except StopIteration:
354 + for progress, status in download.copy_data():
357 + setprogress(DOWNLOADING, progress)
359 + FatalVisibleError(ERROR_CONNECTING)
361 setprogress(DOWNLOADING, 1.0)
365 - one_member = download.unpack()
369 - name, i, total = one_member.next()
370 + for name, i, total in download.unpack():
371 setprogress(UNPACKING, float(i)/total)
372 - except StopIteration:
373 + except SignatureVerifyError:
374 + FatalVisibleError(ERROR_SIGNATURE)
376 + FatalVisibleError(ERROR_CONNECTING)
378 setprogress(UNPACKING, 1.0)
381 @@ -788,9 +812,8 @@ def columnize(list, display_list=None, display_width=None):
382 original_texts = texts[:]
383 for col in range(len(texts)):
384 texts[col] = texts[col].ljust(colwidths[col])
385 - line = u"%s" % " ".join(texts)
386 - for i, text in enumerate(original_texts):
387 - line = line.replace(text, display_texts[i])
388 + texts[col] = texts[col].replace(original_texts[col], display_texts[col])
389 + line = u" ".join(texts)
393 @@ -932,6 +955,10 @@ options:
396 args = [name for name in sorted(os.listdir(u"."), key=methodcaller('lower')) if type(name) == unicode]
398 + # Bail early if there's nothing to list to avoid crashing on indent below
399 + console_print(u"<empty>")
401 indent = max(len(st)+1 for st in args)
404 @@ -1228,7 +1255,7 @@ options:
409 + traceback.print_exc()