← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2244: translatable installer and build script updates (scons distro=1)

 

------------------------------------------------------------
revno: 2244
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Tue 2010-09-21 22:28:03 +0200
message:
  translatable installer and build script updates (scons distro=1)
removed:
  release.sh
  tag.sh
added:
  installer/SConscript
  installer/Strings.xml
  installer/po/
  installer/po/dcpp-installer.pot
modified:
  Compile.txt
  SConstruct
  build_util.py
  changelog.txt
  help/SConscript
  help/util.py
  installer/DCPlusPlus.nsi
  update-languages.sh


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'Compile.txt'
--- Compile.txt	2010-09-14 20:38:28 +0000
+++ Compile.txt	2010-09-21 20:28:03 +0000
@@ -17,7 +17,7 @@
 		Note: SCons relies on Python so you need to have Python installed first.
 		Make sure that SCons is in your PATH environment variable.
 
-		* Perl - 5.12.0.1 (ActivePerl or Cygwin, only needed to build help files)
+		* Perl - 5.12.0.1 (from MSYS, Cygwin or ActivePerl; only needed to build help files)
 		<http://www.perl.org/get.html>
 
 		Make sure that Perl is in your PATH environment variable.
@@ -32,7 +32,7 @@
 
 		Go to your HTML Help Workshop include directory (HTML Help Workshop/include) and copy
 		htmlhelp.h to the htmlhelp/include directory of the DC++ source.
-		Go to your HTML Help Workshop lib directory (HTML Help Workshop\lib) and copy htmlhelp.lib
+		Go to your HTML Help Workshop lib directory (HTML Help Workshop/lib) and copy htmlhelp.lib
 		to the htmlhelp/lib directory of the DC++ source.
 		Make sure that hhc.exe is in your PATH environment variable.
 
@@ -41,6 +41,16 @@
 
 		Make sure that asciidoc is in your PATH environment variable.
 
+		* Unicode NSIS (only needed to build the installer)
+		<http://code.google.com/p/unsis/>
+
+		Make sure that makensis.exe is in your PATH environment variable.
+		Make sure that you are using the Unicode version of the installer builder.
+
+		* zip (from MSYS or Cygwin; only needed to build the official distro)
+
+		Make sure that zip is in your PATH environment variable.
+
 
 2. Compiler
 

=== modified file 'SConstruct'
--- SConstruct	2010-09-14 16:15:35 +0000
+++ SConstruct	2010-09-21 20:28:03 +0000
@@ -77,16 +77,26 @@
 	BoolVariable('savetemps', 'Save intermediate compilation files (assembly output)', 'no'),
 	BoolVariable('unicode', 'Build a Unicode version which fully supports international characters', 'yes'),
 	BoolVariable('i18n', 'Rebuild i18n files in debug build', 'no'),
-	BoolVariable('help', 'Build help files (requires i18n=1 or mode=release)', 'yes'),
+	BoolVariable('help', 'Build help files (requires i18n=1)', 'yes'),
+	BoolVariable('webhelp', 'Build help files for the web (requires help=1)', 'no'),
 	BoolVariable('test', 'Build test suite', 'no'),
-	BoolVariable('webhelp', 'Build help files for the web (requires help=1)', 'no'),
 	('prefix', 'Prefix to use when cross compiling', ''),
-	EnumVariable('arch', 'Target architecture', 'x86', ['x86', 'x64', 'ia64'])
+	EnumVariable('arch', 'Target architecture', 'x86', ['x86', 'x64', 'ia64']),
+	BoolVariable('distro', 'Produce the official distro (forces tools=mingw, mode=release, unicode=1, i18n=1, help=1, webhelp=1, arch=x86)', 'no')
 )
 
 opts.Update(defEnv)
 Help(opts.GenerateHelpText(defEnv))
 
+if defEnv['distro']:
+	defEnv['tools'] = 'mingw'
+	defEnv['mode'] = 'release'
+	defEnv['unicode'] = 1
+	defEnv['i18n'] = 1
+	defEnv['help'] = 1
+	defEnv['webhelp'] = 1
+	defEnv['arch'] = 'x86'
+
 # workaround for SCons 1.2 which hard-codes possible archs (only allows 'x86' and 'amd64'...)
 # TODO remove when SCons knows about all available archs
 TARGET_ARCH = defEnv['arch']
@@ -96,13 +106,16 @@
 env = Environment(ENV = os.environ, tools = [defEnv['tools']], options = opts, TARGET_ARCH = TARGET_ARCH, MSVS_ARCH = TARGET_ARCH)
 
 if 'mingw' not in env['TOOLS'] and 'gcc' in env['TOOLS']:
-	print "Non-mingw gcc builds not supported"
-	Exit(1)
+	raise Exception('Non-mingw gcc builds not supported')
 
-mode = env['mode']
-if mode not in gcc_flags:
-	print "Unknown mode, exiting"
-	Exit(1)
+if env['distro']:
+	env['tools'] = 'mingw'
+	env['mode'] = 'release'
+	env['unicode'] = 1
+	env['i18n'] = 1
+	env['help'] = 1
+	env['webhelp'] = 1
+	env['arch'] = 'x86'
 
 # filter out boost from dependencies to get a speedier rebuild scan
 # this means that if boost changes, scons -c needs to be run
@@ -115,7 +128,7 @@
 SourceFileScanner.function['.h'].recurse_nodes = filterBoost
 SourceFileScanner.function['.hpp'].recurse_nodes = filterBoost
 
-dev = Dev(mode, env['tools'], env)
+dev = Dev(env)
 dev.prepare()
 
 env.SConsignFile()
@@ -153,16 +166,16 @@
 
 	env.Tool("gch", toolpath=".")
 
-env.Append(CPPDEFINES = defs[mode])
+env.Append(CPPDEFINES = defs[env['mode']])
 env.Append(CPPDEFINES = defs['common'])
 
-env.Append(CCFLAGS = flags[mode])
+env.Append(CCFLAGS = flags[env['mode']])
 env.Append(CCFLAGS = flags['common'])
 
-env.Append(CXXFLAGS = xxflags[mode])
+env.Append(CXXFLAGS = xxflags[env['mode']])
 env.Append(CXXFLAGS = xxflags['common'])
 
-env.Append(LINKFLAGS = link_flags[mode])
+env.Append(LINKFLAGS = link_flags[env['mode']])
 env.Append(LINKFLAGS = link_flags['common'])
 
 env.SourceCode('.', None)
@@ -209,4 +222,4 @@
 	dev.test = dev.build('test/')
 else:
 	dev.win32 = dev.build('win32/')
-	
+dev.installer = dev.build('installer/')

=== modified file 'build_util.py'
--- build_util.py	2010-09-14 20:38:28 +0000
+++ build_util.py	2010-09-21 20:28:03 +0000
@@ -3,13 +3,10 @@
 import os
 
 class Dev:
-	def __init__(self, mode, tools, env):
-
-		self.mode = mode
-		self.tools = tools
+	def __init__(self, env):
 		self.env = env
 
-		self.build_root = '#/build/' + self.mode + '-' + self.tools
+		self.build_root = '#/build/' + env['mode'] + '-' + env['tools']
 		if env['arch'] != 'x86':
 			self.build_root += '-' + env['arch']
 		self.build_root += '/'
@@ -103,7 +100,7 @@
 		return local_env.SConscript(source_path + 'SConscript', exports={'dev' : self, 'source_path' : full_path })
 
 	def i18n (self, source_path, buildenv, sources, name):
-		if self.env['mode'] != 'release' and not self.env['i18n']:
+		if not self.env['i18n']:
 			return
 
 		p_oze = glob.glob('po/*.po')
@@ -145,15 +142,23 @@
 		return asciidoc
 
 # source is *one* SCons file node (not a list!) designating the .po file
-# env must contain 'NAME_FILE', which is a SCons file node to the target file
-def gen_po_name(source, env):
+def get_po_name(source):
 	# rely on the comments at the beginning of the po file to find the language name.
 	import codecs, re
 	match = re.compile('^# (.+) translation.*', re.I).search(codecs.open(str(source), 'rb', 'utf_8').readline())
 	if match:
 		name = match.group(1)
 		if name != "XXX":
-			codecs.open(str(env['NAME_FILE']), 'wb', 'utf_8').write(name)
+			return name
+	return None
+
+# source is *one* SCons file node (not a list!) designating the .po file
+# env must contain 'NAME_FILE', which is a SCons file node to the target file
+def gen_po_name(source, env):
+	import codecs
+	name = get_po_name(source)
+	if name:
+		codecs.open(str(env['NAME_FILE']), 'wb', 'utf_8').write(name)
 
 def CheckPKGConfig(context, version):
 	context.Message( 'Checking for pkg-config... ' )
@@ -169,3 +174,16 @@
 
 	context.Result( ret )
 	return ret
+
+def nixify(path):
+	return path.replace('\\', '/')
+
+def array_remove(array, to_remove):
+	if to_remove in array:
+		array.remove(to_remove)
+
+class scoped_cmd:
+	def __init__(self, cmd):
+		self.cmd = cmd
+	def __del__(self):
+		self.cmd()

