1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
# MetaRelease.py
#
# Copyright (c) 2004,2005 Canonical
#
# Author: Michael Vogt <michael.vogt@ubuntu.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
import pygtk
pygtk.require('2.0')
import gobject
import thread
import urllib2
import os
import string
import apt_pkg
import time
import rfc822
from subprocess import Popen,PIPE
class Dist(object):
def __init__(self, name, version, date, supported):
self.name = name
self.version = version
self.date = date
self.supported = supported
self.releaseNotesURI = None
self.upgradeTool = None
self.upgradeToolSig = None
class MetaRelease(gobject.GObject):
# some constants
METARELEASE_URI = "http://changelogs.ubuntu.com/meta-release"
METARELEASE_URI_UNSTABLE = "http://changelogs.ubuntu.com/meta-release-development"
METARELEASE_FILE = "/var/lib/update-manager/meta-release"
__gsignals__ = {
'new_dist_available' : (gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
(gobject.TYPE_PYOBJECT,)),
'dist_no_longer_supported' : (gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
())
}
def __init__(self, useDevelopmentRelase=False):
gobject.GObject.__init__(self)
if useDevelopmentRelase:
self.METARELEASE_URI = self.METARELEASE_URI_UNSTABLE
self.metarelease_information = None
self.downloading = True
# we start the download thread here and we have a timeout
# in the gtk space to test if the download already finished
# this is needed because gtk is not thread-safe
t=thread.start_new_thread(self.download, ())
gobject.timeout_add(1000,self.check)
def get_dist(self):
" return the codename of the current runing distro "
p = Popen(["/bin/lsb_release","-c","-s"],stdout=PIPE)
res = p.wait()
if res != 0:
sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
dist = string.strip(p.stdout.readline())
#dist = "breezy"
return dist
def check(self):
#print "check"
# check if we have a metarelease_information file
if self.metarelease_information != None:
self.parse()
# return False makes g_timeout() stop
return False
# no information yet, keep runing
return True
def parse(self):
#print "parse"
current_dist_name = self.get_dist()
current_dist = None
dists = []
# parse the metarelease_information file
index_tag = apt_pkg.ParseTagFile(self.metarelease_information)
step_result = index_tag.Step()
while step_result:
if index_tag.Section.has_key("Dist"):
name = index_tag.Section["Dist"]
#print name
rawdate = index_tag.Section["Date"]
date = time.mktime(rfc822.parsedate(rawdate))
supported = bool(index_tag.Section["Supported"])
version = index_tag.Section["Version"]
# add the information to a new date object
dist = Dist(name, version, date,supported)
if index_tag.Section.has_key("ReleaseNotes"):
dist.releaseNotesURI = index_tag.Section["ReleaseNotes"]
if index_tag.Section.has_key("UpgradeTool"):
dist.upgradeTool = index_tag.Section["UpgradeTool"]
if index_tag.Section.has_key("UpgradeToolSignature"):
dist.upgradeToolSig = index_tag.Section["UpgradeToolSignature"]
dists.append(dist)
if name == current_dist_name:
current_dist = dist
step_result = index_tag.Step()
# first check if the current runing distro is in the meta-release
# information. if not, we assume that we run on something not
# supported and silently return
if current_dist == None:
print "current dist not found in meta-release file"
return False
# then see what we can upgrade to (only upgrade to supported dists)
upgradable_to = ""
for dist in dists:
if dist.date > current_dist.date and dist.supported == True:
upgradable_to = dist
#print "new dist: %s" % upgradable_to
break
# only warn if unsupported and a new dist is available (because
# the development version is also unsupported)
if upgradable_to != "" and not current_dist.supported:
self.emit("dist_no_longer_supported",upgradabl_to)
elif upgradable_to != "":
self.emit("new_dist_available",upgradable_to)
# parsing done and sucessfully
return True
# the network thread that tries to fetch the meta-index file
# can't touch the gui, runs as a thread
def download(self):
#print "download"
lastmodified = 0
req = urllib2.Request(self.METARELEASE_URI)
if os.access(self.METARELEASE_FILE, os.W_OK):
lastmodified = os.stat(self.METARELEASE_FILE).st_mtime
if lastmodified > 0:
req.add_header("If-Modified-Since", lastmodified)
try:
uri=urllib2.urlopen(req)
f=open(self.METARELEASE_FILE,"w+")
for line in uri.readlines():
f.write(line)
f.flush()
f.seek(0,0)
self.metarelease_information=f
uri.close()
except urllib2.URLError:
if os.path.exists(self.METARELEASE_FILE):
f=open(self.METARELEASE_FILE,"r")
# register in the gobject system, needed for older versions of pygtk,
# never ones do this automatically
gobject.type_register(MetaRelease)
|