blob: deb0a35e7d46f02852c1feb194c4857628b76142 [file] [log] [blame]
# Copyright 2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import io
import re
import subprocess
import sys
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
from portage.util import writemsg
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:
content = f.read()
# In Python 3.2, read_file does not support bytes in file names
# (see bug #429544), so use StringIO to hide the file name.
read_file(io.StringIO(content))
return parser
_trivial_warnings = re.compile(r' looks redundant with value ')
_ignore_kde_key_re = re.compile(r'^\s*(configurationType\s*=|Type\s*=\s*Service)')
_ignore_kde_types = frozenset(
["AkonadiAgent", "AkonadiResource", "Service", "ServiceType"])
# kdebase-data installs files with [Currency Code] sections
# in /usr/share/locale/currency
# kdepim-runtime installs files with [Plugin] and [Wizard]
# sections in /usr/share/apps/akonadi/{plugins,accountwizard}
_ignore_kde_sections = ("Currency Code", "Plugin", "Wizard")
def validate_desktop_entry(path):
args = ["desktop-file-validate", path]
if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
# Python 3.1 does not support bytes in Popen args.
args = [_unicode_encode(x, errors='strict') for x in args]
proc = subprocess.Popen(args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output_lines = _unicode_decode(proc.communicate()[0]).splitlines()
proc.wait()
if output_lines:
# Ignore kde extensions for bug #414125 and bug #432862.
try:
desktop_entry = parse_desktop_entry(path)
except ConfigParserError:
with io.open(_unicode_encode(path,
encoding=_encodings['fs'], errors='strict'),
mode='r', encoding=_encodings['repo.content'],
errors='replace') as f:
for line in f:
if _ignore_kde_key_re.match(line):
# Ignore kde extensions for bug #432862.
del output_lines[:]
break
else:
if desktop_entry.has_section("Desktop Entry"):
try:
entry_type = desktop_entry.get("Desktop Entry", "Type")
except ConfigParserError:
pass
else:
if entry_type in _ignore_kde_types:
del output_lines[:]
try:
desktop_entry.get("Desktop Entry", "Hidden")
except ConfigParserError:
pass
else:
# The "Hidden" key appears to be unique to special kde
# service files (which don't validate well), installed
# in /usr/share/kde4/services/ by packages like
# nepomuk-core and kurifilter-plugins.
del output_lines[:]
for section in _ignore_kde_sections:
if desktop_entry.has_section(section):
del output_lines[:]
if output_lines:
output_lines = [line for line in output_lines
if _trivial_warnings.search(line) is None]
return output_lines
if __name__ == "__main__":
for arg in sys.argv[1:]:
for line in validate_desktop_entry(arg):
writemsg(line + "\n", noiselevel=-1)