From 491007bf2f9be94dbfa2764f3a11a3d4536a162b Mon Sep 17 00:00:00 2001
From: "(no author)" <(no author)@cd1c1023-2f26-0410-ae45-c471fc1f0318>
Date: Thu, 14 Feb 2008 17:16:56 +0000
Subject: [PATCH] Spritz: - 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
---
TODO | 1 -
client/text_configuration.py | 101 ++++++------
client/text_query.py | 22 ++-
libraries/entropy.py | 279 +++++++++++++++++++++++++++++++---
libraries/entropyConstants.py | 11 +-
libraries/entropyTools.py | 2 +
libraries/maskingparser.py | 221 ---------------------------
spritz/src/spritz.glade | 4 +
spritz/src/spritz.py | 67 ++++++--
spritz/src/views.py | 28 +++-
10 files changed, 394 insertions(+), 342 deletions(-)
delete mode 100644 libraries/maskingparser.py
diff --git a/TODO b/TODO
index e26ded645..27d8b3265 100644
--- a/TODO
+++ b/TODO
@@ -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) (*)
diff --git a/client/text_configuration.py b/client/text_configuration.py
index 6bc8cb8fa..9293e70c6 100644
--- a/client/text_configuration.py
+++ b/client/text_configuration.py
@@ -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):
diff --git a/client/text_query.py b/client/text_query.py
index b1ca367cc..807c41664 100644
--- a/client/text_query.py
+++ b/client/text_query.py
@@ -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:
diff --git a/libraries/entropy.py b/libraries/entropy.py
index 8ab94761d..b78c589ef 100644
--- a/libraries/entropy.py
+++ b/libraries/entropy.py
@@ -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):
diff --git a/libraries/entropyConstants.py b/libraries/entropyConstants.py
index d9e2aa747..4cb87dc57 100644
--- a/libraries/entropyConstants.py
+++ b/libraries/entropyConstants.py
@@ -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()
diff --git a/libraries/entropyTools.py b/libraries/entropyTools.py
index b8922f0b8..5ac446771 100644
--- a/libraries/entropyTools.py
+++ b/libraries/entropyTools.py
@@ -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()
diff --git a/libraries/maskingparser.py b/libraries/maskingparser.py
deleted file mode 100644
index 967e7fc3a..000000000
--- a/libraries/maskingparser.py
+++ /dev/null
@@ -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)
diff --git a/spritz/src/spritz.glade b/spritz/src/spritz.glade
index c6218ae53..a68860239 100644
--- a/spritz/src/spritz.glade
+++ b/spritz/src/spritz.glade
@@ -2949,6 +2949,7 @@
True
GTK_RELIEF_NORMAL
True
+
@@ -3025,6 +3026,7 @@
True
GTK_RELIEF_NORMAL
True
+
@@ -3085,6 +3087,7 @@
True
GTK_RELIEF_NORMAL
True
+
@@ -3159,6 +3162,7 @@
True
GTK_RELIEF_NORMAL
True
+
diff --git a/spritz/src/spritz.py b/spritz/src/spritz.py
index e2cb3f3b8..d1320c8d6 100644
--- a/spritz/src/spritz.py
+++ b/spritz/src/spritz.py
@@ -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')
diff --git a/spritz/src/views.py b/spritz/src/views.py
index c1754724e..fae6b54c5 100644
--- a/spritz/src/views.py
+++ b/spritz/src/views.py
@@ -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):