[entropy.db/entropy.spm] implement per-package file association metadata collection/handling
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
Reference in New Issue
Block a user