|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
1 |
# utils.py
|
2 |
#
|
|
3 |
# Copyright (c) 2004-2008 Canonical
|
|
4 |
#
|
|
5 |
# Author: Michael Vogt <mvo@debian.org>
|
|
6 |
#
|
|
7 |
# This program is free software; you can redistribute it and/or
|
|
8 |
# modify it under the terms of the GNU General Public License as
|
|
9 |
# published by the Free Software Foundation; either version 2 of the
|
|
10 |
# License, or (at your option) any later version.
|
|
11 |
#
|
|
12 |
# This program is distributed in the hope that it will be useful,
|
|
13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 |
# GNU General Public License for more details.
|
|
16 |
#
|
|
17 |
# You should have received a copy of the GNU General Public License
|
|
18 |
# along with this program; if not, write to the Free Software
|
|
19 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
20 |
# USA
|
|
21 |
||
22 |
from gettext import gettext as _ |
|
|
249
by Michael Vogt
* UpdateManager/UpdateManager.py: |
23 |
from stat import * |
24 |
||
25 |
import apt_pkg |
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
26 |
import locale |
|
267
by Michael Vogt
* UpdateManager/GtkProgress.py: |
27 |
import logging |
|
249
by Michael Vogt
* UpdateManager/UpdateManager.py: |
28 |
import re |
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
29 |
import os |
|
218
by Michael Vogt
* The 'Ready for karmic' version |
30 |
import os.path |
|
249
by Michael Vogt
* UpdateManager/UpdateManager.py: |
31 |
import subprocess |
32 |
import sys |
|
|
265
by Michael Vogt
* DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeCache.py: |
33 |
import time |
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
34 |
import urllib2 |
|
218
by Michael Vogt
* The 'Ready for karmic' version |
35 |
|
|
265
by Michael Vogt
* DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeCache.py: |
36 |
class ExecutionTime(object): |
37 |
"""
|
|
38 |
Helper that can be used in with statements to have a simple
|
|
39 |
measure of the timming of a particular block of code, e.g.
|
|
40 |
with ExecutinTime("db flush"):
|
|
41 |
db.flush()
|
|
42 |
"""
|
|
43 |
def __init__(self, info=""): |
|
44 |
self.info = info |
|
45 |
def __enter__(self): |
|
46 |
self.now = time.time() |
|
47 |
def __exit__(self, type, value, stack): |
|
48 |
print "%s: %s" % (self.info, time.time() - self.now) |
|
49 |
||
|
253
by Michael Vogt
* update-manager-support-status: |
50 |
# helpers inspired after textwrap - unfortunately
|
51 |
# we can not use textwrap directly because it break
|
|
52 |
# packagenames with "-" in them into new lines
|
|
53 |
def wrap(t, width=70, subsequent_indent=""): |
|
54 |
out = "" |
|
55 |
for s in t.split(): |
|
56 |
if (len(out)-out.rfind("\n")) + len(s) > width: |
|
57 |
out += "\n" + subsequent_indent |
|
58 |
out += s + " " |
|
59 |
return out |
|
60 |
||
61 |
def twrap(s, **kwargs): |
|
62 |
msg = "" |
|
63 |
paras = s.split("\n") |
|
64 |
for par in paras: |
|
65 |
s = wrap(par, **kwargs) |
|
66 |
msg += s+"\n" |
|
67 |
return msg |
|
68 |
||
|
220
by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py: |
69 |
def lsmod(): |
|
233
by Michael Vogt
* DistUpgrade/removal_blacklist.cfg: |
70 |
" return list of loaded modules (or [] if lsmod is not found) "
|
|
220
by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py: |
71 |
modules=[] |
|
233
by Michael Vogt
* DistUpgrade/removal_blacklist.cfg: |
72 |
# FIXME raise?
|
73 |
if not os.path.exists("/sbin/lsmod"): |
|
74 |
return [] |
|
|
220
by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py: |
75 |
p=subprocess.Popen(["/sbin/lsmod"], stdout=subprocess.PIPE) |
76 |
lines=p.communicate()[0].split("\n") |
|
77 |
# remove heading line: "Modules Size Used by"
|
|
78 |
del lines[0] |
|
79 |
# add lines to list, skip empty lines
|
|
80 |
for line in lines: |
|
81 |
if line: |
|
82 |
modules.append(line.split()[0]) |
|
83 |
return modules |
|
84 |
||
85 |
||
|
218
by Michael Vogt
* The 'Ready for karmic' version |
86 |
def check_and_fix_xbit(path): |
87 |
" check if a given binary has the executable bit and if not, add it"
|
|
88 |
if not os.path.exists(path): |
|
89 |
return
|
|
90 |
mode = S_IMODE(os.stat(path)[ST_MODE]) |
|
91 |
if not ((mode & S_IXUSR) == S_IXUSR): |
|
92 |
os.chmod(path, mode | S_IXUSR) |
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
93 |
|
94 |
def country_mirror(): |
|
95 |
" helper to get the country mirror from the current locale "
|
|
96 |
# special cases go here
|
|
97 |
lang_mirror = { 'c' : '', |
|
98 |
}
|
|
99 |
# no lang, no mirror
|
|
100 |
if not os.environ.has_key('LANG'): |
|
101 |
return '' |
|
102 |
lang = os.environ['LANG'].lower() |
|
103 |
# check if it is a special case
|
|
104 |
if lang_mirror.has_key(lang[:5]): |
|
105 |
return lang_mirror[lang[:5]] |
|
106 |
# now check for the most comon form (en_US.UTF-8)
|
|
107 |
if "_" in lang: |
|
108 |
country = lang.split(".")[0].split("_")[1] |
|
109 |
if "@" in country: |
|
110 |
country = country.split("@")[0] |
|
111 |
return country+"." |
|
112 |
else: |
|
113 |
return lang[:2]+"." |
|
114 |
return '' |
|
115 |
||
116 |
def get_dist(): |
|
117 |
" return the codename of the current runing distro "
|
|
|
267
by Michael Vogt
* UpdateManager/GtkProgress.py: |
118 |
# support debug overwrite
|
119 |
dist = os.environ.get("META_RELEASE_FAKE_CODENAME") |
|
120 |
if dist: |
|
121 |
logging.warn("using fake release name '%s' (because of META_RELEASE_FAKE_CODENAME environment) " % dist) |
|
122 |
return dist |
|
123 |
# then check the real one
|
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
124 |
from subprocess import Popen, PIPE |
125 |
p = Popen(["lsb_release","-c","-s"],stdout=PIPE) |
|
126 |
res = p.wait() |
|
127 |
if res != 0: |
|
128 |
sys.stderr.write("lsb_release returned exitcode: %i\n" % res) |
|
129 |
return "unknown distribution" |
|
130 |
dist = p.stdout.readline().strip() |
|
131 |
return dist |
|
132 |
||
133 |
def url_downloadable(uri, debug_func=None): |
|
134 |
"""
|
|
135 |
helper that checks if the given uri exists and is downloadable
|
|
136 |
(supports optional debug_func function handler to support
|
|
137 |
e.g. logging)
|
|
138 |
||
139 |
Supports http (via HEAD) and ftp (via size request)
|
|
140 |
"""
|
|
141 |
if debug_func: |
|
142 |
debug_func("url_downloadable: %s" % uri) |
|
143 |
import urlparse |
|
144 |
(scheme, netloc, path, querry, fragment) = urlparse.urlsplit(uri) |
|
145 |
if scheme == "http": |
|
146 |
import httplib |
|
|
248
by Michael Vogt
* UpdateManager/UpdateManager.py: |
147 |
proxy = os.getenv("http_proxy") |
148 |
if (proxy): |
|
149 |
path = scheme + netloc + path |
|
150 |
netloc = proxy |
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
151 |
try: |
152 |
c = httplib.HTTPConnection(netloc) |
|
153 |
c.request("HEAD", path) |
|
154 |
res = c.getresponse() |
|
155 |
if debug_func: |
|
156 |
debug_func("url_downloadable result '%s'" % res.status) |
|
157 |
res.close() |
|
|
199
by Michael Vogt, Michael Vogt, Jonathan Riddell, Andy Whitcroft
[ Michael Vogt ] |
158 |
if res.status == 200: |
159 |
return True |
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
160 |
except Exception, e: |
161 |
debug_func("error from httplib: '%s'" % e) |
|
162 |
return False |
|
163 |
elif scheme == "ftp": |
|
164 |
import ftplib |
|
165 |
try: |
|
166 |
f = ftplib.FTP(netloc) |
|
167 |
f.login() |
|
168 |
f.cwd(os.path.dirname(path)) |
|
169 |
size = f.size(os.path.basename(path)) |
|
170 |
f.quit() |
|
171 |
if debug_func: |
|
172 |
debug_func("ftplib.size() returned: %s" % size) |
|
173 |
if size != 0: |
|
174 |
return True |
|
175 |
except Exception, e: |
|
176 |
if debug_func: |
|
177 |
debug_func("error from ftplib: '%s'" % e) |
|
178 |
return False |
|
|
199
by Michael Vogt, Michael Vogt, Jonathan Riddell, Andy Whitcroft
[ Michael Vogt ] |
179 |
return False |
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
180 |
|
181 |
def init_proxy(gconfclient=None): |
|
182 |
""" init proxy settings
|
|
183 |
||
184 |
* first check for http_proxy environment (always wins),
|
|
185 |
* then check the apt.conf http proxy,
|
|
186 |
* then look into synaptics conffile
|
|
187 |
* then into gconf (if gconfclient was supplied)
|
|
188 |
"""
|
|
189 |
SYNAPTIC_CONF_FILE = "/root/.synaptic/synaptic.conf" |
|
190 |
proxy = None |
|
191 |
# generic apt config wins
|
|
192 |
apt_pkg.InitConfig() |
|
193 |
if apt_pkg.Config.Find("Acquire::http::Proxy") != '': |
|
194 |
proxy = apt_pkg.Config.Find("Acquire::http::Proxy") |
|
195 |
# then synaptic
|
|
196 |
elif os.path.exists(SYNAPTIC_CONF_FILE): |
|
197 |
cnf = apt_pkg.newConfiguration() |
|
198 |
apt_pkg.ReadConfigFile(cnf, SYNAPTIC_CONF_FILE) |
|
199 |
use_proxy = cnf.FindB("Synaptic::useProxy", False) |
|
200 |
if use_proxy: |
|
201 |
proxy_host = cnf.Find("Synaptic::httpProxy") |
|
202 |
proxy_port = str(cnf.FindI("Synaptic::httpProxyPort")) |
|
203 |
if proxy_host and proxy_port: |
|
204 |
proxy = "http://%s:%s/" % (proxy_host, proxy_port) |
|
205 |
# then gconf
|
|
206 |
elif gconfclient: |
|
207 |
try: # see LP: #281248 |
|
208 |
if gconfclient.get_bool("/system/http_proxy/use_http_proxy"): |
|
209 |
host = gconfclient.get_string("/system/http_proxy/host") |
|
210 |
port = gconfclient.get_int("/system/http_proxy/port") |
|
211 |
use_auth = gconfclient.get_bool("/system/http_proxy/use_authentication") |
|
212 |
if host and port: |
|
213 |
if use_auth: |
|
214 |
auth_user = gconfclient.get_string("/system/http_proxy/authentication_user") |
|
215 |
auth_pw = gconfclient.get_string("/system/http_proxy/authentication_password") |
|
216 |
proxy = "http://%s:%s@%s:%s/" % (auth_user,auth_pw,host, port) |
|
217 |
else: |
|
218 |
proxy = "http://%s:%s/" % (host, port) |
|
219 |
except Exception, e: |
|
220 |
print "error from gconf: %s" % e |
|
221 |
# if we have a proxy, set it
|
|
222 |
if proxy: |
|
223 |
# basic verification
|
|
|
249
by Michael Vogt
* UpdateManager/UpdateManager.py: |
224 |
if not re.match("http://\w+", proxy): |
225 |
print >> sys.stderr, "proxy '%s' looks invalid" % proxy |
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
226 |
return
|
227 |
proxy_support = urllib2.ProxyHandler({"http":proxy}) |
|
228 |
opener = urllib2.build_opener(proxy_support) |
|
229 |
urllib2.install_opener(opener) |
|
230 |
os.putenv("http_proxy",proxy) |
|
231 |
||
|
222
by Michael Vogt
* AutoUpgradeTester: |
232 |
def on_battery(): |
233 |
"""
|
|
|
261
by Michael Vogt, Markus Korn, Michael Vogt
[ Markus Korn ] |
234 |
Check via dbus if the system is running on battery.
|
235 |
This function is using UPower per default, if UPower is not
|
|
236 |
available it falls-back to DeviceKit.Power.
|
|
|
222
by Michael Vogt
* AutoUpgradeTester: |
237 |
"""
|
238 |
try: |
|
239 |
import dbus |
|
240 |
bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) |
|
|
261
by Michael Vogt, Markus Korn, Michael Vogt
[ Markus Korn ] |
241 |
try: |
242 |
devobj = bus.get_object('org.freedesktop.UPower', |
|
243 |
'/org/freedesktop/UPower') |
|
244 |
dev = dbus.Interface(devobj, 'org.freedesktop.DBus.Properties') |
|
245 |
return dev.Get('org.freedesktop.UPower', 'OnBattery') |
|
246 |
except dbus.exceptions.DBusException, e: |
|
247 |
if e._dbus_error_name != 'org.freedesktop.DBus.Error.ServiceUnknown': |
|
248 |
raise
|
|
249 |
devobj = bus.get_object('org.freedesktop.DeviceKit.Power', |
|
250 |
'/org/freedesktop/DeviceKit/Power') |
|
251 |
dev = dbus.Interface(devobj, "org.freedesktop.DBus.Properties") |
|
252 |
return dev.Get("org.freedesktop.DeviceKit.Power", "on_battery") |
|
|
222
by Michael Vogt
* AutoUpgradeTester: |
253 |
except Exception, e: |
|
246
by Michael Vogt
* DistUpgrade/DistUpgradeQuirks.py: |
254 |
#import sys
|
255 |
#print >>sys.stderr, "on_battery returned error: ", e
|
|
|
230
by Michael Vogt
* make the release-upgrader auto selection for the frontend |
256 |
return False |
|
222
by Michael Vogt
* AutoUpgradeTester: |
257 |
|
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
258 |
def _inhibit_sleep_old_interface(): |
259 |
"""
|
|
260 |
Send a dbus signal to org.gnome.PowerManager to not suspend
|
|
261 |
the system, this is to support upgrades from pre-gutsy g-p-m
|
|
262 |
"""
|
|
263 |
import dbus |
|
264 |
bus = dbus.Bus(dbus.Bus.TYPE_SESSION) |
|
265 |
devobj = bus.get_object('org.gnome.PowerManager', |
|
266 |
'/org/gnome/PowerManager') |
|
267 |
dev = dbus.Interface(devobj, "org.gnome.PowerManager") |
|
268 |
cookie = dev.Inhibit('UpdateManager', 'Updating system') |
|
269 |
return (dev, cookie) |
|
270 |
||
271 |
def _inhibit_sleep_new_interface(): |
|
272 |
"""
|
|
273 |
Send a dbus signal to gnome-power-manager to not suspend
|
|
274 |
the system
|
|
275 |
"""
|
|
276 |
import dbus |
|
277 |
bus = dbus.Bus(dbus.Bus.TYPE_SESSION) |
|
278 |
devobj = bus.get_object('org.freedesktop.PowerManagement', |
|
279 |
'/org/freedesktop/PowerManagement/Inhibit') |
|
280 |
dev = dbus.Interface(devobj, "org.freedesktop.PowerManagement.Inhibit") |
|
281 |
cookie = dev.Inhibit('UpdateManager', 'Updating system') |
|
282 |
return (dev, cookie) |
|
283 |
||
284 |
def inhibit_sleep(): |
|
285 |
"""
|
|
286 |
Send a dbus signal to power-manager to not suspend
|
|
287 |
the system, try both the new freedesktop and the
|
|
288 |
old gnome dbus interface
|
|
289 |
"""
|
|
290 |
try: |
|
291 |
return _inhibit_sleep_old_interface() |
|
292 |
except Exception, e: |
|
293 |
try: |
|
294 |
return _inhibit_sleep_new_interface() |
|
295 |
except Exception, e: |
|
296 |
#print "could not send the dbus Inhibit signal: %s" % e
|
|
297 |
return (False, False) |
|
298 |
||
299 |
def allow_sleep(dev, cookie): |
|
300 |
"""Send a dbus signal to gnome-power-manager to allow a suspending
|
|
301 |
the system"""
|
|
302 |
try: |
|
303 |
dev.UnInhibit(cookie) |
|
304 |
except Exception, e: |
|
305 |
print "could not send the dbus UnInhibit signal: %s" % e |
|
306 |
||
307 |
||
308 |
def str_to_bool(str): |
|
309 |
if str == "0" or str.upper() == "FALSE": |
|
310 |
return False |
|
311 |
return True |
|
312 |
||
313 |
def utf8(str): |
|
314 |
return unicode(str, 'latin1').encode('utf-8') |
|
315 |
||
|
268
by Michael Vogt, Barry Warsaw, Michael Vogt
[ Barry Warsaw ] |
316 |
def get_lang(): |
317 |
import logging |
|
318 |
try: |
|
319 |
(locale_s, encoding) = locale.getdefaultlocale() |
|
320 |
return locale_s |
|
321 |
except Exception, e: |
|
322 |
logging.exception("gedefaultlocale() failed") |
|
323 |
return None |
|
324 |
||
|
198
by Michael Vogt
* UpdateManager/Core/MetaRelease.py: |
325 |
def error(parent, summary, message): |
326 |
import gtk |
|
327 |
d = gtk.MessageDialog(parent=parent, |
|
328 |
flags=gtk.DIALOG_MODAL, |
|
329 |
type=gtk.MESSAGE_ERROR, |
|
330 |
buttons=gtk.BUTTONS_CLOSE) |
|
331 |
d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, message)) |
|
332 |
d.realize() |
|
333 |
d.window.set_functions(gtk.gdk.FUNC_MOVE) |
|
334 |
d.set_title("") |
|
335 |
res = d.run() |
|
336 |
d.destroy() |
|
337 |
return False |
|
338 |
||
339 |
def humanize_size(bytes): |
|
340 |
"""
|
|
341 |
Convert a given size in bytes to a nicer better readable unit
|
|
342 |
"""
|
|
343 |
if bytes == 0: |
|
344 |
# TRANSLATORS: download size is 0
|
|
345 |
return _("0 KB") |
|
346 |
elif bytes < 1024: |
|
347 |
# TRANSLATORS: download size of very small updates
|
|
348 |
return _("1 KB") |
|
349 |
elif bytes < 1024 * 1024: |
|
350 |
# TRANSLATORS: download size of small updates, e.g. "250 KB"
|
|
351 |
return locale.format(_("%.0f KB"), bytes/1024) |
|
352 |
else: |
|
353 |
# TRANSLATORS: download size of updates, e.g. "2.3 MB"
|
|
354 |
return locale.format(_("%.1f MB"), bytes / 1024 / 1024) |
|
355 |
||
356 |
if __name__ == "__main__": |
|
|
222
by Michael Vogt
* AutoUpgradeTester: |
357 |
#print mirror_from_sources_list()
|
358 |
print on_battery() |