Compare commits

..

63 Commits

Author SHA1 Message Date
Automatic Release Builder
acc3ed54ae set correct release-branch for submodules 2017-05-18 15:16:00 +02:00
Automatic Release Builder
250152fd7c new version: 2017.2.1 2017-05-18 15:16:00 +02:00
Automatic Release Builder
7dbf960291 release script tweaks for 2017.2 2017-05-18 15:14:46 +02:00
Florent Rougon
5fa23309c5 download_and_compile.sh: replace manually set version with the Git blob ID
By setting the 'ident' attribute for /download_and_compile.sh, this
replacement will be automatic whenever the file is checked out.

Note: the ID is the 40-character hexadecimal blob object name in Git, it
      is *not* the commit ID. 'git show <id>' can be used to obtain the
      script contents from its blob object name (id).

This will avoid spoiling every diff with the version number change, or
alternatively having different versions of the same file displaying and
logging the same version number.

If download_and_compile.sh is moved to a different directory in FGMeta
(or even renamed), then the path in .gitattributes must be adapted for
the substitution to work (the '/' in .gitattributes anchors the match at
the containing directory; I did this because download_and_compile.sh is
a rather generic name, and there *might* be different scripts with the
same name in other dirs...).
2017-05-18 11:32:37 +02:00
Florent Rougon
e8fb2f58f2 Add a basic .gitattributes file to the repository root directory 2017-05-18 10:24:21 +02:00
Florent Rougon
5bf2814178 download_and_compile.sh: dependency changes suggested by Pat Callahan 2017-05-18 10:13:29 +02:00
Florent Rougon
b621bbe3e8 download_and_compile.sh: add function _package_alternative()
- Add function _package_alternative() to select between alternative
  packages (idea of Pat Callahan).

- Split the 'apt-get update' and 'apt-get install' steps to arrange for
  installation of the 'dctrl-tools' prerequisite of
  _package_alternative().

- Add and use functions _aptUpdate() and _aptInstall() for good
  factoring (makes testing easier for people not using sudo, allows one
  to easily switch from 'apt-get' to 'apt' or 'aptitude' if wanted,
  etc.).
2017-05-14 18:58:54 +02:00
portree_kid
9c41bca63f Added manufacturers 2017-05-06 14:01:05 +02:00
portree_kid
efab6d7e51 Added aircraft type racer (ME-209-V1 hard to find otherwise) 2017-05-05 14:08:54 +02:00
portree_kid
910e3ec490 Added more manufacturers to catalog/catalogTags.py 2017-05-05 08:24:29 +02:00
portree_kid
df6d8be57f Replaced TABS by SPACES 2017-05-02 20:46:44 +02:00
portree_kid
b670f096be Added carrier & reconnaissance to aircraft type 2017-04-28 07:26:41 +02:00
portree_kid
b7d27d156f Corrected handley page to handley-page
Added more manufacturers
2017-04-26 16:33:00 +02:00
portree_kid
51e37ac662 Added aircraft manufacturers 2017-04-25 22:25:35 +02:00
Florent Rougon
1d68e73690 download_and_compile.sh: add qtdeclarative5-dev to the list of deps for FG
This was requested by several users; it is now required to compile
FlightGear's built-in launcher.
2017-04-21 18:36:12 +02:00
James Turner
aeaf259c59 Upload PDB files to CrashFix 2017-04-18 08:57:35 +01:00
James Turner
257ba0f733 More tags based on suggestions. 2017-04-13 11:18:29 +01:00
James Turner
7eb3a8886f Improving catalog generation
Support multiple primary aircraft in a package, which has several
aircraft developers have requested. This adjusts the handling of
the variant-of and primary-set tags.

Additionally, this adds partial unit-test coverage for -set.xml
scanning and catalog XML generation. 

Run ./test_catalog to run unit-tests of the catalog generation.
2017-04-12 16:38:58 +01:00
Stuart Buchanan
e86954cc7f Add additional manufacturers and eras.
Note on eras:  I've added every decade since flight started for
consistency and completeness.  For example, the Bell X-1 is from
the 1940s but is post-WW2.
2017-04-02 21:04:01 +01:00
James Turner
f23197f811 Fix a typo. 2017-03-27 13:06:20 +01:00
Stuart Buchanan
f28db85017 Add aerobatic, avro, ultralight and sort lines 2017-03-23 22:50:26 +00:00
James Turner
3f85e1911e Catalog script thumbnails, primary-set fixes.
- extract per-variant thumbnails from -set.xml files
- handle multiple primary aircraft in a directory (this will
  need client-side changes too, eventually)
2017-03-05 21:02:49 +02:00
James Turner
b350cd9827 Adjust build scripts to set FG_BUILD_TYPE
Cmake now has a standard variable to indicate the build type we are
creating. Map the existing settings on each platform to that value
(with varying degrees of nice-ness, further clean-up possible)
2017-02-28 16:25:58 +00:00
James Turner
8e22064b71 Re-add tag validation and support to catalog.
Tags are copied to the catalog.xml again, and validated against
catalogTags.py
2017-02-27 00:32:01 +00:00
James Turner
7a64df78e3 Improve reporting on bad indices. 2017-02-27 00:16:38 +00:00
Automatic Release Builder
493ad2c306 use git:// for fgdata submodule remote to keep jenkins happy 2017-02-22 18:09:42 +01:00
James Turner
533cec6236 Remove FGPanel special case for 64-bits.
We can build a 64-bit FGPanel now, since the issue was GLUT and freeGlut
supports a 64-bit version.

Note the shortcut icon is not disabled automatically, that needs an
additional fix.
2017-02-21 18:17:39 +00:00
Automatic Release Builder
0dd0bf3043 set submodule head for fgdata 2017-02-20 19:30:10 +01:00
Automatic Release Builder
b0594ed4ef track submodule changes for release 2017-02-20 18:52:19 +01:00
Automatic Release Builder
f2e86108d4 new version: 2017.2.0 2017-02-20 18:52:19 +01:00
Automatic Release Builder
8462f3217a new version: 2017.1.1 2017-02-20 18:52:19 +01:00
Automatic Release Builder
735f5160e4 some tweaks to the release_branch builder scripts 2017-02-20 18:51:44 +01:00
Curtis L. Olson
a5949431b1 A couple cleanups .... 2017-02-12 09:44:02 -06:00
Curtis L. Olson
0622410e4a Create the preview directory if it doesn't already exist. 2017-02-12 09:14:05 -06:00
James Turner
acb8a7a793 Fix catalog parsing, add unit-tests
Fixes issues with conflated nodes and skipped previews in the
catalog XML.
2017-02-10 11:55:30 +00:00
Torsten Dreyer
93b71e29e6 looks like sf doesnt like git protocol anymore.
Use anonymous https instead
2017-02-09 17:46:55 +01:00
Torsten Dreyer
fcf5087da9 use release instead of -rc suffix 2017-02-09 17:46:09 +01:00
James Turner
2c7e8318db OpenAL-soft doesn’t need oalinst
Simplifies our install, nice.
2017-02-08 11:49:02 +00:00
Rebecca N. Palmer
157ce05c69 d&c.sh security: use https to prevent MITM attacks
(SourceForge now allows anonymous https fetching)
2017-01-28 17:17:44 +00:00
James Turner
799b0b4ad6 Fix merging of includes when parsing XML.
Incorrect use of addChild was causing overlaid properties not to be
merged correctly when performing an include.
2017-01-20 21:43:19 +00:00
Torsten Dreyer
c9f7483fc4 Merge /u/chrisblues/flightgearMeta/ branch next into next
https://sourceforge.net/p/flightgear/fgmeta/merge-requests/19/
2017-01-13 14:29:06 +00:00
James Turner
4d3a5fb528 Remove my catalog scripts in favour of Curt’s
(But preserve the catalog-tags list for future re-use)
2017-01-12 21:43:02 +00:00
James Turner
e8a6c477cc Preview support. 2017-01-12 21:12:57 +00:00
James Turner
21a53b3537 Update-catalog does SGProps parsing of -set.xml
This restores the ability to use includes in -set.xml files visible
to the catalog code, and also exposes some problems / validation
issues in our -set.xml files. (Which can of course be fixed)
2017-01-12 14:39:35 +00:00
chris_blues
37ff25cfe4 Add Nasa2FGEarthview
a converter script (bash) to download sattelite images from NASA or a mirror
and convert them to usable FGearthview format. Supports different
resolutions.
See:
https://github.com/chris-blues/Nasa2FGearthview
2017-01-12 10:44:40 +01:00
James Turner
0409f339ae Tweaks to my Mac build script. 2017-01-10 18:12:12 +00:00
James Turner
771c2a2abe Windows builds create PDBs again. 2016-12-13 11:32:33 +00:00
James Turner
224a9a0b18 Add my Mac and Linux build helpers.
This is to save new contributors some time getting a build env, since
download-and-compile produces a slightly Baroque setup for day-to-day
development.
2016-12-11 00:18:45 +00:00
James Turner
08cb5c481b Add my Windows build script for posterity.
Linux/Mac coming shortly.
2016-12-10 23:57:11 +00:00
James Turner
c23ec2827f Ignore Windows build directories. 2016-12-09 14:59:57 +00:00
James Turner
ba8feb7d6f Submdoule updates. 2016-12-09 14:56:33 +00:00
James Turner
f1f612206f Re-enable CrashRpt in Windows installers. 2016-12-09 14:50:03 +00:00
Florent Rougon
ef36d50d9b Add directory changes-in-dat-files/apt.dat with two patches for apt.dat
000-general-modify-header.patch:
  indicate that apt.dat has been modified by the FlightGear team

