~ubuntu-branches/ubuntu/lucid/update-manager/lucid

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