Guest User

mintUpdate.py

a guest
Apr 6th, 2015
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 109.15 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. try:
  4.     import os
  5.     import commands
  6.     import codecs
  7.     import sys
  8.     import string
  9.     import gtk
  10.     import gtk.glade
  11.     import gobject
  12.     import tempfile
  13.     import threading
  14.     import time
  15.     import gettext
  16.     import fnmatch
  17.     import urllib2
  18.     import re
  19.     from user import home
  20.     from sets import Set
  21.     import proxygsettings
  22.     sys.path.append('/usr/lib/linuxmint/common')
  23.     from configobj import ConfigObj
  24. except Exception, detail:
  25.     print detail
  26.     pass
  27.  
  28. try:
  29.     import pygtk
  30.     pygtk.require("2.0")
  31. except Exception, detail:
  32.     print detail
  33.     pass
  34.  
  35. from subprocess import Popen, PIPE
  36.  
  37. try:
  38.     numMintUpdate = commands.getoutput("ps -A | grep mintUpdate | wc -l")
  39.     if (numMintUpdate != "0"):
  40.         os.system("killall mintUpdate")        
  41. except Exception, detail:
  42.     print detail
  43.  
  44. architecture = commands.getoutput("uname -a")
  45. if (architecture.find("x86_64") >= 0):
  46.     import ctypes
  47.     libc = ctypes.CDLL('libc.so.6')
  48.     libc.prctl(15, 'mintUpdate', 0, 0, 0)
  49. else:
  50.     import dl
  51.     if os.path.exists('/lib/libc.so.6'):
  52.         libc = dl.open('/lib/libc.so.6')
  53.         libc.call('prctl', 15, 'mintUpdate', 0, 0, 0)
  54.     elif os.path.exists('/lib/i386-linux-gnu/libc.so.6'):
  55.         libc = dl.open('/lib/i386-linux-gnu/libc.so.6')
  56.         libc.call('prctl', 15, 'mintUpdate', 0, 0, 0)
  57.  
  58. # i18n
  59. gettext.install("mintupdate", "/usr/share/linuxmint/locale")
  60.  
  61. CONFIG_DIR = "%s/.config/linuxmint" % home
  62.  
  63. package_short_descriptions = {}
  64. package_descriptions = {}
  65.  
  66. (UPDATE_CHECKED, UPDATE_NAME, UPDATE_LEVEL_PIX, UPDATE_OLD_VERSION, UPDATE_NEW_VERSION, UPDATE_LEVEL_STR, UPDATE_SIZE, UPDATE_SIZE_STR, UPDATE_TYPE_PIX, UPDATE_TYPE, UPDATE_TOOLTIP, UPDATE_SORT_STR, UPDATE_OBJ) = range(13)
  67.  
  68. class PackageUpdate():
  69.     def __init__(self, source_package_name, level, oldVersion, newVersion, extraInfo, warning, update_type, tooltip):
  70.         self.name = source_package_name
  71.         self.description = ""
  72.         self.short_description = ""
  73.         self.level = level
  74.         self.oldVersion = oldVersion
  75.         self.newVersion = newVersion
  76.         self.size = 0
  77.         self.extraInfo = extraInfo
  78.         self.warning = warning
  79.         self.type = update_type
  80.         self.tooltip = tooltip
  81.         self.packages = []
  82.  
  83.     def add_package(self, package, size, short_description, description):
  84.         self.packages.append(package)
  85.         self.description = description
  86.         self.short_description = short_description
  87.         self.size += size
  88.  
  89. class ChangelogRetriever(threading.Thread):
  90.     def __init__(self, source_package, level, version, wTree):
  91.         threading.Thread.__init__(self)
  92.         self.source_package = source_package
  93.         self.level = level
  94.         self.version = version
  95.         self.wTree = wTree
  96.         # get the proxy settings from gsettings
  97.         self.ps = proxygsettings.get_proxy_settings()
  98.  
  99.  
  100.         # Remove the epoch if present in the version
  101.         if ":" in self.version:
  102.             self.version = self.version.split(":")[-1]
  103.            
  104.     def run(self):        
  105.         gtk.gdk.threads_enter()
  106.         self.wTree.get_widget("textview_changes").get_buffer().set_text(_("Downloading changelog..."))  
  107.         gtk.gdk.threads_leave()      
  108.        
  109.         changelog_sources = []            
  110.         if (self.source_package.startswith("lib")):
  111.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/main/%s/%s/%s_%s/changelog" % (self.source_package[0:4], self.source_package, self.source_package, self.version))        
  112.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/multiverse/%s/%s/%s_%s/changelog" % (self.source_package[0:4], self.source_package, self.source_package, self.version))
  113.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/universe/%s/%s/%s_%s/changelog" % (self.source_package[0:4], self.source_package, self.source_package, self.version))        
  114.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/restricted/%s/%s/%s_%s/changelog" % (self.source_package[0:4], self.source_package, self.source_package, self.version))
  115.         else:
  116.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/main/%s/%s/%s_%s/changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))        
  117.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/multiverse/%s/%s/%s_%s/changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))
  118.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/universe/%s/%s/%s_%s/changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))        
  119.             changelog_sources.append("http://changelogs.ubuntu.com/changelogs/pool/restricted/%s/%s/%s_%s/changelog" % (self.source_package[0], self.source_package, self.source_package, self.version))
  120.         changelog_sources.append("http://packages.linuxmint.com/dev/" + self.source_package + "_" + self.version + "_amd64.changes")
  121.         changelog_sources.append("http://packages.linuxmint.com/dev/" + self.source_package + "_" + self.version + "_i386.changes")
  122.        
  123.         changelog = _("No changelog available")
  124.        
  125.         if self.ps == {}:
  126.             # use default urllib2 proxy mechanisms (possibly *_proxy environment vars)
  127.             proxy = urllib2.ProxyHandler()
  128.         else:
  129.             # use proxy settings retrieved from gsettings
  130.             proxy = urllib2.ProxyHandler(self.ps)
  131.  
  132.         opener = urllib2.build_opener(proxy)
  133.         urllib2.install_opener(opener)
  134.  
  135.         for changelog_source in changelog_sources:
  136.             try:                      
  137.                 print "Trying to fetch the changelog from: %s" % changelog_source
  138.                 url = urllib2.urlopen(changelog_source, None, 10)
  139.                 source = url.read()
  140.                 url.close()
  141.                
  142.                 changelog = ""
  143.                 if "linuxmint.com" in changelog_source:
  144.                     changes = source.split("\n")
  145.                     for change in changes:
  146.                         change = change.strip()
  147.                         if change.startswith("*"):
  148.                             changelog = changelog + change + "\n"
  149.                 else:
  150.                     changelog = source                
  151.                 break
  152.             except:
  153.                 pass
  154.                                        
  155.         gtk.gdk.threads_enter()                
  156.         self.wTree.get_widget("textview_changes").get_buffer().set_text(changelog)        
  157.         gtk.gdk.threads_leave()
  158.  
  159. class AutomaticRefreshThread(threading.Thread):
  160.     def __init__(self, treeView, statusIcon, wTree):
  161.         threading.Thread.__init__(self)
  162.         self.treeView = treeView
  163.         self.statusIcon = statusIcon
  164.         self.wTree = wTree
  165.  
  166.     def run(self):
  167.         global app_hidden
  168.         global log
  169.         try:
  170.             while(True):
  171.                 prefs = read_configuration()
  172.                 timer = (prefs["timer_minutes"] * 60) + (prefs["timer_hours"] * 60 * 60) + (prefs["timer_days"] * 24 * 60 * 60)
  173.  
  174.                 try:
  175.                     log.writelines("++ Auto-refresh timer is going to sleep for " + str(prefs["timer_minutes"]) + " minutes, " + str(prefs["timer_hours"]) + " hours and " + str(prefs["timer_days"]) + " days\n")
  176.                     log.flush()
  177.                 except:
  178.                     pass # cause it might be closed already
  179.                 timetosleep = int(timer)
  180.                 if (timetosleep == 0):
  181.                     time.sleep(60) # sleep 1 minute, don't mind the config we don't want an infinite loop to go nuts :)
  182.                 else:
  183.                     time.sleep(timetosleep)
  184.                     if (app_hidden == True):
  185.                         try:
  186.                             log.writelines("++ MintUpdate is in tray mode, performing auto-refresh\n")
  187.                             log.flush()
  188.                         except:
  189.                             pass # cause it might be closed already
  190.                         # Refresh
  191.                         refresh = RefreshThread(self.treeView, self.statusIcon, self.wTree, root_mode=True)
  192.                         refresh.start()
  193.                     else:
  194.                         try:
  195.                             log.writelines("++ The mintUpdate window is open, skipping auto-refresh\n")
  196.                             log.flush()
  197.                         except:
  198.                             pass # cause it might be closed already
  199.  
  200.         except Exception, detail:
  201.             try:
  202.                 log.writelines("-- Exception occured in the auto-refresh thread.. so it's probably dead now: " + str(detail) + "\n")
  203.                 log.flush()
  204.             except:
  205.                 pass # cause it might be closed already
  206.  
  207. class InstallKernelThread(threading.Thread):
  208.  
  209.     def __init__(self, version, wTree, remove=False):
  210.         threading.Thread.__init__(self)        
  211.         self.version = version
  212.         self.wTree = wTree
  213.         self.remove = remove
  214.  
  215.     def run(self):
  216.         cmd = ["pkexec", "/usr/sbin/synaptic", "--hide-main-window",  \
  217.                 "--non-interactive", "--parent-window-id", "%s" % self.wTree.get_widget("window5").window.xid]
  218.         cmd.append("-o")
  219.         cmd.append("Synaptic::closeZvt=true")
  220.         cmd.append("--progress-str")
  221.         cmd.append("\"" + _("Please wait, this can take some time") + "\"")
  222.         cmd.append("--finish-str")
  223.         if self.remove:
  224.             cmd.append("\"" + _("The %s kernel was removed") % self.version + "\"")
  225.         else:
  226.             cmd.append("\"" + _("The %s kernel was installed") % self.version + "\"")
  227.         f = tempfile.NamedTemporaryFile()
  228.  
  229.         for pkg in ['linux-headers-%s' % self.version, 'linux-headers-%s-generic' % self.version, 'linux-image-%s-generic' % self.version, 'linux-image-extra-%s-generic' % self.version]:
  230.             if self.remove:
  231.                 f.write("%s\tdeinstall\n" % pkg)
  232.             else:
  233.                 f.write("%s\tinstall\n" % pkg)
  234.         cmd.append("--set-selections-file")
  235.         cmd.append("%s" % f.name)
  236.         f.flush()        
  237.         comnd = Popen(' '.join(cmd), stdout=log, stderr=log, shell=True)
  238.         returnCode = comnd.wait()
  239.         f.close()
  240.         #sts = os.waitpid(comnd.pid, 0)                
  241.        
  242.  
  243. class InstallThread(threading.Thread):
  244.     global icon_busy
  245.     global icon_up2date
  246.     global icon_updates
  247.     global icon_error
  248.     global icon_unknown
  249.     global icon_apply
  250.  
  251.     def __init__(self, treeView, statusIcon, wTree):
  252.         threading.Thread.__init__(self)
  253.         self.treeView = treeView
  254.         self.statusIcon = statusIcon
  255.         self.wTree = wTree
  256.  
  257.     def run(self):
  258.         global log
  259.         try:
  260.             log.writelines("++ Install requested by user\n")
  261.             log.flush()
  262.             gtk.gdk.threads_enter()
  263.             self.wTree.get_widget("window1").window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
  264.             self.wTree.get_widget("window1").set_sensitive(False)
  265.             installNeeded = False
  266.             packages = []
  267.             model = self.treeView.get_model()
  268.             gtk.gdk.threads_leave()
  269.  
  270.             iter = model.get_iter_first()
  271.             while (iter != None):
  272.                 checked = model.get_value(iter, UPDATE_CHECKED)
  273.                 if (checked == "true"):
  274.                     installNeeded = True
  275.                     package_update = model.get_value(iter, UPDATE_OBJ)
  276.                     for package in package_update.packages:
  277.                         packages.append(package)
  278.                         log.writelines("++ Will install " + str(package) + "\n")
  279.                         log.flush()
  280.                 iter = model.iter_next(iter)
  281.            
  282.             if (installNeeded == True):
  283.                                
  284.                 proceed = True                
  285.                 try:
  286.                     pkgs = ' '.join(str(pkg) for pkg in packages)
  287.                     warnings = commands.getoutput("/usr/lib/linuxmint/mintUpdate/checkWarnings.py %s" % pkgs)
  288.                     #print ("/usr/lib/linuxmint/mintUpdate/checkWarnings.py %s" % pkgs)
  289.                     warnings = warnings.split("###")
  290.                     if len(warnings) == 2:
  291.                         installations = warnings[0].split()
  292.                         removals = warnings[1].split()                                    
  293.                         if len(installations) > 0 or len(removals) > 0:
  294.                             gtk.gdk.threads_enter()
  295.                             try:
  296.                                 dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK_CANCEL, None)
  297.                                 dialog.set_title("")
  298.                                 dialog.set_markup("<b>" + _("This upgrade will trigger additional changes") + "</b>")
  299.                                 #dialog.format_secondary_markup("<i>" + _("All available upgrades for this package will be ignored.") + "</i>")                                
  300.                                 dialog.set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  301.                                 dialog.set_default_size(320, 400)
  302.                                 dialog.set_resizable(True)
  303.                                
  304.                                 if len(removals) > 0:
  305.                                     # Removals
  306.                                     label = gtk.Label()
  307.                                     if len(removals) == 1:
  308.                                         label.set_text(_("The following package will be removed:"))
  309.                                     else:
  310.                                         label.set_text(_("The following %d packages will be removed:") % len(removals))                                    
  311.                                     label.set_alignment(0, 0.5)
  312.                                     scrolledWindow = gtk.ScrolledWindow()
  313.                                     scrolledWindow.set_shadow_type(gtk.SHADOW_IN)
  314.                                     scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
  315.                                     treeview = gtk.TreeView()
  316.                                     column1 = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
  317.                                     column1.set_sort_column_id(0)
  318.                                     column1.set_resizable(True)
  319.                                     treeview.append_column(column1)
  320.                                     treeview.set_headers_clickable(False)
  321.                                     treeview.set_reorderable(False)
  322.                                     treeview.set_headers_visible(False)                                                        
  323.                                     model = gtk.TreeStore(str)
  324.                                     removals.sort()
  325.                                     for pkg in removals:
  326.                                         iter = model.insert_before(None, None)                                
  327.                                         model.set_value(iter, 0, pkg)
  328.                                     treeview.set_model(model)
  329.                                     treeview.show()
  330.                                     scrolledWindow.add(treeview)                                
  331.                                     dialog.vbox.pack_start(label, False, False, 0)
  332.                                     dialog.vbox.pack_start(scrolledWindow, True, True, 0)
  333.                                
  334.                                 if len(installations) > 0:
  335.                                     # Installations
  336.                                     label = gtk.Label()
  337.                                     if len(installations) == 1:
  338.                                         label.set_text(_("The following package will be installed:"))
  339.                                     else:
  340.                                         label.set_text(_("The following %d packages will be installed:") % len(installations))
  341.                                     label.set_alignment(0, 0.5)
  342.                                     scrolledWindow = gtk.ScrolledWindow()
  343.                                     scrolledWindow.set_shadow_type(gtk.SHADOW_IN)
  344.                                     scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
  345.                                     treeview = gtk.TreeView()
  346.                                     column1 = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
  347.                                     column1.set_sort_column_id(0)
  348.                                     column1.set_resizable(True)
  349.                                     treeview.append_column(column1)
  350.                                     treeview.set_headers_clickable(False)
  351.                                     treeview.set_reorderable(False)
  352.                                     treeview.set_headers_visible(False)                                                        
  353.                                     model = gtk.TreeStore(str)
  354.                                     installations.sort()
  355.                                     for pkg in installations:
  356.                                         iter = model.insert_before(None, None)                                
  357.                                         model.set_value(iter, 0, pkg)                              
  358.                                     treeview.set_model(model)
  359.                                     treeview.show()
  360.                                     scrolledWindow.add(treeview)  
  361.                                     dialog.vbox.pack_start(label, False, False, 0)
  362.                                     dialog.vbox.pack_start(scrolledWindow, True, True, 0)
  363.                                
  364.                                 dialog.show_all()                
  365.                                 if dialog.run() == gtk.RESPONSE_OK:
  366.                                     proceed = True
  367.                                 else:
  368.                                     proceed = False
  369.                                 dialog.destroy()  
  370.                             except Exception, detail:
  371.                                 print detail
  372.                             gtk.gdk.threads_leave()  
  373.                         else:
  374.                             proceed = True
  375.                 except Exception, details:
  376.                     print details
  377.                                                                        
  378.                 if proceed:
  379.                     gtk.gdk.threads_enter()
  380.                     self.statusIcon.set_from_file(icon_apply)
  381.                     self.statusIcon.set_tooltip(_("Installing updates"))
  382.                     gtk.gdk.threads_leave()
  383.                     log.writelines("++ Ready to launch synaptic\n")
  384.                     log.flush()
  385.                     cmd = ["pkexec", "/usr/sbin/synaptic", "--hide-main-window",  \
  386.                             "--non-interactive", "--parent-window-id", "%s" % self.wTree.get_widget("window1").window.xid]
  387.                     cmd.append("-o")
  388.                     cmd.append("Synaptic::closeZvt=true")
  389.                     cmd.append("--progress-str")
  390.                     cmd.append("\"" + _("Please wait, this can take some time") + "\"")
  391.                     cmd.append("--finish-str")
  392.                     cmd.append("\"" + _("Update is complete") + "\"")
  393.                     f = tempfile.NamedTemporaryFile()
  394.  
  395.                     for pkg in packages:
  396.                         f.write("%s\tinstall\n" % pkg)
  397.                     cmd.append("--set-selections-file")
  398.                     cmd.append("%s" % f.name)
  399.                     f.flush()
  400.                     comnd = Popen(' '.join(cmd), stdout=log, stderr=log, shell=True)
  401.                     returnCode = comnd.wait()
  402.                     log.writelines("++ Return code:" + str(returnCode) + "\n")
  403.                     #sts = os.waitpid(comnd.pid, 0)
  404.                     f.close()
  405.                     log.writelines("++ Install finished\n")
  406.                     log.flush()
  407.                                        
  408.                     if "mintupdate" in packages:
  409.                         # Restart                        
  410.                         try:
  411.                             log.writelines("++ Mintupdate was updated, restarting it...\n")
  412.                             log.flush()
  413.                             log.close()
  414.                         except:
  415.                             pass #cause we might have closed it already
  416.            
  417.                         command = "/usr/lib/linuxmint/mintUpdate/mintUpdate.py show &"                        
  418.                         os.system(command)
  419.                    
  420.                     else:
  421.                         # Refresh
  422.                         gtk.gdk.threads_enter()
  423.                         self.statusIcon.set_from_file(icon_busy)
  424.                         self.statusIcon.set_tooltip(_("Checking for updates"))
  425.                         self.wTree.get_widget("window1").window.set_cursor(None)
  426.                         self.wTree.get_widget("window1").set_sensitive(True)                        
  427.                         gtk.gdk.threads_leave()
  428.                         refresh = RefreshThread(self.treeView, self.statusIcon, self.wTree)
  429.                         refresh.start()
  430.                 else:
  431.                     # Stop the blinking but don't refresh
  432.                     gtk.gdk.threads_enter()
  433.                     self.wTree.get_widget("window1").window.set_cursor(None)
  434.                     self.wTree.get_widget("window1").set_sensitive(True)
  435.                     gtk.gdk.threads_leave()
  436.             else:
  437.                 # Stop the blinking but don't refresh
  438.                 gtk.gdk.threads_enter()
  439.                 self.wTree.get_widget("window1").window.set_cursor(None)
  440.                 self.wTree.get_widget("window1").set_sensitive(True)
  441.                 gtk.gdk.threads_leave()
  442.  
  443.         except Exception, detail:
  444.             log.writelines("-- Exception occured in the install thread: " + str(detail) + "\n")
  445.             log.flush()
  446.             gtk.gdk.threads_enter()
  447.             self.statusIcon.set_from_file(icon_error)
  448.             self.statusIcon.set_tooltip(_("Could not install the security updates"))
  449.             log.writelines("-- Could not install security updates\n")
  450.             log.flush()
  451.             #self.statusIcon.set_blinking(False)
  452.             self.wTree.get_widget("window1").window.set_cursor(None)
  453.             self.wTree.get_widget("window1").set_sensitive(True)
  454.             gtk.gdk.threads_leave()
  455.  
  456. class RefreshThread(threading.Thread):
  457.     global icon_busy
  458.     global icon_up2date
  459.     global icon_updates
  460.     global icon_error
  461.     global statusbar
  462.     global context_id
  463.  
  464.     def __init__(self, treeview_update, statusIcon, wTree, root_mode=False):
  465.         threading.Thread.__init__(self)
  466.         self.treeview_update = treeview_update
  467.         self.statusIcon = statusIcon
  468.         self.wTree = wTree
  469.         self.root_mode = root_mode
  470.    
  471.     def fetch_l10n_descriptions(self, package_names):
  472.         if os.path.exists("/var/lib/apt/lists"):
  473.             try:
  474.                 super_buffer = []
  475.                 for file in os.listdir("/var/lib/apt/lists"):
  476.                     if ("i18n_Translation") in file and not file.endswith("Translation-en"):
  477.                         fd = codecs.open(os.path.join("/var/lib/apt/lists", file), "r", "utf-8")                    
  478.                         super_buffer += fd.readlines()
  479.  
  480.                 i = 0
  481.                 while i < len(super_buffer):
  482.                     line = super_buffer[i].strip()
  483.                     if line.startswith("Package: "):
  484.                         try:
  485.                             pkgname = line.replace("Package: ", "")
  486.                             short_description = ""
  487.                             description = ""
  488.                             j = 2 # skip md5 line after package name line
  489.                             while True:
  490.                                 if (i+j >= len(super_buffer)):
  491.                                     break
  492.                                 line = super_buffer[i+j].strip()
  493.                                 if line.startswith("Package: "):
  494.                                     break
  495.                                 if j==2:
  496.                                     short_description = line
  497.                                 else:
  498.                                     description += "\n" + line
  499.                                 j += 1
  500.                             if pkgname in package_names:
  501.                                 if not package_descriptions.has_key(pkgname):
  502.                                     package_short_descriptions[pkgname] = short_description
  503.                                     package_descriptions[pkgname] = description
  504.                         except Exception, detail:
  505.                             print "a %s" % detail
  506.                     i += 1
  507.                 del super_buffer    
  508.             except Exception, detail:
  509.                 print "Could not fetch l10n descriptions.."
  510.                 print detail
  511.  
  512.     def run(self):
  513.         global log
  514.         global app_hidden
  515.         gtk.gdk.threads_enter()
  516.         vpaned_position = wTree.get_widget("vpaned1").get_position()
  517.         gtk.gdk.threads_leave()
  518.         try:
  519.             log.writelines("++ Starting refresh\n")
  520.             log.flush()
  521.             gtk.gdk.threads_enter()
  522.             statusbar.push(context_id, _("Starting refresh..."))
  523.             self.wTree.get_widget("window1").window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
  524.             self.wTree.get_widget("window1").set_sensitive(False)
  525.             self.wTree.get_widget("label_error_detail").set_text("")
  526.             self.wTree.get_widget("hbox_error").hide()
  527.             self.wTree.get_widget("scrolledwindow1").hide()
  528.             self.wTree.get_widget("viewport1").hide()
  529.             self.wTree.get_widget("label_error_detail").hide()
  530.             self.wTree.get_widget("image_error").hide()
  531.             # Starts the blinking
  532.             self.statusIcon.set_from_file(icon_busy)
  533.             self.statusIcon.set_tooltip(_("Checking for updates"))
  534.             wTree.get_widget("vpaned1").set_position(vpaned_position)
  535.             #self.statusIcon.set_blinking(True)
  536.             gtk.gdk.threads_leave()
  537.  
  538.             model = gtk.TreeStore(str, str, gtk.gdk.Pixbuf, str, str, str, int, str, gtk.gdk.Pixbuf, str, str, str, object)
  539.             # UPDATE_CHECKED, UPDATE_NAME, UPDATE_LEVEL_PIX, UPDATE_OLD_VERSION, UPDATE_NEW_VERSION, UPDATE_LEVEL_STR,
  540.             # UPDATE_SIZE, UPDATE_SIZE_STR, UPDATE_TYPE_PIX, UPDATE_TYPE, UPDATE_TOOLTIP, UPDATE_SORT_STR, UPDATE_OBJ
  541.  
  542.             model.set_sort_column_id( UPDATE_SORT_STR, gtk.SORT_ASCENDING )
  543.  
  544.             prefs = read_configuration()
  545.  
  546.             # Check to see if no other APT process is running
  547.             if self.root_mode:
  548.                 p1 = Popen(['ps', '-U', 'root', '-o', 'comm'], stdout=PIPE)
  549.                 p = p1.communicate()[0]
  550.                 running = False
  551.                 pslist = p.split('\n')
  552.                 for process in pslist:
  553.                     if process.strip() in ["dpkg", "apt-get","synaptic","update-manager", "adept", "adept-notifier"]:
  554.                         running = True
  555.                         break
  556.                 if (running == True):
  557.                     gtk.gdk.threads_enter()
  558.                     self.statusIcon.set_from_file(icon_unknown)
  559.                     self.statusIcon.set_tooltip(_("Another application is using APT"))
  560.                     statusbar.push(context_id, _("Another application is using APT"))
  561.                     log.writelines("-- Another application is using APT\n")
  562.                     log.flush()
  563.                     #self.statusIcon.set_blinking(False)
  564.                     self.wTree.get_widget("window1").window.set_cursor(None)
  565.                     self.wTree.get_widget("window1").set_sensitive(True)
  566.                     gtk.gdk.threads_leave()
  567.                     return False      
  568.  
  569.             gtk.gdk.threads_enter()
  570.             statusbar.push(context_id, _("Finding the list of updates..."))
  571.             wTree.get_widget("vpaned1").set_position(vpaned_position)
  572.             gtk.gdk.threads_leave()            
  573.             if app_hidden:
  574.                 refresh_command = "/usr/lib/linuxmint/mintUpdate/checkAPT.py 2>/dev/null"
  575.             else:
  576.                 refresh_command = "/usr/lib/linuxmint/mintUpdate/checkAPT.py --use-synaptic %s 2>/dev/null" % self.wTree.get_widget("window1").window.xid
  577.             if self.root_mode:
  578.                 refresh_command = "sudo %s" % refresh_command
  579.             updates =  commands.getoutput(refresh_command)
  580.  
  581.             # Look for mintupdate
  582.             if ("UPDATE###mintupdate###" in updates):                
  583.                 new_mintupdate = True
  584.             else:
  585.                 new_mintupdate = False
  586.            
  587.             updates = string.split(updates, "---EOL---")        
  588.  
  589.             # Look at the updates one by one
  590.             package_updates = {}
  591.             package_names = Set()
  592.             num_visible = 0
  593.             num_safe = 0            
  594.             download_size = 0
  595.             num_ignored = 0
  596.             ignored_list = []
  597.             if os.path.exists("%s/mintupdate.ignored" % CONFIG_DIR):
  598.                 blacklist_file = open("%s/mintupdate.ignored" % CONFIG_DIR, "r")
  599.                 for blacklist_line in blacklist_file:
  600.                     ignored_list.append(blacklist_line.strip())
  601.                 blacklist_file.close()                
  602.  
  603.             if (len(updates) == None):
  604.                 self.statusIcon.set_from_file(icon_up2date)
  605.                 self.statusIcon.set_tooltip(_("Your system is up to date"))
  606.                 statusbar.push(context_id, _("Your system is up to date"))
  607.                 log.writelines("++ System is up to date\n")
  608.                 log.flush()
  609.             else:                
  610.                 for pkg in updates:
  611.                     values = string.split(pkg, "###")
  612.                     if len(values) == 9:
  613.                         status = values[0]
  614.                         if (status == "ERROR"):
  615.                             try:
  616.                                 error_msg = updates[1]
  617.                             except:
  618.                                 error_msg = ""
  619.  
  620.                             gtk.gdk.threads_enter()
  621.                             self.statusIcon.set_from_file(icon_error)
  622.                             self.statusIcon.set_tooltip("%s\n\n%s" % (_("Could not refresh the list of updates"), error_msg))
  623.                             statusbar.push(context_id, _("Could not refresh the list of updates"))
  624.                             log.writelines("-- Error in checkAPT.py, could not refresh the list of updates\n")
  625.                             log.flush()
  626.                             self.wTree.get_widget("label_error_detail").set_text(error_msg)
  627.                             self.wTree.get_widget("label_error_detail").show()
  628.                             self.wTree.get_widget("viewport1").show()
  629.                             self.wTree.get_widget("scrolledwindow1").show()
  630.                             self.wTree.get_widget("image_error").show()
  631.                             self.wTree.get_widget("hbox_error").show()
  632.                             #self.statusIcon.set_blinking(False)
  633.                             self.wTree.get_widget("window1").window.set_cursor(None)
  634.                             self.wTree.get_widget("window1").set_sensitive(True)
  635.                             #statusbar.push(context_id, _(""))
  636.                             gtk.gdk.threads_leave()
  637.                             return False
  638.                                                
  639.                         package = values[1]
  640.                         newVersion = values[2]
  641.                         oldVersion = values[3]
  642.                         size = int(values[4])
  643.                         source_package = values[5]
  644.                         update_type = values[6]
  645.                         short_description = values[7]
  646.                         description = values[8]
  647.  
  648.                         package_names.add(package.replace(":i386", "").replace(":amd64", ""))
  649.  
  650.                         if not package_updates.has_key(source_package):
  651.                             updateIsBlacklisted = False
  652.                             for blacklist in ignored_list:
  653.                                 if fnmatch.fnmatch(source_package, blacklist):
  654.                                     num_ignored = num_ignored + 1
  655.                                     updateIsBlacklisted = True
  656.                                     break
  657.  
  658.                             if updateIsBlacklisted:
  659.                                 continue
  660.  
  661.                             is_a_mint_package = False
  662.                             if (update_type == "linuxmint"):
  663.                                 update_type = "package"
  664.                                 is_a_mint_package = True
  665.  
  666.                             security_update = (update_type == "security")
  667.  
  668.                             if update_type == "security":
  669.                                 tooltip = _("Security update")
  670.                             elif update_type == "backport":
  671.                                 tooltip = _("Software backport. Be careful when upgrading. New versions of sofware can introduce regressions.")
  672.                             elif update_type == "unstable":
  673.                                 tooltip = _("Unstable software. Only apply this update to help developers beta-test new software.")
  674.                             else:
  675.                                 tooltip = _("Software update")
  676.  
  677.                             extraInfo = ""
  678.                             warning = ""
  679.                             if is_a_mint_package:
  680.                                 level = 1 # Level 1 by default
  681.                             else:
  682.                                 level = 3 # Level 3 by default
  683.                             rulesFile = open("/usr/lib/linuxmint/mintUpdate/rules","r")
  684.                             rules = rulesFile.readlines()
  685.                             goOn = True
  686.                             foundPackageRule = False # whether we found a rule with the exact package name or not
  687.                             for rule in rules:
  688.                                 if (goOn == True):
  689.                                     rule_fields = rule.split("|")
  690.                                     if (len(rule_fields) == 5):
  691.                                         rule_package = rule_fields[0]
  692.                                         rule_version = rule_fields[1]
  693.                                         rule_level = rule_fields[2]
  694.                                         rule_extraInfo = rule_fields[3]
  695.                                         rule_warning = rule_fields[4]
  696.                                         if (rule_package == source_package):
  697.                                             foundPackageRule = True
  698.                                             if (rule_version == newVersion):
  699.                                                 level = rule_level
  700.                                                 extraInfo = rule_extraInfo
  701.                                                 warning = rule_warning
  702.                                                 goOn = False # We found a rule with the exact package name and version, no need to look elsewhere
  703.                                             else:
  704.                                                 if (rule_version == "*"):
  705.                                                     level = rule_level
  706.                                                     extraInfo = rule_extraInfo
  707.                                                     warning = rule_warning
  708.                                         else:
  709.                                             if (rule_package.startswith("*")):
  710.                                                 keyword = rule_package.replace("*", "")
  711.                                                 index = source_package.find(keyword)
  712.                                                 if (index > -1 and foundPackageRule == False):
  713.                                                     level = rule_level
  714.                                                     extraInfo = rule_extraInfo
  715.                                                     warning = rule_warning
  716.                             rulesFile.close()
  717.                             level = int(level)
  718.  
  719.                             # Create a new Update
  720.                             update = PackageUpdate(source_package, level, oldVersion, newVersion, extraInfo, warning, update_type, tooltip)
  721.                             update.add_package(package, size, short_description, description)
  722.                             package_updates[source_package] = update
  723.                         else:
  724.                             # Add the package to the Update
  725.                             update = package_updates[source_package]
  726.                             update.add_package(package, size, short_description, description)
  727.                        
  728.                 self.fetch_l10n_descriptions(package_names)
  729.  
  730.                 for source_package in package_updates.keys():
  731.                    
  732.                     package_update = package_updates[source_package]
  733.  
  734.                     if (new_mintupdate and package_update.name != "mintupdate"):
  735.                         continue
  736.  
  737.                     # l10n descriptions
  738.                     l10n_descriptions(package_update)
  739.                     package_update.short_description = clean_l10n_short_description(package_update.short_description)
  740.                     package_update.description = clean_l10n_description(package_update.description)
  741.                    
  742.                     security_update = (package_update.type == "security")
  743.  
  744.                     if ((prefs["level" + str(package_update.level) + "_visible"]) or (security_update and prefs['security_visible'])):
  745.                         iter = model.insert_before(None, None)
  746.                         if (security_update and prefs['security_visible'] and prefs['security_safe']):
  747.                             model.set_value(iter, UPDATE_CHECKED, "true")                            
  748.                             num_safe = num_safe + 1
  749.                             download_size = download_size + package_update.size
  750.                         elif (prefs["level" + str(package_update.level) + "_safe"]):                            
  751.                             model.set_value(iter, UPDATE_CHECKED, "true")                    
  752.                             num_safe = num_safe + 1
  753.                             download_size = download_size + package_update.size
  754.                         else:
  755.                             model.set_value(iter, UPDATE_CHECKED, "false")
  756.                                                                              
  757.                         model.row_changed(model.get_path(iter), iter)
  758.  
  759.                         shortdesc = package_update.short_description
  760.                         if len(shortdesc) > 100:
  761.                             shortdesc = shortdesc[:100] + "..."
  762.                         if (prefs["descriptions_visible"]):
  763.                             model.set_value(iter, UPDATE_NAME, package_update.name + "\n<small><span foreground='#5C5C5C'>%s</span></small>" % shortdesc)
  764.                         else:
  765.                             model.set_value(iter, UPDATE_NAME, package_update.name)
  766.                         model.set_value(iter, UPDATE_LEVEL_PIX, gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/level" + str(package_update.level) + ".png"))
  767.                         model.set_value(iter, UPDATE_OLD_VERSION, package_update.oldVersion)                                
  768.                         model.set_value(iter, UPDATE_NEW_VERSION, package_update.newVersion)                        
  769.                         model.set_value(iter, UPDATE_LEVEL_STR, str(package_update.level))
  770.                         model.set_value(iter, UPDATE_SIZE, package_update.size)
  771.                         model.set_value(iter, UPDATE_SIZE_STR, size_to_string(package_update.size))                        
  772.                         model.set_value(iter, UPDATE_TYPE_PIX, gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/update-type-%s.png" % package_update.type))
  773.                         model.set_value(iter, UPDATE_TYPE, package_update.type)
  774.                         model.set_value(iter, UPDATE_TOOLTIP, package_update.tooltip)
  775.                         model.set_value(iter, UPDATE_SORT_STR, "%s%s" % (str(package_update.level), package_update.name))
  776.                         model.set_value(iter, UPDATE_OBJ, package_update)
  777.                         num_visible = num_visible + 1
  778.  
  779.                 gtk.gdk.threads_enter()  
  780.                 if (new_mintupdate):
  781.                     self.statusString = _("A new version of the update manager is available")
  782.                     self.statusIcon.set_from_file(icon_updates)
  783.                     self.statusIcon.set_tooltip(self.statusString)
  784.                     statusbar.push(context_id, self.statusString)
  785.                     log.writelines("++ Found a new version of mintupdate\n")
  786.                     log.flush()
  787.                 else:
  788.                     if (num_safe > 0):
  789.                         if (num_safe == 1):
  790.                             if (num_ignored == 0):
  791.                                 self.statusString = _("1 recommended update available (%(size)s)") % {'size':size_to_string(download_size)}
  792.                             elif (num_ignored == 1):
  793.                                 self.statusString = _("1 recommended update available (%(size)s), 1 ignored") % {'size':size_to_string(download_size)}
  794.                             elif (num_ignored > 1):
  795.                                 self.statusString = _("1 recommended update available (%(size)s), %(ignored)d ignored") % {'size':size_to_string(download_size), 'ignored':num_ignored}
  796.                         else:
  797.                             if (num_ignored == 0):
  798.                                 self.statusString = _("%(recommended)d recommended updates available (%(size)s)") % {'recommended':num_safe, 'size':size_to_string(download_size)}
  799.                             elif (num_ignored == 1):
  800.                                 self.statusString = _("%(recommended)d recommended updates available (%(size)s), 1 ignored") % {'recommended':num_safe, 'size':size_to_string(download_size)}                            
  801.                             elif (num_ignored > 0):
  802.                                 self.statusString = _("%(recommended)d recommended updates available (%(size)s), %(ignored)d ignored") % {'recommended':num_safe, 'size':size_to_string(download_size), 'ignored':num_ignored}
  803.                         self.statusIcon.set_from_file(icon_updates)
  804.                         self.statusIcon.set_tooltip(self.statusString)
  805.                         statusbar.push(context_id, self.statusString)
  806.                         log.writelines("++ Found " + str(num_safe) + " recommended software updates\n")
  807.                         log.flush()
  808.                     else:
  809.                         self.statusIcon.set_from_file(icon_up2date)
  810.                         self.statusIcon.set_tooltip(_("Your system is up to date"))
  811.                         statusbar.push(context_id, _("Your system is up to date"))
  812.                         log.writelines("++ System is up to date\n")
  813.                         log.flush()
  814.  
  815.             log.writelines("++ Refresh finished\n")
  816.             log.flush()
  817.             # Stop the blinking
  818.             #self.statusIcon.set_blinking(False)
  819.             self.wTree.get_widget("notebook_details").set_current_page(0)
  820.             self.wTree.get_widget("window1").window.set_cursor(None)
  821.             self.treeview_update.set_model(model)
  822.             del model
  823.             self.wTree.get_widget("window1").set_sensitive(True)
  824.             wTree.get_widget("vpaned1").set_position(vpaned_position)
  825.             gtk.gdk.threads_leave()
  826.  
  827.            
  828.  
  829.         except Exception, detail:
  830.             print "-- Exception occured in the refresh thread: " + str(detail)
  831.             log.writelines("-- Exception occured in the refresh thread: " + str(detail) + "\n")
  832.             log.flush()
  833.             gtk.gdk.threads_enter()
  834.             self.statusIcon.set_from_file(icon_error)
  835.             self.statusIcon.set_tooltip(_("Could not refresh the list of updates"))
  836.             #self.statusIcon.set_blinking(False)
  837.             self.wTree.get_widget("window1").window.set_cursor(None)
  838.             self.wTree.get_widget("window1").set_sensitive(True)
  839.             statusbar.push(context_id, _("Could not refresh the list of updates"))
  840.             wTree.get_widget("vpaned1").set_position(vpaned_position)
  841.             gtk.gdk.threads_leave()
  842.  
  843.     def checkDependencies(self, changes, cache):
  844.         foundSomething = False
  845.         for pkg in changes:
  846.             for dep in pkg.candidateDependencies:
  847.                 for o in dep.or_dependencies:
  848.                     try:
  849.                         if cache[o.name].isUpgradable:
  850.                             pkgFound = False
  851.                             for pkg2 in changes:
  852.                                 if o.name == pkg2.name:
  853.                                     pkgFound = True
  854.                             if pkgFound == False:
  855.                                 newPkg = cache[o.name]
  856.                                 changes.append(newPkg)
  857.                                 foundSomething = True
  858.                     except Exception, detail:
  859.                         pass # don't know why we get these..
  860.         if (foundSomething):
  861.             changes = self.checkDependencies(changes, cache)
  862.         return changes
  863.  
  864. def force_refresh(widget, treeview, statusIcon, wTree):
  865.     refresh = RefreshThread(treeview, statusIcon, wTree, root_mode=True)
  866.     refresh.start()
  867.  
  868. def clear(widget, treeView, statusbar, context_id):
  869.     model = treeView.get_model()
  870.     iter = model.get_iter_first()
  871.     while (iter != None):
  872.         model.set_value(iter, 0, "false")
  873.         iter = model.iter_next(iter)
  874.     statusbar.push(context_id, _("No updates selected"))
  875.  
  876. def select_all(widget, treeView, statusbar, context_id):
  877.     model = treeView.get_model()
  878.     iter = model.get_iter_first()
  879.     while (iter != None):
  880.         model.set_value(iter, UPDATE_CHECKED, "true")
  881.         iter = model.iter_next(iter)
  882.     iter = model.get_iter_first()
  883.     download_size = 0
  884.     num_selected = 0
  885.     while (iter != None):
  886.         checked = model.get_value(iter, UPDATE_CHECKED)
  887.         if (checked == "true"):            
  888.             size = model.get_value(iter, UPDATE_SIZE)
  889.             download_size = download_size + size
  890.             num_selected = num_selected + 1                                
  891.         iter = model.iter_next(iter)
  892.     if num_selected == 0:
  893.         statusbar.push(context_id, _("No updates selected"))
  894.     elif num_selected == 1:
  895.         statusbar.push(context_id, _("%(selected)d update selected (%(size)s)") % {'selected':num_selected, 'size':size_to_string(download_size)})
  896.     else:
  897.         statusbar.push(context_id, _("%(selected)d updates selected (%(size)s)") % {'selected':num_selected, 'size':size_to_string(download_size)})
  898.  
  899. def install(widget, treeView, statusIcon, wTree):
  900.     install = InstallThread(treeView, statusIcon, wTree)
  901.     install.start()
  902.  
  903. def change_icon(widget, button, prefs_tree, treeview, statusIcon, wTree):
  904.     global icon_busy
  905.     global icon_up2date
  906.     global icon_updates
  907.     global icon_error
  908.     global icon_unknown
  909.     global icon_apply
  910.     dialog = gtk.FileChooserDialog(_("Update Manager"), None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
  911.     filter1 = gtk.FileFilter()
  912.     filter1.set_name("*.*")
  913.     filter1.add_pattern("*")
  914.     filter2 = gtk.FileFilter()
  915.     filter2.set_name("*.png")
  916.     filter2.add_pattern("*.png")
  917.     dialog.add_filter(filter2)
  918.     dialog.add_filter(filter1)
  919.  
  920.     if dialog.run() == gtk.RESPONSE_OK:
  921.         filename = dialog.get_filename()
  922.         if (button == "busy"):
  923.             prefs_tree.get_widget("image_busy").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(filename, 24, 24))
  924.             icon_busy = filename
  925.         if (button == "up2date"):
  926.             prefs_tree.get_widget("image_up2date").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(filename, 24, 24))
  927.             icon_up2date = filename
  928.         if (button == "updates"):
  929.             prefs_tree.get_widget("image_updates").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(filename, 24, 24))
  930.             icon_updates = filename
  931.         if (button == "error"):
  932.             prefs_tree.get_widget("image_error").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(filename, 24, 24))
  933.             icon_error = filename
  934.         if (button == "unknown"):
  935.             prefs_tree.get_widget("image_unknown").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(filename, 24, 24))
  936.             icon_unknown = filename
  937.         if (button == "apply"):
  938.             prefs_tree.get_widget("image_apply").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(filename, 24, 24))
  939.             icon_apply = filename
  940.     dialog.destroy()
  941.  
  942. def pref_apply(widget, prefs_tree, treeview, statusIcon, wTree):
  943.     global icon_busy
  944.     global icon_up2date
  945.     global icon_updates
  946.     global icon_error
  947.     global icon_unknown
  948.     global icon_apply    
  949.  
  950.     config = ConfigObj("%s/mintUpdate.conf" % CONFIG_DIR)
  951.  
  952.     #Write level config
  953.     config['levels'] = {}
  954.     config['levels']['level1_visible'] = prefs_tree.get_widget("visible1").get_active()
  955.     config['levels']['level2_visible'] = prefs_tree.get_widget("visible2").get_active()
  956.     config['levels']['level3_visible'] = prefs_tree.get_widget("visible3").get_active()
  957.     config['levels']['level4_visible'] = prefs_tree.get_widget("visible4").get_active()
  958.     config['levels']['level5_visible'] = prefs_tree.get_widget("visible5").get_active()
  959.     config['levels']['level1_safe'] = prefs_tree.get_widget("safe1").get_active()
  960.     config['levels']['level2_safe'] = prefs_tree.get_widget("safe2").get_active()
  961.     config['levels']['level3_safe'] = prefs_tree.get_widget("safe3").get_active()
  962.     config['levels']['level4_safe'] = prefs_tree.get_widget("safe4").get_active()
  963.     config['levels']['level5_safe'] = prefs_tree.get_widget("safe5").get_active()    
  964.     config['levels']['security_visible'] = prefs_tree.get_widget("checkbutton_security_visible").get_active()
  965.     config['levels']['security_safe'] = prefs_tree.get_widget("checkbutton_security_safe").get_active()
  966.  
  967.     #Write refresh config
  968.     config['refresh'] = {}
  969.     config['refresh']['timer_minutes'] = int(prefs_tree.get_widget("timer_minutes").get_value())
  970.     config['refresh']['timer_hours'] = int(prefs_tree.get_widget("timer_hours").get_value())
  971.     config['refresh']['timer_days'] = int(prefs_tree.get_widget("timer_days").get_value())
  972.  
  973.     #Write update config
  974.     config['update'] = {}    
  975.     config['update']['dist_upgrade'] = prefs_tree.get_widget("checkbutton_dist_upgrade").get_active()
  976.  
  977.     #Write icons config
  978.     config['icons'] = {}
  979.     config['icons']['busy'] = icon_busy
  980.     config['icons']['up2date'] = icon_up2date
  981.     config['icons']['updates'] = icon_updates
  982.     config['icons']['error'] = icon_error
  983.     config['icons']['unknown'] = icon_unknown
  984.     config['icons']['apply'] = icon_apply
  985.    
  986.     #Write blacklisted updates
  987.     ignored_list = open("%s/mintupdate.ignored" % CONFIG_DIR, "w")
  988.     treeview_blacklist = prefs_tree.get_widget("treeview_blacklist")
  989.     model = treeview_blacklist.get_model()
  990.     iter = model.get_iter_first()
  991.     while iter is not None:
  992.         pkg = model.get_value(iter, UPDATE_CHECKED)
  993.         iter = model.iter_next(iter)
  994.         ignored_list.writelines(pkg + "\n")
  995.     ignored_list.close()
  996.  
  997.     config.write()
  998.  
  999.     prefs_tree.get_widget("window2").hide()
  1000.     refresh = RefreshThread(treeview, statusIcon, wTree)
  1001.     refresh.start()
  1002.  
  1003. def kernels_cancel(widget, tree):
  1004.     tree.get_widget("window5").hide()
  1005.  
  1006. def info_cancel(widget, prefs_tree):
  1007.     prefs_tree.get_widget("window3").hide()
  1008.  
  1009. def history_cancel(widget, tree):
  1010.     tree.get_widget("window4").hide()
  1011.  
  1012. def pref_cancel(widget, prefs_tree):
  1013.     prefs_tree.get_widget("window2").hide()
  1014.  
  1015. def read_configuration():
  1016.     global icon_busy
  1017.     global icon_up2date
  1018.     global icon_updates
  1019.     global icon_error
  1020.     global icon_unknown
  1021.     global icon_apply
  1022.  
  1023.     config = ConfigObj("%s/mintUpdate.conf" % CONFIG_DIR)
  1024.     prefs = {}
  1025.  
  1026.     #Read refresh config
  1027.     try:
  1028.         prefs["timer_minutes"] = int(config['refresh']['timer_minutes'])
  1029.         prefs["timer_hours"] = int(config['refresh']['timer_hours'])
  1030.         prefs["timer_days"] = int(config['refresh']['timer_days'])
  1031.     except:
  1032.         prefs["timer_minutes"] = 30
  1033.         prefs["timer_hours"] = 0
  1034.         prefs["timer_days"] = 0
  1035.  
  1036.     #Read update config
  1037.     try:        
  1038.         prefs["dist_upgrade"] = (config['update']['dist_upgrade'] == "True")
  1039.     except:        
  1040.         prefs["dist_upgrade"] = True
  1041.  
  1042.     #Read icons config
  1043.     try:
  1044.         icon_busy = config['icons']['busy']
  1045.         icon_up2date = config['icons']['up2date']
  1046.         icon_updates = config['icons']['updates']
  1047.         icon_error = config['icons']['error']
  1048.         icon_unknown = config['icons']['unknown']
  1049.         icon_apply = config['icons']['apply']
  1050.     except:
  1051.         icon_busy = "/usr/lib/linuxmint/mintUpdate/icons/base.svg"
  1052.         icon_up2date = "/usr/lib/linuxmint/mintUpdate/icons/base-apply.svg"
  1053.         icon_updates = "/usr/lib/linuxmint/mintUpdate/icons/base-info.svg"
  1054.         icon_error = "/usr/lib/linuxmint/mintUpdate/icons/base-error2.svg"
  1055.         icon_unknown = "/usr/lib/linuxmint/mintUpdate/icons/base.svg"
  1056.         icon_apply = "/usr/lib/linuxmint/mintUpdate/icons/base-exec.svg"
  1057.  
  1058.     #Read levels config
  1059.     try:
  1060.         prefs["level1_visible"] = (config['levels']['level1_visible'] == "True")
  1061.         prefs["level2_visible"] = (config['levels']['level2_visible'] == "True")
  1062.         prefs["level3_visible"] = (config['levels']['level3_visible'] == "True")
  1063.         prefs["level4_visible"] = (config['levels']['level4_visible'] == "True")
  1064.         prefs["level5_visible"] = (config['levels']['level5_visible'] == "True")
  1065.         prefs["level1_safe"] = (config['levels']['level1_safe'] == "True")
  1066.         prefs["level2_safe"] = (config['levels']['level2_safe'] == "True")
  1067.         prefs["level3_safe"] = (config['levels']['level3_safe'] == "True")
  1068.         prefs["level4_safe"] = (config['levels']['level4_safe'] == "True")
  1069.         prefs["level5_safe"] = (config['levels']['level5_safe'] == "True")
  1070.         prefs["security_visible"] = (config['levels']['security_visible'] == "True")
  1071.         prefs["security_safe"] = (config['levels']['security_safe'] == "True")
  1072.     except:
  1073.         prefs["level1_visible"] = True
  1074.         prefs["level2_visible"] = True
  1075.         prefs["level3_visible"] = True
  1076.         prefs["level4_visible"] = False
  1077.         prefs["level5_visible"] = False
  1078.         prefs["level1_safe"] = True
  1079.         prefs["level2_safe"] = True
  1080.         prefs["level3_safe"] = True
  1081.         prefs["level4_safe"] = False
  1082.         prefs["level5_safe"] = False    
  1083.         prefs["security_visible"] = True
  1084.         prefs["security_safe"] = False
  1085.  
  1086.     #Read columns config
  1087.     try:
  1088.         prefs["type_column_visible"] = (config['visible_columns']['type'] == "True")
  1089.     except:
  1090.         prefs["type_column_visible"] = True
  1091.     try:
  1092.         prefs["level_column_visible"] = (config['visible_columns']['level'] == "True")
  1093.     except:
  1094.         prefs["level_column_visible"] = True
  1095.     try:
  1096.         prefs["package_column_visible"] = (config['visible_columns']['package'] == "True")
  1097.     except:
  1098.         prefs["package_column_visible"] = True
  1099.     try:
  1100.         prefs["old_version_column_visible"] = (config['visible_columns']['old_version'] == "True")
  1101.     except:
  1102.         prefs["old_version_column_visible"] = False
  1103.     try:
  1104.         prefs["new_version_column_visible"] = (config['visible_columns']['new_version'] == "True")
  1105.     except:
  1106.         prefs["new_version_column_visible"] = True
  1107.     try:
  1108.         prefs["size_column_visible"] = (config['visible_columns']['size'] == "True")
  1109.     except:
  1110.         prefs["size_column_visible"] = False
  1111.     try:
  1112.         prefs["descriptions_visible"] = (config['visible_columns']['description'] == "True")
  1113.     except:
  1114.         prefs["descriptions_visible"] = True
  1115.  
  1116.     #Read window dimensions
  1117.     try:
  1118.         prefs["dimensions_x"] = int(config['dimensions']['x'])
  1119.         prefs["dimensions_y"] = int(config['dimensions']['y'])
  1120.         prefs["dimensions_pane_position"] = int(config['dimensions']['pane_position'])
  1121.     except:
  1122.         prefs["dimensions_x"] = 790
  1123.         prefs["dimensions_y"] = 540
  1124.         prefs["dimensions_pane_position"] = 278
  1125.  
  1126.     #Read package blacklist
  1127.     try:
  1128.         prefs["blacklisted_packages"] = config['blacklisted_packages']
  1129.     except:
  1130.         prefs["blacklisted_packages"] = []
  1131.  
  1132.     return prefs
  1133.  
  1134. def open_repositories(widget):
  1135.     if os.path.exists("/usr/bin/software-sources"):
  1136.         os.system("/usr/bin/software-sources &")
  1137.     elif os.path.exists("/usr/bin/software-properties-gtk"):
  1138.         os.system("/usr/bin/software-properties-gtk &")
  1139.     elif os.path.exists("/usr/bin/software-properties-kde"):
  1140.         os.system("/usr/bin/software-properties-kde &")
  1141.  
  1142. def open_preferences(widget, treeview, statusIcon, wTree):
  1143.     global icon_busy
  1144.     global icon_up2date
  1145.     global icon_updates
  1146.     global icon_error
  1147.     global icon_unknown
  1148.     global icon_apply
  1149.  
  1150.     gladefile = "/usr/lib/linuxmint/mintUpdate/mintUpdate.glade"
  1151.     prefs_tree = gtk.glade.XML(gladefile, "window2")
  1152.     prefs_tree.get_widget("window2").set_title(_("Preferences") + " - " + _("Update Manager"))
  1153.  
  1154.     prefs_tree.get_widget("label37").set_text(_("Levels"))
  1155.     prefs_tree.get_widget("label36").set_text(_("Auto-Refresh"))
  1156.     prefs_tree.get_widget("label39").set_markup("<b>" + _("Level") + "</b>")
  1157.     prefs_tree.get_widget("label40").set_markup("<b>" + _("Description") + "</b>")
  1158.     prefs_tree.get_widget("label48").set_markup("<b>" + _("Tested?") + "</b>")
  1159.     prefs_tree.get_widget("label54").set_markup("<b>" + _("Origin") + "</b>")
  1160.     prefs_tree.get_widget("label41").set_markup("<b>" + _("Safe?") + "</b>")
  1161.     prefs_tree.get_widget("label42").set_markup("<b>" + _("Visible?") + "</b>")
  1162.     prefs_tree.get_widget("label43").set_text(_("Certified updates. Tested through Romeo or directly maintained by Linux Mint."))
  1163.     prefs_tree.get_widget("label44").set_text(_("Recommended updates. Tested and approved by Linux Mint."))
  1164.     prefs_tree.get_widget("label45").set_text(_("Safe updates. Not tested but believed to be safe."))
  1165.     prefs_tree.get_widget("label46").set_text(_("Unsafe updates. Could potentially affect the stability of the system."))
  1166.     prefs_tree.get_widget("label47").set_text(_("Dangerous updates. Known to affect the stability of the systems depending on certain specs or hardware."))
  1167.     prefs_tree.get_widget("label55").set_text(_("Linux Mint"))
  1168.     prefs_tree.get_widget("label56").set_text(_("Upstream"))
  1169.     prefs_tree.get_widget("label57").set_text(_("Upstream"))
  1170.     prefs_tree.get_widget("label58").set_text(_("Upstream"))
  1171.     prefs_tree.get_widget("label59").set_text(_("Upstream"))
  1172.     prefs_tree.get_widget("label81").set_text(_("Refresh the list of updates every:"))
  1173.     prefs_tree.get_widget("label82").set_text("<i>" + _("Note: The list only gets refreshed while the update manager window is closed (system tray mode).") + "</i>")
  1174.     prefs_tree.get_widget("label82").set_use_markup(True)
  1175.     prefs_tree.get_widget("label83").set_text(_("Update Method"))        
  1176.     prefs_tree.get_widget("label85").set_text(_("Icons"))
  1177.     prefs_tree.get_widget("label86").set_markup("<b>" + _("Icon") + "</b>")
  1178.     prefs_tree.get_widget("label87").set_markup("<b>" + _("Status") + "</b>")
  1179.     prefs_tree.get_widget("label95").set_markup("<b>" + _("New Icon") + "</b>")
  1180.     prefs_tree.get_widget("label88").set_text(_("Busy"))
  1181.     prefs_tree.get_widget("label89").set_text(_("System up-to-date"))
  1182.     prefs_tree.get_widget("label90").set_text(_("Updates available"))
  1183.     prefs_tree.get_widget("label99").set_text(_("Error"))
  1184.     prefs_tree.get_widget("label2").set_text(_("Unknown state"))
  1185.     prefs_tree.get_widget("label3").set_text(_("Applying updates"))    
  1186.     prefs_tree.get_widget("label1").set_text(_("Ignored updates"))
  1187.  
  1188.     prefs_tree.get_widget("checkbutton_dist_upgrade").set_label(_("Include updates which require the installation of new packages or the removal of installed packages"))
  1189.  
  1190.     prefs_tree.get_widget("window2").set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  1191.     prefs_tree.get_widget("window2").show()
  1192.     prefs_tree.get_widget("pref_button_cancel").connect("clicked", pref_cancel, prefs_tree)
  1193.     prefs_tree.get_widget("pref_button_apply").connect("clicked", pref_apply, prefs_tree, treeview, statusIcon, wTree)
  1194.  
  1195.     prefs_tree.get_widget("button_icon_busy").connect("clicked", change_icon, "busy", prefs_tree, treeview, statusIcon, wTree)
  1196.     prefs_tree.get_widget("button_icon_up2date").connect("clicked", change_icon, "up2date", prefs_tree, treeview, statusIcon, wTree)
  1197.     prefs_tree.get_widget("button_icon_updates").connect("clicked", change_icon, "updates", prefs_tree, treeview, statusIcon, wTree)
  1198.     prefs_tree.get_widget("button_icon_error").connect("clicked", change_icon, "error", prefs_tree, treeview, statusIcon, wTree)
  1199.     prefs_tree.get_widget("button_icon_unknown").connect("clicked", change_icon, "unknown", prefs_tree, treeview, statusIcon, wTree)
  1200.     prefs_tree.get_widget("button_icon_apply").connect("clicked", change_icon, "apply", prefs_tree, treeview, statusIcon, wTree)
  1201.  
  1202.     prefs = read_configuration()
  1203.  
  1204.     prefs_tree.get_widget("visible1").set_active(prefs["level1_visible"])
  1205.     prefs_tree.get_widget("visible2").set_active(prefs["level2_visible"])
  1206.     prefs_tree.get_widget("visible3").set_active(prefs["level3_visible"])
  1207.     prefs_tree.get_widget("visible4").set_active(prefs["level4_visible"])
  1208.     prefs_tree.get_widget("visible5").set_active(prefs["level5_visible"])
  1209.     prefs_tree.get_widget("safe1").set_active(prefs["level1_safe"])
  1210.     prefs_tree.get_widget("safe2").set_active(prefs["level2_safe"])
  1211.     prefs_tree.get_widget("safe3").set_active(prefs["level3_safe"])
  1212.     prefs_tree.get_widget("safe4").set_active(prefs["level4_safe"])
  1213.     prefs_tree.get_widget("safe5").set_active(prefs["level5_safe"])
  1214.     prefs_tree.get_widget("checkbutton_security_visible").set_active(prefs["security_visible"])
  1215.     prefs_tree.get_widget("checkbutton_security_safe").set_active(prefs["security_safe"])    
  1216.  
  1217.     prefs_tree.get_widget("checkbutton_security_visible").set_label(_("Always show security updates"))
  1218.     prefs_tree.get_widget("checkbutton_security_safe").set_label(_("Always select and trust security updates"))
  1219.  
  1220.     prefs_tree.get_widget("timer_minutes_label").set_text(_("minutes"))
  1221.     prefs_tree.get_widget("timer_hours_label").set_text(_("hours"))
  1222.     prefs_tree.get_widget("timer_days_label").set_text(_("days"))
  1223.     prefs_tree.get_widget("timer_minutes").set_value(prefs["timer_minutes"])
  1224.     prefs_tree.get_widget("timer_hours").set_value(prefs["timer_hours"])
  1225.     prefs_tree.get_widget("timer_days").set_value(prefs["timer_days"])
  1226.  
  1227.     prefs_tree.get_widget("checkbutton_dist_upgrade").set_active(prefs["dist_upgrade"])
  1228.  
  1229.     prefs_tree.get_widget("image_busy").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(icon_busy, 24, 24))
  1230.     prefs_tree.get_widget("image_up2date").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(icon_up2date, 24, 24))
  1231.     prefs_tree.get_widget("image_updates").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(icon_updates, 24, 24))
  1232.     prefs_tree.get_widget("image_error").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(icon_error, 24, 24))
  1233.     prefs_tree.get_widget("image_unknown").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(icon_unknown, 24, 24))
  1234.     prefs_tree.get_widget("image_apply").set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(icon_apply, 24, 24))
  1235.  
  1236.     # Blacklisted updates
  1237.     treeview_blacklist = prefs_tree.get_widget("treeview_blacklist")
  1238.     column1 = gtk.TreeViewColumn(_("Ignored updates"), gtk.CellRendererText(), text=0)
  1239.     column1.set_sort_column_id(0)
  1240.     column1.set_resizable(True)
  1241.     treeview_blacklist.append_column(column1)
  1242.     treeview_blacklist.set_headers_clickable(True)
  1243.     treeview_blacklist.set_reorderable(False)
  1244.     treeview_blacklist.show()
  1245.  
  1246.     model = gtk.TreeStore(str)
  1247.     model.set_sort_column_id( 0, gtk.SORT_ASCENDING )
  1248.     treeview_blacklist.set_model(model)
  1249.  
  1250.     if os.path.exists("%s/mintupdate.ignored" % CONFIG_DIR):
  1251.         ignored_list = open("%s/mintupdate.ignored" % CONFIG_DIR, "r")
  1252.         for ignored_pkg in ignored_list:            
  1253.             iter = model.insert_before(None, None)
  1254.             model.set_value(iter, 0, ignored_pkg.strip())
  1255.         del model
  1256.         ignored_list.close()
  1257.    
  1258.     prefs_tree.get_widget("toolbutton_add").connect("clicked", add_blacklisted_package, treeview_blacklist)
  1259.     prefs_tree.get_widget("toolbutton_remove").connect("clicked", remove_blacklisted_package, treeview_blacklist)
  1260.  
  1261. def add_blacklisted_package(widget, treeview_blacklist):
  1262.  
  1263.     dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK, None)
  1264.     dialog.set_markup("<b>" + _("Please specify the name of the update to ignore:") + "</b>")
  1265.     dialog.set_title(_("Ignore an update"))
  1266.     dialog.set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  1267.     entry = gtk.Entry()
  1268.     hbox = gtk.HBox()
  1269.     hbox.pack_start(gtk.Label(_("Name:")), False, 5, 5)
  1270.     hbox.pack_end(entry)    
  1271.     dialog.vbox.pack_end(hbox, True, True, 0)
  1272.     dialog.show_all()
  1273.     dialog.run()
  1274.     name = entry.get_text()
  1275.     dialog.destroy()
  1276.     pkg = name.strip()
  1277.     if pkg != '':
  1278.         model = treeview_blacklist.get_model()
  1279.         iter = model.insert_before(None, None)
  1280.         model.set_value(iter, 0, pkg)
  1281.  
  1282. def remove_blacklisted_package(widget, treeview_blacklist):
  1283.     selection = treeview_blacklist.get_selection()
  1284.     (model, iter) = selection.get_selected()
  1285.     if (iter != None):
  1286.         pkg = model.get_value(iter, UPDATE_CHECKED)
  1287.         model.remove(iter)
  1288.  
  1289. def open_history(widget):
  1290.     #Set the Glade file
  1291.     gladefile = "/usr/lib/linuxmint/mintUpdate/mintUpdate.glade"
  1292.     wTree = gtk.glade.XML(gladefile, "window4")
  1293.     treeview_update = wTree.get_widget("treeview_history")
  1294.     wTree.get_widget("window4").set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  1295.  
  1296.     wTree.get_widget("window4").set_title(_("History of updates") + " - " + _("Update Manager"))
  1297.  
  1298.     # the treeview
  1299.     column1 = gtk.TreeViewColumn(_("Date"), gtk.CellRendererText(), text=1)
  1300.     column1.set_sort_column_id(1)
  1301.     column1.set_resizable(True)
  1302.     column2 = gtk.TreeViewColumn(_("Package"), gtk.CellRendererText(), text=0)
  1303.     column2.set_sort_column_id(0)
  1304.     column2.set_resizable(True)
  1305.     column3 = gtk.TreeViewColumn(_("Old version"), gtk.CellRendererText(), text=2)
  1306.     column3.set_sort_column_id(2)
  1307.     column3.set_resizable(True)
  1308.     column4 = gtk.TreeViewColumn(_("New version"), gtk.CellRendererText(), text=3)
  1309.     column4.set_sort_column_id(3)
  1310.     column4.set_resizable(True)    
  1311.  
  1312.     treeview_update.append_column(column1)
  1313.     treeview_update.append_column(column2)
  1314.     treeview_update.append_column(column3)    
  1315.     treeview_update.append_column(column4)    
  1316.  
  1317.     treeview_update.set_headers_clickable(True)
  1318.     treeview_update.set_reorderable(False)
  1319.     treeview_update.set_search_column(0)
  1320.     treeview_update.set_enable_search(True)
  1321.     treeview_update.show()
  1322.  
  1323.     model = gtk.TreeStore(str, str, str, str) # (packageName, date, oldVersion, newVersion)
  1324.  
  1325.     if (os.path.exists("/var/log/dpkg.log")):
  1326.         updates = commands.getoutput("cat /var/log/dpkg.log /var/log/dpkg.log.? 2>/dev/null | egrep \"upgrade\"")
  1327.         updates = string.split(updates, "\n")
  1328.         for pkg in updates:
  1329.             values = string.split(pkg, " ")
  1330.             if len(values) == 6:
  1331.                 date = values[0]
  1332.                 time = values[1]
  1333.                 action = values[2]
  1334.                 package = values[3]
  1335.                 oldVersion = values[4]
  1336.                 newVersion = values[5]    
  1337.  
  1338.                 if action != "upgrade":
  1339.                     continue
  1340.  
  1341.                 if oldVersion == newVersion:
  1342.                     continue
  1343.  
  1344.                 if ":" in package:
  1345.                     package = package.split(":")[0]
  1346.  
  1347.                 iter = model.insert_before(None, None)
  1348.                 model.set_value(iter, 0, package)
  1349.                 model.row_changed(model.get_path(iter), iter)
  1350.                 model.set_value(iter, 1, "%s - %s" % (date, time))                        
  1351.                 model.set_value(iter, 2, oldVersion)
  1352.                 model.set_value(iter, 3, newVersion)                
  1353.  
  1354.     model.set_sort_column_id( 1, gtk.SORT_DESCENDING )
  1355.     treeview_update.set_model(model)
  1356.     del model
  1357.     wTree.get_widget("button_close").connect("clicked", history_cancel, wTree)
  1358.  
  1359. def open_information(widget):
  1360.     global logFile
  1361.     global pid
  1362.  
  1363.     gladefile = "/usr/lib/linuxmint/mintUpdate/mintUpdate.glade"
  1364.     prefs_tree = gtk.glade.XML(gladefile, "window3")
  1365.     prefs_tree.get_widget("window3").set_title(_("Information") + " - " + _("Update Manager"))
  1366.     prefs_tree.get_widget("window3").set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  1367.     prefs_tree.get_widget("close_button").connect("clicked", info_cancel, prefs_tree)    
  1368.     prefs_tree.get_widget("label4").set_text(_("Process ID:"))
  1369.     prefs_tree.get_widget("label5").set_text(_("Log file:"))
  1370.     prefs_tree.get_widget("processid_label").set_text(str(pid))
  1371.     prefs_tree.get_widget("log_filename").set_text(str(logFile))
  1372.     txtbuffer = gtk.TextBuffer()
  1373.     txtbuffer.set_text(commands.getoutput("cat " + logFile))
  1374.     prefs_tree.get_widget("log_textview").set_buffer(txtbuffer)
  1375.  
  1376. def label_size_allocate(widget, rect):
  1377.     widget.set_size_request(rect.width, -1)
  1378.  
  1379. def install_kernel(widget, selection, wTree, window):
  1380.     (model, iter) = selection.get_selected()
  1381.     if (iter != None):
  1382.         (status, version, pkg_version, installed, used, recommended, installable) = model.get_value(iter, 7)
  1383.         installed = (installed == "1")
  1384.         used = (used == "1")            
  1385.         installable = (installable == "1")
  1386.         if (installed):
  1387.             message = _("Are you sure you want to remove the %s kernel?") % version
  1388.         else:
  1389.             message = _("Are you sure you want to install the %s kernel?") % version
  1390.         image = gtk.Image()
  1391.         image.set_from_file("/usr/lib/linuxmint/mintUpdate/icons/warning.png")
  1392.         d = gtk.MessageDialog(window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, message)
  1393.         image.show()
  1394.         d.set_image(image)    
  1395.         d.set_default_response(gtk.RESPONSE_NO)
  1396.         r = d.run()  
  1397.         d.hide()    
  1398.         d.destroy()
  1399.         if r == gtk.RESPONSE_YES:
  1400.             thread = InstallKernelThread(version, wTree, installed)
  1401.             thread.start()        
  1402.             window.hide()
  1403.  
  1404. def open_kernels(widget):
  1405.     global logFile
  1406.     global pid
  1407.  
  1408.     gladefile = "/usr/lib/linuxmint/mintUpdate/mintUpdate.glade"
  1409.     tree = gtk.glade.XML(gladefile, "window5")
  1410.     window = tree.get_widget("window5")
  1411.     window.set_title(_("Linux kernels") + " - " + _("Update Manager"))
  1412.     window.set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")    
  1413.     tree.get_widget("close_button").connect("clicked", kernels_cancel, tree)
  1414.  
  1415.     tree.get_widget("label_warning").connect("size-allocate", label_size_allocate)
  1416.     tree.get_widget("label_contact").connect("size-allocate", label_size_allocate)
  1417.  
  1418.  
  1419.     tree.get_widget("title_warning").set_markup("<span foreground='black' font_weight='bold' size='large'>%s</span>" % _("Warning!"))
  1420.     tree.get_widget("label_warning").set_markup(_("The Linux kernel is a critical part of the system. Regressions can lead to lack of networking, lack of sound, lack of graphical environment or even the inability to boot the computer. Only install or remove kernels if you're experienced with kernels, drivers, dkms and you know how to recover a non-booting computer."))
  1421.     tree.get_widget("label_available").set_markup("%s" % _("The following kernels are available:"))    
  1422.     tree.get_widget("label_more_info").set_text(_("More info..."))
  1423.  
  1424.     tree.get_widget("label_more_info_1").set_markup("<small>%s</small>" % _("Fixes can represent bug fixes, improvements in hardware support or security fixes."))
  1425.     tree.get_widget("label_more_info_2").set_markup("<small>%s</small>" % _("Security fixes are important when local users represent a potential threat (in companies, libraries, schools or public places for instance) or when the computer can be threatened by remote attacks (servers for instance)."))
  1426.     tree.get_widget("label_more_info_3").set_markup("<small>%s</small>" % _("Bug fixes and hardware improvements are important if one of your devices isn't working as expected and the newer kernel addresses that problem."))
  1427.     tree.get_widget("label_more_info_4").set_markup("<small>%s</small>" % _("Regressions represent something which worked well and no longer works after an update. It is common in software development that a code change or even a bug fix introduces side effects and breaks something else. Because of regressions it is recommended to be selective when installing updates or newer kernels."))
  1428.  
  1429.     tree.get_widget("label_known_fixes").set_text(_("Fixes"))
  1430.     tree.get_widget("label_known_regressions").set_text(_("Regressions"))
  1431.     tree.get_widget("label_contact").set_markup("<span foreground='#3c3c3c' font_weight='bold' size='small'>%s</span>" % _("Note: Only known fixes and regressions are mentioned. If you are aware of additional fixes or regressions, please contact the development team."))
  1432.  
  1433.     # the treeview
  1434.     treeview_kernels = tree.get_widget("treeview_kernels")
  1435.  
  1436.     column1 = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), markup=1)
  1437.     column1.set_sort_column_id(1)
  1438.     column1.set_resizable(True)
  1439.     column1.set_expand(True)
  1440.     column2 = gtk.TreeViewColumn(_("Loaded"), gtk.CellRendererPixbuf(), pixbuf=2)
  1441.     column2.set_sort_column_id(2)
  1442.     column2.set_resizable(True)
  1443.     column2.set_expand(False)
  1444.     column3 = gtk.TreeViewColumn(_("Recommended"), gtk.CellRendererPixbuf(), pixbuf=3)
  1445.     column3.set_sort_column_id(3)
  1446.     column3.set_resizable(True)
  1447.     column3.set_expand(False)
  1448.     column4 = gtk.TreeViewColumn(_("Installed"), gtk.CellRendererPixbuf(), pixbuf=4)
  1449.     column4.set_sort_column_id(4)
  1450.     column4.set_resizable(True)
  1451.     column4.set_expand(False)
  1452.     column5 = gtk.TreeViewColumn(_("Fixes"), gtk.CellRendererPixbuf(), pixbuf=5)
  1453.     column5.set_sort_column_id(5)
  1454.     column5.set_resizable(True)
  1455.     column5.set_expand(False)
  1456.     column6 = gtk.TreeViewColumn(_("Regressions"), gtk.CellRendererPixbuf(), pixbuf=6)
  1457.     column6.set_sort_column_id(6)
  1458.     column6.set_resizable(True)
  1459.     column6.set_expand(False)
  1460.  
  1461.     treeview_kernels.append_column(column1)
  1462.     treeview_kernels.append_column(column2)
  1463.     treeview_kernels.append_column(column3)
  1464.     treeview_kernels.append_column(column4)
  1465.     treeview_kernels.append_column(column5)
  1466.     treeview_kernels.append_column(column6)
  1467.  
  1468.     treeview_kernels.set_headers_clickable(True)
  1469.     treeview_kernels.set_reorderable(False)
  1470.     treeview_kernels.set_search_column(1)
  1471.     treeview_kernels.set_enable_search(True)
  1472.     treeview_kernels.show()
  1473.  
  1474.     model = gtk.TreeStore(str, str, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf, object) # (version, label, loaded, recommended, installed, fixes, regressions, values)
  1475.  
  1476.     kernels = commands.getoutput("/usr/lib/linuxmint/mintUpdate/checkKernels.py | grep \"###\"")
  1477.     kernels = kernels.split("\n")
  1478.     column = 2
  1479.     for kernel in kernels:
  1480.         values = string.split(kernel, "###")
  1481.         if len(values) == 7:
  1482.             status = values[0]
  1483.             if status != "KERNEL":
  1484.                 continue
  1485.             (status, version, pkg_version, installed, used, recommended, installable) = values
  1486.             installed = (installed == "1")
  1487.             used = (used == "1")
  1488.             recommended = (recommended == "1")
  1489.             installable = (installable == "1")
  1490.             label = version
  1491.  
  1492.             tick = gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/tick.png")
  1493.             pix_fixes = gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/fixes.png")
  1494.             pix_bugs = gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/regressions.png")
  1495.  
  1496.  
  1497.             iter = model.insert_before(None, None)
  1498.             model.set_value(iter, 0, version)            
  1499.             model.set_value(iter, 7, values)
  1500.             model.row_changed(model.get_path(iter), iter)          
  1501.                        
  1502.             if os.path.exists("/usr/lib/linuxmint/mintUpdate/kernels/%s" % version):
  1503.                 kernel_file = open("/usr/lib/linuxmint/mintUpdate/kernels/%s" % version)
  1504.                 lines = kernel_file.readlines()
  1505.                 num_fixes = 0
  1506.                 num_bugs = 0
  1507.                 for line in lines:
  1508.                     elements = line.split("---")
  1509.                     if len(elements) == 4:
  1510.                         (prefix, title, url, description) = elements                        
  1511.                         if prefix == "fix":
  1512.                             num_fixes += 1
  1513.                         elif prefix == "bug":
  1514.                             num_bugs += 1
  1515.                 if num_fixes > 0:
  1516.                     model.set_value(iter, 5, pix_fixes)
  1517.                 if num_bugs > 0:
  1518.                     model.set_value(iter, 6, pix_bugs)
  1519.  
  1520.             if os.path.exists("/usr/lib/linuxmint/mintUpdate/kernels/versions"):
  1521.                 kernel_file = open("/usr/lib/linuxmint/mintUpdate/kernels/versions")
  1522.                 lines = kernel_file.readlines()
  1523.                 for line in lines:
  1524.                     elements = line.split("\t")
  1525.                     if len(elements) == 3:                        
  1526.                         (versions_version, versions_tag, versions_upstream) = elements                        
  1527.                         if versions_version == pkg_version:
  1528.                             label = "%s (%s)" % (version, versions_upstream.strip())                          
  1529.  
  1530.             if installable and not installed:
  1531.                 button = gtk.Button(_("Install"))
  1532.                 button.connect("clicked", install_kernel, version, window, tree, False)                
  1533.  
  1534.             elif installed and not used:                                            
  1535.                 button = gtk.Button(_("Remove"))
  1536.                 button.connect("clicked", install_kernel, version, window, tree, True)
  1537.  
  1538.             if used:                
  1539.                 model.set_value(iter, 2, tick)
  1540.                 label = "<b>%s</b>" % label                
  1541.             if recommended:                
  1542.                 model.set_value(iter, 3, tick)
  1543.             if installed:                
  1544.                 model.set_value(iter, 4, tick)
  1545.  
  1546.             model.set_value(iter, 1, label)
  1547.                
  1548.     treeview_kernels.set_model(model)
  1549.     del model
  1550.  
  1551.     selection = treeview_kernels.get_selection()
  1552.     selection.connect("changed", display_selected_kernel, tree)
  1553.  
  1554.     button_install = tree.get_widget("button_install")
  1555.     button_install.connect('clicked', install_kernel, selection, tree, window)
  1556.  
  1557.     window.show_all()
  1558.  
  1559. def display_selected_kernel(selection, wTree):
  1560.     button_install = wTree.get_widget("button_install")
  1561.     button_install.set_sensitive(False)
  1562.     button_install.set_tooltip_text("")
  1563.     try:
  1564.         scrolled_fixes = wTree.get_widget("scrolled_fixes")
  1565.         scrolled_regressions = wTree.get_widget("scrolled_regressions")
  1566.         for child in scrolled_fixes.get_children():
  1567.             scrolled_fixes.remove(child)
  1568.         for child in scrolled_regressions.get_children():
  1569.             scrolled_regressions.remove(child)        
  1570.         (model, iter) = selection.get_selected()
  1571.         if (iter != None):
  1572.             (status, version, pkg_version, installed, used, recommended, installable) = model.get_value(iter, 7)
  1573.             installed = (installed == "1")
  1574.             used = (used == "1")            
  1575.             installable = (installable == "1")
  1576.             if installed:
  1577.                 button_install.set_label(_("Remove the %s kernel") % version)
  1578.                 if used:
  1579.                     button_install.set_tooltip_text(_("This kernel cannot be removed because it is currently in use."))
  1580.                 else:
  1581.                     button_install.set_sensitive(True)
  1582.             else:
  1583.                 button_install.set_label(_("Install the %s kernel" % version))
  1584.                 if not installable:
  1585.                     button_install.set_tooltip_text(_("This kernel is not installable."))
  1586.                 else:
  1587.                     button_install.set_sensitive(True)
  1588.             if os.path.exists("/usr/lib/linuxmint/mintUpdate/kernels/%s" % version):
  1589.                 kernel_file = open("/usr/lib/linuxmint/mintUpdate/kernels/%s" % version)
  1590.                 lines = kernel_file.readlines()
  1591.                 fixes_box = gtk.Table()
  1592.                 fixes_box.set_row_spacings(3)
  1593.                 bugs_box = gtk.Table()
  1594.                 bugs_box.set_row_spacings(3)
  1595.                 num_fixes = 0
  1596.                 num_bugs = 0
  1597.                 for line in lines:
  1598.                     elements = line.split("---")
  1599.                     if len(elements) == 4:
  1600.                         (prefix, title, url, description) = elements
  1601.                         link = gtk.Label()
  1602.                         link.set_markup("<a href='%s'>%s</a>" % (url.strip(), title.strip()))
  1603.                         link.set_alignment(0, 0.5);
  1604.                         description_label = gtk.Label()
  1605.                         description = description.strip()
  1606.                         description = re.sub(r'CVE-(\d+)-(\d+)', r'<a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=\g<0>">\g<0></a>', description)
  1607.                         description_label.set_markup("%s" % description.strip())
  1608.                         description_label.set_alignment(0, 0.5);
  1609.                         if prefix == "fix":
  1610.                             fixes_box.attach(link, 0, 1, num_fixes, num_fixes+1, xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=3, ypadding=0)
  1611.                             fixes_box.attach(description_label, 1, 2, num_fixes, num_fixes+1, xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=0, ypadding=0)
  1612.                             num_fixes += 1
  1613.                         elif prefix == "bug":
  1614.                             bugs_box.attach(link, 0, 1, num_bugs, num_bugs+1, xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=3, ypadding=0)
  1615.                             bugs_box.attach(description_label, 1, 2, num_bugs, num_bugs+1, xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=0, ypadding=0)
  1616.                             num_bugs += 1
  1617.                 scrolled_fixes.add_with_viewport(fixes_box)
  1618.                 scrolled_regressions.add_with_viewport(bugs_box)
  1619.                 fixes_box.show_all()
  1620.                 bugs_box.show_all()
  1621.     except Exception, detail:
  1622.         print detail
  1623.  
  1624. def open_help(widget):
  1625.     os.system("yelp help:linuxmint/software-updates &")
  1626.  
  1627. def open_rel_upgrade(widget):
  1628.     os.system("/usr/bin/mint-release-upgrade &")
  1629.  
  1630. def open_about(widget):
  1631.     dlg = gtk.AboutDialog()
  1632.     dlg.set_title(_("About") + " - " + _("Update Manager"))
  1633.     dlg.set_program_name("mintUpdate")
  1634.     dlg.set_comments(_("Update Manager"))
  1635.     try:
  1636.         h = open('/usr/share/common-licenses/GPL','r')
  1637.         s = h.readlines()
  1638.         gpl = ""
  1639.         for line in s:
  1640.             gpl += line
  1641.         h.close()
  1642.         dlg.set_license(gpl)
  1643.     except Exception, detail:
  1644.         print detail
  1645.     try:
  1646.         version = commands.getoutput("/usr/lib/linuxmint/common/version.py mintupdate")
  1647.         dlg.set_version(version)
  1648.     except Exception, detail:
  1649.         print detail
  1650.  
  1651.     dlg.set_authors(["Clement Lefebvre <root@linuxmint.com>", "Chris Hodapp <clhodapp@live.com>"])
  1652.     dlg.set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  1653.     dlg.set_logo(gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg"))
  1654.     def close(w, res):
  1655.         if res == gtk.RESPONSE_CANCEL:
  1656.             w.hide()
  1657.     dlg.connect("response", close)
  1658.     dlg.show()
  1659.  
  1660. def quit_cb(widget, window, vpaned, data = None):
  1661.     global log
  1662.     if data:
  1663.         data.set_visible(False)
  1664.     try:
  1665.         log.writelines("++ Exiting - requested by user\n")
  1666.         log.flush()
  1667.         log.close()
  1668.         save_window_size(window, vpaned)
  1669.     except:
  1670.         pass # cause log might already been closed
  1671.     # Whatever works best heh :)
  1672.     pid = os.getpid()    
  1673.     os.system("kill -9 %s &" % pid)
  1674.     #gtk.main_quit()
  1675.     #sys.exit(0)
  1676.  
  1677. def popup_menu_cb(widget, button, time, data = None):
  1678.     if button == 3:
  1679.         if data:
  1680.             data.show_all()
  1681.             data.popup(None, None, gtk.status_icon_position_menu, 3, time, widget)
  1682.     pass
  1683.  
  1684. def close_window(window, event, vpaned):
  1685.     global app_hidden
  1686.     window.hide()
  1687.     save_window_size(window, vpaned)
  1688.     app_hidden = True
  1689.     return True
  1690.  
  1691. def hide_window(widget, window):
  1692.     global app_hidden
  1693.     window.hide()
  1694.     app_hidden = True
  1695.  
  1696. def activate_icon_cb(widget, data, wTree):
  1697.     global app_hidden
  1698.     if (app_hidden == True):            
  1699.         wTree.get_widget("window1").show_all()
  1700.         app_hidden = False
  1701.     else:
  1702.         wTree.get_widget("window1").hide()
  1703.         app_hidden = True
  1704.         save_window_size(wTree.get_widget("window1"), wTree.get_widget("vpaned1"))
  1705.  
  1706. def save_window_size(window, vpaned):
  1707.  
  1708.     config = ConfigObj("%s/mintUpdate.conf" % CONFIG_DIR)
  1709.     config['dimensions'] = {}
  1710.     config['dimensions']['x'] = window.get_size()[0]
  1711.     config['dimensions']['y'] = window.get_size()[1]
  1712.     config['dimensions']['pane_position'] = vpaned.get_position()
  1713.     config.write()
  1714.  
  1715. def clean_l10n_short_description(description):
  1716.         try:
  1717.             # Remove "Description-xx: " prefix
  1718.             value = re.sub(r'Description-(\S+): ', r'', description)
  1719.             # Only take the first line and trim it
  1720.             value = value.split("\n")[0].strip()
  1721.             # Capitalize the first letter
  1722.             value = value[:1].upper() + value[1:]
  1723.             # Add missing punctuation
  1724.             if len(value) > 0 and value[-1] not in [".", "!", "?"]:
  1725.                 value = "%s." % value
  1726.             # Replace & signs with &amp; (because we pango it)
  1727.             value = value.replace('&', '&amp;')
  1728.  
  1729.             return value
  1730.         except Exception, detail:
  1731.             print detail
  1732.             return description
  1733.  
  1734. def clean_l10n_description(description):
  1735.         try:
  1736.             lines = description.split("\n")
  1737.             value = ""
  1738.             num = 0
  1739.             newline = False
  1740.             for line in lines:
  1741.                 line = line.strip()
  1742.                 if len(line) > 0:
  1743.                     if line == ".":
  1744.                         value = "%s\n" % (value)
  1745.                         newline = True
  1746.                     else:
  1747.                         if (newline):
  1748.                             value = "%s%s" % (value, line.capitalize())
  1749.                         else:
  1750.                             value = "%s %s" % (value, line)
  1751.                         newline = False
  1752.                     num += 1
  1753.             value = value.replace("  ", " ").strip()
  1754.             # Capitalize the first letter
  1755.             value = value[:1].upper() + value[1:]
  1756.             # Add missing punctuation
  1757.             if len(value) > 0 and value[-1] not in [".", "!", "?"]:
  1758.                 value = "%s." % value
  1759.             return value
  1760.         except Exception, detail:
  1761.             print detail
  1762.             return description
  1763.  
  1764. def l10n_descriptions(package_update):
  1765.         package_name = package_update.name.replace(":i386", "").replace(":amd64", "")
  1766.         if package_descriptions.has_key(package_name):
  1767.             package_update.short_description = package_short_descriptions[package_name]
  1768.             package_update.description = package_descriptions[package_name]
  1769.  
  1770. def display_selected_package(selection, wTree):    
  1771.     try:
  1772.         wTree.get_widget("textview_description").get_buffer().set_text("")
  1773.         wTree.get_widget("textview_changes").get_buffer().set_text("")            
  1774.         (model, iter) = selection.get_selected()
  1775.         if (iter != None):                            
  1776.             package_update = model.get_value(iter, UPDATE_OBJ)
  1777.             if wTree.get_widget("notebook_details").get_current_page() == 0:
  1778.                 # Description tab          
  1779.                 description = package_update.description
  1780.                 buffer = wTree.get_widget("textview_description").get_buffer()
  1781.                 buffer.set_text(description)
  1782.                 import pango
  1783.                 try:
  1784.                     buffer.create_tag("dimmed", scale=pango.SCALE_SMALL, foreground="#5C5C5C", style=pango.STYLE_ITALIC)
  1785.                 except:
  1786.                     # Already exists, no big deal..
  1787.                     pass
  1788.                 if (len(package_update.packages) > 1):
  1789.                     dimmed_description = "\n%s %s" % (_("This update contains %d packages: ") % len(package_update.packages), " ".join(package_update.packages))
  1790.                     buffer.insert_with_tags_by_name(buffer.get_end_iter(), dimmed_description, "dimmed")
  1791.                 elif (package_update.packages[0] != package_update.name):
  1792.                     dimmed_description = "\n%s %s" % (_("This update contains 1 package: "), package_update.packages[0])
  1793.                     buffer.insert_with_tags_by_name(buffer.get_end_iter(), dimmed_description, "dimmed")
  1794.             else:
  1795.                 # Changelog tab
  1796.                 retriever = ChangelogRetriever(package_update.name, package_update.level, package_update.newVersion, wTree)
  1797.                 retriever.start()
  1798.                
  1799.     except Exception, detail:
  1800.         print detail
  1801.  
  1802. def switch_page(notebook, page, page_num, Wtree, treeView):
  1803.     selection = treeView.get_selection()
  1804.     (model, iter) = selection.get_selected()
  1805.     if (iter != None):
  1806.         package_update = model.get_value(iter, UPDATE_OBJ)
  1807.         if (page_num == 0):
  1808.             # Description tab
  1809.             description = package_update.description
  1810.             buffer = wTree.get_widget("textview_description").get_buffer()
  1811.             buffer.set_text(description)
  1812.             import pango
  1813.             try:
  1814.                 buffer.create_tag("dimmed", scale=pango.SCALE_SMALL, foreground="#5C5C5C", style=pango.STYLE_ITALIC)
  1815.             except:
  1816.                 # Already exists, no big deal..
  1817.                 pass
  1818.             if (len(package_update.packages) > 1):
  1819.                 dimmed_description = "\n%s %s" % (_("This update contains %d packages: ") % len(package_update.packages), " ".join(package_update.packages))
  1820.                 buffer.insert_with_tags_by_name(buffer.get_end_iter(), dimmed_description, "dimmed")
  1821.             elif (package_update.packages[0] != package_update.name):
  1822.                 dimmed_description = "\n%s %s" % (_("This update contains 1 package: "), package_update.packages[0])
  1823.                 buffer.insert_with_tags_by_name(buffer.get_end_iter(), dimmed_description, "dimmed")
  1824.         else:
  1825.             # Changelog tab                
  1826.             retriever = ChangelogRetriever(package_update.name, package_update.level, package_update.newVersion, wTree)
  1827.             retriever.start()
  1828.  
  1829. def celldatafunction_checkbox(column, cell, model, iter):
  1830.     cell.set_property("activatable", True)
  1831.     checked = model.get_value(iter, UPDATE_CHECKED)
  1832.     if (checked == "true"):
  1833.         cell.set_property("active", True)
  1834.     else:
  1835.         cell.set_property("active", False)
  1836.  
  1837. def toggled(renderer, path, treeview, statusbar, context_id):
  1838.     model = treeview.get_model()
  1839.     iter = model.get_iter(path)
  1840.     if (iter != None):
  1841.         checked = model.get_value(iter, UPDATE_CHECKED)
  1842.         if (checked == "true"):
  1843.             model.set_value(iter, UPDATE_CHECKED, "false")
  1844.         else:
  1845.             model.set_value(iter, UPDATE_CHECKED, "true")
  1846.    
  1847.     iter = model.get_iter_first()
  1848.     download_size = 0
  1849.     num_selected = 0
  1850.     while (iter != None):
  1851.         checked = model.get_value(iter, UPDATE_CHECKED)
  1852.         if (checked == "true"):            
  1853.             size = model.get_value(iter, UPDATE_SIZE)
  1854.             download_size = download_size + size
  1855.             num_selected = num_selected + 1                                
  1856.         iter = model.iter_next(iter)
  1857.     if num_selected == 0:
  1858.         statusbar.push(context_id, _("No updates selected"))
  1859.     elif num_selected == 1:
  1860.         statusbar.push(context_id, _("%(selected)d update selected (%(size)s)") % {'selected':num_selected, 'size':size_to_string(download_size)})
  1861.     else:
  1862.         statusbar.push(context_id, _("%(selected)d updates selected (%(size)s)") % {'selected':num_selected, 'size':size_to_string(download_size)})
  1863.    
  1864. def size_to_string(size):
  1865.     strSize = str(size) + _("B")
  1866.     if (size >= 1024):
  1867.         strSize = str(size / 1024) + _("KB")
  1868.     if (size >= (1024 * 1024)):
  1869.         strSize = str(size / (1024 * 1024)) + _("MB")
  1870.     if (size >= (1024 * 1024 * 1024)):
  1871.         strSize = str(size / (1024 * 1024 * 1024)) + _("GB")
  1872.     return strSize
  1873.  
  1874. def setVisibleColumn(checkmenuitem, column, configName):
  1875.     config = ConfigObj("%s/mintUpdate.conf" % CONFIG_DIR)
  1876.     if (config.has_key('visible_columns')):
  1877.         config['visible_columns'][configName] = checkmenuitem.get_active()
  1878.     else:
  1879.         config['visible_columns'] = {}
  1880.         config['visible_columns'][configName] = checkmenuitem.get_active()
  1881.     config.write()
  1882.     column.set_visible(checkmenuitem.get_active())
  1883.  
  1884. def setVisibleDescriptions(checkmenuitem, treeView, statusIcon, wTree, prefs):
  1885.     config = ConfigObj("%s/mintUpdate.conf" % CONFIG_DIR)
  1886.     if (not config.has_key('visible_columns')):
  1887.         config['visible_columns'] = {}
  1888.     config['visible_columns']['description'] = checkmenuitem.get_active()
  1889.     config.write()
  1890.     prefs["descriptions_visible"] = checkmenuitem.get_active()
  1891.     refresh = RefreshThread(treeView, statusIcon, wTree)
  1892.     refresh.start()
  1893.    
  1894. def menuPopup(widget, event, treeview_update, statusIcon, wTree):
  1895.     if event.button == 3:
  1896.         (model, iter) = widget.get_selection().get_selected()
  1897.         if (iter != None):
  1898.             package_update = model.get_value(iter, UPDATE_OBJ)
  1899.             menu = gtk.Menu()                
  1900.             menuItem = gtk.MenuItem(_("Ignore updates for this package"))
  1901.             menuItem.connect("activate", add_to_ignore_list, treeview_update, package_update.name, statusIcon, wTree)
  1902.             menu.append(menuItem)        
  1903.             menu.show_all()        
  1904.             menu.popup( None, None, None, 3, 0)
  1905.        
  1906. def add_to_ignore_list(widget, treeview_update, pkg, statusIcon, wTree):
  1907.     os.system("echo \"%s\" >> %s/mintupdate.ignored" % (pkg, CONFIG_DIR))
  1908.     refresh = RefreshThread(treeview_update, statusIcon, wTree)
  1909.     refresh.start()
  1910.  
  1911. global app_hidden
  1912. global log
  1913. global logFile
  1914. global pid
  1915. global statusbar
  1916. global context_id
  1917.  
  1918. app_hidden = True
  1919.  
  1920. gtk.gdk.threads_init()
  1921.  
  1922. # prepare the log
  1923. pid = os.getpid()
  1924. logdir = "/tmp/mintUpdate/"
  1925.  
  1926. if not os.path.exists(logdir):
  1927.     os.system("mkdir -p " + logdir)
  1928.     os.system("chmod a+rwx " + logdir)
  1929.    
  1930. log = tempfile.NamedTemporaryFile(prefix = logdir, delete=False)
  1931. logFile = log.name
  1932. try:
  1933.     os.system("chmod a+rw %s" % log.name)
  1934. except Exception, detail:
  1935.     print detail
  1936.  
  1937. log.writelines("++ Launching mintUpdate \n")
  1938. log.flush()
  1939.  
  1940. if (not os.path.exists(CONFIG_DIR)):
  1941.     os.system("mkdir -p %s" % CONFIG_DIR)    
  1942.     log.writelines("++ Creating %s directory\n" % CONFIG_DIR)
  1943.     log.flush()
  1944.  
  1945. try:
  1946.     global icon_busy
  1947.     global icon_up2date
  1948.     global icon_updates
  1949.     global icon_error
  1950.     global icon_unknown
  1951.     global icon_apply
  1952.  
  1953.     prefs = read_configuration()
  1954.  
  1955.     statusIcon = gtk.StatusIcon()
  1956.     statusIcon.set_from_file(icon_busy)
  1957.     statusIcon.set_tooltip(_("Checking for updates"))
  1958.     statusIcon.set_visible(True)    
  1959.  
  1960.     #Set the Glade file
  1961.     gladefile = "/usr/lib/linuxmint/mintUpdate/mintUpdate.glade"
  1962.     wTree = gtk.glade.XML(gladefile, "window1")
  1963.     wTree.get_widget("window1").set_title(_("Update Manager"))
  1964.     wTree.get_widget("window1").set_default_size(prefs['dimensions_x'], prefs['dimensions_y'])
  1965.     wTree.get_widget("vpaned1").set_position(prefs['dimensions_pane_position'])
  1966.    
  1967.     statusbar = wTree.get_widget("statusbar")
  1968.     context_id = statusbar.get_context_id("mintUpdate")
  1969.  
  1970.     vbox = wTree.get_widget("vbox_main")
  1971.     treeview_update = wTree.get_widget("treeview_update")
  1972.     wTree.get_widget("window1").set_icon_from_file("/usr/lib/linuxmint/mintUpdate/icons/base.svg")
  1973.  
  1974.     accel_group = gtk.AccelGroup()
  1975.     wTree.get_widget("window1").add_accel_group(accel_group)
  1976.  
  1977.     # Get the window socket (needed for synaptic later on)
  1978.    
  1979.     if os.getuid() != 0 :
  1980.         # If we're not in root mode do that (don't know why it's needed.. very weird)
  1981.         socket = gtk.Socket()
  1982.         vbox.pack_start(socket, False, False, 0)
  1983.         socket.show()
  1984.         window_id = repr(socket.get_id())
  1985.  
  1986.     # the treeview
  1987.     cr = gtk.CellRendererToggle()
  1988.     cr.connect("toggled", toggled, treeview_update, statusbar, context_id)
  1989.     column1 = gtk.TreeViewColumn(_("Upgrade"), cr)
  1990.     column1.set_cell_data_func(cr, celldatafunction_checkbox)
  1991.     column1.set_sort_column_id(UPDATE_CHECKED)
  1992.     column1.set_resizable(True)
  1993.  
  1994.     column2 = gtk.TreeViewColumn(_("Package"), gtk.CellRendererText(), markup=UPDATE_NAME)
  1995.     column2.set_sort_column_id(UPDATE_NAME)
  1996.     column2.set_resizable(True)
  1997.  
  1998.     column3 = gtk.TreeViewColumn(_("Level"), gtk.CellRendererPixbuf(), pixbuf=UPDATE_LEVEL_PIX)
  1999.     column3.set_sort_column_id(UPDATE_LEVEL_STR)
  2000.     column3.set_resizable(True)
  2001.  
  2002.     column4 = gtk.TreeViewColumn(_("Old version"), gtk.CellRendererText(), text=UPDATE_OLD_VERSION)
  2003.     column4.set_sort_column_id(UPDATE_OLD_VERSION)
  2004.     column4.set_resizable(True)
  2005.  
  2006.     column5 = gtk.TreeViewColumn(_("New version"), gtk.CellRendererText(), text=UPDATE_NEW_VERSION)
  2007.     column5.set_sort_column_id(UPDATE_NEW_VERSION)
  2008.     column5.set_resizable(True)
  2009.  
  2010.     column6 = gtk.TreeViewColumn(_("Size"), gtk.CellRendererText(), text=UPDATE_SIZE_STR)
  2011.     column6.set_sort_column_id(UPDATE_SIZE)
  2012.     column6.set_resizable(True)
  2013.  
  2014.     column7 = gtk.TreeViewColumn(_("Type"), gtk.CellRendererPixbuf(), pixbuf=UPDATE_TYPE_PIX)
  2015.     column7.set_sort_column_id(UPDATE_TYPE)
  2016.     column7.set_resizable(True)
  2017.  
  2018.     treeview_update.set_tooltip_column(UPDATE_TOOLTIP)
  2019.  
  2020.     treeview_update.append_column(column7)
  2021.     treeview_update.append_column(column3)    
  2022.     treeview_update.append_column(column1)
  2023.     treeview_update.append_column(column2)
  2024.     treeview_update.append_column(column4)
  2025.     treeview_update.append_column(column5)    
  2026.     treeview_update.append_column(column6)
  2027.    
  2028.     treeview_update.set_headers_clickable(True)
  2029.     treeview_update.set_reorderable(False)
  2030.     treeview_update.show()
  2031.    
  2032.     treeview_update.connect( "button-release-event", menuPopup, treeview_update, statusIcon, wTree )
  2033.  
  2034.     selection = treeview_update.get_selection()
  2035.     selection.connect("changed", display_selected_package, wTree)
  2036.     wTree.get_widget("notebook_details").connect("switch-page", switch_page, wTree, treeview_update)
  2037.     wTree.get_widget("window1").connect("delete_event", close_window, wTree.get_widget("vpaned1"))
  2038.     wTree.get_widget("tool_apply").connect("clicked", install, treeview_update, statusIcon, wTree)
  2039.     wTree.get_widget("tool_clear").connect("clicked", clear, treeview_update, statusbar, context_id)
  2040.     wTree.get_widget("tool_select_all").connect("clicked", select_all, treeview_update, statusbar, context_id)
  2041.     wTree.get_widget("tool_refresh").connect("clicked", force_refresh, treeview_update, statusIcon, wTree)
  2042.  
  2043.     menu = gtk.Menu()
  2044.     menuItem3 = gtk.ImageMenuItem(gtk.STOCK_REFRESH)
  2045.     menuItem3.connect('activate', force_refresh, treeview_update, statusIcon, wTree)
  2046.     menu.append(menuItem3)
  2047.     menuItem2 = gtk.ImageMenuItem(gtk.STOCK_DIALOG_INFO)
  2048.     menuItem2.connect('activate', open_information)
  2049.     menu.append(menuItem2)    
  2050.     menuItem4 = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
  2051.     menuItem4.connect('activate', open_preferences, treeview_update, statusIcon, wTree)
  2052.     menu.append(menuItem4)
  2053.     menuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
  2054.     menuItem.connect('activate', quit_cb, wTree.get_widget("window1"), wTree.get_widget("vpaned1"), statusIcon)
  2055.     menu.append(menuItem)
  2056.  
  2057.     statusIcon.connect('activate', activate_icon_cb, None, wTree)
  2058.     statusIcon.connect('popup-menu', popup_menu_cb, menu)
  2059.  
  2060.     # Set text for all visible widgets (because of i18n)
  2061.     wTree.get_widget("tool_apply").set_label(_("Install Updates"))
  2062.     wTree.get_widget("tool_refresh").set_label(_("Refresh"))
  2063.     wTree.get_widget("tool_select_all").set_label(_("Select All"))
  2064.     wTree.get_widget("tool_clear").set_label(_("Clear"))
  2065.     wTree.get_widget("label9").set_text(_("Description"))
  2066.     wTree.get_widget("label8").set_text(_("Changelog"))
  2067.  
  2068.     wTree.get_widget("label_error_detail").set_text("")
  2069.     wTree.get_widget("hbox_error").hide()
  2070.     wTree.get_widget("scrolledwindow1").hide()
  2071.     wTree.get_widget("viewport1").hide()
  2072.     wTree.get_widget("label_error_detail").hide()
  2073.     wTree.get_widget("image_error").hide()
  2074.     wTree.get_widget("vpaned1").set_position(prefs['dimensions_pane_position'])
  2075.  
  2076.     fileMenu = gtk.MenuItem(_("_File"))
  2077.     fileSubmenu = gtk.Menu()
  2078.     fileMenu.set_submenu(fileSubmenu)
  2079.     closeMenuItem = gtk.ImageMenuItem(gtk.STOCK_CLOSE)
  2080.     closeMenuItem.get_child().set_text(_("Close"))
  2081.     closeMenuItem.connect("activate", hide_window, wTree.get_widget("window1"))
  2082.     fileSubmenu.append(closeMenuItem)
  2083.  
  2084.     editMenu = gtk.MenuItem(_("_Edit"))
  2085.     editSubmenu = gtk.Menu()
  2086.     editMenu.set_submenu(editSubmenu)
  2087.     prefsMenuItem = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
  2088.     prefsMenuItem.get_child().set_text(_("Preferences"))
  2089.     prefsMenuItem.connect("activate", open_preferences, treeview_update, statusIcon, wTree)
  2090.     editSubmenu.append(prefsMenuItem)
  2091.     if os.path.exists("/usr/bin/software-sources") or os.path.exists("/usr/bin/software-properties-gtk") or os.path.exists("/usr/bin/software-properties-kde"):
  2092.         sourcesMenuItem = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
  2093.         sourcesMenuItem.set_image(gtk.image_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/software-properties.png"))
  2094.         sourcesMenuItem.get_child().set_text(_("Software sources"))
  2095.         sourcesMenuItem.connect("activate", open_repositories)
  2096.         editSubmenu.append(sourcesMenuItem)
  2097.  
  2098.     rel_edition = 'unknown'
  2099.     rel_codename = 'unknown'
  2100.     if os.path.exists("/etc/linuxmint/info"):
  2101.         with open("/etc/linuxmint/info", "r") as info:
  2102.             for line in info:
  2103.                 line = line.strip()
  2104.                 if "EDITION=" in line:
  2105.                     rel_edition = line.split('=')[1].replace('"', '').split()[0]
  2106.                 if "CODENAME=" in line:
  2107.                     rel_codename = line.split('=')[1].replace('"', '').split()[0]
  2108.  
  2109.     rel_path = "/usr/lib/linuxmint/mintUpdate/rel_upgrades/%s" % rel_codename
  2110.     if os.path.exists(rel_path):
  2111.         config = ConfigObj(os.path.join(rel_path, "info"))
  2112.         if rel_edition.lower() in config['general']['editions']:
  2113.             rel_target = config['general']['target_name']
  2114.             relUpgradeMenuItem = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
  2115.             relUpgradeMenuItem.set_image(gtk.image_new_from_file("/usr/lib/linuxmint/mintUpdate/icons/rel_upgrade.png"))
  2116.             relUpgradeMenuItem.get_child().set_text(_("Upgrade to %s") % rel_target)
  2117.             relUpgradeMenuItem.connect("activate", open_rel_upgrade)
  2118.             editSubmenu.append(relUpgradeMenuItem)
  2119.  
  2120.     viewMenu = gtk.MenuItem(_("_View"))
  2121.     viewSubmenu = gtk.Menu()
  2122.     viewMenu.set_submenu(viewSubmenu)
  2123.     historyMenuItem = gtk.ImageMenuItem(gtk.STOCK_INDEX)
  2124.     historyMenuItem.get_child().set_text(_("History of updates"))
  2125.     historyMenuItem.connect("activate", open_history)
  2126.     kernelMenuItem = gtk.ImageMenuItem(gtk.STOCK_EXECUTE)
  2127.     kernelMenuItem.get_child().set_text(_("Linux kernels"))
  2128.     kernelMenuItem.connect("activate", open_kernels)
  2129.     infoMenuItem = gtk.ImageMenuItem(gtk.STOCK_DIALOG_INFO)
  2130.     infoMenuItem.get_child().set_text(_("Information"))
  2131.     infoMenuItem.connect("activate", open_information)
  2132.     visibleColumnsMenuItem = gtk.MenuItem(gtk.STOCK_DIALOG_INFO)
  2133.     visibleColumnsMenuItem.get_child().set_text(_("Visible columns"))
  2134.     visibleColumnsMenu = gtk.Menu()
  2135.     visibleColumnsMenuItem.set_submenu(visibleColumnsMenu)
  2136.  
  2137.     typeColumnMenuItem = gtk.CheckMenuItem(_("Type"))
  2138.     typeColumnMenuItem.set_active(prefs["type_column_visible"])
  2139.     column7.set_visible(prefs["type_column_visible"])
  2140.     typeColumnMenuItem.connect("toggled", setVisibleColumn, column7, "type")
  2141.     visibleColumnsMenu.append(typeColumnMenuItem)
  2142.  
  2143.     levelColumnMenuItem = gtk.CheckMenuItem(_("Level"))
  2144.     levelColumnMenuItem.set_active(prefs["level_column_visible"])
  2145.     column3.set_visible(prefs["level_column_visible"])
  2146.     levelColumnMenuItem.connect("toggled", setVisibleColumn, column3, "level")
  2147.     visibleColumnsMenu.append(levelColumnMenuItem)
  2148.  
  2149.     packageColumnMenuItem = gtk.CheckMenuItem(_("Package"))
  2150.     packageColumnMenuItem.set_active(prefs["package_column_visible"])
  2151.     column2.set_visible(prefs["package_column_visible"])
  2152.     packageColumnMenuItem.connect("toggled", setVisibleColumn, column2, "package")
  2153.     visibleColumnsMenu.append(packageColumnMenuItem)
  2154.  
  2155.     oldVersionColumnMenuItem = gtk.CheckMenuItem(_("Old version"))
  2156.     oldVersionColumnMenuItem.set_active(prefs["old_version_column_visible"])
  2157.     column4.set_visible(prefs["old_version_column_visible"])
  2158.     oldVersionColumnMenuItem.connect("toggled", setVisibleColumn, column4, "old_version")
  2159.     visibleColumnsMenu.append(oldVersionColumnMenuItem)
  2160.  
  2161.     newVersionColumnMenuItem = gtk.CheckMenuItem(_("New version"))
  2162.     newVersionColumnMenuItem.set_active(prefs["new_version_column_visible"])
  2163.     column5.set_visible(prefs["new_version_column_visible"])
  2164.     newVersionColumnMenuItem.connect("toggled", setVisibleColumn, column5, "new_version")
  2165.     visibleColumnsMenu.append(newVersionColumnMenuItem)
  2166.  
  2167.     sizeColumnMenuItem = gtk.CheckMenuItem(_("Size"))
  2168.     sizeColumnMenuItem.set_active(prefs["size_column_visible"])
  2169.     column6.set_visible(prefs["size_column_visible"])
  2170.     sizeColumnMenuItem.connect("toggled", setVisibleColumn, column6, "size")
  2171.     visibleColumnsMenu.append(sizeColumnMenuItem)
  2172.  
  2173.     viewSubmenu.append(visibleColumnsMenuItem)
  2174.  
  2175.     descriptionsMenuItem = gtk.CheckMenuItem(_("Show descriptions"))
  2176.     descriptionsMenuItem.set_active(prefs["descriptions_visible"])    
  2177.     descriptionsMenuItem.connect("toggled", setVisibleDescriptions, treeview_update, statusIcon, wTree, prefs)
  2178.     viewSubmenu.append(descriptionsMenuItem)
  2179.  
  2180.     viewSubmenu.append(historyMenuItem)
  2181.     viewSubmenu.append(kernelMenuItem)
  2182.     viewSubmenu.append(infoMenuItem)
  2183.  
  2184.     helpMenu = gtk.MenuItem(_("_Help"))
  2185.     helpSubmenu = gtk.Menu()
  2186.     helpMenu.set_submenu(helpSubmenu)
  2187.     helpMenuItem = gtk.ImageMenuItem(gtk.STOCK_HELP)
  2188.     helpMenuItem.get_child().set_text(_("Contents"))
  2189.     helpMenuItem.connect("activate", open_help)
  2190.     key, mod = gtk.accelerator_parse("F1")
  2191.     helpMenuItem.add_accelerator("activate", accel_group, key, mod, gtk.ACCEL_VISIBLE)
  2192.     aboutMenuItem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
  2193.     aboutMenuItem.get_child().set_text(_("About"))
  2194.     aboutMenuItem.connect("activate", open_about)
  2195.     helpSubmenu.append(helpMenuItem)
  2196.     helpSubmenu.append(aboutMenuItem)
  2197.  
  2198.     #browser.connect("activate", browser_callback)
  2199.     #browser.show()
  2200.     wTree.get_widget("menubar1").append(fileMenu)
  2201.     wTree.get_widget("menubar1").append(editMenu)
  2202.     wTree.get_widget("menubar1").append(viewMenu)
  2203.     wTree.get_widget("menubar1").append(helpMenu)
  2204.  
  2205.     if len(sys.argv) > 1:
  2206.         showWindow = sys.argv[1]
  2207.         if (showWindow == "show"):
  2208.             wTree.get_widget("window1").show_all()
  2209.             wTree.get_widget("label_error_detail").set_text("")
  2210.             wTree.get_widget("hbox_error").hide()
  2211.             wTree.get_widget("scrolledwindow1").hide()
  2212.             wTree.get_widget("viewport1").hide()
  2213.             wTree.get_widget("label_error_detail").hide()
  2214.             wTree.get_widget("image_error").hide()
  2215.             wTree.get_widget("vpaned1").set_position(prefs['dimensions_pane_position'])
  2216.             app_hidden = False    
  2217.  
  2218.     wTree.get_widget("notebook_details").set_current_page(0)
  2219.  
  2220.     refresh = RefreshThread(treeview_update, statusIcon, wTree)
  2221.     refresh.start()
  2222.  
  2223.     auto_refresh = AutomaticRefreshThread(treeview_update, statusIcon, wTree)
  2224.     auto_refresh.start()
  2225.     gtk.main()
  2226.  
  2227. except Exception, detail:
  2228.     print detail
  2229.     log.writelines("-- Exception occured in main thread: " + str(detail) + "\n")
  2230.     log.flush()
  2231.     log.close()
Add Comment
Please, Sign In to add comment