From 2f6b40eab75abe4a163999fcda65ecefb7c71be7 Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Mon, 29 Mar 2010 15:36:03 +0200 Subject: [PATCH] [entropy.db/entropy.spm] implement per-package file association metadata collection/handling --- libraries/entropy/db/__init__.py | 73 +++++++++++++++++++ .../interfaces/portage_plugin/__init__.py | 49 ++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/libraries/entropy/db/__init__.py b/libraries/entropy/db/__init__.py index 3f444f34f..4a8e038ae 100644 --- a/libraries/entropy/db/__init__.py +++ b/libraries/entropy/db/__init__.py @@ -348,6 +348,15 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): FOREIGN KEY(idpackage) REFERENCES baseinfo(idpackage) ON DELETE CASCADE ); + CREATE TABLE packagedesktopmime ( + idpackage INTEGER, + name VARCHAR, + mimetype VARCHAR, + executable VARCHAR, + icon VARCHAR, + FOREIGN KEY(idpackage) REFERENCES baseinfo(idpackage) ON DELETE CASCADE + ); + CREATE TABLE packagesignatures ( idpackage INTEGER PRIMARY KEY, sha1 VARCHAR, @@ -1414,6 +1423,10 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): self.insertKeywords(idpackage, pkg_data['keywords']) self.insertLicenses(pkg_data['licensedata']) self.insertMirrors(pkg_data['mirrorlinks']) + + # packages and file association metadata + self._insertDesktopMime(idpackage, pkg_data.get('desktop_mime', [])) + # package ChangeLog if pkg_data.get('changelog'): self.insertChangelog(pkg_data['category'], pkg_data['name'], @@ -1546,6 +1559,11 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): DELETE FROM injected WHERE idpackage = %d; DELETE FROM installedtable WHERE idpackage = %d; """ % r_tup) + # FIXME: incorportate in query above before 2010-12-31 + if self._doesTableExist("packagedesktopmime"): + self._cursor().execute(""" + DELETE FROM packagedesktopmime WHERE idpackage = (?)""", + (idpackage,)) if do_cleanup: # Cleanups if at least one package has been removed @@ -2265,6 +2283,21 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): INSERT INTO packagesignatures VALUES (?,?,?,?) """, (idpackage, sha1, sha256, sha512)) + def _insertDesktopMime(self, idpackage, metadata): + """ + Insert file association information for package. + + @param idpackage: package indentifier + @type idpackage: int + @param metadata: list of dict() containing file association metadata + @type metadata: list + """ + mime_data = [(idpackage, x['name'], x['mimetype'], x['executable'], + x['icon']) for x in metadata] + if mime_data: + self._cursor().executemany(""" + INSERT INTO packagedesktopmime VALUES (?,?,?,?,?)""", mime_data) + def _insertSpmPhases(self, idpackage, phases): """ Insert Source Package Manager phases for package. @@ -3164,6 +3197,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): 'signatures': signatures, 'spm_phases': self.retrieveSpmPhases(idpackage), 'spm_repository': self.retrieveSpmRepository(idpackage), + 'desktop_mime': [], } @rtype: dict @@ -3262,6 +3296,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): 'signatures': signatures, 'spm_phases': self.retrieveSpmPhases(idpackage), 'spm_repository': self.retrieveSpmRepository(idpackage), + 'desktop_mime': self.retrieveDesktopMime(idpackage), } return data @@ -4022,6 +4057,29 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): if spm_repo: return spm_repo[0] + def retrieveDesktopMime(self, idpackage): + """ + Return file association metadata for package. + + @param idpackage: package indentifier + @type idpackage: int + @return: list of dict() containing file association information + @rtype: list + """ + if not self._doesTableExist("packagedesktopmime"): + return [] + + cur = self._cursor().execute(""" + SELECT name, mimetype, executable, icon FROM packagedesktopmime + WHERE idpackage = (?)""", (idpackage,)) + data = [] + for row in cur.fetchall(): + item = {} + item['name'], item['mimetype'], item['executable'], \ + item['icon'] = row + data.append(item) + return data + def retrieveNeededRaw(self, idpackage): """ Return (raw format) "NEEDED" ELF metadata for libraries contained @@ -6185,6 +6243,9 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): old_readonly = self.readOnly self.readOnly = False + if not self._doesTableExist("packagedesktopmime"): + self._createPackageDesktopMimeTable() + if not self._doesTableExist("licenses_accepted"): self._createLicensesAcceptedTable() @@ -7514,6 +7575,18 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface): CREATE TABLE packagesets ( setname VARCHAR, dependency VARCHAR ); """) + def _createPackageDesktopMimeTable(self): + self._cursor().execute(""" + CREATE TABLE packagedesktopmime ( + idpackage INTEGER, + name VARCHAR, + mimetype VARCHAR, + executable VARCHAR, + icon VARCHAR, + FOREIGN KEY(idpackage) REFERENCES baseinfo(idpackage) ON DELETE CASCADE + ); + """) + def createCategoriesdescriptionTable(self): self._cursor().execute(""" CREATE TABLE categoriesdescription ( category VARCHAR, diff --git a/libraries/entropy/spm/plugins/interfaces/portage_plugin/__init__.py b/libraries/entropy/spm/plugins/interfaces/portage_plugin/__init__.py index f9118a568..28cfa3c9d 100644 --- a/libraries/entropy/spm/plugins/interfaces/portage_plugin/__init__.py +++ b/libraries/entropy/spm/plugins/interfaces/portage_plugin/__init__.py @@ -1055,6 +1055,9 @@ class PortagePlugin(SpmPlugin): data['licensedata'] = self._extract_pkg_metadata_license_data( licenses_dir, data['license']) + data['desktop_mime'] = self._extract_pkg_metadata_desktop_mime( + pkg_dir, data['content']) + data['mirrorlinks'] = self._extract_pkg_metadata_mirror_links( data['sources']) @@ -1071,7 +1074,8 @@ class PortagePlugin(SpmPlugin): self.get_merge_protected_paths_mask()) log_dir = etpConst['logdir']+"/elog" - if not os.path.isdir(log_dir): os.makedirs(log_dir) + if not os.path.isdir(log_dir): + os.makedirs(log_dir) data['messages'] = self._extract_pkg_metadata_messages(log_dir, data['category'], data['name'], data['version']) @@ -4097,6 +4101,49 @@ class PortagePlugin(SpmPlugin): return pkg_messages + def _extract_pkg_metadata_desktop_mime(self, pkg_dir, content): + + valid_paths = [x for x in content if x.endswith(".desktop")] + if not valid_paths: + return [] + + data_dirs = [os.path.join(x, "applications") for x in \ + os.getenv("XDG_DATA_DIRS", "/usr/share").split(":")] + + def filter_valid_paths(path): + for data_dir in data_dirs: + if path.startswith(data_dir): + return True + return False + + valid_paths = list(filter(filter_valid_paths, valid_paths)) + valid_paths = [os.path.join(pkg_dir, x[1:]) for x in valid_paths] + + desktop_mime = [] + + for desktop_path in sorted(valid_paths): + if not (os.path.isfile(desktop_path) and \ + os.access(desktop_path, os.R_OK)): + continue + with open(desktop_path, "r") as desk_f: + desk_data = [x.strip().split("=", 1) for x in \ + desk_f.readlines() if len(x.strip().split("=", 1)) == 2] + raw_desk_meta = dict(desk_data) + + if "MimeType" not in raw_desk_meta: + continue + elif "Name" not in raw_desk_meta: + continue + desk_meta = { + "name": raw_desk_meta['Name'], + "mimetype": raw_desk_meta['MimeType'], + "executable": raw_desk_meta.get('Exec'), + "icon": raw_desk_meta.get("Icon"), + } + desktop_mime.append(desk_meta) + + return desktop_mime + def _extract_pkg_metadata_license_data(self, licenses_dir, license_string): pkg_licensedata = {}