Fixed errors in help text.
[zeroinstall.git] / download_box.py
blob7f41e370c7f2fd3d62c119570d8cf616ecf9f8a7
1 import gtk
2 import os
4 from zeroinstall.injector.model import SafeException
5 from zeroinstall.injector import download, run
6 from gui import policy, pretty_size
7 from dialog import Dialog
9 import warnings
10 warnings.filterwarnings('ignore', category = DeprecationWarning, module='download_box')
12 def download_with_gui(mainwindow, prog_args, run_afterwards, main = None):
13 """If all downloads are ready, runs the program. Otherwise,
14 hides mainwindow, shows the download progress box and then runs
15 it. On error, mainwindow is re-shown."""
16 downloads = []
17 for iface, impl in policy.get_uncached_implementations():
18 if not impl.download_sources:
19 raise SafeException("Implementation " + impl.id + " of "
20 "interface " + iface.get_name() + " cannot be "
21 "downloaded (no download locations given in "
22 "interface!")
23 dl = download.begin_impl_download(policy.get_best_source(impl),
24 force = True)
25 downloads.append((iface, dl))
26 def run_it():
27 policy.abort_all_downloads()
28 if not run_afterwards:
29 mainwindow.destroy()
30 return
31 try:
32 if main is None:
33 run.execute(policy, prog_args) # Don't break older versions
34 else:
35 run.execute(policy, prog_args, main = main)
36 mainwindow.destroy()
37 except SafeException, ex:
38 box = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
39 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
40 str(ex))
41 box.run()
42 box.destroy()
43 mainwindow.show()
44 if downloads:
45 DownloadProgessBox(run_it, downloads, mainwindow).show()
46 else:
47 run_it()
49 class DownloadProgessBox(Dialog):
50 mainwindow = None
51 run_it = None
52 n_downloads = None
53 idle_timeout = None
54 errors = False
56 def __init__(self, run_it, downloads, mainwindow):
57 Dialog.__init__(self)
58 self.set_title('Downloading, please wait...')
59 self.mainwindow = mainwindow
60 self.run_it = run_it
61 self.n_downloads = 0
63 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
65 table = gtk.Table(len(downloads) + 1, 3)
66 self.vbox.pack_start(table, False, False, 0)
67 table.set_row_spacings(4)
68 table.set_col_spacings(10)
69 table.set_border_width(10)
71 bars = []
73 row = 0
74 for iface, dl in downloads:
75 bar = gtk.ProgressBar()
76 bars.append((dl, bar))
77 table.attach(gtk.Label(iface.get_name()),
78 0, 1, row, row + 1)
79 table.attach(gtk.Label(pretty_size(dl.source.size)),
80 1, 2, row, row + 1)
81 table.attach(bar, 2, 3, row, row + 1)
82 row += 1
83 self.start_download(dl)
85 mainwindow.hide()
86 self.vbox.show_all()
88 def resp(box, resp):
89 for iface, dl in downloads:
90 dl.abort()
91 gtk.timeout_remove(self.idle_timeout)
92 self.idle_timeout = None
93 self.destroy()
94 mainwindow.show()
95 policy.recalculate()
96 self.connect('response', resp)
98 def update_bars():
99 if self.n_downloads == 0:
100 if not self.errors:
101 self.destroy()
102 self.run_it()
103 return False
104 for dl, bar in bars:
105 perc = dl.get_current_fraction()
106 bar.set_fraction(perc)
107 return True
109 self.idle_timeout = gtk.timeout_add(250, update_bars)
111 def start_download(self, dl):
112 error_stream = dl.start()
113 def error_ready(src, cond):
114 got = os.read(src.fileno(), 100)
115 if not got:
116 error_stream.close()
117 self.n_downloads -= 1
118 try:
119 data = dl.error_stream_closed()
120 policy.add_to_cache(dl.source, data)
121 except Exception, ex:
122 label = gtk.Label("Error getting '%s':\n%s" % (dl.url, ex))
123 label.set_padding(4, 4)
124 self.vbox.pack_start(label, False, True, 2)
125 label.set_selectable(True)
126 label.show()
127 self.errors = True
128 return False
129 return False
130 dl.error_stream_data(got)
131 return True
133 self.n_downloads += 1
134 gtk.input_add(error_stream, gtk.gdk.INPUT_READ, error_ready)