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)
|