commit 7043629baf708cbb96671b66db3278e8be5b5d11 Author: Raoul Snyman Date: Sat Jun 9 21:02:47 2012 +0200 Created a packaging repository for Windows and OS X bzr-revno: 1 diff --git a/osx/DmgImageIcon.png b/osx/DmgImageIcon.png new file mode 100644 index 0000000..85457d8 Binary files /dev/null and b/osx/DmgImageIcon.png differ diff --git a/osx/DmgImageInstallBackground.png b/osx/DmgImageInstallBackground.png new file mode 100755 index 0000000..8a41d3b Binary files /dev/null and b/osx/DmgImageInstallBackground.png differ diff --git a/osx/DmgImageInstallBackgroundClean.png b/osx/DmgImageInstallBackgroundClean.png new file mode 100755 index 0000000..1008621 Binary files /dev/null and b/osx/DmgImageInstallBackgroundClean.png differ diff --git a/osx/Info.plist b/osx/Info.plist new file mode 100755 index 0000000..de01751 --- /dev/null +++ b/osx/Info.plist @@ -0,0 +1,125 @@ + + + + + + CFBundleDocumentTypes + + + CFBundleTypeExtension + + osz + + CFBundleTypeIconFiles + + OpenLP.icns + + CFBundleTypeName + OpenLP Service + CFBundleTypeRole + Viewer + LSHandlerRank + Owner + LSItemContentTypes + + org.openlp.osz + + + + CFBundleTypeExtension + + otz + + CFBundleTypeIconFiles + + OpenLP.icns + + CFBundleTypeName + OpenLP Theme + CFBundleTypeRole + Viewer + LSHandlerRank + Owner + LSItemContentTypes + + org.openlp.otz + + + + + UTExportedTypeDeclarations + + + UTTypeIdentifier + org.openlp.osz + UTTypeDescription + OpenLP Service + UTTypeConformsTo + + public.data + public.content + + UTTypeTagSpecification + + public.filename-extension + + osz + + public.mime-type + + application/x-openlp-service + + + + + UTTypeIdentifier + org.openlp.otz + UTTypeDescription + OpenLP Theme + UTTypeConformsTo + + public.data + public.content + + UTTypeTagSpecification + + public.filename-extension + + otz + + public.mime-type + + application/x-openlp-theme + + + + + +CFBundleIdentifier +org.openlp +CFBundleShortVersionString +%(openlp_version)s +CFBundleVersion +%(openlp_version)s +CFBundleInfoDictionaryVersion +6.0 +CFBundleDisplayName +OpenLP +CFBundleIconFile +OpenLP.icns +CFBundleExecutable +MacOS/OpenLP +CFBundleName +OpenLP +CFBundleGetInfoString +OpenLP %(openlp_version)s +LSHasLocalizedDisplayName + +NSAppleScriptEnabled + +CFBundlePackageType +APPL +LSBackgroundOnly + + + diff --git a/osx/LICENSE.txt b/osx/LICENSE.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/osx/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 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. + + + Copyright (C) + + 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. + + , 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. diff --git a/osx/Makefile b/osx/Makefile new file mode 100644 index 0000000..738a27a --- /dev/null +++ b/osx/Makefile @@ -0,0 +1,28 @@ +all: + python build.py -c openlp.cfg + +view: + python build.py -c openlp.cfg --package-view --compress-view + +package: + + python build.py -c openlp.cfg --package --package-view + +bundle: + + python build.py -c openlp.cfg --compress --compress-view + +clean: + # remove old configuration files + rm -f openlp.spec + rm -f Info.plist + rm -f .version + + # remove old build artifacts + rm -rf build + rm -rf dist + rm -rf Macopenlp.app + rm -rf OpenLP.app + rm -f warnopenlp.txt + rm -f *dmg + diff --git a/osx/OpenLP.icns b/osx/OpenLP.icns new file mode 100644 index 0000000..6066b11 Binary files /dev/null and b/osx/OpenLP.icns differ diff --git a/osx/applescript-adjustview-10-5.master b/osx/applescript-adjustview-10-5.master new file mode 100755 index 0000000..19be239 --- /dev/null +++ b/osx/applescript-adjustview-10-5.master @@ -0,0 +1,74 @@ +on saveImageWithItselfAsIcon(icon_image_file) + -- save icon_image_file with itself as icon + set icon_image_file_string to icon_image_file as string + tell application "Image Events" + launch + set icon_image to open file icon_image_file_string + save icon_image with icon + close icon_image + end tell +end saveImageWithItselfAsIcon + +on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder) + tell application "Finder" to set f to aFileOrFolderWithIcon as alias + -- grab the file's icon + my CopyOrPaste(f, "c") + -- now the icon is in the clipboard + tell application "Finder" to set c to aFileOrFolder as alias + my CopyOrPaste(result, "v") +end copyIconOfTo + +on CopyOrPaste(i, cv) + tell application "Finder" + activate + open information window of i + end tell + tell application "System Events" to tell process "Finder" to tell window 1 + keystroke tab -- select icon button + keystroke (cv & "w") using command down (* (copy or paste) + close window *) + end tell -- window 1 then process Finder then System Events +end CopyOrPaste + +on run + set icon_image_file to POSIX file "%s" as alias + set dmg_file to POSIX file "/Volumes/%s" as alias + + my saveImageWithItselfAsIcon(icon_image_file) + -- wait for virus scanner + delay 2 + my copyIconOfTo(icon_image_file, dmg_file) + + tell application "Finder" + tell disk "%s" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {400, 100, 1100, 500} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + set background picture of theViewOptions to file ".background:installer-background.png" + if not exists file "Applications" then + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + end if + delay 5 + set position of item "%s" of container window to {160, 200} + set position of item ".Trashes" of container window to {100, 500} + set position of item ".installer-background.png" of container window to {200, 500} + set position of item ".DS_Store" of container window to {400, 500} + set position of item "Applications" of container window to {550, 200} + set position of item ".VolumeIcon.icns" of container window to {500, 500} + set position of item ".fseventsd" of container window to {300, 500} + if exists POSIX file ".SymAVx86QSFile" then + set position of item ".SymAVx86QSFile" of container window to {600, 500} + end if + open + close + update without registering applications + -- wait until the virus scan completes + delay 5 + -- eject + end tell + end tell +end run diff --git a/osx/applescript-adjustview-10-6.master b/osx/applescript-adjustview-10-6.master new file mode 100755 index 0000000..1708425 --- /dev/null +++ b/osx/applescript-adjustview-10-6.master @@ -0,0 +1,77 @@ +on saveImageWithItselfAsIcon(icon_image_file) + -- save icon_image_file with itself as icon + set icon_image_file_string to icon_image_file as string + tell application "Image Events" + launch + set icon_image to open file icon_image_file_string + save icon_image with icon + close icon_image + end tell +end saveImageWithItselfAsIcon + +on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder) + tell application "Finder" to set f to aFileOrFolderWithIcon as alias + -- grab the file's icon + my CopyOrPaste(f, "c") + -- now the icon is in the clipboard + tell application "Finder" to set c to aFileOrFolder as alias + my CopyOrPaste(result, "v") +end copyIconOfTo + +on CopyOrPaste(i, cv) + tell application "Finder" + activate + set infoWindow to open information window of i + set infoWindowName to name of infoWindow + end tell + tell application "System Events" to tell process "Finder" to tell window infoWindowName + keystroke tab -- select icon button + keystroke (cv & "w") using command down (* (copy or paste) + close window *) + end tell -- window 1 then process Finder then System Events +end CopyOrPaste + +on run + set icon_image_file to POSIX file "%s" as alias + set dmg_file to POSIX file "/Volumes/%s" as alias + + my saveImageWithItselfAsIcon(icon_image_file) + -- wait for virus scanner + delay 2 + my copyIconOfTo(icon_image_file, dmg_file) + + tell application "Finder" + tell disk "%s" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {400, 100, 1100, 500} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + set background picture of theViewOptions to file ".background:installer-background.png" + if not exists file "Applications" then + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + end if + delay 1 + set position of item "%s" of container window to {160, 200} + set position of item ".Trashes" of container window to {100, 500} + set position of item ".background" of container window to {200, 500} + set position of item ".DS_Store" of container window to {400, 500} + set position of item "Applications" of container window to {550, 200} + if exists file ".VolumeIcon.icns" then + set position of item ".VolumeIcon.icns" of container window to {500, 500} + end if + set position of item ".fseventsd" of container window to {300, 500} + if exists POSIX file ".SymAVx86QSFile" then + set position of item ".SymAVx86QSFile" of container window to {600, 500} + end if + open + close + update without registering applications + -- wait until the virus scan completes + delay 5 + -- eject + end tell + end tell +end run diff --git a/osx/applescript-seticon-10-5.master b/osx/applescript-seticon-10-5.master new file mode 100755 index 0000000..738c4b8 --- /dev/null +++ b/osx/applescript-seticon-10-5.master @@ -0,0 +1,40 @@ +on saveImageWithItselfAsIcon(icon_image_file) + -- save icon_image_file with itself as icon + set icon_image_file_string to icon_image_file as string + tell application "Image Events" + launch + set icon_image to open file icon_image_file_string + save icon_image with icon + close icon_image + end tell +end saveImageWithItselfAsIcon + +on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder) + tell application "Finder" to set f to aFileOrFolderWithIcon as alias + -- grab the file's icon + my CopyOrPaste(f, "c") + -- now the icon is in the clipboard + tell application "Finder" to set c to aFileOrFolder as alias + my CopyOrPaste(result, "v") +end copyIconOfTo + +on CopyOrPaste(i, cv) + tell application "Finder" + activate + open information window of i + end tell + tell application "System Events" to tell process "Finder" to tell window 1 + keystroke tab -- select icon button + keystroke (cv & "w") using command down (* (copy or paste) + close window *) + end tell -- window 1 then process Finder then System Events +end CopyOrPaste + +on run + set icon_image_file to POSIX file "%s" as alias + set dmg_file to POSIX file "%s" as alias + + my saveImageWithItselfAsIcon(icon_image_file) + -- wait for virus scanner + delay 2 + my copyIconOfTo(icon_image_file, dmg_file) +end run diff --git a/osx/applescript-seticon-10-6.master b/osx/applescript-seticon-10-6.master new file mode 100755 index 0000000..849f023 --- /dev/null +++ b/osx/applescript-seticon-10-6.master @@ -0,0 +1,41 @@ +on saveImageWithItselfAsIcon(icon_image_file) + -- save icon_image_file with itself as icon + set icon_image_file_string to icon_image_file as string + tell application "Image Events" + launch + set icon_image to open file icon_image_file_string + save icon_image with icon + close icon_image + end tell +end saveImageWithItselfAsIcon + +on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder) + tell application "Finder" to set f to aFileOrFolderWithIcon as alias + -- grab the file's icon + my CopyOrPaste(f, "c") + -- now the icon is in the clipboard + tell application "Finder" to set c to aFileOrFolder as alias + my CopyOrPaste(result, "v") +end copyIconOfTo + +on CopyOrPaste(i, cv) + tell application "Finder" + activate + set infoWindow to open information window of i + set infoWindowName to name of infoWindow + end tell + tell application "System Events" to tell process "Finder" to tell window infoWindowName + keystroke tab -- select icon button + keystroke (cv & "w") using command down (* (copy or paste) + close window *) + end tell -- window 1 then process Finder then System Events +end CopyOrPaste + +on run + set icon_image_file to POSIX file "%s" as alias + set dmg_file to POSIX file "%s" as alias + + my saveImageWithItselfAsIcon(icon_image_file) + -- wait for virus scanner + delay 2 + my copyIconOfTo(icon_image_file, dmg_file) +end run diff --git a/osx/config.ini.default b/osx/config.ini.default new file mode 100644 index 0000000..0fc6792 --- /dev/null +++ b/osx/config.ini.default @@ -0,0 +1,19 @@ +[executables] +sphinx = sphinx-build +pyinstaller = %(here)s/../pyinstaller/pyinstaller.py +lrelease = lrelease +diskutil = diskutil +hdiutil = hdiutil +osascript = osascript + +[paths] +branch = %(projects)s/trunk +documentation = %(projects)s/documentation +macicon = %(here)s/OpenLP.icns +bundleinfo = %(here)s/Info.plist +hooks = resources/pyinstaller +dmg_background = %(here)s/DmgImageInstallBackground.png + +[transifex] +username = +password = diff --git a/osx/macosx-builder.py b/osx/macosx-builder.py new file mode 100644 index 0000000..5179e9a --- /dev/null +++ b/osx/macosx-builder.py @@ -0,0 +1,714 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # +# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # +# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode # +# Woldsund # +# --------------------------------------------------------------------------- # +# 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; version 2 of the License. # +# # +# 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., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +""" +Mac OS X Build Script +-------------------- + +This script is used to build the Mac OS X app bundle and pack it into dmg file. +For this script to work out of the box, it depends on a number of things: + +Python 2.6/2.7 + +PyQt4 + You should already have this installed, OpenLP doesn't work without it. The + version the script expects is the packaged one available from River Bank + Computing. + +PyEnchant + This script expects the precompiled, installable version of PyEnchant to be + installed. You can find this on the PyEnchant site. + +Sphinx + This is used to build the documentation. The documentation trunk must be at + the same directory level as OpenLP trunk and named "documentation". + +PyInstaller + PyInstaller should be a checkout of revision 1355 of trunk, and in a + directory which is configured in the openlp.cfg. The revision is very + important as there is just included a fix for builds on OS X. + + To install PyInstaller, first checkout trunk from Subversion. The + easiest way is to do a + + svn co http://svn.pyinstaller.org/trunk + + Then you need to copy the two hook-*.py files from the "pyinstaller" + subdirectory in OpenLP's "resources" directory into PyInstaller's + "hooks" directory. + +Bazaar + You need the command line "bzr" client installed. + +OpenLP + A checkout of the latest code, in a branch directory, which is in a Bazaar + shared repository directory. This means your code should be in a directory + structure like this: "openlp\branch-name". + +macosx-builder.py + This script, of course. It should be in the "osx-package" directory + at the same level as OpenLP trunk. + +Mako + Mako Templates for Python. This package is required for building the + remote plugin. It can be installed by going to your + python_directory\scripts\.. and running "easy_install Mako". If you do not + have easy_install, the Mako package can be obtained here: + + http://www.makotemplates.org/download.html + +SQLAlchemy Migrate + Required for the databases used in OpenLP. The package can be + obtained here: + + http://code.google.com/p/sqlalchemy-migrate/ + + +config.ini.default + The configuration file contains settings of the version string to include + in the bundle as well as directory and file settings for different + purposes (e.g. PyInstaller location or installer background image) + +To start the build process do a + + make + +The result should be a {openlp_dmgname}.dmg +file in the same directory. If something went wrong - this sometimes happen +with the graphical commands in the Apple script - do a + + make clean + +and start the build process again. If you want to execute only parts of the +build process you can specify different make targets + + make view -- runs the Apple scripts to set the icons + make package -- creates the dmg file and copies the application files + make bundle -- compresses the dmg file and sets the dmg file icon +""" + +import os +import plistlib +import sys +from shutil import copy, rmtree +from subprocess import Popen, PIPE +from ConfigParser import SafeConfigParser as ConfigParser +from argparse import ArgumentParser + + +def _which(command): + """ + Return absolute path to a command found on system PATH. + """ + for path in os.environ["PATH"].split(os.pathsep): + if os.access(os.path.join(path, command), os.X_OK): + print "%s/%s" % (path, command) + return "%s/%s" % (path, command) + + +class MacosxBuilder(object): + """ + The :class:`MacosxBuilder` class encapsulates everything that is needed + to build a Mac OS X .dmg file. + """ + def __init__(self): + self.setup_args() + self.setup_system_paths() + self.read_config() + self.setup_executables() + self.setup_paths() + + def _print(self, text, *args): + """ + Print stuff out. Later we might want to use a log file. + """ + if len(args) > 0: + text = text % tuple(args) + print text + + def _print_verbose(self, text, *args): + """ + Print output, obeying "verbose" mode. + """ + if self.args.verbose: + self._print(text, *args) + + def _run_command(self, cmd, err_msg): + """ + Run command in subprocess and print error message in case of Exception. + + Return text from stdout. + """ + proc = Popen(cmd, stdout=PIPE, stderr=PIPE) + output, error = proc.communicate() + code = proc.wait() + if code != 0: + self._print(output) + self._print(error) + raise Exception(err_msg) + return output + + def _get_directory_size(self, directory): + """ + Return directory size - size of everything in the dir. + """ + dir_size = 0 + for (path, dirs, files) in os.walk(directory): + for file in files: + filename = os.path.join(path, file) + dir_size += os.path.getsize(filename) + return dir_size + + def _get_mountpoints(self): + """ + Return list of mounted disks on Mac. + """ + # Get the output in plist format. + paths = [] + output = self._run_command([self.hdiutil, 'info', '-plist'], + u'Detecting mount points failed.') + pl = plistlib.readPlistFromString(output) + for image in pl['images']: + for se in image['system-entities']: + if se.get('mount-point'): + paths.append(se.get('mount-point')) + + return paths + + def setup_args(self): + """ + Set up an argument parser and parse the command line arguments. + """ + parser = ArgumentParser() + parser.add_argument('-b', '--branch', metavar='BRANCH', dest='branch', + help='Specify the path to the branch you wish to build.', + default='../trunk') + parser.add_argument('--devel', dest='devel', + action='store_true', default=False, + help='Development build does not have set icons for .dmg file ' + 'and .dmg filename contains bzr revision number.') + parser.add_argument('-d', '--documentation', metavar='DOCS', + dest='docs', default=os.path.join('..', 'documentation'), + help='Specify the path to the documentation branch.') + parser.add_argument('-c', '--config', metavar='CONFIG', dest='config', + help='Specify the path to the configuration file.', + default=os.path.abspath(os.path.join('.', 'config.ini.default'))) + parser.add_argument('-u', '--skip-update', dest='skip_update', + action='store_true', default=False, + help='Do NOT update the branch before building.') + parser.add_argument('-t', '--skip-translations', + dest='skip_translations', action='store_true', default=False, + help='Do NOT update the language translation files.') + parser.add_argument('--transifex', + dest='update_translations', action='store_true', default=False, + help='Update the language translation from Transifex.') + parser.add_argument('-v', '--verbose', dest='verbose', + action='store_true', default=False, + help='Print out additional information.') + self.args = parser.parse_args() + + def read_config(self): + """ + Read the configuration from the configuration file. + """ + self.config = ConfigParser(defaults={ + u'here': self.script_path + }) + self.config.read(os.path.abspath(self.args.config)) + + def setup_system_paths(self): + """ + Set up some system paths. + """ + self.script_path = os.path.dirname(os.path.abspath(__file__)) + self.python = sys.executable + + def setup_executables(self): + """ + Set up the paths to the executables we use. + """ + self.sphinx = _which(self.config.get(u'executables', u'sphinx')) + self.pyinstaller = os.path.abspath( + self.config.get(u'executables', u'pyinstaller')) + self.lrelease = _which(self.config.get(u'executables', u'lrelease')) + self.diskutil = _which(self.config.get(u'executables', u'diskutil')) + self.hdiutil = _which(self.config.get(u'executables', u'hdiutil')) + self.osascript = _which(self.config.get(u'executables', u'osascript')) + + def setup_paths(self): + """ + Set up a variety of paths that we use throughout the build process. + """ + if self.args.branch: + branch_path = self.args.branch + else: + branch_path = self.config.get(u'paths', u'branch') + self.branch_path = os.path.abspath(branch_path) + if self.args.docs: + docs_path = self.args.docs + else: + docs_path = self.config.get(u'paths', u'documentation') + self.docs_path = os.path.abspath(docs_path) + + self.openlp_script = os.path.abspath( + os.path.join(branch_path, u'openlp.pyw')) + self.hooks_path = os.path.abspath(os.path.join( + self.branch_path, self.config.get(u'paths', u'hooks'))) + self.mac_icon = os.path.abspath( + self.config.get(u'paths', u'macicon')) + self.bundle_info = os.path.abspath( + self.config.get(u'paths', u'bundleinfo')) + self.dmg_background_img = os.path.abspath( + self.config.get(u'paths', u'dmg_background')) + self.i18n_utils = os.path.join(self.branch_path, u'scripts', + u'translation_utils.py') + self.source_path = os.path.join(self.branch_path, u'openlp') + self.manual_path = os.path.join(self.docs_path, u'manual') + self.manual_build_path = os.path.join(self.manual_path, u'build') + self.i18n_path = os.path.join(self.branch_path, u'resources', u'i18n') + self.build_path = os.path.join(self.branch_path, u'build') + self.dist_app_path = os.path.join(self.branch_path, u'dist', u'OpenLP.app') + self.dist_path = os.path.join(self.branch_path, u'dist', u'OpenLP.app', + 'Contents', 'MacOS') + + # Path to Qt translation files. + from PyQt4.QtCore import QCoreApplication + qt_plug_dir = str(list(QCoreApplication.libraryPaths())[0]) + self.qt_translat_path = os.path.join(os.path.dirname(qt_plug_dir), + 'translations') + + def update_code(self): + """ + Update the code in the branch. + """ + os.chdir(self.branch_path) + self._print(u'Reverting any changes to the code...') + bzr = Popen((u'bzr', u'revert'), stdout=PIPE) + output = bzr.communicate()[0] + code = bzr.wait() + if code != 0: + self._print(output) + raise Exception(u'Error reverting the code') + self._print(u'Updating the code...') + bzr = Popen((u'bzr', u'update'), stdout=PIPE) + output = bzr.communicate()[0] + code = bzr.wait() + if code != 0: + self._print(output) + raise Exception(u'Error updating the code') + + def run_pyinstaller(self): + """ + Run PyInstaller on the branch to build an executable. + """ + self._print(u'Running PyInstaller...') + os.chdir(self.branch_path) + # arch -i386 ensures 32bit build is created. + pyinstaller = Popen(('arch', '-i386', self.python, + self.pyinstaller, + u'--noconfirm', + u'--windowed', + u'--noupx', + u'--additional-hooks-dir', self.hooks_path, + u'--log-level=ERROR', + u'-o', self.branch_path, + #u'-i', self.mac_icon, + u'-p', self.branch_path, + u'-n', u'OpenLP', + self.openlp_script), + stdout=PIPE) + output = pyinstaller.communicate()[0] + code = pyinstaller.wait() + if code != 0: + self._print(output) + raise Exception(u'Error running PyInstaller') + + def write_version_file(self): + """ + Write the version number to a file for reading once installed. + """ + self._print(u'Writing version file...') + os.chdir(self.branch_path) + bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE) + output = bzr.communicate()[0] + code = bzr.wait() + if code != 0: + raise Exception(u'Error running bzr tags') + lines = output.splitlines() + if len(lines) == 0: + tag = u'0.0.0' + revision = u'0' + else: + tag, revision = lines[-1].split() + bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'), stdout=PIPE) + output, error = bzr.communicate() + code = bzr.wait() + if code != 0: + raise Exception(u'Error running bzr log') + output_ascii = unicode(output, errors=u'ignore') + latest = output_ascii.split(u':')[0] + version_string = latest == revision and tag or \ + u'%s-bzr%s' % (tag, latest) + self.version_string = version_string + version_file = open(os.path.join(self.dist_path, u'.version'), u'w') + version_file.write(version_string) + version_file.close() + + def copy_plugins(self): + """ + Copy all the plugins to the correct directory so that OpenLP sees that + it has plugins. + """ + self._print(u'Copying plugins...') + source = os.path.join(self.source_path, u'plugins') + dest = os.path.join(self.dist_path, u'plugins') + for root, dirs, files in os.walk(source): + for filename in files: + if not filename.endswith(u'.pyc'): + dest_path = os.path.join(dest, root[len(source)+1:]) + if not os.path.exists(dest_path): + os.makedirs(dest_path) + self._print_verbose(u'... %s', filename) + copy(os.path.join(root, filename), + os.path.join(dest_path, filename)) + + def copy_media_player(self): + """ + Copy the media players to the correct directory for OpenLP. + """ + self._print(u'Copying media player...') + source = os.path.join(self.source_path, u'core', u'ui', u'media') + dest = os.path.join(self.dist_path, u'core', u'ui', u'media') + for root, dirs, files in os.walk(source): + for filename in files: + if not filename.endswith(u'.pyc'): + dest_path = os.path.join(dest, root[len(source)+1:]) + if not os.path.exists(dest_path): + os.makedirs(dest_path) + self._print_verbose(u'... %s', filename) + copy(os.path.join(root, filename), + os.path.join(dest_path, filename)) + + def copy_mac_bundle_files(self): + """ + Copy Info.plist and OpenLP.icns to app bundle. + """ + copy(self.mac_icon, os.path.join(self.dist_app_path, + 'Contents', 'Resources', os.path.basename(self.mac_icon))) + # Add OpenLP version to Info.plist and put it to app bundle. + fr = open(self.bundle_info, u'r') + fw = open(os.path.join(self.dist_app_path, + 'Contents', os.path.basename(self.bundle_info)), 'w') + text = fr.read() + text = text % {'openlp_version': self.version_string} + fw.write(text) + + fr.close() + fw.close() + + def copy_macosx_files(self): + """ + Copy all the OSX-specific files. + """ + self._print(u'Copying extra files for Mac OS X...') + self._print_verbose(u'... LICENSE.txt') + copy(os.path.join(self.script_path, u'LICENSE.txt'), + os.path.join(self.dist_path, u'LICENSE.txt')) + + def update_translations(self): + """ + Update the translations. + """ + self._print(u'Updating translations...') + if not self.config.has_section('transifex'): + raise Exception(u'No section named "transifex" found.') + if not self.config.has_option('transifex', 'username'): + raise Exception(u'No option named "username" found.') + if not self.config.has_option('transifex', 'password'): + raise Exception(u'No option named "password" found.') + username = self.config.get(u'transifex', u'username') + password = self.config.get(u'transifex', u'password') + os.chdir(os.path.split(self.i18n_utils)[0]) + translation_utils = Popen([self.python, self.i18n_utils, u'-qdpu', + u'-U', username, u'-P', password]) + code = translation_utils.wait() + if code != 0: + raise Exception(u'Error running translation_utils.py') + + def compile_translations(self): + """ + Compile the translations for Qt. + """ + self._print(u'Compiling translations...') + files = os.listdir(self.i18n_path) + if not os.path.exists(os.path.join(self.dist_path, u'i18n')): + os.makedirs(os.path.join(self.dist_path, u'i18n')) + for file in files: + if file.endswith(u'.ts'): + self._print_verbose(u'... %s', file) + source_path = os.path.join(self.i18n_path, file) + dest_path = os.path.join(self.dist_path, u'i18n', + file.replace(u'.ts', u'.qm')) + lconvert = Popen((self.lrelease, u'-compress', u'-silent', + source_path, u'-qm', dest_path)) + code = lconvert.wait() + if code != 0: + raise Exception(u'Error running lconvert on %s' % \ + source_path) + self._print(u'Copying qm files...') + source = self.qt_translat_path + files = os.listdir(source) + for filename in files: + if filename.startswith(u'qt_') and filename.endswith(u'.qm') and \ + len(filename) == 8: + self._print_verbose(u'... %s', filename) + copy(os.path.join(source, filename), + os.path.join(self.dist_path, u'i18n', filename)) + + def run_sphinx(self): + """ + Run Sphinx to build an HTML Help project. + """ + self._print(u'Deleting previous manual build... %s', + self.manual_build_path) + if os.path.exists(self.manual_build_path): + rmtree(self.manual_build_path) + self._print(u'Running Sphinx...') + os.chdir(self.manual_path) + sphinx = Popen((self.sphinx, u'-b', u'htmlhelp', u'-d', + u'build/doctrees', u'source', u'build/htmlhelp'), stdout=PIPE) + output, error = sphinx.communicate() + code = sphinx.wait() + if code != 0: + self._print(output) + raise Exception(u'Error running Sphinx') + + def create_dmg_file(self): + """ + Create .dmg file. + """ + self._print(u'Creating dmg file...') + + dmg_name = 'OpenLP-' + self.version_string + '.dmg' + dmg_file = os.path.join(self.branch_path, 'build', dmg_name) + # Remove dmg if it exists. + if os.path.exists(dmg_file): + os.remove(dmg_file) + # Create empty dmg file. + size = self._get_directory_size(self.dist_app_path) # in bytes. + size = size / (1024 * 1024) # Convert to megabytes. + size += 10 # Additional space in .dmg for other files. + self._print(u'... dmg disk size: %s' % size) + self._run_command([self.hdiutil, 'create', dmg_file, + '-ov', '-megabytes', str(size), + '-fs', 'HFS+', '-volname', 'OpenLP'], + u'Could not create dmg file.' + ) + + # Mount empty dmg file. + old_mounts = self._get_mountpoints() + self._print(u'... mounting the dmg file: %s' % dmg_file) + self._run_command([self.hdiutil, 'attach', dmg_file], + u'Could not mount dmg file, cannot continue.' + ) + new_mounts = self._get_mountpoints() + # Get the mount point from difference between paths + # after mounting and before mounting the dmg file. + dmg_volume_path = list(set(new_mounts) - set(old_mounts))[0] + + # Copy OpenLP.app and other files to .dmg + # TODO more reliable way to determine dmg_volume_path + self._print(u'... Copying the app to the dmg: ' + dmg_volume_path) + self._run_command(['cp', '-r', self.dist_app_path, + dmg_volume_path], + u'Could not copy app bundle, dmg creation failed.' + ) + + self._print('... Copying the background image.') + os.mkdir(os.path.join(dmg_volume_path, '.background')) + self._run_command(['cp', self.dmg_background_img, + os.path.join(dmg_volume_path, + '.background/installer-background.png')], + u'Could not copy the background image, dmg creation failed.' + ) + + # Unmount dmg file. + self._print('... unmounting the dmg.') + self._run_command([self.hdiutil, 'detach', dmg_volume_path], + 'Could not unmount the dmg file, dmg creation failed.' + ) + + # Compress dmg file. + self._print('... compressing the dmg file') + compressed_dmg = os.path.join(self.branch_path, 'dist', + os.path.basename(dmg_file)) # Put dmg to 'dist' dir. + # Remove dmg if it exists. + if os.path.exists(compressed_dmg): + os.remove(compressed_dmg) + self._run_command([self.hdiutil, + 'convert', dmg_file, '-format', 'UDZO', + '-imagekey', 'zlib-level=9', '-o', compressed_dmg], + u'Could not compress the dmg file, dmg creation failed.' + ) + + # Jenkins integration. + # Continuous integration server needs to know the filename of dmg. + # Write java property file. For uploading dmg to openlp. + if self.args.devel: + fpath = os.path.join(self.branch_path, 'openlp.properties') + self._print('... writing property file for jenkins: %s' % + fpath) + f = open(fpath, 'w') + f.write('OPENLP_DMGNAME=' + os.path.basename(dmg_file) + '\n') + f.close() + + # Dmg done. + self._print('Finished creating dmg file, resulting file: %s' % + compressed_dmg) + + # TODO Reimplement following actions. + #adjust_package_view(settings, adjustview_scriptname) + #compress_view(settings, seticon_scriptname, dmg_file) + + + def main(self): + """ + The main function to run the Mac OS X builder. + """ + self._print_verbose(u'OpenLP main script: ......%s', + self.openlp_script) + self._print_verbose(u'Script path: .............%s', + os.path.split(os.path.abspath(__file__))[0]) + self._print_verbose(u'Branch path: .............%s', self.branch_path) + self._print_verbose(u'Source path: .............%s', self.source_path) + self._print_verbose(u'"dist.app" path: .........%s', self.dist_app_path) + self._print_verbose(u'"dist" path: .............%s', self.dist_path) + self._print_verbose(u'"hooks" path: .............%s', self.hooks_path) + self._print_verbose(u'PyInstaller: .............%s', self.pyinstaller) + self._print_verbose(u'Documentation branch path:%s', self.docs_path) + self._print_verbose(u'') + if not self.args.skip_update: + self.update_code() + self.run_pyinstaller() + self.write_version_file() + self.copy_mac_bundle_files() + self.copy_plugins() + self.copy_media_player() + # TODO creating help on Mac + if os.path.exists(self.manual_path): + self.run_sphinx() + else: + self._print(u'') + self._print(u'WARNING: Documentation trunk not found. Mac OS X') + self._print(u' Help file will not be included in build') + self._print(u'') + self.copy_macosx_files() + if not self.args.skip_translations: + if self.args.update_translations: + self.update_translations() + self.compile_translations() + self.create_dmg_file() + + self._print(u'Done.') + raise SystemExit() + + +if __name__ == u'__main__': + MacosxBuilder().main() + + + +# TODO reimplement following options. They arenecessary for release builds. +def compress_view(settings, seticon_scriptname, dmg_file): + logging.info('[%s] setting icon of the dmg file...', script_name) + try: + f = open(seticon_scriptname) + p = subp.Popen(["osascript"], stdin=subp.PIPE) + p.communicate(f.read() % ((os.getcwd() + '/' + + settings['openlp_dmg_icon_file']), dmg_file)) + f.close() + result = p.returncode + if (result != 0): + logging.error('[%s] could not set the icon to the dmg file, \ + dmg creation failed!', script_name) + sys.exit(1) + except IOError, e: + logging.error('[%s] could not adjust the view (%s), dmg creation \ + failed!', script_name, e) + sys.exit(1) + except OSError, e: + logging.error('[%s] could not set the icon to the dmg file(%s), \ + dmg creation failed!', script_name, e) + sys.exit(1) + +def adjust_package_view(settings, adjustview_scriptname): + logging.info('[%s] making adjustments to the view...', script_name) + try: + f = open(adjustview_scriptname) + p = subp.Popen(["osascript"], stdin=subp.PIPE) + p.communicate(f.read() % ((os.getcwd() + '/' + \ + settings['openlp_dmg_icon_file']), + settings['openlp_appname'], + settings['openlp_appname'], + settings['openlp_appname'])) + f.close() + result = p.returncode + if (result != 0): + logging.error('[%s] could not adjust the view, dmg creation \ + failed!', script_name) + sys.exit(1) + except IOError, e: + logging.error('[%s] could not adjust the view (%s), dmg creation \ + failed!', script_name, e) + sys.exit(1) + except OSError, e: + logging.error('[%s] could not adjust the view (%s), dmg creation \ + failed!', script_name, e) + sys.exit(1) + +def old_main(): + + version = platform.mac_ver()[0] + # we only need the differenciation between leopard and snow leopard + if version.startswith("10.6") or version.startswith("10.7"): + SNOWLEOPARD = True + logging.info('[%s] using snow leopard scripts (version = %s)', + script_name, version) + adjustview_scriptname = "applescript-adjustview-10-6.master" + seticon_scriptname = "applescript-seticon-10-6.master" + else: + SNOWLEOPARD = False + logging.info('[%s] using leopard scripts (version = %s)', script_name, + version) + adjustview_scriptname = "applescript-adjustview-10-5.master" + seticon_scriptname = "applescript-seticon-10-5.master" + + if not os.path.isfile(adjustview_scriptname) \ + or not os.path.isfile(seticon_scriptname): + logging.error('[%s] could not find apple scripts for given OS X ' + + 'version %s', script_name, version) + sys.exit(1) diff --git a/windows/LICENSE.txt b/windows/LICENSE.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/windows/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 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. + + + Copyright (C) + + 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. + + , 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. diff --git a/windows/OpenLP-2.0.iss.default b/windows/OpenLP-2.0.iss.default new file mode 100644 index 0000000..b13f2e8 --- /dev/null +++ b/windows/OpenLP-2.0.iss.default @@ -0,0 +1,184 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define AppName "OpenLP" +#define AppVerName "OpenLP 2.0" +#define AppPublisher "OpenLP Developers" +#define AppURL "http://openlp.org/" +#define AppExeName "OpenLP.exe" + +#define FileHandle FileOpen("%(branch)s\dist\OpenLP\.version") +#define FileLine FileRead(FileHandle) +#define RealVersion FileLine +#expr FileClose(FileHandle) + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppID={{AA7699FA-B2D2-43F4-8A70-D497D03C9485} +AppName={#AppName} +AppVerName={#AppVerName} +AppPublisher={#AppPublisher} +AppPublisherURL={#AppURL} +AppSupportURL={#AppURL} +AppUpdatesURL={#AppURL} +DefaultDirName={pf}\{#AppName} +DefaultGroupName={#AppVerName} +AllowNoIcons=true +LicenseFile=LICENSE.txt +OutputDir=%(branch)s\dist +OutputBaseFilename=OpenLP-{#RealVersion}-setup +Compression=lzma/Max +SolidCompression=true +SetupIconFile=OpenLP.ico +WizardImageFile=WizImageBig.bmp +WizardSmallImageFile=WizImageSmall.bmp +ChangesAssociations=true + +[Languages] +Name: english; MessagesFile: compiler:Default.isl +Name: basque; MessagesFile: compiler:Languages\Basque.isl +Name: brazilianportuguese; MessagesFile: compiler:Languages\BrazilianPortuguese.isl +Name: catalan; MessagesFile: compiler:Languages\Catalan.isl +Name: czech; MessagesFile: compiler:Languages\Czech.isl +Name: danish; MessagesFile: compiler:Languages\Danish.isl +Name: dutch; MessagesFile: compiler:Languages\Dutch.isl +Name: finnish; MessagesFile: compiler:Languages\Finnish.isl +Name: french; MessagesFile: compiler:Languages\French.isl +Name: german; MessagesFile: compiler:Languages\German.isl +Name: hebrew; MessagesFile: compiler:Languages\Hebrew.isl +Name: hungarian; MessagesFile: compiler:Languages\Hungarian.isl +Name: italian; MessagesFile: compiler:Languages\Italian.isl +Name: japanese; MessagesFile: compiler:Languages\Japanese.isl +Name: norwegian; MessagesFile: compiler:Languages\Norwegian.isl +Name: polish; MessagesFile: compiler:Languages\Polish.isl +Name: portuguese; MessagesFile: compiler:Languages\Portuguese.isl +Name: russian; MessagesFile: compiler:Languages\Russian.isl +Name: slovak; MessagesFile: compiler:Languages\Slovak.isl +Name: slovenian; MessagesFile: compiler:Languages\Slovenian.isl +Name: spanish; MessagesFile: compiler:Languages\Spanish.isl + +[Tasks] +Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons} +Name: quicklaunchicon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; OnlyBelowVersion: 0, 6.1 + +[Files] +Source: %(branch)s\dist\OpenLP\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs +; DLL used to check if the target program is running at install time +Source: psvince.dll; flags: dontcopy +; psvince is installed in {app} folder, so it will be loaded at +; uninstall time to check if the target program is running +Source: psvince.dll; DestDir: {app} + +[Icons] +Name: {group}\{#AppName}; Filename: {app}\{#AppExeName} +Name: {group}\{#AppName} (Debug); Filename: {app}\{#AppExeName}; Parameters: -l debug +Name: {group}\{#AppName} Help; Filename: {app}\{#AppName}.chm; Check: FileExists(ExpandConstant('{app}\{#AppName}.chm')) +Name: {group}\{cm:ProgramOnTheWeb,{#AppName}}; Filename: {#AppURL} +Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe} +Name: {commondesktop}\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: desktopicon +Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: quicklaunchicon + +[Run] +Filename: {app}\{#AppExeName}; Description: {cm:LaunchProgram,{#AppName}}; Flags: nowait postinstall skipifsilent + +[Registry] +Root: HKCR; Subkey: .osz; ValueType: string; ValueName: ; ValueData: OpenLP; Flags: uninsdeletevalue +Root: HKCR; Subkey: OpenLP; ValueType: string; ValueName: ; ValueData: OpenLP Service; Flags: uninsdeletekey +Root: HKCR; Subkey: OpenLP\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\OpenLP.exe,0 +Root: HKCR; Subkey: OpenLP\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\OpenLP.exe"" ""%1""" + +[UninstallDelete] +; Remove support directory created when program is run: +Type: filesandordirs; Name: {app}\support +; Remove program directory if empty: +Name: {app}; Type: dirifempty + +[Code] +// Function to call psvince.dll at install time +function IsModuleLoadedInstall(modulename: AnsiString ): Boolean; +external 'IsModuleLoaded@files:psvince.dll stdcall setuponly'; + +// Function to call psvince.dll at uninstall time +function IsModuleLoadedUninstall(modulename: AnsiString ): Boolean; +external 'IsModuleLoaded@{app}\psvince.dll stdcall uninstallonly' ; + +function GetUninstallString(): String; +var + sUnInstPath: String; + sUnInstallString: String; +begin + sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); + sUnInstallString := ''; + if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then + RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); + Result := sUnInstallString; +end; + +function IsUpgrade(): Boolean; +begin + Result := (GetUninstallString() <> ''); +end; + +// Return Values: +// 1 - uninstall string is empty +// 2 - error executing the UnInstallString +// 3 - successfully executed the UnInstallString +function UnInstallOldVersion(): Integer; +var + sUnInstallString: String; + iResultCode: Integer; +begin + Result := 0; + sUnInstallString := GetUninstallString(); + if sUnInstallString <> '' then + begin + sUnInstallString := RemoveQuotes(sUnInstallString); + if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then + Result := 3 + else + Result := 2; + end + else + Result := 1; +end; + +function InitializeSetup(): Boolean; +begin + Result := true; + while IsModuleLoadedInstall( 'OpenLP.exe' ) and Result do + begin + if MsgBox( 'Openlp is currently running, please close it to continue the install.', + mbError, MB_OKCANCEL ) = IDCANCEL then + begin + Result := false; + end; + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if (CurStep=ssInstall) then + begin + if (IsUpgrade()) then + begin + UnInstallOldVersion(); + end; + end; +end; + +function InitializeUninstall(): Boolean; +begin + Result := true; + while IsModuleLoadedUninstall( 'OpenLP.exe' ) and Result do + begin + if MsgBox( 'Openlp is currently running, please close it to continue the uninstall.', + mbError, MB_OKCANCEL ) = IDCANCEL then + begin + Result := false; + end; + end; +// Unload psvince.dll, otherwise it is not deleted + UnloadDLL(ExpandConstant('{app}\psvince.dll')); +end; diff --git a/windows/OpenLP.ico b/windows/OpenLP.ico new file mode 100644 index 0000000..b275542 Binary files /dev/null and b/windows/OpenLP.ico differ diff --git a/windows/OpenLP.reg b/windows/OpenLP.reg new file mode 100644 index 0000000..0ceee96 Binary files /dev/null and b/windows/OpenLP.reg differ diff --git a/windows/OpenLPPortableLauncher.ini b/windows/OpenLPPortableLauncher.ini new file mode 100644 index 0000000..430fc22 --- /dev/null +++ b/windows/OpenLPPortableLauncher.ini @@ -0,0 +1,10 @@ +[Launch] +ProgramExecutable=OpenLP\OpenLP.exe +CommandLineArguments="-p" +WaitForProgram=False +WorkingDirectory=%PAL:AppDir%\AppName +SinglePortableAppInstance=True +DirectoryMoveOK=Yes + +[Environment] +PATH=%PATH%;%PAL:Drive%\VLCPortable\App\vlc diff --git a/windows/WizImageBig.bmp b/windows/WizImageBig.bmp new file mode 100644 index 0000000..32b2ca0 Binary files /dev/null and b/windows/WizImageBig.bmp differ diff --git a/windows/WizImageSmall.bmp b/windows/WizImageSmall.bmp new file mode 100644 index 0000000..58c716f Binary files /dev/null and b/windows/WizImageSmall.bmp differ diff --git a/windows/appinfo.ini.default b/windows/appinfo.ini.default new file mode 100644 index 0000000..3abf098 --- /dev/null +++ b/windows/appinfo.ini.default @@ -0,0 +1,26 @@ +[Format] +Type=PortableApps.comFormat +Version=3.0 + +[Details] +Name=OpenLP Portable +AppID=OpenLPPortable +Publisher=OpenLP.org +Homepage=openlp.org +Category=Utilities +Description=Lyrics Projection +Language=Multilingual + +[License] +Shareable=true +OpenSource=true +Freeware=true +CommercialUse=true + +[Version] +DisplayVersion=%(version)s +PackageVersion=%(version)s + +[Control] +Icons=1 +Start=OpenLPPortable.exe diff --git a/windows/config.ini.default b/windows/config.ini.default new file mode 100644 index 0000000..f580aaf --- /dev/null +++ b/windows/config.ini.default @@ -0,0 +1,21 @@ +[executables] +innosetup = %(progfiles)s\Inno Setup 5\ISCC.exe +sphinx = %(pyroot)s\Scripts\sphinx-build.exe +pyinstaller = %(here)s\..\pyinstaller\pyinstaller.py +vcbuild = %(progfiles)s\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe +htmlhelp = %(progfiles)s\HTML Help Workshop\hhc.exe +psvince = %(here)s\psvince.dll +lrelease = %(sitepackages)s\PyQt4\bin\lrelease.exe +portablelauncher = %(progfiles)s\PortableApps.comLauncher\PortableApps.comLauncherGenerator.exe +portableinstaller = %(progfiles)s\PortableApps.comInstaller\PortableApps.comInstaller.exe + +[paths] +branch = %(projects)s\trunk +documentation = %(projects)s\documentation +win32icon = %(here)s\OpenLP.ico +hooks = %(here)s +portable = %(projects)s\OpenLPPortable + +[transifex] +username = +password = diff --git a/windows/help.html b/windows/help.html new file mode 100644 index 0000000..59d2fb2 --- /dev/null +++ b/windows/help.html @@ -0,0 +1,20 @@ + + + OpenLP Help + + +

