osTools.py :  » Media-Sound-Audio » athenaCL » athenaCL » libATH » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Media Sound Audio » athenaCL 
athenaCL » athenaCL » libATH » osTools.py
#!/usr/local/bin/python
#-----------------------------------------------------------------||||||||||||--
# Name:         osTools.py
# Purpose:      low level operating system wrappers.
#
# Authors:      Christopher Ariza
#
# Copyright:    (c) 2003-2006 Christopher Ariza
# License:      GPL
#-----------------------------------------------------------------||||||||||||--


import os, tempfile, time, shutil, time
from athenaCL.libATH import drawer
from athenaCL.libATH import language
lang = language.LangObj()
# do not import any higher level modules here

_MOD = 'osTools.py'

#-----------------------------------------------------------------||||||||||||--
# extensions are expected to be stored with a leading .
# all general purpose extension groups
imageEXT = ('.jpg', '.jpeg', '.tif', '.tiff', '.gif', '.png')
audioEXT = ('.aif', '.aiff', '.wav', '.wave', '.sd2', '.mp3', 
            '.m4a', '.mp4', '.m4p', '.m4b', '.mka')
midiEXT  = ('.mid', '.midi', '.mp4')
videoEXT = ('.mov', '.mpg', '.mpeg', '.avi', '.asf', '.wmv', 
            '.m4v', '.mp4', '.mp4v', '.mkv')
dataEXT  = ('.dmg', '.tar', '.zip', '.gz', '.sit', '.hqx')
codeEXT  = ('.py', '.xml', '.c++', '.c', '.h', '.htm', '.html', '.mid',
            '.sco', '.csd', '.orc', '.bat', '.css')
textEXT  = ('.txt', '.doc', '.csd')
psEXT    = ('.ps', '.eps', '.pdf')
# bundle extensions
mediaEXT = imageEXT + videoEXT # only common downloaded media
knownEXT = (imageEXT + audioEXT + videoEXT + dataEXT + 
            codeEXT + textEXT + midiEXT + psEXT)
            
            
#-----------------------------------------------------------------||||||||||||--
# utility functions for naming, getting files

def gmtimeStr():
   """get a gm time string in a nice format"""
   raw = time.gmtime()
   asc = time.asctime(raw)
   asc = asc.replace('  ', ' ') # removie double spaces
   asc = asc.split(' ')
   msg = '%s, %s %s %s %s GMT' % (asc[0], raw[2], asc[1],
                                  raw[0], asc[3])
   return msg
   

def localtimeStr():
   """get a gm time string in a nice format"""
   raw = time.localtime()
   asc = time.asctime(raw)
   asc = asc.replace('  ', ' ') # removie double spaces
   asc = asc.split(' ')
   msg = '%s, %s %s %s %s EST' % (asc[0], raw[2], asc[1],
                                  raw[0], asc[3])
   return msg

def gmtimeStamp(sigDig=6, zone='gmt'):
   "returns a string with spaced 0s, can varry signif digits"
   if zone == 'gmt':
      timeTuple = list(time.gmtime()) # get time tuple
   else: # if local
      timeTuple = list(time.localtime()) # get time tuple
   if sigDig > 0:
      timeTuple = timeTuple[0:sigDig] # just get first 6 elements
   else: # remove from the front
      timeTuple = timeTuple[abs(sigDig):6] # just get first 6 elements
   strName = ''
   for entry in timeTuple:
      if entry <= 9: # small nums perceed with 0
         strName = strName + '.0%s' % str(entry)
      else:
         strName = strName + '.%s' % str(entry)
   strName = strName[1:] # remove leading .
   return strName


def localtimeStamp(sigDig=6):
   "returns a string with spaced 0s, can varry signif digits"
   return gmtimeStamp(sigDig, 'local')

def tempDir():
   "get a temp directory"
   # dir to write temp files within
   # used in many scripts to do temp work
   tempPath = '/Volumes/xdisc/_scratch'
   if not os.path.exists(tempPath): # use temp dir if doesnt exist
      tempPath = tempfile.mkdtemp()
      print lang.WARN, 'using %s as scratch directory' % tempPath
   return tempPath

def tempFileName(ext):
   return gmtimeStamp() + ext