001-CCC5-fix-missing-Unicom-frequency.patch:
  add missing Unicom frequency for CCC5 (Havelock), thanks to wkitty42

The patch files have LF line endings (otherwise this is a mess: some
lines ending with LF and others with CRLF inside the same file). In
order to obtain this, apt.dat has been recoded to LF line endings (Unix
and MacOS X), then the changes have been made, the diff commands run,
and finally the resulting file has been recoded with CRLF line endings
(Windows) before being gzipped and written to FGData. This was done so
in order to preserve compatibility with software that could not handle a
change in $FG_ROOT/Airports/apt.dat.gz's line ending style.
2016-12-08 19:20:06 +01:00
James Turner
5b969d37ec Correct way to invoke ISCC in quiet mode! 2016-12-02 16:59:07 +00:00
James Turner
8e82d4e1fb Revert "Reduce logging level of NSIS."
This reverts commit 2dfbc989ba.
2016-12-02 16:58:15 +00:00
James Turner
2dfbc989ba Reduce logging level of NSIS. 2016-11-29 16:30:01 +00:00
James Turner
93b085f441 Fix a typo 2016-11-25 21:52:42 +00:00
James Turner
52bceabab7 Catalog includes description / authors per variant. 2016-11-25 21:51:46 +00:00
James Turner
cee226183c Official catalog supports 2017.* versions. 2016-11-25 17:20:31 +00:00
Torsten Dreyer
6cb7d12ec1 Remove locale folder from install
After removal of fgrun, this folder does not exist anymore
2016-11-18 11:06:36 +01:00
Automatic Release Builder
16a42dfc6b Add the scripts to automize the release process 2016-11-17 15:38:09 +01:00
Automatic Release Builder
9d6ce08430 track submodule changes for release 2016-11-17 13:43:40 +01:00
Automatic Release Builder
95b7ef534b new version: 2017.1.0 2016-11-17 13:43:39 +01:00
55 changed files with 3492 additions and 962 deletions

23
.gitattributes vendored Normal file
View 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

1
.gitignore vendored
View File

@@ -20,3 +20,4 @@ archivebuild
osgbuild
CMakeCache.txt
*.pyc
build-*

14
.gitmodules vendored
View File

@@ -1,20 +1,20 @@
[submodule "simgear"]
path = simgear
url = git://git.code.sf.net/p/flightgear/simgear
branch = release/2016.4
url = https://git.code.sf.net/p/flightgear/simgear
branch = release/2017.2
[submodule "flightgear"]
path = flightgear
url = git://git.code.sf.net/p/flightgear/flightgear
branch = release/2016.4
url = https://git.code.sf.net/p/flightgear/flightgear
branch = release/2017.2
[submodule "fgrun"]
path = fgrun
url = git://git.code.sf.net/p/flightgear/fgrun
url = https://git.code.sf.net/p/flightgear/fgrun
branch = next
[submodule "fgdata"]
path = fgdata
url = git://git.code.sf.net/p/flightgear/fgdata
branch = release/2016.4
branch = release/2017.2
[submodule "windows-3rd-party"]
path = windows-3rd-party
url = git://git.code.sf.net/p/flightgear/windows-3rd-party
url = https://git.code.sf.net/p/flightgear/windows-3rd-party
branch = master

View File

@@ -74,7 +74,6 @@ ArchitecturesAllowed=x86 x64
[Tasks]
; NOTE: The following entry contains English phrases ("Create a desktop icon" and "Additional icons"). You are free to translate them into another language if required.
Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"
Name: "insoal"; Description: "Install OpenAL (the sound engine)"
[Files]
; NOTE: run subst X: F:\ (or whatever path the expanded tree resides at)
@@ -90,9 +89,9 @@ Source: "{#ThirdPartyDir}\3rdParty\bin\OpenAL32.dll"; DestDir: "{app}\bin"; Chec
Source: "{#ThirdPartyDir}\3rdParty\bin\libpng.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\libcurl.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\libintl-8.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
;Source: "X:\3rdParty\bin\CrashRpt1402.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
;Source: "X:\3rdParty\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
;Source: "X:\3rdParty\bin\CrashSender1402.exe"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\CrashRpt1403.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty\bin\CrashSender1403.exe"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
Source: "{#VCInstallDir}\redist\x86\Microsoft.VC140.CRT\*.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
; 64 bits install
@@ -105,16 +104,11 @@ Source: "{#ThirdPartyDir}\3rdParty.x64\bin\OpenAL32.dll"; DestDir: "{app}\bin";
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\libpng.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\libcurl.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\libintl-8.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
;Source: "X:\3rdParty.x64\bin\CrashRpt1402.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
;Source: "X:\3rdParty.x64\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
;Source: "X:\3rdParty.x64\bin\CrashSender1402.exe"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\CrashRpt1403.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
Source: "{#ThirdPartyDir}\3rdParty.x64\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
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
Source: "{#ThirdPartyDir}\..\oalinst.exe"; DestDir: "{app}\bin"; Flags: ignoreversion skipifsourcedoesntexist
; Include the base package
#if IncludeData == "TRUE"
Source: "X:\fgdata\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
@@ -216,9 +210,6 @@ Name: "{group}\Tools\FGCom"; Filename: "{app}\bin\fgcom.exe"; WorkingDir: "{app}
Name: "{group}\Tools\FGCom-testing"; Filename: "{app}\bin\fgcom.exe"; Parameters: "--frequency=910"; WorkingDir: "{app}\bin"
Name: "{group}\Tools\Explore Documentation Folder"; Filename: "{app}\data\Docs"
[Run]
filename: "{app}\bin\oalinst.exe"; WorkingDir: "{app}\bin"; Description: "Installing OpenAL"; Check: IsTaskSelected('insoal') and FileExists(ExpandConstant('{app}\bin\oalinst.exe'))
[Code]
const
NET_FW_SCOPE_ALL = 0;

339
Nasa2FGearthview/LICENSE Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

167
Nasa2FGearthview/README.md Normal file
View File

