diff --git a/TODO b/TODO index a3d33936c..14545f44c 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,7 @@ TODO list: - tool to create arbitrary .tbz2 (like debs?) - if chosen command doesn't exist, return error - find a way to better handle real smartapps deps + - add support for database revisions log Project Status: diff --git a/client/cacheTools.py b/client/cacheTools.py index 8261215ed..6bbd84052 100644 --- a/client/cacheTools.py +++ b/client/cacheTools.py @@ -31,7 +31,7 @@ import confTools def cache(options): rc = 0 if len(options) < 1: - return rc + return -10 equoRequestVerbose = False equoRequestQuiet = False @@ -46,9 +46,10 @@ def cache(options): if myopts[0] == "clean": rc = cleanCache() - - if myopts[0] == "generate": + elif myopts[0] == "generate": rc = generateCache(quiet = equoRequestQuiet, verbose = equoRequestVerbose) + else: + rc = -10 return rc diff --git a/client/confTools.py b/client/confTools.py index ff0014dd8..31fb85a9f 100644 --- a/client/confTools.py +++ b/client/confTools.py @@ -42,7 +42,7 @@ def configurator(options): rc = 0 if len(options) < 1: - return rc + return -10 equoRequestVerbose = False equoRequestQuiet = False @@ -58,9 +58,10 @@ def configurator(options): if myopts[0] == "info": rc = confinfo() - elif myopts[0] == "update": rc = update() + else: + rc = -10 return rc diff --git a/client/equo b/client/equo index 2d7bb3c2e..b63cfc046 100644 --- a/client/equo +++ b/client/equo @@ -95,6 +95,10 @@ def print_help(): print_info(" \t\tA .tbz2 package that can contain multiple packages (Gentoo compatible)") print_info(" \t\t"+darkgreen("package")+red("\t\t\t generate a smart package for the provided atoms")) print_info(" \t\t"+darkgreen("quickpkg")+red("\t\t repackage installed files belonging to the provided atoms")) + print_info(" \t\t"+darkgreen("inflate")+red("\t\t\t transform provided Gentoo .tbz2 packages into an Entropy one (Portage needed)")) + print_info(" \t\t\t"+red("--savedir")+"\t save new packages to the specified directory") + print_info(" \t\t"+darkgreen("deflate")+red("\t\t\t transform provided Entropy .tbz2 packages into an Gentoo ones (Portage needed)")) + print_info(" \t\t\t"+red("--savedir")+"\t save new packages to the specified directory") print_info(" \t"+blue("database")+brown("\t handle installed packages database")) print_info(" \t\t"+darkgreen("generate")+red("\t\t generate installed packages database")) @@ -207,6 +211,8 @@ try: if len(options) > 1: import queryTools rc = queryTools.searchPackage(options[1:]) + else: + rc = -10 elif (options[0] == "database"): entropyTools.applicationLockCheck("database") @@ -217,6 +223,11 @@ try: entropyTools.applicationLockCheck("cleanup") entropyTools.cleanup([ etpConst['packagestmpdir'], etpConst['logdir'], etpConst['entropyunpackdir'], etpConst['packagesbindir'] ]) rc = 0 + else: + rc = -10 + + if rc == -10: + print_error(darkred("Wrong parameters.")) # kill threads threads = entropyTools.threading.enumerate() for thread in threads: diff --git a/client/equoTools.py b/client/equoTools.py index c32445b4d..bd7b527a8 100644 --- a/client/equoTools.py +++ b/client/equoTools.py @@ -1026,35 +1026,44 @@ def installPackage(infoDict): packageContent = [] # setup imageDir properly imageDir = imageDir.encode(getfilesystemencoding()) + # merge data into system for currentdir,subdirs,files in os.walk(imageDir): # create subdirs for dir in subdirs: - #dirpath += "/"+dir - imagepathDir = currentdir + "/" + dir + + imagepathDir = currentdir + "/" + dir rootdir = imagepathDir[len(imageDir):] - # get info - if (rootdir): - if os.path.islink(rootdir): - if not os.path.exists(rootdir): # broken symlink - #print "I want to remove "+rootdir - #print os.readlink(rootdir) - os.remove(rootdir) - elif os.path.isfile(rootdir): # weird - equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"WARNING!!! "+str(rootdir)+" is a file when it should be a directory !! Removing in 10 seconds...") - print_warning(red(" *** ")+bold(rootdir)+red(" is a file when it should be a directory !! Removing in 10 seconds...")) - import time - time.sleep(10) - os.remove(rootdir) - if (not os.path.isdir(rootdir)) and (not os.access(rootdir,os.R_OK)): - #print "creating dir "+rootdir - os.makedirs(rootdir) - user = os.stat(imagepathDir)[4] - group = os.stat(imagepathDir)[5] - os.chown(rootdir,user,group) - shutil.copystat(imagepathDir,rootdir) - #dirpath = '' - for file in files: + + # handle broken symlinks + if os.path.islink(rootdir) and not os.path.exists(rootdir):# broken symlink + os.remove(rootdir) + + # if our directory is a file on the live system + elif os.path.isfile(rootdir): # really weird...! + equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"WARNING!!! "+str(rootdir)+" is a file when it should be a directory !! Removing in 10 seconds...") + print_warning(red(" *** ")+bold(rootdir)+red(" is a file when it should be a directory !! Removing in 10 seconds...")) + import time + time.sleep(10) + os.remove(rootdir) + + # if our directory is a symlink instead, then copy the symlink + if os.path.islink(imagepathDir) and not os.path.isdir(rootdir): # for security we skip live items that are dirs + tolink = os.readlink(imagepathDir) + if os.path.islink(rootdir): + os.remove(rootdir) + os.symlink(tolink,rootdir) + elif (not os.path.isdir(rootdir)) and (not os.access(rootdir,os.R_OK)): + #print "creating dir "+rootdir + os.makedirs(rootdir) + + if not os.path.islink(rootdir): # symlink don't need permissions, also until os.walk ends they might be broken + user = os.stat(imagepathDir)[4] + group = os.stat(imagepathDir)[5] + os.chown(rootdir,user,group) + shutil.copystat(imagepathDir,rootdir) + + for file in files: fromfile = currentdir+"/"+file tofile = fromfile[len(imageDir):] diff --git a/client/queryTools.py b/client/queryTools.py index a44b3d6fc..1fbc8775e 100644 --- a/client/queryTools.py +++ b/client/queryTools.py @@ -37,7 +37,7 @@ def query(options): rc = 0 if len(options) < 1: - return rc + return -10 equoRequestVerbose = False equoRequestQuiet = False @@ -84,10 +84,10 @@ def query(options): if len(mylistopts) > 0: if mylistopts[0] == "installed": rc = searchInstalled(verbose = equoRequestVerbose, quiet = equoRequestQuiet) - # add more here - elif myopts[0] == "description": rc = searchDescription(myopts[1:], quiet = equoRequestQuiet) + else: + rc = -10 return rc diff --git a/client/repositoriesTools.py b/client/repositoriesTools.py index c2d01343a..cf00008d1 100644 --- a/client/repositoriesTools.py +++ b/client/repositoriesTools.py @@ -52,13 +52,13 @@ def repositories(options): if (options[0] == "update"): rc = syncRepositories(forceUpdate = equoRequestForceUpdate) - - if (options[0] == "status"): + elif (options[0] == "status"): for repo in etpRepositories: showRepositoryInfo(repo) - - if (options[0] == "repoinfo"): + elif (options[0] == "repoinfo"): showRepositories() + else: + rc = -10 return rc # this function shows a list of enabled repositories diff --git a/client/rescueTools.py b/client/rescueTools.py index 1117e26ed..9c582614c 100644 --- a/client/rescueTools.py +++ b/client/rescueTools.py @@ -136,8 +136,8 @@ def database(options): print_info(red(" Now generating depends caching table...")) clientDbconn.regenerateDependsTable() print_info(red(" Database reinitialized successfully.")) - clientDbconn.closeDB() + return 0 elif (options[0] == "resurrect"): @@ -233,6 +233,7 @@ def database(options): print_info(red(" Database resurrected successfully.")) print_warning(red(" Keep in mind that virtual/meta packages couldn't be matched. They don't own any files.")) + return 0 elif (options[0] == "depends"): print_info(red(" Regenerating depends caching table...")) @@ -240,6 +241,10 @@ def database(options): clientDbconn.regenerateDependsTable() clientDbconn.closeDB() print_info(red(" Depends caching table regenerated successfully.")) + return 0 + + else: + return -10 ''' diff --git a/client/uiTools.py b/client/uiTools.py index 73d35a499..938b4406d 100644 --- a/client/uiTools.py +++ b/client/uiTools.py @@ -115,6 +115,8 @@ def package(options): else: print_error(red(" Nothing to do.")) rc = 127 + else: + rc = -10 return rc diff --git a/libraries/entropyConstants.py b/libraries/entropyConstants.py index b8e58b964..cfa20b8da 100644 --- a/libraries/entropyConstants.py +++ b/libraries/entropyConstants.py @@ -27,8 +27,7 @@ from sys import exit # Specifications of the content of etpData -# THIS IS THE KEY PART OF ENTROPY BINARY PACKAGES MANAGEMENT -# DO NOT EDIT THIS UNLESS YOU KNOW WHAT YOU'RE DOING !! +''' etpData = { 'name': u"", # the Package Name 'version': u"", # the Package version @@ -66,6 +65,7 @@ etpData = { 'needed': u"", # runtime libraries needed by the package 'trigger': u"", # this will become a bool, containing info about external trigger presence } +''' # Entropy database SQL initialization Schema and data structure etpSQLInitDestroyAll = """ diff --git a/libraries/entropyTools.py b/libraries/entropyTools.py index 1acf0214c..e6125ac81 100644 --- a/libraries/entropyTools.py +++ b/libraries/entropyTools.py @@ -268,6 +268,39 @@ def extractEdb(tbz2file, dbpath = None): old.close() return dbpath +def removeEdb(tbz2file, savedir): + entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"removeEdb: called -> "+tbz2file) + old = open(tbz2file,"rb") + new = open(savedir+"/"+os.path.basename(tbz2file),"wb") + + # position old to the end + old.seek(0,2) + # read backward until we find + bytes = old.tell() + counter = bytes + + while counter >= 0: + old.seek(counter-bytes,2) + byte = old.read(1) + if byte == "|": + old.seek(counter-bytes-31,2) # wth I can't use len(etpConst['databasestarttag']) ??? + chunk = old.read(31)+byte + if chunk == etpConst['databasestarttag']: + old.seek(counter-bytes-32,2) + break + counter -= 1 + + endingbyte = old.tell() + old.seek(0) + while old.tell() <= endingbyte: + byte = old.read(1) + new.write(byte) + counter += 1 + + new.flush() + new.close() + old.close() + return savedir+"/"+os.path.basename(tbz2file) # This function creates the .md5 file related to the given package file # @returns the complete hash file path @@ -1269,4 +1302,515 @@ def quickpkg(pkgdata,dirpath): if os.path.isfile(dirpath): return dirpath else: - return None \ No newline at end of file + return None + +# This function extracts all the info from a .tbz2 file and returns them +def extractPkgData(package, etpBranch = etpConst['branch']): + + entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"extractPkgData: called -> package: "+str(package)) + data = {} + + from portageTools import synthetizeRoughDependencies, getPackagesInSystem, getConfigProtectAndMask, getThirdPartyMirrors + + info_package = bold(os.path.basename(package))+": " + + print_info(yellow(" * ")+red(info_package+"Getting package name/version..."),back = True) + tbz2File = package + package = package.split(".tbz2")[0] + package = remove_tag(package) + + # FIXME: deprecated - will be removed soonly + if package.split("-")[len(package.split("-"))-1].startswith("t"): + package = '-t'.join(package.split("-t")[:-1]) + + package = package.split("-") + pkgname = "" + pkglen = len(package) + if package[pkglen-1].startswith("r"): + pkgver = package[pkglen-2]+"-"+package[pkglen-1] + pkglen -= 2 + else: + pkgver = package[len(package)-1] + pkglen -= 1 + for i in range(pkglen): + if i == pkglen-1: + pkgname += package[i] + else: + pkgname += package[i]+"-" + pkgname = pkgname.split("/")[len(pkgname.split("/"))-1] + + # Fill Package name and version + data['name'] = pkgname + data['version'] = pkgver + + print_info(yellow(" * ")+red(info_package+"Getting package md5..."),back = True) + # .tbz2 md5 + data['digest'] = md5sum(tbz2File) + + print_info(yellow(" * ")+red(info_package+"Getting package mtime..."),back = True) + # .tbz2 md5 + data['datecreation'] = str(getFileUnixMtime(tbz2File)) + + print_info(yellow(" * ")+red(info_package+"Getting package size..."),back = True) + # .tbz2 byte size + data['size'] = str(os.stat(tbz2File)[6]) + + print_info(yellow(" * ")+red(info_package+"Unpacking package data..."),back = True) + # unpack file + tbz2TmpDir = etpConst['packagestmpdir']+"/"+data['name']+"-"+data['version']+"/" + extractXpak(tbz2File,tbz2TmpDir) + + print_info(yellow(" * ")+red(info_package+"Getting package CHOST..."),back = True) + # Fill chost + f = open(tbz2TmpDir+dbCHOST,"r") + data['chost'] = f.readline().strip() + f.close() + + print_info(yellow(" * ")+red(info_package+"Setting package branch..."),back = True) + data['branch'] = etpBranch + + print_info(yellow(" * ")+red(info_package+"Getting package description..."),back = True) + # Fill description + data['description'] = "" + try: + f = open(tbz2TmpDir+dbDESCRIPTION,"r") + data['description'] = f.readline().strip() + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package homepage..."),back = True) + # Fill homepage + data['homepage'] = "" + try: + f = open(tbz2TmpDir+dbHOMEPAGE,"r") + data['homepage'] = f.readline().strip() + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package slot information..."),back = True) + # fill slot, if it is + data['slot'] = "" + try: + f = open(tbz2TmpDir+dbSLOT,"r") + data['slot'] = f.readline().strip() + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package eclasses information..."),back = True) + # fill eclasses list + data['eclasses'] = [] + try: + f = open(tbz2TmpDir+dbINHERITED,"r") + data['eclasses'] = f.readline().strip().split() + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package needed libraries information..."),back = True) + # fill needed list + data['needed'] = set() + try: + f = open(tbz2TmpDir+dbNEEDED,"r") + lines = f.readlines() + f.close() + for line in lines: + line = line.strip() + if line: + needed = line.split() + if len(needed) == 2: + libs = needed[1].split(",") + for lib in libs: + if (lib.find(".so") != -1): + data['needed'].add(lib) + except IOError: + pass + data['needed'] = list(data['needed']) + + print_info(yellow(" * ")+red(info_package+"Getting package content..."),back = True) + # dbCONTENTS + data['content'] = {} + try: + f = open(tbz2TmpDir+dbCONTENTS,"r") + content = f.readlines() + f.close() + outcontent = set() + for line in content: + line = line.strip().split() + try: + datatype = line[0] + datafile = line[1:] + if datatype == 'obj': + datafile = datafile[:-2] + datafile = ' '.join(datafile) + elif datatype == 'dir': + datafile = ' '.join(datafile) + elif datatype == 'sym': + datafile = datafile[:-3] + datafile = ' '.join(datafile) + else: + print "unhandled !!!!!!!",datafile + raise Exception + outcontent.add((datafile,datatype)) + except: + pass + + # convert to plain str() since it's that's used by portage + # when portage will use utf, test utf-8 encoding + _outcontent = set() + for i in outcontent: + datatype = i[1] + datafile = str(i[0]) + _outcontent.add((i[0],i[1])) + outcontent = list(_outcontent) + outcontent.sort() + for i in outcontent: + data['content'][str(i[0])] = i[1] + + except IOError: + pass + + # files size on disk + if (data['content']): + data['disksize'] = 0 + for file in data['content']: + try: + size = os.stat(file)[6] + data['disksize'] += size + except: + pass + else: + data['disksize'] = 0 + + # [][][] Kernel dependent packages hook [][][] + data['versiontag'] = '' + kernelDependentModule = False + kernelItself = False + for file in data['content']: + if file.find("/lib/modules/") != -1: + kernelDependentModule = True + # get the version of the modules + kmodver = file.split("/lib/modules/")[1] + kmodver = kmodver.split("/")[0] + + lp = kmodver.split("-")[len(kmodver.split("-"))-1] + if lp.startswith("r"): + kname = kmodver.split("-")[len(kmodver.split("-"))-2] + kver = kmodver.split("-")[0]+"-"+kmodver.split("-")[len(kmodver.split("-"))-1] + else: + kname = kmodver.split("-")[len(kmodver.split("-"))-1] + kver = kmodver.split("-")[0] + break + # validate the results above + if (kernelDependentModule): + matchatom = "linux-"+kname+"-"+kver + if (matchatom == data['name']+"-"+data['version']): + # discard, it's the kernel itself, add other deps instead + kernelItself = True + kernelDependentModule = False + + # add strict kernel dependency + # done below + + print_info(yellow(" * ")+red(info_package+"Getting package download URL..."),back = True) + # Fill download relative URI + if (kernelDependentModule): + data['versiontag'] = kmodver + # force slot == tag: + data['slot'] = kmodver + versiontag = "#"+data['versiontag'] + else: + versiontag = "" + data['download'] = etpConst['binaryurirelativepath']+data['branch']+"/"+data['name']+"-"+data['version']+versiontag+".tbz2" + + print_info(yellow(" * ")+red(info_package+"Getting package counter..."),back = True) + # Fill counter + f = open(tbz2TmpDir+dbCOUNTER,"r") + data['counter'] = f.readline().strip() + f.close() + + print_info(yellow(" * ")+red(info_package+"Getting package category..."),back = True) + # Fill category + f = open(tbz2TmpDir+dbCATEGORY,"r") + data['category'] = f.readline().strip() + f.close() + + data['trigger'] = "" + print_info(yellow(" * ")+red(info_package+"Getting package external trigger availability..."),back = True) + if os.path.isfile(etpConst['triggersdir']+"/"+data['category']+"/"+data['name']+"/"+etpConst['triggername']): + f = open(etpConst['triggersdir']+"/"+data['category']+"/"+data['name']+"/"+etpConst['triggername'],"rb") + f.seek(0,2) + size = f.tell() + f.seek(0) + data['trigger'] = f.read(size) + f.close() + + print_info(yellow(" * ")+red(info_package+"Getting package CFLAGS..."),back = True) + # Fill CFLAGS + data['cflags'] = "" + try: + f = open(tbz2TmpDir+dbCFLAGS,"r") + data['cflags'] = f.readline().strip() + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package CXXFLAGS..."),back = True) + # Fill CXXFLAGS + data['cxxflags'] = "" + try: + f = open(tbz2TmpDir+dbCXXFLAGS,"r") + data['cxxflags'] = f.readline().strip() + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package License information..."),back = True) + # Fill license + data['license'] = [] + try: + f = open(tbz2TmpDir+dbLICENSE,"r") + # strip away || ( ) + tmpLic = f.readline().strip().split() + f.close() + for x in tmpLic: + if x: + if (not x.startswith("|")) and (not x.startswith("(")) and (not x.startswith(")")): + data['license'].append(x) + data['license'] = ' '.join(data['license']) + except IOError: + data['license'] = "" + pass + + print_info(yellow(" * ")+red(info_package+"Getting package USE flags..."),back = True) + # Fill USE + data['useflags'] = [] + f = open(tbz2TmpDir+dbUSE,"r") + tmpUSE = f.readline().strip() + f.close() + + try: + f = open(tbz2TmpDir+dbIUSE,"r") + tmpIUSE = f.readline().strip().split() + f.close() + except IOError: + tmpIUSE = [] + + PackageFlags = [] + for x in tmpUSE.split(): + if (x): + PackageFlags.append(x) + + for i in tmpIUSE: + try: + PackageFlags.index(i) + data['useflags'].append(i) + except: + data['useflags'].append("-"+i) + + print_info(yellow(" * ")+red(info_package+"Getting package provide content..."),back = True) + # Fill Provide + data['provide'] = [] + try: + f = open(tbz2TmpDir+dbPROVIDE,"r") + provide = f.readline().strip() + f.close() + if (provide): + provide = provide.split() + for x in provide: + data['provide'].append(x) + except: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package sources information..."),back = True) + # Fill sources + data['sources'] = [] + try: + f = open(tbz2TmpDir+dbSRC_URI,"r") + sources = f.readline().strip().split() + f.close() + tmpData = [] + cnt = -1 + skip = False + data['sources'] = [] + + for source in sources: + cnt += +1 + if source.endswith("?"): + # it's an use flag + source = source[:len(source)-1] + direction = True + if source.startswith("!"): + direction = False + source = source[1:] + # now get the useflag + useflag = False + try: + data['useflags'].index(source) + useflag = True + except: + pass + + + if (useflag) and (direction): # useflag is enabled and it's asking for sources or useflag is not enabled and it's not not (= True) asking for sources + # ack parsing from ( to ) + skip = False + elif (useflag) and (not direction): + # deny parsing from ( to ) + skip = True + elif (not useflag) and (direction): + # deny parsing from ( to ) + skip = True + else: + # ack parsing from ( to ) + skip = False + + elif source.startswith(")"): + # reset skip + skip = False + + elif (not source.startswith("(")): + if (not skip): + data['sources'].append(source) + + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package mirrors list..."),back = True) + # manage data['sources'] to create data['mirrorlinks'] + # =mirror://openoffice|link1|link2|link3 + data['mirrorlinks'] = [] + for i in data['sources']: + if i.startswith("mirror://"): + # parse what mirror I need + mirrorURI = i.split("/")[2] + mirrorlist = getThirdPartyMirrors(mirrorURI) + data['mirrorlinks'].append([mirrorURI,mirrorlist]) # mirrorURI = openoffice and mirrorlist = [link1, link2, link3] + + + print_info(yellow(" * ")+red(info_package+"Getting source package supported ARCHs..."),back = True) + # fill KEYWORDS + data['keywords'] = [] + try: + f = open(tbz2TmpDir+dbKEYWORDS,"r") + cnt = f.readline().strip().split() + for i in cnt: + if i: + data['keywords'].append(i) + f.close() + except IOError: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package supported ARCHs..."),back = True) + + # fill ARCHs + kwords = data['keywords'] + _kwords = [] + for i in kwords: + if i.startswith("~"): + i = i[1:] + _kwords.append(i) + data['binkeywords'] = [] + for i in etpConst['supportedarchs']: + try: + x = _kwords.index(i) + data['binkeywords'].append(i) + except: + pass + + print_info(yellow(" * ")+red(info_package+"Getting package dependencies..."),back = True) + # Fill dependencies + # to fill dependencies we use *DEPEND files + f = open(tbz2TmpDir+dbRDEPEND,"r") + roughDependencies = f.readline().strip() + f.close() + if (not roughDependencies): + f = open(tbz2TmpDir+dbDEPEND,"r") + roughDependencies = f.readline().strip() + f.close() + f = open(tbz2TmpDir+dbPDEPEND,"r") + roughDependencies += " "+f.readline().strip() + f.close() + roughDependencies = roughDependencies.split() + + # variables filled + # data['dependencies'], data['conflicts'] + deps,conflicts = synthetizeRoughDependencies(roughDependencies,' '.join(PackageFlags)) + data['dependencies'] = [] + for i in deps.split(): + data['dependencies'].append(i) + data['conflicts'] = [] + for i in conflicts.split(): + # check if i == PROVIDE + if i not in data['provide']: # we handle these conflicts using emerge, so we can just filter them out + data['conflicts'].append(i) + + if (kernelDependentModule): + # add kname to the dependency + data['dependencies'].append("=sys-kernel/linux-"+kname+"-"+kver) + + if (kernelItself): + # it's the kernel, add dependency on all tagged packages + try: + data['dependencies'].append("=sys-kernel/linux-"+kname+"-modules-"+kver) + except: + pass + + print_info(yellow(" * ")+red(info_package+"Getting System package List..."),back = True) + # write only if it's a systempackage + data['systempackage'] = '' + systemPackages = getPackagesInSystem() + for x in systemPackages: + x = dep_getkey(x) + y = data['category']+"/"+data['name'] + if x == y: + # found + data['systempackage'] = "xxx" + break + + print_info(yellow(" * ")+red(info_package+"Getting CONFIG_PROTECT/CONFIG_PROTECT_MASK List..."),back = True) + # write only if it's a systempackage + protect, mask = getConfigProtectAndMask() + data['config_protect'] = protect + data['config_protect_mask'] = mask + + # fill data['messages'] + # etpConst['logdir']+"/elog" + if not os.path.isdir(etpConst['logdir']+"/elog"): + os.makedirs(etpConst['logdir']+"/elog") + data['messages'] = [] + if os.path.isdir(etpConst['logdir']+"/elog"): + elogfiles = os.listdir(etpConst['logdir']+"/elog") + myelogfile = data['category']+":"+data['name']+"-"+data['version'] + foundfiles = [] + for file in elogfiles: + if file.startswith(myelogfile): + foundfiles.append(file) + if foundfiles: + elogfile = foundfiles[0] + if len(foundfiles) > 1: + # get the latest + mtimes = [] + for file in foundfiles: + mtimes.append((getFileUnixMtime(etpConst['logdir']+"/elog/"+file),file)) + mtimes.sort() + elogfile = mtimes[len(mtimes)-1][1] + messages = extractElog(etpConst['logdir']+"/elog/"+elogfile) + for message in messages: + out = re.subn("emerge","equo install",message) + message = out[0] + data['messages'].append(message) + else: + print_warning(red(etpConst['logdir']+"/elog")+" not set, have you configured make.conf properly?") + + print_info(yellow(" * ")+red(info_package+"Getting Entropy API version..."),back = True) + # write API info + data['etpapi'] = etpConst['etpapi'] + + # removing temporary directory + os.system("rm -rf "+tbz2TmpDir) + + print_info(yellow(" * ")+red(info_package+"Done"),back = True) + return data \ No newline at end of file diff --git a/libraries/portageTools.py b/libraries/portageTools.py index e411a877e..693021072 100644 --- a/libraries/portageTools.py +++ b/libraries/portageTools.py @@ -32,7 +32,7 @@ import os from entropyConstants import * import portage import portage_const -from portage_dep import isvalidatom, isspecific, isjustname, dep_getkey, dep_getcpv #FIXME: Use the ones from entropyTools +from portage_dep import isvalidatom, isspecific, isjustname, dep_getkey, dep_getcpv from portage_util import grabdict_package from portage_const import USER_CONFIG_PATH diff --git a/libraries/reagentTools.py b/libraries/reagentTools.py index 4f0c718a9..a22ad3d71 100644 --- a/libraries/reagentTools.py +++ b/libraries/reagentTools.py @@ -32,7 +32,6 @@ import re from sys import exit,getfilesystemencoding,path import os import shutil -from portageTools import synthetizeRoughDependencies, getThirdPartyMirrors, getPackagesInSystem, getConfigProtectAndMask # Logging initialization import logTools @@ -54,14 +53,14 @@ def generator(package, dbconnection = None, enzymeRequestBranch = etpConst['bran packagename = os.path.basename(package) print_info(yellow(" * ")+red("Processing: ")+bold(packagename)+red(", please wait...")) - etpData = extractPkgData(package, enzymeRequestBranch) + mydata = extractPkgData(package, enzymeRequestBranch) if dbconnection is None: dbconn = databaseTools.openServerDatabase(readOnly = False, noUpload = True) else: dbconn = dbconnection - idpk, revision, etpDataUpdated, accepted = dbconn.handlePackage(etpData) + idpk, revision, etpDataUpdated, accepted = dbconn.handlePackage(mydata) # add package info to our official repository etpConst['officialrepositoryname'] if (accepted): @@ -303,512 +302,6 @@ def update(options): print_info(green(" * ")+red("Statistics: ")+blue("Entries created/updated: ")+bold(str(etpCreated))+yellow(" - ")+darkblue("Entries discarded: ")+bold(str(etpNotCreated))) -# This function extracts all the info from a .tbz2 file and returns them -def extractPkgData(package, etpBranch = etpConst['branch']): - - reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"extractPkgData: called -> package: "+str(package)) - - info_package = bold(os.path.basename(package))+": " - # Clean the variables - for i in etpData: - etpData[i] = u"" - - print_info(yellow(" * ")+red(info_package+"Getting package name/version..."),back = True) - tbz2File = package - package = package.split(".tbz2")[0] - package = remove_tag(package) - - # FIXME: deprecated - will be removed soonly - if package.split("-")[len(package.split("-"))-1].startswith("t"): - package = '-t'.join(package.split("-t")[:-1]) - - package = package.split("-") - pkgname = "" - pkglen = len(package) - if package[pkglen-1].startswith("r"): - pkgver = package[pkglen-2]+"-"+package[pkglen-1] - pkglen -= 2 - else: - pkgver = package[len(package)-1] - pkglen -= 1 - for i in range(pkglen): - if i == pkglen-1: - pkgname += package[i] - else: - pkgname += package[i]+"-" - pkgname = pkgname.split("/")[len(pkgname.split("/"))-1] - - # Fill Package name and version - etpData['name'] = pkgname - etpData['version'] = pkgver - - print_info(yellow(" * ")+red(info_package+"Getting package md5..."),back = True) - # .tbz2 md5 - etpData['digest'] = md5sum(tbz2File) - - print_info(yellow(" * ")+red(info_package+"Getting package mtime..."),back = True) - # .tbz2 md5 - etpData['datecreation'] = str(getFileUnixMtime(tbz2File)) - - print_info(yellow(" * ")+red(info_package+"Getting package size..."),back = True) - # .tbz2 byte size - etpData['size'] = str(os.stat(tbz2File)[6]) - - print_info(yellow(" * ")+red(info_package+"Unpacking package data..."),back = True) - # unpack file - tbz2TmpDir = etpConst['packagestmpdir']+"/"+etpData['name']+"-"+etpData['version']+"/" - extractXpak(tbz2File,tbz2TmpDir) - - print_info(yellow(" * ")+red(info_package+"Getting package CHOST..."),back = True) - # Fill chost - f = open(tbz2TmpDir+dbCHOST,"r") - etpData['chost'] = f.readline().strip() - f.close() - - print_info(yellow(" * ")+red(info_package+"Setting package branch..."),back = True) - etpData['branch'] = etpBranch - - print_info(yellow(" * ")+red(info_package+"Getting package description..."),back = True) - # Fill description - etpData['description'] = "" - try: - f = open(tbz2TmpDir+dbDESCRIPTION,"r") - etpData['description'] = f.readline().strip() - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package homepage..."),back = True) - # Fill homepage - etpData['homepage'] = "" - try: - f = open(tbz2TmpDir+dbHOMEPAGE,"r") - etpData['homepage'] = f.readline().strip() - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package slot information..."),back = True) - # fill slot, if it is - etpData['slot'] = "" - try: - f = open(tbz2TmpDir+dbSLOT,"r") - etpData['slot'] = f.readline().strip() - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package eclasses information..."),back = True) - # fill eclasses list - etpData['eclasses'] = [] - try: - f = open(tbz2TmpDir+dbINHERITED,"r") - etpData['eclasses'] = f.readline().strip().split() - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package needed libraries information..."),back = True) - # fill needed list - etpData['needed'] = set() - try: - f = open(tbz2TmpDir+dbNEEDED,"r") - lines = f.readlines() - f.close() - for line in lines: - line = line.strip() - if line: - needed = line.split() - if len(needed) == 2: - libs = needed[1].split(",") - for lib in libs: - if (lib.find(".so") != -1): - etpData['needed'].add(lib) - except IOError: - pass - etpData['needed'] = list(etpData['needed']) - - print_info(yellow(" * ")+red(info_package+"Getting package content..."),back = True) - # dbCONTENTS - etpData['content'] = {} - try: - f = open(tbz2TmpDir+dbCONTENTS,"r") - content = f.readlines() - f.close() - outcontent = set() - for line in content: - line = line.strip().split() - try: - datatype = line[0] - datafile = line[1:] - if datatype == 'obj': - datafile = datafile[:-2] - datafile = ' '.join(datafile) - elif datatype == 'dir': - datafile = ' '.join(datafile) - elif datatype == 'sym': - datafile = datafile[:-3] - datafile = ' '.join(datafile) - else: - print "unhandled !!!!!!!",datafile - raise Exception - outcontent.add((datafile,datatype)) - except: - pass - - # convert to plain str() since it's that's used by portage - # when portage will use utf, test utf-8 encoding - _outcontent = set() - for i in outcontent: - datatype = i[1] - datafile = str(i[0]) - _outcontent.add((i[0],i[1])) - outcontent = list(_outcontent) - outcontent.sort() - for i in outcontent: - etpData['content'][str(i[0])] = i[1] - - except IOError: - pass - - # files size on disk - if (etpData['content']): - etpData['disksize'] = 0 - for file in etpData['content']: - try: - size = os.stat(file)[6] - etpData['disksize'] += size - except: - pass - else: - etpData['disksize'] = 0 - - # [][][] Kernel dependent packages hook [][][] - kernelDependentModule = False - kernelItself = False - for file in etpData['content']: - if file.find("/lib/modules/") != -1: - kernelDependentModule = True - # get the version of the modules - kmodver = file.split("/lib/modules/")[1] - kmodver = kmodver.split("/")[0] - - lp = kmodver.split("-")[len(kmodver.split("-"))-1] - if lp.startswith("r"): - kname = kmodver.split("-")[len(kmodver.split("-"))-2] - kver = kmodver.split("-")[0]+"-"+kmodver.split("-")[len(kmodver.split("-"))-1] - else: - kname = kmodver.split("-")[len(kmodver.split("-"))-1] - kver = kmodver.split("-")[0] - break - # validate the results above - if (kernelDependentModule): - matchatom = "linux-"+kname+"-"+kver - if (matchatom == etpData['name']+"-"+etpData['version']): - # discard, it's the kernel itself, add other deps instead - kernelItself = True - kernelDependentModule = False - - # add strict kernel dependency - # done below - - print_info(yellow(" * ")+red(info_package+"Getting package download URL..."),back = True) - # Fill download relative URI - if (kernelDependentModule): - etpData['versiontag'] = kmodver - # force slot == tag: - etpData['slot'] = kmodver - versiontag = "#"+etpData['versiontag'] - else: - versiontag = "" - etpData['download'] = etpConst['binaryurirelativepath']+etpData['branch']+"/"+etpData['name']+"-"+etpData['version']+versiontag+".tbz2" - - print_info(yellow(" * ")+red(info_package+"Getting package counter..."),back = True) - # Fill counter - f = open(tbz2TmpDir+dbCOUNTER,"r") - etpData['counter'] = f.readline().strip() - f.close() - - print_info(yellow(" * ")+red(info_package+"Getting package category..."),back = True) - # Fill category - f = open(tbz2TmpDir+dbCATEGORY,"r") - etpData['category'] = f.readline().strip() - f.close() - - etpData['trigger'] = "" - print_info(yellow(" * ")+red(info_package+"Getting package external trigger availability..."),back = True) - if os.path.isfile(etpConst['triggersdir']+"/"+etpData['category']+"/"+etpData['name']+"/"+etpConst['triggername']): - f = open(etpConst['triggersdir']+"/"+etpData['category']+"/"+etpData['name']+"/"+etpConst['triggername'],"rb") - f.seek(0,2) - size = f.tell() - f.seek(0) - etpData['trigger'] = f.read(size) - f.close() - - print_info(yellow(" * ")+red(info_package+"Getting package CFLAGS..."),back = True) - # Fill CFLAGS - etpData['cflags'] = "" - try: - f = open(tbz2TmpDir+dbCFLAGS,"r") - etpData['cflags'] = f.readline().strip() - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package CXXFLAGS..."),back = True) - # Fill CXXFLAGS - etpData['cxxflags'] = "" - try: - f = open(tbz2TmpDir+dbCXXFLAGS,"r") - etpData['cxxflags'] = f.readline().strip() - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package License information..."),back = True) - # Fill license - etpData['license'] = [] - try: - f = open(tbz2TmpDir+dbLICENSE,"r") - # strip away || ( ) - tmpLic = f.readline().strip().split() - f.close() - for x in tmpLic: - if x: - if (not x.startswith("|")) and (not x.startswith("(")) and (not x.startswith(")")): - etpData['license'].append(x) - etpData['license'] = ' '.join(etpData['license']) - except IOError: - etpData['license'] = "" - pass - - print_info(yellow(" * ")+red(info_package+"Getting package USE flags..."),back = True) - # Fill USE - etpData['useflags'] = [] - f = open(tbz2TmpDir+dbUSE,"r") - tmpUSE = f.readline().strip() - f.close() - - try: - f = open(tbz2TmpDir+dbIUSE,"r") - tmpIUSE = f.readline().strip().split() - f.close() - except IOError: - tmpIUSE = [] - - PackageFlags = [] - for x in tmpUSE.split(): - if (x): - PackageFlags.append(x) - - for i in tmpIUSE: - try: - PackageFlags.index(i) - etpData['useflags'].append(i) - except: - etpData['useflags'].append("-"+i) - - print_info(yellow(" * ")+red(info_package+"Getting package provide content..."),back = True) - # Fill Provide - etpData['provide'] = [] - try: - f = open(tbz2TmpDir+dbPROVIDE,"r") - provide = f.readline().strip() - f.close() - if (provide): - provide = provide.split() - for x in provide: - etpData['provide'].append(x) - except: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package sources information..."),back = True) - # Fill sources - etpData['sources'] = [] - try: - f = open(tbz2TmpDir+dbSRC_URI,"r") - sources = f.readline().strip().split() - f.close() - tmpData = [] - cnt = -1 - skip = False - etpData['sources'] = [] - - for source in sources: - cnt += +1 - if source.endswith("?"): - # it's an use flag - source = source[:len(source)-1] - direction = True - if source.startswith("!"): - direction = False - source = source[1:] - # now get the useflag - useflag = False - try: - etpData['useflags'].index(source) - useflag = True - except: - pass - - - if (useflag) and (direction): # useflag is enabled and it's asking for sources or useflag is not enabled and it's not not (= True) asking for sources - # ack parsing from ( to ) - skip = False - elif (useflag) and (not direction): - # deny parsing from ( to ) - skip = True - elif (not useflag) and (direction): - # deny parsing from ( to ) - skip = True - else: - # ack parsing from ( to ) - skip = False - - elif source.startswith(")"): - # reset skip - skip = False - - elif (not source.startswith("(")): - if (not skip): - etpData['sources'].append(source) - - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package mirrors list..."),back = True) - # manage etpData['sources'] to create etpData['mirrorlinks'] - # =mirror://openoffice|link1|link2|link3 - etpData['mirrorlinks'] = [] - for i in etpData['sources']: - if i.startswith("mirror://"): - # parse what mirror I need - mirrorURI = i.split("/")[2] - mirrorlist = getThirdPartyMirrors(mirrorURI) - etpData['mirrorlinks'].append([mirrorURI,mirrorlist]) # mirrorURI = openoffice and mirrorlist = [link1, link2, link3] - - print_info(yellow(" * ")+red(info_package+"Getting source package supported ARCHs..."),back = True) - # fill KEYWORDS - etpData['keywords'] = [] - try: - f = open(tbz2TmpDir+dbKEYWORDS,"r") - cnt = f.readline().strip().split() - for i in cnt: - if i: - etpData['keywords'].append(i) - f.close() - except IOError: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package supported ARCHs..."),back = True) - - # fill ARCHs - kwords = etpData['keywords'] - _kwords = [] - for i in kwords: - if i.startswith("~"): - i = i[1:] - _kwords.append(i) - etpData['binkeywords'] = [] - for i in etpConst['supportedarchs']: - try: - x = _kwords.index(i) - etpData['binkeywords'].append(i) - except: - pass - - print_info(yellow(" * ")+red(info_package+"Getting package dependencies..."),back = True) - # Fill dependencies - # to fill dependencies we use *DEPEND files - f = open(tbz2TmpDir+dbRDEPEND,"r") - roughDependencies = f.readline().strip() - f.close() - if (not roughDependencies): - f = open(tbz2TmpDir+dbDEPEND,"r") - roughDependencies = f.readline().strip() - f.close() - f = open(tbz2TmpDir+dbPDEPEND,"r") - roughDependencies += " "+f.readline().strip() - f.close() - roughDependencies = roughDependencies.split() - - # variables filled - # etpData['dependencies'], etpData['conflicts'] - deps,conflicts = synthetizeRoughDependencies(roughDependencies,' '.join(PackageFlags)) - etpData['dependencies'] = [] - for i in deps.split(): - etpData['dependencies'].append(i) - etpData['conflicts'] = [] - for i in conflicts.split(): - # check if i == PROVIDE - if i not in etpData['provide']: # we handle these conflicts using emerge, so we can just filter them out - etpData['conflicts'].append(i) - - if (kernelDependentModule): - # add kname to the dependency - etpData['dependencies'].append("=sys-kernel/linux-"+kname+"-"+kver) - - if (kernelItself): - # it's the kernel, add dependency on all tagged packages - try: - etpData['dependencies'].append("=sys-kernel/linux-"+kname+"-modules-"+kver) - except: - pass - - print_info(yellow(" * ")+red(info_package+"Getting System package List..."),back = True) - # write only if it's a systempackage - systemPackages = getPackagesInSystem() - for x in systemPackages: - x = dep_getkey(x) - y = etpData['category']+"/"+etpData['name'] - if x == y: - # found - etpData['systempackage'] = "xxx" - break - - print_info(yellow(" * ")+red(info_package+"Getting CONFIG_PROTECT/CONFIG_PROTECT_MASK List..."),back = True) - # write only if it's a systempackage - protect, mask = getConfigProtectAndMask() - etpData['config_protect'] = protect - etpData['config_protect_mask'] = mask - - # fill etpData['messages'] - # etpConst['logdir']+"/elog" - etpData['messages'] = [] - if os.path.isdir(etpConst['logdir']+"/elog"): - elogfiles = os.listdir(etpConst['logdir']+"/elog") - myelogfile = etpData['category']+":"+etpData['name']+"-"+etpData['version'] - foundfiles = [] - for file in elogfiles: - if file.startswith(myelogfile): - foundfiles.append(file) - if foundfiles: - elogfile = foundfiles[0] - if len(foundfiles) > 1: - # get the latest - mtimes = [] - for file in foundfiles: - mtimes.append((getFileUnixMtime(etpConst['logdir']+"/elog/"+file),file)) - mtimes.sort() - elogfile = mtimes[len(mtimes)-1][1] - messages = extractElog(etpConst['logdir']+"/elog/"+elogfile) - for message in messages: - out = re.subn("emerge","equo install",message) - message = out[0] - etpData['messages'].append(message) - else: - print_warning(red(etpConst['logdir']+"/elog")+" not set, have you configured make.conf properly?") - - print_info(yellow(" * ")+red(info_package+"Getting Entropy API version..."),back = True) - # write API info - etpData['etpapi'] = etpConst['etpapi'] - - # removing temporary directory - os.system("rm -rf "+tbz2TmpDir) - - print_info(yellow(" * ")+red(info_package+"Done"),back = True) - return etpData - def dependsTableInitialize(dbconn = None, runActivator = True): closedb = False @@ -923,7 +416,7 @@ def database(options): currCounter += 1 print_info(darkgreen(" [")+red(mybranch)+darkgreen("] ")+green("(")+ blue(str(currCounter))+"/"+red(str(atomsnumber))+green(") ")+red("Analyzing ")+bold(pkg)+red(" ..."), back = True) - etpData = extractPkgData(etpConst['packagesbindir']+"/"+mybranch+"/"+pkg, mybranch) + mydata = extractPkgData(etpConst['packagesbindir']+"/"+mybranch+"/"+pkg, mybranch) # get previous revision revisionAvail = revisionsMatch.get(os.path.basename(etpData['download'])) addRevision = 0 @@ -931,7 +424,7 @@ def database(options): if mybranch == revisionAvail[0]: addRevision = revisionAvail[1] # fill the db entry - idpk, revision, etpDataUpdated, accepted = dbconn.addPackage(etpData, revision = addRevision) + idpk, revision, etpDataUpdated, accepted = dbconn.addPackage(mydata, revision = addRevision) print_info(darkgreen(" [")+red(mybranch)+darkgreen("] ")+green("(")+ blue(str(currCounter))+"/"+red(str(atomsnumber))+green(") ")+red("Analyzing ")+bold(pkg)+red(". Revision: ")+blue(str(addRevision))) diff --git a/libraries/smartTools.py b/libraries/smartTools.py index 3e0be2cb9..0cf22a5e7 100644 --- a/libraries/smartTools.py +++ b/libraries/smartTools.py @@ -33,12 +33,20 @@ def smart(options): # Options available for all the packages submodules smartRequestEmpty = False + smartRequestSavedir = None + savedir = False newopts = [] for opt in options: if (opt == "--empty"): smartRequestEmpty = True + elif (opt == "--savedir"): + savedir = True else: - newopts.append(opt) + if savedir: + smartRequestSavedir = opt + savedir = False + else: + newopts.append(opt) options = newopts rc = 0 @@ -48,6 +56,8 @@ def smart(options): rc = smartPackagesHandler(options[1:]) elif (options[0] == "quickpkg"): rc = QuickpkgHandler(options[1:]) + elif (options[0] == "inflate") or (options[0] == "deflate"): + rc = CommonFlate(options[1:], action = options[0], savedir = smartRequestSavedir) else: rc = -10 @@ -98,6 +108,78 @@ def QuickpkgHandler(mypackages): print_info(darkgreen(" * ")+red("Saved in: ")+resultfile) return 0 +def CommonFlate(mytbz2s, action, savedir = None): + + if (not mytbz2s): + print_error(darkred(" * ")+red("No packages specified.")) + return 1 + + # test if portage is available + try: + import portageTools + except: + print_error(darkred(" * ")+bold("Portage")+red(" is not available.")) + return 1 + + if savedir: + if not os.path.isdir(savedir): + print_error(darkred(" * ")+bold("--savedir")+red(" specified does not exist.")) + return 1 + else: + savedir = etpConst['packagestmpdir'] + + for tbz2 in mytbz2s: + print_info(brown(" * ")+darkred("Analyzing: ")+tbz2) + if not (os.path.isfile(tbz2) and tbz2.endswith(".tbz2")): + print_error(darkred(" * ")+bold(tbz2)+red(" is not a valid tbz2")) + return 1 + + if action == "inflate": + rc = InflateHandler(mytbz2s, savedir) + elif action == "deflate": + rc = DeflateHandler(mytbz2s, savedir) + else: + rc = -10 + return rc + + +def InflateHandler(mytbz2s, savedir = None): + + print_info(brown(" Using branch: ")+bold(etpConst['branch'])) + + # analyze files + for tbz2 in mytbz2s: + print_info(darkgreen(" * ")+darkred("Inflating: ")+tbz2, back = True) + etptbz2path = savedir+"/"+os.path.basename(tbz2) + if os.path.realpath(tbz2) != os.path.realpath(etptbz2path): # can convert a file without copying + shutil.copy2(tbz2,etptbz2path) + mydata = entropyTools.extractPkgData(etptbz2path) + # append arbitrary revision + mydata['revision'] = 9999 + # create temp database + dbpath = etpConst['packagestmpdir']+"/"+str(entropyTools.getRandomNumber()) + while os.path.isfile(dbpath): + dbpath = etpConst['packagestmpdir']+"/"+str(entropyTools.getRandomNumber()) + # create + mydbconn = openGenericDatabase(dbpath) + mydbconn.initializeDatabase() + mydbconn.addPackage(mydata, revision = mydata['revision']) + mydbconn.closeDB() + entropyTools.aggregateEdb(tbz2file = etptbz2path, dbfile = dbpath) + os.remove(dbpath) + print_info(darkgreen(" * ")+darkred("Inflated package: ")+etptbz2path) + + return 0 + +def DeflateHandler(mytbz2s, savedir = None): + + # analyze files + for tbz2 in mytbz2s: + print_info(darkgreen(" * ")+darkred("Deflating: ")+tbz2, back = True) + newtbz2 = entropyTools.removeEdb(tbz2,savedir) + print_info(darkgreen(" * ")+darkred("Deflated package: ")+newtbz2) + + return 0 def smartPackagesHandler(mypackages):