Back to index

enigmail  1.4.3
mozinfo.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 # ***** BEGIN LICENSE BLOCK *****
00004 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005 #
00006 # The contents of this file are subject to the Mozilla Public License Version
00007 # 1.1 (the "License"); you may not use this file except in compliance with
00008 # the License. You may obtain a copy of the License at
00009 # http://www.mozilla.org/MPL/
00010 #
00011 # Software distributed under the License is distributed on an "AS IS" basis,
00012 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013 # for the specific language governing rights and limitations under the
00014 # License.
00015 #
00016 # The Original Code is Mozilla Corporation Code.
00017 #
00018 # The Initial Developer of the Original Code is
00019 # Mikeal Rogers.
00020 # Portions created by the Initial Developer are Copyright (C) 2008
00021 # the Initial Developer. All Rights Reserved.
00022 #
00023 # Contributor(s):
00024 #  Mikeal Rogers <mikeal.rogers@gmail.com>
00025 #  Henrik Skupin <hskupin@mozilla.com>
00026 #  Clint Talbert <ctalbert@mozilla.com>
00027 #
00028 # Alternatively, the contents of this file may be used under the terms of
00029 # either the GNU General Public License Version 2 or later (the "GPL"), or
00030 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031 # in which case the provisions of the GPL or the LGPL are applicable instead
00032 # of those above. If you wish to allow use of your version of this file only
00033 # under the terms of either the GPL or the LGPL, and not to allow others to
00034 # use your version of this file under the terms of the MPL, indicate your
00035 # decision by deleting the provisions above and replace them with the notice
00036 # and other provisions required by the GPL or the LGPL. If you do not delete
00037 # the provisions above, a recipient may use your version of this file under
00038 # the terms of any one of the MPL, the GPL or the LGPL.
00039 #
00040 # ***** END LICENSE BLOCK *****
00041 
00042 """
00043 file for interface to transform introspected system information to a format
00044 pallatable to Mozilla
00045 
00046 Information:
00047 - os : what operating system ['win', 'mac', 'linux', ...]
00048 - bits : 32 or 64
00049 - processor : processor architecture ['x86', 'x86_64', 'ppc', ...]
00050 - version : operating system version string
00051 
00052 For windows, the service pack information is also included
00053 """
00054 
00055 # TODO: it might be a good idea of adding a system name (e.g. 'Ubuntu' for
00056 # linux) to the information; I certainly wouldn't want anyone parsing this
00057 # information and having behaviour depend on it
00058 
00059 import os
00060 import platform
00061 import re
00062 import sys
00063 
00064 # keep a copy of the os module since updating globals overrides this
00065 _os = os
00066 
00067 class unknown(object):
00068     """marker class for unknown information"""
00069     def __nonzero__(self):
00070         return False
00071     def __str__(self):
00072         return 'UNKNOWN'
00073 unknown = unknown() # singleton
00074 
00075 # get system information
00076 info = {'os': unknown,
00077         'processor': unknown,
00078         'version': unknown,
00079         'bits': unknown }
00080 (system, node, release, version, machine, processor) = platform.uname()
00081 (bits, linkage) = platform.architecture()
00082 
00083 # get os information and related data
00084 if system in ["Microsoft", "Windows"]:
00085     info['os'] = 'win'    
00086     # There is a Python bug on Windows to determine platform values
00087     # http://bugs.python.org/issue7860
00088     if "PROCESSOR_ARCHITEW6432" in os.environ:
00089         processor = os.environ.get("PROCESSOR_ARCHITEW6432", processor)
00090     else:
00091         processor = os.environ.get('PROCESSOR_ARCHITECTURE', processor)
00092         system = os.environ.get("OS", system).replace('_', ' ')
00093         service_pack = os.sys.getwindowsversion()[4]
00094         info['service_pack'] = service_pack
00095 elif system == "Linux":
00096     (distro, version, codename) = platform.dist()
00097     version = distro + " " + version
00098     if not processor:
00099         processor = machine
00100     info['os'] = 'linux'
00101 elif system == "Darwin":
00102     (release, versioninfo, machine) = platform.mac_ver()
00103     version = "OS X " + release
00104     info['os'] = 'mac'
00105 elif sys.platform in ('solaris', 'sunos5'):
00106     info['os'] = 'unix'
00107     version = sys.platform
00108 info['version'] = version # os version
00109 
00110 # processor type and bits
00111 if processor in ["i386", "i686"]:
00112     if bits == "32bit":
00113         processor = "x86"
00114     elif bits == "64bit":
00115         processor = "x86_64"
00116 elif processor == "AMD64":
00117     bits = "64bit"
00118     processor = "x86_64"
00119 elif processor == "Power Macintosh":
00120     processor = "ppc"
00121 bits = re.search('(\d+)bit', bits).group(1)
00122 info.update({'processor': processor,
00123              'bits': int(bits),
00124             })
00125 
00126 # standard value of choices, for easy inspection
00127 choices = {'os': ['linux', 'win', 'mac', 'unix'],
00128            'bits': [32, 64],
00129            'processor': ['x86', 'x86_64', 'ppc']}
00130 
00131 
00132 def sanitize(info):
00133     """Do some sanitization of input values, primarily
00134     to handle universal Mac builds."""
00135     if "processor" in info and info["processor"] == "universal-x86-x86_64":
00136         # If we're running on OS X 10.6 or newer, assume 64-bit
00137         if release[:4] >= "10.6":
00138             info["processor"] = "x86_64"
00139             info["bits"] = 64
00140         else:
00141             info["processor"] = "x86"
00142             info["bits"] = 32
00143 
00144 # method for updating information
00145 def update(new_info):
00146     """update the info"""
00147     info.update(new_info)
00148     sanitize(info)
00149     globals().update(info)
00150 
00151     # convenience data for os access
00152     for os_name in choices['os']:
00153         globals()['is' + os_name.title()] = info['os'] == os_name
00154     # unix is special
00155     if isLinux:
00156         globals()['isUnix'] = True
00157 
00158 update({})
00159 
00160 # exports
00161 __all__ = info.keys()
00162 __all__ += ['is' + os_name.title() for os_name in choices['os']]
00163 __all__ += ['info', 'unknown', 'main', 'choices', 'update']
00164 
00165 
00166 def main(args=None):
00167 
00168     # parse the command line
00169     from optparse import OptionParser
00170     parser = OptionParser()
00171     for key in choices:
00172         parser.add_option('--%s' % key, dest=key,
00173                           action='store_true', default=False,
00174                           help="display choices for %s" % key)
00175     options, args = parser.parse_args()
00176 
00177     # args are JSON blobs to override info
00178     if args:
00179         try:
00180             from json import loads
00181         except ImportError:
00182             try:
00183                 from simplejson import loads
00184             except ImportError:
00185                 def loads(string):
00186                     """*really* simple json; will not work with unicode"""
00187                     return eval(string, {'true': True, 'false': False, 'null': None})
00188         for arg in args:
00189             if _os.path.exists(arg):
00190                 string = file(arg).read()
00191             else:
00192                 string = arg
00193             update(loads(string))
00194 
00195     # print out choices if requested
00196     flag = False
00197     for key, value in options.__dict__.items():
00198         if value is True:
00199             print '%s choices: %s' % (key, ' '.join([str(choice)
00200                                                      for choice in choices[key]]))
00201             flag = True
00202     if flag: return
00203 
00204     # otherwise, print out all info
00205     for key, value in info.items():
00206         print '%s: %s' % (key, value)
00207 
00208 if __name__ == '__main__':
00209     main()