def tempFile(ext='.txt'):
   """make temp file in temp dir, otherwise get standard temp file
   branch by platform and do different things here
   """
   tempDir = '/Volumes/xdisc/_scratch'
   if not os.path.exists(tempDir): # use temp file
      tempPath = tempfile.mktemp(ext)
   else:
      tempName = gmtimeStamp() + ext
      tempPath = os.path.join(tempDir, tempName)
   return tempPath

#-----------------------------------------------------------------||||||||||||--
# messagge formatting for standard output

def alertMsg(str='', prepend=''):
   print '%s--||||||||||||-- %s' % (prepend, str)
   
def cmtAlert(str='', prepend='#'):
   return '%s--||||||||||||-- %s\n' % (prepend, str)

def cmtHalfStr():
   return '   #' + '-'*70 + '--||--\n'

def cmtFullStr():
   return '#' + '-'*63 + '--||||||||||||--\n'


#-----------------------------------------------------------------||||||||||||--
# posix commands

PROMPTdarwin = '%s %s: (user password required).'
PROMPTposix  = '%s %s: (superuser password required).'

def less(path, line=1):
   if os.name == 'posix': # create launch script
      if line <= 0: line = 1
      # -M info line
      # -e quite after run
      # -w highlights last line
      # -z-2 scoress -2 height
      # + starts at this line
      # -~ turns off tildes for eof
      cmdStr = 'less -M -e -w -~ -z-3 +%s %s' % (line, path)
      os.system(cmdStr)

def touch(path, str=None):
   if os.name == 'posix': # create launch script
      os.system("touch '%s'" % path)
      if str != None: # append to newly created file
         os.system("echo '%s' > %s" % (str, path))

def tag(src, ext, tagString):
   """changes a file by inserting a tagString before extension
   expects src to have the extension on it already
   """   
   dir, name = os.path.split(src)
   if ext[0] != '.': # add period if missing
      ext = '.' + ext
   lenStub = len(name) - len(ext)
   tagName = name[:lenStub] + '-' + tagString + name[lenStub:]
   tagPath = os.path.join(dir, tagName)
   return tagPath


#-----------------------------------------------------------------||||||||||||--

def rmdir(path):
   if os.name == 'posix': 
      os.system('rmdir "%s"' % path)
   else: # mac, windows
      os.rmdir(path)


def rm(path):
   if path == os.sep: raise ValueError, 'macro remove canceled' # safety
   if os.name == 'posix': 
      os.system('rm -f -r "%s"' % path)
   else: # mac, windows
      for root, dirs, files in os.walk(path, topdown=False):
          for name in files:
              os.remove(os.path.join(root, name))
          for name in dirs:
              os.rmdir(os.path.join(root, name))
      os.rmdir(path)
      
def rmSudo(path, sudoFound=None):
   """sudo is not avail on all plats, so su root on other nixes"""
   if path == os.sep: raise ValueError, 'macro remove canceled' # safety
   if os.name == 'posix': 
      if sudoFound == None: # test
         sudoFound = drawer.isSudo() # 1 if exists
      if drawer.isDarwin() or sudoFound:
         print PROMPTdarwin % ('removing', path)
         os.system('sudo rm -f -r "%s"' % path)
      else: # other *nixes
         print PROMPTposix % ('removing', path)
         os.system('su root -c "rm -f -r %s"' % path)
   else: # mac, windows
      for root, dirs, files in os.walk(path, topdown=False):
          for name in files:
              os.remove(os.path.join(root, name))
          for name in dirs:
              os.rmdir(os.path.join(root, name))
      os.rmdir(path)
        
   

def cp(src, dst):
   """alwaws does a recursive backup"""
   if os.name == 'posix': 
      os.system('cp -r "%s" "%s"' % (src, dst))
   else: # mac, windows
      if os.path.isdir():
         shutil.copytree(src, dst)
      else: # assume a file
         shutil.copyfile(src, dst)
      
def cpTag(src, ext, tagString):
   "copies a file by inserting a tagString before extension"
   tagPath = tag(src, ext, tagString)
   cp(src, tagPath)
   return tagPath

