<commit_before>"""
Complete implementation of the XDG Icon Spec Version 0.8
http://standards.freedesktop.org/icon-theme-spec/
"""

import os, sys, time

from xdg.IniFile import *
from xdg.BaseDirectory import *
from xdg.Exceptions import *

import xdg.Config

class IconTheme(IniFile):
	"Class to parse and validate IconThemes"
	def __init__(self):
		IniFile.__init__(self)

	def __repr__(self):
		return self.name

	def parse(self, file):
		IniFile.parse(self, file, ["Icon Theme", "KDE Icon Theme"])
		self.dir = os.path.dirname(file)
		(nil, self.name) = os.path.split(self.dir)

	def getDir(self):
		return self.dir

	# Standard Keys
	def getName(self):
		return self.get('Name', locale = True)
	def getComment(self):
		return self.get('Comment', locale = True)
	def getInherits(self):
		return self.get('Inherits', list = True)
	def getDirectories(self):
		return self.get('Directories', list = True)
	def getHidden(self):
		return self.get('Hidden', type = "boolean")
	def getExample(self):
		return self.get('Example')

	# Per Directory Keys
	def getSize(self, directory):
		return self.get('Size', type = "integer", group = directory)
	def getContext(self, directory):
		return self.get('Context', group = directory)
	def getType(self, directory):
		value = self.get('Type', group = directory)
		if value:
			return value
		else:
			return "Threshold"
	def getMaxSize(self, directory):
		value = self.get('MaxSize', type = "integer", group = directory)
		if value or value == 0:
			return value
		else:
			return self.getSize(directory)
	def getMinSize(self, directory):
		value = self.get('MinSize', type = "integer", group = directory)
		if value or value == 0:
			return value
		else:
			return self.getSize(directory)
	def getThreshold(self, directory):
		value = self.get('Threshold', type = "integer", group = directory)
		if value or value == 0:
			return value
		else:
			return 2

	# validation stuff
	def checkExtras(self):
		# header
		if self.defaultGroup == "KDE Icon Theme":
			self.warnings.append('[KDE Icon Theme]-Header is deprecated')

		# file extension
		if self.fileExtension == ".theme":
			pass
		elif self.fileExtension == ".desktop":
			self.warnings.append('.desktop fileExtension is deprecated')
		else:
			self.warnings.append('Unknown File extension')

		# Check required keys
		# Name
		try:
			self.name = self.content[self.defaultGroup]["Name"]
		except KeyError:
			self.errors.append("Key 'Name' is missing")

		# Comment
		try:
			self.comment = self.content[self.defaultGroup]["Comment"]
		except KeyError:
			self.errors.append("Key 'Comment' is missing")

		# Directories
		try:
			self.directories = self.content[self.defaultGroup]["Directories"]
		except KeyError:
			self.errors.append("Key 'Directories' is missing")

	def checkGroup(self, group):
		# check if group header is valid
		if group == self.defaultGroup:
			pass
		elif group in self.getDirectories():
			try:
				self.type = self.content[group]["Type"]
			except KeyError:
				self.type = "Threshold"
			try:
				self.name = self.content[group]["Name"]
			except KeyError:
				self.errors.append("Key 'Name' in Group '%s' is missing" % group)
		elif not (re.match("^\[X-", group) and group.decode("utf-8", "ignore").encode("ascii", 'ignore') == group):
			self.errors.append("Invalid Group name: %s" % group)

	def checkKey(self, key, value, group):
		# standard keys		
		if group == self.defaultGroup:
			if re.match("^Name"+xdg.Locale.regex+"$", key):
				pass
			elif re.match("^Comment"+xdg.Locale.regex+"$", key):
				pass
			elif key == "Inherits":
				self.checkValue(key, value, list = True)
			elif key == "Directories":
				self.checkValue(key, value, list = True)
			elif key == "Hidden":
				self.checkValue(key, value, type = "boolean")
			elif key == "Example":
				self.checkValue(key, value)
			elif re.match("^X-[a-zA-Z0-9-]+", key):
				pass
			else:
				self.errors.append("Invalid key: %s" % key)
		elif group in self.getDirectories():
			if key == "Size":
				self.checkValue(key, value, type = "integer")
			elif key == "Context":
				self.checkValue(key, value)
			elif key == "Type":
				self.checkValue(key, value)
				if value not in ["Fixed", "Scalable", "Threshold"]:
					self.errors.append("Key 'Type' must be one out of 'Fixed','Scalable','Threshold', but is %s" % value)
			elif key == "MaxSize":
				self.checkValue(key, value, type = "integer")
				if self.type != "Scalable":
					self.errors.append("Key 'MaxSize' give, but Type is %s" % self.type)
			elif key == "MinSize":
				self.checkValue(key, value, type = "integer")
				if self.type != "Scalable":
					self.errors.append("Key 'MinSize' give, but Type is %s" % self.type)
			elif key == "Threshold":
				self.checkValue(key, value, type = "integer")
				if self.type != "Threshold":
					self.errors.append("Key 'Threshold' give, but Type is %s" % self.type)
			elif re.match("^X-[a-zA-Z0-9-]+", key):
				pass
			else:
				self.errors.append("Invalid key: %s" % key)


