Compare commits
43 Commits
release/20
...
version/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8331bc2697 | ||
|
|
c0d6016d64 | ||
|
|
b350cd9827 | ||
|
|
8e22064b71 | ||
|
|
7a64df78e3 | ||
|
|
493ad2c306 | ||
|
|
533cec6236 | ||
|
|
0dd0bf3043 | ||
|
|
b0594ed4ef | ||
|
|
f2e86108d4 | ||
|
|
8462f3217a | ||
|
|
735f5160e4 | ||
|
|
a5949431b1 | ||
|
|
0622410e4a | ||
|
|
acb8a7a793 | ||
|
|
93b71e29e6 | ||
|
|
fcf5087da9 | ||
|
|
2c7e8318db | ||
|
|
157ce05c69 | ||
|
|
799b0b4ad6 | ||
|
|
c9f7483fc4 | ||
|
|
4d3a5fb528 | ||
|
|
e8a6c477cc | ||
|
|
21a53b3537 | ||
|
|
37ff25cfe4 | ||
|
|
0409f339ae | ||
|
|
771c2a2abe | ||
|
|
224a9a0b18 | ||
|
|
08cb5c481b | ||
|
|
c23ec2827f | ||
|
|
ba8feb7d6f | ||
|
|
f1f612206f | ||
|
|
ef36d50d9b | ||
|
|
5b969d37ec | ||
|
|
8e82d4e1fb | ||
|
|
2dfbc989ba | ||
|
|
93b085f441 | ||
|
|
52bceabab7 | ||
|
|
cee226183c | ||
|
|
6cb7d12ec1 | ||
|
|
16a42dfc6b | ||
|
|
9d6ce08430 | ||
|
|
95b7ef534b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,3 +20,4 @@ archivebuild
|
||||
osgbuild
|
||||
CMakeCache.txt
|
||||
*.pyc
|
||||
build-*
|
||||
|
||||
14
.gitmodules
vendored
14
.gitmodules
vendored
@@ -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 = next
|
||||
[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 = next
|
||||
[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 = next
|
||||
[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
|
||||
|
||||
@@ -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
339
Nasa2FGearthview/LICENSE
Normal 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
167
Nasa2FGearthview/README.md
Normal 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
1403
Nasa2FGearthview/convert.sh
Executable file
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@ cp simgear-*.tar.bz2 ../output/.
|
||||
#####################################################################################
|
||||
echo "Starting on FlightGear"
|
||||
cd ../fgBuild
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" ../flightgear
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DSIMGEAR_SHARED:BOOL="ON" -DFG_BUILD_TYPE=Release ../flightgear
|
||||
|
||||
# compile
|
||||
make
|
||||
@@ -60,4 +60,3 @@ echo "Assembling base package"
|
||||
cd $WORKSPACE
|
||||
|
||||
tar cjf output/FlightGear-$VERSION-data.tar.bz2 fgdata/
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
|
||||
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
|
||||
|
||||
IF %IS_NIGHTLY_BUILD% EQU 1 (
|
||||
SET FGBUILDTYPE=Nightly
|
||||
) ELSE (
|
||||
SET FGBUILDTYPE=Release
|
||||
)
|
||||
|
||||
REM following are for testing the script locally
|
||||
REM SET PATH=%PATH%;%ProgramFiles%\CMake\bin;%ProgramFiles(x86)%\"Inno Setup 5"\
|
||||
REM SET QT5SDK32=C:\Qt\5.6\msvc2015
|
||||
@@ -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 ..
|
||||
|
||||
@@ -86,17 +94,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
|
||||
|
||||
|
||||
@@ -78,3 +78,6 @@ simFeatureTags = [
|
||||
]
|
||||
|
||||
tags = aircraftTypeTags + manufacturerTags + eraTags + simFeatureTags + propulsionTags + featureTags
|
||||
|
||||
def isValidTag(maybeTag):
|
||||
return maybeTag in tags
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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):
|
||||
11
catalog/testData/bad-index.xml
Normal file
11
catalog/testData/bad-index.xml
Normal 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>
|
||||
25
catalog/testData/props1.xml
Normal file
25
catalog/testData/props1.xml
Normal 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>
|
||||
20
catalog/testData/props2.xml
Normal file
20
catalog/testData/props2.xml
Normal 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>
|
||||
22
catalog/testData/root-include.xml
Normal file
22
catalog/testData/root-include.xml
Normal 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>
|
||||
6
catalog/testData/sub-include.xml
Normal file
6
catalog/testData/sub-include.xml
Normal 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>
|
||||
61
catalog/test_sgprops.py
Executable file
61
catalog/test_sgprops.py
Executable 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()
|
||||
@@ -9,6 +9,9 @@ import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import sgprops
|
||||
import sys
|
||||
import catalogTags
|
||||
|
||||
CATALOG_VERSION = 4
|
||||
|
||||
@@ -23,6 +26,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:
|
||||
@@ -44,55 +49,125 @@ def make_xml_leaf(name, text):
|
||||
|
||||
# return all available aircraft information from the set file as a
|
||||
# dict
|
||||
def scan_set_file(set_file):
|
||||
def scan_set_file(aircraft_dir, set_file):
|
||||
global includes
|
||||
|
||||
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')
|
||||
set_path = os.path.join(aircraft_dir, set_file)
|
||||
|
||||
local_includes = includes
|
||||
local_includes.append(aircraft_dir)
|
||||
root_node = sgprops.readProps(set_path, includePaths = local_includes)
|
||||
|
||||
if not root_node.hasChild("sim"):
|
||||
return None
|
||||
|
||||
sim_node = root_node.getChild("sim")
|
||||
if sim_node == None:
|
||||
return None
|
||||
|
||||
variant = {}
|
||||
variant['name'] = 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['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
|
||||
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'))
|
||||
|
||||
# allow -set.xml files to declare themselves as primary.
|
||||
# we use this avoid needing a variant-of in every other -set.xml
|
||||
variant['primary-set'] = sim_node.getValue('primary-set', False)
|
||||
|
||||
# extract and record previews for each variant
|
||||
if sim_node.hasChild('previews'):
|
||||
print "has previews ..."
|
||||
variant['previews'] = extract_previews(sim_node.getChild('previews'), aircraft_dir)
|
||||
|
||||
if sim_node.hasChild('rating'):
|
||||
rating_node = sim_node.getChild("rating")
|
||||
variant['rating_FDM'] = rating_node.getValue("FDM", 0)
|
||||
variant['rating_systems'] = rating_node.getValue("systems", 0)
|
||||
variant['rating_cockpit'] = rating_node.getValue("cockpit", 0)
|
||||
variant['rating_model'] = rating_node.getValue("model", 0)
|
||||
|
||||
if sim_node.hasChild('tags'):
|
||||
variant['tags'] = extract_tags(sim_node.getChild('tags'), set_file)
|
||||
|
||||
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):
|
||||
# old way of finding the master aircraft: it's the only one whose
|
||||
# variant-of is empty. All the others have an actual value
|
||||
# newer alternative is to specify one -set.xml as the primary. All the
|
||||
# others are therefore variants.
|
||||
setDicts = []
|
||||
found_master = False
|
||||
package = None
|
||||
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:
|
||||
try:
|
||||
d = scan_set_file(aircraft_dir, file)
|
||||
if d == None:
|
||||
continue
|
||||
except:
|
||||
print "Skipping set file since couldn't be parsed:", os.path.join(aircraft_dir, file), sys.exc_info()[0]
|
||||
continue
|
||||
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'] == '':
|
||||
|
||||
setDicts.append(d)
|
||||
if d['primary-set']:
|
||||
found_master = True
|
||||
package = variant
|
||||
else:
|
||||
variants.append( {'id': variant['id'],
|
||||
'name': variant['name'] } )
|
||||
package = d
|
||||
|
||||
# didn't find a dict identified explicitly as the primary, look for one
|
||||
# with an undefined variant-of
|
||||
if not found_master:
|
||||
for d in setDicts:
|
||||
if d['variant-of'] == '':
|
||||
found_master = True
|
||||
package = d
|
||||
break
|
||||
|
||||
if not found_master:
|
||||
if len(setDicts) > 1:
|
||||
print "Warning, no explicit primary set.xml in " + aircraft_dir
|
||||
# use the first one
|
||||
package = setDicts[0]
|
||||
|
||||
# variants is just all the set dicts except the master
|
||||
variants = setDicts
|
||||
variants.remove(package)
|
||||
return (package, variants)
|
||||
|
||||
# use svn commands to report the last change date within dir
|
||||
@@ -143,6 +218,44 @@ def get_md5sum(file):
|
||||
f.close()
|
||||
return md5sum
|
||||
|
||||
def append_preview_nodes(node, variant, download_base, package_name):
|
||||
if not 'previews' in variant:
|
||||
return
|
||||
|
||||
for preview in variant['previews']:
|
||||
preview_node = ET.Element('preview')
|
||||
preview_url = download_base + 'previews/' + package_name + '_' + preview['path']
|
||||
preview_node.append( make_xml_leaf('type', preview['type']) )
|
||||
preview_node.append( make_xml_leaf('url', preview_url) )
|
||||
preview_node.append( make_xml_leaf('path', preview['path']) )
|
||||
node.append(preview_node)
|
||||
|
||||
def copy_previews_for_variant(variant, package_name, package_dir, previews_dir):
|
||||
if not 'previews' in variant:
|
||||
return
|
||||
|
||||
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 append_tag_nodes(node, variant):
|
||||
if not 'tags' in variant:
|
||||
return
|
||||
|
||||
for tag in variant['tags']:
|
||||
node.append(make_xml_leaf('tag', tag))
|
||||
|
||||
#def get_file_stats(file):
|
||||
# f = open(file, 'r')
|
||||
# md5 = hashlib.md5(f.read()).hexdigest()
|
||||
@@ -180,12 +293,25 @@ 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 +320,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,6 +360,7 @@ 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,
|
||||
@@ -264,6 +393,15 @@ for scm in scm_list:
|
||||
package_node.append(variant_node)
|
||||
variant_node.append( make_xml_leaf('id', variant['id']) )
|
||||
variant_node.append( make_xml_leaf('name', variant['name']) )
|
||||
if 'description' in variant:
|
||||
variant_node.append( make_xml_leaf('description', variant['description']) )
|
||||
|
||||
if 'author' in variant:
|
||||
variant_node.append( make_xml_leaf('author', variant['author']) )
|
||||
|
||||
append_preview_nodes(variant_node, variant, download_base, name)
|
||||
append_tag_nodes(variant_node, variant)
|
||||
|
||||
package_node.append( make_xml_leaf('dir', name) )
|
||||
if not download_base.endswith('/'):
|
||||
download_base += '/'
|
||||
@@ -272,6 +410,9 @@ for scm in scm_list:
|
||||
package_node.append( make_xml_leaf('url', download_url) )
|
||||
package_node.append( make_xml_leaf('thumbnail', thumbnail_url) )
|
||||
|
||||
append_preview_nodes(package_node, package, download_base, name)
|
||||
append_tag_nodes(package_node, package)
|
||||
|
||||
# todo: url (download), thumbnail (download url)
|
||||
|
||||
# get cached md5sum if it exists
|
||||
@@ -310,7 +451,7 @@ for scm in scm_list:
|
||||
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')
|
||||
@@ -319,6 +460,10 @@ for scm in scm_list:
|
||||
catalog_node.append(package_node)
|
||||
package_node.append( make_xml_leaf('thumbnail-path', 'thumbnail.jpg') )
|
||||
|
||||
# copy previews for the package and variants into the
|
||||
# output directory
|
||||
copy_previews_for_package(package, variants, name, aircraft_dir, previews_dir)
|
||||
|
||||
# write out the master catalog file
|
||||
cat_file = os.path.join(output_dir, 'catalog.xml')
|
||||
catalog_root.write(cat_file, encoding='utf-8', xml_declaration=True, pretty_print=True)
|
||||
@@ -332,4 +477,3 @@ files = os.listdir(output_dir)
|
||||
for file in files:
|
||||
if file.endswith('.zip')and not file in valid_zips:
|
||||
print "orphaned zip:", 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
|
||||
@@ -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
21
compile-scripts/README.md
Normal 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
130
compile-scripts/commands-linux.rb
Executable 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
135
compile-scripts/commands-mac.rb
Executable 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."
|
||||
52
compile-scripts/pull_build.bat
Normal file
52
compile-scripts/pull_build.bat
Normal 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
|
||||
@@ -18,7 +18,7 @@
|
||||
# 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)"
|
||||
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
|
||||
@@ -316,7 +316,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 +345,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,7 +378,7 @@ 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
|
||||
_gitDownload https://github.com/openscenegraph/osg.git
|
||||
_gitUpdate OpenSceneGraph-3.2
|
||||
|
||||
if [ "$RECONFIGURE" = "y" ]; then
|
||||
@@ -419,7 +419,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 +452,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 +479,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 +521,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 +649,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 +702,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 +753,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
2
fgdata
Submodule fgdata updated: a2e9da7604...c8b090fa4e
Submodule flightgear updated: 6f36cd89b7...989ebf73a6
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
239
package.py
239
package.py
@@ -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
|
||||
@@ -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:
|
||||
|
||||
73
release_builder/create-release-branch-for.sh
Executable file
73
release_builder/create-release-branch-for.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/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 Foobar. 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
|
||||
git config user.name "Automatic Release Builder"
|
||||
git config user.email "build@flightgear.org"
|
||||
createBranch
|
||||
popd > /dev/null
|
||||
shift
|
||||
done
|
||||
45
release_builder/create-release-branch.sh
Executable file
45
release_builder/create-release-branch.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
THIS_RELEASE="2017.1"
|
||||
NEXT_RELEASE="2017.2"
|
||||
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}"
|
||||
|
||||
1
release_builder/version
Normal file
1
release_builder/version
Normal file
@@ -0,0 +1 @@
|
||||
2017.3.0
|
||||
2
simgear
2
simgear
Submodule simgear updated: 235e38b69b...9840302931
@@ -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])
|
||||
@@ -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>
|
||||
|
||||
|
||||
Submodule windows-3rd-party updated: 5b231bc794...790648cd69
Reference in New Issue
Block a user