def cpSudo(src, dst, sudoFound=None):
   """sudo is not avail on all plats, so su root on other nixes"""
   if os.name == 'posix': 
      if sudoFound == None: # test
         sudoFound = drawer.isSudo() # 1 if exists
      if drawer.isDarwin() or sudoFound:
         print PROMPTdarwin % ('writing', dst)
         os.system('sudo cp %s %s' % (src, dst))
      else: # other *nixes
         print PROMPTposix % ('writing', dst)
         os.system('su root -c "cp %s %s"' % (src, dst))
   else: # mac, windows
      if os.path.isdir():
         shutil.copytree(src, dst)
      else: # assume a file
         shutil.copyfile(src, dst)

def cpTagSudo(src, ext, tagString, sudoFound=None):
   "copies a file by inserting a tagString before extension"
   tagPath = tag(src, ext, tagString)
   cpSudo(src, tagPath, sudoFound)
   return tagPath
   

def mv(src, dst):
   if os.name == 'posix': 
      os.system('mv "%s" "%s"' % (src, dst))
   else: # mac, windows
      shutil.move(src, dst)

def mvTag(src, ext, tagString):
   "moves a file by inserting a tagString before extension"
   tagPath = tag(src, ext, tagString)
   mv(src, tagPath)
   return tagPath

def mvSudo(src, dst, sudoFound=None):
   """sudo is not avail on all plats, so su root on other nixes"""
   if os.name == 'posix': 
      if sudoFound == None: # test
         sudoFound = drawer.isSudo() # 1 if exists
      if drawer.isDarwin() or sudoFound:
         print PROMPTdarwin % ('moving', dst)
         os.system('sudo mv %s %s' % (src, dst))
      else: # other *nixes
         print PROMPTposix % ('moving', dst)
         os.system('su root -c "mv %s %s"' % (src, dst))
   else: # mac, windows
      shutil.move(src, dst)


def mkdir(path, flagStr=''):
   if os.name == 'posix': 
      os.system("mkdir %s '%s'" % (flagStr, path))
   else:
      os.mkdir(path) # not recusive
      
def mkdirSudo(path, sudoFound=None, flagStr=''):
   """sudo is not avail on all plats, so su root on other nixes"""
   if os.name == 'posix': 
      if sudoFound == None: # test
         sudoFound = drawer.isSudo() # 1 if exists
      if drawer.isDarwin() or sudoFound:
         print PROMPTdarwin %  ('writing directory', path)
         os.system('sudo mkdir %s %s' % (flagStr, path))
      else: # other *nixes
         print PROMPTposix % ('writing directory', path)
         os.system('su root -c "mkdir %s %s"' % (flagStr, path))
   else:
      os.mkdir(path)


def chmod(value, path,):
   if os.name == 'posix': 
      if not drawer.isStr(value):
         value = str(value)
      os.system("chmod %s '%s'" % (value, path))

def chmodSudo(value, path, sudoFound=None):
   """sudo is not avail on all plats, so su root on other nixes"""
   if os.name == 'posix': 
      if not drawer.isStr(value):
         value = str(value)
      if sudoFound == None: # test
         sudoFound = drawer.isSudo() # 1 if exists
      if drawer.isDarwin() or sudoFound:
         print PROMPTdarwin %  ('changing permissions', path)
         os.system('sudo chmod %s "%s"' % (value, path))
      else: # other *nixes
         print PROMPTposix % ('changing permissions', path)
         os.system('su root -c "chmod %s %s"' % (value, path))


#-----------------------------------------------------------------||||||||||||--
def md5checksum(filePath):
   """return an md5 checksum for a file"""
   import md5 # this is depcreated; use hashlib

   print _MOD, 'mpd5 obtained from:', filePath
   f = open(filePath)
   msg = f.read()
   f.close()
   val = md5.new(msg).hexdigest()
   print _MOD, 'md5:', val
   return val
      
def man(path):
   cmd = 'nroff -man %s | less' % path
   os.system(cmd)


#-----------------------------------------------------------------||||||||||||--
# posix commands, relying on external command line utils

def curlFtpUplad(srcPath, dstPath, user, pswd):
   # need quotes around user and password incase of crazy chars
   # -m is max transfer time; not set here as does not seem to make a difference
   cmdStr = 'curl -# --max-time 2048 -T %s -u "%s":"%s" ftp://%s' % (srcPath,
                                                       user, pswd, dstPath)
   os.system(cmdStr)