OpenLP Help

+ +

You can access help from within OpenLP by navigating to Help -> User Guide

+ +

Also, the following Help options are available:

+ +
    +
  • OpenLP.org - Visit the Main website for OpenLP.
  • +
  • Online Help - Visit the online manual for OpenLP. (Most up-to-date documentation, internet connection required.)
  • +
  • Local OpenLP Help - Use the local help files (no internet connection required.)
  • + +
+ + + diff --git a/windows/openlp-logo-16x16.png b/windows/openlp-logo-16x16.png new file mode 100644 index 0000000..41a14c6 Binary files /dev/null and b/windows/openlp-logo-16x16.png differ diff --git a/windows/openlp-logo-32x32.png b/windows/openlp-logo-32x32.png new file mode 100644 index 0000000..ca128af Binary files /dev/null and b/windows/openlp-logo-32x32.png differ diff --git a/windows/openlp.conf b/windows/openlp.conf new file mode 100644 index 0000000..aab3b22 --- /dev/null +++ b/windows/openlp.conf @@ -0,0 +1,26 @@ +[bibles] +status = 1 + +[media] +status = 1 + +[alerts] +status = 1 + +[presentations] +status = 1 + +[custom] +status = 1 + +[remotes] +status = 0 + +[images] +status = 1 + +[songusage] +status = 1 + +[songs] +status = 1 diff --git a/windows/psvince.dll b/windows/psvince.dll new file mode 100644 index 0000000..e910509 Binary files /dev/null and b/windows/psvince.dll differ diff --git a/windows/windows-builder.py b/windows/windows-builder.py new file mode 100644 index 0000000..612c269 --- /dev/null +++ b/windows/windows-builder.py @@ -0,0 +1,686 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # +# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # +# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode # +# Woldsund # +# --------------------------------------------------------------------------- # +# 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; version 2 of the License. # +# # +# 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., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +""" +Windows Build Script +-------------------- + +This script is used to build the Windows binary and the accompanying installer. +For this script to work out of the box, it depends on a number of things: + +Python 2.6/2.7 + +PyQt4 + You should already have this installed, OpenLP doesn't work without it. The + version the script expects is the packaged one available from River Bank + Computing. + +PyEnchant + This script expects the precompiled, installable version of PyEnchant to be + installed. You can find this on the PyEnchant site. + +Inno Setup 5 + Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5" + +Sphinx + This is used to build the documentation. The documentation trunk must be at + the same directory level as OpenLP trunk and named "documentation". + +HTML Help Workshop + This is used to create the help file. + +PyInstaller + PyInstaller should be a checkout of revision 1470 of trunk, and in a + directory called, "pyinstaller" on the same level as OpenLP's Bazaar shared + repository directory. The revision is very important as there is currently + a major regression in HEAD. + + To install PyInstaller, first checkout trunk from Subversion. The easiest + way is to install TortoiseSVN and then checkout the following URL to a + directory called "pyinstaller":: + + http://svn.pyinstaller.org/trunk + +Bazaar + You need the command line "bzr" client installed. + +OpenLP + A checkout of the latest code, in a branch directory, which is in a Bazaar + shared repository directory. This means your code should be in a directory + structure like this: "openlp\branch-name". + +Visual C++ 2008 Express Edition + This is to build pptviewlib.dll, the library for controlling the + PowerPointViewer. + +windows-builder.py + This script, of course. It should be in the "windows-installer" directory + at the same level as OpenLP trunk. + +psvince.dll + This dll is used during the actual install of OpenLP to check if OpenLP is + running on the users machine prior to the setup. If OpenLP is running, + the install will fail. The dll can be obtained from here: + + http://www.vincenzo.net/isxkb/index.php?title=PSVince) + + The dll is presently included with this script. + +Mako + Mako Templates for Python. This package is required for building the + remote plugin. It can be installed by going to your + python_directory\scripts\.. and running "easy_install Mako". If you do not + have easy_install, the Mako package can be obtained here: + + http://www.makotemplates.org/download.html + +SQLAlchemy Migrate + Required for the databases used in OpenLP. The package can be + obtained here: + + http://code.google.com/p/sqlalchemy-migrate/ + +Portable App Builds + The following are required if you are planning to make a portable build of + OpenLP. The portable build conforms to the standards published by + PortableApps.com: + + http://portableapps.com/development/portableapps.com_format + + PortableApps.com Installer: + + http://portableapps.com/apps/development/portableapps.com_installer + + PortableApps.com Launcher: + + http://portableapps.com/apps/development/portableapps.com_launcher + + NSIS Portable (Unicode version): + + http://portableapps.com/apps/development/nsis_portable +""" + +import os +import sys +from shutil import copy, rmtree, copytree +from subprocess import Popen, PIPE +from ConfigParser import SafeConfigParser as ConfigParser +from argparse import ArgumentParser + + +class WindowsBuilder(object): + """ + The :class:`WindowsBuilder` class encapsulates everything that is needed + to build a Windows installer. + """ + def __init__(self): + self.setup_args() + self.setup_system_paths() + self.read_config() + self.setup_executables() + self.setup_paths() + self.version = u'' + + def _print(self, text, *args): + """ + Print stuff out. Later we might want to use a log file. + """ + if len(args) > 0: + text = text % tuple(args) + print text + + def _print_verbose(self, text, *args): + """ + Print output, obeying "verbose" mode. + """ + if self.args.verbose: + self._print(text, *args) + + def setup_args(self): + """ + Set up an argument parser and parse the command line arguments. + """ + parser = ArgumentParser() + parser.add_argument('-b', '--branch', metavar='BRANCH', dest='branch', + help='Specify the path to the branch you wish to build.', + default='../trunk') + parser.add_argument('-d', '--documentation', metavar='DOCS', + dest='docs', default=os.path.join('..', 'documentation'), + help='Specify the path to the documentation branch.') + parser.add_argument('-c', '--config', metavar='CONFIG', dest='config', + help='Specify the path to the configuration file.', + default=os.path.abspath(os.path.join('.', 'config.ini'))) + parser.add_argument('-u', '--skip-update', dest='skip_update', + action='store_true', default=False, + help='Do NOT update the branch before building.') + parser.add_argument('-p', '--portable', metavar='PORTABLE', + dest='portable', default=None, + help='Specify the path to build the portable installation.') + parser.add_argument('-t', '--skip-translations', + dest='skip_translations', action='store_true', default=False, + help='Do NOT update the language translation files.') + parser.add_argument('-v', '--verbose', dest='verbose', + action='store_true', default=False, + help='Print out additional information.') + self.args = parser.parse_args() + + def read_config(self): + """ + Read the configuration from the configuration file. + """ + self.config = ConfigParser(defaults={ + u'pyroot': self.python_root, + u'progfiles': self.program_files, + u'sitepackages': self.site_packages, + u'here': self.script_path + }) + self.config.read(os.path.abspath(self.args.config)) + + def setup_system_paths(self): + """ + Set up some system paths. + """ + self.script_path = os.path.split(os.path.abspath(__file__))[0] + self.python = sys.executable + self.python_root = os.path.split(self.python)[0] + self.site_packages = os.path.join(self.python_root, + u'Lib', u'site-packages') + self.program_files = os.getenv(u'PROGRAMFILES') + + def setup_executables(self): + """ + Set up the paths to the executables we use. + """ + self.innosetup = os.path.abspath( + self.config.get(u'executables', u'innosetup')) + self.sphinx = os.path.abspath( + self.config.get(u'executables', u'sphinx')) + self.pyinstaller = os.path.abspath( + self.config.get(u'executables', u'pyinstaller')) + self.vcbuild = os.path.abspath( + self.config.get(u'executables', u'vcbuild')) + self.hhc = os.path.abspath( + self.config.get(u'executables', u'htmlhelp')) + self.psvince = os.path.abspath( + self.config.get(u'executables', u'psvince')) + self.portableinstaller = os.path.abspath( + self.config.get(u'executables', u'portableinstaller')) + self.portablelauncher = os.path.abspath( + self.config.get(u'executables', u'portablelauncher')) + if os.path.exists(os.path.join(self.site_packages, u'PyQt4', u'bin')): + # Older versions of the PyQt4 Windows installer put their binaries + # in the "bin" directory + self.lrelease = os.path.join(self.site_packages, u'PyQt4', + u'bin', u'lrelease.exe') + else: + # Newer versions of the PyQt4 Windows installer put their binaries + # in the base directory of the installation + self.lrelease = os.path.join(self.site_packages, u'PyQt4', + u'lrelease.exe') + + def setup_paths(self): + """ + Set up a variety of paths that we use throughout the build process. + """ + if self.args.branch: + branch_path = self.args.branch + else: + branch_path = self.config.get(u'paths', u'branch') + self.branch_path = os.path.abspath(branch_path) + if self.args.docs: + docs_path = self.args.docs + else: + docs_path = self.config.get(u'paths', u'documentation') + self.docs_path = os.path.abspath(docs_path) + if self.args.portable: + portable_path = self.args.portable + else: + try: + portable_path = self.config.get(u'paths', u'portable') + except: + portable_path = u'' + if portable_path: + self.portable_path = os.path.abspath(portable_path) + self.args.portable = self.portable_path + else: + self.portable_path = u'' + self.openlp_script = os.path.abspath( + os.path.join(branch_path, u'openlp.pyw')) + self.hooks_path = os.path.abspath(self.config.get(u'paths', u'hooks')) + self.win32_icon = os.path.abspath( + self.config.get(u'paths', u'win32icon')) + self.i18n_utils = os.path.join(self.branch_path, u'scripts', + u'translation_utils.py') + self.source_path = os.path.join(self.branch_path, u'openlp') + self.manual_path = os.path.join(self.docs_path, u'manual') + self.manual_build_path = os.path.join(self.manual_path, u'build') + self.helpfile_path = os.path.join(self.manual_build_path, u'htmlhelp') + self.i18n_path = os.path.join(self.branch_path, u'resources', u'i18n') + self.winres_path = os.path.join(self.branch_path, u'resources', + u'windows') + self.build_path = os.path.join(self.branch_path, u'build') + self.dist_path = os.path.join(self.branch_path, u'dist', u'OpenLP') + self.pptviewlib_path = os.path.join(self.source_path, u'plugins', + u'presentations', u'lib', u'pptviewlib') + + def update_code(self): + """ + Update the code in the branch. + """ + os.chdir(self.branch_path) + self._print(u'Reverting any changes to the code...') + bzr = Popen((u'bzr', u'revert'), stdout=PIPE) + output = bzr.communicate()[0] + code = bzr.wait() + if code != 0: + self._print(output) + raise Exception(u'Error reverting the code') + self._print(u'Updating the code...') + bzr = Popen((u'bzr', u'update'), stdout=PIPE) + output = bzr.communicate()[0] + code = bzr.wait() + if code != 0: + self._print(output) + raise Exception(u'Error updating the code') + + def run_pyinstaller(self): + """ + Run PyInstaller on the branch to build an executable. + """ + self._print(u'Running PyInstaller...') + os.chdir(self.branch_path) + pyinstaller = Popen((self.python, self.pyinstaller, + u'--noconfirm', + u'--windowed', + u'--noupx', + u'--additional-hooks-dir', self.hooks_path, + u'--log-level=ERROR', + u'-o', self.branch_path, + u'-i', self.win32_icon, + u'-p', self.branch_path, + u'-n', u'OpenLP', + self.openlp_script), + stdout=PIPE) + output = pyinstaller.communicate()[0] + code = pyinstaller.wait() + if code != 0: + self._print(output) + raise Exception(u'Error running PyInstaller') + + def write_version_file(self): + """ + Write the version number to a file for reading once installed. + """ + self._print(u'Writing version file...') + os.chdir(self.branch_path) + bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE) + output = bzr.communicate()[0] + code = bzr.wait() + if code != 0: + raise Exception(u'Error running bzr tags') + lines = output.splitlines() + if len(lines) == 0: + tag = u'0.0.0' + revision = u'0' + else: + tag, revision = lines[-1].split() + bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'), stdout=PIPE) + output, error = bzr.communicate() + code = bzr.wait() + if code != 0: + raise Exception(u'Error running bzr log') + output_ascii = unicode(output, errors=u'ignore') + latest = output_ascii.split(u':')[0] + version_string = latest == revision and tag or \ + u'%s-bzr%s' % (tag, latest) + # Save decimal version in case we need to do a portable build. + self.version = latest == revision and tag or\ + u'%s.%s' % (tag, latest) + version_file = open(os.path.join(self.dist_path, u'.version'), u'w') + version_file.write(version_string) + version_file.close() + + def copy_plugins(self): + """ + Copy all the plugins to the correct directory so that OpenLP sees that + it has plugins. + """ + self._print(u'Copying plugins...') + source = os.path.join(self.source_path, u'plugins') + dest = os.path.join(self.dist_path, u'plugins') + for root, dirs, files in os.walk(source): + for filename in files: + if not filename.endswith(u'.pyc'): + dest_path = os.path.join(dest, root[len(source)+1:]) + if not os.path.exists(dest_path): + os.makedirs(dest_path) + self._print_verbose(u'... %s', filename) + copy(os.path.join(root, filename), + os.path.join(dest_path, filename)) + + def copy_media_player(self): + """ + Copy the media players to the correct directory for OpenLP. + """ + self._print(u'Copying media player...') + source = os.path.join(self.source_path, u'core', u'ui', u'media') + dest = os.path.join(self.dist_path, u'core', u'ui', u'media') + for root, dirs, files in os.walk(source): + for filename in files: + if not filename.endswith(u'.pyc'): + dest_path = os.path.join(dest, root[len(source)+1:]) + if not os.path.exists(dest_path): + os.makedirs(dest_path) + self._print_verbose(u'... %s', filename) + copy(os.path.join(root, filename), + os.path.join(dest_path, filename)) + + def copy_windows_files(self): + """ + Copy all the Windows-specific files. + """ + self._print(u'Copying extra files for Windows...') + self._print_verbose(u'... OpenLP.ico') + copy(os.path.join(self.script_path, u'OpenLP.ico'), + os.path.join(self.dist_path, u'OpenLP.ico')) + self._print_verbose(u'... LICENSE.txt') + copy(os.path.join(self.script_path, u'LICENSE.txt'), + os.path.join(self.dist_path, u'LICENSE.txt')) + self._print_verbose(u'... psvince.dll') + copy(self.psvince, os.path.join(self.dist_path, u'psvince.dll')) + if os.path.isfile(os.path.join(self.helpfile_path, u'OpenLP.chm')): + self._print_verbose(u'... OpenLP.chm') + copy(os.path.join(self.helpfile_path, u'OpenLP.chm'), + os.path.join(self.dist_path, u'OpenLP.chm')) + else: + self._print(u'... WARNING: Windows help file not found') + + def update_translations(self): + """ + Update the translations. + """ + self._print(u'Updating translations...') + if not self.config.has_section('transifex'): + raise Exception(u'No section named "transifex" found.') + if not self.config.has_option('transifex', 'username'): + raise Exception(u'No option named "username" found.') + if not self.config.has_option('transifex', 'password'): + raise Exception(u'No option named "password" found.') + username = self.config.get(u'transifex', u'username') + password = self.config.get(u'transifex', u'password') + os.chdir(os.path.split(self.i18n_utils)[0]) + translation_utils = Popen([self.python, self.i18n_utils, u'-qdpu', + u'-U', username, u'-P', password]) + code = translation_utils.wait() + if code != 0: + raise Exception(u'Error running translation_utils.py') + + def compile_translations(self): + """ + Compile the translations for Qt. + """ + self._print(u'Compiling translations...') + files = os.listdir(self.i18n_path) + if not os.path.exists(os.path.join(self.dist_path, u'i18n')): + os.makedirs(os.path.join(self.dist_path, u'i18n')) + for file in files: + if file.endswith(u'.ts'): + self._print_verbose(u'... %s', file) + source_path = os.path.join(self.i18n_path, file) + dest_path = os.path.join(self.dist_path, u'i18n', + file.replace(u'.ts', u'.qm')) + lconvert = Popen((self.lrelease, u'-compress', u'-silent', + source_path, u'-qm', dest_path)) + code = lconvert.wait() + if code != 0: + raise Exception(u'Error running lconvert on %s' % \ + source_path) + self._print(u'Copying qm files...') + source = os.path.join(self.site_packages, u'PyQt4', u'translations') + files = os.listdir(source) + for filename in files: + if filename.startswith(u'qt_') and filename.endswith(u'.qm') and \ + len(filename) == 8: + self._print_verbose(u'... %s', filename) + copy(os.path.join(source, filename), + os.path.join(self.dist_path, u'i18n', filename)) + + def run_sphinx(self): + """ + Run Sphinx to build an HTML Help project. + """ + self._print(u'Deleting previous help manual build... %s', + self.manual_build_path) + if os.path.exists(self.manual_build_path): + rmtree(self.manual_build_path) + self._print(u'Running Sphinx...') + os.chdir(self.manual_path) + sphinx = Popen((self.sphinx, u'-b', u'htmlhelp', u'-d', + u'build/doctrees', u'source', u'build/htmlhelp'), stdout=PIPE) + output, error = sphinx.communicate() + code = sphinx.wait() + if code != 0: + self._print(output) + raise Exception(u'Error running Sphinx') + + def run_htmlhelp(self): + """ + Run HTML Help Workshop to convert the Sphinx output into a manual. + """ + self._print(u'Running HTML Help Workshop...') + os.chdir(os.path.join(self.manual_build_path, u'htmlhelp')) + hhc = Popen((self.hhc, u'OpenLP.chm'), stdout=PIPE) + output, error = hhc.communicate() + code = hhc.wait() + if code != 1: + self._print(u'Exit code:', code) + self._print(output) + raise Exception(u'Error running HTML Help Workshop') + + def create_innosetup_file(self): + """ + Create an InnoSetup file pointing to the branch being built. + """ + self._print(u'Creating Inno Setup file...') + input = open(os.path.join(self.script_path, + u'OpenLP-2.0.iss.default'), u'r').read() + output = input.replace(u'%(branch)s', self.branch_path) + outfile = open(os.path.join(self.script_path, + u'OpenLP-2.0.iss'), u'w') + outfile.write(output) + outfile.close() + + def check_portableapp_directory(self): + """ + Checks the PortableApp directory structure amd creates + missing subdirs + """ + self._print(u' Checking PortableApps directory structure...') + launcher_path = os.path.join(self.portable_path, u'App', + u'Appinfo', u'Launcher') + if not os.path.exists(launcher_path): + os.makedirs(launcher_path) + settings_path = os.path.join(self.portable_path, u'Data', + u'Settings') + if not os.path.exists(settings_path): + os.makedirs(settings_path) + + def create_portableapps_appinfo_file(self): + """ + Create a Portabbleapps appinfo.ini file. + """ + self._print(u' Creating PortableApps appinfo file ...') + input = open(os.path.join(self.script_path, + u'appinfo.ini.default'), u'r').read() + output = input.replace(u'%(version)s', self.version) + outfile = open(os.path.join(self.portable_path, u'App', + u'Appinfo', u'appinfo.ini'), u'w') + outfile.write(output) + outfile.close() + + def run_innosetup(self): + """ + Run InnoSetup to create an installer. + """ + self._print(u'Running Inno Setup...') + os.chdir(self.script_path) + innosetup = Popen((self.innosetup, + os.path.join(self.script_path, u'OpenLP-2.0.iss'), u'/q')) + code = innosetup.wait() + if code != 0: + raise Exception(u'Error running Inno Setup') + + def run_portableapp_builder(self): + """ + Creates a portable installer. + 1 Copies the distribution to the portable apps directory + 2 Builds the PortableApps Launcher + 3 Builds the PortableApps Install + """ + self._print(u'Running PortableApps Builder...') + self.check_portableapp_directory() + self.create_portableapps_appinfo_file() + self._print(u' Copying distribution files') + portable_app_path = os.path.join(self.portable_path, u'App', u'OpenLP') + # Copy distribution files to portableapp build directory. + if os.path.exists(portable_app_path): + rmtree(portable_app_path) + copytree(self.dist_path, portable_app_path) + # Copy help files to portableapp build directory. + self._print(u' Copying help files') + copytree(self.helpfile_path, + os.path.join(portable_app_path, u'help')) + # Copy the icons. + copy(os.path.join(self.script_path, u'OpenLP.ico'), + os.path.join(self.portable_path, u'App', + u'Appinfo', u'appicon.ico')) + copy(os.path.join(self.script_path, u'openlp-logo-16x16.png'), + os.path.join(self.portable_path, u'App', + u'Appinfo', u'appicon_16.png')) + copy(os.path.join(self.script_path, u'openlp-logo-32x32.png'), + os.path.join(self.portable_path, u'App', + u'Appinfo', u'appicon_32.png')) + # Copy the launcher config ini file + launcher_path = os.path.join(self.portable_path, u'App', + u'Appinfo', u'Launcher') + if not os.path.exists(launcher_path): + os.mkdir(launcher_path) + copy(os.path.join(self.script_path, u'OpenLPPortableLauncher.ini'), + os.path.join(launcher_path, u'OpenLPPortable.ini')) + # Copy the help.html file + copy(os.path.join(self.script_path, u'help.html'),self.portable_path) + # Build the launcher. + self._print(u' Building PortableApps Launcher') + portableapps = Popen((self.portablelauncher, self.portable_path), + stdout=PIPE) + code = portableapps.wait() + if code != 0: + raise Exception(u'Error creating PortableAppa Launcher') + # Build the portable installer. + self._print(u' Building PortableApps Installer') + portableapps = Popen((self.portableinstaller, self.portable_path), + stdout=PIPE) + code = portableapps.wait() + if code != 0: + raise Exception(u'Error running PortableApps Installer') + portable_app = os.path.abspath(os.path.join(self.portable_path, u'..', + u'OpenLPPortable_%s.paf.exe' % self.version)) + if os.path.exists(portable_app): + copy(portable_app, os.path.abspath( + os.path.join(self.dist_path, u'..'))) + self._print(u' PortableApp build complete') + else: + raise Exception(u'PortableApp failed to build') + + def build_pptviewlib(self): + """ + Build the PowerPoint Viewer DLL using Visual Studio. + """ + self._print(u'Building PPTVIEWLIB.DLL...') + vcbuild = Popen((self.vcbuild, u'/rebuild', + os.path.join(self.pptviewlib_path, u'pptviewlib.vcproj'), + u'Release|Win32')) + code = vcbuild.wait() + if code != 0: + raise Exception(u'Error building pptviewlib.dll') + copy(os.path.join(self.pptviewlib_path, u'Release', + u'pptviewlib.dll'), self.pptviewlib_path) + + def main(self): + """ + The main function to run the Windows builder. + """ + self._print_verbose(u'OpenLP main script: ......%s', + self.openlp_script) + self._print_verbose(u'Script path: .............%s', + os.path.split(os.path.abspath(__file__))[0]) + self._print_verbose(u'Branch path: .............%s', self.branch_path) + self._print_verbose(u'Source path: .............%s', self.source_path) + self._print_verbose(u'Dist path: ...............%s', self.dist_path) + self._print_verbose(u'Portable path: ...........%s', + self.portable_path) + self._print_verbose(u'PyInstaller: .............%s', self.pyinstaller) + self._print_verbose(u'Documentation branch path:%s', self.docs_path) + self._print_verbose(u'Help file build path: ....%s', + self.helpfile_path) + self._print_verbose(u'Inno Setup path: .........%s', self.innosetup) + self._print_verbose(u'PortableApp Launcher......%s', + self.portablelauncher) + self._print_verbose(u'PortableApp Installer.....%s', + self.portableinstaller) + self._print_verbose(u'Windows resources: .......%s', self.winres_path) + self._print_verbose(u'VCBuild path: ............%s', self.vcbuild) + self._print_verbose(u'PPTVIEWLIB path: .........%s', + self.pptviewlib_path) + self._print_verbose(u'') + if not self.args.skip_update: + self.update_code() + self.build_pptviewlib() + self.run_pyinstaller() + self.write_version_file() + self.copy_plugins() + self.copy_media_player() + if os.path.exists(self.manual_path): + self.run_sphinx() + self.run_htmlhelp() + else: + self._print(u'') + self._print(u'WARNING: Documentation trunk not found. Windows') + self._print(u' Help file will not be included in build') + self._print(u'') + self.copy_windows_files() + if not self.args.skip_translations: + self.update_translations() + self.compile_translations() + self.create_innosetup_file() + self.run_innosetup() + if self.args.portable: + self.run_portableapp_builder() + self._print(u'Done.') + +if __name__ == u'__main__': + WindowsBuilder().main()