Compare commits
31 Commits
version/20
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acc3ed54ae | ||
|
|
250152fd7c | ||
|
|
7dbf960291 | ||
|
|
5fa23309c5 | ||
|
|
e8fb2f58f2 | ||
|
|
5bf2814178 | ||
|
|
b621bbe3e8 | ||
|
|
9c41bca63f | ||
|
|
efab6d7e51 | ||
|
|
910e3ec490 | ||
|
|
df6d8be57f | ||
|
|
b670f096be | ||
|
|
b7d27d156f | ||
|
|
51e37ac662 | ||
|
|
1d68e73690 | ||
|
|
aeaf259c59 | ||
|
|
257ba0f733 | ||
|
|
7eb3a8886f | ||
|
|
e86954cc7f | ||
|
|
f23197f811 | ||
|
|
f28db85017 | ||
|
|
3f85e1911e | ||
|
|
b350cd9827 | ||
|
|
8e22064b71 | ||
|
|
7a64df78e3 | ||
|
|
493ad2c306 | ||
|
|
533cec6236 | ||
|
|
0dd0bf3043 | ||
|
|
b0594ed4ef | ||
|
|
f2e86108d4 | ||
|
|
8462f3217a |
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Set default behaviour, in case users don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
.gitattributes text export-ignore
|
||||
.gitignore text export-ignore
|
||||
*.py text
|
||||
*.txt text
|
||||
*.rst text
|
||||
*.xml text
|
||||
*.desktop text
|
||||
*.svg text
|
||||
*.jpg binary
|
||||
*.png binary
|
||||
*.gif binary
|
||||
*.bat text eol=crlf
|
||||
AUTHORS text
|
||||
COPYING text
|
||||
COPYING.* text
|
||||
README.* text
|
||||
Makefile text
|
||||
ChangeLog text
|
||||
ChangeLog.* text
|
||||
/download_and_compile.sh text ident
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -1,19 +1,19 @@
|
||||
[submodule "simgear"]
|
||||
path = simgear
|
||||
url = https://git.code.sf.net/p/flightgear/simgear
|
||||
branch = next
|
||||
branch = release/2017.2
|
||||
[submodule "flightgear"]
|
||||
path = flightgear
|
||||
url = https://git.code.sf.net/p/flightgear/flightgear
|
||||
branch = next
|
||||
branch = release/2017.2
|
||||
[submodule "fgrun"]
|
||||
path = fgrun
|
||||
url = https://git.code.sf.net/p/flightgear/fgrun
|
||||
branch = next
|
||||
[submodule "fgdata"]
|
||||
path = fgdata
|
||||
url = https://git.code.sf.net/p/flightgear/fgdata
|
||||
branch = next
|
||||
url = git://git.code.sf.net/p/flightgear/fgdata
|
||||
branch = release/2017.2
|
||||
[submodule "windows-3rd-party"]
|
||||
path = windows-3rd-party
|
||||
url = https://git.code.sf.net/p/flightgear/windows-3rd-party
|
||||
|
||||
@@ -109,10 +109,6 @@ Source: "{#ThirdPartyDir}\3rdParty.x64\bin\crashrpt_lang.ini"; DestDir: "{app}\b
|
||||
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\CrashSender1403.exe"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "{#VCInstallDir}\redist\x64\Microsoft.VC140.CRT\*.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
|
||||
; 32/64 bits install
|
||||
;NOTE: FGPanel has no 64 bits equivalent, so we are using the 32 bits binary for 32&64 bits OS
|
||||
Source: "{#InstallDir32}\bin\fgpanel.exe"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||
|
||||
; Include the base package
|
||||
#if IncludeData == "TRUE"
|
||||
Source: "X:\fgdata\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
|
||||
|
||||
@@ -38,7 +38,7 @@ cp simgear-*.tar.bz2 ../output/.
|
||||
#####################################################################################
|
||||
echo "Starting on FlightGear"
|
||||
cd ../fgBuild
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" ../flightgear
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" -DFG_BUILD_TYPE=Release ../flightgear
|
||||
|
||||
# compile
|
||||
make
|
||||
@@ -60,4 +60,3 @@ echo "Assembling base package"
|
||||
cd $WORKSPACE
|
||||
|
||||
tar cjf output/FlightGear-$VERSION-data.tar.bz2 fgdata/
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
|
||||
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
|
||||
|
||||
IF %IS_NIGHTLY_BUILD% EQU 1 (
|
||||
SET FGBUILDTYPE=Nightly
|
||||
) ELSE (
|
||||
SET FGBUILDTYPE=Release
|
||||
)
|
||||
|
||||
REM following are for testing the script locally
|
||||
REM SET PATH=%PATH%;%ProgramFiles%\CMake\bin;%ProgramFiles(x86)%\"Inno Setup 5"\
|
||||
REM SET QT5SDK32=C:\Qt\5.6\msvc2015
|
||||
@@ -27,7 +33,8 @@ cmake ..\flightgear -G "Visual Studio 14" ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140 ^
|
||||
-DCMAKE_PREFIX_PATH:PATH=%WORKSPACE%/install/msvc140/OpenSceneGraph ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
|
||||
-DCMAKE_PREFIX_PATH=%QT5SDK32%;%OSG32%
|
||||
-DCMAKE_PREFIX_PATH=%QT5SDK32%;%OSG32% ^
|
||||
-DFG_BUILD_TYPE=%FGBUILDTYPE%
|
||||
cmake --build . --config RelWithDebInfo --target INSTALL
|
||||
|
||||
cd ..
|
||||
@@ -49,7 +56,8 @@ cmake ..\flightgear -G "Visual Studio 14 Win64" ^
|
||||
-DMSVC_3RDPARTY_ROOT=%WORKSPACE%/windows-3rd-party/msvc140 ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140-64 ^
|
||||
-DCMAKE_PREFIX_PATH=%QT5SDK64%;%OSG64%
|
||||
-DCMAKE_PREFIX_PATH=%QT5SDK64%;%OSG64% ^
|
||||
-DFG_BUILD_TYPE=%FGBUILDTYPE%
|
||||
cmake --build . --config RelWithDebInfo --target INSTALL
|
||||
|
||||
cd ..
|
||||
@@ -67,9 +75,10 @@ subst X: %WORKSPACE%.
|
||||
REM ensure output dir is clean since we upload the entirety of it
|
||||
rmdir /S /Q output
|
||||
|
||||
REM archiving PDB files
|
||||
copy %WORKSPACE%\build-fg32\src\Main\RelWithDebInfo\fgfs.pdb %WORKSPACE%\Output\fgfs-x86-%BUILD_NUMBER%.pdb
|
||||
copy %WORKSPACE%\build-fg64\src\Main\RelWithDebInfo\fgfs.pdb %WORKSPACE%\Output\fgfs-x64-%BUILD_NUMBER%.pdb
|
||||
SET CRASHFIX_UPLOAD_URL=http://crashes.flightgear.org/index.php/debugInfo/uploadExternal
|
||||
SET FGFS_PDB=src\Main\RelWithDebInfo\fgfs.pdb
|
||||
ECHO Uploading PDB files to %CRASHFIX_UPLOAD_URL%
|
||||
upload -v -u %CRASHFIX_UPLOAD_URL% FlightGear %WORKSPACE%\build-fg32\%FGFS_PDB% %WORKSPACE%\build-fg64\%FGFS_PDB%
|
||||
|
||||
REM indirect way to get command output into an environment variable
|
||||
set PATH=%OSG32%\bin;%PATH%
|
||||
|
||||
229
catalog/catalog.py
Normal file
229
catalog/catalog.py
Normal file
@@ -0,0 +1,229 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import lxml.etree as ET
|
||||
import os
|
||||
import re
|
||||
import sgprops
|
||||
import sys
|
||||
import catalogTags
|
||||
|
||||
CATALOG_VERSION = 4
|
||||
|
||||
# xml node (robust) get text helper
|
||||
def get_xml_text(e):
|
||||
if e != None and e.text != None:
|
||||
return e.text
|
||||
else:
|
||||
return ''
|
||||
|
||||
# return all available aircraft information from the set file as a
|
||||
# dict
|
||||
def scan_set_file(aircraft_dir, set_file, includes):
|
||||
base_file = os.path.basename(set_file)
|
||||
base_id = base_file[:-8]
|
||||
set_path = os.path.join(aircraft_dir, set_file)
|
||||
|
||||
includes.append(aircraft_dir)
|
||||
root_node = sgprops.readProps(set_path, includePaths = includes)
|
||||
|
||||
if not root_node.hasChild("sim"):
|
||||
return None
|
||||
|
||||
sim_node = root_node.getChild("sim")
|
||||
if sim_node == None:
|
||||
return None
|
||||
|
||||
variant = {}
|
||||
variant['name'] = sim_node.getValue("description", None)
|
||||
variant['status'] = sim_node.getValue("status", None)
|
||||
variant['author'] = sim_node.getValue("author", None)
|
||||
variant['description'] = sim_node.getValue("long-description", None)
|
||||
variant['id'] = base_id
|
||||
|
||||
# allow -set.xml files to declare themselves as primary.
|
||||
# we use this avoid needing a variant-of in every other -set.xml
|
||||
variant['primary-set'] = sim_node.getValue('primary-set', False)
|
||||
|
||||
# extract and record previews for each variant
|
||||
if sim_node.hasChild('previews'):
|
||||
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)
|
||||
|
||||
if sim_node.hasChild('tags'):
|
||||
variant['tags'] = extract_tags(sim_node.getChild('tags'), set_file)
|
||||
|
||||
if sim_node.hasChild('thumbnail'):
|
||||
variant['thumbnail'] = sim_node.getValue("thumbnail", None)
|
||||
|
||||
variant['variant-of'] = sim_node.getValue("variant-of", None)
|
||||
#print ' ', variant
|
||||
return variant
|
||||
|
||||
def extract_previews(previews_node, aircraft_dir):
|
||||
result = []
|
||||
for node in previews_node.getChildren("preview"):
|
||||
previewType = node.getValue("type", None)
|
||||
previewPath = node.getValue("path", None)
|
||||
|
||||
# check path exists in base-name-dir
|
||||
fullPath = os.path.join(aircraft_dir, previewPath)
|
||||
if not os.path.isfile(fullPath):
|
||||
print "Bad preview path, skipping:" + fullPath
|
||||
continue
|
||||
result.append({'type':previewType, 'path':previewPath})
|
||||
|
||||
return result
|
||||
|
||||
def extract_tags(tags_node, set_path):
|
||||
result = []
|
||||
for node in tags_node.getChildren("tag"):
|
||||
tag = node.value
|
||||
# check tag is in the allowed list
|
||||
if not catalogTags.isValidTag(tag):
|
||||
print "Unknown tag value:", tag, " in ", set_path
|
||||
result.append(tag)
|
||||
|
||||
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):
|
||||
setDicts = []
|
||||
primaryAircraft = []
|
||||
package = None
|
||||
|
||||
files = os.listdir(aircraft_dir)
|
||||
for file in sorted(files, key=lambda s: s.lower()):
|
||||
if file.endswith('-set.xml'):
|
||||
try:
|
||||
d = scan_set_file(aircraft_dir, file, includes)
|
||||
if d == None:
|
||||
continue
|
||||
except:
|
||||
print "Skipping set file since couldn't be parsed:", os.path.join(aircraft_dir, file), sys.exc_info()[0]
|
||||
continue
|
||||
|
||||
setDicts.append(d)
|
||||
if d['primary-set']:
|
||||
# ensure explicit primary-set aircraft goes first
|
||||
primaryAircraft.insert(0, d)
|
||||
elif d['variant-of'] == None:
|
||||
primaryAircraft.append(d)
|
||||
|
||||
if len(setDicts) == 0:
|
||||
return None
|
||||
|
||||
# use the first one
|
||||
if len(primaryAircraft) == 0:
|
||||
print "Aircraft has no primary aircraft at all:", aircraft_dir
|
||||
primaryAircraft = [setDicts[0]]
|
||||
|
||||
package = primaryAircraft[0]
|
||||
if not 'thumbnail' in package:
|
||||
package['thumbnail'] = "thumbnail.jpg"
|
||||
|
||||
# variants is just all the set dicts except the first one
|
||||
variants = setDicts
|
||||
variants.remove(package)
|
||||
return (package, variants)
|
||||
|
||||
# create an xml node with text content
|
||||
def make_xml_leaf(name, text):
|
||||
leaf = ET.Element(name)
|
||||
if text != None:
|
||||
if isinstance(text, (int, long)):
|
||||
leaf.text = str(text)
|
||||
else:
|
||||
leaf.text = text
|
||||
else:
|
||||
leaf.text = ''
|
||||
return leaf
|
||||
|
||||
def append_preview_nodes(node, variant, download_base, package_name):
|
||||
if not 'previews' in variant:
|
||||
return
|
||||
|
||||
for preview in variant['previews']:
|
||||
preview_node = ET.Element('preview')
|
||||
preview_url = download_base + 'previews/' + package_name + '_' + preview['path']
|
||||
preview_node.append( make_xml_leaf('type', preview['type']) )
|
||||
preview_node.append( make_xml_leaf('url', preview_url) )
|
||||
preview_node.append( make_xml_leaf('path', preview['path']) )
|
||||
node.append(preview_node)
|
||||
|
||||
def append_tag_nodes(node, variant):
|
||||
if not 'tags' in variant:
|
||||
return
|
||||
|
||||
for tag in variant['tags']:
|
||||
node.append(make_xml_leaf('tag', tag))
|
||||
|
||||
def make_aircraft_node(aircraftDirName, package, variants, downloadBase):
|
||||
#print "package:", package
|
||||
#print "variants:", variants
|
||||
package_node = ET.Element('package')
|
||||
package_node.append( make_xml_leaf('name', package['name']) )
|
||||
package_node.append( make_xml_leaf('status', package['status']) )
|
||||
package_node.append( make_xml_leaf('author', package['author']) )
|
||||
package_node.append( make_xml_leaf('description', package['description']) )
|
||||
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']) )
|
||||
package_node.append( make_xml_leaf('id', package['id']) )
|
||||
for variant in variants:
|
||||
variant_node = ET.Element('variant')
|
||||
package_node.append(variant_node)
|
||||
variant_node.append( make_xml_leaf('id', variant['id']) )
|
||||
variant_node.append( make_xml_leaf('name', variant['name']) )
|
||||
if 'description' in variant:
|
||||
variant_node.append( make_xml_leaf('description', variant['description']) )
|
||||
|
||||
if 'author' in variant:
|
||||
variant_node.append( make_xml_leaf('author', variant['author']) )
|
||||
|
||||
if 'thumbnail' in variant:
|
||||
# note here we prefix with the package name, since the thumbnail path
|
||||
# is assumed to be unique within the package
|
||||
thumbUrl = downloadBase + "thumbnails/" + aircraftDirName + '_' + variant['thumbnail']
|
||||
variant_node.append(make_xml_leaf('thumbnail', thumbUrl))
|
||||
variant_node.append(make_xml_leaf('thumbnail-path', variant['thumbnail']))
|
||||
|
||||
variantOf = variant['variant-of']
|
||||
if variantOf is None:
|
||||
variant_node.append(make_xml_leaf('variant-of', '_primary_'))
|
||||
else:
|
||||
variant_node.append(make_xml_leaf('variant-of', variantOf))
|
||||
|
||||
append_preview_nodes(variant_node, variant, downloadBase, aircraftDirName)
|
||||
append_tag_nodes(variant_node, variant)
|
||||
|
||||
package_node.append( make_xml_leaf('dir', aircraftDirName) )
|
||||
|
||||
download_url = downloadBase + aircraftDirName + '.zip'
|
||||
thumbnail_url = downloadBase + 'thumbnails/' + aircraftDirName + '_' + package['thumbnail']
|
||||
|
||||
package_node.append( make_xml_leaf('url', download_url) )
|
||||
package_node.append( make_xml_leaf('thumbnail', thumbnail_url) )
|
||||
package_node.append( make_xml_leaf('thumbnail-path', package['thumbnail']))
|
||||
|
||||
append_preview_nodes(package_node, package, downloadBase, aircraftDirName)
|
||||
append_tag_nodes(package_node, package)
|
||||
|
||||
return package_node
|
||||
@@ -1,80 +1,162 @@
|
||||
aircraftTypeTags = [
|
||||
"ga", "fighter", "helicopter", "glider", "spaceship", "bomber", "groundvehicle",
|
||||
"tanker", "cargo", "transport", "bizjet", "trainer", "airship", "balloon"
|
||||
"aerobatic",
|
||||
"airship",
|
||||
"balloon",
|
||||
"bizjet",
|
||||
"bomber",
|
||||
"cargo",
|
||||
"carrier",
|
||||
"fighter",
|
||||
"ga",
|
||||
"glider",
|
||||
"groundvehicle",
|
||||
"helicopter",
|
||||
"racer",
|
||||
"spaceship",
|
||||
"tanker",
|
||||
"trainer",
|
||||
"transport",
|
||||
"ultralight",
|
||||
"reconnaissance",
|
||||
"seacraft",
|
||||
"crop-duster",
|
||||
"bush-plane"
|
||||
]
|
||||
|
||||
manufacturerTags = [
|
||||
"boeing", "cessna", "diamond", "douglas", "bell", "piper",
|
||||
"airbus", "vickers", "lockheed", "fokker",
|
||||
"embraer", "bombardier", "pilatus", "robin",
|
||||
"eurocopter"
|
||||
"airbus",
|
||||
"antonov",
|
||||
"atr",
|
||||
"avro",
|
||||
"bell",
|
||||
"bleriot",
|
||||
"boeing",
|
||||
"bombardier",
|
||||
"caudron",
|
||||
"cessna",
|
||||
"consolidated",
|
||||
"dassault",
|
||||
"diamond",
|
||||
"dornier",
|
||||
"douglas",
|
||||
"embraer",
|
||||
"eurocopter",
|
||||
"fairchild",
|
||||
"fairey",
|
||||
"focke-wulf",
|
||||
"fokker",
|
||||
"general-dynamics",
|
||||
"gotha",
|
||||
"grumman",
|
||||
"handley-page",
|
||||
"hawker",
|
||||
"heinkel",
|
||||
"ilyushin",
|
||||
"junkers",
|
||||
"lockheed",
|
||||
"mc-donnell-douglas",
|
||||
"messerschmitt",
|
||||
"mikoyan-gurevich",
|
||||
"mitsubishi",
|
||||
"northrop",
|
||||
"pilatus",
|
||||
"piper",
|
||||
"robin",
|
||||
"saab",
|
||||
"short",
|
||||
"sopwith",
|
||||
"spad",
|
||||
"sukhoi",
|
||||
"supermarine",
|
||||
"tupolev",
|
||||
"vickers",
|
||||
"vought",
|
||||
"yakovlev"
|
||||
]
|
||||
|
||||
eraTags = [
|
||||
"early-pioneers",
|
||||
"ww1",
|
||||
"1910s",
|
||||
"1920s",
|
||||
"1930s",
|
||||
"golden-age",
|
||||
"ww2",
|
||||
"coldwar", "vietnam",
|
||||
"1940s",
|
||||
"1950s",
|
||||
"1960s",
|
||||
"1970s",
|
||||
"1980s",
|
||||
"1990s",
|
||||
"2000s",
|
||||
"2010s",
|
||||
"coldwar",
|
||||
"early-pioneers",
|
||||
"golden-age",
|
||||
"gulfwar1",
|
||||
"gulfwar2"
|
||||
"gulfwar2",
|
||||
"vietnam",
|
||||
"ww1",
|
||||
"ww2"
|
||||
]
|
||||
|
||||
featureTags = [
|
||||
"ifr",
|
||||
"retractable-gear",
|
||||
"fixed-gear",
|
||||
"tail-dragger",
|
||||
"seaplane",
|
||||
"vtol",
|
||||
"stol",
|
||||
"experimental",
|
||||
"prototype",
|
||||
"fictional",
|
||||
"aerobatic",
|
||||
"airship",
|
||||
"amphibious",
|
||||
"biplane",
|
||||
"triplane",
|
||||
"canard",
|
||||
"castering-wheel",
|
||||
"delta",
|
||||
"etops",
|
||||
"experimental",
|
||||
"fictional",
|
||||
"fixed-gear",
|
||||
"floats",
|
||||
"glass-cockpit",
|
||||
"high-wing",
|
||||
"h-tail",
|
||||
"hud",
|
||||
"ifr",
|
||||
"prototype",
|
||||
"refuel",
|
||||
"retractable-gear",
|
||||
"seaplane",
|
||||
"skis",
|
||||
"stol",
|
||||
"supersonic",
|
||||
"t-tail",
|
||||
"v-tail",
|
||||
"high-wing",
|
||||
"cannard",
|
||||
"tail-dragger",
|
||||
"tricycle",
|
||||
"tail-hook",
|
||||
"refuel",
|
||||
"delta",
|
||||
"triplane",
|
||||
"v-tail",
|
||||
"variable-geometry",
|
||||
"glass-cockpit",
|
||||
"hud",
|
||||
"etops",
|
||||
"floats",
|
||||
"amphibious",
|
||||
"airship",
|
||||
"aerobatic"
|
||||
"vtol",
|
||||
"wing-fold"
|
||||
]
|
||||
|
||||
propulsionTags = [
|
||||
"piston", "radial",
|
||||
"afterburner",
|
||||
"diesel",
|
||||
"variable-pitch",
|
||||
"electric",
|
||||
"jet",
|
||||
"propeller",
|
||||
"piston",
|
||||
"radial",
|
||||
"rocket",
|
||||
"single-engine",
|
||||
"supercharged",
|
||||
"turboprop",
|
||||
"jet", "afterburner", "rocket",
|
||||
"electric",
|
||||
"twin-engine",
|
||||
"single-engine"
|
||||
"variable-pitch",
|
||||
"fixed-pitch"
|
||||
]
|
||||
|
||||
simFeatureTags = [
|
||||
"tow",
|
||||
"dual-controls",
|
||||
"rembrandt"
|
||||
"rembrandt",
|
||||
"tow",
|
||||
"wildfire"
|
||||
]
|
||||
|
||||
tags = aircraftTypeTags + manufacturerTags + eraTags + simFeatureTags + propulsionTags + featureTags
|
||||
|
||||
def isValidTag(maybeTag):
|
||||
return maybeTag in tags
|
||||
|
||||
@@ -185,12 +185,13 @@ class PropsHandler(handler.ContentHandler):
|
||||
if 'include' in attrs.keys():
|
||||
self.handleInclude(attrs['include'])
|
||||
return
|
||||
|
||||
|
||||
currentState = self._stateStack[-1]
|
||||
if 'n' in attrs.keys():
|
||||
try:
|
||||
index = int(attrs['n'])
|
||||
except:
|
||||
print "Invalid index at line:", self._locator.getLineNumber(), "of", self._path
|
||||
raise IndexError("Invalid index at line:", self._locator.getLineNumber(), "of", self._path)
|
||||
|
||||
currentState.recordExplicitIndex(name, index)
|
||||
|
||||
0
catalog/testData/Aircraft/f16/Previews/cockpit.png
Normal file
0
catalog/testData/Aircraft/f16/Previews/cockpit.png
Normal file
12
catalog/testData/Aircraft/f16/f16-common.xml
Normal file
12
catalog/testData/Aircraft/f16/f16-common.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<PropertyList>
|
||||
<sim include="settings-common.xml">
|
||||
<author>Wilbur Wright</author>
|
||||
<tags>
|
||||
<tag>fighter</tag>
|
||||
<tag>1980s</tag>
|
||||
<tag>glass-cockpit</tag>
|
||||
</tags>
|
||||
</sim>
|
||||
|
||||
</PropertyList>
|
||||
11
catalog/testData/Aircraft/f16/f16-trainer-set.xml
Normal file
11
catalog/testData/Aircraft/f16/f16-trainer-set.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<PropertyList include="f16-common.xml">
|
||||
<sim>
|
||||
<name>f16-trainer</name>
|
||||
<description>F16 Trainer</description>
|
||||
<long-description>Twin-seat trainer version of the F16</long-description>
|
||||
|
||||
|
||||
</sim>
|
||||
|
||||
</PropertyList>
|
||||
36
catalog/testData/Aircraft/f16/f16a-set.xml
Normal file
36
catalog/testData/Aircraft/f16/f16a-set.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<PropertyList include="f16-common.xml">
|
||||
<sim>
|
||||
<name>f16a</name>
|
||||
<description>F16-A</description>
|
||||
<long-description>The F16 is compact, light-weight multi-role fighter used around the world</long-description>
|
||||
|
||||
<primary-set type="bool">true</primary-set>
|
||||
|
||||
<rating>
|
||||
<FDM type="int">3</FDM>
|
||||
<systems type="int">1</systems>
|
||||
<cockpit type="int">2</cockpit>
|
||||
<model type="int">5</model>
|
||||
</rating>
|
||||
|
||||
<previews>
|
||||
<preview>
|
||||
<type>exterior</type>
|
||||
<splash type="bool">true</splash>
|
||||
<path>Previews/exterior-1.png</path>
|
||||
</preview>
|
||||
<preview>
|
||||
<type>exterior</type>
|
||||
<splash type="bool">true</splash>
|
||||
<path>Previews/exterior-f16a-2.png</path>
|
||||
</preview>
|
||||
<preview>
|
||||
<type>panel</type>
|
||||
<splash type="bool">false</splash>
|
||||
<path>Previews/cockpit.png</path>
|
||||
</preview>
|
||||
</previews>
|
||||
</sim>
|
||||
|
||||
</PropertyList>
|
||||
12
catalog/testData/Aircraft/f16/f16b-set.xml
Normal file
12
catalog/testData/Aircraft/f16/f16b-set.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<PropertyList include="f16-common.xml">
|
||||
<sim>
|
||||
<name>f16b</name>
|
||||
<description>F16-B</description>
|
||||
<long-description>The F16-B is an upgraded version of the F16A.</long-description>
|
||||
<variant-of>f16a</variant-of>
|
||||
|
||||
<author>James T Kirk</author>
|
||||
</sim>
|
||||
|
||||
</PropertyList>
|
||||
10
catalog/testData/Aircraft/f16/f16c-set.xml
Normal file
10
catalog/testData/Aircraft/f16/f16c-set.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<PropertyList include="f16-common.xml">
|
||||
<sim>
|
||||
<name>f16c</name>
|
||||
<description>F16-C</description>
|
||||
<long-description>The F16-C is an upgraded version of the F16A.</long-description>
|
||||
<variant-of>f16a</variant-of>
|
||||
</sim>
|
||||
|
||||
</PropertyList>
|
||||
12
catalog/testData/OtherDir/settings-common.xml
Normal file
12
catalog/testData/OtherDir/settings-common.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!-- this file exists to test including + overlaying in the set XML -->
|
||||
|
||||
<PropertyList>
|
||||
<views>
|
||||
<view n="0">
|
||||
<foo>dsdddd</foo>
|
||||
</view>
|
||||
</views>
|
||||
|
||||
</PropertyList>
|
||||
116
catalog/test_catalog.py
Executable file
116
catalog/test_catalog.py
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import unittest
|
||||
import sgprops
|
||||
import os
|
||||
import catalog
|
||||
import lxml.etree as ET
|
||||
|
||||
class UpdateCatalogTests(unittest.TestCase):
|
||||
def test_scan_set(self):
|
||||
info = catalog.scan_set_file("testData/Aircraft/f16", "f16a-set.xml", ["testData/OtherDir"])
|
||||
self.assertEqual(info['id'], 'f16a')
|
||||
self.assertEqual(info['name'], 'F16-A')
|
||||
self.assertEqual(info['primary-set'], True)
|
||||
self.assertEqual(info['variant-of'], None)
|
||||
self.assertEqual(info['author'], 'Wilbur Wright')
|
||||
self.assertEqual(info['rating_FDM'], 3)
|
||||
self.assertEqual(info['rating_model'], 5)
|
||||
self.assertEqual(len(info['tags']), 3)
|
||||
|
||||
def test_scan_dir(self):
|
||||
(pkg, variants) = catalog.scan_aircraft_dir("testData/Aircraft/f16", ["testData/OtherDir"])
|
||||
|
||||
self.assertEqual(pkg['id'], 'f16a')
|
||||
f16trainer = next(v for v in variants if v['id'] == 'f16-trainer')
|
||||
self.assertEqual(pkg['author'], 'Wilbur Wright')
|
||||
self.assertEqual(len(variants), 3)
|
||||
|
||||
# test variant relatonship between
|
||||
self.assertEqual(pkg['variant-of'], None)
|
||||
self.assertEqual(pkg['primary-set'], True)
|
||||
|
||||
self.assertEqual(f16trainer['variant-of'], None)
|
||||
self.assertEqual(f16trainer['primary-set'], False)
|
||||
|
||||
f16b = next(v for v in variants if v['id'] == 'f16b')
|
||||
self.assertEqual(f16b['variant-of'], 'f16a')
|
||||
self.assertEqual(f16b['primary-set'], False)
|
||||
self.assertEqual(f16b['author'], 'James T Kirk')
|
||||
|
||||
f16c = next(v for v in variants if v['id'] == 'f16c')
|
||||
self.assertEqual(f16c['variant-of'], 'f16a')
|
||||
self.assertEqual(f16c['primary-set'], False)
|
||||
|
||||
self.assertEqual(f16c['author'], 'Wilbur Wright')
|
||||
|
||||
|
||||
def test_extract_previews(self):
|
||||
info = catalog.scan_set_file("testData/Aircraft/f16", "f16a-set.xml", ["testData/OtherDir"])
|
||||
previews = info['previews']
|
||||
self.assertEqual(len(previews), 3)
|
||||
self.assertEqual(2, len([p for p in previews if p['type'] == 'exterior']))
|
||||
self.assertEqual(1, len([p for p in previews if p['type'] == 'panel']))
|
||||
self.assertEqual(1, len([p for p in previews if p['path'] == 'Previews/exterior-1.png']))
|
||||
|
||||
def test_extract_tags(self):
|
||||
info = catalog.scan_set_file("testData/Aircraft/f16", "f16a-set.xml", ["testData/OtherDir"])
|
||||
tags = info['tags']
|
||||
|
||||
def test_node_creation(self):
|
||||
(pkg, variants) = catalog.scan_aircraft_dir("testData/Aircraft/f16", ["testData/OtherDir"])
|
||||
|
||||
catalog_node = ET.Element('PropertyList')
|
||||
catalog_root = ET.ElementTree(catalog_node)
|
||||
|
||||
pkgNode = catalog.make_aircraft_node('f16', pkg, variants, "http://foo.com/testOutput/")
|
||||
catalog_node.append(pkgNode)
|
||||
|
||||
# write out so we can parse using sgprops
|
||||
# yes we are round-tripping via the disk, if you can improve
|
||||
# then feel free..
|
||||
if not os.path.isdir("testOutput"):
|
||||
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)
|
||||
|
||||
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'), 'f16');
|
||||
self.assertEqual(parsedPkgNode.getValue('url'), 'http://foo.com/testOutput/f16.zip');
|
||||
self.assertEqual(parsedPkgNode.getValue('thumbnail'), 'http://foo.com/testOutput/thumbnails/f16_thumbnail.jpg');
|
||||
self.assertEqual(parsedPkgNode.getValue('thumbnail-path'), 'thumbnail.jpg');
|
||||
|
||||
self.assertEqual(parsedPkgNode.getValue('name'), pkg['name']);
|
||||
self.assertEqual(parsedPkgNode.getValue('description'), pkg['description']);
|
||||
self.assertEqual(parsedPkgNode.getValue('author'), "Wilbur Wright");
|
||||
|
||||
parsedVariants = parsedPkgNode.getChildren("variant")
|
||||
self.assertEqual(len(parsedVariants), 3)
|
||||
|
||||
f16ANode = parsedPkgNode
|
||||
self.assertEqual(f16ANode.getValue('name'), 'F16-A');
|
||||
|
||||
for index, pv in enumerate(parsedVariants):
|
||||
var = variants[index]
|
||||
self.assertEqual(pv.getValue('name'), var['name']);
|
||||
self.assertEqual(pv.getValue('description'), var['description']);
|
||||
|
||||
if (var['id'] == 'f16-trainer'):
|
||||
self.assertEqual(pv.getValue('variant-of'), '_primary_')
|
||||
self.assertEqual(pv.getValue('author'), "Wilbur Wright");
|
||||
elif (var['id'] == 'f16b'):
|
||||
self.assertEqual(pv.getValue('variant-of'), 'f16a')
|
||||
self.assertEqual(pv.getValue('description'), 'The F16-B is an upgraded version of the F16A.')
|
||||
self.assertEqual(pv.getValue('author'), "James T Kirk");
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -11,6 +11,8 @@ import subprocess
|
||||
import time
|
||||
import sgprops
|
||||
import sys
|
||||
import catalogTags
|
||||
import catalog
|
||||
|
||||
CATALOG_VERSION = 4
|
||||
|
||||
@@ -34,127 +36,6 @@ def get_xml_text(e):
|
||||
else:
|
||||
return ''
|
||||
|
||||
# create an xml node with text content
|
||||
def make_xml_leaf(name, text):
|
||||
leaf = ET.Element(name)
|
||||
if text != None:
|
||||
if isinstance(text, (int, long)):
|
||||
leaf.text = str(text)
|
||||
else:
|
||||
leaf.text = text
|
||||
else:
|
||||
leaf.text = ''
|
||||
return leaf
|
||||
|
||||
# return all available aircraft information from the set file as a
|
||||
# dict
|
||||
def scan_set_file(aircraft_dir, set_file):
|
||||
global includes
|
||||
|
||||
base_file = os.path.basename(set_file)
|
||||
base_id = base_file[:-8]
|
||||
set_path = os.path.join(aircraft_dir, set_file)
|
||||
|
||||
local_includes = includes
|
||||
local_includes.append(aircraft_dir)
|
||||
root_node = sgprops.readProps(set_path, includePaths = local_includes)
|
||||
|
||||
if not root_node.hasChild("sim"):
|
||||
return None
|
||||
|
||||
sim_node = root_node.getChild("sim")
|
||||
if sim_node == None:
|
||||
return None
|
||||
|
||||
variant = {}
|
||||
variant['name'] = sim_node.getValue("description", None)
|
||||
variant['status'] = sim_node.getValue("status", None)
|
||||
variant['author'] = sim_node.getValue("author", None)
|
||||
variant['description'] = sim_node.getValue("long-description", None)
|
||||
variant['id'] = base_id
|
||||
|
||||
# allow -set.xml files to declare themselves as primary.
|
||||
# we use this avoid needing a variant-of in every other -set.xml
|
||||
variant['primary-set'] = sim_node.getValue('primary-set', False)
|
||||
|
||||
# extract and record previews for each variant
|
||||
if sim_node.hasChild('previews'):
|
||||
print "has previews ..."
|
||||
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['variant-of'] = sim_node.getValue("variant-of", None)
|
||||
#print ' ', variant
|
||||
return variant
|
||||
|
||||
def extract_previews(previews_node, aircraft_dir):
|
||||
result = []
|
||||
for node in previews_node.getChildren("preview"):
|
||||
previewType = node.getValue("type", None)
|
||||
previewPath = node.getValue("path", None)
|
||||
|
||||
# check path exists in base-name-dir
|
||||
fullPath = os.path.join(aircraft_dir, previewPath)
|
||||
if not os.path.isfile(fullPath):
|
||||
print "Bad preview path, skipping:" + fullPath
|
||||
continue
|
||||
result.append({'type':previewType, 'path':previewPath})
|
||||
|
||||
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):
|
||||
# old way of finding the master aircraft: it's the only one whose
|
||||
# variant-of is empty. All the others have an actual value
|
||||
# newer alternative is to specify one -set.xml as the primary. All the
|
||||
# others are therefore variants.
|
||||
setDicts = []
|
||||
found_master = False
|
||||
package = None
|
||||
|
||||
files = os.listdir(aircraft_dir)
|
||||
for file in sorted(files, key=lambda s: s.lower()):
|
||||
if file.endswith('-set.xml'):
|
||||
try:
|
||||
d = scan_set_file(aircraft_dir, file)
|
||||
if d == None:
|
||||
continue
|
||||
except:
|
||||
print "Skipping set file since couldn't be parsed:", os.path.join(aircraft_dir, file), sys.exc_info()[0]
|
||||
continue
|
||||
|
||||
setDicts.append(d)
|
||||
if d['primary-set']:
|
||||
found_master = True
|
||||
package = d
|
||||
|
||||
# didn't find a dict identified explicitly as the primary, look for one
|
||||
# with an undefined variant-of
|
||||
if not found_master:
|
||||
for d in setDicts:
|
||||
if d['variant-of'] == '':
|
||||
found_master = True
|
||||
package = d
|
||||
break
|
||||
|
||||
if not found_master:
|
||||
if len(setDicts) > 1:
|
||||
print "Warning, no explicit primary set.xml in " + aircraft_dir
|
||||
# use the first one
|
||||
package = setDicts[0]
|
||||
|
||||
# variants is just all the set dicts except the master
|
||||
variants = setDicts
|
||||
variants.remove(package)
|
||||
return (package, variants)
|
||||
|
||||
# use svn commands to report the last change date within dir
|
||||
def last_change_date_svn(dir):
|
||||
command = [ 'svn', 'info', dir ]
|
||||
@@ -203,18 +84,6 @@ def get_md5sum(file):
|
||||
f.close()
|
||||
return md5sum
|
||||
|
||||
def append_preview_nodes(node, variant, download_base, package_name):
|
||||
if not 'previews' in variant:
|
||||
return
|
||||
|
||||
for preview in variant['previews']:
|
||||
preview_node = ET.Element('preview')
|
||||
preview_url = download_base + 'previews/' + package_name + '_' + preview['path']
|
||||
preview_node.append( make_xml_leaf('type', preview['type']) )
|
||||
preview_node.append( make_xml_leaf('url', preview_url) )
|
||||
preview_node.append( make_xml_leaf('path', preview['path']) )
|
||||
node.append(preview_node)
|
||||
|
||||
def copy_previews_for_variant(variant, package_name, package_dir, previews_dir):
|
||||
if not 'previews' in variant:
|
||||
return
|
||||
@@ -234,6 +103,95 @@ def copy_previews_for_package(package, variants, package_name, package_dir, prev
|
||||
for v in variants:
|
||||
copy_previews_for_variant(v, package_name, package_dir, previews_dir)
|
||||
|
||||
def copy_thumbnail_for_variant(variant, package_name, package_dir, thumbnails_dir):
|
||||
if not 'thumbnail' in variant:
|
||||
return
|
||||
|
||||
thumb_src = os.path.join(package_dir, variant['thumbnail'])
|
||||
thumb_dst = os.path.join(thumbnails_dir, package_name + '_' + variant['thumbnail'])
|
||||
|
||||
dir = os.path.dirname(thumb_dst)
|
||||
if not os.path.isdir(dir):
|
||||
os.makedirs(dir)
|
||||
if os.path.exists(thumb_src):
|
||||
shutil.copy2(thumb_src, thumb_dst)
|
||||
|
||||
def copy_thumbnails_for_package(package, variants, package_name, package_dir, thumbnails_dir):
|
||||
copy_thumbnail_for_variant(package, package_name, package_dir, thumbnails_dir)
|
||||
|
||||
# and now each variant in turn
|
||||
for v in variants:
|
||||
copy_thumbnail_for_variant(v, package_name, package_dir, thumbnails_dir)
|
||||
|
||||
def process_aircraft_dir(name, repo_path):
|
||||
global includes
|
||||
global download_base
|
||||
global output_dir
|
||||
global valid_zips
|
||||
global previews_dir
|
||||
|
||||
aircraft_dir = os.path.join(repo_path, name)
|
||||
if not os.path.isdir(aircraft_dir):
|
||||
return
|
||||
|
||||
(package, variants) = catalog.scan_aircraft_dir(aircraft_dir, includes)
|
||||
if package == None:
|
||||
print "skipping:", name, "(no -set.xml files)"
|
||||
return
|
||||
|
||||
print "%s:" % name,
|
||||
|
||||
package_node = catalog.make_aircraft_node(name, package, variants, download_base)
|
||||
|
||||
download_url = download_base + name + '.zip'
|
||||
thumbnail_url = download_base + 'thumbnails/' + name + '_' + package['thumbnail']
|
||||
|
||||
# get cached md5sum if it exists
|
||||
md5sum = get_xml_text(md5sum_root.find(str('aircraft_' + name)))
|
||||
|
||||
# now do the packaging and rev number stuff
|
||||
dir_mtime = scan_dir_for_change_date_mtime(aircraft_dir)
|
||||
if repo_type == 'svn':
|
||||
rev = last_change_date_svn(aircraft_dir)
|
||||
else:
|
||||
d = datetime.datetime.utcfromtimestamp(dir_mtime)
|
||||
rev = d.strftime("%Y%m%d")
|
||||
package_node.append( catalog.make_xml_leaf('revision', rev) )
|
||||
#print "rev:", rev
|
||||
#print "dir mtime:", dir_mtime
|
||||
zipfile = os.path.join( output_dir, name + '.zip' )
|
||||
valid_zips.append(name + '.zip')
|
||||
if not os.path.exists(zipfile) \
|
||||
or dir_mtime > os.path.getmtime(zipfile) \
|
||||
or args.clean:
|
||||
# rebuild zip file
|
||||
print "updating:", zipfile
|
||||
make_aircraft_zip(repo_path, name, zipfile)
|
||||
md5sum = get_md5sum(zipfile)
|
||||
else:
|
||||
print "(no change)"
|
||||
if md5sum == "":
|
||||
md5sum = get_md5sum(zipfile)
|
||||
filesize = os.path.getsize(zipfile)
|
||||
package_node.append( catalog.make_xml_leaf('md5', md5sum) )
|
||||
package_node.append( catalog.make_xml_leaf('file-size-bytes', filesize) )
|
||||
|
||||
# handle md5sum cache
|
||||
node = md5sum_root.find('aircraft_' + name)
|
||||
if node != None:
|
||||
node.text = md5sum
|
||||
else:
|
||||
md5sum_root.append( catalog.make_xml_leaf('aircraft_' + name, md5sum) )
|
||||
|
||||
# handle thumbnails
|
||||
copy_thumbnails_for_package(package, variants, name, aircraft_dir, thumbnail_dir)
|
||||
|
||||
catalog_node.append(package_node)
|
||||
|
||||
# copy previews for the package and variants into the
|
||||
# output directory
|
||||
copy_previews_for_package(package, variants, name, aircraft_dir, previews_dir)
|
||||
|
||||
#def get_file_stats(file):
|
||||
# f = open(file, 'r')
|
||||
# md5 = hashlib.md5(f.read()).hexdigest()
|
||||
@@ -266,6 +224,9 @@ else:
|
||||
scm_list = config_node.findall('scm')
|
||||
upload_node = config_node.find('upload')
|
||||
download_base = get_xml_text(config_node.find('download-url'))
|
||||
if not download_base.endswith('/'):
|
||||
download_base += '/'
|
||||
|
||||
output_dir = get_xml_text(config_node.find('local-output'))
|
||||
if output_dir == '':
|
||||
output_dir = os.path.join(args.dir, 'output')
|
||||
@@ -339,106 +300,8 @@ for scm in scm_list:
|
||||
print "skipping:", name
|
||||
continue
|
||||
|
||||
aircraft_dir = os.path.join(repo_path, name)
|
||||
if os.path.isdir(aircraft_dir):
|
||||
print "%s:" % name,
|
||||
(package, variants) = scan_aircraft_dir(aircraft_dir)
|
||||
if package == None:
|
||||
print "skipping:", name, "(no -set.xml files)"
|
||||
continue
|
||||
#print "package:", package
|
||||
#print "variants:", variants
|
||||
package_node = ET.Element('package')
|
||||
package_node.append( make_xml_leaf('name', package['name']) )
|
||||
package_node.append( make_xml_leaf('status', package['status']) )
|
||||
package_node.append( make_xml_leaf('author', package['author']) )
|
||||
package_node.append( make_xml_leaf('description', package['description']) )
|
||||
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']) )
|
||||
package_node.append( make_xml_leaf('id', package['id']) )
|
||||
for variant in variants:
|
||||
variant_node = ET.Element('variant')
|
||||
package_node.append(variant_node)
|
||||
variant_node.append( make_xml_leaf('id', variant['id']) )
|
||||
variant_node.append( make_xml_leaf('name', variant['name']) )
|
||||
if 'description' in variant:
|
||||
variant_node.append( make_xml_leaf('description', variant['description']) )
|
||||
|
||||
if 'author' in variant:
|
||||
variant_node.append( make_xml_leaf('author', variant['author']) )
|
||||
|
||||
append_preview_nodes(variant_node, variant, download_base, name)
|
||||
|
||||
package_node.append( make_xml_leaf('dir', name) )
|
||||
if not download_base.endswith('/'):
|
||||
download_base += '/'
|
||||
download_url = download_base + name + '.zip'
|
||||
thumbnail_url = download_base + 'thumbnails/' + name + '_thumbnail.jpg'
|
||||
package_node.append( make_xml_leaf('url', download_url) )
|
||||
package_node.append( make_xml_leaf('thumbnail', thumbnail_url) )
|
||||
|
||||
append_preview_nodes(package_node, package, download_base, name)
|
||||
|
||||
# todo: url (download), thumbnail (download url)
|
||||
|
||||
# get cached md5sum if it exists
|
||||
md5sum = get_xml_text(md5sum_root.find(str('aircraft_' + name)))
|
||||
|
||||
# now do the packaging and rev number stuff
|
||||
dir_mtime = scan_dir_for_change_date_mtime(aircraft_dir)
|
||||
if repo_type == 'svn':
|
||||
rev = last_change_date_svn(aircraft_dir)
|
||||
else:
|
||||
d = datetime.datetime.utcfromtimestamp(dir_mtime)
|
||||
rev = d.strftime("%Y%m%d")
|
||||
package_node.append( make_xml_leaf('revision', rev) )
|
||||
#print "rev:", rev
|
||||
#print "dir mtime:", dir_mtime
|
||||
zipfile = os.path.join( output_dir, name + '.zip' )
|
||||
valid_zips.append(name + '.zip')
|
||||
if not os.path.exists(zipfile) \
|
||||
or dir_mtime > os.path.getmtime(zipfile) \
|
||||
or args.clean:
|
||||
# rebuild zip file
|
||||
print "updating:", zipfile
|
||||
make_aircraft_zip(repo_path, name, zipfile)
|
||||
md5sum = get_md5sum(zipfile)
|
||||
else:
|
||||
print "(no change)"
|
||||
if md5sum == "":
|
||||
md5sum = get_md5sum(zipfile)
|
||||
filesize = os.path.getsize(zipfile)
|
||||
package_node.append( make_xml_leaf('md5', md5sum) )
|
||||
package_node.append( make_xml_leaf('file-size-bytes', filesize) )
|
||||
|
||||
# handle md5sum cache
|
||||
node = md5sum_root.find('aircraft_' + name)
|
||||
if node != None:
|
||||
node.text = md5sum
|
||||
else:
|
||||
md5sum_root.append( make_xml_leaf('aircraft_' + name, md5sum) )
|
||||
|
||||
# handle thumbnails
|
||||
thumbnail_src = os.path.join(aircraft_dir, 'thumbnail.jpg')
|
||||
thumbnail_dst = os.path.join(thumbnail_dir, name + '_thumbnail.jpg')
|
||||
if os.path.exists(thumbnail_src):
|
||||
shutil.copy2(thumbnail_src, thumbnail_dst)
|
||||
catalog_node.append(package_node)
|
||||
package_node.append( make_xml_leaf('thumbnail-path', 'thumbnail.jpg') )
|
||||
|
||||
# copy previews for the package and variants into the
|
||||
# output directory
|
||||
copy_previews_for_package(package, variants, name, aircraft_dir, previews_dir)
|
||||
# process each aircraft in turn
|
||||
process_aircraft_dir(name, repo_path)
|
||||
|
||||
# write out the master catalog file
|
||||
cat_file = os.path.join(output_dir, 'catalog.xml')
|
||||
|
||||
@@ -17,7 +17,15 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
VERSION="2.34"
|
||||
script_blob_id='$Id$'
|
||||
# Slightly tricky substitution to avoid our regexp being wildly replaced with
|
||||
# the blob name (id) when the script is checked out:
|
||||
#
|
||||
# First extract the hexadecimal blob object name followed by a '$'
|
||||
VERSION="$(echo "$script_blob_id" | sed 's@\$Id: *\([0-9a-f]\+\) *@\1@')"
|
||||
# Then remove the trailing '$'
|
||||
VERSION="${VERSION%\$}"
|
||||
|
||||
FGVERSION="release/$(git ls-remote --heads https://git.code.sf.net/p/flightgear/flightgear|grep '\/release\/'|cut -f4 -d'/'|sort -t . -k 1,1n -k2,2n -k3,3n|tail -1)"
|
||||
|
||||
#######################################################
|
||||
@@ -100,6 +108,16 @@ function _logSep(){
|
||||
echo "***********************************" >> $LOGFILE
|
||||
}
|
||||
|
||||
function _aptUpdate(){
|
||||
echo "Asking password for 'apt-get update'..."
|
||||
sudo apt-get update
|
||||
}
|
||||
|
||||
function _aptInstall(){
|
||||
echo "Asking password for 'apt-get install $*'..."
|
||||
sudo apt-get install "$@"
|
||||
}
|
||||
|
||||
function _gitUpdate(){
|
||||
if [ "$DOWNLOAD" != "y" ]; then
|
||||
return
|
||||
@@ -143,6 +161,48 @@ function _make(){
|
||||
fi
|
||||
}
|
||||
|
||||
# Find an available, non-virtual package matching one of the given regexps.
|
||||
#
|
||||
# Each positional parameter is interpreted as a POSIX extended regular
|
||||
# expression. These parameters are examined from left to right, and the first
|
||||
# available matching package is added to the global PKG variable. If no match
|
||||
# is found, the script aborts.
|
||||
function _package_alternative(){
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Empty package alternative: this is a bug in the script, aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Considering a package alternative:" "$@"
|
||||
_package_alternative_inner "$@"
|
||||
}
|
||||
|
||||
# This function requires the 'dctrl-tools' package
|
||||
function _package_alternative_inner(){
|
||||
local pkg
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "No match found for the package alternative, aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# This finds non-virtual packages only (on purpose)
|
||||
pkg="$(apt-cache dumpavail | \
|
||||
grep-dctrl -e -sPackage -FPackage \
|
||||
"^[[:space:]]*($1)[[:space:]]*\$" - | \
|
||||
sed -ne '1s/^Package:[[:space:]]*//gp')"
|
||||
|
||||
if [[ -n "$pkg" ]]; then
|
||||
echo "Package alternative matched for $pkg"
|
||||
PKG="$PKG $pkg"
|
||||
return 0
|
||||
else
|
||||
# Try with the next regexp
|
||||
shift
|
||||
_package_alternative_inner "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
#######################################################
|
||||
# set script to stop if an error occours
|
||||
set -e
|
||||
@@ -201,6 +261,23 @@ _logSep
|
||||
|
||||
#######################################################
|
||||
#######################################################
|
||||
|
||||
if [[ "$DOWNLOAD_PACKAGES" = "y" ]] && [[ "$APT_GET_UPDATE" = "y" ]]; then
|
||||
_aptUpdate
|
||||
fi
|
||||
|
||||
# Ensure 'dctrl-tools' is installed
|
||||
if [[ "$(dpkg-query --showformat='${db:Status-Status}\n' --show dctrl-tools \
|
||||
2>/dev/null)" != "installed" ]]; then
|
||||
if [[ "$DOWNLOAD_PACKAGES" = "y" ]]; then
|
||||
_aptInstall dctrl-tools
|
||||
else
|
||||
echo -n "The 'dctrl-tools' package is needed, but DOWNLOAD_PACKAGES is "
|
||||
echo -e "not set to 'y'.\nAborting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Minimum
|
||||
PKG="build-essential cmake git"
|
||||
# cmake
|
||||
@@ -210,9 +287,12 @@ PKG="$PKG libcgal-dev libgdal-dev libtiff5-dev"
|
||||
# TGGUI/OpenRTI
|
||||
PKG="$PKG libqt4-dev"
|
||||
# SG/FG
|
||||
PKG="$PKG zlib1g-dev freeglut3-dev libboost-dev libopenscenegraph-dev"
|
||||
PKG="$PKG zlib1g-dev freeglut3-dev libboost-dev"
|
||||
_package_alternative libopenscenegraph-3.4-dev libopenscenegraph-dev \
|
||||
'libopenscenegraph-[0-9]+\.[0-9]+-dev'
|
||||
# FG
|
||||
PKG="$PKG libopenal-dev libudev-dev qt5-default libdbus-1-dev libpng12-dev libplib-dev"
|
||||
PKG="$PKG libopenal-dev libudev-dev qt5-default qtdeclarative5-dev libdbus-1-dev libplib-dev"
|
||||
_package_alternative libpng-dev libpng12-dev libpng16-dev
|
||||
# FGPanel
|
||||
PKG="$PKG fluid libbz2-dev libfltk1.3-dev libxi-dev libxmu-dev"
|
||||
# FGAdmin
|
||||
@@ -224,12 +304,8 @@ PKG="$PKG python-tk"
|
||||
# FGx (FGx is not compatible with Qt5, however we have installed Qt5 by default)
|
||||
#PKG="$PKG libqt5xmlpatterns5-dev libqt5webkit5-dev"
|
||||
|
||||
if [ "$DOWNLOAD_PACKAGES" = "y" ]; then
|
||||
echo "Asking password for apt-get operations..."
|
||||
if [ "$APT_GET_UPDATE" = "y" ]; then
|
||||
sudo apt-get update
|
||||
fi
|
||||
sudo apt-get install $PKG
|
||||
if [[ "$DOWNLOAD_PACKAGES" = "y" ]]; then
|
||||
_aptInstall $PKG
|
||||
fi
|
||||
|
||||
#######################################################
|
||||
@@ -379,8 +455,8 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="OSG"' ]]; then
|
||||
echo "****************************************" | tee -a $LOGFILE
|
||||
cd "$CBD"/openscenegraph
|
||||
_gitDownload https://github.com/openscenegraph/osg.git
|
||||
_gitUpdate OpenSceneGraph-3.2
|
||||
|
||||
_gitUpdate OpenSceneGraph-3.4
|
||||
|
||||
if [ "$RECONFIGURE" = "y" ]; then
|
||||
cd "$CBD"
|
||||
mkdir -p build/openscenegraph
|
||||
|
||||
2
fgdata
2
fgdata
Submodule fgdata updated: 6a3316ebd8...c8b090fa4e
Submodule flightgear updated: 9aaff777d9...989ebf73a6
@@ -21,7 +21,7 @@ echo "Build path is: $PATH"
|
||||
###############################################################################
|
||||
echo "Starting on SimGear"
|
||||
pushd sgBuild
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DENABLE_CURL:BOOL="ON" -DCMAKE_BUILD_TYPE=RelWithDebInfo ../simgear
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DCMAKE_BUILD_TYPE=RelWithDebInfo ../simgear
|
||||
|
||||
# compile
|
||||
make
|
||||
@@ -39,7 +39,14 @@ popd
|
||||
################################################################################
|
||||
echo "Starting on FlightGear"
|
||||
pushd fgBuild
|
||||
cmake -DFG_NIGHTLY=1 -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DCMAKE_BUILD_TYPE=RelWithDebInfo ../flightgear
|
||||
|
||||
if [ $FG_IS_RELEASE == '1' ]; then
|
||||
FGBUILDTYPE=Release
|
||||
else
|
||||
FGBUILDTYPE=Nightly
|
||||
fi
|
||||
|
||||
cmake -DFG_BUILD_TYPE=$FGBUILDTYPE -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DCMAKE_BUILD_TYPE=RelWithDebInfo ../flightgear
|
||||
|
||||
make
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU General Public License
|
||||
#along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
#along with FlightGear If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if [ -z "$1" -o -z "$2" ]; then
|
||||
echo "usage: thismajor.thisminor nextmajor.nextminor path"
|
||||
@@ -65,8 +65,6 @@ createBranch() {
|
||||
while [ $# -gt 0 ]; do
|
||||
echo "Processing $1"
|
||||
pushd $1 > /dev/null
|
||||
git config user.name "Automatic Release Builder"
|
||||
git config user.email "build@flightgear.org"
|
||||
createBranch
|
||||
popd > /dev/null
|
||||
shift
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
THIS_RELEASE="2017.1"
|
||||
NEXT_RELEASE="2017.2"
|
||||
THIS_RELEASE="2017.2"
|
||||
NEXT_RELEASE="2017.3"
|
||||
SUBMODULES="simgear flightgear fgdata"
|
||||
|
||||
#:<< 'COMMENT_END'
|
||||
|
||||
2
simgear
2
simgear
Submodule simgear updated: 86fb1ed00f...9840302931
Reference in New Issue
Block a user