Improve the validator.py script. Fix false positives with particles and variants. Use a logger instead.
This was SVN commit r26333.
This commit is contained in:
parent
0e1da6af7a
commit
adcd1d105c
@ -2,10 +2,9 @@
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import xml.etree.ElementTree
|
||||
|
||||
from logging import getLogger, StreamHandler, INFO, Formatter
|
||||
|
||||
class Actor:
|
||||
def __init__(self, mod_name, vfs_path):
|
||||
@ -14,20 +13,45 @@ class Actor:
|
||||
self.name = os.path.basename(vfs_path)
|
||||
self.textures = []
|
||||
self.material = ''
|
||||
self.logger = getLogger(__name__)
|
||||
|
||||
def read(self, physical_path):
|
||||
try:
|
||||
tree = xml.etree.ElementTree.parse(physical_path)
|
||||
except xml.etree.ElementTree.ParseError as err:
|
||||
sys.stderr.write('Error in "%s": %s\n' % (physical_path, err.msg))
|
||||
self.logger.error('"%s": %s\n' % (physical_path, err.msg))
|
||||
return False
|
||||
root = tree.getroot()
|
||||
# Special case: particles don't need a diffuse texture.
|
||||
if len(root.findall('.//particles')) > 0:
|
||||
self.textures.append("baseTex")
|
||||
|
||||
for element in root.findall('.//material'):
|
||||
self.material = element.text
|
||||
for element in root.findall('.//texture'):
|
||||
self.textures.append(element.get('name'))
|
||||
for element in root.findall('.//variant'):
|
||||
file = element.get('file')
|
||||
if file:
|
||||
self.read_variant(physical_path, os.path.join('art', 'variants', file))
|
||||
return True
|
||||
|
||||
def read_variant(self, actor_physical_path, relative_path):
|
||||
physical_path = actor_physical_path.replace(self.vfs_path, relative_path)
|
||||
try:
|
||||
tree = xml.etree.ElementTree.parse(physical_path)
|
||||
except xml.etree.ElementTree.ParseError as err:
|
||||
self.logger.error('"%s": %s\n' % (physical_path, err.msg))
|
||||
return False
|
||||
|
||||
root = tree.getroot()
|
||||
file = root.get('file')
|
||||
if file:
|
||||
self.read_variant(actor_physical_path, os.path.join('art', 'variants', file))
|
||||
|
||||
for element in root.findall('.//texture'):
|
||||
self.textures.append(element.get('name'))
|
||||
|
||||
|
||||
class Material:
|
||||
def __init__(self, mod_name, vfs_path):
|
||||
@ -40,7 +64,7 @@ class Material:
|
||||
try:
|
||||
root = xml.etree.ElementTree.parse(physical_path).getroot()
|
||||
except xml.etree.ElementTree.ParseError as err:
|
||||
sys.stderr.write('Error in "%s": %s\n' % (physical_path, err.msg))
|
||||
self.logger.error('"%s": %s\n' % (physical_path, err.msg))
|
||||
return False
|
||||
for element in root.findall('.//required_texture'):
|
||||
texture_name = element.get('name')
|
||||
@ -58,6 +82,17 @@ class Validator:
|
||||
self.materials = {}
|
||||
self.invalid_materials = {}
|
||||
self.actors = []
|
||||
self.__init_logger
|
||||
|
||||
@property
|
||||
def __init_logger(self):
|
||||
logger = getLogger(__name__)
|
||||
logger.setLevel(INFO)
|
||||
ch = StreamHandler()
|
||||
ch.setLevel(INFO)
|
||||
ch.setFormatter(Formatter('%(levelname)s - %(message)s'))
|
||||
logger.addHandler(ch)
|
||||
self.logger = logger
|
||||
|
||||
def get_physical_path(self, mod_name, vfs_path):
|
||||
return os.path.realpath(os.path.join(self.vfs_root, mod_name, vfs_path))
|
||||
@ -109,7 +144,7 @@ class Validator:
|
||||
def run(self):
|
||||
start_time = time.time()
|
||||
|
||||
sys.stdout.write('Collecting list of files to check\n')
|
||||
self.logger.info('Collecting list of files to check\n')
|
||||
|
||||
self.find_materials(os.path.join('art', 'materials'))
|
||||
self.find_actors(os.path.join('art', 'actors'))
|
||||
@ -118,32 +153,32 @@ class Validator:
|
||||
if not actor.material:
|
||||
continue
|
||||
if actor.material not in self.materials and actor.material not in self.invalid_materials:
|
||||
sys.stderr.write('Error in "%s": unknown material "%s"' % (
|
||||
self.get_physical_path(actor.mod_name, actor.vfs_path),
|
||||
self.logger.error('"%s": unknown material "%s"' % (
|
||||
self.get_mod_path(actor.mod_name, actor.vfs_path),
|
||||
actor.material
|
||||
))
|
||||
if actor.material not in self.materials:
|
||||
continue
|
||||
material = self.materials[actor.material]
|
||||
for required_texture in material.required_textures:
|
||||
if required_texture in actor.textures:
|
||||
continue
|
||||
sys.stderr.write('Error in "%s": actor does not contain required texture "%s" from "%s"\n' % (
|
||||
self.get_physical_path(actor.mod_name, actor.vfs_path),
|
||||
required_texture,
|
||||
|
||||
missing_textures = ', '.join(set([required_texture for required_texture in material.required_textures if required_texture not in actor.textures]))
|
||||
if len(missing_textures) > 0:
|
||||
self.logger.error('"%s": actor does not contain required texture(s) "%s" from "%s"' % (
|
||||
self.get_mod_path(actor.mod_name, actor.vfs_path),
|
||||
missing_textures,
|
||||
material.name
|
||||
))
|
||||
for texture in actor.textures:
|
||||
if texture in material.required_textures:
|
||||
continue
|
||||
sys.stderr.write('Warning in "%s": actor contains unnecessary texture "%s" from "%s"\n' % (
|
||||
self.get_physical_path(actor.mod_name, actor.vfs_path),
|
||||
texture,
|
||||
|
||||
extra_textures = ', '.join(set([extra_texture for extra_texture in actor.textures if extra_texture not in material.required_textures]))
|
||||
if len(extra_textures) > 0:
|
||||
self.logger.warning('"%s": actor contains unnecessary texture(s) "%s" from "%s"' % (
|
||||
self.get_mod_path(actor.mod_name, actor.vfs_path),
|
||||
extra_textures,
|
||||
material.name
|
||||
))
|
||||
|
||||
finish_time = time.time()
|
||||
sys.stdout.write('Total execution time: %.3f seconds.\n' % (finish_time - start_time))
|
||||
self.logger.info('Total execution time: %.3f seconds.\n' % (finish_time - start_time))
|
||||
|
||||
if __name__ == '__main__':
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
Loading…
Reference in New Issue
Block a user