- completed configuration files interface
- some misc bug fixes
Entropy:
- moved the package masking parser to entropy.py/EquoInterface
- fixed some issues in equo query orphans and moved some equo conf functions to its EquoInterface class


git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@1212 cd1c1023-2f26-0410-ae45-c471fc1f0318
This commit is contained in:
(no author)
2008-02-14 17:16:56 +00:00
parent 880ec1d214
commit 491007bf2f
10 changed files with 394 additions and 342 deletions
-1
View File
@@ -12,7 +12,6 @@ TODO list:
- find a way to better handle real smartapps deps (need split PDEPEND?)
Spritz:
- handle config files updates interface (*)
- handle multi repos in "available" menu (*)
- add masking interface (*)
- add branch switching menu (for upgrades) (*)
+46 -55
View File
@@ -72,7 +72,7 @@ def update(cmd = None):
while 1:
print_info(brown(" @@ ")+darkgreen("Scanning filesystem..."))
scandata = Equo.FileUpdates.scanfs(dcache = cache_status)
if (cache_status):
if cache_status:
for x in scandata:
print_info("("+blue(str(x))+") "+red(" file: ")+etpConst['systemroot']+scandata[x]['destination'])
cache_status = True
@@ -100,7 +100,8 @@ def update(cmd = None):
# automerge files asking one by one
for key in keys:
if not os.path.isfile(etpConst['systemroot']+scandata[key]['source']):
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
Equo.FileUpdates.remove_from_cache(key)
scandata = Equo.FileUpdates.scandata
continue
print_info(darkred("Configuration file: ")+darkgreen(etpConst['systemroot']+scandata[key]['destination']))
if cmd == -3:
@@ -109,28 +110,19 @@ def update(cmd = None):
continue
print_info(darkred("Moving ")+darkgreen(etpConst['systemroot']+scandata[key]['source'])+darkred(" to ")+brown(etpConst['systemroot']+scandata[key]['destination']))
# old file backup
if etpConst['filesbackup'] and os.path.isfile(etpConst['systemroot']+scandata[key]['destination']):
bcount = 0
backupfile = etpConst['systemroot']+os.path.dirname(scandata[key]['destination'])+"/._equo_backup."+unicode(bcount)+"_"+os.path.basename(scandata[key]['destination'])
while os.path.lexists(backupfile):
bcount += 1
backupfile = etpConst['systemroot']+os.path.dirname(scandata[key]['destination'])+"/._equo_backup."+unicode(bcount)+"_"+os.path.basename(scandata[key]['destination'])
try:
shutil.copy2(etpConst['systemroot']+scandata[key]['destination'],backupfile)
except IOError:
pass
Equo.FileUpdates.merge_file(key)
scandata = Equo.FileUpdates.scandata
shutil.move(etpConst['systemroot']+scandata[key]['source'],etpConst['systemroot']+scandata[key]['destination'])
# remove from cache
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
break
elif cmd in (-7,-9):
for key in keys:
if not os.path.isfile(etpConst['systemroot']+scandata[key]['source']):
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
Equo.FileUpdates.remove_from_cache(key)
scandata = Equo.FileUpdates.scandata
continue
print_info(darkred("Configuration file: ")+darkgreen(etpConst['systemroot']+scandata[key]['destination']))
if cmd == -7:
@@ -138,11 +130,9 @@ def update(cmd = None):
if rc == "No":
continue
print_info(darkred("Discarding ")+darkgreen(etpConst['systemroot']+scandata[key]['source']))
try:
os.remove(etpConst['systemroot']+scandata[key]['source'])
except:
pass
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
Equo.FileUpdates.remove_file(key)
scandata = Equo.FileUpdates.scandata
break
@@ -151,20 +141,27 @@ def update(cmd = None):
# do files exist?
if not os.path.isfile(etpConst['systemroot']+scandata[cmd]['source']):
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
Equo.FileUpdates.remove_from_cache(cmd)
scandata = Equo.FileUpdates.scandata
continue
if not os.path.isfile(etpConst['systemroot']+scandata[cmd]['destination']):
print_info(darkred("Automerging file: ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
shutil.move(etpConst['systemroot']+scandata[key]['source'],etpConst['systemroot']+scandata[key]['destination'])
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
Equo.FileUpdates.merge_file(cmd)
scandata = Equo.FileUpdates.scandata
continue
# end check
diff = showdiff(etpConst['systemroot']+scandata[cmd]['destination'],etpConst['systemroot']+scandata[cmd]['source'])
if (not diff):
print_info(darkred("Automerging file ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
shutil.move(etpConst['systemroot']+scandata[cmd]['source'],etpConst['systemroot']+scandata[cmd]['destination'])
scandata = Equo.FileUpdates.remove_from_cache(scandata,key)
Equo.FileUpdates.merge_file(cmd)
scandata = Equo.FileUpdates.scandata
continue
print_info(darkred("Selected file: ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
@@ -182,37 +179,28 @@ def update(cmd = None):
comeback = True
break
elif action == 1:
print_info(darkred("Replacing ")+darkgreen(etpConst['systemroot']+scandata[cmd]['destination'])+darkred(" with ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
print_info(darkred("Replacing ") + darkgreen(etpConst['systemroot'] + \
scandata[cmd]['destination']) + darkred(" with ") + \
darkgreen(etpConst['systemroot'] + scandata[cmd]['source']))
# old file backup
if etpConst['filesbackup'] and os.path.isfile(etpConst['systemroot']+scandata[cmd]['destination']):
bcount = 0
backupfile = etpConst['systemroot']+os.path.dirname(scandata[cmd]['destination'])+"/._equo_backup."+unicode(bcount)+"_"+os.path.basename(scandata[cmd]['destination'])
while os.path.lexists(backupfile):
bcount += 1
backupfile = etpConst['systemroot']+os.path.dirname(scandata[cmd]['destination'])+"/._equo_backup."+unicode(bcount)+"_"+os.path.basename(scandata[cmd]['destination'])
try:
shutil.copy2(etpConst['systemroot']+scandata[cmd]['destination'],backupfile)
except IOError:
pass
Equo.FileUpdates.merge_file(cmd)
scandata = Equo.FileUpdates.scandata
shutil.move(etpConst['systemroot']+scandata[cmd]['source'],etpConst['systemroot']+scandata[cmd]['destination'])
scandata = Equo.FileUpdates.remove_from_cache(scandata,cmd)
comeback = True
break
elif action == 2:
print_info(darkred("Deleting file ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
try:
os.remove(etpConst['systemroot']+scandata[cmd]['source'])
except:
pass
scandata = Equo.FileUpdates.remove_from_cache(scandata,cmd)
print_info(darkred("Deleting file ") + darkgreen(etpConst['systemroot'] + scandata[cmd]['source']))
Equo.FileUpdates.remove_file(cmd)
scandata = Equo.FileUpdates.scandata
comeback = True
break
elif action == 3:
print_info(darkred("Editing file ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
print_info(darkred("Editing file ") + darkgreen(etpConst['systemroot']+scandata[cmd]['source']))
if os.getenv("EDITOR"):
os.system("$EDITOR "+etpConst['systemroot']+scandata[cmd]['source'])
elif os.access("/bin/nano",os.X_OK):
@@ -229,12 +217,15 @@ def update(cmd = None):
print_error(" Cannot find a suitable editor. Can't edit file directly.")
comeback = True
break
print_info(darkred("Edited file ")+darkgreen(etpConst['systemroot']+scandata[cmd]['source'])+darkred(" - showing differencies:"))
diff = showdiff(etpConst['systemroot']+scandata[cmd]['destination'],etpConst['systemroot']+scandata[cmd]['source'])
if (not diff):
print_info(darkred("Automerging file ")+darkgreen(scandata[cmd]['source']))
shutil.move(etpConst['systemroot']+scandata[cmd]['source'],etpConst['systemroot']+scandata[cmd]['destination'])
scandata = Equo.FileUpdates.remove_from_cache(scandata, cmd)
print_info(darkred("Edited file ") + darkgreen(etpConst['systemroot'] + scandata[cmd]['source']) + darkred(" - showing differencies:"))
diff = showdiff(etpConst['systemroot'] + scandata[cmd]['destination'],etpConst['systemroot'] + scandata[cmd]['source'])
if not diff:
print_info(darkred("Automerging file ") + darkgreen(scandata[cmd]['source']))
Equo.FileUpdates.merge_file(cmd)
scandata = Equo.FileUpdates.scandata
comeback = True
break
@@ -242,7 +233,7 @@ def update(cmd = None):
elif action == 4:
# show diffs again
diff = showdiff(etpConst['systemroot']+scandata[cmd]['destination'],etpConst['systemroot']+scandata[cmd]['source'])
diff = showdiff(etpConst['systemroot'] + scandata[cmd]['destination'], etpConst['systemroot'] + scandata[cmd]['source'])
continue
if (comeback):
+10 -12
View File
@@ -394,13 +394,14 @@ def searchOrphans():
for currentdir,subdirs,files in os.walk(xdir):
for filename in files:
# filter python compiled objects?
if filename.endswith(".pyo") or filename.startswith(".pyc") or filename == '.keep':
if filename.endswith(".pyo") or filename.endswith(".pyc") or filename == '.keep':
continue
mask = [x for x in etpConst['filesystemdirsmask'] if x.startswith(x)]
if (not mask):
filename = os.path.join(currentdir,filename)
mask = [x for x in etpConst['filesystemdirsmask'] if filename.startswith(x)]
if not mask:
if (not etpUi['quiet']):
print_info(red(" @@ ")+blue("Looking: ")+bold(file[:50]+"..."), back = True)
foundFiles.add(file)
print_info(red(" @@ ")+blue("Looking: ")+bold(filename[:50]+"..."), back = True)
foundFiles.add(filename)
totalfiles = len(foundFiles)
if (not etpUi['quiet']):
print_info(red(" @@ ")+blue("Analyzed directories: ")+' '.join(etpConst['filesystemdirs']))
@@ -419,15 +420,12 @@ def searchOrphans():
atom = clientDbconn.retrieveAtom(idpackage)
txt = "["+str(count)+"/"+length+"] "
print_info(red(" @@ ")+blue("Intersecting content of package: ")+txt+bold(atom), back = True)
content = clientDbconn.retrieveContent(idpackage)
_content = set()
for x in content:
for x in clientDbconn.retrieveContent(idpackage):
if x.startswith("/usr/lib64"):
x = "/usr/lib"+x[len("/usr/lib64"):]
_content.add(x)
content.add(x)
# remove from foundFiles
del content
foundFiles.difference_update(_content)
foundFiles -= content
if (not etpUi['quiet']):
print_info(red(" @@ ")+blue("Intersection completed. Showing statistics: "))
print_info(red(" @@ ")+blue("Number of total files: ")+bold(str(totalfiles)))
@@ -437,7 +435,7 @@ def searchOrphans():
# order
foundFiles = list(foundFiles)
foundFiles.sort()
if (not etpUi['quiet']):
if not etpUi['quiet']:
print_info(red(" @@ ")+blue("Writing file to disk: ")+bold("/tmp/equo-orphans.txt"))
f = open("/tmp/equo-orphans.txt","w")
for x in foundFiles:
+259 -20
View File
@@ -90,9 +90,12 @@ class EquoInterface(TextInterface):
self.xcache = xcache
if self.openclientdb:
self.openClientDatabase()
self.FileUpdates = self.__FileUpdates()
self.FileUpdates = self.FileUpdatesInterfaceLoader()
self.repoDbCache = {}
# masking parser
self.MaskingParser = self.PackageMaskingParserInterfaceLoader()
# are we running on a livecd? (/proc/cmdline has "cdroot")
if self.entropyTools.islive():
self.xcache = False
@@ -179,6 +182,14 @@ class EquoInterface(TextInterface):
NOTE: DO NOT USE THIS DIRECTLY, BUT USE EquoInterface.openRepositoryDatabase
'''
def loadRepositoryDatabase(self, repositoryName, xcache = True, indexing = True):
# load the masking parser
if etpConst['packagemasking'] == None:
etpConst['packagemasking'] = self.MaskingParser.parse()
# merge universal keywords
for x in etpConst['packagemasking']['keywords']['universal']:
etpConst['keywords'].add(x)
if repositoryName.endswith(".tbz2"):
xcache = False
dbfile = etpRepositories[repositoryName]['dbpath']+"/"+etpConst['etpdatabasefile']
@@ -2039,13 +2050,17 @@ class EquoInterface(TextInterface):
'''
Configuration files (updates, not entropy related) interface :: begin
'''
def __FileUpdates(self):
def FileUpdatesInterfaceLoader(self):
conn = FileUpdatesInterface(EquoInstance = self)
return conn
'''
Configuration files (updates, not entropy related) interface :: end
'''
def PackageMaskingParserInterfaceLoader(self):
conn = PackageMaskingParser(EquoInstance = self)
return conn
'''
Real package actions (install/remove) interface
'''
@@ -3353,17 +3368,51 @@ class FileUpdatesInterface:
except:
raise exceptionTools.IncorrectParameter("IncorrectParameter: a valid Entropy Instance is needed")
self.scandata = None
def merge_file(self, key):
self.scanfs(dcache = True)
self.do_backup(key)
shutil.move(etpConst['systemroot'] + self.scandata[key]['source'], etpConst['systemroot'] + self.scandata[key]['destination'])
self.remove_from_cache(key)
def remove_file(self, key):
self.scanfs(dcache = True)
try:
os.remove(etpConst['systemroot'] + self.scandata[key]['source'])
except OSError:
pass
self.remove_from_cache(key)
def do_backup(self, key):
self.scanfs(dcache = True)
if etpConst['filesbackup'] and os.path.isfile(etpConst['systemroot']+self.scandata[key]['destination']):
bcount = 0
backupfile = etpConst['systemroot'] + os.path.dirname(self.scandata[key]['destination']) + "/._equo_backup." + unicode(bcount) + "_" + os.path.basename(self.scandata[key]['destination'])
while os.path.lexists(backupfile):
bcount += 1
backupfile = etpConst['systemroot'] + os.path.dirname(self.scandata[key]['destination']) + "/._equo_backup." + unicode(bcount) + "_" + os.path.basename(self.scandata[key]['destination'])
try:
shutil.copy2(etpConst['systemroot'] + self.scandata[key]['destination'],backupfile)
except IOError:
pass
'''
@description: scan for files that need to be merged
@output: dictionary using filename as key
'''
def scanfs(self, dcache = True):
if (dcache):
if dcache:
if self.scandata != None:
return self.scandata
# can we load cache?
try:
z = self.load_cache()
if z != None:
self.scandata = z.copy()
return z
except:
pass
@@ -3432,6 +3481,7 @@ class FileUpdatesInterface:
self.Entropy.dumpTools.dumpobj(etpCache['configfiles'],scandata)
except IOError:
pass
self.scandata = scandata.copy()
return scandata
def load_cache(self):
@@ -3462,15 +3512,12 @@ class FileUpdatesInterface:
@attention: please be sure that filepath is properly formatted before using this function
'''
def add_to_cache(self, filepath):
try:
scandata = self.load_cache()
except:
scandata = self.scanfs(dcache = False)
keys = scandata.keys()
self.scanfs(dcache = True)
keys = self.scandata.keys()
try:
for key in keys:
if scandata[key]['source'] == filepath[len(etpConst['systemroot']):]:
del scandata[key]
if self.scandata[key]['source'] == filepath[len(etpConst['systemroot']):]:
del self.scandata[key]
except:
pass
# get next counter
@@ -3481,19 +3528,17 @@ class FileUpdatesInterface:
index = 0
index += 1
mydata = self.generate_dict(filepath)
scandata[index] = mydata.copy()
try:
self.Entropy.dumpTools.dumpobj(etpCache['configfiles'],scandata)
except IOError:
pass
self.scandata[index] = mydata.copy()
self.Entropy.dumpTools.dumpobj(etpCache['configfiles'],self.scandata)
def remove_from_cache(self, sd, key):
def remove_from_cache(self, key):
self.scanfs(dcache = True)
try:
del sd[key]
del self.scandata[key]
except:
pass
self.Entropy.dumpTools.dumpobj(etpCache['configfiles'],sd)
return sd
self.Entropy.dumpTools.dumpobj(etpCache['configfiles'],self.scandata)
return self.scandata
def generate_dict(self, filepath):
@@ -5520,6 +5565,7 @@ class TriggerInterface:
def trigger_ebuild_postinstall(self):
stdfile = open("/dev/null","w")
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stderr = stdfile
myebuild = [self.pkgdata['xpakdir']+"/"+x for x in os.listdir(self.pkgdata['xpakdir']) if x.endswith(".ebuild")]
@@ -5532,10 +5578,13 @@ class TriggerInterface:
header = red(" ##")
)
try:
if not os.path.isfile(self.pkgdata['unpackdir']+"/portage/"+portage_atom+"/temp/environment"): # if environment is not yet created, we need to run pkg_setup()
if not os.path.isfile(self.pkgdata['unpackdir']+"/portage/"+portage_atom+"/temp/environment"):
# if environment is not yet created, we need to run pkg_setup()
sys.stdout = stdfile
rc = self.portageTools.portage_doebuild(myebuild, mydo = "setup", tree = "bintree", cpv = portage_atom, portage_tmpdir = self.pkgdata['unpackdir'])
if rc == 1:
self.Entropy.equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"[POST] ATTENTION Cannot properly run Gentoo postinstall (pkg_setup()) trigger for "+str(portage_atom)+". Something bad happened.")
sys.stdout = oldstdout
rc = self.portageTools.portage_doebuild(myebuild, mydo = "postinst", tree = "bintree", cpv = portage_atom, portage_tmpdir = self.pkgdata['unpackdir'])
if rc == 1:
self.Entropy.equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"[POST] ATTENTION Cannot properly run Gentoo postinstall (pkg_postinst()) trigger for "+str(portage_atom)+". Something bad happened.")
@@ -5553,6 +5602,7 @@ class TriggerInterface:
def trigger_ebuild_preinstall(self):
stdfile = open("/dev/null","w")
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stderr = stdfile
myebuild = [self.pkgdata['xpakdir']+"/"+x for x in os.listdir(self.pkgdata['xpakdir']) if x.endswith(".ebuild")]
@@ -5565,9 +5615,11 @@ class TriggerInterface:
header = red(" ##")
)
try:
sys.stdout = stdfile
rc = self.portageTools.portage_doebuild(myebuild, mydo = "setup", tree = "bintree", cpv = portage_atom, portage_tmpdir = self.pkgdata['unpackdir']) # create mysettings["T"]+"/environment"
if rc == 1:
self.Entropy.equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"[PRE] ATTENTION Cannot properly run Gentoo preinstall (pkg_setup()) trigger for "+str(portage_atom)+". Something bad happened.")
sys.stdout = oldstdout
rc = self.portageTools.portage_doebuild(myebuild, mydo = "preinst", tree = "bintree", cpv = portage_atom, portage_tmpdir = self.pkgdata['unpackdir'])
if rc == 1:
self.Entropy.equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"[PRE] ATTENTION Cannot properly run Gentoo preinstall (pkg_preinst()) trigger for "+str(portage_atom)+". Something bad happened.")
@@ -6044,6 +6096,193 @@ timeout=10
)
return "(hd0,0)"
class PackageMaskingParser:
def __init__(self, EquoInstance):
self.Entropy = EquoInstance
try:
self.Entropy.instanceTest()
except:
raise exceptionTools.IncorrectParameter("IncorrectParameter: a valid Entropy Instance is needed")
def parse(self):
self.etpMaskFiles = {
'keywords': etpConst['confdir']+"/packages/package.keywords", # keywording configuration files
'unmask': etpConst['confdir']+"/packages/package.unmask", # unmasking configuration files
'mask': etpConst['confdir']+"/packages/package.mask", # masking configuration files
}
self.etpMtimeFiles = {
'keywords_mtime': etpConst['dumpstoragedir']+"/keywords.mtime", # keywording configuration files mtime
'unmask_mtime': etpConst['dumpstoragedir']+"/unmask.mtime", # unmasking configuration files mtime
'mask_mtime': etpConst['dumpstoragedir']+"/mask.mtime", # masking configuration files mtime
}
data = {}
for item in self.etpMaskFiles:
data[item] = eval('self.'+item+'_parser')()
return data
'''
parser of package.keywords file
'''
def keywords_parser(self):
self.__validateEntropyCache(self.etpMaskFiles['keywords'],self.etpMtimeFiles['keywords_mtime'])
data = {
'universal': set(),
'packages': {},
'repositories': {},
}
if os.path.isfile(self.etpMaskFiles['keywords']):
f = open(self.etpMaskFiles['keywords'],"r")
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
keywordinfo = line.split()
# skip wrong lines
if len(keywordinfo) > 3:
sys.stderr.write(">> "+line+" << is invalid!!")
continue
if len(keywordinfo) == 1: # inversal keywording, check if it's not repo=
# repo=?
if keywordinfo[0].startswith("repo="):
sys.stderr.write(">> "+line+" << is invalid!!")
continue
# atom? is it worth it? it would take a little bit to parse uhm... >50 entries...!?
#kinfo = keywordinfo[0]
if keywordinfo[0] == "**": keywordinfo[0] = "" # convert into entropy format
data['universal'].add(keywordinfo[0])
continue # needed?
if len(keywordinfo) in (2,3): # inversal keywording, check if it's not repo=
# repo=?
if keywordinfo[0].startswith("repo="):
sys.stderr.write(">> "+line+" << is invalid!!")
continue
# add to repo?
items = keywordinfo[1:]
if keywordinfo[0] == "**": keywordinfo[0] = "" # convert into entropy format
reponame = [x for x in items if x.startswith("repo=") and (len(x.split("=")) == 2)]
if reponame:
reponame = reponame[0].split("=")[1]
if reponame not in data['repositories']:
data['repositories'][reponame] = {}
# repository unmask or package in repository unmask?
if keywordinfo[0] not in data['repositories'][reponame]:
data['repositories'][reponame][keywordinfo[0]] = set()
if len(items) == 1:
# repository unmask
data['repositories'][reponame][keywordinfo[0]].add('*')
else:
if "*" not in data['repositories'][reponame][keywordinfo[0]]:
item = [x for x in items if not x.startswith("repo=")]
data['repositories'][reponame][keywordinfo[0]].add(item[0])
else:
# it's going to be a faulty line!!??
if len(items) == 2: # can't have two items and no repo=
sys.stderr.write(">> "+line+" << is invalid!!")
continue
# add keyword to packages
if keywordinfo[0] not in data['packages']:
data['packages'][keywordinfo[0]] = set()
data['packages'][keywordinfo[0]].add(items[0])
return data
def unmask_parser(self):
self.__validateEntropyCache(self.etpMaskFiles['unmask'],self.etpMtimeFiles['unmask_mtime'])
data = set()
if os.path.isfile(self.etpMaskFiles['unmask']):
f = open(self.etpMaskFiles['unmask'],"r")
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
# FIXME: need validation? probably not since atomMatch handles it all
# and doesn't care about badly formatted atoms
data.add(line)
return data
def mask_parser(self):
self.__validateEntropyCache(self.etpMaskFiles['mask'],self.etpMtimeFiles['mask_mtime'])
data = set()
if os.path.isfile(self.etpMaskFiles['mask']):
f = open(self.etpMaskFiles['mask'],"r")
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
# FIXME: need validation? probably not since atomMatch handles it all
# and doesn't care about badly formatted atoms
data.add(line)
return data
'''
internal functions
'''
def __removeRepoCache(self):
if os.path.isdir(etpConst['dumpstoragedir']):
for repoid in etpRepositoriesOrder:
self.Entropy.repository_move_clear_cache(repoid)
else:
os.makedirs(etpConst['dumpstoragedir'])
def __saveFileMtime(self,toread,tosaveinto):
if not os.path.isfile(toread):
currmtime = 0.0
else:
currmtime = os.path.getmtime(toread)
if not os.path.isdir(etpConst['dumpstoragedir']):
os.makedirs(etpConst['dumpstoragedir'])
f = open(tosaveinto,"w")
f.write(str(currmtime))
f.flush()
f.close()
def __validateEntropyCache(self,maskfile,mtimefile):
if os.getuid() != 0: # can't validate if running as user, thus cache shouldn't be loaded either
return
# handle on-disk cache validation
# in this case, repositories cache
# if package.keywords is changed, we must destroy cache
if not os.path.isfile(mtimefile):
# we can't know if package.keywords has been updated
# remove repositories caches
self.__removeRepoCache()
self.__saveFileMtime(maskfile,mtimefile)
else:
# check mtime
try:
f = open(mtimefile,"r")
mtime = float(f.readline().strip())
# compare with current mtime
try:
currmtime = os.path.getmtime(maskfile)
except OSError:
currmtime = 0.0
if mtime != currmtime:
self.__removeRepoCache()
self.__saveFileMtime(maskfile,mtimefile)
except:
self.__removeRepoCache()
self.__saveFileMtime(maskfile,mtimefile)
class Callable:
def __init__(self, anycallable):
+1 -10
View File
@@ -26,7 +26,6 @@ import gc
import sys
import os
import stat
import maskingparser
import exceptionTools
@@ -626,7 +625,7 @@ def initConfig_entropyConstants(rootdir):
'securityurl': "http://packages.sabayonlinux.org/security/security-advisories.tar.bz2",
# packages keywords/mask/unmask settings
'packagemasking': {}, # package masking information dictionary filled by maskingparser.py
'packagemasking': None, # package masking information dictionary filled by the masking parser
# packages whose need their other installs (different tag), to be removed
'conflicting_tagged_packages': {
@@ -887,14 +886,6 @@ def initConfig_entropyConstants(rootdir):
url += etpConst['product']+"/handlers/"
etpRemoteSupport[servername] = url
# generate masking dictionary
myparser = maskingparser.parser(etpConst,etpCache)
etpConst['packagemasking'] = myparser.parse()
# merge universal keywords
for x in etpConst['packagemasking']['keywords']['universal']:
etpConst['keywords'].add(x)
del myparser
gc.collect()
initConfig_clientConstants()
+2
View File
@@ -148,6 +148,8 @@ def get_remote_data(url):
return False
def islive():
if not os.path.isfile("/proc/cmdline"):
return False
f = open("/proc/cmdline")
cmdline = f.readline().strip().split()
f.close()
-221
View File
@@ -1,221 +0,0 @@
#!/usr/bin/python
'''
# DESCRIPTION:
# Parser of /etc/entropy/packages/* files
Copyright (C) 2007-2008 Fabio Erculiani
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import os
'''
This function parses files in etpMaskFiles and returns collected data to caller (dict)
'''
class parser:
def __init__(self,etpConst,etpCache):
self.etpConst = etpConst
self.etpCache = etpCache
def parse(self):
self.etpMaskFiles = {
'keywords': self.etpConst['confdir']+"/packages/package.keywords", # keywording configuration files
'unmask': self.etpConst['confdir']+"/packages/package.unmask", # unmasking configuration files
'mask': self.etpConst['confdir']+"/packages/package.mask", # masking configuration files
}
self.etpMtimeFiles = {
'keywords_mtime': self.etpConst['dumpstoragedir']+"/keywords.mtime", # keywording configuration files mtime
'unmask_mtime': self.etpConst['dumpstoragedir']+"/unmask.mtime", # unmasking configuration files mtime
'mask_mtime': self.etpConst['dumpstoragedir']+"/mask.mtime", # masking configuration files mtime
}
data = {}
for item in self.etpMaskFiles:
data[item] = eval('self.'+item+'_parser')()
return data
'''
parser of package.keywords file
'''
def keywords_parser(self):
self.__validateEntropyCache(self.etpMaskFiles['keywords'],self.etpMtimeFiles['keywords_mtime'])
data = {
'universal': set(),
'packages': {},
'repositories': {},
}
if os.path.isfile(self.etpMaskFiles['keywords']):
f = open(self.etpMaskFiles['keywords'],"r")
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
keywordinfo = line.split()
# skip wrong lines
if len(keywordinfo) > 3:
print ">> "+line+" << is invalid!!"
continue
if len(keywordinfo) == 1: # inversal keywording, check if it's not repo=
# repo=?
if keywordinfo[0].startswith("repo="):
print ">> "+line+" << is invalid!!"
continue
# atom? is it worth it? it would take a little bit to parse uhm... >50 entries...!?
#kinfo = keywordinfo[0]
if keywordinfo[0] == "**": keywordinfo[0] = "" # convert into entropy format
data['universal'].add(keywordinfo[0])
continue # needed?
if len(keywordinfo) in (2,3): # inversal keywording, check if it's not repo=
# repo=?
if keywordinfo[0].startswith("repo="):
print ">> "+line+" << is invalid!!"
continue
# add to repo?
items = keywordinfo[1:]
if keywordinfo[0] == "**": keywordinfo[0] = "" # convert into entropy format
reponame = [x for x in items if x.startswith("repo=") and (len(x.split("=")) == 2)]
if reponame:
reponame = reponame[0].split("=")[1]
if reponame not in data['repositories']:
data['repositories'][reponame] = {}
# repository unmask or package in repository unmask?
if keywordinfo[0] not in data['repositories'][reponame]:
data['repositories'][reponame][keywordinfo[0]] = set()
if len(items) == 1:
# repository unmask
data['repositories'][reponame][keywordinfo[0]].add('*')
else:
if "*" not in data['repositories'][reponame][keywordinfo[0]]:
item = [x for x in items if not x.startswith("repo=")]
data['repositories'][reponame][keywordinfo[0]].add(item[0])
else:
# it's going to be a faulty line!!??
if len(items) == 2: # can't have two items and no repo=
print ">> "+line+" << is invalid!!"
continue
# add keyword to packages
if keywordinfo[0] not in data['packages']:
data['packages'][keywordinfo[0]] = set()
data['packages'][keywordinfo[0]].add(items[0])
return data
def unmask_parser(self):
self.__validateEntropyCache(self.etpMaskFiles['unmask'],self.etpMtimeFiles['unmask_mtime'])
data = set()
if os.path.isfile(self.etpMaskFiles['unmask']):
f = open(self.etpMaskFiles['unmask'],"r")
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
# FIXME: need validation? probably not since atomMatch handles it all
# and doesn't care about badly formatted atoms
data.add(line)
return data
def mask_parser(self):
self.__validateEntropyCache(self.etpMaskFiles['mask'],self.etpMtimeFiles['mask_mtime'])
data = set()
if os.path.isfile(self.etpMaskFiles['mask']):
f = open(self.etpMaskFiles['mask'],"r")
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
# FIXME: need validation? probably not since atomMatch handles it all
# and doesn't care about badly formatted atoms
data.add(line)
return data
'''
internal functions
'''
def __removeRepoCache(self):
if os.path.isdir(self.etpConst['dumpstoragedir']):
content = os.listdir(self.etpConst['dumpstoragedir'])
for item in content:
if item.startswith(self.etpCache['dbMatch']+self.etpConst['dbnamerepoprefix']) and item.endswith(".dmp"):
os.remove(self.etpConst['dumpstoragedir']+"/"+item)
elif item.startswith(self.etpCache['atomMatch']) and item.endswith(".dmp"):
os.remove(self.etpConst['dumpstoragedir']+"/"+item)
elif item.startswith(self.etpCache['world_update']) and item.endswith(".dmp"):
os.remove(self.etpConst['dumpstoragedir']+"/"+item)
elif item.startswith(self.etpCache['world_available']) and item.endswith(".dmp"):
os.remove(self.etpConst['dumpstoragedir']+"/"+item)
elif item.startswith(self.etpCache['check_package_update']) and item.endswith(".dmp"):
os.remove(self.etpConst['dumpstoragedir']+"/"+item)
else:
os.makedirs(self.etpConst['dumpstoragedir'])
def __saveFileMtime(self,toread,tosaveinto):
if not os.path.isfile(toread):
currmtime = 0.0
else:
currmtime = os.path.getmtime(toread)
if not os.path.isdir(self.etpConst['dumpstoragedir']):
os.makedirs(self.etpConst['dumpstoragedir'])
f = open(tosaveinto,"w")
f.write(str(currmtime))
f.flush()
f.close()
def __validateEntropyCache(self,maskfile,mtimefile):
if os.getuid() != 0: # can't validate if running as user, thus cache shouldn't be loaded either
return
# handle on-disk cache validation
# in this case, repositories cache
# if package.keywords is changed, we must destroy cache
if not os.path.isfile(mtimefile):
# we can't know if package.keywords has been updated
# remove repositories caches
self.__removeRepoCache()
self.__saveFileMtime(maskfile,mtimefile)
else:
# check mtime
try:
f = open(mtimefile,"r")
mtime = float(f.readline().strip())
# compare with current mtime
try:
currmtime = os.path.getmtime(maskfile)
except OSError:
currmtime = 0.0
if mtime != currmtime:
self.__removeRepoCache()
self.__saveFileMtime(maskfile,mtimefile)
except:
self.__removeRepoCache()
self.__saveFileMtime(maskfile,mtimefile)
+4
View File
@@ -2949,6 +2949,7 @@
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_filesMerge_clicked" last_modification_time="Thu, 14 Feb 2008 14:17:08 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment84">
@@ -3025,6 +3026,7 @@
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_filesDelete_clicked" last_modification_time="Thu, 14 Feb 2008 14:17:16 GMT"/>
</widget>
</child>
</widget>
@@ -3085,6 +3087,7 @@
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_deleteFiles_clicked" last_modification_time="Thu, 14 Feb 2008 15:16:21 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment86">
@@ -3159,6 +3162,7 @@
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_mergeFiles_clicked" last_modification_time="Thu, 14 Feb 2008 15:16:28 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment87">
+52 -15
View File
@@ -110,7 +110,7 @@ class SpritzController(Controller):
task.start()
def __runEditor(self, data):
os.system(data['cmd'])
os.system(data['cmd']+"&> /dev/null")
delete = data['delete']
if delete and os.path.isfile(data['file']):
try:
@@ -122,22 +122,52 @@ class SpritzController(Controller):
selection = self.filesView.view.get_selection()
model, iterator = selection.get_selected()
if model != None and iterator != None:
destination = model.get_value( iterator, 1 )
source = model.get_value( iterator, 0 )
identifier = model.get_value( iterator, 0 )
destination = model.get_value( iterator, 2 )
source = model.get_value( iterator, 1 )
source = os.path.join(os.path.dirname(destination),source)
return source, destination
return None,None
return identifier, source, destination
return 0,None,None
def on_filesDelete_clicked( self, widget ):
identifier, source, dest = self.__get_Edit_filename()
if not identifier:
return True
self.Equo.FileUpdates.remove_file(identifier)
self.filesView.populate(self.Equo.FileUpdates.scandata)
def on_filesMerge_clicked( self, widget ):
identifier, source, dest = self.__get_Edit_filename()
if not identifier:
return True
self.Equo.FileUpdates.merge_file(identifier)
self.filesView.populate(self.Equo.FileUpdates.scandata)
def on_mergeFiles_clicked( self, widget ):
self.Equo.FileUpdates.scanfs(dcache = True)
keys = self.Equo.FileUpdates.scandata.keys()
for key in keys:
self.Equo.FileUpdates.merge_file(key)
# it's cool watching it runtime
self.filesView.populate(self.Equo.FileUpdates.scandata)
def on_deleteFiles_clicked( self, widget ):
self.Equo.FileUpdates.scanfs(dcache = True)
keys = self.Equo.FileUpdates.scandata.keys()
for key in keys:
self.Equo.FileUpdates.remove_file(key)
# it's cool watching it runtime
self.filesView.populate(self.Equo.FileUpdates.scandata)
def on_filesEdit_clicked( self, widget ):
source, dest = self.__get_Edit_filename()
if source == None:
identifier, source, dest = self.__get_Edit_filename()
if not identifier:
return True
self.runEditor(source)
def on_filesViewChanges_clicked( self, widget ):
source, dest = self.__get_Edit_filename()
if source == None:
identifier, source, dest = self.__get_Edit_filename()
if not identifier:
return True
randomfile = self.Equo.entropyTools.getRandomTempFile()+".diff"
diffcmd = "diff -Nu "+dest+" "+source+" > "+randomfile
@@ -681,18 +711,25 @@ class SpritzApplication(SpritzController,SpritzGUI):
def setupEditor(self):
paths = self.Equo.entropyTools.collectLinkerPaths()
pathenv = os.getenv("PATH")
for path in paths:
pathenv += ":"+path
if os.path.isfile("/etc/profile.env"):
f = open("/etc/profile.env")
env_file = f.readlines()
for line in env_file:
line = line.strip()
if line.startswith("export PATH='"):
line = line[len("export PATH='"):]
line = line.rstrip("'")
for path in line.split(":"):
pathenv += ":"+path
break
os.environ['PATH'] = pathenv
self.fileEditor = '/usr/bin/xterm -e $EDITOR'
de_session = os.getenv('DESKTOP_SESSION')
path = os.getenv('PATH').split(":")
# FIXME: disabled for now because it needs a properly configured environment
#if os.access("/usr/bin/xdg-open",os.X_OK):
# self.fileEditor = "/usr/bin/xdg-open"
if os.access("/usr/bin/xdg-open",os.X_OK):
self.fileEditor = "/usr/bin/xdg-open"
if de_session.find("kde") != -1:
for item in path:
itempath = os.path.join(item,'kwrite')
+20 -8
View File
@@ -575,31 +575,37 @@ class EntropyFilesView:
def setup_view( self ):
""" Create Notebook list for single page """
model = gtk.TreeStore( gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING )
model = gtk.TreeStore( gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING )
self.view.set_model( model )
cell0 = gtk.CellRendererText()
column0 = gtk.TreeViewColumn( "", cell0, markup = 0 )
column0.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column0.set_fixed_width( 2 )
self.view.append_column( column0 )
cell1 = gtk.CellRendererText()
column1 = gtk.TreeViewColumn( _( "Proposed" ), cell1, markup = 0 )
column1 = gtk.TreeViewColumn( _( "Proposed" ), cell1, markup = 1 )
column1.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column1.set_fixed_width( 220 )
column1.set_fixed_width( 250 )
column1.set_resizable( True )
self.view.append_column( column1 )
cell2 = gtk.CellRendererText()
column2 = gtk.TreeViewColumn( _( "Destination" ), cell2, markup = 1 )
column2 = gtk.TreeViewColumn( _( "Destination" ), cell2, markup = 2 )
column2.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column2.set_fixed_width( 330 )
column2.set_fixed_width( 300 )
column2.set_resizable( True )
self.view.append_column( column2 )
cell3 = gtk.CellRendererText()
column3 = gtk.TreeViewColumn( _( "Rev." ), cell3, text=2 )
column3 = gtk.TreeViewColumn( _( "Rev." ), cell3, text=3 )
column3.set_resizable( True )
column3.set_sizing( gtk.TREE_VIEW_COLUMN_FIXED )
column3.set_fixed_width( 30 )
self.view.append_column( column3 )
model.set_sort_column_id( 0, gtk.SORT_ASCENDING )
#self.view.get_selection().set_mode( gtk.SELECTION_MULTIPLE )
self.view.get_selection().set_mode( gtk.SELECTION_SINGLE )
return model
def populate( self, scandata ):
@@ -607,7 +613,13 @@ class EntropyFilesView:
keys = scandata.keys()
keys.sort()
for key in keys:
self.model.append(None,[os.path.basename(scandata[key]['source']),scandata[key]['destination'],scandata[key]['revision']])
self.model.append(None,[
key,
os.path.basename(scandata[key]['source']),
scandata[key]['destination'],
scandata[key]['revision']
]
)
class CategoriesView:
def __init__( self, treeview,qview):