Catalog generation enhancements
This commit is contained in:
+23
-48
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
import lxml.etree as ET
|
import xml.etree.cElementTree as ET
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sgprops
|
import sgprops
|
||||||
@@ -61,11 +61,19 @@ def scan_set_file(aircraft_dir, set_file, includes):
|
|||||||
|
|
||||||
if sim_node.hasChild('authors'):
|
if sim_node.hasChild('authors'):
|
||||||
# aircraft has structured authors data, handle that
|
# aircraft has structured authors data, handle that
|
||||||
variant['authors'] = extract_authors(sim_node.getChild('authors'))
|
variant['authors'] = sim_node.getChild('authors')
|
||||||
|
|
||||||
elif sim_node.hasChild('author'):
|
# 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)
|
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'):
|
if sim_node.hasChild('long-description'):
|
||||||
variant['description'] = sim_node.getValue("long-description", None)
|
variant['description'] = sim_node.getValue("long-description", None)
|
||||||
variant['id'] = base_id
|
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)
|
variant['previews'] = extract_previews(sim_node.getChild('previews'), aircraft_dir)
|
||||||
|
|
||||||
if sim_node.hasChild('rating'):
|
if sim_node.hasChild('rating'):
|
||||||
rating_node = sim_node.getChild("rating")
|
variant['rating'] = 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)
|
|
||||||
|
|
||||||
if sim_node.hasChild('tags'):
|
if sim_node.hasChild('tags'):
|
||||||
variant['tags'] = extract_tags(sim_node.getChild('tags'), set_file)
|
variant['tags'] = extract_tags(sim_node.getChild('tags'), set_file)
|
||||||
@@ -125,20 +129,6 @@ def extract_tags(tags_node, set_path):
|
|||||||
|
|
||||||
return result
|
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
|
# scan all the -set.xml files in an aircraft directory. Returns a
|
||||||
# package dict and a list of variants.
|
# package dict and a list of variants.
|
||||||
def scan_aircraft_dir(aircraft_dir, includes):
|
def scan_aircraft_dir(aircraft_dir, includes):
|
||||||
@@ -217,20 +207,8 @@ def append_tag_nodes(node, variant):
|
|||||||
|
|
||||||
def append_author_nodes(node, info):
|
def append_author_nodes(node, info):
|
||||||
if 'authors' in info:
|
if 'authors' in info:
|
||||||
authors_node = ET.Element('authors')
|
node.append(info['authors']._createXMLElement())
|
||||||
for a in info['authors']:
|
if 'author' in info:
|
||||||
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:
|
|
||||||
# traditional single author string
|
# traditional single author string
|
||||||
node.append( make_xml_leaf('author', info['author']) )
|
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:
|
if 'minimum-fg-version' in package:
|
||||||
package_node.append( make_xml_leaf('minimum-fg-version', package['minimum-fg-version']) )
|
package_node.append( make_xml_leaf('minimum-fg-version', package['minimum-fg-version']) )
|
||||||
|
|
||||||
if 'rating_FDM' in package or 'rating_systems' in package \
|
if 'rating' in package:
|
||||||
or 'rating_cockpit' in package or 'rating_model' in package:
|
package_node.append(package['rating']._createXMLElement())
|
||||||
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']) )
|
|
||||||
package_node.append( make_xml_leaf('id', package['id']) )
|
package_node.append( make_xml_leaf('id', package['id']) )
|
||||||
for variant in variants:
|
for variant in variants:
|
||||||
variant_node = ET.Element('variant')
|
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_preview_nodes(package_node, package, downloadBase, aircraftDirName)
|
||||||
append_tag_nodes(package_node, package)
|
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
|
return package_node
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<PropertyList>
|
||||||
|
<sim>
|
||||||
|
<name>dc3</name>
|
||||||
|
<description>Douglas DC-3</description>
|
||||||
|
<author>Donald Douglas</author>
|
||||||
|
<authors>
|
||||||
|
<author>
|
||||||
|
<name>Donald Douglas</name>
|
||||||
|
<nick>dd</nick>
|
||||||
|
<email>dd@douglas.com</email>
|
||||||
|
<description>Made all the stuff</description>
|
||||||
|
</author>
|
||||||
|
</authors>
|
||||||
|
<urls>
|
||||||
|
<support>https://bugtracker.douglas.com/</support>
|
||||||
|
<home-page>http://www.douglas.com</home-page>
|
||||||
|
</urls>
|
||||||
|
</sim>
|
||||||
|
|
||||||
|
</PropertyList>
|
||||||
+62
-21
@@ -4,7 +4,7 @@ import unittest
|
|||||||
import sgprops
|
import sgprops
|
||||||
import os
|
import os
|
||||||
import catalog
|
import catalog
|
||||||
import lxml.etree as ET
|
import xml.etree.cElementTree as ET
|
||||||
|
|
||||||
catalog.quiet = True
|
catalog.quiet = True
|
||||||
|
|
||||||
@@ -15,24 +15,25 @@ class UpdateCatalogTests(unittest.TestCase):
|
|||||||
self.assertEqual(info['name'], 'F16-A')
|
self.assertEqual(info['name'], 'F16-A')
|
||||||
self.assertEqual(info['primary-set'], True)
|
self.assertEqual(info['primary-set'], True)
|
||||||
self.assertEqual(info['variant-of'], None)
|
self.assertEqual(info['variant-of'], None)
|
||||||
self.assertEqual(info['rating_FDM'], 3)
|
# self.assertEqual(info['rating_FDM'], 3)
|
||||||
self.assertEqual(info['rating_model'], 5)
|
# 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(len(info['tags']), 3)
|
||||||
self.assertEqual(info['minimum-fg-version'], '2017.4')
|
self.assertEqual(info['minimum-fg-version'], '2017.4')
|
||||||
|
|
||||||
authorsArray = info['authors']
|
authors = info['authors']
|
||||||
self.assertNotIn('author', info)
|
self.assertNotIn('author', info)
|
||||||
self.assertEqual(len(authorsArray), 2)
|
self.assertEqual(len(authors.getChildren()), 2)
|
||||||
|
|
||||||
author0 = authorsArray[0]
|
self.assertEqual(authors.getValue('author[0]/name'), 'Wilbur Wright')
|
||||||
self.assertEqual(author0['name'], 'Wilbur Wright')
|
self.assertEqual(authors.getValue('author[0]/nick'), 'wilburw')
|
||||||
self.assertEqual(author0['nick'], 'wilburw')
|
self.assertEqual(authors.getValue('author[0]/email'), 'ww@wright.com')
|
||||||
self.assertEqual(author0['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):
|
def test_scan_dir(self):
|
||||||
(pkg, variants) = catalog.scan_aircraft_dir("testData/Aircraft/f16", ["testData/OtherDir"])
|
(pkg, variants) = catalog.scan_aircraft_dir("testData/Aircraft/f16", ["testData/OtherDir"])
|
||||||
@@ -55,19 +56,17 @@ class UpdateCatalogTests(unittest.TestCase):
|
|||||||
|
|
||||||
authorsArray = f16b['authors']
|
authorsArray = f16b['authors']
|
||||||
self.assertNotIn('author', f16b)
|
self.assertNotIn('author', f16b)
|
||||||
self.assertEqual(len(authorsArray), 2)
|
|
||||||
|
|
||||||
author0 = authorsArray[0]
|
self.assertEqual(authorsArray.getValue('author[0]/name'), 'James T Kirk')
|
||||||
self.assertEqual(author0['name'], 'James T Kirk')
|
self.assertEqual(authorsArray.getValue('author[0]/nick'), 'starlover')
|
||||||
self.assertEqual(author0['nick'], 'starlover')
|
|
||||||
|
|
||||||
f16c = next(v for v in variants if v['id'] == 'f16c')
|
f16c = next(v for v in variants if v['id'] == 'f16c')
|
||||||
self.assertEqual(f16c['variant-of'], 'f16a')
|
self.assertEqual(f16c['variant-of'], 'f16a')
|
||||||
self.assertEqual(f16c['primary-set'], False)
|
self.assertEqual(f16c['primary-set'], False)
|
||||||
|
|
||||||
authorsArray = f16c['authors']
|
authors = f16c['authors']
|
||||||
self.assertNotIn('author', f16c)
|
self.assertNotIn('author', f16c)
|
||||||
self.assertEqual(len(authorsArray), 2)
|
self.assertEqual(len(authors.getChildren()), 2)
|
||||||
|
|
||||||
# test some older constructs for compat
|
# test some older constructs for compat
|
||||||
def test_scan_dir_legacy(self):
|
def test_scan_dir_legacy(self):
|
||||||
@@ -104,7 +103,7 @@ class UpdateCatalogTests(unittest.TestCase):
|
|||||||
os.mkdir("testOutput")
|
os.mkdir("testOutput")
|
||||||
|
|
||||||
cat_file = os.path.join("testOutput", 'catalog_fragment.xml')
|
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)
|
parsed = sgprops.readProps(cat_file)
|
||||||
parsedPkgNode = parsed.getChild("package")
|
parsedPkgNode = parsed.getChild("package")
|
||||||
@@ -125,6 +124,12 @@ class UpdateCatalogTests(unittest.TestCase):
|
|||||||
parsedVariants = parsedPkgNode.getChildren("variant")
|
parsedVariants = parsedPkgNode.getChildren("variant")
|
||||||
self.assertEqual(len(parsedVariants), 3)
|
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
|
# author data verification
|
||||||
self.assertFalse(parsedPkgNode.hasChild('author'));
|
self.assertFalse(parsedPkgNode.hasChild('author'));
|
||||||
parsedAuthors = parsedPkgNode.getChild("authors").getChildren('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("email"), "shatner@enterprise.com")
|
||||||
self.assertEqual(author1.getValue("description"), "Everything")
|
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):
|
def test_minimalAircraft(self):
|
||||||
# test an aircraft with a deliberately spartan -set.xml file with
|
# test an aircraft with a deliberately spartan -set.xml file with
|
||||||
# most interesting data missing
|
# most interesting data missing
|
||||||
@@ -176,7 +217,7 @@ class UpdateCatalogTests(unittest.TestCase):
|
|||||||
os.mkdir("testOutput2")
|
os.mkdir("testOutput2")
|
||||||
|
|
||||||
cat_file = os.path.join("testOutput2", 'catalog_fragment.xml')
|
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)
|
parsed = sgprops.readProps(cat_file)
|
||||||
parsedPkgNode = parsed.getChild("package")
|
parsedPkgNode = parsed.getChild("package")
|
||||||
|
|||||||
Reference in New Issue
Block a user