diff options
Diffstat (limited to 'lib/sunhpc/core/files.py')
-rw-r--r-- | lib/sunhpc/core/files.py | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/lib/sunhpc/core/files.py b/lib/sunhpc/core/files.py new file mode 100644 index 0000000..886a059 --- /dev/null +++ b/lib/sunhpc/core/files.py @@ -0,0 +1,445 @@ +#coding:utf-8 +import os +import re +import sys +import stat +import time +import shutil +import string +import xml.sax +import datetime + +class File: + + def __init__(self, file, timestamp=None, size=None): + self.setFile(file, timestamp, size) + self.imortal = 0 + + def __cmp__(self, file): + if self.getBaseName() != file.getBaseName() or \ + self.timestamp == file.timestamp: + rc = 0 + elif self.timestamp > file.timestamp: + rc = 1 + else: + rc = -1 + + if rc and self.imortal + file.imortal == 1: + if self.imortal: + rc = 1 + else: + rc = -1 + + return rc + + def setFile(self, file, timestamp=None, size=None): + self.pathname = os.path.dirname(file) + self.filename = os.path.basename(file) + + if None not in (timestamp, size): + self.timestamp = timestamp + self.size = size + elif not os.path.islink(file): + self.timestamp = os.path.getmtime(file) + self.size = os.path.getsize(file) + else: + orig = os.readlink(file) + if os.path.isfile(orig): + self.timestamp = os.path.getmtime(orig) + self.size = os.path.getsize(file) + else: + self.timestamp = 0 + self.size = 0 + + def explode(self): + + file = self.getFullName() + if os.path.islink(file): + orig = os.readlink(file) + if os.path.isfile(orig): + os.unlink(file) + shutil.copy2(orig, file) + + tm = os.path.getmtime(orig) + os.utime(file, (tm, tm)) + + def setImortal(self): + self.imortal = 1 + + def getTimestamp(self): + return self.timestamp + + def getSize(self): + return float(self.size) / (1024*1024) + + def getUniqueName(self): + return self.filename + + def getBaseName(self): + return self.filename + + def getName(self): + return self.filename + + def getShortName(self): + return os.path.splitext(self.filename)[0] + + def getPath(self): + return self.pathname + + def getFullName(self): + return str(os.path.join(self.pathname, self.filename)) + + def getFileMode(self): + return self.getMode(self.getFullName()) + + def getMode(self, path): + dirs = os.stat(path) + mode = oct(dirs.st_mode)[-3:] # 目录权限0o750 -3:750 + return (mode, dirs.st_uid, dirs.st_gid) + + def symlink(self, target, base=''): + if os.path.isfile(target) or os.path.islink(target): + os.unlink(target) + os.symlink(self.getFullName(), target) + + def chmod(self, mode): + # python2 : 0664 + # python3 : 0o664 + if os.path.exists(self.getFullName()): + os.chmod(self.getFullName(), mode) + + def dump(self): + print ('%s(%s)' % (self.filename, self.pathname)) + +class Tree: + + def __init__(self, root): + self.root = root + self.tree = {} + self.build('') + + def getRoot(self): + return self.root + + def getDirs(self): + return list(self.tree.keys()) + + def getSize(self): + len = 0 + for key in self.tree.keys(): + for file in self.tree[key]: + len = len + file.getSize() + return float(len) + + def getFiles(self, path=''): + + try: + list = self.tree[path] + except KeyError: + list = [] + return list + + def setFiles(self, path, files): + self.tree[path] = files + + def build(self, dir): + path = os.path.join(self.root, dir) + if not os.path.isdir(path): + return + + try: + files = os.listdir(path) + # 移除python缓存文件夹 + if '__pycache__' in files: files.remove('__pycache__') + except: + files = [] + + v = [] + for f in files: + filepath = os.path.join(path, f) + if os.path.isdir(filepath) and not \ + os.path.islink(filepath): + self.build(os.path.join(dir, f)) + else: + if re.match('.*\.rpm$', f) != None: + v.append(RPMFile(filepath)) + elif re.match('roll-.*\.iso$', f) != None: + v.append(RollFile(filepath)) + else: + v.append(File(filepath)) + self.tree[dir] = v + + def apply(self, func, root=None): + for key in self.tree.keys(): + for e in self.tree[key]: + func(key, e, root) + + +class RPMBaseFile(File): + + def __init__(self, file, timestamp=None, size=None, ext=1): + File.__init__(self, file, timestamp, size) + self.list = [] + + s = self.filename # name-ver-rpmver.arch.rpm + for x in range(0, ext): + i = s.rfind(".") + s = self.filename[:i] + + i = s.rfind(".") + self.list.append(s[i+1:]) # get architecture string + s = self.filename[:i] + + i = s.rfind("-") # get RPM version string + self.release = s[i+1:] + self.list.append(self.versionList(s[i+1:])) + s = self.filename[:i] + + i = s.rfind("-") # get software version string + self.version = s[i+1:] + self.list.append(self.versionList(s[i+1:])) + self.list.append(self.filename[:i]) # get package name + self.list.reverse() # we built the list backwards + + def versionList(self, s): + list = [] + for e in re.split('\.+|_+', s): + l = [] + num = '' + alpha = '' + for c in e: + if c in string.digits: + num = num + c + if alpha: + l.append(alpha) + alpha = '' + else: + alpha = alpha + c + if num: + l.append(num) + num = '' + if alpha: + l.append(alpha) + if num: + l.append(num) + list.append(l) + return list + + def getBaseName(self): + return self.list[0] + + def getUniqueName(self): + return '%s-%s' % (self.list[0], self.list[3]) + +class RPMFile(RPMBaseFile): + + def __init__(self, file, timestamp=None, size=None): + RPMBaseFile.__init__(self, file, timestamp, size) + + def __cmp__(self, file): + if self.getPackageArch() != file.getPackageArch(): + rc = 0 + else: + if abs(int(self.timestamp) - int(file.timestamp)) < 120 : + # print "CMP %s:%s" % (self.getFullName(), file.getFullName()) + f1=os.popen("rpm -qp --qf '%%{BUILDTIME}' %s" % self.getFullName()) + self.timestamp=float(f1.readline()) + f1.close() + f2=os.popen("rpm -qp --qf '%%{BUILDTIME}' %s" % file.getFullName()) + file.timestamp=float(f2.readline()) + f2.close() + + rc = File.__cmp__(self, file) + return rc + + def getPackageName(self): + return self.getBaseName() + + def getPackageVersion(self): + return self.list[1] + + def getPackageRelease(self): + return self.list[2] + + def getPackageVersionString(self): + return self.version + + def getPackageReleaseString(self): + return self.release + + def getPackageArch(self): + return self.list[3] + +class RollInfoFile(File, + xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler, + xml.sax.handler.EntityResolver, xml.sax.handler.ErrorHandler): + + def __init__(self, file): + File.__init__(self, file) + + self.attrs = {} + parser = xml.sax.make_parser() + parser.setContentHandler(self) + fin = open(file, 'r') + parser.parse(fin) + fin.close() + + def startElement(self, name, attrs): + self.attrs[str(name)] = {} + for (attrName, attrVal) in attrs.items(): + self.attrs[str(name)][str(attrName)] = str(attrVal) + + def getXML(self): + + xml = [] + xml.append('<roll name="%s" interface="%s">' % + (self.getRollName(), self.getRollInterface())) + for tag in self.attrs.keys(): + if tag == 'roll': + continue + attrs = '' + for key,val in self.attrs[tag].items(): + attrs += ' %s="%s"' % (key, val) + xml.append('\t<%s%s/>' % (tag, attrs)) + xml.append('</roll>') + + return string.join(xml, '\n') + + def getRollName(self): + return self.attrs['roll']['name'] + + def getRollInterface(self): + return self.attrs['roll']['interface'] + + def getRollVersion(self): + return self.attrs['info']['version'] + + def getRollRelease(self): + return self.attrs['info']['release'] + + def setRollOS(self, os): + self.attrs['info']['os'] = os + + def getRollOS(self): + try: + return self.attrs['info']['os'] + except KeyError: + return 'linux' + + def setRollArch(self, arch): + self.attrs['info']['arch'] = arch + + def getRollArch(self): + return self.attrs['info']['arch'] + + def getISOMaxSize(self): + return float(self.attrs['iso']['maxsize']) + + def setISOMaxSize(self, size): + self.attrs['iso']['maxsize'] = size + + def getISOFlags(self): + return self.attrs['iso']['mkisofs'] + + def getRollRolls(self): + return self.attrs['rpm']['rolls'] + + def isBootable(self): + return int(self.attrs['iso']['bootable']) + + def hasRolls(self): + if self.attrs['rpm']['rolls'] != '0': + return 1 + else: + return 0 + + def hasRPMS(self): + return int(self.attrs['rpm']['bin']) + + def hasSRPMS(self): + return int(self.attrs['rpm']['src']) + + def getDepsName(self): + return self.attrs['deps']['name'] + + def getDepsHost(self): + return self.attrs['deps']['host'] + +class RPMbuild: + def __init__(self, root): + self.root = root + self.tree = {} + self.fulldirs = {} + self.build('') + + def getRoot(self): + return self.root + + def getRootName(self): + return self.root.split('/')[-1] + + def getRootMode(self): + return self.getMode(self.root) + + def getPathMode(self, path): + return self.getMode(path) + + def getMode(self, path): + dirs = os.stat(path) + mode = oct(dirs.st_mode)[-3:] # 目录权限0o750 -3:750 + return (mode, dirs.st_uid, dirs.st_gid) + + def getDirs(self): + return list(self.tree.keys()) + + def getDirMode(self, path): + return self.fulldirs[path] + + def getFiles(self, path=''): + try: + list = self.tree[path] + except KeyError: + list = [] + return list + + def build(self, dir): + + path = os.path.join(self.root, dir) + if not os.path.isdir(path): + return + + try: + files = os.listdir(path) + # 移除python缓存文件夹 + #if '__pycache__' in files: files.remove('__pycache__') + except: + raise + files = [] + + v = [] + for f in files: + filepath = os.path.join(path, f) + if os.path.isdir(filepath) and not os.path.islink(filepath): + self.build(os.path.join(dir, f)) + else: + v.append(File(filepath)) + + dirs = os.stat(path) + mode = oct(dirs[stat.ST_MODE])[-3:] # 目录权限0o750 -3:750 + uid = dirs.st_uid #目录的uid + gid = dirs.st_gid #目录的gid + + # 格式: (dirname, owner, uid, gid) + self.fulldirs[dir] = (mode, uid, gid) + self.tree[dir] = v + + + + + + + + + + |