From 0b46052259c67b07a814c12d3a24841ca48383ac Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 25 Jul 2018 11:38:52 +0100 Subject: [PATCH] Catalog generation enhancements --- catalog/catalog.py | 73 +++++++------------- catalog/testData/Aircraft/dc3/dc3-set.xml | 21 ++++++ catalog/test_catalog.py | 83 +++++++++++++++++------ 3 files changed, 107 insertions(+), 70 deletions(-) create mode 100644 catalog/testData/Aircraft/dc3/dc3-set.xml diff --git a/catalog/catalog.py b/catalog/catalog.py index 9540244..7098237 100644 --- a/catalog/catalog.py +++ b/catalog/catalog.py @@ -2,7 +2,7 @@ import argparse import datetime -import lxml.etree as ET +import xml.etree.cElementTree as ET import os import re import sgprops @@ -61,11 +61,19 @@ def scan_set_file(aircraft_dir, set_file, includes): if sim_node.hasChild('authors'): # aircraft has structured authors data, handle that - variant['authors'] = extract_authors(sim_node.getChild('authors')) - - elif sim_node.hasChild('author'): + variant['authors'] = sim_node.getChild('authors') + + # can have legacy author tag alongside new strucutred data for + # backwards FG compatability + if sim_node.hasChild('author'): variant['author'] = sim_node.getValue("author", None) + if sim_node.hasChild('maintainers'): + variant['maintainers'] = sim_node.getChild('maintainers') + + if sim_node.hasChild('urls'): + variant['urls'] = sim_node.getChild('urls') + if sim_node.hasChild('long-description'): variant['description'] = sim_node.getValue("long-description", None) variant['id'] = base_id @@ -79,11 +87,7 @@ def scan_set_file(aircraft_dir, set_file, includes): variant['previews'] = extract_previews(sim_node.getChild('previews'), aircraft_dir) if sim_node.hasChild('rating'): - rating_node = sim_node.getChild("rating") - variant['rating_FDM'] = rating_node.getValue("FDM", 0) - variant['rating_systems'] = rating_node.getValue("systems", 0) - variant['rating_cockpit'] = rating_node.getValue("cockpit", 0) - variant['rating_model'] = rating_node.getValue("model", 0) + variant['rating'] = sim_node.getChild("rating") if sim_node.hasChild('tags'): variant['tags'] = extract_tags(sim_node.getChild('tags'), set_file) @@ -125,20 +129,6 @@ def extract_tags(tags_node, set_path): return result -def extract_authors(authors_node): - result = [] - for author in authors_node.getChildren("author"): - authorName = author.getValue("name", None) - if (authorName == None): - continue - - authorNick = author.getValue("nick", None) - authorEmail = author.getValue("email", None) - authorDesc = author.getValue("description", None) - - result.append({'name':authorName, 'nick':authorNick, 'email':authorEmail, 'description':authorDesc}) - return result - # scan all the -set.xml files in an aircraft directory. Returns a # package dict and a list of variants. def scan_aircraft_dir(aircraft_dir, includes): @@ -217,20 +207,8 @@ def append_tag_nodes(node, variant): def append_author_nodes(node, info): if 'authors' in info: - authors_node = ET.Element('authors') - for a in info['authors']: - a_node = ET.Element('author') - a_node.append(make_xml_leaf('name', a['name'])) - if (a['email'] != None): - a_node.append(make_xml_leaf('email', a['email'])) - if (a['nick'] != None): - a_node.append(make_xml_leaf('nick', a['nick'])) - if (a['description'] != None): - a_node.append(make_xml_leaf('description', a['description'])) - authors_node.append(a_node) - - node.append(authors_node) - elif 'author' in info: + node.append(info['authors']._createXMLElement()) + if 'author' in info: # traditional single author string node.append( make_xml_leaf('author', info['author']) ) @@ -249,18 +227,9 @@ def make_aircraft_node(aircraftDirName, package, variants, downloadBase): if 'minimum-fg-version' in package: package_node.append( make_xml_leaf('minimum-fg-version', package['minimum-fg-version']) ) - if 'rating_FDM' in package or 'rating_systems' in package \ - or 'rating_cockpit' in package or 'rating_model' in package: - rating_node = ET.Element('rating') - package_node.append(rating_node) - rating_node.append( make_xml_leaf('FDM', - package['rating_FDM']) ) - rating_node.append( make_xml_leaf('systems', - package['rating_systems']) ) - rating_node.append( make_xml_leaf('cockpit', - package['rating_cockpit']) ) - rating_node.append( make_xml_leaf('model', - package['rating_model']) ) + if 'rating' in package: + package_node.append(package['rating']._createXMLElement()) + package_node.append( make_xml_leaf('id', package['id']) ) for variant in variants: variant_node = ET.Element('variant') @@ -303,4 +272,10 @@ def make_aircraft_node(aircraftDirName, package, variants, downloadBase): append_preview_nodes(package_node, package, downloadBase, aircraftDirName) append_tag_nodes(package_node, package) + if 'maintainers' in package: + package_node.append(package['maintainers']._createXMLElement()) + + if 'urls' in package: + package_node.append(package['urls']._createXMLElement()) + return package_node diff --git a/catalog/testData/Aircraft/dc3/dc3-set.xml b/catalog/testData/Aircraft/dc3/dc3-set.xml new file mode 100644 index 0000000..168949c --- /dev/null +++ b/catalog/testData/Aircraft/dc3/dc3-set.xml @@ -0,0 +1,21 @@ + + + + dc3 + Douglas DC-3 + Donald Douglas + + + Donald Douglas + dd + dd@douglas.com + Made all the stuff + + + + https://bugtracker.douglas.com/ + http://www.douglas.com + + + + diff --git a/catalog/test_catalog.py b/catalog/test_catalog.py index ed0f669..2e6f138 100755 --- a/catalog/test_catalog.py +++ b/catalog/test_catalog.py @@ -4,7 +4,7 @@ import unittest import sgprops import os import catalog -import lxml.etree as ET +import xml.etree.cElementTree as ET catalog.quiet = True @@ -15,24 +15,25 @@ class UpdateCatalogTests(unittest.TestCase): self.assertEqual(info['name'], 'F16-A') self.assertEqual(info['primary-set'], True) self.assertEqual(info['variant-of'], None) - self.assertEqual(info['rating_FDM'], 3) - self.assertEqual(info['rating_model'], 5) + # self.assertEqual(info['rating_FDM'], 3) + # self.assertEqual(info['rating_model'], 5) + + ratings = info['rating'] + self.assertEqual(ratings.getValue('FDM'), 3) + self.assertEqual(ratings.getValue('model'), 5) + self.assertEqual(len(info['tags']), 3) self.assertEqual(info['minimum-fg-version'], '2017.4') - authorsArray = info['authors'] + authors = info['authors'] self.assertNotIn('author', info) - self.assertEqual(len(authorsArray), 2) + self.assertEqual(len(authors.getChildren()), 2) - author0 = authorsArray[0] - self.assertEqual(author0['name'], 'Wilbur Wright') - self.assertEqual(author0['nick'], 'wilburw') - self.assertEqual(author0['email'], 'ww@wright.com') + self.assertEqual(authors.getValue('author[0]/name'), 'Wilbur Wright') + self.assertEqual(authors.getValue('author[0]/nick'), 'wilburw') + self.assertEqual(authors.getValue('author[0]/email'), 'ww@wright.com') + self.assertEqual(authors.getValue('author[1]/name'), 'Orville Wright') - author1 = authorsArray[1] - self.assertEqual(author1['name'], 'Orville Wright') - # self.assertNotIn('nick', author1) - # self.assertNotIn('email', author1) def test_scan_dir(self): (pkg, variants) = catalog.scan_aircraft_dir("testData/Aircraft/f16", ["testData/OtherDir"]) @@ -55,19 +56,17 @@ class UpdateCatalogTests(unittest.TestCase): authorsArray = f16b['authors'] self.assertNotIn('author', f16b) - self.assertEqual(len(authorsArray), 2) - author0 = authorsArray[0] - self.assertEqual(author0['name'], 'James T Kirk') - self.assertEqual(author0['nick'], 'starlover') + self.assertEqual(authorsArray.getValue('author[0]/name'), 'James T Kirk') + self.assertEqual(authorsArray.getValue('author[0]/nick'), 'starlover') f16c = next(v for v in variants if v['id'] == 'f16c') self.assertEqual(f16c['variant-of'], 'f16a') self.assertEqual(f16c['primary-set'], False) - authorsArray = f16c['authors'] + authors = f16c['authors'] self.assertNotIn('author', f16c) - self.assertEqual(len(authorsArray), 2) + self.assertEqual(len(authors.getChildren()), 2) # test some older constructs for compat def test_scan_dir_legacy(self): @@ -104,7 +103,7 @@ class UpdateCatalogTests(unittest.TestCase): os.mkdir("testOutput") cat_file = os.path.join("testOutput", 'catalog_fragment.xml') - catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True, pretty_print=True) + catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True) parsed = sgprops.readProps(cat_file) parsedPkgNode = parsed.getChild("package") @@ -125,6 +124,12 @@ class UpdateCatalogTests(unittest.TestCase): parsedVariants = parsedPkgNode.getChildren("variant") self.assertEqual(len(parsedVariants), 3) + # verify rating copying + self.assertEqual(parsedPkgNode.getValue('rating/FDM'), 3) + self.assertEqual(parsedPkgNode.getValue('rating/cockpit'), 2) + self.assertEqual(parsedPkgNode.getValue('rating/model'), 5) + + # author data verification self.assertFalse(parsedPkgNode.hasChild('author')); parsedAuthors = parsedPkgNode.getChild("authors").getChildren('author') @@ -161,6 +166,42 @@ class UpdateCatalogTests(unittest.TestCase): self.assertEqual(author1.getValue("email"), "shatner@enterprise.com") self.assertEqual(author1.getValue("description"), "Everything") + def test_node_creation2(self): + (pkg, variants) = catalog.scan_aircraft_dir("testData/Aircraft/dc3", ["testData/OtherDir"]) + + catalog_node = ET.Element('PropertyList') + catalog_root = ET.ElementTree(catalog_node) + + pkgNode = catalog.make_aircraft_node('dc3', pkg, variants, "http://foo.com/testOutput/") + catalog_node.append(pkgNode) + + if not os.path.isdir("testOutput"): + os.mkdir("testOutput") + + cat_file = os.path.join("testOutput", 'catalog_fragment2.xml') + catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True) + + parsed = sgprops.readProps(cat_file) + parsedPkgNode = parsed.getChild("package") + + self.assertEqual(parsedPkgNode.name, "package"); + + self.assertEqual(parsedPkgNode.getValue('id'), pkg['id']); + self.assertEqual(parsedPkgNode.getValue('dir'), 'dc3'); + self.assertEqual(parsedPkgNode.getValue('url'), 'http://foo.com/testOutput/dc3.zip'); + + self.assertEqual(parsedPkgNode.getValue('author'), 'Donald Douglas'); + + parsedAuthors = parsedPkgNode.getChild("authors").getChildren('author') + self.assertEqual(len(parsedAuthors), 1) + author1 = parsedAuthors[0] + self.assertEqual(author1.getValue("name"), "Donald Douglas") + self.assertEqual(author1.getValue("nick"), "dd") + self.assertEqual(author1.getValue("email"), "dd@douglas.com") + + urls = parsedPkgNode.getChild('urls') + self.assertEqual(urls.getValue('home-page'), 'http://www.douglas.com') + def test_minimalAircraft(self): # test an aircraft with a deliberately spartan -set.xml file with # most interesting data missing @@ -176,7 +217,7 @@ class UpdateCatalogTests(unittest.TestCase): os.mkdir("testOutput2") cat_file = os.path.join("testOutput2", 'catalog_fragment.xml') - catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True, pretty_print=True) + catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True) parsed = sgprops.readProps(cat_file) parsedPkgNode = parsed.getChild("package")