def curlFtpDelete(path, user, pswd, dummy='__init__.py'):
   # curl must access a file before executing a -q command
   # w/o -O or -T, will print file to stdio
   # must have a dummy file in the ftp dir that a deletion is desired
   # must cd to temp dir to avoid downloading and overwriting
   
   # assume that dummy file is py __init__.py
   # could optionally upload this file if not provided
   stub, name = os.path.split(path)
   # create new dummy path
   dummyPath = os.path.join(stub, dummy)
   cmdStr = 'curl -# -u "%s":"%s" ftp://%s -Q "-DELE %s" ' % (
                         user, pswd, dummyPath, name)
   os.system(cmdStr)

def tarGzip(path):
   "tars and gzips a directory"
   dir, name = os.path.split(path)
   tarName = '%s.tar' % name
   tarPath = os.path.join(dir, tarName)

   # -C changes cd for tar session
   cmdStr = 'tar -C %s -cf %s %s' % (dir, tarPath, name)
   os.system(cmdStr)

   cmdStr = 'gzip %s' % tarPath
   os.system(cmdStr)
   gzipPath = '%s.gz' % tarPath
   return gzipPath 

def zip(path):
   "creates a zip of a dir"
   dir, name = os.path.split(path)
   cmdStr = 'cd %s; zip -r %s %s' % (dir, name, name)
   os.system(cmdStr)
   zipPath = '%s.zip' % path
   return zipPath

def cvsCheckout(dstDir, pserver, package):
   "uses cvs to get a package from pserver a drop it in dstDir"
   currentDir = os.getcwd()
   os.chdir(dstDir) # need to be in dir
   cmds = (
   'cvs -d:pserver:%s login' % pserver,
   'cvs -z3 -d:pserver:%s co %s' % (pserver, package))
   for cmd in cmds:
      os.system(cmd)
   os.chdir(currentDir) # return to previous dir

# cvs -d:pserver:ariza@cvs.sourceforge.net:/cvsroot/athenacl login
# cvs -z3 -d:pserver:ariza@cvs.sourceforge.net:/cvsroot/athenacl co athenaCL

def cvsSshCheckout(dstDir, pserver, package):
   "uses cvs to get a package from pserver a drop it in dstDir"
   currentDir = os.getcwd()
   os.chdir(dstDir) # need to be in dir
   cmds = ('cvs -z3 -d:ext:%s co %s' % (pserver, package), )
   for cmd in cmds:
      os.system(cmd)
   os.chdir(currentDir) # return to previous dir


def pdfMerge(fileDst, fileList):
   """uses ghostscript to merge pdf files into a new file"""
   if drawer.isStr(fileList):
      fileList = [fileList,] 
   cmd = 'gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%s ' % fileDst
   for file in fileList:
      cmd = cmd + '%s ' % file
   os.system(cmd)

def epsToJpg(srcPath, dstPath, rez=300, q=100, size=100):
   """convert and eps to a jpg with imagemagick"""
   if size != 100:
      sizeStr = '-geometry %s' % size + '%' # make into a percent
   else:
      sizeStr = ''
      
   cmd = 'convert %s -density %sx%s -quality %s %s %s' % (sizeStr,
                                    rez, rez, q, srcPath, dstPath)
   os.system(cmd)

def jpgToTxt(srcPath, dstPath=None):
   """character recognition w/ gocr
   http://jocr.sourceforge.net/links.html
   use djpeg to convert to bpm
   note: this works very poorly
   """
   if dstPath == None:
      dir, name = os.path.split(srcPath)
      name, ext = extSplit(name)
      dstPath = os.path.join(dir, '%s-ocr.txt' % name)

   # pnm is the default, can be bmp
   cmd = 'djpeg -pnm -gray %s | /usr/local/bin/gocr -f ASCII -o %s' % (srcPath, dstPath)
   os.system(cmd)



#-----------------------------------------------------------------||||||||||||--
# darwin commands (not cross platform)

def ditto(src, dst):
   "copies a file w/ resources, only on darwin/macos x"
   os.system("ditto -rsrcFork '%s' '%s'" % (src, dst))

def dittoSudo(src, dst):
   os.system("sudo ditto -rsrcFork '%s' '%s'" % (src, dst))

