1#!/usr/bin/env python3 2#coding:utf8 3 4 5# *** TROUBLESHOOTING *** 6# 1) If you get the error "ImportError: No module named zope.interface" then add an empty __init__.py file to the PYTHONDIR/Lib/site-packages/zope directory 7# 2) It is expected that you will have NSIS 3 NSIS from http://nsis.sourceforge.net installed. 8 9import codecs 10import sys 11# try: 12# if (sys.version_info.major != 2) or (sys.version_info.minor < 7): 13# raise Exception("You must build Syncplay with Python 2.7!") 14# except AttributeError: 15# import warnings 16# warnings.warn("You must build Syncplay with Python 2.7!") 17 18from glob import glob 19import os 20import subprocess 21from string import Template 22 23from distutils.core import setup 24try: 25 from py2exe.build_exe import py2exe 26except ImportError: 27 from py2exe.distutils_buildexe import py2exe 28 29import syncplay 30from syncplay.messages import getMissingStrings 31 32missingStrings = getMissingStrings() 33if missingStrings is not None and missingStrings is not "": 34 import warnings 35 warnings.warn("MISSING/UNUSED STRINGS DETECTED:\n{}".format(missingStrings)) 36 37def get_nsis_path(): 38 bin_name = "makensis.exe" 39 from winreg import HKEY_LOCAL_MACHINE as HKLM 40 from winreg import KEY_READ, KEY_WOW64_32KEY, OpenKey, QueryValueEx 41 42 try: 43 nsisreg = OpenKey(HKLM, "Software\\NSIS", 0, KEY_READ | KEY_WOW64_32KEY) 44 if QueryValueEx(nsisreg, "VersionMajor")[0] >= 3: 45 return "{}\\{}".format(QueryValueEx(nsisreg, "")[0], bin_name) 46 else: 47 raise Exception("You must install NSIS 3 or later.") 48 except WindowsError: 49 return bin_name 50 51NSIS_COMPILE = get_nsis_path() 52 53OUT_DIR = "syncplay_v{}".format(syncplay.version) 54SETUP_SCRIPT_PATH = "syncplay_setup.nsi" 55NSIS_SCRIPT_TEMPLATE = r""" 56 !include LogicLib.nsh 57 !include nsDialogs.nsh 58 !include FileFunc.nsh 59 60 LoadLanguageFile "$${NSISDIR}\Contrib\Language files\English.nlf" 61 LoadLanguageFile "$${NSISDIR}\Contrib\Language files\Polish.nlf" 62 LoadLanguageFile "$${NSISDIR}\Contrib\Language files\Russian.nlf" 63 LoadLanguageFile "$${NSISDIR}\Contrib\Language files\German.nlf" 64 LoadLanguageFile "$${NSISDIR}\Contrib\Language files\Italian.nlf" 65 LoadLanguageFile "$${NSISDIR}\Contrib\Language files\Spanish.nlf" 66 67 Unicode true 68 69 Name "Syncplay $version" 70 OutFile "Syncplay-$version-Setup.exe" 71 InstallDir $$PROGRAMFILES\Syncplay 72 RequestExecutionLevel admin 73 ManifestDPIAware false 74 XPStyle on 75 Icon syncplay\resources\icon.ico ;Change DIR 76 SetCompressor /SOLID lzma 77 78 VIProductVersion "$version.0" 79 VIAddVersionKey /LANG=$${LANG_ENGLISH} "ProductName" "Syncplay" 80 VIAddVersionKey /LANG=$${LANG_ENGLISH} "FileVersion" "$version.0" 81 VIAddVersionKey /LANG=$${LANG_ENGLISH} "LegalCopyright" "Syncplay" 82 VIAddVersionKey /LANG=$${LANG_ENGLISH} "FileDescription" "Syncplay" 83 84 VIAddVersionKey /LANG=$${LANG_POLISH} "ProductName" "Syncplay" 85 VIAddVersionKey /LANG=$${LANG_POLISH} "FileVersion" "$version.0" 86 VIAddVersionKey /LANG=$${LANG_POLISH} "LegalCopyright" "Syncplay" 87 VIAddVersionKey /LANG=$${LANG_POLISH} "FileDescription" "Syncplay" 88 89 VIAddVersionKey /LANG=$${LANG_RUSSIAN} "ProductName" "Syncplay" 90 VIAddVersionKey /LANG=$${LANG_RUSSIAN} "FileVersion" "$version.0" 91 VIAddVersionKey /LANG=$${LANG_RUSSIAN} "LegalCopyright" "Syncplay" 92 VIAddVersionKey /LANG=$${LANG_RUSSIAN} "FileDescription" "Syncplay" 93 94 VIAddVersionKey /LANG=$${LANG_ITALIAN} "ProductName" "Syncplay" 95 VIAddVersionKey /LANG=$${LANG_ITALIAN} "FileVersion" "$version.0" 96 VIAddVersionKey /LANG=$${LANG_ITALIAN} "LegalCopyright" "Syncplay" 97 VIAddVersionKey /LANG=$${LANG_ITALIAN} "FileDescription" "Syncplay" 98 99 VIAddVersionKey /LANG=$${LANG_SPANISH} "ProductName" "Syncplay" 100 VIAddVersionKey /LANG=$${LANG_SPANISH} "FileVersion" "$version.0" 101 VIAddVersionKey /LANG=$${LANG_SPANISH} "LegalCopyright" "Syncplay" 102 VIAddVersionKey /LANG=$${LANG_SPANISH} "FileDescription" "Syncplay" 103 104 LangString ^SyncplayLanguage $${LANG_ENGLISH} "en" 105 LangString ^Associate $${LANG_ENGLISH} "Associate Syncplay with multimedia files." 106 LangString ^Shortcut $${LANG_ENGLISH} "Create Shortcuts in following locations:" 107 LangString ^StartMenu $${LANG_ENGLISH} "Start Menu" 108 LangString ^Desktop $${LANG_ENGLISH} "Desktop" 109 LangString ^QuickLaunchBar $${LANG_ENGLISH} "Quick Launch Bar" 110 LangString ^AutomaticUpdates $${LANG_ENGLISH} "Check for updates automatically" 111 LangString ^UninstConfig $${LANG_ENGLISH} "Delete configuration file." 112 113 LangString ^SyncplayLanguage $${LANG_POLISH} "pl" 114 LangString ^Associate $${LANG_POLISH} "Skojarz Syncplaya z multimediami" 115 LangString ^Shortcut $${LANG_POLISH} "Utworz skroty w nastepujacych miejscach:" 116 LangString ^StartMenu $${LANG_POLISH} "Menu Start" 117 LangString ^Desktop $${LANG_POLISH} "Pulpit" 118 LangString ^QuickLaunchBar $${LANG_POLISH} "Pasek szybkiego uruchamiania" 119 LangString ^UninstConfig $${LANG_POLISH} "Usun plik konfiguracyjny." 120 121 LangString ^SyncplayLanguage $${LANG_RUSSIAN} "ru" 122 LangString ^Associate $${LANG_RUSSIAN} "Ассоциировать Syncplay с видеофайлами" 123 LangString ^Shortcut $${LANG_RUSSIAN} "Создать ярлыки:" 124 LangString ^StartMenu $${LANG_RUSSIAN} "в меню Пуск" 125 LangString ^Desktop $${LANG_RUSSIAN} "на рабочем столе" 126 LangString ^QuickLaunchBar $${LANG_RUSSIAN} "в меню быстрого запуска" 127 LangString ^AutomaticUpdates $${LANG_RUSSIAN} "Проверять обновления автоматически"; TODO: Confirm Russian translation ("Check for updates automatically") 128 LangString ^UninstConfig $${LANG_RUSSIAN} "Удалить файл настроек." 129 130 LangString ^SyncplayLanguage $${LANG_GERMAN} "de" 131 LangString ^Associate $${LANG_GERMAN} "Syncplay als Standardprogramm für Multimedia-Dateien verwenden." 132 LangString ^Shortcut $${LANG_GERMAN} "Erstelle Verknüpfungen an folgenden Orten:" 133 LangString ^StartMenu $${LANG_GERMAN} "Startmenü" 134 LangString ^Desktop $${LANG_GERMAN} "Desktop" 135 LangString ^QuickLaunchBar $${LANG_GERMAN} "Schnellstartleiste" 136 LangString ^AutomaticUpdates $${LANG_GERMAN} "Automatisch nach Updates suchen"; 137 LangString ^UninstConfig $${LANG_GERMAN} "Konfigurationsdatei löschen." 138 139 LangString ^SyncplayLanguage $${LANG_ITALIAN} "it" 140 LangString ^Associate $${LANG_ITALIAN} "Associa Syncplay con i file multimediali." 141 LangString ^Shortcut $${LANG_ITALIAN} "Crea i collegamenti nei percorsi seguenti:" 142 LangString ^StartMenu $${LANG_ITALIAN} "Menu Start" 143 LangString ^Desktop $${LANG_ITALIAN} "Desktop" 144 LangString ^QuickLaunchBar $${LANG_ITALIAN} "Barra di avvio rapido" 145 LangString ^AutomaticUpdates $${LANG_ITALIAN} "Controllo automatico degli aggiornamenti" 146 LangString ^UninstConfig $${LANG_ITALIAN} "Cancella i file di configurazione." 147 148 LangString ^SyncplayLanguage $${LANG_SPANISH} "es" 149 LangString ^Associate $${LANG_SPANISH} "Asociar Syncplay con archivos multimedia." 150 LangString ^Shortcut $${LANG_SPANISH} "Crear accesos directos en las siguientes ubicaciones:" 151 LangString ^StartMenu $${LANG_SPANISH} "Menú de inicio" 152 LangString ^Desktop $${LANG_SPANISH} "Escritorio" 153 LangString ^QuickLaunchBar $${LANG_SPANISH} "Barra de acceso rápido" 154 LangString ^AutomaticUpdates $${LANG_SPANISH} "Buscar actualizaciones automáticamente" 155 LangString ^UninstConfig $${LANG_SPANISH} "Borrar archivo de configuración." 156 157 ; Remove text to save space 158 LangString ^ClickInstall $${LANG_GERMAN} " " 159 160 PageEx license 161 LicenseData syncplay\resources\license.rtf 162 PageExEnd 163 Page custom DirectoryCustom DirectoryCustomLeave 164 Page instFiles 165 166 UninstPage custom un.installConfirm un.installConfirmLeave 167 UninstPage instFiles 168 169 Var Dialog 170 Var Icon_Syncplay 171 Var Icon_Syncplay_Handle 172 ;Var CheckBox_Associate 173 Var CheckBox_AutomaticUpdates 174 Var CheckBox_StartMenuShortcut 175 Var CheckBox_DesktopShortcut 176 Var CheckBox_QuickLaunchShortcut 177 ;Var CheckBox_Associate_State 178 Var CheckBox_AutomaticUpdates_State 179 Var CheckBox_StartMenuShortcut_State 180 Var CheckBox_DesktopShortcut_State 181 Var CheckBox_QuickLaunchShortcut_State 182 Var Button_Browse 183 Var Directory 184 Var GroupBox_DirSub 185 Var Label_Text 186 Var Label_Shortcut 187 Var Label_Size 188 Var Label_Space 189 Var Text_Directory 190 191 Var Uninst_Dialog 192 Var Uninst_Icon 193 Var Uninst_Icon_Handle 194 Var Uninst_Label_Directory 195 Var Uninst_Label_Text 196 Var Uninst_Text_Directory 197 Var Uninst_CheckBox_Config 198 Var Uninst_CheckBox_Config_State 199 200 Var Size 201 Var SizeHex 202 Var AvailibleSpace 203 Var AvailibleSpaceGiB 204 Var Drive 205 Var VLC_Directory 206 207 ;!macro APP_ASSOCIATE EXT FileCLASS DESCRIPTION COMMANDTEXT COMMAND 208 ; WriteRegStr HKCR ".$${EXT}" "" "$${FileCLASS}" 209 ; WriteRegStr HKCR "$${FileCLASS}" "" `$${DESCRIPTION}` 210 ; WriteRegStr HKCR "$${FileCLASS}\shell" "" "open" 211 ; WriteRegStr HKCR "$${FileCLASS}\shell\open" "" `$${COMMANDTEXT}` 212 ; WriteRegStr HKCR "$${FileCLASS}\shell\open\command" "" `$${COMMAND}` 213 ;!macroend 214 215 !macro APP_UNASSOCIATE EXT FileCLASS 216 ; Backup the previously associated File class 217 ReadRegStr $$R0 HKCR ".$${EXT}" `$${FileCLASS}_backup` 218 WriteRegStr HKCR ".$${EXT}" "" "$$R0" 219 DeleteRegKey HKCR `$${FileCLASS}` 220 !macroend 221 222 ;!macro ASSOCIATE EXT 223 ; !insertmacro APP_ASSOCIATE "$${EXT}" "Syncplay.$${EXT}" "$$INSTDIR\Syncplay.exe,%1%" \ 224 ; "Open with Syncplay" "$$INSTDIR\Syncplay.exe $$\"%1$$\"" 225 ;!macroend 226 227 !macro UNASSOCIATE EXT 228 !insertmacro APP_UNASSOCIATE "$${EXT}" "Syncplay.$${EXT}" 229 !macroend 230 231 ;Prevents from running more than one instance of installer and sets default state of checkboxes 232 Function .onInit 233 System::Call 'kernel32::CreateMutexA(i 0, i 0, t "SyncplayMutex") i .r1 ?e' 234 Pop $$R0 235 StrCmp $$R0 0 +3 236 MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." 237 Abort 238 239 ;StrCpy $$CheckBox_Associate_State $${BST_CHECKED} 240 StrCpy $$CheckBox_StartMenuShortcut_State $${BST_CHECKED} 241 242 Call GetSize 243 Call DriveSpace 244 Call Language 245 FunctionEnd 246 247 ;Language selection dialog 248 Function Language 249 Push "" 250 Push $${LANG_ENGLISH} 251 Push English 252 Push $${LANG_POLISH} 253 Push Polski 254 Push $${LANG_RUSSIAN} 255 Push Русский 256 Push $${LANG_GERMAN} 257 Push Deutsch 258 Push $${LANG_ITALIAN} 259 Push Italiano 260 Push $${LANG_SPANISH} 261 Push Español 262 Push A ; A means auto count languages 263 LangDLL::LangDialog "Language Selection" "Please select the language of Syncplay and the installer" 264 Pop $$LANGUAGE 265 StrCmp $$LANGUAGE "cancel" 0 +2 266 Abort 267 FunctionEnd 268 269 Function DirectoryCustom 270 271 nsDialogs::Create 1018 272 Pop $$Dialog 273 274 GetFunctionAddress $$R8 DirectoryCustomLeave 275 nsDialogs::OnBack $$R8 276 277 $${NSD_CreateIcon} 0u 0u 22u 20u "" 278 Pop $$Icon_Syncplay 279 $${NSD_SetIconFromInstaller} $$Icon_Syncplay $$Icon_Syncplay_Handle 280 281 $${NSD_CreateLabel} 25u 0u 241u 34u "$$(^DirText)" 282 Pop $$Label_Text 283 284 $${NSD_CreateText} 8u 38u 187u 12u "$$INSTDIR" 285 Pop $$Text_Directory 286 $${NSD_SetFocus} $$Text_Directory 287 288 $${NSD_CreateBrowseButton} 202u 37u 55u 14u "$$(^BrowseBtn)" 289 Pop $$Button_Browse 290 $${NSD_OnClick} $$Button_Browse DirectoryBrowseDialog 291 292 $${NSD_CreateGroupBox} 1u 27u 264u 30u "$$(^DirSubText)" 293 Pop $$GroupBox_DirSub 294 295 $${NSD_CreateLabel} 0u 122u 132 8u "$$(^SpaceRequired)$$SizeMB" 296 Pop $$Label_Size 297 298 $${NSD_CreateLabel} 321u 122u 132 8u "$$(^SpaceAvailable)$$AvailibleSpaceGiB.$$AvailibleSpaceGB" 299 Pop $$Label_Space 300 301 ;$${NSD_CreateCheckBox} 8u 59u 187u 10u "$$(^Associate)" 302 ;Pop $$CheckBox_Associate 303 304 $${NSD_CreateCheckBox} 8u 72u 250u 10u "$$(^AutomaticUpdates)" 305 Pop $$CheckBox_AutomaticUpdates 306 $${NSD_Check} $$CheckBox_AutomaticUpdates 307 308 $${NSD_CreateLabel} 8u 95u 187u 10u "$$(^Shortcut)" 309 Pop $$Label_Shortcut 310 311 $${NSD_CreateCheckbox} 8u 105u 60u 10u "$$(^StartMenu)" 312 Pop $$CheckBox_StartMenuShortcut 313 314 $${NSD_CreateCheckbox} 78u 105u 70u 10u "$$(^Desktop)" 315 Pop $$CheckBox_DesktopShortcut 316 317 $${NSD_CreateCheckbox} 158u 105u 130u 10u "$$(^QuickLaunchBar)" 318 Pop $$CheckBox_QuickLaunchShortcut 319 320 ;$${If} $$CheckBox_Associate_State == $${BST_CHECKED} 321 ; $${NSD_Check} $$CheckBox_Associate 322 ;$${EndIf} 323 324 325 $${If} $$CheckBox_StartMenuShortcut_State == $${BST_CHECKED} 326 $${NSD_Check} $$CheckBox_StartMenuShortcut 327 $${EndIf} 328 329 $${If} $$CheckBox_DesktopShortcut_State == $${BST_CHECKED} 330 $${NSD_Check} $$CheckBox_DesktopShortcut 331 $${EndIf} 332 333 $${If} $$CheckBox_QuickLaunchShortcut_State == $${BST_CHECKED} 334 $${NSD_Check} $$CheckBox_QuickLaunchShortcut 335 $${EndIf} 336 337 $${If} $$CheckBox_AutomaticUpdates_State == $${BST_CHECKED} 338 $${NSD_Check} $$CheckBox_AutomaticUpdates 339 $${EndIf} 340 341 nsDialogs::Show 342 343 $${NSD_FreeIcon} $$Icon_Syncplay_Handle 344 345 FunctionEnd 346 347 Function DirectoryCustomLeave 348 $${NSD_GetText} $$Text_Directory $$INSTDIR 349 ;$${NSD_GetState} $$CheckBox_Associate $$CheckBox_Associate_State 350 $${NSD_GetState} $$CheckBox_AutomaticUpdates $$CheckBox_AutomaticUpdates_State 351 $${NSD_GetState} $$CheckBox_StartMenuShortcut $$CheckBox_StartMenuShortcut_State 352 $${NSD_GetState} $$CheckBox_DesktopShortcut $$CheckBox_DesktopShortcut_State 353 $${NSD_GetState} $$CheckBox_QuickLaunchShortcut $$CheckBox_QuickLaunchShortcut_State 354 FunctionEnd 355 356 Function DirectoryBrowseDialog 357 nsDialogs::SelectFolderDialog $$(^DirBrowseText) 358 Pop $$Directory 359 $${If} $$Directory != error 360 StrCpy $$INSTDIR $$Directory 361 $${NSD_SetText} $$Text_Directory $$INSTDIR 362 Call DriveSpace 363 $${NSD_SetText} $$Label_Space "$$(^SpaceAvailable)$$AvailibleSpaceGiB.$$AvailibleSpaceGB" 364 $${EndIf} 365 Abort 366 FunctionEnd 367 368 Function GetSize 369 StrCpy $$Size "$totalSize" 370 IntOp $$Size $$Size / 1024 371 IntFmt $$SizeHex "0x%08X" $$Size 372 IntOp $$Size $$Size / 1024 373 FunctionEnd 374 375 ;Calculates Free Space on HDD 376 Function DriveSpace 377 StrCpy $$Drive $$INSTDIR 1 378 $${DriveSpace} "$$Drive:\" "/D=F /S=M" $$AvailibleSpace 379 IntOp $$AvailibleSpaceGiB $$AvailibleSpace / 1024 380 IntOp $$AvailibleSpace $$AvailibleSpace % 1024 381 IntOp $$AvailibleSpace $$AvailibleSpace / 102 382 FunctionEnd 383 384 Function InstallOptions 385 ;$${If} $$CheckBox_Associate_State == $${BST_CHECKED} 386 ; Call Associate 387 ; DetailPrint "Associated Syncplay with multimedia files" 388 ;$${EndIf} 389 390 $${If} $$CheckBox_StartMenuShortcut_State == $${BST_CHECKED} 391 CreateDirectory $$SMPROGRAMS\Syncplay 392 SetOutPath "$$INSTDIR" 393 CreateShortCut "$$SMPROGRAMS\Syncplay\Syncplay.lnk" "$$INSTDIR\Syncplay.exe" "" 394 CreateShortCut "$$SMPROGRAMS\Syncplay\Syncplay Server.lnk" "$$INSTDIR\syncplayServer.exe" "" 395 CreateShortCut "$$SMPROGRAMS\Syncplay\Uninstall.lnk" "$$INSTDIR\Uninstall.exe" "" 396 WriteINIStr "$$SMPROGRAMS\Syncplay\SyncplayWebsite.url" "InternetShortcut" "URL" "https://syncplay.pl" 397 $${EndIf} 398 399 $${If} $$CheckBox_DesktopShortcut_State == $${BST_CHECKED} 400 SetOutPath "$$INSTDIR" 401 CreateShortCut "$$DESKTOP\Syncplay.lnk" "$$INSTDIR\Syncplay.exe" "" 402 $${EndIf} 403 404 $${If} $$CheckBox_QuickLaunchShortcut_State == $${BST_CHECKED} 405 SetOutPath "$$INSTDIR" 406 CreateShortCut "$$QUICKLAUNCH\Syncplay.lnk" "$$INSTDIR\Syncplay.exe" "" 407 $${EndIf} 408 FunctionEnd 409 410 ;Associates extensions with Syncplay 411 ;Function Associate 412 ; !insertmacro ASSOCIATE avi 413 ; !insertmacro ASSOCIATE mpg 414 ; !insertmacro ASSOCIATE mpeg 415 ; !insertmacro ASSOCIATE mpe 416 ; !insertmacro ASSOCIATE m1v 417 ; !insertmacro ASSOCIATE m2v 418 ; !insertmacro ASSOCIATE mpv2 419 ; !insertmacro ASSOCIATE mp2v 420 ; !insertmacro ASSOCIATE mkv 421 ; !insertmacro ASSOCIATE mp4 422 ; !insertmacro ASSOCIATE m4v 423 ; !insertmacro ASSOCIATE mp4v 424 ; !insertmacro ASSOCIATE 3gp 425 ; !insertmacro ASSOCIATE 3gpp 426 ; !insertmacro ASSOCIATE 3g2 427 ; !insertmacro ASSOCIATE 3pg2 428 ; !insertmacro ASSOCIATE flv 429 ; !insertmacro ASSOCIATE f4v 430 ; !insertmacro ASSOCIATE rm 431 ; !insertmacro ASSOCIATE wmv 432 ; !insertmacro ASSOCIATE swf 433 ; !insertmacro ASSOCIATE rmvb 434 ; !insertmacro ASSOCIATE divx 435 ; !insertmacro ASSOCIATE amv 436 ;FunctionEnd 437 438 Function WriteRegistry 439 Call GetSize 440 WriteRegStr HKLM SOFTWARE\Syncplay "Install_Dir" "$$INSTDIR" 441 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "DisplayName" "Syncplay" 442 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "InstallLocation" "$$INSTDIR" 443 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "UninstallString" '"$$INSTDIR\uninstall.exe"' 444 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "DisplayIcon" "$$INSTDIR\resources\icon.ico" 445 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "Publisher" "Syncplay" 446 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "DisplayVersion" "$version" 447 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "URLInfoAbout" "https://syncplay.pl/" 448 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "NoModify" 1 449 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "NoRepair" 1 450 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "EstimatedSize" "$$SizeHex" 451 WriteINIStr $$APPDATA\syncplay.ini general language $$(^SyncplayLanguage) 452 $${If} $$CheckBox_AutomaticUpdates_State == $${BST_CHECKED} 453 WriteINIStr $$APPDATA\syncplay.ini general CheckForUpdatesAutomatically "True" 454 $${Else} 455 WriteINIStr $$APPDATA\syncplay.ini general CheckForUpdatesAutomatically "False" 456 $${EndIf} 457 FunctionEnd 458 459 Function un.installConfirm 460 nsDialogs::Create 1018 461 Pop $$Uninst_Dialog 462 463 $${NSD_CreateIcon} 0u 1u 22u 20u "" 464 Pop $$Uninst_Icon 465 $${NSD_SetIconFromInstaller} $$Uninst_Icon $$Uninst_Icon_Handle 466 467 $${NSD_CreateLabel} 0u 45u 55u 8u "$$(^UninstallingSubText)" 468 Pop $$Uninst_Label_Directory 469 470 $${NSD_CreateLabel} 25u 0u 241u 34u "$$(^UninstallingText)" 471 Pop $$Uninst_Label_Text 472 473 ReadRegStr $$INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "InstallLocation" 474 $${NSD_CreateText} 56u 43u 209u 12u "$$INSTDIR" 475 Pop $$Uninst_Text_Directory 476 EnableWindow $$Uninst_Text_Directory 0 477 478 $${NSD_CreateCheckBox} 0u 60u 250u 10u "$$(^UninstConfig)" 479 Pop $$Uninst_CheckBox_Config 480 481 482 nsDialogs::Show 483 $${NSD_FreeIcon} $$Uninst_Icon_Handle 484 FunctionEnd 485 486 Function un.installConfirmLeave 487 $${NSD_GetState} $$Uninst_CheckBox_Config $$Uninst_CheckBox_Config_State 488 FunctionEnd 489 490 Function un.AssociateDel 491 !insertmacro UNASSOCIATE avi 492 !insertmacro UNASSOCIATE mpg 493 !insertmacro UNASSOCIATE mpeg 494 !insertmacro UNASSOCIATE mpe 495 !insertmacro UNASSOCIATE m1v 496 !insertmacro UNASSOCIATE m2v 497 !insertmacro UNASSOCIATE mpv2 498 !insertmacro UNASSOCIATE mp2v 499 !insertmacro UNASSOCIATE mkv 500 !insertmacro UNASSOCIATE mp4 501 !insertmacro UNASSOCIATE m4v 502 !insertmacro UNASSOCIATE mp4v 503 !insertmacro UNASSOCIATE 3gp 504 !insertmacro UNASSOCIATE 3gpp 505 !insertmacro UNASSOCIATE 3g2 506 !insertmacro UNASSOCIATE 3pg2 507 !insertmacro UNASSOCIATE flv 508 !insertmacro UNASSOCIATE f4v 509 !insertmacro UNASSOCIATE rm 510 !insertmacro UNASSOCIATE wmv 511 !insertmacro UNASSOCIATE swf 512 !insertmacro UNASSOCIATE rmvb 513 !insertmacro UNASSOCIATE divx 514 !insertmacro UNASSOCIATE amv 515 FunctionEnd 516 517 Function un.InstallOptions 518 Delete $$SMPROGRAMS\Syncplay\Syncplay.lnk 519 Delete "$$SMPROGRAMS\Syncplay\Syncplay Server.lnk" 520 Delete $$SMPROGRAMS\Syncplay\Uninstall.lnk 521 Delete $$SMPROGRAMS\Syncplay\SyncplayWebsite.url 522 RMDir $$SMPROGRAMS\Syncplay 523 Delete $$DESKTOP\Syncplay.lnk 524 Delete $$QUICKLAUNCH\Syncplay.lnk 525 ReadRegStr $$VLC_Directory HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" "VLCInstallLocation" 526 IfFileExists "$$VLC_Directory\lua\intf\syncplay.lua" 0 +2 527 Delete $$VLC_Directory\lua\intf\syncplay.lua 528 FunctionEnd 529 530 Section "Install" 531 SetOverwrite on 532 SetOutPath $$INSTDIR 533 WriteUninstaller uninstall.exe 534 535 $installFiles 536 537 Call InstallOptions 538 Call WriteRegistry 539 SectionEnd 540 541 Section "Uninstall" 542 Call un.AssociateDel 543 Call un.InstallOptions 544 $uninstallFiles 545 DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Syncplay" 546 DeleteRegKey HKLM SOFTWARE\Syncplay 547 Delete $$INSTDIR\uninstall.exe 548 RMDir $$INSTDIR\Syncplay\\resources\lua\intf 549 RMDir $$INSTDIR\Syncplay\\resources\lua 550 RMDir $$INSTDIR\Syncplay\\resources 551 RMDir $$INSTDIR\resources 552 RMDir $$INSTDIR\lib 553 RMDir $$INSTDIR 554 555 $${If} $$Uninst_CheckBox_Config_State == $${BST_CHECKED} 556 IfFileExists "$$APPDATA\.syncplay" 0 +2 557 Delete $$APPDATA\.syncplay 558 IfFileExists "$$APPDATA\syncplay.ini" 0 +2 559 Delete $$APPDATA\syncplay.ini 560 $${EndIf} 561 SectionEnd 562""" 563 564class NSISScript(object): 565 def create(self): 566 fileList, totalSize = self.getBuildDirContents(OUT_DIR) 567 print("Total size eq: {}".format(totalSize)) 568 installFiles = self.prepareInstallListTemplate(fileList) 569 uninstallFiles = self.prepareDeleteListTemplate(fileList) 570 571 if os.path.isfile(SETUP_SCRIPT_PATH): 572 raise RuntimeError("Cannot create setup script, file exists at {}".format(SETUP_SCRIPT_PATH)) 573 contents = Template(NSIS_SCRIPT_TEMPLATE).substitute( 574 version=syncplay.version, 575 uninstallFiles=uninstallFiles, 576 installFiles=installFiles, 577 totalSize=totalSize, 578 ) 579 with codecs.open(SETUP_SCRIPT_PATH, "w", "utf-8-sig") as outfile: 580 outfile.write(contents) 581 582 def compile(self): 583 if not os.path.isfile(NSIS_COMPILE): 584 return "makensis.exe not found, won't create the installer" 585 subproc = subprocess.Popen([NSIS_COMPILE, SETUP_SCRIPT_PATH], env=os.environ) 586 subproc.communicate() 587 retcode = subproc.returncode 588 os.remove(SETUP_SCRIPT_PATH) 589 if retcode: 590 raise RuntimeError("NSIS compilation return code: %d" % retcode) 591 592 def getBuildDirContents(self, path): 593 fileList = {} 594 totalSize = 0 595 for root, _, files in os.walk(path): 596 totalSize += sum(os.path.getsize(os.path.join(root, file_)) for file_ in files) 597 for file_ in files: 598 new_root = root.replace(OUT_DIR, "").strip("\\") 599 if new_root not in fileList: 600 fileList[new_root] = [] 601 fileList[new_root].append(file_) 602 return fileList, totalSize 603 604 def prepareInstallListTemplate(self, fileList): 605 create = [] 606 for dir_ in fileList.keys(): 607 create.append('SetOutPath "$INSTDIR\\{}"'.format(dir_)) 608 for file_ in fileList[dir_]: 609 create.append('FILE "{}\\{}\\{}"'.format(OUT_DIR, dir_, file_)) 610 return "\n".join(create) 611 612 def prepareDeleteListTemplate(self, fileList): 613 delete = [] 614 for dir_ in fileList.keys(): 615 for file_ in fileList[dir_]: 616 delete.append('DELETE "$INSTDIR\\{}\\{}"'.format(dir_, file_)) 617 delete.append('RMdir "$INSTDIR\\{}"'.format(file_)) 618 return "\n".join(delete) 619 620def pruneUnneededLibraries(): 621 from pathlib import Path 622 cwd = os.getcwd() 623 libDir = cwd + '\\' + OUT_DIR + '\\lib\\' 624 unneededModules = ['PySide2.Qt3D*', 'PySide2.QtAxContainer.pyd', 'PySide2.QtCharts.pyd', 'PySide2.QtConcurrent.pyd', 625 'PySide2.QtDataVisualization.pyd', 'PySide2.QtHelp.pyd', 'PySide2.QtLocation.pyd', 626 'PySide2.QtMultimedia.pyd', 'PySide2.QtMultimediaWidgets.pyd', 'PySide2.QtOpenGL.pyd', 627 'PySide2.QtPositioning.pyd', 'PySide2.QtPrintSupport.pyd', 'PySide2.QtQml.pyd', 628 'PySide2.QtQuick.pyd', 'PySide2.QtQuickWidgets.pyd', 'PySide2.QtScxml.pyd', 'PySide2.QtSensors.pyd', 629 'PySide2.QtSql.pyd', 'PySide2.QtSvg.pyd', 'PySide2.QtTest.pyd', 'PySide2.QtTextToSpeech.pyd', 630 'PySide2.QtUiTools.pyd', 'PySide2.QtWebChannel.pyd', 'PySide2.QtWebEngine.pyd', 631 'PySide2.QtWebEngineCore.pyd', 'PySide2.QtWebEngineWidgets.pyd', 'PySide2.QtWebSockets.pyd', 632 'PySide2.QtWinExtras.pyd', 'PySide2.QtXml.pyd', 'PySide2.QtXmlPatterns.pyd'] 633 unneededLibs = ['Qt53D*', 'Qt5Charts.dll', 'Qt5Concurrent.dll', 'Qt5DataVisualization.dll', 'Qt5Gamepad.dll', 'Qt5Help.dll', 634 'Qt5Location.dll', 'Qt5Multimedia.dll', 'Qt5MultimediaWidgets.dll', 'Qt5OpenGL.dll', 'Qt5Positioning.dll', 635 'Qt5PrintSupport.dll', 'Qt5Quick.dll', 'Qt5QuickWidgets.dll', 'Qt5Scxml.dll', 'Qt5Sensors.dll', 'Qt5Sql.dll', 636 'Qt5Svg.dll', 'Qt5Test.dll', 'Qt5TextToSpeech.dll', 'Qt5WebChannel.dll', 'Qt5WebEngine.dll', 637 'Qt5WebEngineCore.dll', 'Qt5WebEngineWidgets.dll', 'Qt5WebSockets.dll', 'Qt5WinExtras.dll', 'Qt5Xml.dll', 638 'Qt5XmlPatterns.dll'] 639 windowsDLL = ['MSVCP140.dll', 'VCRUNTIME140.dll'] 640 deleteList = unneededModules + unneededLibs + windowsDLL 641 deleteList.append('api-*') 642 for filename in deleteList: 643 for p in Path(libDir).glob(filename): 644 p.unlink() 645 646def copyQtPlugins(paths): 647 import shutil 648 from PySide2 import QtCore 649 basePath = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.PluginsPath) 650 basePath = basePath.replace('/', '\\') 651 destBase = os.getcwd() + '\\' + OUT_DIR 652 for elem in paths: 653 elemDir, elemName = os.path.split(elem) 654 source = basePath + '\\' + elem 655 dest = destBase + '\\' + elem 656 destDir = destBase + '\\' + elemDir 657 os.makedirs(destDir, exist_ok=True) 658 shutil.copy(source, dest) 659 660class build_installer(py2exe): 661 def run(self): 662 py2exe.run(self) 663 print('*** deleting unnecessary libraries and modules ***') 664 pruneUnneededLibraries() 665 print('*** copying qt plugins ***') 666 copyQtPlugins(qt_plugins) 667 script = NSISScript() 668 script.create() 669 print("*** compiling the NSIS setup script ***") 670 script.compile() 671 print("*** DONE ***") 672 673guiIcons = glob('syncplay/resources/*.png') + ['syncplay/resources/spinner.mng'] 674 675resources = [ 676 "syncplay/resources/icon.ico", 677 "syncplay/resources/syncplayintf.lua", 678 "syncplay/resources/license.rtf", 679 "syncplay/resources/third-party-notices.rtf" 680] 681resources.extend(guiIcons) 682intf_resources = ["syncplay/resources/lua/intf/syncplay.lua"] 683 684qt_plugins = ['platforms\\qwindows.dll', 'styles\\qwindowsvistastyle.dll'] 685 686common_info = dict( 687 name='Syncplay', 688 version=syncplay.version, 689 author='Uriziel', 690 author_email='dev@syncplay.pl', 691 description='Syncplay', 692) 693 694info = dict( 695 common_info, 696 windows=[{ 697 "script": "syncplayClient.py", 698 "icon_resources": [(1, "syncplay\\resources\\icon.ico")], 699 'dest_base': "Syncplay"}, 700 ], 701 console=['syncplayServer.py'], 702 # *** If you wish to make the Syncplay client use console mode (for --no-gui to work) then comment out the above two lines and uncomment the following line: 703 # console=['syncplayServer.py', {"script":"syncplayClient.py", "icon_resources":[(1, "resources\\icon.ico")], 'dest_base': "Syncplay"}], 704 705 options={ 706 'py2exe': { 707 'dist_dir': OUT_DIR, 708 'packages': 'PySide2, cffi, OpenSSL, certifi', 709 'includes': 'twisted, sys, encodings, datetime, os, time, math, urllib, ast, unicodedata, _ssl, win32pipe, win32file', 710 'excludes': 'venv, doctest, pdb, unittest, win32clipboard, win32pdh, win32security, win32trace, win32ui, winxpgui, win32process, Tkinter', 711 'dll_excludes': 'msvcr71.dll, MSVCP90.dll, POWRPROF.dll', 712 'optimize': 2, 713 'compressed': 1 714 } 715 }, 716 data_files=[("resources", resources), ("resources/lua/intf", intf_resources)], 717 zipfile="lib/libsync", 718 cmdclass={"py2exe": build_installer}, 719) 720 721sys.argv.extend(['py2exe']) 722setup(**info)