Download dialog basically works. (Need to fix loader.)
[jben2_gui.git] / jben / jben / interface / gtk / dialog / dict_download.py
blob1f4de3e123ac23109f498471c73a40e1b1f4bd28
1 # -*- coding: utf-8 -*-
3 from __future__ import absolute_import
5 import sys, os, Queue, urllib2
6 import gtk, gobject
7 from ..widget.storedsize import StoredSizeDialog
8 from jben.download_thread import DownloadThread
11 class DictDownload(StoredSizeDialog):
13 """Downloads dictionaries from a specified mirror."""
15 def __init__(self, app, parent, mirror, files):
16 StoredSizeDialog.__init__(
17 self, "gui.dialog.dict_download.size", -1, -1,
18 title=_("Download dictionaries"),
19 parent=parent,
20 flags=gtk.DIALOG_MODAL
22 self.app = app
23 self._layout()
24 self.connect("show", self.on_show)
25 self.connect("destroy", self.on_destroy)
26 self.urls = ["/".join((mirror, f)) for f in files]
27 self.handled_urls = []
28 self.dt = None
29 self.timeout_src = None
31 def on_show(self, widget):
32 self._do_new_thread()
34 def on_destroy(self, widget):
35 print "on_destroy called"
36 self.set_sensitive(False)
37 if self.timeout_src:
38 if not gobject.source_remove(self.timeout_src):
39 print >> sys.stderr, "WARNING: Could not remove timeout"
40 if self.dt:
41 self.dt.abort()
42 self.dt.join()
44 def run(self):
45 """Single-time run command; hides GTK boilerplate."""
46 gtk.Dialog.run(self)
47 self.destroy()
49 def _layout(self):
50 self.ok_btn = self.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
51 self.ok_btn.set_sensitive(False)
53 def _add_progress_bar(self):
54 layout = self.get_content_area()
55 self.cur_prog_bar = gtk.ProgressBar()
56 self.cur_prog_bar.set_pulse_step(0.01)
57 layout.pack_start(self.cur_prog_bar, expand=False)
58 layout.show_all()
60 def _do_new_thread(self):
61 try:
62 url = self.urls.pop()
63 print "Starting new thread for download:", url
64 fname = url.rsplit('/', 1)[-1]
65 out_fname = os.path.join(self.app.dictmgr.get_dict_dir(), fname)
66 self.dt = DownloadThread(url, out_fname, timeout=5)
67 self.dt.start()
68 self._add_progress_bar()
69 self.timeout_src = gobject.timeout_add(10, self.on_thread_poll,
70 self.dt)
71 except IndexError:
72 print "URL queue empty, finishing up"
73 self._finish()
75 def on_thread_poll(self, dt):
76 try:
77 while True:
78 (message, status) = dt.out_queue.get(block=False)
79 if message == dt.CONNECTING:
80 self.cur_prog_bar.set_text("Connecting...")
81 elif message == dt.CONNECTED:
82 self.cur_prog_bar.set_text(dt.realurl)
83 elif message == dt.DOWNLOADING:
84 if dt.filesize:
85 frct = status / float(dt.filesize)
86 pct = (100 * frct) if status else 0
87 out_str = "%s: %d bytes (%f)%%" % (
88 dt.realurl, status, pct)
89 self.cur_prog_bar.set_text(out_str)
90 self.cur_prog_bar.set_fraction(max(frct, 1.0))
91 else:
92 out_str = "%s: %d bytes" % (dt.realurl, status)
93 self.cur_prog_bar.set_text(out_str)
94 self.cur_prog_bar.pulse()
95 elif message == dt.DONE:
96 self.cur_prog_bar.set_text("Download complete")
97 self.cur_prog_bar.set_fraction(1.0)
98 self._do_new_thread()
99 return False
100 elif message == dt.ERROR:
101 if type(status) is urllib2.URLError:
102 err_str = "Error opening %s: %s" % \
103 (dt.realurl or dt.url, status.reason)
104 else:
105 err_str = "Error occurred during download: %s" % \
106 str(status)
107 self.cur_prog_bar.set_text(err_str)
108 self._do_new_thread()
109 return False
110 else:
111 raise Exception("Unknown thread message: (%s, %s)" %
112 (message, status))
113 except Queue.Empty:
114 return True
116 def _thread_finished(self, thread):
117 self.handled_urls.append(thread.realurl)
118 self._do_new_thread()
120 def _finish(self):
121 self.ok_btn.set_sensitive(True)