def rsync(src, dst):
   if not src.endswith(os.sep):
      srcLead = src + '/' # provides symmetrical behaviour
   if not dst.endswith(os.sep):
      dstLead = dst + '/' # provides symmetrical behaviour
   os.system("rsync -auvz '%s' '%s'" % (srcLead, dst))


def osascript(lineList):
   "call an applescript as a list of applescript code lines"
   msg = []
   for entry in lineList:
      # remove blank lines
      if entry == '':
         continue
      msg.append(" -e '%s'" % entry)
   cmdStr = "osascript -l AppleScript %s" % ''.join(msg)
   os.system(cmdStr)

def rez(path, creatorCode, typeCode, rsrcFilePath):
   flags = (' -c ' + creatorCode + ' -t ' + 
            typeCode + ' -o ' + path)
   cmdStr = 'Rez ' + rsrcFilePath + flags
   os.system(cmdStr)

def mountAfp(user, pswd, ip, dirVol):
   """mounts a afp drive; checks to see if it exists"""
   if not os.path.exists(dirVol):
      mkdir(dirVol)
      dir, vol = os.path.split(dirVol)
      cmdStr = 'mount_afp "afp://%s:%s@%s/%s" %s' % (
            user, pswd, ip, vol, dirVol)
      os.system(cmdStr)
   else:
      print '%s already exists.' % dirVol

def unmount(dirVol):
   os.system('umount %s' % dirVol)

def rsrcSetCreator(path, creator, type=None):
   if drawer.isCarbon():
      import Carbon.File
      fss = Carbon.File.FSSpec(path)
      finfo = fss.FSpGetFInfo()
      finfo.Creator = creator
      if type != None:
         finfo.Type = type
      fss.FSpSetFInfo(finfo)
   else:
      import macfs
      f = macfs.FSSpec(path)
      f.SetCreatorType(creator, type) 

def rsrcGetCreator(path):
   if drawer.isCarbon():
      import Carbon.File
      fss = Carbon.File.FSSpec(path)
      finfo = fss.FSpGetFInfo()
      creator = finfo.Creator
      type = finfo.Type
   else:
      import macfs
      f = macfs.FSSpec(path)
      creator, type = f.GetCreatorType()
   return creator, type


def hide(path):
   "darwin/macos only: hides a file using SetFile"
   cmdStr = 'SetFile -a V %s'  % path
   os.system(cmdStr)

