MkDistr.py :  » Language-Interface » ChinesePython » chinesepython2.1.3-0.4 » Mac » scripts » 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 » Language Interface » ChinesePython 
ChinesePython » chinesepython2.1.3 0.4 » Mac » scripts » MkDistr.py
#
# Interactively decide what to distribute
#
#
# The exclude file signals files to always exclude,
# The pattern file lines are of the form
# *.c
# This excludes all files ending in .c.
#
# The include file signals files and directories to include.
# Records are of the form
# ('Tools:bgen:AE:AppleEvents.py', 'Lib:MacToolbox:AppleEvents.py')
# This includes the specified file, putting it in the given place, or
# ('Tools:bgen:AE:AppleEvents.py', None)
# This excludes the specified file.
#
from MkDistr_ui import *
import fnmatch
import re
import os
import sys
import macfs
import macostools

DEBUG=0

SyntaxError='Include/exclude file syntax error'

class Matcher:
  """Include/exclude database, common code"""
  
  def __init__(self, filename):
    self.filename = filename
    self.rawdata = []
    self.parse(filename)
    self.rawdata.sort()
    self.rebuild()
    self.modified = 0

  def parse(self, dbfile):
    try:
      fp = open(dbfile)
    except IOError:
      return
    data = fp.readlines()
    fp.close()
    for d in data:
      d = d[:-1]
      if not d or d[0] == '#': continue
      pat = self.parseline(d)
      self.rawdata.append(pat)
        
  def save(self):
    fp = open(self.filename, 'w')
    self.savedata(fp, self.rawdata)
    self.modified = 0
      
  def add(self, value):
    if len(value) == 1:
      value = value + ('',)
    self.rawdata.append(value)
    self.rebuild1(value)
    self.modified = 1
    
  def delete(self, value):
    key = value
    for i in range(len(self.rawdata)):
      if self.rawdata[i][0] == key:
        del self.rawdata[i]
        self.unrebuild1(i, key)
        self.modified = 1
        return
    print 'Not found!', key
        
  def getall(self):
    return map(lambda x: x[0], self.rawdata)
  
  def get(self, value):
    for src, dst in self.rawdata:
      if src == value:
        return src, dst
    print 'Not found!', value
        
  def is_modified(self):
    return self.modified
              
class IncMatcher(Matcher):
  """Include filename database and matching engine"""

  def rebuild(self):
    self.idict = {}
    self.edict = {}
    for v in self.rawdata:
      self.rebuild1(v)
      
  def parseline(self, line):
    try:
      data = eval(line)
    except:
      raise SyntaxError, line
    if type(data) <> type(()) or len(data) not in (1,2):
      raise SyntaxError, line
    if len(data) == 1:
      data = data + ('',)
    return data
    
  def savedata(self, fp, data):
    for d in self.rawdata:
      fp.write(`d`+'\n')
    
  def rebuild1(self, (src, dst)):
    if dst == '':
      dst = src
    if dst == None:
      self.edict[src] = None
    else:
      self.idict[src] = dst
      
  def unrebuild1(self, num, src):
    if self.idict.has_key(src):
      del self.idict[src]
    else:
      del self.edict[src]
  
  def match(self, patharg):
    removed = []
    # First check the include directory
    path = patharg
    while 1:
      if self.idict.has_key(path):
        # We know of this path (or initial piece of path)
        dstpath = self.idict[path]
        # We do want it distributed. Tack on the tail.
        while removed:
          dstpath = os.path.join(dstpath, removed[0])
          removed = removed[1:]
        # Finally, if the resultant string ends in a separator
        # tack on our input filename
        if dstpath[-1] == os.sep:
          dir, file = os.path.split(path)
          dstpath = os.path.join(dstpath, file)
        if DEBUG:
          print 'include', patharg, dstpath
        return dstpath
##      path, lastcomp = os.path.split(path)
##      if not path:
##        break
##      removed[0:0] = [lastcomp]
##    # Next check the exclude directory
##    path = patharg
##    while 1:
      if self.edict.has_key(path):
        if DEBUG:
          print 'exclude', patharg, path
        return ''
      path, lastcomp = os.path.split(path)
      if not path:
        break
      removed[0:0] = [lastcomp]
    if DEBUG:
      print 'nomatch', patharg
    return None
      
  def checksourcetree(self):
    rv = []
    for name in self.idict.keys():
      if not os.path.exists(name):
        rv.append(name)
    return rv
        