class IconData(IniFile):
	"Class to parse and validate IconData Files"
	def __init__(self):
		IniFile.__init__(self)

	def __repr__(self):
		return self.getDisplayName()

	def parse(self, file):
		IniFile.parse(self, file, ["Icon Data"])

	# Standard Keys
	def getDisplayName(self):
		return self.get('DisplayName', locale = True)
	def getEmbeddedTextRectangle(self):
		return self.get('EmbeddedTextRectangle', list = True)
	def getAttachPoints(self):
		return self.get('AttachPoints', type = "point", list = True)

	# validation stuff
	def checkExtras(self):
		# file extension
		if self.fileExtension != ".icon":
			self.warnings.append('Unknown File extension')

	def checkGroup(self, group):
		# check if group header is valid
		if not (group == self.defaultGroup \<commit_msg>small fix<commit_after>"""
Complete implementation of the XDG Icon Spec Version 0.8
http://standards.freedesktop.org/icon-theme-spec/
"""

import os, sys, time

from xdg.IniFile import *
from xdg.BaseDirectory import *
from xdg.Exceptions import *

import xdg.Config

class IconTheme(IniFile):
	"Class to parse and validate IconThemes"
	def __init__(self):
		IniFile.__init__(self)

	def __str__(self):
		return self.name

	def parse(self, file):
		IniFile.parse(self, file, ["Icon Theme", "KDE Icon Theme"])
		self.dir = os.path.dirname(file)
		(nil, self.name) = os.path.split(self.dir)

	def getDir(self):
		return self.dir

	# Standard Keys
	def getName(self):
		return self.get('Name', locale = True)
	def getComment(self):
		return self.get('Comment', locale = True)
	def getInherits(self):
		return self.get('Inherits', list = True)
	def getDirectories(self):
		return self.get('Directories', list = True)
	def getHidden(self):
		return self.get('Hidden', type = "boolean")
	def getExample(self):
		return self.get('Example')

	# Per Directory Keys
	def getSize(self, directory):
		return self.get('Size', type = "integer", group = directory)
	def getContext(self, directory):
		return self.get('Context', group = directory)
	def getType(self, directory):
		value = self.get('Type', group = directory)
		if value:
			return value
		else:
			return "Threshold"
	def getMaxSize(self, directory):
		value = self.get('MaxSize', type = "integer", group = directory)
		if value or value == 0:
			return value
		else:
			return self.getSize(directory)
	def getMinSize(self, directory):
		value = self.get('MinSize', type = "integer", group = directory)
		if value or value == 0:
			return value
		else:
			return self.getSize(directory)
	def getThreshold(self, directory):
		value = self.get('Threshold', type = "integer", group = directory)
		if value or value == 0:
			return value
		else:
			return 2

	# validation stuff
	def checkExtras(self):
		# header
		if self.defaultGroup == "KDE Icon Theme":
			self.warnings.append('[KDE Icon Theme]-Header is deprecated')

		# file extension
		if self.fileExtension == ".theme":
			pass
		elif self.fileExtension == ".desktop":
			self.warnings.append('.desktop fileExtension is deprecated')
		else:
			self.warnings.append('Unknown File extension')

		# Check required keys
		# Name
		try:
			self.name = self.content[self.defaultGroup]["Name"]
		except KeyError:
			self.errors.append("Key 'Name' is missing")

		# Comment
		try:
			self.comment = self.content[self.defaultGroup]["Comment"]
		except KeyError:
			self.errors.append("Key 'Comment' is missing")

		# Directories
		try:
			self.directories = self.content[self.defaultGroup]["Directories"]
		except KeyError:
			self.errors.append("Key 'Directories' is missing")

	def checkGroup(self, group):
		# check if group header is valid
		if group == self.defaultGroup:
			pass
		elif group in self.getDirectories():
			try:
				self.type = self.content[group]["Type"]
			except KeyError:
				self.type = "Threshold"
			try:
				self.name = self.content[group]["Name"]
			except KeyError:
				self.errors.append("Key 'Name' in Group '%s' is missing" % group)
		elif not (re.match("^\[X-", group) and group.decode("utf-8", "ignore").encode("ascii", 'ignore') == group):
			self.errors.append("Invalid Group name: %s" % group)

	def checkKey(self, key, value, group):
		# standard keys		
		if group == self.defaultGroup:
			if re.match("^Name"+xdg.Locale.regex+"$", key):
				pass
			elif re.match("^Comment"+xdg.Locale.regex+"$", key):
				pass
			elif key == "Inherits":
				self.checkValue(key, value, list = True)
			elif key == "Directories":
				self.checkValue(key, value, list = True)
			elif key == "Hidden":
				self.checkValue(key, value, type = "boolean")
			elif key == "Example":
				self.checkValue(key, value)
			elif re.match("^X-[a-zA-Z0-9-]+", key):
				pass
			else:
				self.errors.append("Invalid key: %s" % key)
		elif group in self.getDirectories():
			if key == "Size":
				self.checkValue(key, value, type = "integer")
			elif key == "Context":
				self.checkValue(key, value)
			elif key == "Type":
				self.checkValue(key, value)
				if value not in ["Fixed", "Scalable", "Threshold"]:
					self.errors.append("Key 'Type' must be one out of 'Fixed','Scalable','Threshold', but is %s" % value)
			elif key == "MaxSize":
				self.checkValue(key, value, type = "integer")
				if self.type != "Scalable":
					self.errors.append("Key 'MaxSize' give, but Type is %s" % self.type)
			elif key == "MinSize":
				self.checkValue(key, value, type = "integer")
				if self.type != "Scalable":
					self.errors.append("Key 'MinSize' give, but Type is %s" % self.type)
			elif key == "Threshold":
				self.checkValue(key, value, type = "integer")
				if self.type != "Threshold":
					self.errors.append("Key 'Threshold' give, but Type is %s" % self.type)
			elif re.match("^X-[a-zA-Z0-9-]+", key):
				pass
			else:
				self.errors.append("Invalid key: %s" % key)


class IconData(IniFile):
	"Class to parse and validate IconData Files"
	def __init__(self):
		IniFile.__init__(self)

	def __str__(self):
		return self.getDisplayName()

	def parse(self, file):
		IniFile.parse(self, file, ["Icon Data"])

	# Standard Keys
	def getDisplayName(self):
		return self.get('DisplayName', locale = True)
	def getEmbeddedTextRectangle(self):
		return self.get('EmbeddedTextRectangle', list = True)
	def getAttachPoints(self):
		return self.get('AttachPoints', type = "point", list = True)

	# validation stuff
	def checkExtras(self):
		# file extension
		if self.fileExtension != ".icon":
			self.warnings.append('Unknown File extension')

	def checkGroup(self, group):
		# check if group header is valid
		if not (group == self.defaultGroup \
{'fraction_non_alphanumeric': 0.1462821403752606, 'fraction_numerical': 0.001911049339819319, 'mean_word_length': 3.8908241291418864, 'pattern_counts': {'":': 34, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3050455', 'n_tokens_mistral': 4308, 'n_tokens_neox': 3756, 'n_words': 1057}