aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pym/portage/util/_desktop_entry.py')
-rw-r--r--pym/portage/util/_desktop_entry.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/pym/portage/util/_desktop_entry.py b/pym/portage/util/_desktop_entry.py
new file mode 100644
index 000000000..101965f6a
--- /dev/null
+++ b/pym/portage/util/_desktop_entry.py
@@ -0,0 +1,70 @@
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import io
+import subprocess
+
+try:
+ from configparser import Error as ConfigParserError, RawConfigParser
+except ImportError:
+ from ConfigParser import Error as ConfigParserError, RawConfigParser
+
+from portage import _encodings, _unicode_encode, _unicode_decode
+
+def parse_desktop_entry(path):
+ """
+ Parse the given file with RawConfigParser and return the
+ result. This may raise an IOError from io.open(), or a
+ ParsingError from RawConfigParser.
+ """
+ parser = RawConfigParser()
+
+ # use read_file/readfp in order to control decoding of unicode
+ try:
+ # Python >=3.2
+ read_file = parser.read_file
+ except AttributeError:
+ read_file = parser.readfp
+
+ with io.open(_unicode_encode(path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='r', encoding=_encodings['repo.content'],
+ errors='replace') as f:
+ read_file(f)
+
+ return parser
+
+_ignored_service_errors = (
+ 'error: required key "Name" in group "Desktop Entry" is not present',
+ 'error: key "Actions" is present in group "Desktop Entry", but the type is "Service" while this key is only valid for type "Application"',
+ 'error: key "MimeType" is present in group "Desktop Entry", but the type is "Service" while this key is only valid for type "Application"',
+)
+
+def validate_desktop_entry(path):
+ proc = subprocess.Popen([b"desktop-file-validate", _unicode_encode(path)],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output_lines = _unicode_decode(proc.communicate()[0]).splitlines()
+ proc.wait()
+
+ if output_lines:
+ try:
+ desktop_entry = parse_desktop_entry(path)
+ except ConfigParserError:
+ pass
+ else:
+ if desktop_entry.has_section("Desktop Entry"):
+ try:
+ entry_type = desktop_entry.get("Desktop Entry", "Type")
+ except ConfigParserError:
+ pass
+ else:
+ if entry_type == "Service":
+ # Filter false errors for Type=Service (bug #414125).
+ filtered_output = []
+ for line in output_lines:
+ if line[len(path)+2:] in _ignored_service_errors:
+ continue
+ filtered_output.append(line)
+ output_lines = filtered_output
+
+ return output_lines