class ExcMatcher(Matcher):
  """Exclude pattern database and matching engine"""

  def rebuild(self):
    self.relist = []
    for v in self.rawdata:
      self.rebuild1(v)
    
  def parseline(self, data):
    return (data, None)

  def savedata(self, fp, data):
    for d in self.rawdata:
      fp.write(d[0]+'\n')    
    
  def rebuild1(self, (src, dst)):
    pat = fnmatch.translate(src)
    if DEBUG:
      print 'PATTERN', `src`, 'REGEX', `pat`
    self.relist.append(re.compile(pat))
    
  def unrebuild1(self, num, src):
    del self.relist[num]
  
  def match(self, path):
    comps = os.path.split(path)
    file = comps[-1]
    for pat in self.relist:
      if pat and pat.match(file):
        if DEBUG:
          print 'excmatch', file, pat
        return 1
    return 0    
     
    
class Main:
  """The main program glueing it all together"""
  
  def __init__(self):
    InitUI()
    os.chdir(sys.prefix)
    if not os.path.isdir(':Mac:Distributions'):
      os.mkdir(':Mac:Distributions')
    self.typedist = GetType()
    self.inc = IncMatcher(':Mac:Distributions:%s.include'%self.typedist)
    self.exc = ExcMatcher(':Mac:Distributions:%s.exclude'%self.typedist)
    self.ui = MkDistrUI(self)
    self.ui.mainloop()
    
  def check(self):
    return self.checkdir(':', 1)
    
  def checkdir(self, path, istop):
    if DEBUG:
      print 'checkdir', path
    files = os.listdir(path)
    rv = []
    todo = []
    for f in files:
      if DEBUG:
        print 'checkfile', f
      if self.exc.match(f):
        if DEBUG:
          print 'exclude match', f
        continue
      fullname = os.path.join(path, f)
      if DEBUG:
        print 'checkpath', fullname
      matchvalue = self.inc.match(fullname)
      if matchvalue == None:
        if os.path.isdir(fullname):
          if DEBUG:
            print 'do dir', fullname
          todo.append(fullname)
        else:
          if DEBUG:
            print 'include', fullname
          rv.append(fullname)
      elif DEBUG:
        print 'badmatch', matchvalue
    for d in todo:
      if len(rv) > 500:
        if istop:
          rv.append('... and more ...')
        return rv
      rv = rv + self.checkdir(d, 0)
    return rv
    
  def run(self):
    missing = self.inc.checksourcetree()
    if missing:
      print '==== Missing source files ===='
      for i in missing:
        print i
      print '==== Fix and retry ===='
      return
    destprefix = os.path.join(sys.prefix, ':Mac:Distributions:(vise)')
    destprefix = os.path.join(destprefix, '%s Distribution'%self.typedist)
    if not self.rundir(':', destprefix, 0):
      return
    self.rundir(':', destprefix, 1)

  def rundir(self, path, destprefix, doit):
    files = os.listdir(path)
    todo = []
    rv = 1
    for f in files:
      if self.exc.match(f):
        continue
      fullname = os.path.join(path, f)
      if os.path.isdir(fullname):
        todo.append(fullname)
      else:
        dest = self.inc.match(fullname)
        if dest == None:
          print 'Not yet resolved:', fullname
          rv = 0
        if dest:
          if doit:
            print 'COPY ', fullname
            print '  -> ', os.path.join(destprefix, dest)
            try:
              macostools.copy(fullname, os.path.join(destprefix, dest), 1)
            except: #DBG
              print '*** Copy failed mysteriously, try again'
              print '*** cwd', os.getcwd() #DBG
              print '*** fsspec', macfs.FSSpec(fullname) #DBG
              # Get rid of open files
              try:
                i = 1 / 0
              except:
                pass
              macostools.copy(fullname, os.path.join(destprefix, dest), 1)
    for d in todo:
      if not self.rundir(d, destprefix, doit):
        rv = 0
    return rv
    
  def save(self):
    self.inc.save()
    self.exc.save()
    
  def is_modified(self):
    return self.inc.is_modified() or self.exc.is_modified()

if __name__ == '__main__':
  Main()
  
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.