def dmg(version, path, readmePath=None, dmgRsrc=None, vTag=1):
   """creates a .dmg of a dir;
      path is the path to the dir that needs to be archived
      name is taken from name at end of path
      vTag = 1 means a version tagged copy is made with normal name
   """
   currentDir = os.getcwd() # used only to return to

   buildDir, name = os.path.split(path)
   os.chdir(buildDir) # need to be in dir where depositing archive

   if name in os.listdir('/Volumes'):
      raise Exception('a volume is in the way! remove it!')

   # make a folder to wrap image contents
   tmpDir  = os.path.join(tempDir(), 'dmgBuild')
   tmpPath = os.path.join(tmpDir, '%s' % name)
   ditto(path, tmpPath) # copy original to inner folder
   # create message
   if readmePath == None:
      pass
   elif readmePath == 'install':
      msgPath = os.path.join(tmpDir, 'install.txt') 
      str = "To install %s, drag the %s folder to your Applications folder. Double click %s.app to start the program." % (name, name, name)
      touch(msgPath, str) # creates file and writes string
   else:
      readmeDir, readmeName = os.path.split(readmePath)
      msgPath = os.path.join(tmpDir, readmeName)
      ditto(readmePath, msgPath)
   # copy rsrc to dmg (for background, icons, etc)
   if dmgRsrc != None:
      for rsrcPath in dmgRsrc:
         rsrcDir, rsrcName = os.path.split(rsrcPath)
         dstPath = os.path.join(tmpDir, rsrcName)
         ditto(rsrcPath, dstPath) # copy to volume

   dmgName = '%s-%s.dmg' % (name, version)
   dmgPath = os.path.join(buildDir, dmgName)
   dmgNameShort = '%s.dmg' % name
   dmgPathShort = os.path.join(buildDir, dmgNameShort)

   # used to store device id
   tmpDeviceTxtPath = os.path.join(buildDir, 'tmpDeviceID.txt')

   # this is alreayd done once but it essential
   os.chdir(buildDir) # need to be in dir where depositing archive
   # execute command
   cmdList = ('hdiutil create -megabytes 40 %s -layout NONE' % dmgNameShort,
              'hdid -nomount %s > %s' % (dmgNameShort, tmpDeviceTxtPath),)
   for cmdStr in cmdList:
      os.system(cmdStr)

   # get device id from text string
   f = open(tmpDeviceTxtPath, 'r')    
   txtLines = f.readlines()
   f.close()
   deviceStr = txtLines[0].strip()
   
   # finish commands
   cmdList = ('newfs_hfs -v %s %s' % (name, deviceStr), # new fs
              'hdiutil eject %s' % (deviceStr), # eject
              'hdid %s' % (dmgNameShort),) # remount to write to
   for cmdStr in cmdList:
      os.system(cmdStr)
   
   # copy dirs to volume
   ditto(tmpDir, '/Volumes/%s/' % (name)) # copy to volume

   if dmgRsrc != None:
      print 'Customize dmg now, then press return'
      os.system('read ') # wait for return form user
      ### break to make manual adjustments
   # hide resource files, if around
   if dmgRsrc != None:
      for rsrcPath in dmgRsrc: # already moved, have to change path
         rsrcDir, rsrcName = os.path.split(rsrcPath)
         dstPath = os.path.join(('/Volumes/%s' % name), rsrcName)
         hide(dstPath) # uses a sytem find, not . pre thing

   # final commands
   cmdList = ('hdiutil eject %s' % (deviceStr), # eject
              'hdiutil convert -format UDZO %s -o %s' % (dmgNameShort, dmgName),
              'rm %s' % dmgNameShort) # remove short
   for cmdStr in cmdList:
      os.system(cmdStr)

   # remove temporary files
   rm(tmpDir)
   rm(tmpDeviceTxtPath)

   # make a copy of dmg w/o version number
   ditto(dmgPath, dmgPathShort)
   if vTag != 1: # dont keep the version tagged copy
      rm(dmgPath)
   # return dir
   os.chdir(currentDir)
   return dmgPath
   
   
#-----------------------------------------------------------------||||||||||||--
# path utilities

def extSplit(name, extList=None):
   """split name, extension; if extList is given, find only w/n this list
   return wholeName (even if a path), None if ext not found
   all '.' are dropped from both name and ext
   """
   if extList == None:
      extList = knownEXT # search all known extensions
   nameStub = name
   foundExt = ''
   for ext in extList:
      if name[-len(ext):].lower() == ext: # if has this ext
         nameStub = name[:-len(ext)]
         foundExt = ext
         break
   if nameStub == name: # no extension foudn
      return nameStub, None
   else: # check for periods, extension should have leading period
      if nameStub[-1] == '.':
         nameStub = nameStub[:-1]
      if foundExt[0] != '.': # start with leading period
         foundExt = '.' + foundExt
      return nameStub, foundExt


def dirGather(searchDir, extList):
   """searches a dir for files that match a given list of 
   of file extensions. returns a list of the names of these files.
   not recursive
   """
   dirContent = os.listdir(searchDir)
   selNames = []
   selPaths = []
   for entry in dirContent:
      for ext in extList:
         if entry[-len(ext):] == ext:
            selNames.append(entry)
            selPaths.append(os.path.join(searchDir, entry))
            break
   return selNames, selPaths


def pathTrimStub(path, stub=None):
   """takes a path and removes the parent stub component
      path should always be longer then stub
   """
   if stub == None:
      return path # do nothing
   stubList = stub.split(os.sep)
   pathList = path.split(os.sep)
   relList  = pathList[len(stubList):]
   relPath = ''
   for dir in relList:
      relPath = os.path.join(relPath, dir)
   return relPath
   