@@ -0,0 +1,167 @@
# Nasa2FGearthview
A bash-script to convert NASA satellite images to ready-to-use
textures for FG's EarthView using ImageMagick.
For info about FGearthview, see the forum thread:
https://forum.flightgear.org/viewtopic.php?f=6&t=15754
or this FG-wiki-page:
http://wiki.flightgear.org/Earthview
------------------------------------
About:
This script runs on Linux (maybe Mac also?) in a Bash
(Bourne Again Shell) - Windows is not supported (by the nature of the
script). Maybe it works on windows as well, I don't know, feel free
to try, and please let me know! :)
This will download the raw images from http://visibleearth.nasa.gov -
their server is not very fast, so I provide an alternative download
location: https://musicchris.de/download/FG/EarthView/raw-data-NASA.7z
This one is much quicker! If you really want the images directly from
NASA, then provide "nasa" to the script (see below)
In the end you will have 8 world-textures in .png and .dds format.
Generally .dds is better in performance, but it won't work on some
graphics cards. If this is the case for you, then try the .png files.
For further information see:
http://wiki.flightgear.org/index.php?title=DDS_Textures_in_FlightGear&redirect=no
If you also converted the clouds, then you'll also find 8 cloud-
textures in the format .png. Because the .dds-format has trouble with
rendering heavy alpha images, which is because of it's compression
algorythm [1], I think it's useless to also build faulty files.
However, this is not entirely true! It is possible to switch off the
.dds/DXT compression. But this results in huge files and is rather
heavy on the GPU's RAM.
Buckaroo has created a nice overview on dds-compression:
[1] http://www.buckarooshangar.com/flightgear/tut_dds.html
------------------------------------
Installation and usage:
Simply copy "convert.sh" into a folder of your liking and run it:
$ ./convert.sh
This will show a help text, since you didn't specify any target(s).
Possible targets are:
* world
* clouds
* all
Additionally, there are some options you could specify (further
explained below):
* 1k | 2k | 4k | 8k | 16k
* nasa
* no-download
* cleanup
* rebuild
* check
So your call could look sth like this:
$ ./convert.sh world no-download cleanup 8k
------------------------------------
Requirements:
WARNING!
This script uses a *lot* disk space! Make sure you have at least 90GB
available!
Also, this script will run for a *very long* time! It might be best to
let it run over night - your computer might become unresponsive from
time to time, due to the heavy CPU and memory load, which tends to
occur, when converting 54000x27000 images. ;-)
I also recommend to deactivate swapping!
$ sudo swapoff -a
To reactivate swapping do:
$ sudo swapon -a
This script relies on wget and imagemagick. Both are easily installed
by your systems package-management-system.
(On Debian/Ubuntu this is "apt-get")
So, on Debian for instance, you only need to put the following into
the console:
$ sudo apt-get install wget imagemagick
Depending on your distro, the package names might differ slightly! Use
a search engine of your choice to find out, how the packages are named
in your distro!
You may want to check:
$ apt search imagemagick
------------------------------------
Targets:
world
Generates the world tiles, needed to run FG with EarthView.
You will find the results in output/[$resolution]/*. Copy
these into $FGDATA/Models/Astro/*. More about the installation
of these textures can be found here:
http://wiki.flightgear.org/Earthview#Customization
clouds
Generates the cloud tiles, needed to run FG with EarthView.
The locations are the same as the other textures mentioned
above. Note that clouds are only available with up to 8k
resolution, due to the available data at NASA.
all
Converts everything needed for a full-blown earthview texture
set. Does the same as:
$ ./convert.sh world clouds
Options:
1k | 2k | 4k | 8k | 16k
Lets you specify a desired resolution of the textures.
Possible values are 1k, 2k, 4k, 8k and 16k. If nothing is
specified, the script will generate all of the resolutions.
16k is only available for earth textures.
nasa
Causes the script to download directly from
http://visibleearth.nasa.gov . If omitted the script will
download from
https://musicchris.de/download/FG/EarthView/raw-data-NASA.7z
which is much faster!
Uses wget either way.
no-download
Causes the script to skip the download function. If you
already have the source images, then you don't need to
re-download them. (About 2.4GB!)
If omitted, the script will download the source images from
https://musicchris.de/download/FG/EarthView/raw-data-NASA.7z
cleanup
Deletes the temporary files created during texture generation.
These can be found in tmp/
Note: if for some reason you later want some other resolution,
then it's good to have the data there. So only do this, when
you're quite sure that you're done.
Frees up a lot of disk-space! Which would have to be
regenerated if needed again.
rebuild
Deletes only the temporary files of the given target. So if
you call './convert.sh rebuild world' the script will delete
all corresponding temp-files of the target world, which will
trigger a complete regeneration of the relevant (instead of
skipping existing files)
check
Creates mosaics of the tiles, so you can look at them and see
if all went well.

1403
Nasa2FGearthview/convert.sh Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -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/

View File

@@ -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
@@ -19,7 +25,7 @@ cmake ..\simgear -G "Visual Studio 14" ^
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
-DCMAKE_PREFIX_PATH:PATH=%OSG32% ^
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140
cmake --build . --config Release --target INSTALL
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fg32
cmake ..\flightgear -G "Visual Studio 14" ^
@@ -27,8 +33,9 @@ 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%
cmake --build . --config Release --target INSTALL
-DCMAKE_PREFIX_PATH=%QT5SDK32%;%OSG32% ^
-DFG_BUILD_TYPE=%FGBUILDTYPE%
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..
@@ -42,15 +49,16 @@ cmake ..\SimGear -G "Visual Studio 14 Win64" ^
-DBOOST_ROOT=%WORKSPACE%/windows-3rd-party ^
-DCMAKE_PREFIX_PATH:PATH=%OSG64% ^
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc140-64
cmake --build . --config Release --target INSTALL
cmake --build . --config RelWithDebInfo --target INSTALL
cd ..\build-fg64
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%
cmake --build . --config Release --target INSTALL
-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%
@@ -86,17 +95,17 @@ IF %IS_NIGHTLY_BUILD% EQU 1 (
REM FlightGear nightly: with fgdata, output filename would be "FlightGear-x.x.x-nightly-full.exe"
CALL :writeBaseConfig
CALL :writeNightlyFullConfig
iscc FlightGear.iss
iscc /Q FlightGear.iss
REM FlightGear nightly: without fgdata, output filename would be "FlightGear-x.x.x-nightly.exe"
CALL :writeBaseConfig
CALL :writeNightlyDietConfig
iscc FlightGear.iss
iscc /Q FlightGear.iss
) ELSE (
REM FlightGear release: with fgdata, output filename would be "FlightGear-x.x.x.exe"
CALL :writeBaseConfig
CALL :writeReleaseConfig
iscc FlightGear.iss
iscc /Q FlightGear.iss
)
GOTO End

229
catalog/catalog.py Normal file
View 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

162
catalog/catalogTags.py Normal file
View File

@@ -0,0 +1,162 @@
aircraftTypeTags = [
"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 = [
"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 = [
"1910s",
"1920s",
"1930s",
"1940s",
"1950s",
"1960s",
"1970s",
"1980s",
"1990s",
"2000s",
"2010s",
"coldwar",
"early-pioneers",
"golden-age",
"gulfwar1",
"gulfwar2",
"vietnam",
"ww1",
"ww2"
]
featureTags = [
"aerobatic",
"airship",
"amphibious",
"biplane",
"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",
"tail-dragger",
"tricycle",
"tail-hook",
"triplane",
"v-tail",
"variable-geometry",
"vtol",
"wing-fold"
]
propulsionTags = [
"afterburner",
"diesel",
"electric",
"jet",
"propeller",
"piston",
"radial",
"rocket",
"single-engine",
"supercharged",
"turboprop",
"twin-engine",
"variable-pitch",
"fixed-pitch"
]
simFeatureTags = [
"dual-controls",
"rembrandt",
"tow",
"wildfire"
]
tags = aircraftTypeTags + manufacturerTags + eraTags + simFeatureTags + propulsionTags + featureTags
def isValidTag(maybeTag):
return maybeTag in tags

View File

@@ -11,6 +11,9 @@
<skip>c172</skip>
<skip>tu134</skip>
</scm>
<include-dir>/home/curt/Projects/FlightGear/flightgear-fgdata</include-dir>
<include-dir>/home/curt/Projects/FlightGear/flightgear-fgaddon</include-dir>
<!-- <scm>
<type>git</type>
<update type="bool">false</update>

View File

@@ -7,7 +7,8 @@
<version n="2">3.6.*</version>
<version n="3">3.7.*</version>
<version n="4">2016.1.*</version>
<version n="4">2016.*.*</version>
<version n="5">2016.*.*</version>
<version n="6">2017.*.*</version>
<id>org.flightgear.fgaddon</id>
<license>GPL</license>
<url>http://mirrors.ibiblio.org/flightgear/ftp/Aircraft/catalog.xml</url>

View File

@@ -144,6 +144,22 @@ class Node(object):
return n;
class ParseState:
def __init__(self):
self._counters = {}
def getNextIndex(self, name):
if name in self._counters:
self._counters[name] += 1
else:
self._counters[name] = 0
return self._counters[name]
def recordExplicitIndex(self, name, index):
if not name in self._counters:
self._counters[name] = index
else:
self._counters[name] = max(self._counters[name], index)
class PropsHandler(handler.ContentHandler):
def __init__(self, root = None, path = None, includePaths = []):
@@ -152,6 +168,7 @@ class PropsHandler(handler.ContentHandler):
self._basePath = os.path.dirname(path)
self._includes = includePaths
self._locator = None
self._stateStack = [ParseState()]
if root is None:
# make a nameless root node
@@ -164,20 +181,28 @@ class PropsHandler(handler.ContentHandler):
def startElement(self, name, attrs):
self._content = None
if (name == 'PropertyList'):
# still need to handle includes on the root element
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
self._current = self._current.addChild(name)
return
raise IndexError("Invalid index at line:", self._locator.getLineNumber(), "of", self._path)
currentState.recordExplicitIndex(name, index)
self._current = self._current.getChild(name, index, create=True)
else:
self._current = self._current.addChild(name)
index = currentState.getNextIndex(name)
# important we use getChild here, so that includes are resolved
# correctly
self._current = self._current.getChild(name, index, create=True)
self._stateStack.append(ParseState())
if 'include' in attrs.keys():
self.handleInclude(attrs['include'])
@@ -228,6 +253,7 @@ class PropsHandler(handler.ContentHandler):
self._current = self._current.parent
self._content = None
self._currentTy = None
self._stateStack.pop()
def parsePropsBool(self, content):

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<PropertyList>
<sim>
<!-- found in the F-15 XML -->
<uhf n="[0]">
<frequencies>
<selected-mhz type="int">225000</selected-mhz>
</frequencies>
</uhf>
</sim>
</PropertyList>

View File

@@ -0,0 +1,25 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<value type="int">42</value>
<thing>
<value>apple</value>
</thing>
<thing>
<value>lemon</value>
</thing>
<thing>
<value>pear</value>
</thing>
<!-- ensure explicit indexing works -->
<sub>
<value n="1">a</value>
<value n="3">b</value>
<value n="99">c</value>
<value>d</value> <!-- should be assigned n=100 -->
</sub>
</PropertyList>

View File

@@ -0,0 +1,20 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList include="root-include.xml">
<value type="int">33</value>
<thing>
<value>apple</value>
</thing>
<thing>
<value>lemon</value>
</thing>
<sub include ="sub-include.xml">
<!-- different index to avoid being included over -->
<widget n="100" type="int">99</widget>
</sub>
</PropertyList>

View File

@@ -0,0 +1,22 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<value type="int">42</value>
<value type="int">43</value>
<value type="int">44</value>
<sim>
<views>
</views>
<preview>
</preview>
<preview>
</preview>
</sim>
<payload>
<weight>
</weight>
</payload>
</PropertyList>

View File

@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<PropertyList>
<widget type="int">42</widget>
<widget type="int">43</widget>
<widget type="int">44</widget>
</PropertyList>

116
catalog/test_catalog.py Executable file
View 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()

61
catalog/test_sgprops.py Executable file
View File

@@ -0,0 +1,61 @@
import unittest
import types
import sgprops
class SGProps(unittest.TestCase):
def test_parse(self):
parsed = sgprops.readProps("testData/props1.xml")
self.assertEqual(parsed.getValue("value"), 42)
self.assertEqual(type(parsed.getValue("value")), types.IntType)
valNode = parsed.getChild("value")
self.assertEqual(valNode.parent, parsed)
self.assertEqual(valNode.name, "value")
self.assertEqual(valNode.value, 42)
self.assertEqual(type(valNode.value), types.IntType)
with self.assertRaises(IndexError):
missingNode = parsed.getChild("missing")
things = parsed.getChildren("thing")
self.assertEqual(len(things), 3)
self.assertEqual(things[0], parsed.getChild("thing", 0));
self.assertEqual(things[1], parsed.getChild("thing", 1));
self.assertEqual(things[2], parsed.getChild("thing", 2));
self.assertEqual(things[0].getValue("value"), "apple");
self.assertEqual(things[1].getValue("value"), "lemon");
self.assertEqual(things[2].getValue("value"), "pear");
def test_create(self):
pass
def test_invalidIndex(self):
with self.assertRaises(IndexError):
parsed = sgprops.readProps("testData/bad-index.xml")
def test_include(self):
parsed = sgprops.readProps("testData/props2.xml")
# test that value in main file over-rides the one in the include
self.assertEqual(parsed.getValue("value"), 33)
# but these come from the included file
self.assertEqual(parsed.getValue("value[1]"), 43)
self.assertEqual(parsed.getValue("value[2]"), 44)
subNode = parsed.getChild("sub")
widgets = subNode.getChildren("widget")
self.assertEqual(len(widgets), 4)
self.assertEqual(widgets[2].value, 44)
self.assertEqual(widgets[3].value, 99)
if __name__ == '__main__':
unittest.main()

View File

@@ -9,6 +9,10 @@ import re
import shutil
import subprocess
import time
import sgprops
import sys
import catalogTags
import catalog
CATALOG_VERSION = 4
@@ -23,6 +27,8 @@ parser.add_argument("--clean", help="Force regeneration of all zip files",
parser.add_argument("dir", help="Catalog directory")
args = parser.parse_args()
includes = []
# xml node (robust) get text helper
def get_xml_text(e):
if e != None and e.text != None:
@@ -30,71 +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(set_file):
base_file = os.path.basename(set_file)
base_id = base_file[:-8]
#print ' scanning:', base_file
parser = ET.XMLParser(remove_blank_text=True)
set_xml = ET.parse(set_file, parser)
set_node = set_xml.getroot()
sim_node = set_node.find('sim')
if sim_node == None:
return None
variant = {}
variant['name'] = get_xml_text(sim_node.find('description'))
variant['status'] = get_xml_text(sim_node.find('status'))
variant['author'] = get_xml_text(sim_node.find('author'))
variant['description'] = get_xml_text(sim_node.find('long-description'))
variant['id'] = base_id
rating_node = sim_node.find('rating')
if rating_node != None:
variant['rating_FDM'] = int(get_xml_text(rating_node.find('FDM')))
variant['rating_systems'] = int(get_xml_text(rating_node.find('systems')))
variant['rating_cockpit'] = int(get_xml_text(rating_node.find('cockpit')))
variant['rating_model'] = int(get_xml_text(rating_node.find('model')))
variant['variant-of'] = get_xml_text(sim_node.find('variant-of'))
#print ' ', variant
return variant
# 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):
found_master = False
package = None
variants = []
files = os.listdir(aircraft_dir)
for file in sorted(files, key=lambda s: s.lower()):
if file.endswith('-set.xml'):
variant = scan_set_file(os.path.join(aircraft_dir, file))
if variant == None:
continue
if package == None:
# just in case no one claims to be master, the first
# variant defaults to master, but we will overwrite
# this if we find something better.
package = variant
if not found_master and variant['variant-of'] == '':
found_master = True
package = variant
else:
variants.append( {'id': variant['id'],
'name': variant['name'] } )
return (package, variants)
# use svn commands to report the last change date within dir
def last_change_date_svn(dir):
command = [ 'svn', 'info', dir ]
@@ -143,6 +84,114 @@ def get_md5sum(file):
f.close()
return md5sum
def copy_previews_for_variant(variant, package_name, package_dir, previews_dir):
if not 'previews' in variant:
return
for preview in variant['previews']:
preview_src = os.path.join(package_dir, preview['path'])
preview_dst = os.path.join(previews_dir, package_name + '_' + preview['path'])
#print preview_src, preview_dst, preview['path']
dir = os.path.dirname(preview_dst)
if not os.path.isdir(dir):
os.makedirs(dir)
if os.path.exists(preview_src):
shutil.copy2(preview_src, preview_dst)
def copy_previews_for_package(package, variants, package_name, package_dir, previews_dir):
copy_previews_for_variant(package, package_name, package_dir, previews_dir)
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()
@@ -175,17 +224,33 @@ 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')
if not os.path.isdir(output_dir):
os.mkdir(output_dir)
thumbnail_dir = os.path.join(output_dir, 'thumbnails')
if not os.path.isdir(thumbnail_dir):
os.mkdir(thumbnail_dir)
previews_dir = os.path.join(output_dir, 'previews')
if not os.path.isdir(previews_dir):
os.mkdir(previews_dir)
tmp = os.path.join(args.dir, 'zip-excludes.lst')
zip_excludes = os.path.realpath(tmp)
for i in config_node.findall("include-dir"):
path = get_xml_text(i)
if not os.path.exists(path):
print "Skipping missing include path:", path
continue
includes.append(path)
# freshen repositories
if args.no_update:
print 'Skipping repository updates.'
@@ -194,6 +259,8 @@ else:
for scm in scm_list:
repo_type = get_xml_text(scm.find('type'))
repo_path = get_xml_text(scm.find('path'))
includes.append(repo_path)
if repo_type == 'svn':
print 'SVN update:', repo_path
subprocess.call(['svn', 'update', repo_path])
@@ -232,92 +299,9 @@ for scm in scm_list:
if name in skip_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']) )
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) )
# 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') )
# 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')
@@ -332,4 +316,3 @@ files = os.listdir(output_dir)
for file in files:
if file.endswith('.zip')and not file in valid_zips:
print "orphaned zip:", file

View File

@@ -1,80 +0,0 @@
aircraftTypeTags = [
"ga", "fighter", "helicopter", "glider", "spaceship", "bomber", "groundvehicle",
"tanker", "cargo", "transport", "bizjet", "trainer", "airship", "balloon"
]
manufacturerTags = [
"boeing", "cessna", "diamond", "douglas", "bell", "piper",
"airbus", "vickers", "lockheed", "fokker",
"embraer", "bombardier", "pilatus", "robin",
"eurocopter"
]
eraTags = [
"early-pioneers",
"ww1",
"1920s",
"1930s",
"golden-age",
"ww2",
"coldwar", "vietnam",
"1950s",
"1960s",
"1970s",
"1980s",
"1990s",
"2000s",
"gulfwar1",
"gulfwar2"
]
featureTags = [
"ifr",
"retractable-gear",
"fixed-gear",
"tail-dragger",
"seaplane",
"vtol",
"stol",
"experimental",
"prototype",
"fictional",
"biplane",
"triplane",
"supersonic",
"t-tail",
"v-tail",
"high-wing",
"cannard",
"tail-hook",
"refuel",
"delta",
"variable-geometry",
"glass-cockpit",
"hud",
"etops",
"floats",
"amphibious",
"airship",
"aerobatic"
]
propulsionTags = [
"piston", "radial",
"diesel",
"variable-pitch",
"supercharged",
"turboprop",
"jet", "afterburner", "rocket",
"electric",
"twin-engine",
"single-engine"
]
simFeatureTags = [
"tow",
"dual-controls",
"rembrandt"
]
tags = aircraftTypeTags + manufacturerTags + eraTags + simFeatureTags + propulsionTags + featureTags

View File

@@ -0,0 +1,9 @@
--- apt.dat 2016-12-08 18:43:50.000000000 +0100
+++ apt.dat-000 2016-12-08 18:56:02.310707492 +0100
@@ -1,5 +1,5 @@
I
-1000 Version - data cycle 2013.10, build 20131335, metadata AptXP1000. Copyright <20> 2013, Robin A. Peel (robin@x-plane.com). This data is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("AptNavGNULicence.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+1000 Version - data cycle 2013.10, build 20131335, metadata AptXP1000, further modified by the FlightGear team (cf. <https://sourceforge.net/p/flightgear/fgmeta/ci/next/tree/changes-in-dat-files/apt.dat>). Copyright <20> 2013, Robin A. Peel (robin@x-plane.com). This data is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("AptNavGNULicence.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
1 15 1 0 VHXX [X] CLOSED Kai Tak

View File

@@ -0,0 +1,11 @@
--- apt.dat 2016-12-08 18:56:02.310707492 +0100
+++ apt.dat-001 2016-12-08 19:01:00.082169377 +0100
@@ -926129,7 +926129,7 @@
19 45.98520090 -065.30815534 1 WS
19 45.98509598 -065.29620316 1 WS
19 45.98776000 -065.29826459 1 WS
-51 12320
+51 12320 CTAF/UNICOM
1 1000 0 1 3MN7 Haven
100 22.86 3 0 0.25 0 0 0 15 45.49243037 -094.12309108 0.00 0.00 1 0 0 0 33 45.48749963 -094.11966060 0.00 0.00 1 0 0 0

21
compile-scripts/README.md Normal file
View File

@@ -0,0 +1,21 @@
This is the scripts I (James) use to maintain my builds on each platform.
They're much less clever than 'download and compile' but they do enough for me
and probably most other people, if you tweak the paths accordingly. The Mac
and Linux ones require Ruby (which is usually pre-installed). There are no
instructions - if you can't figure out what these do from reading the scripts,
you almost certainly should not be using them!
They all assume a top-level folder which contains
checkouts of simgear, flightgear, fgdata, OpenSceneGraph (into a dir named
'osg') and the windows-3rd-party dir in the case of Windows. It's assumed
you copy the script to that same dir, edit paths and run from there.
The Mac and Linux scripts will do the checkout for you - the Windows is not
so smart because Window batch scripts are not my friend.
On Mac you will need to grab the 3rdparty-dependency-build from Jenkins, or
build PLIB manually yourself, either should be straightforward. For all other
dependencies on Mac / Linux use your package manager / Homebrew.
Files will be installed into a subdir called 'dist'

130
compile-scripts/commands-linux.rb Executable file
View File

@@ -0,0 +1,130 @@
#!/usr/bin/ruby
require 'fileutils'
require 'optparse'
include FileUtils
baseDir = Dir.pwd
gitArgs = ""
qtPath = ""
doPull = false
doCMake = false
doInit = false
doClean = false
doPackage = false
cmakeCommonArgs = "-DCMAKE_INSTALL_PREFIX=#{baseDir}/dist -DSIMGEAR_SHARED=1"
cmakeFGArgs = ""
sfUser = "jmturner"
OptionParser.new do |opts|
opts.banner = "Usage: commands.rb [options]"
opts.on("", "--init", "Setup empty") do |v|
doInit = v
end
opts.on("-p", "--[no-]pull", "Pull from Git") do |v|
doPull = v
end
opts.on("-c", "--cmake", "Run Cmake") do |v|
doCMake = v
end
opts.on("", "--clean", "Clean build dirs") do |v|
doClean = v
end
opts.on("-r", "--rebase", "Rebase when pulling") do |v|
gitArgs += "--rebase"
end
opts.on("", "--qt=QTPATH", "Set Qt path when running cmake") do |v|
qtPath = v
end
end.parse!(ARGV)
def cloneEverything()
puts "Initialising"
if File.exist?("#{Dir.pwd}/simgear") or File.exist?("#{Dir.pwd}/flightgear")
puts "Checkout already exists"
return
end
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/simgear simgear`
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/flightgear flightgear`
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/fgdata fgdata`
`git clone https://github.com/openscenegraph/osg.git osg`
end
def createDirs()
`mkdir -p sgbuild`
`mkdir -p fgbuild`
`mkdir -p osg_release_build`
end
# path is needed for Cmake & running macdeployqt
if qtPath != ""
ENV['PATH'] = "#{ENV['PATH']}:#{qtPath}/bin"
end
if doClean
puts "Cleaning build dirs"
`rm -r sgbuild`
`rm -r fgbuild`
`rm -r osg_release_build`
createDirs()
end
if doInit
puts "Doing init"
cloneEverything()
createDirs();
end
if doPull
puts "Pulling from Git"
dataPull = Thread.new do
puts "Syncing FGData"
Dir.chdir "#{baseDir}/fgdata"
`git pull #{gitArgs}`
end
Dir.chdir "#{baseDir}/simgear"
`git pull #{gitArgs}`
Dir.chdir "#{baseDir}/flightgear"
`git pull #{gitArgs}`
end
Dir.chdir "#{baseDir}/osg_release_build"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
`cmake ../osg -DCMAKE_INSTALL_PREFIX=#{baseDir}/dist`
end
puts "Building OpenSceneGraph"
`make`
`make install`
Dir.chdir "#{baseDir}/sgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
`cmake ../simgear #{cmakeCommonArgs}`
end
puts "Building SimGear"
`make`
`make install`
Dir.chdir "#{baseDir}/fgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
if qtPath != ""
cmakeFGArgs = '-DENABLE_QT=1'
end
`cmake ../flightgear #{cmakeCommonArgs} #{cmakeFGArgs}`
end
puts "Building FlightGear"
`make`
`make install`
puts "All done."

135
compile-scripts/commands-mac.rb Executable file
View File

@@ -0,0 +1,135 @@
#!/usr/bin/ruby
require 'fileutils'
require 'optparse'
include FileUtils
baseDir = Dir.pwd
gitArgs = ""
qtPath = ""
doPull = false
doCMake = false
doInit = false
doClean = false
doPackage = false
cmakePlatformArgs = "-G Xcode"
cmakeCommonArgs = "-DCMAKE_INSTALL_PREFIX=#{baseDir}/dist"
cmakeSGArgs = "-DSIMGEAR_SHARED=1"
cmakeFGArgs = "-DSIMGEAR_SHARED=1"
sfUser = "jmturner"
OptionParser.new do |opts|
opts.banner = "Usage: commands.rb [options]"
opts.on("", "--init", "Setup empty") do |v|
doInit = v
end
opts.on("-p", "--[no-]pull", "Pull from Git") do |v|
doPull = v
end
opts.on("-c", "--cmake", "Run Cmake") do |v|
doCMake = v
end
opts.on("", "--clean", "Clean build dirs") do |v|
doClean = v
end
opts.on("-r", "--rebase", "Rebase when pulling") do |v|
gitArgs += "--rebase"
end
opts.on("", "--qt=QTPATH", "Set Qt path when running cmake") do |v|
qtPath = v
end
end.parse!(ARGV)
def cloneEverything()
puts "Initialising"
if File.exist?("#{Dir.pwd}/simgear") or File.exist?("#{Dir.pwd}/flightgear")
puts "Checkout already exists"
return
end
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/simgear simgear`
`git clone ssh://#{sfUser}@git.code.sf.net/p/flightgear/flightgear flightgear`
`git clone git@github.com:zakalawe/osg.git osg`
end
def createDirs()
`mkdir -p sgbuild`
`mkdir -p fgbuild`
`mkdir -p osg_fg_build`
end
# path is needed for Cmake & running macdeployqt
if qtPath != ""
ENV['PATH'] = "#{ENV['PATH']}:#{qtPath}/bin"
end
if doClean
puts "Cleaning build dirs"
`rm -r sgbuild`
`rm -r fgbuild`
`rm -r osg_fg_build`
end
if doInit
puts "Doing init"
cloneEverything()
end
if doPull
puts "Pulling from Git"
dataPull = Thread.new do
puts "Syncing FGData"
Dir.chdir "#{baseDir}/fgdata"
`git pull #{gitArgs}`
end
Dir.chdir "#{baseDir}/simgear"
`git pull #{gitArgs}`
Dir.chdir "#{baseDir}/flightgear"
`git pull #{gitArgs}`
end
createDirs()
Dir.chdir "#{baseDir}/osg_fg_build"
if doCMake or !File.exist?("#{Dir.pwd}/Makefile")
`cmake ../osg #{cmakeCommonArgs}`
end
puts "Building OpenSceneGraph"
`make -j4`
`make install`
Dir.chdir "#{baseDir}/sgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/SimGear.xcodeproj")
`cmake ../simgear #{cmakePlatformArgs} #{cmakeCommonArgs} #{cmakeSGArgs}`
end
puts "Building SimGear Debug"
`xcodebuild -target install -configuration Debug`
puts "Building SimGear Release"
`xcodebuild -target install -configuration Release`
Dir.chdir "#{baseDir}/fgbuild"
if doCMake or !File.exist?("#{Dir.pwd}/FlightGear.xcodeproj")
if qtPath != ""
cmakeFGArgs = '-DENABLE_QT=1'
end
`cmake ../flightgear #{cmakePlatformArgs} #{cmakeCommonArgs} #{cmakeFGArgs}`
end
puts "Building FlightGear Debug"
`xcodebuild -target fgfs -configuration Debug`
puts "Building FlightGear Release"
`xcodebuild -target fgfs -configuration Release`
puts "All done."

View File

@@ -0,0 +1,52 @@
SET PATH=%PATH%;%ProgramFiles%\CMake\bin
SET QT5SDK64=C:\Qt\5.6\msvc2015_64
SET CMAKE_TOOLCHAIN="Visual Studio 14 Win64"
SET ROOT_DIR=%CD%
md osgbuild
md sgbuild
md fgbuild
REM md fgrun-build
cd simgear
git pull --rebase
cd ..\flightgear
git pull --rebase
REM cd ..\fgrun
REM git pull --rebase
cd ..\osgbuild
cmake ..\osg -G %CMAKE_TOOLCHAIN% ^
-DACTUAL_3RDPARTY_DIR:PATH=%ROOT_DIR%\windows-3rd-party\msvc140\3rdparty.x64 ^
-DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\dist ^
-DOSG_USE_UTF8_FILENAME:BOOL=ON
cmake --build . --config Release --target INSTALL
cmake --build . --config Debug --target INSTALL
cd ..\sgbuild
cmake ..\simgear -G %CMAKE_TOOLCHAIN% ^
-DMSVC_3RDPARTY_ROOT=%ROOT_DIR%\windows-3rd-party\msvc140 ^
-DOSG_FSTREAM_EXPORT_FIXED:BOOL=ON ^
-DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\dist
cmake --build . --config Release --target INSTALL
cmake --build . --config Debug --target INSTALL
cd ..\fgbuild
cmake ..\flightgear -G %CMAKE_TOOLCHAIN% ^
-DMSVC_3RDPARTY_ROOT=%ROOT_DIR%\windows-3rd-party\msvc140 ^
-DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\dist ^
-DCMAKE_PREFIX_PATH=%QT5SDK64% ^
-DOSG_FSTREAM_EXPORT_FIXED:BOOL=ON
cmake --build . --config Release --target INSTALL
cmake --build . --config Debug --target INSTALL
REM cd ..\fgrun-build
REM cmake ..\fgrun -G %CMAKE_TOOLCHAIN% ^
REM -DMSVC_3RDPARTY_ROOT=C:\FGFS\windows-3rd-party\msvc140 ^
REM -DCMAKE_INSTALL_PREFIX:PATH=C:\FGFS\dist
REM cmake --build . --config Release --target INSTALL
REM cmake --build . --config Debug --target INSTALL

View File

@@ -17,8 +17,16 @@
# 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"
FGVERSION="release/$(git ls-remote --heads git://git.code.sf.net/p/flightgear/flightgear|grep '\/release\/'|cut -f4 -d'/'|sort -t . -k 1,1n -k2,2n -k3,3n|tail -1)"
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)"
#######################################################
# THANKS TO
@@ -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
#######################################################
@@ -316,7 +392,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="PLIB"' ]]; then
mkdir -p "plib"
cd "$CBD"/plib
_gitDownload git://git.code.sf.net/p/libplib/code
_gitDownload https://git.code.sf.net/p/libplib/code
_gitUpdate master
if [ "$RECONFIGURE" = "y" ]; then
@@ -345,7 +421,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="OPENRTI"' ]]; then
mkdir -p "openrti"
cd "$CBD"/openrti
_gitDownload git://git.code.sf.net/p/openrti/OpenRTI
_gitDownload https://git.code.sf.net/p/openrti/OpenRTI
if [ "$STABLE" = "STABLE" ]; then
_gitUpdate release-0.7
@@ -378,9 +454,9 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="OSG"' ]]; then
echo "**************** OSG *******************" | tee -a $LOGFILE
echo "****************************************" | tee -a $LOGFILE
cd "$CBD"/openscenegraph
_gitDownload http://github.com/openscenegraph/osg.git
_gitUpdate OpenSceneGraph-3.2
_gitDownload https://github.com/openscenegraph/osg.git
_gitUpdate OpenSceneGraph-3.4
if [ "$RECONFIGURE" = "y" ]; then
cd "$CBD"
mkdir -p build/openscenegraph
@@ -419,7 +495,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="SIMGEAR"' ]]; then
mkdir -p "simgear"
cd "$CBD"/simgear
_gitDownload git://git.code.sf.net/p/flightgear/simgear
_gitDownload https://git.code.sf.net/p/flightgear/simgear
_gitUpdate $FGVERSION
if [ "$RECONFIGURE" = "y" ]; then
@@ -452,7 +528,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="FGFS"' || "$(declare -p WHAT
cd "$CBD"/flightgear
if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="FGFS"' ]]; then
_gitDownload git://git.code.sf.net/p/flightgear/flightgear
_gitDownload https://git.code.sf.net/p/flightgear/flightgear
_gitUpdate $FGVERSION
if [ "$RECONFIGURE" = "y" ]; then
@@ -479,7 +555,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="FGFS"' || "$(declare -p WHAT
echo "**************** DATA ******************" | tee -a $LOGFILE
echo "****************************************" | tee -a $LOGFILE
_gitDownload git://git.code.sf.net/p/flightgear/fgdata
_gitDownload https://git.code.sf.net/p/flightgear/fgdata
_gitUpdate $FGVERSION
fi
cd "$CBD"
@@ -521,7 +597,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="FGRUN"' ]]; then
mkdir -p "fgrun"
cd "$CBD"/fgrun
_gitDownload git://git.code.sf.net/p/flightgear/fgrun
_gitDownload https://git.code.sf.net/p/flightgear/fgrun
_gitUpdate $FGVERSION
if [ "$RECONFIGURE" = "y" ]; then
@@ -649,7 +725,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="ATCPIE"' ]]; then
mkdir -p "$INSTALL_DIR_ATCPIE"
cd $INSTALL_DIR_ATCPIE
_gitDownload git://git.code.sf.net/p/atc-pie/code
_gitDownload https://git.code.sf.net/p/atc-pie/code
_gitUpdate master
cd "$CBD"
@@ -702,7 +778,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="TERRAGEAR"' ]]; then
mkdir -p "terragear"
cd "$CBD"/terragear
_gitDownload git://git.code.sf.net/p/flightgear/terragear
_gitDownload https://git.code.sf.net/p/flightgear/terragear
_gitUpdate scenery/ws2.0
if [ "$RECONFIGURE" = "y" ]; then
@@ -753,7 +829,7 @@ if [[ "$(declare -p WHATTOBUILD)" =~ '['([0-9]+)']="TERRAGEARGUI"' ]]; then
mkdir -p "terrageargui"
cd "$CBD"/terrageargui
_gitDownload git://git.code.sf.net/p/flightgear/fgscenery/terrageargui
_gitDownload https://git.code.sf.net/p/flightgear/fgscenery/terrageargui
_gitUpdate master

2
fgdata

Submodule fgdata updated: c16a56a8a1...c8b090fa4e

View File

@@ -1,50 +0,0 @@
# git diff --quiet e5f841bc84d31fee339191a59b8746cb4eb8074c -- ./Aircraft/
import subprocess
import os, sgprops
class GITCatalogRepository:
def __init__(self, node, singleAircraft = False):
self._path = node.getValue("path")
if not os.path.exists(os.path.join(self._path , ".git")):
raise RuntimeError("not a Git directory:" + self._path )
self._usesSubmodules = node.getValue("uses-submodules", False)
self._singleAircraft = singleAircraft
self._currentRevision = subprocess.check_output(["git", "rev-parse", "HEAD"],
cwd = self._path)
self._aircraftPath = None
if node.hasChild("scan-suffix"):
self._aircraftPath = os.path.join(path, node.getValue("scan-suffix"))
@property
def path(self):
return self._path
@property
def aircraftPath(self):
return self._aircraftPath
def hasPathChanged(self, path, oldRev):
diffArgs = ["git", "diff", "--quiet", oldRev, "--"]
if not (self._usesSubmodules and self._singleAircraft):
diffArgs.append(path)
return subprocess.call(diffArgs, cwd = self._path)
def update(self):
subprocess.call(["git", "pull"])
self._currentRevision = subprocess.check_output(["git", "rev-parse", "HEAD"],
cwd = self._path)
if self._usesSubmodules:
subprocess.call(["git", "submodule", "update"], cwd = self._path)
def scmRevisionForPath(self, path):
if self._usesSubmodules:
return subprocess.check_output(["git", "rev-parse", "HEAD"], cwd = self._path)
return self._currentRevision

View File

@@ -1,34 +0,0 @@
# git diff --quiet e5f841bc84d31fee339191a59b8746cb4eb8074c -- ./Aircraft/
import subprocess
import os
import sgprops
import git_catalog_repository
class GitDiscreteSCM:
def __init__(self, node):
configNode = node.parent
self._repos = {}
# iterate over aicraft paths finding repositories
for g in config.getChildren("aircraft-dir"):
repo = GITCatalogRepository(g, useSubmodules = False,
singleAircraft = True)
def hasPathChanged(self, path, oldRev):
return self._repos[path].hasPathChanged(path, oldRev)
def update(self):
for r in self._repos:
r.update()
def scmRevisionForPath(self, path):
return self._repos[path].scmRevisionForPath(path)

View File

@@ -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

View File

@@ -1,226 +0,0 @@
#!/usr/bin/python
import os, sys, re, glob, shutil
import subprocess
import sgprops
import argparse
import urllib2
import package as pkg
import svn_catalog_repository
import git_catalog_repository
import git_discrete_repository
parser = argparse.ArgumentParser()
parser.add_argument("--clean", help="Regenerate every package",
action="store_true")
parser.add_argument("--update", help="Update/pull SCM source",
action="store_true")
parser.add_argument("--force-dirty", dest="forcedirty",
help="Mark every package as dirty", action="store_true")
parser.add_argument("--no-update",
dest = "noupdate",
help="Disable updating from SCM source",
action="store_true")
parser.add_argument("--no-upload",
dest = "noupload",
help="Disable uploading to destination server",
action="store_true")
parser.add_argument("dir", help="Catalog directory")
args = parser.parse_args()
CATALOG_VERSION = 4
includePaths = []
packages = {}
def scanPackages(scmRepo):
result = []
globPath = scmRepo.aircraftPath
if globPath is None:
return result
print "Scanning", globPath
print os.getcwd()
for d in glob.glob(globPath):
# check dir contains at least one -set.xml file
if len(glob.glob(os.path.join(d, "*-set.xml"))) == 0:
print "no -set.xml in", d
continue
result.append(pkg.PackageData(d, scmRepo))
return result
def initScmRepository(node):
scmType = node.getValue("type")
if (scmType == "svn"):
return svn_catalog_repository.SVNCatalogRepository(node)
elif (scmType == "git"):
return git_catalog_repository.GITCatalogRepository(node)
elif (scmType == "git-discrete"):
return git_discrete_repository.GitDiscreteSCM(node)
elif (scmType == None):
raise RuntimeError("No scm/type defined in catalog configuration")
else:
raise RuntimeError("Unspported SCM type:" + scmType)
def initRepositories():
repositories = []
for scm in config.getChildren("scm"):
scmRepo = initScmRepository(scm)
if args.update or (not args.noupdate and scm.getValue("update")):
scmRepo.update()
# presumably include repos in parse path
# TODO: make this configurable
includePaths.append(scmRepo.path)
repositories.append(scmRepo)
return repositories
def processUpload(node, outputPath):
if args.noupload or not node.getValue("enabled", True):
print "Upload disabled"
return
uploadType = node.getValue("type")
if (uploadType == "rsync"):
subprocess.call(["rsync", node.getValue("args", "-az"), ".",
node.getValue("remote")],
cwd = outputPath)
elif (uploadType == "rsync-ssh"):
print "Doing rsync upload to:", node.getValue("remote")
subprocess.call(["rsync", node.getValue("args", "-azve"),
"ssh", ".",
node.getValue("remote")],
cwd = outputPath)
elif (uploadType == "scp"):
subprocess.call(["scp", node.getValue("args", "-r"), ".",
node.getValue("remote")],
cwd = outputPath)
else:
raise RuntimeError("Unsupported upload type:" + uploadType)
def parseExistingCatalog():
global existingCatalogPath
global previousCatalog
# contains existing catalog
existingCatalogPath = os.path.join(outPath, 'catalog.xml')
if not os.path.exists(existingCatalogPath):
url = config.getValue("template/url")
print "Attempting downloading from", url
try:
# can happen on new or from clean, try to pull current
# catalog from the upload location
response = urllib2.urlopen(url, timeout = 5)
content = response.read()
f = open(existingCatalogPath, 'w' )
f.write( content )
f.close()
print "...worked"
except urllib2.URLError as e:
print "Downloading current catalog failed", e, "from", url
rootDir = args.dir
if not os.path.isabs(rootDir):
rootDir = os.path.abspath(rootDir)
os.chdir(rootDir)
configPath = 'catalog.config.xml'
if not os.path.exists(configPath):
raise RuntimeError("no config file found at:" + configPath)
config = sgprops.readProps(configPath)
# out path
outPath = config.getValue('output-dir')
if outPath is None:
# default out path
outPath = os.path.join(rootDir, "output")
elif not os.path.isabs(outPath):
outPath = os.path.join(rootDir, "output")
if args.clean:
print "Cleaning output"
shutil.rmtree(outPath)
if not os.path.exists(outPath):
os.mkdir(outPath)
thumbnailPath = os.path.join(outPath, config.getValue('thumbnail-dir', "thumbnails"))
if not os.path.exists(thumbnailPath):
os.mkdir(thumbnailPath)
thumbnailUrls = list(t.value for t in config.getChildren("thumbnail-url"))
for i in config.getChildren("include-dir"):
if not os.path.exists(i.value):
print "Skipping missing include path:", i.value
continue
includePaths.append(i.value)
parseExistingCatalog()
repositories = initRepositories()
for scm in repositories:
for p in scanPackages(scm):
try:
p.scanSetXmlFiles(includePaths)
packages[p.id] = p
except:
print "Skipping SCM package due to exception:", p.path
if os.path.exists(existingCatalogPath):
try:
previousCatalog = sgprops.readProps(existingCatalogPath)
except:
print "Previous catalog is malformed"
previousCatalog = sgprops.Node()
for p in previousCatalog.getChildren("package"):
pkgId = p.getValue("id")
if not pkgId in packages.keys():
print "Orphaned old package:", pkgId
continue
packages[pkgId].setPreviousData(p)
else:
print "No previous catalog"
catalogNode = sgprops.Node("catalog")
sgprops.copy(config.getChild("template"), catalogNode)
catalogNode.getChild("catalog-version", create = True).value = CATALOG_VERSION
mirrorUrls = list(m.value for m in config.getChildren("mirror"))
packagesToGenerate = []
for p in packages.values():
if p.isSourceModified or args.forcedirty:
packagesToGenerate.append(p)
else:
p.useExistingCatalogData()
excludeFilePath = os.path.join(rootDir, "zip-excludes.lst")
# def f(x):
# x.generateZip(outPath)
# x.extractThumbnails(thumbnailPath)
# return True
#
# p = Pool(8)
# print(p.map(f,packagesToGenerate))
for p in packagesToGenerate:
p.generateZip(outPath, excludeFilePath)
p.extractThumbnails(thumbnailPath)
print "Creating catalog"
for p in packages.values():
catalogNode.addChild(p.packageNode(mirrorUrls, thumbnailUrls[0]))
catalogNode.write(os.path.join(outPath, "catalog.xml"))
for up in config.getChildren("upload"):
processUpload(up, outPath)

View File

@@ -1,239 +0,0 @@
import os, subprocess
import sgprops
import hashlib # for MD5
import shutil # for copy2
import catalogTags
standardTagSet = frozenset(catalogTags.tags)
def isNonstandardTag(t):
return t not in standardTagSet
thumbnailNames = ["thumbnail.png", "thumbnail.jpg"]
class VariantData:
def __init__(self, path, node):
#self._primary = primary
self._path = path
self._name = node.getValue("sim/description")
if (not self._name):
print "Missing description for " + path
self._name = "Missing description:" + self.id
# ratings
# seperate thumbnails
@property
def name(self):
return self._name
@property
def id(self):
return self._path[:-8] # "remove -set.xml" (8 chars)
@property
def catalogNode(self):
n = sgprops.Node("variant")
n.addChild("id").value = self.id
n.addChild("name").value = self.name
return n
class PackageData:
def __init__(self, path, scmRepo):
self._path = path
self._scm = scmRepo
self._previousSCMRevision = None
self._previousRevision = 0
self._thumbnails = []
self._variants = {}
self._revision = 0
self._md5 = None
self._fileSize = 0
self._primarySetXmlPath = None
self._node = sgprops.Node("package")
def setPreviousData(self, node):
self._previousRevision = node.getValue("revision")
self._previousMD5 = node.getValue("md5")
self._previousSCMRevision = node.getValue("scm-revision")
self._fileSize = int(node.getValue("file-size-bytes"))
@property
def id(self):
return self._primarySetXmlPath
@property
def thumbnails(self):
return self._thumbnails
@property
def path(self):
return self._path
@property
def variants(self):
return self._variants
@property
def scmRevision(self):
currentRev = self._scm.scmRevisionForPath(self.path)
if (currentRev is None):
raise RuntimeError("Unable to query SCM revision of files")
return currentRev
@property
def isSourceModified(self):
if (self._previousSCMRevision == None):
return True
if (self._previousSCMRevision == self.scmRevision):
return False
return True
def scanSetXmlFiles(self, includes):
foundPrimary = False
foundMultiple = False
for f in os.listdir(self.path):
if not f.endswith("-set.xml"):
continue
p = os.path.join(self.path, f)
node = sgprops.readProps(p, includePaths = includes)
if not node.hasChild("sim"):
continue
simNode = node.getChild("sim")
# honour variosu exclusion flags
if (simNode.getValue("exclude-from-catalog", False) or simNode.getValue("exclude-from-gui", False)):
continue
primary = simNode.getValue("variant-of", None)
if primary:
if not primary in self.variants:
self._variants[primary] = []
self._variants[primary].append(VariantData(f, node))
continue
if foundPrimary:
if not foundMultiple:
print "Multiple primary -set.xml files at:" + self.path
print "\t" + p
foundMultiple = True
continue
else:
foundPrimary = True;
self._primarySetXmlPath = f[:-8] # trim -set.xml
self.parsePrimarySetNode(simNode)
for n in thumbnailNames:
if os.path.exists(os.path.join(self.path, n)):
self._thumbnails.append(n)
if not foundPrimary:
raise RuntimeError("No primary -set.xml found at:" + self.path)
def parsePrimarySetNode(self, sim):
# basic / mandatory values
self._node.addChild('name').value = sim.getValue('description')
longDesc = sim.getValue('long-description')
if longDesc is not None:
self._node.addChild('description').value = longDesc
# copy all the standard values
for p in ['status', 'author', 'license']:
v = sim.getValue(p)
if v is not None:
self._node.addChild(p).value = v
# ratings
if sim.hasChild('rating'):
pkgRatings = self._node.addChild('rating')
for r in ['FDM', 'systems', 'cockpit', 'model']:
pkgRatings.addChild(r).value = sim.getValue('rating/' + r, 0)
# copy tags
if sim.hasChild('tags'):
for c in sim.getChild('tags').getChildren('tag'):
if isNonstandardTag(c.value):
print "Skipping non-standard tag:", c.value, self.path
else:
self._node.addChild('tag').value = c.value
for t in sim.getChildren("thumbnail"):
self._thumbnails.append(t.value)
def validate(self):
for t in self._thumbnails:
if not os.path.exists(os.path.join(self.path, t)):
raise RuntimeError("missing thumbnail:" + t);
def generateZip(self, outDir, globalExcludePath):
self._revision = self._previousRevision + 1
baseName = os.path.basename(self.path)
zipName = baseName + ".zip"
zipFilePath = os.path.join(outDir, zipName)
os.chdir(os.path.dirname(self.path))
print "Creating zip", zipFilePath
# anything we can do to make this faster?
zipArgs = ['zip', '--quiet', '-r']
if os.path.exists(globalExcludePath):
zipArgs += [ "-x@" + globalExcludePath]
excludePath = os.path.join(self.path, 'package-exclude.lst')
if (os.path.exists(excludePath)):
print self.id, "has zip exclude list"
zipArgs += ["-x@" + excludePath]
zipArgs += [zipFilePath, baseName]
subprocess.call(zipArgs)
zipFile = open(zipFilePath, 'r')
self._md5 = hashlib.md5(zipFile.read()).hexdigest()
self._fileSize = os.path.getsize(zipFilePath)
def useExistingCatalogData(self):
self._md5 = self._previousMD5
def packageNode(self, mirrorUrls, thumbnailUrl):
self._node.addChild("id").value = self.id
self._node.getChild("md5", create = True).value = self._md5
self._node.getChild("file-size-bytes", create = True).value = self._fileSize
self._node.getChild("revision", create = True).value = int(self._revision)
self._node.getChild("scm-revision", create = True).value = self.scmRevision
baseName = os.path.basename(self.path)
self._node.getChild("dir", create = True).value = baseName
zipName = baseName + ".zip"
for m in mirrorUrls:
self._node.addChild("url").value = m + "/" + zipName
for t in self._thumbnails:
self._node.addChild("thumbnail-path").value = t
self._node.addChild("thumbnail").value = thumbnailUrl + "/" + self.id + "_" + t
for pr in self._variants:
for vr in self._variants[pr]:
self._node.addChild(vr.catalogNode)
return self._node
def extractThumbnails(self, thumbnailDir):
for t in self._thumbnails:
fullName = self.id + "_" + t
shutil.copy2(os.path.join(self._path, t),
os.path.join(thumbnailDir, fullName)
)
# TODO : verify image format, size and so on

View File

@@ -8,14 +8,19 @@ import os, sys, re, fnmatch
from subprocess import call
suffix = '.dmg'
release_version = "unknown"
if sys.argv[1] == 'windows':
suffix = '.exe'
if sys.argv[1] == 'linux':
suffix = '.tar.bz2'
isReleaseCandidate = False
isRelease = False
if len(sys.argv) > 2 and sys.argv[2] == 'release':
isReleaseCandidate = True
isRelease = True
if len(sys.argv) > 3:
release_version = sys.argv[3]
allSuffix = '*' + suffix
@@ -25,10 +30,10 @@ sourceForgeUserHost = "jmturner@frs.sourceforge.net"
sftpCommandFile = "sftp-commands"
symbolDir = "/home/jenkins/symbols"
if isReleaseCandidate:
if isRelease:
publicRoot = "/var/www/html/builds/rc"
incomingDir = "/home/jenkins/incoming"
sourceForgePath = "/home/frs/project/f/fl/flightgear/release-candidate/"
sourceForgePath = "/home/frs/project/f/fl/flightgear/release-" + release_version + "/"
else:
publicRoot = "/var/www/html/builds/nightly"
incomingDir = "/home/jenkins/nightly-incoming"
@@ -81,15 +86,15 @@ for file in incomingFiles:
outFile = file
# insert -rc before suffix
if isReleaseCandidate:
m = re.match(r'(\w+-\d+\.\d+\.\d+[\w-]*)' + suffix, file)
outFile = m.group(1) + '-rc' + suffix
print "RC out name is " + outFile
#if isRelease:
#m = re.match(r'(\w+-\d+\.\d+\.\d+[\w-]*)' + suffix, file)
#outFile = m.group(1) + '-rc' + suffix
#print "RC out name is " + outFile
os.rename(srcFile, outFile)
newFiles.append(outFile)
if not isReleaseCandidate:
if not isRelease:
# symlink for stable web URL
m = re.match(r'(\w+)-\d+\.\d+\.\d+-([\w-]+)' + suffix, file)
latestName = m.group(1) + '-latest-' + m.group(2) + suffix
@@ -102,17 +107,17 @@ for file in incomingFiles:
# remove files from SF
if len(oldFiles) > 0:
f = open(sftpCommandFile, 'w')
f.write("cd " + sourceForgePath + '\n')
for file in oldFiles:
print "Removing file " + file + " from SourceForge"
f.write("rm " + file + '\n')
f.write("bye\n")
f.close()
call(["sftp", "-b", sftpCommandFile, sourceForgeUserHost])
os.remove(sftpCommandFile)
#if len(oldFiles) > 0:
# f = open(sftpCommandFile, 'w')
# f.write("cd " + sourceForgePath + '\n')
# for file in oldFiles:
# print "Removing file " + file + " from SourceForge"
# f.write("rm " + file + '\n')
# f.write("bye\n")
# f.close()
#
# call(["sftp", "-b", sftpCommandFile, sourceForgeUserHost])
# os.remove(sftpCommandFile)
# upload to SourceForge
for file in newFiles:

View File

@@ -0,0 +1,71 @@
#!/bin/bash
#This file is part of FlightGear
#
#FlightGear is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 2 of the License, or
#(at your option) any later version.
#
#FlightGear is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#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"
exit
fi
IFS='.' read -r -a VERSION_A <<< "$1"
shift
if [ ${#VERSION_A[@]} != 2 ]; then
echo "Need version as 'number.number'"
exit
fi
THIS_MAJOR_VERSION=${VERSION_A[0]}
THIS_MINOR_VERSION=${VERSION_A[1]}
RELEASE_BRANCH="release/${THIS_MAJOR_VERSION}.${THIS_MINOR_VERSION}"
IFS='.' read -r -a VERSION_A <<< "$1"
shift
if [ ${#VERSION_A[@]} != 2 ]; then
echo "Need version as 'number.number'"
exit
fi
NEXT_MAJOR_VERSION=${VERSION_A[0]}
NEXT_MINOR_VERSION=${VERSION_A[1]}
setVersionTo() {
local V="$1"
echo "setting version to $V"
echo "$V" > version
git add version
echo "new version: $V" | git commit --file=-
git tag "version/$V"
}
createBranch() {
echo "Preparing release in `pwd`"
git checkout next
git pull --rebase
setVersionTo "${THIS_MAJOR_VERSION}.${THIS_MINOR_VERSION}.1"
echo "Creating branch $RELEASE_BRANCH for version $(cat version) in `pwd`"
git branch "$RELEASE_BRANCH"
setVersionTo "${NEXT_MAJOR_VERSION}.${NEXT_MINOR_VERSION}.0"
}
while [ $# -gt 0 ]; do
echo "Processing $1"
pushd $1 > /dev/null
createBranch
popd > /dev/null
shift
done

View File

@@ -0,0 +1,45 @@
#!/bin/bash
THIS_RELEASE="2017.2"
NEXT_RELEASE="2017.3"
SUBMODULES="simgear flightgear fgdata"
#:<< 'COMMENT_END'
git checkout next
git pull --rebase
$(dirname $0)/create-release-branch-for.sh "$THIS_RELEASE" "$NEXT_RELEASE" $SUBMODULES .
# use release branch for submodules
git checkout release/${THIS_RELEASE}
for f in $SUBMODULES; do
git config -f .gitmodules submodule.${f}.branch release/${THIS_RELEASE}
done
git add .gitmodules && echo "set correct release-branch for submodules" | git commit --file=-
# track submodule changes
git checkout next
git add $SUBMODULES && echo "track submodule changes for release" | git commit --file=-
#COMMENT_END
echo "Check this and submodules $SUBMODULES - hit <enter> to push or <ctrl-c> to cancel"
read something
for f in $SUBMODULES .; do
pushd "$f"
echo "Pushing $f"
git checkout release/${THIS_RELEASE} && git push origin release/${THIS_RELEASE} && git push origin version/${THIS_RELEASE}.1 && git push origin version/${NEXT_RELEASE}.0 && git checkout next && git push
popd
done
#this needs ~/.ssh/config to contain this
#HOST sf svn.code.sf.net
# HOSTNAME svn.code.sf.net
# IdentityFile ~/.ssh/your_sf_keyfile
# IdentitiesOnly yes
# User user_sf_username
svn copy svn+ssh://svn.code.sf.net/p/flightgear/fgaddon/trunk \
svn+ssh://svn.code.sf.net/p/flightgear/fgaddon/branches/release-${THIS_RELEASE} \
-m "branching for release ${THIS_RELEASE}"

Submodule simgear updated: c92a953511...9840302931

View File

@@ -1,41 +0,0 @@
import subprocess, os, sgprops
import xml.etree.cElementTree as ET
class SVNCatalogRepository:
def __init__(self, node):
path = node.getValue("path")
if not os.path.exists(path):
raise RuntimeError("No directory at:" + path)
self._path = path
xml = subprocess.check_output(["svn", "info", "--xml", path])
root = ET.fromstring(xml)
if (root.find(".//repository/root") == None):
raise RuntimeError("Not an SVN repository:" + path)
self._aircraftPath = None
if node.hasChild("scan-suffix"):
self._aircraftPath = os.path.join(path, node.getValue("scan-suffix"))
@property
def path(self):
return self._path
@property
def aircraftPath(self):
return self._aircraftPath
def hasPathChanged(self, path, oldRevision):
return self.scmRevisionForPath(path) != oldRevision
def scmRevisionForPath(self, path):
xml = subprocess.check_output(["svn", "info", "--xml", path])
root = ET.fromstring(xml)
commit = root.find(".//entry/commit")
return commit.get('revision', 0)
def update(self):
print "SVN update of", self._path
subprocess.call(["svn", "update", self._path])

View File

@@ -1,52 +0,0 @@
<?xml version="1.0"?>
<!--
Template catalog - copy and modify for your site as required
-->
<PropertyList>
<!--
catalogProps.addChild('version').value = '3.1.0'
catalogProps.addChild('id').value = 'org.flightgear.default'
catalogProps.addChild('license').value = 'GPL'
catalogProps.addChild('url').value = "http://fgfs.goneabitbursar.com/pkg/3.1.0/default-catalog.xml"
catalogProps.addChild('description').value = "Aircraft developed and maintained by the FlightGear project"
de = catalogProps.addChild('de')
# de.addChild('description').value = "<German translation of catalog description>"
fr = catalogProps.addChild('fr')
-->
<version>3.4.*</version>
<version>3.5.*</version>
<version>3.6.*</version>
<id>org.myorganisation.hangar</id>
<license>GPL</license>
<url>http://some.stable.url.com/foo/bar/catalog.xml</url>
<description>A collection of interesting aircraft with some features
</description>
<de>
<description>Au Deutsch</description>
</de>
<fr>
<description>Francais</description>
</fr>
<mirror>http://some.url/</mirror>
<!-- <mirror>another mirror</mirror> -->
<thumbnails>http://some.url/images</thumbnails>
<git-repository>git://some.git.repo/</git-repository>
<repository-prefix>Aircraft</repository-prefix>
</PropertyList>

View File

@@ -1 +1 @@
2016.4.3
2017.2.1