00001 #! /usr/bin/env python -m 00002 # -*- coding: utf-8 -*- 00003 # _____ 00004 # / _ \ 00005 # / _/ \ \ 00006 # / / \_/ \ 00007 # / \_/ _ \ ___ _ ___ ___ ____ ____ ___ _____ _ _ 00008 # \ / \_/ \ / / _\| | | __| / _ \ | ┌┐ \ | ┌┐ \ / _ \ |_ _|| | | | 00009 # \ \_/ \_/ / | | | | | └─┐| |_| || └┘ / | └┘_/| |_| | | | | └─┘ | 00010 # \ \_/ / | |_ | |_ | ┌─┘| _ || |\ \ | | | _ | | | | ┌─┐ | 00011 # \_____/ \___/|___||___||_| |_||_| \_\|_| |_| |_| |_| |_| |_| 00012 # ROBOTICS™ 00013 # 00014 # File: clearpath/__main__.py 00015 # Desc: Clearpath Robotics Installed Python Modules Listing. 00016 # Auth: Malcolm Robert 00017 # 00018 # Copyright © 2010 Clearpath Robotics, Inc. 00019 # All Rights Reserved 00020 # 00021 # Redistribution and use in source and binary forms, with or without 00022 # modification, are permitted provided that the following conditions are met: 00023 # * Redistributions of source code must retain the above copyright 00024 # notice, this list of conditions and the following disclaimer. 00025 # * Redistributions in binary form must reproduce the above copyright 00026 # notice, this list of conditions and the following disclaimer in the 00027 # documentation and/or other materials provided with the distribution. 00028 # * Neither the name of Clearpath Robotics, Inc. nor the 00029 # names of its contributors may be used to endorse or promote products 00030 # derived from this software without specific prior written permission. 00031 # 00032 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00033 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00034 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00035 # ARE DISCLAIMED. IN NO EVENT SHALL CLEARPATH ROBOTICS, INC. BE LIABLE FOR ANY 00036 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00037 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00038 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00039 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00040 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00041 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00042 # 00043 # Please send comments, questions, or patches to code@clearpathrobotics.com 00044 # 00045 00046 00047 00048 00049 ################################################################################ 00050 # Module 00051 00052 00053 00054 ## @package clearpath.__main__ 00055 # Clearpath Robotics Modules Listing 00056 # 00057 # Python Script for listing installed Clearpath python modules. 00058 # 00059 # @author Malcolm Robert 00060 # @date 24/03/10 00061 # @version 1.0 00062 # 00063 # @section USE 00064 # 00065 # This module, the main script for the clearpath package, provides the user 00066 # with a list of installed Clearpath Robotics, Inc. modules, their versions, 00067 # and whether the module can run as a script (x) or just a module (m). 00068 # Because this script imports modules as it searches, only modules compatible 00069 # with the version of Python you are running will be listed. 00070 # 00071 # This script is executed by running 00072 # 'python -m clearpath' for Python 2.7+ and Python 3.1+ or 00073 # 'python -m clearpath.__main__' for Python 2.6- and Python 3.0. 00074 # 00075 # @section HISTORY 00076 # 00077 # Version 1.0 00078 # - Initial Creation 00079 # - Python 2.5+ & 3.x compatible 00080 # 00081 # @section License 00082 # @copydoc public_license 00083 # 00084 """Python Script for listing installed Clearpath python modules. 00085 00086 Copyright © 2010 Clearpath Robotics, Inc. 00087 All rights reserved 00088 00089 Created: 24/03/10 00090 Author: Malcolm Robert 00091 Version: 1.0 00092 """ 00093 00094 00095 # A note on comments: 00096 # To take advantage of the superior Doxygen documentation generator, 00097 # Doxygen comments (first line ##, following lines #) are used. 00098 # It is still important to provide Python __doc__ strings for use with help() 00099 # and pydoc, however, they (except for module) are also grabbed by Doxygen. 00100 # To fix this, the custom Doxygen tag @pydoc has been added to separate 00101 # __doc__ strings from being included in the last Doxygen tag. 00102 # @pydoc must be the last Doxygen tag before """doc string""" 00103 # Additionally, the custom Doxygen tag @req has been added to specify 00104 # required modules that do not come with the standard Python distribution. 00105 # Both custom tags are aliases to @par. 00106 00107 00108 # Required Python Modules 00109 import os.path # File Path Manipulation 00110 import pkgutil # Python Package Utilities 00111 import sys # Python Interpreter Functionality 00112 00113 00114 # Module Support 00115 ## Module Version 00116 __version__ = "1.0" 00117 """Module Version""" 00118 ## SVN Code Revision 00119 __revision__ = "$Revision: 634 $" 00120 """ SVN Code Revision""" 00121 00122 00123 00124 00125 ################################################################################ 00126 # Module Listing 00127 00128 00129 00130 ## List Installed Modules 00131 # 00132 # Lists installed modules within the given package. 00133 # List format is similar to the Unix program tree. 00134 # 00135 # @param package The name of the package to list 00136 # @param prefix The string to put at the start of each line 00137 # @param pos The location of the package: 0 - head, 1 - middle, 2 - tail 00138 # @return list of tuple(line,version,is_script) in the display order 00139 # 00140 # @pydoc 00141 def list_modules(package, prefix = '', pos = 0): 00142 """List Installed Modules.""" 00143 mods = [] 00144 00145 # import the package for traversal 00146 try: 00147 __import__(package) 00148 pkg = sys.modules[package] 00149 00150 # print package name 00151 pre = ''; 00152 if pos >= 2: 00153 mods.append(tuple([prefix + "`-- " + pkg.__name__.split('.')[-1], 00154 "%s r%s" % (pkg.__version__, 00155 pkg.__revision__[10:-1].strip()), 00156 hasattr(pkg,'__main')])) 00157 pre = prefix + " " 00158 elif pos == 1: 00159 mods.append(tuple([prefix + "|-- " + pkg.__name__.split('.')[-1], 00160 "%s r%s" % (pkg.__version__, 00161 pkg.__revision__[10:-1].strip()), 00162 hasattr(pkg,'__main')])) 00163 pre = prefix + "| " 00164 else: 00165 mods.append(tuple([prefix + pkg.__name__.split('.')[-1], 00166 "%s r%s" % (pkg.__version__, 00167 pkg.__revision__[10:-1].strip()), 00168 hasattr(pkg,'__main')])) 00169 pre = prefix 00170 00171 # grab sub-packages & modules and sort them by name 00172 def mod_key(mod): 00173 return mod[0] 00174 children = [tuple([name, ispkg]) for _, name, ispkg in \ 00175 pkgutil.iter_modules([os.path.dirname(pkg.__file__)])] 00176 children.sort(key=mod_key) 00177 00178 # traverse children 00179 for i in range(0,len(children)): 00180 00181 # module -> import & print 00182 if children[i][1] == False: 00183 try: 00184 __import__(package + "." + children[i][0]) 00185 chi = sys.modules[package + "." + children[i][0]] 00186 if i >= len(children) - 1: 00187 mods.append(tuple([pre + "`-- " + children[i][0], 00188 "%s r%s" % (chi.__version__, 00189 chi.__revision__[10:-1].strip()), 00190 hasattr(chi,'__main')])) 00191 else: 00192 mods.append(tuple([pre + "|-- " + children[i][0], 00193 "%s r%s" % (chi.__version__, 00194 chi.__revision__[10:-1].strip()), 00195 hasattr(chi,'__main')])) 00196 except: 00197 pass 00198 00199 # package -> recursion 00200 else: 00201 if i >= len(children) - 1: 00202 mods += list_modules(package + "." + children[i][0], pre, 2) 00203 else: 00204 mods += list_modules(package + "." + children[i][0], pre, 1) 00205 00206 # package must be import-able to be displayed 00207 except: 00208 pass 00209 return mods 00210 00211 00212 00213 ## List Installed Modules 00214 # 00215 # Main Program for Clearpath Robotics, Inc. package 00216 # - Gets a tree list of installed clearpath modules and their versions 00217 # - Prints the list to stdout 00218 # 00219 # @pydoc 00220 def __main(): 00221 """List Installed Modules.""" 00222 00223 # Get the tree list 00224 modules = list_modules('clearpath', '', 0) 00225 00226 # Calculate padding requirements for pretty printing 00227 def mod_key(mod): 00228 return mod[0] 00229 width = max(list(map(len,list(map(mod_key,modules))))) + 1 00230 def mod_key1(mod): 00231 return mod[1] 00232 length = max(list(map(len,list(map(mod_key1,modules))))) 00233 00234 # Print the tree list 00235 for mod in modules: 00236 if mod[2] == True: 00237 print((mod[0] + ' ' + '.'*(width-len(mod[0])) + ' [' + mod[1] + 00238 '.'*(length-len(mod[1])) + '] x')) 00239 else: 00240 print((mod[0] + ' ' + '.'*(width-len(mod[0])) + ' [' + mod[1] + 00241 ' '*(length-len(mod[1])) + '] m')) 00242 00243 # Exit the program 00244 sys.exit(0); 00245 00246 00247 00248 00249 ################################################################################ 00250 # Script 00251 00252 00253 00254 # Check if run as a script 00255 if __name__ == "__main__": 00256 00257 # Run the main method 00258 __main() 00259 00260 # Exit Bad - Should not reach so if it does: error 00261 sys.exit(1)