#-----------------------------------------------------------------||||||||||||--
def launch(pathExe):
   """a mulitplatform solution to launching a file
   can be used to run an executable script or file
   media files should use open below
   used for launching .bat files in elr commands as well"""
   failFlag = None
   if os.name == 'mac': # FUTURE: elr should launch csd file?
      import findertools
      try: findertools.launch(pathExe)
      except: failFlag = 'failed'
      del findertools  
   elif os.name == 'posix':
      try:
         exitStatus = os.system(pathExe)  
         # if not equal to zero an exit error has occured
         if exitStatus != 0: failFlag = 'failed'  
      except: failFlag = 'failed'
   else: # win or other
      try:# spawns a new, detached process
         # this seems to be the best solution
         # same as win32api.ShellExecute()
         os.startfile(pathExe)
         # this works on most plats, but opens a new console window
         # os.system('start %s' % (pathExe))
         # this never actually gave a detached process on nt
         # os.spawnv(os.P_NOWAIT, pathExe, ['',])  # used to be P_DETACH
      except:
         failFlag = 'failed'
      if failFlag == 'failed':
         failFlag = None # reset
         try:  # try second method if above method doesnt work
            os.system(pathExe)
         except:
            failFlag = 'failed'
   return failFlag


def openMedia(path, prefDict=None):
   """open a media or text file, file type is determined by extension
   will assume that path is to a media file, rather than an exe
   for executable scripts, use launch
   if prefDict is provided, will get app path from there
   keys in this disc must start w/ media type; image, audio, midi, text, ps"""
   path = drawer.pathScrub(path)
   dir, name = os.path.split(path)
   name, ext = extSplit(name)

   if ext in imageEXT: fileType = 'image'
   elif ext in audioEXT: fileType = 'audio'
   elif ext in videoEXT: fileType = 'video'
   elif ext in midiEXT: fileType = 'midi'
   elif ext in textEXT or ext in codeEXT: fileType = 'text'
   elif ext in psEXT: fileType = 'ps'
   else: fileType = None

   app = None # default nothing
   
   if prefDict == None and fileType != None: # get default apps
      if os.name == 'mac': pass # rely on system
      elif os.name == 'posix':
         if drawer.isDarwin(): # assume sys default for most
            if fileType in ['audio', 'midi', 'video']: 
               app = '/Applications/QuickTime Player.app'
         else: # other unix
            if fileType   == 'text' : app = 'more'
            elif fileType == 'audio': app = 'xmms'     #'play' should work too
            elif fileType == 'midi' : app = 'playmidi' #
            elif fileType == 'image': app = 'imagemagick'
            elif fileType == 'ps': app = 'gs'   
      else: # win or other
         pass # rely on system
   elif fileType != None: # get from prefDict
      for key in prefDict.keys():
         # match by filetype string leading key and path
         if key.startswith(fileType) and 'path' in key.lower(): 
            app = prefDict[key] # may be a complete file path, or a name

   if app == '': app = None # if given as empty, convert to none
   elif not drawer.isApp(app): app = None # if not an app any more, drop

   if os.name == 'mac':  # os9
      cmdExe = '%s' % path # on mac, just launch txt file, rely on pref
   elif os.name == 'posix':
      if drawer.isDarwin():
         if app == None: # no app use system default 
            cmdExe = 'open "%s"' % path   
         elif app.lower().endswith('.app'): # if a .app type app
            cmdExe = 'open -a "%s" "%s"' % (app, path)
         else: # its a unix style command
            cmdExe = '%s %s' % (app, path)
      else: # other unix
         if app == None:
            cmdExe = '%s' % (path)
         else:
            cmdExe = '%s %s' % (app, path)
   else: # win or other, rely on system settings
      cmdExe = '%s' % path # on win, just launch path        
   return launch(cmdExe) # returns None on success


#-----------------------------------------------------------------||||||||||||--
# python, ath utilies

def findSiteLib():
   """this replaces site.here, which is no longer around after python 2.3
   /System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3
   sys.prefix: (note that exec_prefix is also possible)
   '/System/Library/Frameworks/Python.framework/Versions/2.3'   
   the solution below seems to be the only good cross platform solution
   """
   return os.path.dirname(os.__file__)

def findSitePackages():
   """same as a above, but add site-packages"""
   return os.path.join(os.path.dirname(os.__file__), 'site-packages')
   
