1 #!/usr/bin/python2.4
2 #
3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 # Use is subject to license terms.
24 #
25
26 CLIENT_API_VERSION = 0
27 PKG_CLIENT_NAME = "packagemanager"
28
29 import gettext # XXX Temporary workaround
30 import sys
31 import time
32 import datetime
33 from threading import Thread
34 from urllib2 import URLError
35 try:
36 import gobject
37 import gtk
38 import gtk.glade
39 import pygtk
40 pygtk.require("2.0")
41 except ImportError:
42 sys.exit(1)
43 import pkg.client.progress as progress
44 import pkg.misc
45 import pkg.client.api as api
46 import pkg.client.api_errors as api_errors
47 from pkg.misc import TransferTimedOutException, TransportException
48 import pkg.gui.enumerations as enumerations
49
50 class InstallUpdate(progress.ProgressTracker):
51 def __init__(self, install_list, parent, image_dir, \
52 ips_update = False, action = -1):
53 if action == -1:
54 return
55 # XXX Workaround as BE is using msg(_("message"))
56 # which bypasses the self._ mechanism the GUI is using
57 gettext.install("pkg","/usr/lib/locale")
58 progress.ProgressTracker.__init__(self)
59 self.update_list = []
60 self.parent = parent
61 self.ips_update = ips_update
62 self.ip = None
63 self.progress_stop_timer_thread = False
64 self.progress_stop_timer_running = False
65 self.prev_pkg = None
66 self.action = action
67 try:
68 self.api_o = api.ImageInterface(image_dir, \
69 CLIENT_API_VERSION, \
70 self, None, PKG_CLIENT_NAME)
71 except api_errors.VersionException:
72 msg = self.parent._("The version of the API is not correct.\n" + \
73 "Package Manager can't continue this operation.\n")
74 self.parent.error_occured(msg)
75 return
76 except api_errors.ImageNotFoundException:
77 msg = self.parent._("The image was not found.")
78 self.parent.error_occured(msg)
79 return
80 w_tree_createplan = gtk.glade.XML(parent.gladefile, "createplandialog")
81 w_tree_installupdate = gtk.glade.XML(parent.gladefile, "installupdate")
82 w_tree_downloadingfiles = \
83 gtk.glade.XML(parent.gladefile, "downloadingfiles")
84 w_tree_installingdialog = \
85 gtk.glade.XML(parent.gladefile, "installingdialog")
86 w_tree_networkdown = gtk.glade.XML(parent.gladefile, "networkdown")
87 self.w_createplan_dialog = \
88 w_tree_createplan.get_widget("createplandialog")
89 self.w_next_button = \
90 w_tree_installupdate.get_widget("next")
91 self.w_cancel_button = \
92 w_tree_installupdate.get_widget("cancel")
93 self.w_createplan_progressbar = \
94 w_tree_createplan.get_widget("createplanprogress")
95 self.w_createplan_textview = \
96 w_tree_createplan.get_widget("createplantextview")
97 self.w_createplan_label = \
98 w_tree_createplan.get_widget("packagedependencies")
99 self.w_createplancancel_button = \
100 w_tree_createplan.get_widget("cancelcreateplan")
101 self.w_canceldownload_button = \
102 w_tree_downloadingfiles.get_widget("canceldownload")
103 self.w_download_label = \
104 w_tree_downloadingfiles.get_widget("packagedependencies2")
105 self.w_installupdate_dialog = \
106 w_tree_installupdate.get_widget("installupdate")
107 self.w_summary_label = \
108 w_tree_installupdate.get_widget("packagenamelabel3")
109 self.w_review_treeview = w_tree_installupdate.get_widget("treeview1")
110 self.w_information_label = w_tree_installupdate.get_widget("label5")
111 self.w_downloadingfiles_dialog = \
112 w_tree_downloadingfiles.get_widget("downloadingfiles")
113 self.w_download_textview = \
114 w_tree_downloadingfiles.get_widget("downloadtextview")
115 self.w_download_progressbar = \
116 w_tree_downloadingfiles.get_widget("downloadprogress")
117 self.w_installing_dialog = \
118 w_tree_installingdialog.get_widget("installingdialog")
119 self.w_installingdialog_label = \
120 w_tree_installingdialog.get_widget("packagedependencies3")
121 self.w_installingdialog_expander = \
122 w_tree_installingdialog.get_widget("expander4")
123 self.w_installing_textview = \
124 w_tree_installingdialog.get_widget("installingtextview")
125 self.w_installing_progressbar = \
126 w_tree_installingdialog.get_widget("installingprogress")
127 self.w_networkdown_dialog = w_tree_networkdown.get_widget("networkdown")
128 self.w_createplan_progressbar.set_pulse_step(0.1)
129 installed_updated_column = gtk.TreeViewColumn('Installed/Updated')
130 self.w_review_treeview.append_column(installed_updated_column)
131 cell = gtk.CellRendererText()
132 installed_updated_column.pack_start(cell, True)
133 installed_updated_column.add_attribute(cell, 'text', 0)
134 self.w_review_treeview.expand_all()
135
136 if self.action == enumerations.REMOVE:
137 self.w_installupdate_dialog.set_title(self.parent._(\
138 "Remove Confirmation"))
139 self.w_information_label.set_text(\
140 self.parent._("This action affects other packages.\n" + \
141 "Review the packages to be removed.\n" + \
142 "Click Next to continue."))
143 self.w_installing_dialog.set_title(\
144 self.parent._("Removing Packages"))
145 self.w_createplan_dialog.set_title(\
146 self.parent._("Remove Check"))
147 self.w_installingdialog_label.set_text(\
148 self.parent._("Removing Packages..."))
149
150 try:
151 dic_createplan = \
152 {
153 "on_cancelcreateplan_clicked": \
154 self.__on_cancelcreateplan_clicked,
155 }
156 dic_installupdate = \
157 {
158 "on_cancel_button_clicked": \
159 self.__on_cancel_button_clicked,
160 "on_next_button_clicked":self.__on_next_button_clicked,
161 }
162 dic_downloadingfiles = \
163 {
164 "on_canceldownload_clicked": \
165 self.__on_cancel_download_clicked,
166 }
167 dic_networkdown = \
168 {
169 "on_networkdown_close_clicked": \
170 self.__on_networkdown_close_clicked,
171 }
172 w_tree_createplan.signal_autoconnect(dic_createplan)
173 w_tree_installupdate.signal_autoconnect(dic_installupdate)
174 w_tree_downloadingfiles.signal_autoconnect(dic_downloadingfiles)
175 w_tree_networkdown.signal_autoconnect(dic_networkdown)
176 except AttributeError, error:
177 print self.parent._('GUI will not respond to any event! %s. \
178 Check installupdate.py signals') \
179 % error
180 # XXX Hidden until progress will give information about fmri
181 self.w_installingdialog_expander.hide()
182 pulse_t = Thread(target = self.__progressdialog_progress_pulse)
183 thread = Thread(target = self.__plan_the_install_updateimage_ex, \
184 args = (install_list, ))
185 pulse_t.start()
186 thread.start()
187 self.w_createplan_label.set_text(\
188 self.parent._("Checking package dependencies..."))
189 self.w_createplancancel_button.set_sensitive(True)
190 self.w_createplan_dialog.show()
191
192 def __on_cancelcreateplan_clicked(self, widget):
193 '''Handler for signal send by cancel button, which user might press during
194 evaluation stage - while the dialog is creating plan'''
195 if self.api_o.can_be_canceled():
196 Thread(target = self.api_o.cancel, args = ()).start()
197 self.w_createplan_label.set_text(\
198 self.parent._("Canceling..."))
199 self.w_createplancancel_button.set_sensitive(False)
200
201 def __on_cancel_button_clicked(self, widget):
202 '''Handler for signal send by cancel button, which is available for the
203 user after evaluation stage on the dialog showing what will be installed
204 or updated'''
205 self.api_o.reset()
206 self.w_installupdate_dialog.destroy()
207
208 def __on_next_button_clicked(self, widget):
209 '''Handler for signal send by next button, which is available for the
210 user after evaluation stage on the dialog showing what will be installed
211 or updated'''
212 self.w_installupdate_dialog.hide()
213 download_thread = Thread(target = self.__prepare_stage_ex, \
214 args = (self.api_o, ))
215 download_thread.start()
216
217 def __on_cancel_download_clicked(self, widget):
218 '''Handler for signal send by cancel button, which user might press during
219 download stage.'''
220 if self.api_o.can_be_canceled():
221 Thread(target = self.api_o.cancel, args = ()).start()
222 self.w_download_label.set_text(\
223 self.parent._("Canceling..."))
224 self.w_canceldownload_button.set_sensitive(False)
225
226 def __on_networkdown_close_clicked(self, widget):
227 '''Handler for signal send by close button on the dialog showing that
228 there was some problem with the network connection.'''
229 self.w_networkdown_dialog.destroy()
230
231 def __update_createplan_progress(self, action):
232 buf = self.w_createplan_textview.get_buffer()
233 textiter = buf.get_end_iter()
234 buf.insert(textiter, action)
235
236 def __progressdialog_progress_pulse(self):
237 while not self.progress_stop_timer_thread:
238 gobject.idle_add(self.w_createplan_progressbar.pulse)
239 time.sleep(0.1)
240
241 def __update_download_progress(self, cur_bytes, total_bytes):
242 prog = float(cur_bytes)/total_bytes
243 self.w_download_progressbar.set_fraction(prog)
244 size_a_str = ""
245 size_b_str = ""
246 if cur_bytes > 0:
247 size_a_str = pkg.misc.bytes_to_str(cur_bytes)
248 if total_bytes > 0:
249 size_b_str = pkg.misc.bytes_to_str(total_bytes)
250 c = "Downloaded: " + size_a_str + " / " + size_b_str
251 self.w_download_progressbar.set_text(c)
252
253 def __update_install_progress(self, current, total):
254 prog = float(current)/total
255 self.w_installing_progressbar.set_fraction(prog)
256
257 def __update_install_pulse(self):
258 while not self.progress_stop_timer_thread:
259 self.progress_stop_timer_running = True
260 gobject.idle_add(self.w_installing_progressbar.pulse)
261 time.sleep(0.1)
262 self.progress_stop_timer_running = False
263
264 def __plan_the_install_updateimage_ex(self, list_of_packages):
265 try:
266 self.__plan_the_install_updateimage(list_of_packages)
267 except:
268 self.progress_stop_timer_thread = True
269 gobject.idle_add(self.w_createplan_dialog.hide)
270 msg = self.parent._("An unknown error occured while " + \
271 "preparing the\nlist of packages\n\nPlease let the " + \
272 "developers know about this problem by filing\n" + \
273 "a bug at http://defect.opensolaris.org")
274 msg += "\n\nException value: " + "\n" + str(sys.exc_value)
275 gobject.idle_add(self.parent.error_occured, msg)
276 sys.exc_clear()
277 return
278
279 def __plan_the_install_updateimage(self, list_of_packages):
280 '''Function which plans the image'''
281 gobject.idle_add(self.__update_createplan_progress, \
282 self.parent._("Evaluation started.\n" + \
283 "Gathering packages information, please wait...\n"))
284 stuff_to_do = False
285 if self.action == enumerations.INSTALL_UPDATE:
286 try:
287 stuff_to_do = self.api_o.plan_install(list_of_packages, \
288 filters = [])
289 except api_errors.InvalidCertException:
290 self.progress_stop_timer_thread = True
291 gobject.idle_add(self.w_createplan_dialog.hide)
292 msg = self.parent._("Invalid repository certificate." + \
293 "\nYou can not install packages from the" + \
294 "\nrepopsitory, which doesn't have" + \
295 "\nappropriate certificate.")
296 gobject.idle_add(self.parent.error_occured, msg)
297 return
298 except api_errors.PlanCreationException:
299 self.progress_stop_timer_thread = True
300 gobject.idle_add(self.w_createplan_dialog.hide)
301 msg = self.parent._("Installation failed during\n" + \
302 "creating plan, please check your network\n" + \
303 "connection and you can try to re-run the operation.")
304 gobject.idle_add(self.parent.error_occured, msg)
305 return
306 except api_errors.InventoryException:
307 self.progress_stop_timer_thread = True
308 gobject.idle_add(self.w_createplan_dialog.hide)
309 msg = self.parent._("Install failed.\n" + \
310 "The inventory is not correct.")
311 gobject.idle_add(self.parent.error_occured, msg)
312 return
313 except api_errors.CanceledException:
314 self.progress_stop_timer_thread = True
315 gobject.idle_add(self.w_createplan_dialog.hide)
316 return
317 except api_errors.CatalogRefreshException:
318 # network problem
319 self.progress_stop_timer_thread = True
320 gobject.idle_add(self.w_createplan_dialog.hide)
321 msg = self.parent._("Please check the network " + \
322 "connection.\nIs the repository accessible?")
323 gobject.idle_add(self.parent.error_occured, msg)
324 return
325
326 elif self.action == enumerations.REMOVE:
327 try:
328 plan_uninstall = self.api_o.plan_uninstall
329 stuff_to_do = \
330 plan_uninstall(list_of_packages, False, False)
331 except api_errors.PlanCreationException:
332 self.progress_stop_timer_thread = True
333 gobject.idle_add(self.w_createplan_dialog.hide)
334 msg = self.parent._("Update All failed during\n" + \
335 "creating plan, please check your network\n" + \
336 "connection and you can try to re-run the update all.")
337 gobject.idle_add(self.parent.error_occured, msg)
338 return
339 except api_errors.CanceledException:
340 self.progress_stop_timer_thread = True
341 gobject.idle_add(self.w_createplan_dialog.hide)
342 return
343 except api_errors.NonLeafPackageException, nlpe:
344 self.progress_stop_timer_thread = True
345 gobject.idle_add(self.__afterplan_nonleaf_dialog, nlpe)
346 return
347
348 elif self.action == enumerations.IMAGE_UPDATE:
349 try:
350 # we are passing force, since we already checked if the
351 # SUNWipkg and SUNWipkg-gui are up to date.
352 stuff_to_do, opensolaris_image, cre = \
353 self.api_o.plan_update_all(sys.argv[0], \
354 refresh_catalogs = False, \
355 noexecute = False, force = True)
356 if cre and not cre.succeeded:
357 self.progress_stop_timer_thread = True
358 gobject.idle_add(self.w_createplan_dialog.hide)
359 msg = self.parent._("Unexpected failure with" + \
360 "\ncatalog refresh during image-update" + \
361 " while \ndetermining what to update.")
362 gobject.idle_add(self.parent.error_occured, msg)
363 return
364 except api_errors.CatalogRefreshException:
365 self.progress_stop_timer_thread = True
366 gobject.idle_add(self.w_createplan_dialog.hide)
367 msg = self.parent._("Update All failed during " + \
368 "catalog refresh\n")
369 gobject.idle_add(self.parent.error_occured, msg)
370 return
371 except api_errors.IpkgOutOfDateException:
372 self.progress_stop_timer_thread = True
373 gobject.idle_add(self.w_createplan_dialog.hide)
374 msg = self.parent._("pkg(5) appears to be out of " + \
375 "date and should be\n updated before running " + \
376 "Update All.\nPlease update SUNWipkg package")
377 gobject.idle_add(self.parent.error_occured, msg)
378 return
379 except api_errors.PlanCreationException:
380 self.progress_stop_timer_thread = True
381 gobject.idle_add(self.w_createplan_dialog.hide)
382 msg = self.parent._("Update All failed during\n" + \
383 "creating plan, please check your network\n" + \
384 "connection and you can try to re-run the update all.")
385 gobject.idle_add(self.parent.error_occured, msg)
386 return
387 except api_errors.CanceledException:
388 self.progress_stop_timer_thread = True
389 gobject.idle_add(self.w_createplan_dialog.hide)
390 return
391 except api_errors.NetworkUnavailableException:
392 self.progress_stop_timer_thread = True
393 gobject.idle_add(self.w_createplan_dialog.hide)
394 msg = self.parent._("Please check the network " + \
395 "connection.\nIs the repository accessible?")
396 gobject.idle_add(self.parent.error_occured, msg)
397 return
398 if stuff_to_do:
399 gobject.idle_add(self.__afterplan_confirmation_dialog, self.api_o)
400
401 def __prepare_stage_ex(self, api_o):
402 try:
403 self.__prepare_stage(api_o)
404 except:
405 gobject.idle_add(self.w_downloadingfiles_dialog.hide)
406 msg = self.parent._("An unknown error occured while " + \
407 "downloading the files\n\nPlease let the developers know " + \
408 "about this problem by filing\na bug " + \
409 "at http://defect.opensolaris.org")
410 msg += "\n\nException value: " + "\n" + str(sys.exc_value)
411 gobject.idle_add(self.parent.error_occured, msg)
412 sys.exc_clear()
413
414 def __prepare_stage(self, api_o):
415 gobject.idle_add(self.w_downloadingfiles_dialog.show)
416 text = self.parent._("Preparing to download packages, please wait...")
417 gobject.idle_add(self.__add_info_to_downloadtext, text)
418 try:
419 api_o.prepare()
420 except (api_errors.ProblematicPermissionsIndexException, \
421 api_errors.PlanMissingException):
422 gobject.idle_add(self.w_downloadingfiles_dialog.hide)
423 msg = self.parent._("An error occured while " + \
424 "downloading the files\nPlease check your permissions and" + \
425 "\nnetwork connection.")
426 gobject.idle_add(self.parent.error_occured, msg)
427 return
428 except api_errors.CanceledException:
429 gobject.idle_add(self.w_downloadingfiles_dialog.hide)
430 return
431 except (TransferTimedOutException, TransportException):
432 gobject.idle_add(self.w_downloadingfiles_dialog.hide)
433 gobject.idle_add(self.w_networkdown_dialog.show)
434 return
435 except URLError:
436 gobject.idle_add(self.w_downloadingfiles_dialog.hide)
437 gobject.idle_add(self.w_networkdown_dialog.show)
438 return
439 self.__execute_stage_ex(api_o)
440
441 def __execute_stage_ex(self, api_o):
442 try:
443 self.__execute_stage(api_o)
444 except:
445 gobject.idle_add(self.w_installing_dialog.hide)
446 msg = self.parent._("An unknown error occured while " + \
447 "installing\nupdating or removing packages" + \
448 "\n\nPlease let the developers know about this problem " + \
449 "by filing\na bug at http://defect.opensolaris.org")
450 msg += "\n\nException value: " + "\n" + str(sys.exc_value)
451 gobject.idle_add(self.parent.error_occured, msg)
452 sys.exc_clear()
453 return
454
455 def __execute_stage(self, api_o):
456 text = self.parent._("Installing Packages...")
457 gobject.idle_add(self.w_downloadingfiles_dialog.hide)
458 gobject.idle_add(self.w_installingdialog_label.set_text, text)
459 gobject.idle_add(self.w_installing_dialog.show)
460 try:
461 api_o.execute_plan()
462 except api_errors.CorruptedIndexException:
463 gobject.idle_add(self.w_installing_dialog.hide)
464 msg = self.parent._("There was an error during installation." + \
465 "\nThe index is corrupted. You might wan't try to fix" + \
466 "\nthis problem by running command:" + \
467 "\npfexec pkg rebuild-index")
468 gobject.idle_add(self.parent.error_occured, msg)
469 return
470 except api_errors.ProblematicPermissionsIndexException:
471 gobject.idle_add(self.w_installing_dialog.hide)
472 msg = self.parent._("An error occured while " + \
473 "installing the files\nPlease check your permissions")
474 gobject.idle_add(self.parent.error_occured, msg)
475 return
476 except api_errors.ImageplanStateException:
477 gobject.idle_add(self.w_installing_dialog.hide)
478 msg = self.parent._("There was an error during installation." + \
479 "\nThe State of the image is incorrect and the operation" + \
480 "\ncan't be finished.")
481 gobject.idle_add(self.parent.error_occured, msg)
482 return
483 except api_errors.ImageUpdateOnLiveImageException:
484 gobject.idle_add(self.w_installing_dialog.hide)
485 msg = self.parent._("This is an Live Image. The install" + \
486 "\noperation can't be performed.")
487 gobject.idle_add(self.parent.error_occured, msg)
488 return
489 except api_errors.PlanMissingException:
490 gobject.idle_add(self.w_installing_dialog.hide)
491 msg = self.parent._("There was an error during installation." + \
492 "\nThe Plan of the operation is missing and the operation" + \
493 "\ncan't be finished.")
494 gobject.idle_add(self.parent.error_occured, msg)
495 return
496 gobject.idle_add(self.__operations_done)
497
498 def __operations_done(self):
499 if self.parent != None:
500 if not self.ips_update and not self.action == \
501 enumerations.IMAGE_UPDATE:
502 self.__update_package_list()
503 self.w_installing_dialog.hide()
504
505 if self.ips_update:
506 self.parent.shutdown_after_ips_update()
507 elif self.action == enumerations.IMAGE_UPDATE:
508 self.parent.shutdown_after_image_update()
509
510 def __update_package_list(self):
511 self.parent.update_package_list(self.update_list)
512
513 def __add_info_to_downloadtext(self, text):
514 '''Function which adds another line text in the "more details" download
515 dialog'''
516 buf = self.w_download_textview.get_buffer()
517 textiter = buf.get_end_iter()
518 if text:
519 buf.insert(textiter, text + "\n")
520
521 def __add_info_to_installtext(self, text):
522 '''Function which adds another line text in the "more details" install
523 dialog'''
524 buf = self.w_installing_textview.get_buffer()
525 textiter = buf.get_end_iter()
526 buf.insert(textiter, text)
527
528 def cat_output_start(self):
529 return
530
531 def cat_output_done(self):
532 return
533
534 def eval_output_start(self):
535 '''Called by progress tracker when the evaluation of the packages just
536 started.'''
537 return
538
539 def eval_output_progress(self):
540 '''Called by progress tracker each time some package was evaluated. The
541 call is being done by calling progress tracker evaluate_progress()
542 function'''
543 cur_eval_fmri = self.eval_cur_fmri
544 gobject.idle_add(self.__update_createplan_progress, \
545 self.parent._("Evaluating: %s\n") % cur_eval_fmri)
546
547 def eval_output_done(self):
548 ninst = self.eval_goal_install_npkgs
549 nupdt = self.eval_goal_update_npkgs
550 nremv = self.eval_goal_remove_npkgs
551 nbytes = self.dl_goal_nbytes
552 gobject.idle_add(self.__eval_output_done, \
553 ninst, nupdt, nremv, nbytes)
554
555 def __eval_output_done(self, ninst, nupdt, nremv, nbytes):
556 label_text = ""
557 if nupdt > 0 and nupdt != 1:
558 label_text += \
559 self.parent._("%d packages will be updated\n") % nupdt
560 elif nupdt == 1:
561 label_text += \
562 self.parent._("%d package will be updated\n") % nupdt
563 if ninst > 0 and ninst != 1:
564 label_text += \
565 self.parent._("%d packages will be installed\n\n") % ninst
566 elif ninst == 1:
567 label_text += \
568 self.parent._("%d package will be installed\n\n") % ninst
569 if nremv > 0 and nremv != 1:
570 label_text += \
571 self.parent._("%d packages will be removed\n\n") % nremv
572 elif nremv == 1:
573 label_text += \
574 self.parent._("%d package will be removed\n\n") % nremv
575 if not nbytes:
576 nbytes = 0
577 if nbytes > 0:
578 size_str = pkg.misc.bytes_to_str(nbytes)
579 label_text += self.parent._("%s will be downloaded") % size_str
580 self.w_summary_label.set_text(label_text)
581
582 def __afterplan_nonleaf_dialog(self, non_leaf_exception):
583 self.w_installupdate_dialog.set_title(self.parent._(\
584 "Remove Confirmation"))
585 self.w_information_label.set_text(\
586 self.parent._("This action couldn't be finished.\n" + \
587 "Some of the selected packages depends on other.\n" + \
588 "Please review the dependencies."))
589 self.w_next_button.hide()
590 self.w_cancel_button.set_label(self.parent._("Close"))
591 pkg_blocker = non_leaf_exception[0]
592 treestore = gtk.TreeStore(str)
593 pkg_iter = treestore.append(None, [pkg_blocker])
594 for pkg_a in non_leaf_exception[1]:
595 treestore.append(pkg_iter, [pkg_a])
596 self.w_review_treeview.set_model(treestore)
597 self.w_review_treeview.expand_all()
598 label_text = self.parent._("None of the packages will be removed")
599 self.w_summary_label.set_text(label_text)
600 self.progress_stop_timer_thread = True
601 self.w_createplan_dialog.hide()
602 self.w_installupdate_dialog.show()
603
604
605 def __afterplan_confirmation_dialog(self, api_o):
606 updated_installed = \
607 [
608 ["Packages To Be Installed:"],
609 ["Packages To Be Updated:"],
610 ["Packages To Be Removed:"]
611 ]
612 treestore = gtk.TreeStore(str)
613 install_iter = None
614 updated_iter = None
615 remove_iter = None
616 plan = api_o.describe().get_changes()
617 for pkg_plan in plan:
618 origin_fmri = pkg_plan[0]
619 destination_fmri = pkg_plan[1]
620 if origin_fmri and destination_fmri:
621 if not updated_iter:
622 updated_iter = treestore.append(None, \
623 updated_installed[1])
624 pkg_a = self.__get_pkgstr_from_pkginfo(destination_fmri)
625 treestore.append(updated_iter, [pkg_a])
626 elif not origin_fmri and destination_fmri:
627 if not install_iter:
628 install_iter = treestore.append(None, \
629 updated_installed[0])
630 pkg_a = self.__get_pkgstr_from_pkginfo(destination_fmri)
631 treestore.append(install_iter, [pkg_a])
632 elif origin_fmri and not destination_fmri:
633 if not remove_iter:
634 remove_iter = treestore.append(None, \
635 updated_installed[2])
636 pkg_a = self.__get_pkgstr_from_pkginfo(origin_fmri)
637 treestore.append(remove_iter, [pkg_a])
638
639 self.w_review_treeview.set_model(treestore)
640 self.w_review_treeview.expand_all()
641 self.progress_stop_timer_thread = True
642 self.w_createplan_dialog.hide()
643 self.w_installupdate_dialog.show()
644
645 def __get_pkgstr_from_pkginfo(self, pkginfo):
646 dt_str = self.get_datetime(pkginfo.packaging_date)
647 s_ver = pkginfo.version
648 s_bran = pkginfo.branch
649 pkg_name = pkginfo.pkg_stem
650 if not pkg_name in self.update_list:
651 self.update_list.append(pkg_name)
652 l_ver = 0
653 version_pref = ""
654 while l_ver < len(s_ver) -1:
655 version_pref += "%d%s" % (s_ver[l_ver],".")
656 l_ver += 1
657 version_pref += "%d%s" % (s_ver[l_ver],"-")
658 l_ver = 0
659 version_suf = ""
660 while l_ver < len(s_bran) -1:
661 version_suf += "%d%s" % (s_bran[l_ver],".")
662 l_ver += 1
663 version_suf += "%d" % s_bran[l_ver]
664 pkg_version = version_pref + version_suf + dt_str
665 return pkg_name + "@" + pkg_version
666
667 def ver_output(self):
668 return
669
670 def ver_output_error(self, actname, errors):
671 return
672
673 def dl_output(self):
674 gobject.idle_add(self.__update_download_progress, \
675 self.dl_cur_nbytes, self.dl_goal_nbytes)
676 if self.prev_pkg != self.dl_cur_pkg:
677 self.prev_pkg = self.dl_cur_pkg
678 text = self.parent._("Downloading: ") + self.dl_cur_pkg
679 gobject.idle_add(self.__add_info_to_downloadtext, text)
680 return
681
682 def dl_output_done(self):
683 return
684
685 def act_output(self):
686 gobject.idle_add(self.__update_install_progress, \
687 self.act_cur_nactions, self.act_goal_nactions)
688 return
689
690 def act_output_done(self):
691 return
692
693 def ind_output(self):
694 self.progress_stop_timer_thread = False
695 gobject.idle_add(self.__indexing_progress)
696 return
697
698 def __indexing_progress(self):
699 if not self.progress_stop_timer_running:
700 self.w_installingdialog_label.set_text(\
701 self.parent._("Creating packages index..."))
702 Thread(target = self.__update_install_pulse).start()
703
704 def ind_output_done(self):
705 self.progress_stop_timer_thread = True
706 return
707
708 @staticmethod
709 def get_datetime(date_time):
710 '''Support function for getting date from the API.'''
711 date_tmp = time.strptime(date_time, "%a %b %d %H:%M:%S %Y")
712 date_tmp2 = datetime.datetime(*date_tmp[0:5])
713 return date_tmp2.strftime(":%m%d")