2
# update-manager.in - easy updating application
4
# Copyright (c) 2004 Canonical
7
# Author: Michiel Sikkes <michiel@eyesopened.nl>
8
# Michael Vogt <mvo@debian.org>
10
# This program is free software; you can redistribute it and/or
11
# modify it under the terms of the GNU General Public License as
12
# published by the Free Software Foundation; either version 2 of the
13
# License, or (at your option) any later version.
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
# GNU General Public License for more details.
20
# You should have received a copy of the GNU General Public License
21
# along with this program; if not, write to the Free Software
22
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
49
import xml.sax.saxutils
53
# - cary a reference to the update-class around in the ListStore
54
# - kill "all_changes" and move the changes into the "Update" class
57
(LIST_INSTALL, LIST_CONTENTS, LIST_NAME, LIST_SHORTDESC,
58
LIST_VERSION, LIST_LONG_DESCR, LIST_PKG) = range(7)
60
# actions for "invoke_manager"
61
(INSTALL, UPDATE) = range(2)
63
SYNAPTIC_PINFILE = "/var/lib/synaptic/preferences"
65
METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release"
66
#METARELEASE_URI = "http://people.ubuntu.com/~mvo/meta-release-test"
67
METARELEASE_FILE = "/var/lib/update-manager/meta-release"
69
CHANGELOGS_URI="http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog"
71
# fixme: use a utils package for this sort of stuff
73
if str == "0" or str.upper() == "FALSE":
78
return unicode(str, 'latin1').encode('utf-8')
82
def __init__(self, package, cache, records, depcache):
83
#package = cache[name]
85
version = depcache.GetCandidateVer(package)
86
file, index = version.FileList.pop(0)
87
records.Lookup((file, index))
90
self.version = version.VerStr
91
self.shortdesc = records.ShortDesc
93
self.size = version.Size
95
longdesc = records.LongDesc
96
lines = longdesc.split("\n")
100
first_char = string.strip(line)[0]
102
self.longdesc = self.longdesc + "\n"
104
self.longdesc = self.longdesc + line + "\n"
107
def __init__(self, parent_window):
110
self.parent_window = parent_window
112
def saveDistUpgrade(self, cache, depcache):
113
""" this functions mimics a upgrade but will never remove anything """
114
depcache.Upgrade(True)
115
if depcache.DelCount > 0:
116
# nice try, falling back
117
for pkg in cache.Packages:
118
depcache.MarkKeep(pkg)
119
assert depcache.BrokenCount == 0 and depcache.DelCount == 0
122
def update(self, cache, records, depcache):
125
self.saveDistUpgrade(cache, depcache)
126
for pkg in cache.Packages:
127
if depcache.MarkedUpgrade(pkg) or depcache.MarkedInstall(pkg):
128
self.pkgs.append(Update(pkg, cache, records, depcache))
129
self.num_updates = self.num_updates + 1
130
elif depcache.IsInstBroken(pkg) or depcache.IsNowBroken(pkg):
131
broken.append(pkg.Name)
132
elif pkg.CurrentVer != None and depcache.IsUpgradable(pkg):
133
#print "MarkedKeep: %s " % pkg.Name
134
held_back.append(pkg.Name)
135
self.pkgs.sort(lambda x,y: cmp(x.name,y.name))
136
if depcache.BrokenCount > 0:
137
# FIXME: show what packages are broken
138
msg=("<big><b>%s</b></big>\n\n%s"%(_("Your system has broken packages!"),
139
_("This means that some dependencies "
140
"of the installed packages are not "
141
"satisfied. Please use \"Synaptic\" "
142
"or \"apt-get\" to fix the "
145
dialog = gtk.MessageDialog(self.parent_window, 0, gtk.MESSAGE_ERROR,
147
dialog.set_markup(msg)
148
dialog.vbox.set_spacing(6)
152
if depcache.KeepCount > 0:
153
#print "WARNING, keeping packages"
154
msg=("<big><b>%s</b></big>\n\n%s"%(_("It is not possible to upgrade "
157
"besides the actual upgrade of the "
158
"packages some further action "
159
"(such as installing or removing "
161
"is required. Please use Synaptic "
162
"\"Smart Upgrade\" or "
163
"\"apt-get dist-upgrade\" to fix "
166
dialog = gtk.MessageDialog(self.parent_window, 0, gtk.MESSAGE_INFO,
168
dialog.set_default_response(gtk.RESPONSE_OK)
169
dialog.set_markup(msg)
170
dialog.vbox.set_spacing(6)
171
label = gtk.Label(_("The following packages are not upgraded: "))
172
label.set_alignment(0.0,0.5)
173
dialog.set_border_width(6)
175
dialog.vbox.pack_start(label)
176
scroll = gtk.ScrolledWindow()
177
scroll.set_size_request(-1,200)
178
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
179
text = gtk.TextView()
180
text.set_editable(False)
181
text.set_cursor_visible(False)
182
buf = text.get_buffer()
184
buf.set_text("\n".join(held_back))
186
dialog.vbox.pack_start(scroll)
194
# FIXME: wrong location for this func
195
# don't touch the gui in this function, it needs to be thread-safe
196
def get_changelog(self, name, lock):
197
pkg = self.cache[name]
199
# FIXME: not correct, need to get canidateVer
200
version = self.depcache.GetCandidateVer(pkg)
201
file, index = version.FileList.pop(0)
202
self.records.Lookup((file, index))
203
if self.records.SourcePkg != "":
204
srcpkg = self.records.SourcePkg
209
l = string.split(pkg.Section,"/")
214
if srcpkg.startswith("lib"):
215
prefix = "lib" + srcpkg[3]
217
verstr = version.VerStr
218
l = string.split(verstr,":")
223
uri = CHANGELOGS_URI % (src_section,prefix,srcpkg,srcpkg, verstr)
224
changelog = urllib2.urlopen(uri)
225
#print changelog.read()
226
# do only get the lines that are new
228
regexp = "^%s \((.*)\)(.*)$" % (srcpkg)
232
line = changelog.readline()
236
match = re.match(regexp,line)
238
if apt_pkg.VersionCompare(match.group(1),pkg.CurrentVer.VerStr) <= 0:
240
# EOF (shouldn't really happen)
241
alllines = alllines + line
243
# only write if we where not canceld
245
self.all_changes[name] = [alllines, srcpkg]
246
except urllib2.HTTPError:
248
self.all_changes[name] = [_("Changes not found, the server may not be updated yet."), srcpkg]
251
self.all_changes[name] = [_("Failed to download changes. Please check if there is an active internet connection."), srcpkg]
255
def set_changes_buffer(self, changes_buffer, text, name, srcpkg):
256
changes_buffer.set_text("")
257
lines = text.split("\n")
259
changes_buffer.set_text(text)
264
end_iter = changes_buffer.get_end_iter()
266
version_match = re.match("^%s \((.*)\)(.*)$" % (srcpkg), line)
267
#bullet_match = re.match("^.*[\*-]", line)
268
author_match = re.match("^.*--.*<.*@.*>.*$", line)
270
version = version_match.group(1)
271
version_text = _("Version %s: \n") % version
272
changes_buffer.insert_with_tags_by_name(end_iter, version_text, "versiontag")
273
# mvo: disabled for now as it does not catch multi line entries
274
# (see ubuntu #7034 for rational)
275
#elif bullet_match and not author_match:
276
# bullet_text = " " + line + "\n"
277
# changes_buffer.insert(end_iter, bullet_text)
280
#chanages_buffer.insert(end_iter, "\n")
282
changes_buffer.insert(end_iter, line+"\n")
285
def cursor_changed(self, widget):
286
tuple = widget.get_cursor()
288
# check if we have a path at all
291
model = widget.get_model()
292
iter = model.get_iter(path)
295
long_desc = model.get_value(iter, 5)
296
if long_desc == None:
298
desc_buffer = self.DescView.get_buffer()
299
desc_buffer.set_text(utf8(long_desc))
301
# now do the changelog
302
name = model.get_value(iter, 2)
306
changes_buffer = self.ChangesView.get_buffer()
308
# check if we have the changes already
309
if self.all_changes.has_key(name):
310
changes = self.all_changes[name]
311
self.set_changes_buffer(changes_buffer, changes[0], name, changes[1])
313
if self.expander.get_expanded():
314
self.treeview.set_sensitive(False)
315
self.Glade.get_widget("hbox_footer").set_sensitive(False)
316
lock = thread.allocate_lock()
318
t=thread.start_new_thread(self.get_changelog,(name,lock))
319
changes_buffer.set_text(_("Downloading changes..."))
320
button = self.Glade.get_widget("button_cancel_dl_changelog")
322
id = button.connect("clicked",
323
lambda w,lock: lock.release(), lock)
324
# wait for the dl-thread
327
while gtk.events_pending():
329
# download finished (or canceld, or time-out)
331
button.disconnect(id);
332
self.treeview.set_sensitive(True)
333
self.Glade.get_widget("hbox_footer").set_sensitive(True)
335
if self.all_changes.has_key(name):
336
changes = self.all_changes[name]
337
self.set_changes_buffer(changes_buffer, changes[0], name, changes[1])
339
def remove_update(self, pkg):
341
if name in self.packages:
342
self.packages.remove(name)
343
self.dl_size -= pkg.size
344
if len(self.packages) == 0:
345
self.installbutton.set_sensitive(False)
348
def add_update(self, pkg):
350
if name not in self.packages:
351
self.packages.append(name)
352
self.dl_size += pkg.size
353
if len(self.packages) > 0:
354
self.installbutton.set_sensitive(True)
357
def update_count(self):
358
text = "%i (%s)" % (len(self.packages),
359
apt_pkg.SizeToStr(self.dl_size))
360
self.NumUpdates.set_text(text)
362
def activate_details(self, expander, data):
363
expanded = self.expander.get_expanded()
364
self.gconfclient.set_bool("/apps/update-manager/show_details",expanded)
366
self.cursor_changed(self.treeview)
368
def run_synaptic(self, id, action, lock):
369
apt_pkg.PkgSystemUnLock()
370
cmd = ["/usr/sbin/synaptic", "--hide-main-window", "--non-interactive",
371
"--plug-progress-into", "%s" % (id) ]
372
if action == INSTALL:
373
cmd.append("--set-selections")
374
cmd.append("--progress-str")
375
cmd.append("%s" % _("The updates are being applied."))
376
cmd.append("--finish-str")
377
cmd.append("%s" % _("Upgrade finished"))
378
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
380
for s in self.packages:
381
f.write("%s\tinstall\n" % s)
384
elif action == UPDATE:
385
cmd.append("--update-at-startup")
388
print "run_synaptic() called with unknown action"
391
# use this once gksudo does propper reporting
392
#if os.geteuid() != 0:
393
# if os.system("gksudo /bin/true") != 0:
395
# cmd = "sudo " + cmd;
398
def plug_removed(self, w, (win,socket)):
399
#print "plug_removed"
400
# plug was removed, but we don't want to get it removed, only hiden
405
def plug_added(self, sock, win):
407
while gtk.events_pending():
410
def on_button_reload_clicked(self, widget):
411
#print "on_button_reload_clicked"
412
self.invoke_manager(UPDATE)
414
def on_button_help_clicked(self, widget):
415
gnome.help_display_desktop(self.gnome_program, "update-manager", "update-manager", "")
417
def on_button_install_clicked(self, widget):
418
#print "on_button_install_clicked"
419
self.invoke_manager(INSTALL)
421
def invoke_manager(self, action):
422
# check first if no other package manager is runing
424
lock = os.path.dirname(apt_pkg.Config.Find("Dir::State::status"))+"/lock"
425
lock_file= open(lock)
426
flk=struct.pack('hhllhl',fcntl.F_WRLCK,0,0,0,0,0)
428
rv = fcntl.fcntl(lock_file, fcntl.F_GETLK, flk)
430
print "Error getting lockstatus"
432
locked = struct.unpack('hhllhl', rv)[0]
433
if locked != fcntl.F_UNLCK:
434
msg=("<big><b>%s</b></big>\n\n%s"%(_("Another package manager is "
436
_("You can run only one "
437
"package management application "
438
"at the same time. Please close "
439
"this other application first.")));
440
dialog = gtk.MessageDialog(self.main_window, 0, gtk.MESSAGE_ERROR,
442
dialog.set_markup(msg)
447
# don't display apt-listchanges, we already showed the changelog
448
os.environ["APT_LISTCHANGES_FRONTEND"]="none"
450
# set window to insensitive
451
self.main_window.set_sensitive(False)
452
# create a progress window that will swallow the synaptic progress bars
455
win.set_title(_("Updating package list..."))
457
win.set_title(_("Installing updates..."))
458
win.set_border_width(6)
459
win.set_transient_for(self.main_window)
460
win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
462
win.set_resizable(False)
463
# prevent the window from closing with the delete button (there is
464
# a cancel button in the window)
465
win.connect("delete_event", lambda e,w: True);
468
socket = gtk.Socket()
472
socket.connect("plug-added", self.plug_added, win)
473
socket.connect("plug-removed", self.plug_removed, (win,socket))
474
lock = thread.allocate_lock()
476
t = thread.start_new_thread(self.run_synaptic,(socket.get_id(),action,lock))
478
while gtk.events_pending():
482
while gtk.events_pending():
485
self.main_window.set_sensitive(True)
487
def toggled(self, renderer, path_string):
488
""" a toggle button in the listview was toggled """
489
iter = self.store.get_iter_from_string(path_string)
490
if self.store.get_value(iter, LIST_INSTALL):
491
self.store.set_value(iter, LIST_INSTALL, False)
492
self.remove_update(self.store.get_value(iter, LIST_PKG))
494
self.store.set_value(iter, LIST_INSTALL, True)
495
self.add_update(self.store.get_value(iter, LIST_PKG))
499
""" exit the application, save the state """
504
def save_state(self):
505
""" save the state (window-size for now) """
506
(x,y) = self.main_window.get_size()
507
self.gconfclient.set_pair("/apps/update-manager/window_size",
508
gconf.VALUE_INT, gconf.VALUE_INT, x, y)
510
def restore_state(self):
511
""" restore the state (window-size for now) """
512
expanded = self.gconfclient.get_bool("/apps/update-manager/show_details")
513
self.expander.set_expanded(expanded)
514
(x,y) = self.gconfclient.get_pair("/apps/update-manager/window_size",
515
gconf.VALUE_INT, gconf.VALUE_INT)
517
self.main_window.resize(x,y)
519
def on_button_preferences_clicked(self, widget):
520
""" start gnome-software preferences """
521
# args: "-n" means we take care of the reloading of the
522
# package list ourself
523
apt_pkg.PkgSystemUnLock()
524
args = ['/usr/bin/gnome-software-properties', '-n']
525
child = subprocess.Popen(args)
526
self.main_window.set_sensitive(False)
531
while gtk.events_pending():
533
# repository information changed, call "reload"
535
apt_pkg.PkgSystemLock()
537
print "Error geting the cache"
538
apt_pkg.PkgSystemLock()
540
self.on_button_reload_clicked(None)
541
self.main_window.set_sensitive(True)
543
def __init__(self, download_changes_at_startup=False):
545
self.gnome_program = gnome.init("update-manager", "0.39")
547
self.download_changes_at_startup = download_changes_at_startup
550
self.all_changes = {}
551
self.dist = self.get_dist()
552
if os.path.exists("../data/update-manager.glade"):
553
self.Glade = gtk.glade.XML("../data/update-manager.glade")
555
self.Glade = gtk.glade.XML("@prefix@/share/update-manager/update-manager.glade")
557
self.NumUpdates = self.Glade.get_widget("num_updates")
558
self.main_window = self.Glade.get_widget("MainWindow")
559
self.main_window.connect("delete_event", lambda w, ev: self.exit())
560
self.DescView = self.Glade.get_widget("descview")
561
self.ChangesView = self.Glade.get_widget("textview_changes")
562
changes_buffer = self.ChangesView.get_buffer()
563
changes_buffer.create_tag("versiontag", weight=pango.WEIGHT_BOLD)
564
self.expander = self.Glade.get_widget("expander_details")
565
self.expander.connect("notify::expanded", self.activate_details)
567
self.installbutton = self.Glade.get_widget("button_install")
568
self.Glade.signal_connect("on_button_install_clicked",
569
self.on_button_install_clicked)
570
self.Glade.signal_connect("on_button_close_clicked",
571
lambda w: self.exit())
572
self.Glade.signal_connect("on_button_reload_clicked",
573
self.on_button_reload_clicked)
574
self.Glade.signal_connect("on_button_preferences_clicked",
575
self.on_button_preferences_clicked)
576
self.Glade.signal_connect("on_button_help_clicked",
577
self.on_button_help_clicked)
579
self.treeview = self.Glade.get_widget("updatelist")
581
self.store = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str, str, str, str,
582
gobject.TYPE_PYOBJECT)
583
self.treeview.set_model(self.store)
584
self.treeview.set_headers_clickable(True);
586
self.treeview.connect('cursor-changed', self.cursor_changed)
588
tr = gtk.CellRendererText()
589
tr.set_property("xpad", 10)
590
tr.set_property("ypad", 10)
591
cr = gtk.CellRendererToggle()
592
cr.set_property("activatable", True)
593
cr.set_property("xpad", 10)
594
cr.connect("toggled", self.toggled)
595
self.cb = gtk.TreeViewColumn("Install", cr, active=LIST_INSTALL)
596
c0 = gtk.TreeViewColumn("Name", tr, markup=LIST_CONTENTS)
597
c0.set_resizable(True)
598
major,minor,patch = gtk.pygtk_version
599
if (major >= 2) and (minor >= 5):
600
self.cb.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
601
self.cb.set_fixed_width(30)
602
c0.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
603
c0.set_fixed_width(100)
604
#self.treeview.set_fixed_height_mode(True)
606
self.treeview.append_column(self.cb)
607
self.cb.set_visible(False);
608
self.treeview.append_column(c0)
609
self.treeview.set_search_column(LIST_NAME)
610
#self.treeview.append_column(c1)
611
#self.treeview.append_column(c2)
612
#self.treeview.set_headers_visible(False)
613
# set expander to last position
616
SYNAPTIC_CONF_FILE = "%s/.synaptic/synaptic.conf" % pwd.getpwuid(0)[5]
617
if os.path.exists(SYNAPTIC_CONF_FILE):
618
cnf = apt_pkg.newConfiguration()
619
apt_pkg.ReadConfigFile(cnf, SYNAPTIC_CONF_FILE)
620
use_proxy = cnf.FindB("Synaptic::useProxy", False)
622
proxy_host = cnf.Find("Synaptic::httpProxy")
623
proxy_port = str(cnf.FindI("Synaptic::httpProxyPort"))
624
if proxy_host and proxy_port:
625
proxy_support = urllib2.ProxyHandler({"http":"http://%s:%s" % (proxy_host, proxy_port)})
626
opener = urllib2.build_opener(proxy_support)
627
urllib2.install_opener(opener)
629
self.gconfclient = gconf.client_get_default()
634
if self.download_changes_at_startup:
635
dialog = self.Glade.get_widget("dialog_fetching")
636
dialog.set_transient_for(self.main_window)
637
dialog.set_modal(True)
638
progress = self.Glade.get_widget("progressbar_fetching")
640
while gtk.events_pending():
646
self.all_changes = {}
649
self.list = UpdateList(self.main_window)
652
self.list.update(self.cache, self.records, self.depcache)
653
if self.list.num_updates < 1:
654
# set the label and treeview and hide the checkbox column
655
self.cb.set_visible(False)
657
label = self.Glade.get_widget("label_header")
658
text = "<big><b>%s</b></big>\n\n%s" % (_("Your system is up-to-date!"),
659
_("There are no updates available."))
660
label.set_markup(text)
661
self.store.append([False, _("Your system is up-to-date!"), None, None, None, None, None])
662
# make sure no install is possible
663
self.installbutton.set_sensitive(False)
665
self.cb.set_visible(True)
667
self.treeview.set_headers_visible(False)
668
label = self.Glade.get_widget("label_header")
669
text = _("<big><b>Available Updates</b></big>\n"
671
"The following packages are found to be upgradable. You can upgrade them by "
672
"using the Install button.")
673
label.set_markup(text)
675
for pkg in self.list.pkgs:
676
if self.download_changes_at_startup:
677
progress.set_fraction(float(i)/len(self.list.pkgs))
678
while gtk.events_pending():
680
lock = thread.allocate_lock()
681
self.all_changes[pkg.name] = self.get_changelog(pkg.name,lock)
683
name = xml.sax.saxutils.escape(pkg.name)
684
summary = xml.sax.saxutils.escape(pkg.shortdesc)
685
contents = "<big><b>%s</b></big>\n<small>%s\n\n" % (name, summary)
686
contents = contents + _("New version: %s") % (pkg.version) + "</small>"
688
iter = self.store.append([True, contents, pkg.name, pkg.shortdesc, pkg.version, pkg.longdesc, pkg])
692
if self.download_changes_at_startup:
698
# FIXME: use lsb-release binary and cache the result
700
f = open("/etc/lsb-release", "r")
701
lines = f.readlines()
703
key, value = line.split("=")
704
if (key == "DISTRIB_CODENAME"):
708
def current_dist_not_supported(self, name):
710
msg = "<big><b>%s</b></big>\n\n%s" % (_("Your distribution is no longer supported"), _("Please upgrade to a newer version of Ubuntu Linux. The version you are running will no longer get security fixes or other critical updates. Please see http://www.ubuntulinux.org for upgrade information."))
711
dialog = gtk.MessageDialog(self.main_window, 0, gtk.MESSAGE_WARNING,
713
dialog.set_markup(msg)
718
def new_dist_available(self, name):
720
# check if the user already knowns about this dist
721
seen = self.gconfclient.get_string("/apps/update-manager/seen_dist")
725
msg = "<big><b>%s</b></big>\n\n%s" % (_("There is a new release of Ubuntu available!"), _("A new release with the codename '%s' is available. Please see http://www.ubuntulinux.org/ for upgrade instructions.") % name)
726
dialog = gtk.MessageDialog(self.main_window, 0, gtk.MESSAGE_INFO,
727
gtk.BUTTONS_CLOSE, "")
728
dialog.set_markup(msg)
729
check = gtk.CheckButton(_("Never show this message again"))
731
dialog.vbox.pack_start(check)
733
if check.get_active():
734
self.gconfclient.set_string("/apps/update-manager/seen_dist",name)
737
# code that does the meta release file checking
738
def check_meta_release(self):
739
#print "check_meta_release"
740
current_dist = self.dist
742
if self.metarelease_information != None:
743
#print "meta_release found (current_dist: %s)" % (current_dist)
744
# we have a meta-release file
745
current_dist_date = 0
746
current_dist_supported = False
747
new_dist_available = False
749
index_tag = apt_pkg.ParseTagFile(self.metarelease_information)
750
step_result = index_tag.Step()
752
if index_tag.Section.has_key("Dist"):
753
dist = index_tag.Section["Dist"]
754
date = time.mktime(rfc822.parsedate(index_tag.Section["Date"]))
756
if dist == current_dist:
757
current_dist_supported = str_to_bool(index_tag.Section["Supported"])
758
current_dist_date = time.mktime(rfc822.parsedate(index_tag.Section["Date"]))
759
step_result = index_tag.Step()
760
# check for newer dists
764
if dist == current_dist:
766
if dists[dist] > current_dist_date and not dist == current_dist:
768
current_dist_date = dists[dist]
770
# we know nothing about the installed distro, so we just return
775
# only warn if unsupported and a new dist is available (because
776
# the development version is also unsupported)
777
if new_dist != "" and not current_dist_supported:
778
self.current_dist_not_supported(new_dist)
780
self.new_dist_available(new_dist)
781
# don't run this event again
783
# we have no information about the meta-release, so run it again
786
# the network thread that tries to fetch the meta-index file
787
def get_meta_release(self):
789
req = urllib2.Request(METARELEASE_URI)
790
if os.access(METARELEASE_FILE, os.W_OK):
791
lastmodified = os.stat(METARELEASE_FILE).st_mtime
793
req.add_header("If-Modified-Since", lastmodified)
795
uri=urllib2.urlopen(req)
796
f=open(METARELEASE_FILE,"w+")
797
for line in uri.readlines():
801
self.metarelease_information=f
803
except urllib2.URLError:
806
# fixme: we should probably abstract away all the stuff from libapt
810
apt_pkg.PkgSystemLock()
812
d = gtk.MessageDialog(parent=self.main_window,
813
flags=gtk.DIALOG_MODAL,
814
type=gtk.MESSAGE_ERROR,
815
buttons=gtk.BUTTONS_OK)
816
d.set_markup("<big><b>%s</b></big>\n\n%s" % (
817
_("Unable to get exclusive lock"),
818
_("This usually means that another package management "
819
"application (like apt-get or aptitude) already running. "
820
"Please close that application first")))
825
self.cache = apt_pkg.GetCache()
826
#apt_pkg.Config.Set("Debug::pkgPolicy","1")
827
self.depcache = apt_pkg.GetDepCache(self.cache)
828
self.depcache.ReadPinFile()
829
if os.path.exists(SYNAPTIC_PINFILE):
830
self.depcache.ReadPinFile(SYNAPTIC_PINFILE)
832
self.records = apt_pkg.GetPkgRecords(self.cache)
836
# FIXME: stat a check update thread
837
self.metarelease_information = None
838
t=thread.start_new_thread(self.get_meta_release, ())
839
gobject.timeout_add(1000, self.check_meta_release)
840
#self.get_meta_release()
842
self.store.append([True, _("Initializing and getting list of updates..."),
843
None, None, None, None, None])
845
while gtk.events_pending():
848
# global init of apt, FIXME: move all the apt details in it's own class
854
if __name__ == "__main__":
857
DIR="@prefix@/share/locale"
858
gettext.bindtextdomain(APP, DIR)
859
gettext.textdomain(APP)
860
gtk.glade.bindtextdomain(APP, DIR)
861
gtk.glade.textdomain(APP)
863
if os.geteuid() != 0:
864
dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
865
_("You need to be root to run this program"))
870
if (len(sys.argv) > 1) and (sys.argv[1].strip() == "--download-changes-at-startup"):
871
updatemanager = UpdateManager(True)
873
updatemanager = UpdateManager()