def findFinkDir():
   """this command only works on unix systems
   finds base fink dir stub
   retuns None on error: means no fink installation
   """
   if os.name == 'posix': # create launch script
      import commands
      msg = commands.getoutput('fink dumpinfo -p %p fink')
      # last line is somethign like: %p: /sw
      msgStr = msg.split('\n')[-1] # get last if more tn 1 line
      if msgStr.find('command not found') >= 0: # cant find fink command
         if os.path.exists('/sw/bin/fink'): return '/sw'
         else: return None
      else:   
         preface = '%p: '
         if msgStr.startswith(preface):
            msgStr = msgStr.replace(preface, '')
         return msgStr # return just directory string
   else: return None

def findSubDir(goal='athenaCL'):
   """recurse up a path search for dir """
   srcPath = os.getcwd()
   while 1:
      path, dir = os.path.split(srcPath)
      if dir == goal: return srcPath
      if path == '' or dir == '': return None # nowhere else to go
      srcPath = path # reassign

def findAthenaPath():
   """this is the same method used in setup.py, athenacl.py, athenaObj.py"""
   try: import libATH #assume we are in package dir
   except ImportError:
      try: from athenaCL import libATH
      except ImportError: # if n a subdirectory of athena
         return findSubDir('athenaCL') # none if found, otherwise path   
   libPath = libATH.__path__[0] # list, get first item
   if os.path.isabs(libPath) != 1: #relative path, add cwd
      libPath = os.path.abspath(libPath)
   return os.path.dirname(libPath)

def findManPath(group=1, altSys=None):
   """on unix opperating systems find man path for given group
   returns None of no man path found
   altSys sets options for specific sytems: fink
   """
   if os.name != 'posix': return None
   # common places for man directories to resside
   commonManDirs = ['/usr/share/man/', '/usr/local/man', '/usr/man']
   # check system type
   if altSys == None:
      dirs = commonManDirs
   elif altSys == 'fink':
      finkStub = findFinkDir()
      if not finkStub == None: # fink exists
         dirs = [os.path.join(finkStub, 'share', 'man')]
      else: # use common dirs
         dirs = commonManDirs
   else: raise ValueError, 'bad system alternate option given'
   found = []
   for path in dirs:
      if os.path.isdir(path):
         manDir = 'man%s' % group
         manDirPath = os.path.join(path, manDir)
         if os.path.isdir(manDirPath): # check this group exists
            found.append(manDirPath)
   if found == []:
      return None
   else:
      return found[0]

def _idlePathCandidate():
   idlePath = []
   idlePath.append(os.path.join(os.path.dirname(findSiteLib()), 
                                'Tools', 'idle'))
   idlePath.append(os.path.join(findSiteLib(), 'idlelib'))
   
   
def findIdle():
   "finds idle on various platforms; returns dir with idle.py"
   # all platforms use one of these forms
   idlePath = []
   idlePath.append(os.path.join(os.path.dirname(findSiteLib()), 
                                'Tools', 'idle'))
   idlePath.append(os.path.join(findSiteLib(), 'idlelib'))
   # python 2.3 has changed the location of idle on win
   # site.here is "lib" dir in Python dir; must go up to tools
   # dont need to move up from site.here; Tools below site.here
   # py2.3 in macos x as framework install

   for path in idlePath: # search list of possible paths
      if os.path.isdir(path) == 1: # if a directory
         dirOfIdlePath = os.listdir(path)
         if 'idle.py' in dirOfIdlePath:
            return path
         else:
            pass
      else:
         pass
   return None # if nothing found





#-----------------------------------------------------------------||||||||||||--
# utilities used during installatioin

def findBinPath(optFink=0):
   """get path to launcher dir file on posix systems"""
   if os.name != 'posix': return None
   if optFink: # fink on darwin
      finkStub = findFinkDir()
      if not finkStub == None: # if fink installed, release, other default
         return os.path.join(finkStub, 'bin')
   # default for all unix systesms
   return '/usr/local/bin'
   
def findAthBinPath(optFink=0):
   """get path to launcher dir file on posix systems"""
   if os.name != 'posix': return None
   dir = None
   if optFink: # fink on darwin
      finkStub = findFinkDir()
      if not finkStub == None: # if fink installed, release, other default
         dir = os.path.join(finkStub, 'bin')
   if dir == None:
      # default for all unix systesms
      dir = '/usr/local/bin'
   # launcher is one word lower case
   return os.path.join(dir, 'athenacl')
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.