=== modified file 'changelog.txt'
--- changelog.txt	2010-09-05 14:04:54 +0000
+++ changelog.txt	2010-09-21 20:28:03 +0000
@@ -19,6 +19,7 @@
 * Fix some counters that could have caused issues when running dc++ for a long time
 * [L#617517] More portable critical sections (thanks big muscle)
 * Removed stlport support (probably defunct by now...)
+* Modernize the installer and make it translatable (poy)
 
 -- 0.770 2010-07-05 --
 * [L#550300] Catch more potential file corruptions (thanks bigmuscle)

=== modified file 'help/SConscript'
--- help/SConscript	2010-07-01 17:43:48 +0000
+++ help/SConscript	2010-09-21 20:28:03 +0000
@@ -7,7 +7,7 @@
 env = dev.env.Clone()
 
 import os
-from util import array_remove
+from build_util import array_remove
 
 # static_HTMLs holds static (not dynamically generated) HTML sources
 static_HTMLs = Glob('*.html', strings = 1)
@@ -25,7 +25,7 @@
 if not env['help']:
 	Return()
 
-if env['mode'] != 'release' and not env['i18n']:
+if not env['i18n']:
 	Return()
 
 if env.WhereIs('perl') is None:
@@ -90,11 +90,11 @@
 # additional dependencies (that have to be built before the help file)
 CHM_dependencies = ['addendum.txt', 'cshelp.h']
 
-from build_util import gen_po_name
+from build_util import nixify, gen_po_name, scoped_cmd
 import filecmp
 from gen_toc import gen_toc
 from set_hhp_locale import set_hhp_locale
-from util import nixify, scoped_cmd, get_lcid
+from util import get_lcid
 
 po4a_path = Dir('#/po4a').abspath + '/'
 env['po4a_cmd'] = lambda prog, options: 'perl -I"' + po4a_path + 'lib" "' + po4a_path + prog + '" -f xhtml -o "translated=p<placeholder> p<placeholder><a>" -o "untranslated=<untranslated> <untranslated><a> <untranslated><li>" -o foldattributes -o "includessi=' + nixify(Dir('#/help').abspath) + '/" -M utf-8 -L utf-8 ' + options

=== modified file 'help/util.py'
--- help/util.py	2009-10-06 14:09:49 +0000
+++ help/util.py	2010-09-21 20:28:03 +0000
@@ -1,16 +1,3 @@
-def nixify(path):
-	return path.replace('\\', '/')
-
-def array_remove(array, to_remove):
-	if to_remove in array:
-		array.remove(to_remove)
-
-class scoped_cmd:
-	def __init__(self, cmd):
-		self.cmd = cmd
-	def __del__(self):
-		self.cmd()
-
 def get_lcid(lang):
 	from locale import windows_locale
 

=== modified file 'installer/DCPlusPlus.nsi'
--- installer/DCPlusPlus.nsi	2010-09-08 15:35:43 +0000
+++ installer/DCPlusPlus.nsi	2010-09-21 20:28:03 +0000
@@ -1,7 +1,20 @@
 !include "MUI2.nsh"
 !include "Sections.nsh"
 
+!ifndef NSIS_UNICODE
+	!error "An Unicode version of NSIS is required, see <http://code.google.com/p/unsis/>"
+!endif
+
 Var VERSION ; will be filled in onInit
+!macro GetDCPlusPlusVersion
+	; Get the DC++ version and store it in $VERSION
+	GetDllVersionLocal "DCPlusPlus.exe" $R0 $R1
+	IntOp $R2 $R0 / 0x00010000
+	IntOp $R3 $R0 & 0x0000FFFF
+	IntOp $R4 $R1 / 0x00010000
+	IntOp $R5 $R1 & 0x0000FFFF
+	StrCpy $VERSION "$R2.$R3$R4$R5"
+!macroend
 
 ; The name of the installer
 Name "DC++ $VERSION"
@@ -31,13 +44,13 @@
 !define MUI_UNABORTWARNING
 !define MUI_UNABORTWARNING_CANCEL_DEFAULT
 
-;!define MUI_LANGDLL_ALWAYSSHOW
-;!define MUI_LANGDLL_REGISTRY_ROOT "HKLM"
-;!define MUI_LANGDLL_REGISTRY_KEY "SOFTWARE\DC++"
-;!define MUI_LANGDLL_REGISTRY_VALUENAME "Install_Language"
-;!define MUI_LANGDLL_WINDOWTITLE "$(^NameDA) language selection"
+!define MUI_LANGDLL_ALWAYSSHOW
+!define MUI_LANGDLL_REGISTRY_ROOT "HKLM"
+!define MUI_LANGDLL_REGISTRY_KEY "SOFTWARE\DC++"
+!define MUI_LANGDLL_REGISTRY_VALUENAME "Install_Language"
+!define MUI_LANGDLL_WINDOWTITLE "$(^NameDA) language selection"
 
-!define MUI_LICENSEPAGE_TEXT_TOP "DC++ is licensed under the GPL, here is the full text."
+!define MUI_LICENSEPAGE_TEXT_TOP $(LICENSE_TOP)
 !insertmacro MUI_PAGE_LICENSE "License.txt"
 
 !define MUI_COMPONENTSPAGE_NODESC
@@ -47,23 +60,24 @@
 
 !insertmacro MUI_PAGE_INSTFILES
 
-!define MUI_UNCONFIRMPAGE_TEXT_TOP "$(^UninstallingText) Warning: the 'locale' directory ($INSTDIR\locale) will be completely erased!"
+!define MUI_UNCONFIRMPAGE_TEXT_TOP "$(^UninstallingText) $(WARNING_LOCALE_ERASED)"
 !insertmacro MUI_UNPAGE_CONFIRM
 
 !insertmacro MUI_UNPAGE_INSTFILES
 
-!insertmacro MUI_LANGUAGE "English"
-;!insertmacro MUI_LANGUAGE "French"
+; i18n.nsh should be generated by the build script to contain a list of all the languages.
+!include "i18n.nsh"
 !insertmacro MUI_RESERVEFILE_LANGDLL
 
 ; The stuff to install
-Section "DC++ (required)" dcpp
+Section $(SECTION_DCPP) dcpp
   ; Set output path to the installation directory.
   SetOutPath $INSTDIR
 
   ; Check for existing settings in the profile first
   IfFileExists "$APPDATA\DC++\*.xml" 0 check_programdir
-  MessageBox MB_YESNO|MB_ICONQUESTION "A previous installation of DC++ has been found, backup settings and queue? (You can find them in $APPDATA\DC++\BACKUP later)" IDNO no_backup
+  StrCpy $R0 "$APPDATA\DC++\BACKUP"
+  MessageBox MB_YESNO|MB_ICONQUESTION $(BACKUP_QUESTION) IDNO no_backup
   CreateDirectory "$APPDATA\DC++\BACKUP\"
   CopyFiles "$APPDATA\DC++\*.xml" "$APPDATA\DC++\BACKUP\"
   goto no_backup
@@ -73,7 +87,8 @@
   ; Delete a possibly existing dcppboot.xml to be able to check for existing local settings 
   Delete "$INSTDIR\dcppboot.xml"
   IfFileExists "$INSTDIR\*.xml" 0 no_backup
-  MessageBox MB_YESNO|MB_ICONQUESTION "A previous installation of DC++ has been found, backup settings and queue? (You can find them in $INSTDIR\BACKUP later)" IDNO no_backup
+  StrCpy $R0 "$INSTDIR\BACKUP"
+  MessageBox MB_YESNO|MB_ICONQUESTION $(BACKUP_QUESTION) IDNO no_backup
   CreateDirectory "$INSTDIR\BACKUP\"
   CopyFiles "$INSTDIR\*.xml" "$INSTDIR\BACKUP\"
 
@@ -113,22 +128,21 @@
   WriteUninstaller "uninstall.exe"
 SectionEnd
 
-Section "IP -> Country mappings"
+Section $(SECTION_IP_COUNTRY)
   SetOutPath $INSTDIR
   File "GeoIPCountryWhois.csv"
 SectionEnd
 
-; optional section
-Section "Start Menu Shortcuts"
+Section $(SECTION_START_MENU)
   CreateDirectory "$SMPROGRAMS\DC++"
-  CreateShortCut "$SMPROGRAMS\DC++\DC++.lnk" "$INSTDIR\DCPlusPlus.exe" "" "$INSTDIR\DCPlusPlus.exe" 0 "" "" "DC++ File Sharing Application"
-  CreateShortCut "$SMPROGRAMS\DC++\License.lnk" "$INSTDIR\License.txt"
-  CreateShortCut "$SMPROGRAMS\DC++\Help.lnk" "$INSTDIR\DCPlusPlus.chm"
-  CreateShortCut "$SMPROGRAMS\DC++\Change Log.lnk" "$INSTDIR\ChangeLog.txt"
-  CreateShortCut "$SMPROGRAMS\DC++\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
+  CreateShortCut "$SMPROGRAMS\DC++\DC++.lnk" "$INSTDIR\DCPlusPlus.exe" "" "$INSTDIR\DCPlusPlus.exe" 0 "" "" "$(SM_DCPP_DESCR)"
+  CreateShortCut "$SMPROGRAMS\DC++\$(SM_LICENSE).lnk" "$INSTDIR\License.txt"
+  CreateShortCut "$SMPROGRAMS\DC++\$(SM_HELP).lnk" "$INSTDIR\DCPlusPlus.chm"
+  CreateShortCut "$SMPROGRAMS\DC++\$(SM_CHANGELOG).lnk" "$INSTDIR\changelog.txt"
+  CreateShortCut "$SMPROGRAMS\DC++\$(SM_UNINSTALL).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
 SectionEnd
 
-Section "Store settings in your user profile directory" loc
+Section $(SECTION_LOCAL) loc
   ; Change to nonlocal dcppboot if the checkbox left checked
   SetOutPath $INSTDIR
   File /oname=dcppboot.xml "dcppboot.nonlocal.xml" 
@@ -143,7 +157,7 @@
   IntOp $0 $0 & ${SF_SELECTED}
   StrCmp $0 ${SF_SELECTED} skip
     StrCpy $R9 "1"
-    MessageBox MB_OK|MB_ICONEXCLAMATION "If you want to keep your settings in the program directory using Windows Vista or later, make sure that you DO NOT install DC++ into 'Program Files'! This can lead to abnormal behaviour like loss of settings or downloads."
+	MessageBox MB_OK|MB_ICONEXCLAMATION $(LOCAL_WARNING)
 skip:
 FunctionEnd
 
@@ -165,29 +179,17 @@
 	IntOp $0 ${SF_SELECTED} | ${SF_RO}
 	SectionSetFlags ${dcpp} $0
 
-	; Get the DC++ version and store it in $VERSION
-	GetDllVersionLocal "DCPlusPlus.exe" $R0 $R1
-	IntOp $R2 $R0 / 0x00010000
-	IntOp $R3 $R0 & 0x0000FFFF
-	IntOp $R4 $R1 / 0x00010000
-	IntOp $R5 $R1 & 0x0000FFFF
-	StrCpy $VERSION "$R2.$R3$R4$R5"
+	!insertmacro GetDCPlusPlusVersion
 
-	;!insertmacro MUI_LANGDLL_DISPLAY
+	!insertmacro MUI_LANGDLL_DISPLAY
 FunctionEnd
 
 ; uninstall stuff
 
 Function un.onInit
-	; Get the DC++ version and store it in $VERSION
-	GetDllVersionLocal "DCPlusPlus.exe" $R0 $R1
-	IntOp $R2 $R0 / 0x00010000
-	IntOp $R3 $R0 & 0x0000FFFF
-	IntOp $R4 $R1 / 0x00010000
-	IntOp $R5 $R1 & 0x0000FFFF
-	StrCpy $VERSION "$R2.$R3$R4$R5"
+	!insertmacro GetDCPlusPlusVersion
 
-	;!insertmacro MUI_UNGETLANGUAGE
+	!insertmacro MUI_UNGETLANGUAGE
 FunctionEnd
 
 ; special uninstall section.
@@ -197,15 +199,15 @@
   DeleteRegKey HKLM SOFTWARE\DC++
   ; remove files
   Delete "$INSTDIR\DCPlusPlus.exe"
+  Delete "$INSTDIR\changelog.txt"
+  Delete "$INSTDIR\cshelp.rtf"
+  Delete "$INSTDIR\dcppboot.xml"
   Delete "$INSTDIR\DCPlusPlus.chm"
-  Delete "$INSTDIR\dcppboot.xml"
-  Delete "$INSTDIR\License-GeoIP.txt"
   Delete "$INSTDIR\License.txt"
-  Delete "$INSTDIR\ChangeLog.txt"
-  Delete "$INSTDIR\cshelp.rtf"
+  Delete "$INSTDIR\LICENSE-GeoIP.txt"
   Delete "$INSTDIR\LICENSE-OpenSSL.txt"
+  Delete "$INSTDIR\mingwm10.dll"
   Delete "$INSTDIR\GeoIPCountryWhois.csv"
-  Delete "$INSTDIR\mingwm10.dll"
 
   ; Delete the whole locale directory
   RMDir /r "$INSTDIR\locale"
@@ -223,7 +225,7 @@
   ; remove directories used.
   RMDir "$SMPROGRAMS\DC++"
 
-  MessageBox MB_YESNO|MB_ICONQUESTION "Also remove queue, settings and the whole DC++ program directory ($INSTDIR) with all of its sub-directories?" IDYES kill_dir
+  MessageBox MB_YESNO|MB_ICONQUESTION $(UN_REMOVE_QUESTION) IDYES kill_dir
 
   RMDir "$INSTDIR"
   goto end_uninstall

=== added file 'installer/SConscript'
--- installer/SConscript	1970-01-01 00:00:00 +0000
+++ installer/SConscript	2010-09-21 20:28:03 +0000
@@ -0,0 +1,143 @@
+# Build the DC++ installer
+# Dependencies:
+# - Perl, in order to use po4a <http://po4a.alioth.debian.org/>
+# - Unicode NSIS <http://code.google.com/p/unsis/>
+# - zip (MSYS / Cygwin provide one)
+# - bzr (this tree must be under bzr version control)
+
+Import('dev')
+env = dev.env.Clone()
+
+if not env['i18n'] and not env['distro']:
+	Return()
+
+if env.WhereIs('perl') is None:
+	raise Exception('Perl is required to run po4a scripts, installer translation impossible')
+
+nsis = None
+if env['distro']:
+	nsis = env.WhereIs('makensis')
+	if nsis is None:
+		raise Exception('makensis.exe not found in PATH - Unicode NSIS is required to build the distro')
+	if env.WhereIs('bzr') is None:
+		raise Exception('"bzr" is required to build the distro; this tree must be under bzr version control')
+	if env.WhereIs('strip') is None:
+		raise Exception('"strip" is required to build the distro; it should be part of MinGW / binutils')
+	if env.WhereIs('zip') is None:
+		raise Exception('"zip" is required to build the distro; get the one from MSYS or Cygwin')
+
+from build_util import nixify
+import re
+
+po4a_path = Dir('#/po4a').abspath + '/'
+env['po4a_cmd'] = lambda prog, options: 'perl -I"' + po4a_path + 'lib" "' + po4a_path + prog + '" -f xml -M utf-8 -L utf-8 ' + options
+
+# create the translation template
+def gen_pot(target, source, env):
+	return env.Execute(env['po4a_cmd']('po4a-gettextize', '-o "package-name=dcpp-installer" -o "copyright-holder=Jacek Sieka" -o "msgid-bugs-address=dcplusplus-devel@xxxxxxxxxxxxxxxxxxxxx" -m "' + nixify(str(source[0])) + '" -p "' + nixify(str(target[0])) + '"'))
+potfile = File('po/dcpp-installer.pot')
+env.Command(potfile, File('Strings.xml'), Action(gen_pot, 'Extracting installer texts to $TARGET'))
+
+# update .po's in installer/po
+po_list = Glob('po/*.po')
+for po_node in po_list:
+	env.Precious(env.PoBuild(po_node, potfile))
+
+if nsis is None:
+	Return()
+
+from build_util import get_po_name, scoped_cmd
+import bzrlib
+import codecs
+import os.path
+from xml.dom.minidom import parse
+
+# gather the files necessary to create the installer
+sources = Glob('*.*')
+reg = re.compile('^\W*File.+"([^"]+)"')
+f = codecs.open('DCPlusPlus.nsi', 'rb', 'utf_8')
+for line in f:
+	match = reg.search(line)
+	if match:
+		match = match.group(1)
+		if env.FindFile(match, '#'):
+			match = '#/' + match
+		else:
+			# file not found in the root; must be a built file
+			match = dev.get_build_path('bin') + '/' + match
+		sources.append(match)
+f.close()
+sources.append(potfile)
+sources.append(po_list)
+sources.sort()
+
+def gen_installer(target, source, env):
+	# create the temporary build directory
+	build_dir = 'build/installer'
+	build_path = build_dir + '/'
+	env.Execute([Delete(build_dir), Mkdir(build_dir)])
+	dir_cleaner = scoped_cmd(lambda: env.Execute(Delete(build_dir)))
+
+	# the file, included by the installer, that lists all available translations
+	f_i18n = codecs.open(build_path + 'i18n.nsh', 'wb', 'utf_8')
+
+	# copy the source files to the build directory
+	for node in source:
+		name = os.path.basename(node.path)
+
+		if name == 'DCPlusPlus.exe':
+			env.Execute('strip "' + nixify(node.path) + '" -o "' + build_path + name + '"')
+
+		elif name[-3:] == '.po' or name[-4:] == '.pot':
+			# find the corresponding name among the NSIS language files
+			name = get_po_name(node)
+			if name is None:
+				# this must be the template (.pot)
+				name = 'English'
+			elif name == 'Norwegian Bokmal':
+				name = 'Norwegian'
+			elif name == 'Norwegian Nynorsk':
+				name = 'NorwegianNynorsk'
+			elif name == 'Brazilian Portuguese':
+				name = 'PortugueseBR'
+			elif name == 'Simplified Chinese':
+				name = 'SimpChinese'
+			if os.path.exists(os.path.dirname(nsis) + '/Contrib/Language files/' + name + '.nlf'):
+				f_i18n.write('!insertmacro MUI_LANGUAGE "' + name + '"\n!insertmacro LANGFILE_INCLUDE "_' + name + '.nsh"\n')
+				xml_file = build_path + 'Strings.xml'
+				# translate our strings
+				env.Execute(env['po4a_cmd']('po4a-translate', '-m "installer/Strings.xml" -l "' + xml_file + '" -p "' + nixify(str(node)) + '" -k 0'))
+				# parse translated strings to generate message catalogs suitable for the installer
+				f_nsh = codecs.open(build_path + '_' + name + '.nsh', 'wb', 'utf_8')
+				f_nsh.write('!insertmacro LANGFILE_EXT "' + name + '"\n')
+				dom = parse(xml_file)
+				for elem in dom.firstChild.childNodes:
+					if elem.nodeType == elem.ELEMENT_NODE:
+						f_nsh.write('${LangFileString} ' + elem.nodeName + ' "' + elem.firstChild.nodeValue + '"\n')
+				f_nsh.close()
+				dom.unlink()
+				env.Execute(Delete(xml_file))
+
+		else:
+			env.Execute(Copy(build_path + name, node))
+
+	f_i18n.close()
+
+	# create the installer
+	ret = env.Execute('makensis ' + build_path + 'DCPlusPlus.nsi')
+	if ret:
+		return ret
+	env.Execute(Move(target[0], build_path + os.path.basename(target[0].path)))
+
+	# make the zip binary archive
+	env.Execute('cd "' + build_dir + '" && zip -9 -r "' + nixify(str(target[1].abspath)) + '" . -x "dcppboot.nonlocal.xml" -x "\\*.ico" -x "\\*.nsh" -x "\\*.nsi" && cd "' + env.Dir('#').abspath + '"')
+
+	# use "bzr export" to zip the source
+	env.Execute('bzr export "' + nixify(str(target[2])) + '"')
+
+	return ret
+
+distro_path = '#/build/distro/'
+ret = env.Command([distro_path + 'DCPlusPlus-xxx.exe', distro_path + 'DCPlusPlus-xxx.zip', distro_path + 'DCPlusPlus-xxx-src.zip'], sources, Action(gen_installer, 'Creating final distro packages ($TARGETS)'))
+
+Return('ret')

=== added file 'installer/Strings.xml'
--- installer/Strings.xml	1970-01-01 00:00:00 +0000
+++ installer/Strings.xml	2010-09-21 20:28:03 +0000
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Strings>
+	<LICENSE_TOP>DC++ is licensed under the GPL, here is the full text.</LICENSE_TOP>
+	<SECTION_DCPP>DC++ (required)</SECTION_DCPP>
+	<BACKUP_QUESTION>A previous installation of DC++ has been found; backup settings and queue to '$R0'?</BACKUP_QUESTION>
+	<SECTION_IP_COUNTRY>IP -&gt; country mappings</SECTION_IP_COUNTRY>
+	<SECTION_START_MENU>Start menu shortcuts</SECTION_START_MENU>
+	<SECTION_LOCAL>Store settings in the user profile directory</SECTION_LOCAL>
+	<LOCAL_WARNING>Unchecking this box will make DC++ store its settings in the program directory. This is strongly discouraged on Windows Vista and later; settings or downloads might get lost.</LOCAL_WARNING>
+	<WARNING_LOCALE_ERASED>Warning: the 'locale' directory ($INSTDIR\locale) will be completely erased!</WARNING_LOCALE_ERASED>
+	<SM_DCPP_DESCR>DC++ (file sharing application)</SM_DCPP_DESCR>
+	<SM_LICENSE>License</SM_LICENSE>
+	<SM_HELP>Help</SM_HELP>
+	<SM_CHANGELOG>Change Log</SM_CHANGELOG>
+	<SM_UNINSTALL>Uninstall</SM_UNINSTALL>
+	<UN_REMOVE_QUESTION>Also remove queue, settings and the whole DC++ program directory ($INSTDIR) with all of its sub-directories?</UN_REMOVE_QUESTION>
+</Strings>

=== added directory 'installer/po'
=== added file 'installer/po/dcpp-installer.pot'
--- installer/po/dcpp-installer.pot	1970-01-01 00:00:00 +0000
+++ installer/po/dcpp-installer.pot	2010-09-21 20:28:03 +0000
@@ -0,0 +1,110 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR Jacek Sieka
+# This file is distributed under the same license as the dcpp-installer package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: dcpp-installer VERSION\n"
+"Report-Msgid-Bugs-To: dcplusplus-devel@xxxxxxxxxxxxxxxxxxxxx\n"
+"POT-Creation-Date: 2010-09-21 22:19+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: ENCODING"
+
+#. type: Content of: <Strings><LICENSE_TOP>
+#: installer/Strings.xml:3
+#, no-wrap
+msgid "DC++ is licensed under the GPL, here is the full text."
+msgstr ""
+
+#. type: Content of: <Strings><SECTION_DCPP>
+#: installer/Strings.xml:4
+#, no-wrap
+msgid "DC++ (required)"
+msgstr ""
+
+#. type: Content of: <Strings><BACKUP_QUESTION>
+#: installer/Strings.xml:5
+#, no-wrap
+msgid ""
+"A previous installation of DC++ has been found; backup settings and queue to "
+"'$R0'?"
+msgstr ""
+
+#. type: Content of: <Strings><SECTION_IP_COUNTRY>
+#: installer/Strings.xml:6
+#, no-wrap
+msgid "IP -&gt; country mappings"
+msgstr ""
+
+#. type: Content of: <Strings><SECTION_START_MENU>
+#: installer/Strings.xml:7
+#, no-wrap
+msgid "Start menu shortcuts"
+msgstr ""
+
+#. type: Content of: <Strings><SECTION_LOCAL>
+#: installer/Strings.xml:8
+#, no-wrap
+msgid "Store settings in the user profile directory"
+msgstr ""
+
+#. type: Content of: <Strings><LOCAL_WARNING>
+#: installer/Strings.xml:9
+#, no-wrap
+msgid ""
+"Unchecking this box will make DC++ store its settings in the program "
+"directory. This is strongly discouraged on Windows Vista and later; settings "
+"or downloads might get lost."
+msgstr ""
+
+#. type: Content of: <Strings><WARNING_LOCALE_ERASED>
+#: installer/Strings.xml:10
+#, no-wrap
+msgid ""
+"Warning: the 'locale' directory ($INSTDIR\\locale) will be completely "
+"erased!"
+msgstr ""
+
+#. type: Content of: <Strings><SM_DCPP_DESCR>
+#: installer/Strings.xml:11
+#, no-wrap
+msgid "DC++ (file sharing application)"
+msgstr ""
+
+#. type: Content of: <Strings><SM_LICENSE>
+#: installer/Strings.xml:12
+#, no-wrap
+msgid "License"
+msgstr ""
+
+#. type: Content of: <Strings><SM_HELP>
+#: installer/Strings.xml:13
+#, no-wrap
+msgid "Help"
+msgstr ""
+
+#. type: Content of: <Strings><SM_CHANGELOG>
+#: installer/Strings.xml:14
+#, no-wrap
+msgid "Change Log"
+msgstr ""
+
+#. type: Content of: <Strings><SM_UNINSTALL>
+#: installer/Strings.xml:15
+#, no-wrap
+msgid "Uninstall"
+msgstr ""
+
+#. type: Content of: <Strings><UN_REMOVE_QUESTION>
+#: installer/Strings.xml:16
+#, no-wrap
+msgid ""
+"Also remove queue, settings and the whole DC++ program directory ($INSTDIR) "
+"with all of its sub-directories?"
+msgstr ""

=== removed file 'release.sh'
--- release.sh	2010-01-19 23:27:03 +0000
+++ release.sh	1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-scons mode=release
-cp build/release-mingw/bin/DCPlusPlus.exe .
-i686-mingw32-strip DCPlusPlus.exe
-
-#copy /b app\dcplusplus.chm .
-zip -9 DCPlusPlus-$1.zip changelog.txt dcppboot.xml DCPlusPlus.chm DCPlusPlus.exe Example.xml License.txt LICENSE-GeoIP.txt LICENSE-OpenSSL.txt magnet.exe GeoIPCountryWhois.csv mingwm10.dll
-
-find *.txt *.TXT *.nsi *.xml *.py *.csv *.sh Doxyfile SConstruct boost bzip2 dcpp help htmlhelp res smartwin win32 openssl zlib \
- -wholename "*/.svn" -prune -o -print | grep -v gch$ | zip -9 DCPlusPlus-$1-src.zip -9 -@
-
-makensis DCPlusPlus.nsi
-mv DCPlusPlus-xxx.exe DCPlusPlus-$1.exe
-
-rm DCPlusPlus.exe
-
-svn status
-

=== removed file 'tag.sh'
--- tag.sh	2007-11-09 19:47:30 +0000
+++ tag.sh	1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-svn copy . https://dcplusplus.svn.sourceforge.net/svnroot/dcplusplus/dcplusplus/tags/dcplusplus-$1 -m "$1"

=== modified file 'update-languages.sh'
--- update-languages.sh	2010-03-11 19:01:52 +0000
+++ update-languages.sh	2010-09-21 20:28:03 +0000
@@ -34,9 +34,9 @@
 
 }
 
-scons i18n=1 dcpp/po win32/po help/po
+scons i18n=1 dcpp/po win32/po help/po installer/po
 
 process libdcpp dcpp
 process dcpp-win32 win32
 process dcpp-help help
-
+process dcpp-installer installer