Better error when downloading if a python import fails.
[zeroinstall/zeroinstall-mseaborn.git] / zeroinstall / 0launch-gui / download_box.py
blobb188ef42728ef31dbf840226a7b305ceaf632893
1 import gtk
2 import os, sys
3 import sets # Note: for Python 2.3; frozenset is only in Python 2.4
5 from zeroinstall.injector.model import SafeException
6 from zeroinstall.injector import download, writer
7 from zeroinstall.support import tasks
8 from zeroinstall import support
9 from gui import policy
10 from dialog import Dialog
12 import warnings
13 warnings.filterwarnings('ignore', category = DeprecationWarning, module='download_box')
15 def download_with_gui(mainwindow):
16 """If all downloads are ready, prints the selected versions and exits. Otherwise,
17 hides mainwindow, shows the download progress box and then prints them.
18 On error, mainwindow is re-shown and returns False. Before starting,
19 any current downloads (interfaces) are aborted.
20 On success, calls sys.exit(0)."""
21 try:
22 policy.abort_all_downloads()
24 # Existing downloads don't disappear until the kill signal takes
25 # effect. Rather than waiting, just filter them out later.
26 existing_downloads = sets.ImmutableSet(policy.handler.monitored_downloads)
28 task = tasks.Task(policy.download_impls(), "download implementations")
30 def run_it():
31 policy.abort_all_downloads()
33 from zeroinstall.injector import selections
34 sels = selections.Selections(policy)
35 doc = sels.toDOM()
36 reply = doc.toxml('utf-8')
37 sys.stdout.write(('Length:%8x\n' % len(reply)) + reply)
38 mainwindow.window.destroy()
39 sys.exit(0) # Success
40 if sets.ImmutableSet(policy.handler.monitored_downloads) - existing_downloads:
41 DownloadProgessBox(run_it, mainwindow).show()
42 else:
43 run_it()
44 except SafeException, ex:
45 box = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
46 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
47 str(ex))
48 box.run()
49 box.destroy()
50 mainwindow.window.show()
52 class DownloadProgessBox(Dialog):
53 mainwindow = None
54 run_it = None
55 idle_timeout = None
56 errors = False
58 def __init__(self, run_it, mainwindow):
59 Dialog.__init__(self)
60 self.set_title('Downloading, please wait...')
61 self.mainwindow = mainwindow
62 assert self.mainwindow.download_box is None
63 self.mainwindow.download_box = self
64 self.run_it = run_it
66 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
68 downloads = [(x, x.expected_size) for x in policy.handler.monitored_downloads
69 if hasattr(x, 'expected_size')]
71 table = gtk.Table(len(downloads) + 1, 3)
72 self.vbox.pack_start(table, False, False, 0)
73 table.set_row_spacings(4)
74 table.set_col_spacings(10)
75 table.set_border_width(10)
77 bars = []
79 row = 0
80 for dl, size in downloads:
81 bar = gtk.ProgressBar()
82 bars.append((dl, bar))
83 table.attach(gtk.Label(os.path.basename(dl.url)),
84 0, 1, row, row + 1)
85 table.attach(gtk.Label(support.pretty_size(size)),
86 1, 2, row, row + 1)
87 table.attach(bar, 2, 3, row, row + 1)
88 row += 1
90 mainwindow.window.hide()
91 self.vbox.show_all()
93 def resp(box, resp):
94 for dl, size in downloads:
95 dl.abort()
96 gtk.timeout_remove(self.idle_timeout)
97 self.idle_timeout = None
98 self.destroy()
99 mainwindow.download_box = None
100 mainwindow.window.show()
101 policy.recalculate()
102 self.connect('response', resp)
104 def update_bars():
105 if not policy.handler.monitored_downloads:
106 if policy.get_uncached_implementations():
107 return False
108 self.destroy()
109 self.run_it()
110 for dl, bar in bars:
111 perc = dl.get_current_fraction()
112 if perc >= 0:
113 bar.set_fraction(perc)
114 return True
116 self.idle_timeout = gtk.timeout_add(250, update_bars)