1 import gtk
, os
, gobject
, sys
3 from zeroinstall
.injector
.policy
import Policy
4 from zeroinstall
.injector
import download
5 from zeroinstall
.injector
.model
import SafeException
6 from zeroinstall
.injector
.reader
import InvalidInterface
8 from checking
import CheckingBox
15 class GUIPolicy(Policy
):
18 monitored_downloads
= None
19 checking
= None # GtkDialog ("Checking for updates...")
20 original_implementation
= None
22 def __init__(self
, interface
, prog_args
, download_only
, refresh
):
23 Policy
.__init
__(self
, interface
)
27 self
.monitored_downloads
= []
30 self
.window
= mainwindow
.MainWindow(prog_args
, download_only
)
31 root
= policy
.get_interface(policy
.root
)
32 self
.window
.browser
.set_root(root
)
35 if root
.name
is not None:
36 self
.checking
= CheckingBox(root
)
37 def checking_destroyed(c
):
38 show_details
= self
.checking
.show_details
40 if show_details
or self
.ready
is False or self
.versions_changed():
44 download_box
.download_with_gui(self
.window
, prog_args
,
45 run_afterwards
= not download_only
)
46 self
.checking
.connect('destroy', checking_destroyed
)
48 self
.refresh_all(force
= False)
50 def monitor_download(self
, dl
):
51 self
.monitored_downloads
.append(dl
)
53 error_stream
= dl
.start()
54 def error_ready(src
, cond
):
55 got
= os
.read(src
.fileno(), 100)
58 self
.monitored_downloads
.remove(dl
)
59 if len(self
.monitored_downloads
) == 0:
60 gobject
.source_remove(self
.pulse
)
61 self
.window
.progress
.hide()
64 data
= dl
.error_stream_closed()
65 self
.check_signed_data(dl
, data
)
66 except download
.DownloadError
, ex
:
67 dialog
.alert(self
.window
,
68 "Error downloading interface '%s':\n\n%s" %
69 (dl
.interface
.uri
, ex
))
70 except InvalidInterface
, ex
:
71 dialog
.alert(self
.window
,
72 "Syntax error in downloaded interface '%s':\n\n%s" %
73 (dl
.interface
.uri
, ex
))
74 except SafeException
, ex
:
75 dialog
.alert(self
.window
,
76 "Error updating interface '%s':\n\n%s" %
77 (dl
.interface
.uri
, ex
))
78 if len(self
.monitored_downloads
) == 0 and self
.checking
:
79 self
.checking
.updates_done(self
.versions_changed())
81 dl
.error_stream_data(got
)
84 gobject
.io_add_watch(error_stream
,
85 gobject
.IO_IN | gobject
.IO_HUP
,
88 if self
.pulse
is None:
91 self
.checking
.progress
.pulse()
93 self
.window
.progress
.pulse()
95 self
.pulse
= gobject
.timeout_add(50, pulse
)
96 self
.window
.progress
.show()
98 def recalculate(self
):
99 Policy
.recalculate(self
)
104 print >>sys
.stderr
, "Your version of the injector is very old. " \
105 "Try upgrading (http://0install.net/injector.html)"
107 self
.window
.set_response_sensitive(gtk
.RESPONSE_OK
, self
.ready
)
109 def confirm_trust_keys(self
, interface
, sigs
, iface_xml
):
111 trust_box
.confirm_trust(interface
, sigs
, iface_xml
)
120 def get_best_source(self
, impl
):
121 """Return the best download source for this implementation."""
122 return impl
.download_sources
[0]
124 # XXX: Remove this. Moved to Policy.
125 def refresh_all(self
, force
= True):
126 for x
in self
.walk_interfaces():
127 self
.begin_iface_download(x
, force
)
129 def abort_all_downloads(self
):
130 for x
in self
.monitored_downloads
[:]:
133 def set_original_implementations(self
):
134 assert self
.original_implementation
is None
135 self
.original_implementation
= policy
.implementation
.copy()
137 def versions_changed(self
):
138 """Return whether we have now chosen any different implementations.
139 If so, we want to show the dialog to the user to confirm the new ones."""
141 if not self
.original_implementation
:
142 return True # Shouldn't happen?
143 if len(self
.original_implementation
) != len(self
.implementation
):
145 for iface
in self
.original_implementation
:
146 old
= self
.original_implementation
[iface
]
149 new
= self
.implementation
.get(iface
, None)
156 def pretty_size(size
):
160 return '%d bytes' % size
162 for unit
in ('Kb', 'Mb', 'Gb', 'Tb'):
166 return '%.1f %s' % (size
, unit
)