From 342c72d41ceb27fb77561a156af838d4e6a7d25d Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@cd1c1023-2f26-0410-ae45-c471fc1f0318> Date: Wed, 20 Feb 2008 16:17:07 +0000 Subject: [PATCH] - added license.mask (not working yet) - added license accept request menu - moved some functions to EquoInterface - added some functions to handle licenses in the database API - allow user to accept a license forever git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@1262 cd1c1023-2f26-0410-ae45-c471fc1f0318 --- TODO | 9 ++-- client/text_configuration.py | 17 ++----- client/text_ui.py | 48 +++++++++++++++++++ conf/packages/license.mask | 12 +++++ libraries/databaseTools.py | 33 +++++++++++++ libraries/entropy.py | 89 +++++++++++++++++++++++------------ libraries/entropyConstants.py | 4 ++ 7 files changed, 163 insertions(+), 49 deletions(-) create mode 100644 conf/packages/license.mask diff --git a/TODO b/TODO index 0bdcf7a14..d7d9a044b 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ TODO list: - - include license data in the database (*) - - implement configuration files snapshot tool (*) - - write a tool that will rebuild kernel dependant packages (*) + - implement configuration files snapshot tool + - write a tool that will rebuild kernel dependant packages - migrate server code to ServerInterface [] write a tool that helps keeping packages updated (also supporting injected ones) [] complete reagent spm interface @@ -13,7 +12,7 @@ TODO list: - find a way to better handle real smartapps deps (need split PDEPEND?) Spritz: - - if a package has a non OSS License, show it (*) + - if a package has a non OSS License, show it (*) IMPLEMENT - remove package info widgets and write from scratch (*) - debug (*) - add masking menu @@ -26,4 +25,4 @@ Project Status: - reagent: complete. - activator: complete. ============ -- equo - beta stage: 50% \ No newline at end of file +- equo - beta stage: 60% \ No newline at end of file diff --git a/client/text_configuration.py b/client/text_configuration.py index 9293e70c6..890c057e0 100644 --- a/client/text_configuration.py +++ b/client/text_configuration.py @@ -201,22 +201,13 @@ def update(cmd = None): elif action == 3: 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): - os.system("/bin/nano "+etpConst['systemroot']+scandata[cmd]['source']) - elif os.access("/bin/vi",os.X_OK): - os.system("/bin/vi "+etpConst['systemroot']+scandata[cmd]['source']) - elif os.access("/usr/bin/vi",os.X_OK): - os.system("/usr/bin/vi "+etpConst['systemroot']+scandata[cmd]['source']) - elif os.access("/usr/bin/emacs",os.X_OK): - os.system("/usr/bin/emacs "+etpConst['systemroot']+scandata[cmd]['source']) - elif os.access("/bin/emacs",os.X_OK): - os.system("/bin/emacs "+etpConst['systemroot']+scandata[cmd]['source']) - else: + editor = Equo.get_file_editor() + if editor == None: print_error(" Cannot find a suitable editor. Can't edit file directly.") comeback = True break + else: + os.system(editor+" "+etpConst['systemroot']+scandata[cmd]['source']) 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']) diff --git a/client/text_ui.py b/client/text_ui.py index 6b7ed6cf4..0de47fdbd 100644 --- a/client/text_ui.py +++ b/client/text_ui.py @@ -556,6 +556,54 @@ def installPackages(packages = [], atomsdata = [], deps = True, emptydeps = Fals currentqueue = 0 currentremovalqueue = 0 + def read_lic_selection(): + print_info(darkred(" Please choose an action")) + print_info(" ("+blue("1")+")"+darkgreen(" Read the license")) + print_info(" ("+blue("2")+")"+brown(" Accept the license (I've read it)")) + print_info(" ("+blue("3")+")"+darkred(" Accept the license and don't ask anymore (I've read it)")) + print_info(" ("+blue("0")+")"+bold(" Quit")) + # wait user interaction + action = readtext(" Your choice (type a number and press enter): ") + return action + + ### Before even starting the fetch, make sure that the user accepts their licenses + licenses = Equo.get_licenses_to_accept(runQueue) + if licenses: + print_info(red(" @@ ")+blue("You need to accept the licenses below:")) + keys = licenses.keys() + keys.sort() + for key in keys: + print_info(red(" :: License: ")+bold(key)+red(", needed by:")) + for match in licenses[key]: + dbconn = Equo.openRepositoryDatabase(match[1]) + atom = dbconn.retrieveAtom(match[0]) + print_info(blue(" ## ")+"["+brown("from")+":"+red(match[1])+"] "+bold(atom)) + while 1: + choice = read_lic_selection() + try: + choice = int(choice) + except TypeError: + continue + if choice not in (0,1,2,3): + continue + if choice == 0: + dirscleanup() + return 0,0 + elif choice == 1: # read + filename = Equo.get_text_license(key, match[1]) + viewer = Equo.get_file_viewer() + if viewer == None: + print_info(red(" No file viewer ! License saved into %s " % (filename,) )) + continue + os.system(viewer+" "+filename) + os.remove(filename) + continue + elif choice == 2: + break + elif choice == 3: + Equo.clientDbconn.acceptLicense(key) + break + ### Before starting the real install, fetch packages and verify checksum. fetchqueue = 0 for packageInfo in runQueue: diff --git a/conf/packages/license.mask b/conf/packages/license.mask new file mode 100644 index 000000000..fa2a959b0 --- /dev/null +++ b/conf/packages/license.mask @@ -0,0 +1,12 @@ +# license.mask example file +# +# In this file you can specify Gentoo license identifiers (/usr/portage/licenses), one per line, whose belonging packages must be masked. + +# LINE CONSTRUCTION: +# +# See examples below + +# EXAMPLES: +# NVIDIA +# ATI +# AMD \ No newline at end of file diff --git a/libraries/databaseTools.py b/libraries/databaseTools.py index 0ce8b6199..911d190c8 100644 --- a/libraries/databaseTools.py +++ b/libraries/databaseTools.py @@ -2531,6 +2531,17 @@ class etpDatabase: self.storeInfoCache(idpackage,'retrieveLicensedataKeys',licdata) return licdata + def retrieveLicenseText(self, license_name): + if not self.doesTableExist("licensedata"): + if (etpConst['uid'] == 0) and (not self.readOnly): + self.createLicensedataTable() + return None + self.cursor.execute('SELECT text FROM licensedata WHERE licensename = (?)', (license_name,)) + text = self.cursor.fetchone() + if not text: + return None + return text[0] + def retrieveLicense(self, idpackage): cache = self.fetchInfoCache(idpackage,'retrieveLicense') @@ -2703,6 +2714,25 @@ class etpDatabase: return False return True + def isLicenseAccepted(self, license_name): + if not self.doesTableExist("licenses_accepted"): + self.createLicensesAcceptedTable() + self.cursor.execute('SELECT licensename FROM licenses_accepted WHERE licensename = (?)', (license_name,)) + result = self.cursor.fetchone() + if not result: + return False + return True + + def acceptLicense(self, license_name): + if self.readOnly or (etpConst['uid'] != 0): + return + if not self.doesTableExist("licenses_accepted"): + self.createLicensesAcceptedTable() + if self.isLicenseAccepted(license_name): + return + self.cursor.execute('INSERT INTO licenses_accepted VALUES (?)', (license_name,)) + self.commitChanges() + def isLicenseAvailable(self,pkglicense): if not pkglicense or not pkglicense.isalnum(): # workaround for packages without a license but just garbage pkglicense = ' ' @@ -3620,6 +3650,9 @@ class etpDatabase: def createLicensedataTable(self): self.cursor.execute('CREATE TABLE licensedata ( licensename VARCHAR UNIQUE, text BLOB, compressed INTEGER );') + def createLicensesAcceptedTable(self): + self.cursor.execute('CREATE TABLE licenses_accepted ( licensename VARCHAR UNIQUE );') + def createTriggerTable(self): self.cursor.execute('CREATE TABLE triggers ( idpackage INTEGER PRIMARY KEY, data BLOB );') diff --git a/libraries/entropy.py b/libraries/entropy.py index 11a03f29e..7dded3272 100644 --- a/libraries/entropy.py +++ b/libraries/entropy.py @@ -321,38 +321,8 @@ class EquoInterface(TextInterface): self.updateProgress(darkred("Cache generation complete."), importance = 2, type = "info") def do_depcache(self): - ''' - self.updateProgress(darkred("Dependencies"), importance = 2, type = "warning") - self.updateProgress(darkred("Scanning repositories"), importance = 2, type = "warning") - keys = set() - for reponame in etpRepositoriesOrder: - self.updateProgress(darkgreen("Scanning %s" % (etpRepositories[reponame]['description'],)) , importance = 1, type = "info", back = True) - # get all packages keys - try: - dbconn = self.openRepositoryDatabase(reponame) - except exceptionTools.RepositoryError: - self.updateProgress(darkred("Cannot download/access: %s" % (etpRepositories[reponame]['description'],)) , importance = 2, type = "error") - continue - pkgdata = dbconn.listAllPackages() - pkgdata = set(pkgdata) - for info in pkgdata: - key = self.entropyTools.dep_getkey(info[0]) - keys.add(key) - ''' self.updateProgress(darkgreen("Resolving metadata"), importance = 1, type = "warning") - - ''' # XXX world calculation is enough - maxlen = len(keys) - cnt = 0 - for key in keys: - cnt += 1 - self.updateProgress(darkgreen("Resolving key: %s") % ( - key - ), importance = 0, type = "info", back = True, count = (cnt, maxlen) ) - self.atomMatch(key) - ''' - # we can barely ignore any exception from here # especially cases where client db does not exist try: @@ -452,6 +422,64 @@ class EquoInterface(TextInterface): crying_atoms.add((iatom,repo)) return crying_atoms + def get_licenses_to_accept(self, install_queue): + if not install_queue: + return [] + licenses = {} + for match in install_queue: + repoid = match[1] + dbconn = self.openRepositoryDatabase(repoid) + wl = etpConst['packagemasking']['repos_license_whitelist'].get(repoid) + if not wl: + continue + keys = dbconn.retrieveLicensedataKeys(match[0]) + for key in keys: + if key not in wl: + found = self.clientDbconn.isLicenseAccepted(key) + if found: + continue + if not licenses.has_key(key): + licenses[key] = set() + licenses[key].add(match) + return licenses + + def get_text_license(self, license_name, repoid): + dbconn = self.openRepositoryDatabase(repoid) + text = dbconn.retrieveLicenseText(license_name) + tempfile = self.entropyTools.getRandomTempFile() + f = open(tempfile,"w") + for x in text: + f.write(x) + f.flush() + f.close() + return tempfile + + def get_file_viewer(self): + viewer = None + if os.access("/usr/bin/less",os.X_OK): + viewer = "/usr/bin/less" + elif os.access("/bin/more",os.X_OK): + viewer = "/bin/more" + if not viewer: + viewer = self.get_file_editor() + return viewer + + def get_file_editor(self): + editor = None + if os.getenv("EDITOR"): + editor = "$EDITOR" + elif os.access("/bin/nano",os.X_OK): + editor = "/bin/nano" + elif os.access("/bin/vi",os.X_OK): + editor = "/bin/vi" + elif os.access("/usr/bin/vi",os.X_OK): + editor = "/usr/bin/vi" + elif os.access("/usr/bin/emacs",os.X_OK): + editor = "/usr/bin/emacs" + elif os.access("/bin/emacs",os.X_OK): + editor = "/bin/emacs" + return editor + def libraries_test(self, dbconn = None, reagent = False): if dbconn == None: @@ -6363,7 +6391,6 @@ class PackageMaskingParser: data = {} for item in self.etpMaskFiles: data[item] = eval('self.'+item+'_parser')() - #print data['repos_license_whitelist'] return data diff --git a/libraries/entropyConstants.py b/libraries/entropyConstants.py index 6846976f7..cc41065e1 100644 --- a/libraries/entropyConstants.py +++ b/libraries/entropyConstants.py @@ -311,6 +311,10 @@ CREATE TABLE licensedata ( compressed INTEGER ); +CREATE TABLE licenses_accepted ( + licensename VARCHAR UNIQUE +); + """ # ETP_ARCH_CONST setup