Use iface_cache interface directly.
[zeroinstall.git] / download_box.py
blob77072f29db966de816b86213a64a4ab4a6532973
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):
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 if not run_afterwards:
28 mainwindow.destroy()
29 return
30 try:
31 run.execute(policy, prog_args)
32 mainwindow.destroy()
33 except SafeException, ex:
34 box = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
35 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
36 str(ex))
37 box.run()
38 box.destroy()
39 mainwindow.show()
40 if downloads:
41 DownloadProgessBox(run_it, downloads, mainwindow).show()
42 else:
43 run_it()
45 class DownloadProgessBox(Dialog):
46 mainwindow = None
47 run_it = None
48 n_downloads = None
49 idle_timeout = None
50 errors = False
52 def __init__(self, run_it, downloads, mainwindow):
53 Dialog.__init__(self)
54 self.set_title('Downloading, please wait...')
55 self.mainwindow = mainwindow
56 self.run_it = run_it
57 self.n_downloads = 0
59 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
61 table = gtk.Table(len(downloads) + 1, 3)
62 self.vbox.pack_start(table, False, False, 0)
63 table.set_row_spacings(4)
64 table.set_col_spacings(10)
65 table.set_border_width(10)
67 bars = []
69 row = 0
70 for iface, dl in downloads:
71 bar = gtk.ProgressBar()
72 bars.append((dl, bar))
73 table.attach(gtk.Label(iface.get_name()),
74 0, 1, row, row + 1)
75 table.attach(gtk.Label(pretty_size(dl.source.size)),
76 1, 2, row, row + 1)
77 table.attach(bar, 2, 3, row, row + 1)
78 row += 1
79 self.start_download(dl)
81 mainwindow.hide()
82 self.vbox.show_all()
84 def resp(box, resp):
85 for iface, dl in downloads:
86 dl.abort()
87 gtk.timeout_remove(self.idle_timeout)
88 self.idle_timeout = None
89 self.destroy()
90 mainwindow.show()
91 self.connect('response', resp)
93 def update_bars():
94 if self.n_downloads == 0:
95 if not self.errors:
96 self.destroy()
97 self.run_it()
98 return False
99 for dl, bar in bars:
100 perc = dl.get_current_fraction()
101 bar.set_fraction(perc)
102 return True
104 self.idle_timeout = gtk.timeout_add(250, update_bars)
106 def start_download(self, dl):
107 error_stream = dl.start()
108 def error_ready(src, cond):
109 got = os.read(src.fileno(), 100)
110 if not got:
111 error_stream.close()
112 self.n_downloads -= 1
113 try:
114 data = dl.error_stream_closed()
115 policy.add_to_cache(dl.source, data)
116 except SafeException, ex:
117 label = gtk.Label("Error getting '%s':\n%s" % (dl.url, ex))
118 label.set_padding(4, 4)
119 self.vbox.pack_start(label, False, True, 2)
120 label.show()
121 self.errors = True
122 return False
123 return False
124 dl.error_stream_data(got)
125 return True
127 self.n_downloads += 1
128 gtk.input_add(error_stream, gtk.gdk.INPUT_READ, error_ready)