File size: 9,649 Bytes
27867f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
Var Dialog
Var lblLabel
Var lblUsername
Var lblPassword
Var txtUsername
Var pwdPassword
Var pwdConfirmPassword
Var hwnd
Var user

Var pwd
Var pwd2
Var subfolder
Var cmd
Var pythoninstall
Var pythonpath
Var DataFolder
Var txtDataFolder
Var BROWSEDATA

!include "CharToASCII.nsh"
!include "Base64.nsh"


Function DataFolderPage
    nsDialogs::Create /NOUNLOAD 1018
    Pop $Dialog
    ${If} $Dialog == error
        Abort
    ${EndIf}
    CreateDirectory "$DataFolder"
    ${NSD_CreateLabel} 0 0 100% 24u "Please specify the Cabernet data folder. \

        Writeable by the user: System$\r$\nIt is highly recommended to have \

        this folder be easy to access."
    ${NSD_CreateGroupBox} 0 40u 100% 34u "Data Folder"
        ${NSD_CreateText} 3% 54u 77% 12u "$DataFolder"
        Pop $txtDataFolder
        ${NSD_CreateBrowseButton} 82% 54u 15% 13u "Browse"
        pop $BROWSEDATA
        ${NSD_OnClick} $BROWSEDATA BrowseData
    nsDialogs::Show
FunctionEnd

Function BrowseData
    nsDialogs::SelectFolderDialog "Select Data Folder" "$DataFolder"
    pop $0
    ${If} $0 != error
        ${NSD_SetText} $txtDataFolder $0
        StrCpy $DataFolder $0
    ${EndIf}
FunctionEnd

Function DataFolderPageLeave
    ${NSD_GetText} $txtDataFolder $DataFolder
FunctionEnd

Function UserPassPage
    nsDialogs::Create /NOUNLOAD 1018
    Pop $Dialog
    ${If} $Dialog == error
        Abort
    ${EndIf}
    ${NSD_CreateLabel} 0 0 100% 24u "Please specify LocastUsername and Password."
    Pop $lblLabel
    ${NSD_CreateLabel} 0 30u 60u 12u "Username:"
    Pop $lblUsername
    ${NSD_CreateText} 65u 30u 50% 12u ""
    Pop $txtUsername
    ${NSD_CreateLabel} 0 45u 60u 12u "Password:"
    Pop $lblPassword
    ${NSD_CreatePassword} 65u 45u 50% 12u ""
    Pop $pwdPassword
    ${NSD_CreateLabel} 0 60u 60u 12u "Confirm Password:"
    Pop $lblPassword
    ${NSD_CreatePassword} 65u 60u 50% 12u ""
    Pop $pwdConfirmPassword
    ${NSD_CreateCheckbox} 65u 75u 50% 12u "Show password"
    Pop $hwnd
    ${NSD_OnClick} $hwnd ShowPassword
    nsDialogs::Show
FunctionEnd

Function UserPassPageLeave
    ${NSD_GetText} $txtUsername $user
    ${NSD_GetText} $pwdPassword $pwd
    ${NSD_GetText} $pwdConfirmPassword $pwd2
    ${If} $user == ""
    ${OrIf} $pwd == ""
    ${OrIf} $pwd2 == ""
        MessageBox MB_OK "All entries are required"
        Abort
    ${EndIf}
    ${If} $pwd != $pwd2
        MessageBox MB_OK "passwords do not match, try again"
        Abort
    ${EndIf}
    ${Base64_Encode} $pwd
    Pop $0
    StrCpy $pwd $0
FunctionEnd

Function ShowPassword
    Pop $hwnd
    ${NSD_GetState} $hwnd $0
    ShowWindow $pwdPassword ${SW_HIDE}
    ShowWindow $pwdConfirmPassword ${SW_HIDE}
    ${If} $0 == 1
        SendMessage $pwdPassword ${EM_SETPASSWORDCHAR} 0 0
        SendMessage $pwdConfirmPassword ${EM_SETPASSWORDCHAR} 0 0
    ${Else}
        SendMessage $pwdPassword ${EM_SETPASSWORDCHAR} 42 0
        SendMessage $pwdConfirmPassword ${EM_SETPASSWORDCHAR} 42 0
    ${EndIf}
    ShowWindow $pwdPassword ${SW_SHOW}
    ShowWindow $pwdConfirmPassword ${SW_SHOW}
FunctionEnd

Function TestPython
    !define SOURCEPATH "../.."
    SetOutPath "$INSTDIR"
    File "${SOURCEPATH}\build\WINDOWS\findpython.pyw"
    StrCpy $cmd 'python findpython.pyw'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 PythonFound
        MessageBox MB_OK "Python 3.x not found, Make sure to install python$\r$\n\

            for all users if a Windows Service is needed or single user$\r$\n\

            without admin access"
        StrCpy $pythonpath ""
        Goto PythonMissing
    PythonFound:
    MessageBox MB_OK "Using Python installation $1$\r$\n\

        If this is not correct, please uninstall the unwanted python versions"
    Push $1
    Call Trim
    Pop $pythonpath
    Call ClearPythonInstallFlag
    PythonMissing:
    Delete $INSTDIR\findpython.pyw
FunctionEnd

Function TestPythonSilent
    SetOutPath "$INSTDIR"
    File "${SOURCEPATH}\build\WINDOWS\findpython.pyw"
    nsExec::ExecToStack 'python findpython.pyw'
    Pop $0 ;return value
    Pop $1 ;return value
    IntCmp $0 0 PythonFound
        StrCpy $pythonpath ""
        Goto PythonMissing
    PythonFound:
    Push $1
    Call Trim
    Pop $pythonpath
    ;StrCpy $pythonpath $1
    PythonMissing:
    Delete $INSTDIR\findpython.pyw
FunctionEnd

Function UpdateConfig
    SetOutPath "$INSTDIR"
    StrCpy $cmd 'python -m build.WINDOWS.UpdateConfig -i "$INSTDIR" -d "$DataFolder"'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 PythonDone
        MessageBox MB_OK "Unable to update Config file. Edit the file manually. $0 $1"
    PythonDone:
FunctionEnd

Function AddFiles
    ; !define SOURCEPATH "../.."
    SetOutPath "$INSTDIR"
    File "${SOURCEPATH}\tvh_main.py"
    File "${SOURCEPATH}\LICENSE"
    File "${SOURCEPATH}\CHANGELOG.md"
    File "${SOURCEPATH}\.dockerignore"
    File "${SOURCEPATH}\docker-compose.yml"
    File "${SOURCEPATH}\Dockerfile"
    File "${SOURCEPATH}\Docker_entrypoint.sh"
    File "${SOURCEPATH}\Dockerfile_tvh_crypt.alpine"
    File "${SOURCEPATH}\Dockerfile_tvh_crypt.slim-buster"
    File "${SOURCEPATH}\README.md"
    File "${SOURCEPATH}\TVHEADEND.md"
    File "${SOURCEPATH}\requirements.txt"
    Rename "$INSTDIR\TVHEADEND.md" "$INSTDIR\README.txt"

    SetOutPath "$INSTDIR\lib"
    File /r /x __pycache__ /x development "${SOURCEPATH}\lib\*.*"
    SetOutPath "$INSTDIR\plugins"
    File /r /x __pycache__ "${SOURCEPATH}\plugins\*.*"

    SetOutPath "$INSTDIR\build\WINDOWS"
    File "${SOURCEPATH}\build\WINDOWS\UpdateConfig.pyw"
FunctionEnd

; arg: $subfolder
; return: $subfolder
Function GetSubfolder
    FindFirst $0 $1 "$subfolder"
    StrCmp $1 "" empty
    ${If} ${FileExists} "$subfolder"
        StrCpy $subfolder $1
    ${EndIf}
    Goto done
    empty:
    StrCpy $subfolder ""
    done:
    FindClose $0
FunctionEnd


Function InstallService
    Call TestPythonSilent
    StrCmp "$pythonpath" "" 0 found
        MessageBox MB_OK "Unable to detect python install, aborting $pythonpath"
        Abort
    found:
    StrCpy $cmd '"$INSTDIR\lib\tvheadend\service\Windows\nssm.exe" install Cabernet \

        "$pythonpath" "\""$INSTDIR\tvh_main.py\""" -c "\""$DataFolder\config.ini\"""'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 5 ServiceAlreadyInstalled
    IntCmp $0 0 ServiceDone
        MessageBox MB_OK "Service not installed. status:$0 $1"
    ServiceDone:
    StrCpy $cmd '$INSTDIR\lib\tvheadend\service\Windows\nssm.exe set Cabernet AppDirectory "$INSTDIR"'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 Service2Done
        MessageBox MB_OK "Service update AppDirectory failed.  status:$0 $1"
    Service2Done:
    CreateDirectory "$TEMP\cabernet"
    StrCpy $cmd '$INSTDIR\lib\tvheadend\service\Windows\nssm.exe set Cabernet AppStdout "$TEMP\cabernet\out.log"'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 Service3Done
        MessageBox MB_OK "Service update AppDirectory failed.  status:$0 $1"
    Service3Done:
    StrCpy $cmd '$INSTDIR\lib\tvheadend\service\Windows\nssm.exe set Cabernet AppStderr "$TEMP\cabernet\error.log"'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 Service4Done
        MessageBox MB_OK "Service update AppDirectory failed.  status:$0 $1"
    Service4Done:
    StrCpy $cmd '$INSTDIR\lib\tvheadend\service\Windows\nssm.exe set Cabernet AppStdoutCreationDisposition 2'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 Service5Done
        MessageBox MB_OK "Service update AppDirectory failed.  status:$0 $1"
    Service5Done:
    StrCpy $cmd '$INSTDIR\lib\tvheadend\service\Windows\nssm.exe set Cabernet AppStderrCreationDisposition 2'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 Service6Done
        MessageBox MB_OK "Service update AppDirectory failed.  status:$0 $1"
    Goto Service6Done
    ServiceAlreadyInstalled:
    MessageBox MB_OK "Service already installed"
    Service6Done:
FunctionEnd


Function un.installService
    StrCpy $cmd '"$INSTDIR\lib\tvheadend\service\Windows\nssm.exe" stop Cabernet'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    StrCpy $cmd '"$INSTDIR\lib\tvheadend\service\Windows\nssm.exe" remove Cabernet confirm'
    nsExec::ExecToStack '$cmd'
    Pop $0 ;return value
    Pop $1 ; status text
    IntCmp $0 0 ServiceDone
        MessageBox MB_OK "Service not uninstalled. status:$0 $1"
    ServiceDone:
FunctionEnd


; Trim
;   Removes leading & trailing whitespace from a string
; Usage:
;   Push
;   Call Trim
;   Pop
Function Trim
	Exch $R1 ; Original string
	Push $R2
Loop:
	StrCpy $R2 "$R1" 1
	StrCmp "$R2" " " TrimLeft
	StrCmp "$R2" "$\r" TrimLeft
	StrCmp "$R2" "$\n" TrimLeft
	StrCmp "$R2" "$\t" TrimLeft
	GoTo Loop2
TrimLeft:
	StrCpy $R1 "$R1" "" 1
	Goto Loop
Loop2:
	StrCpy $R2 "$R1" 1 -1
	StrCmp "$R2" " " TrimRight
	StrCmp "$R2" "$\r" TrimRight
	StrCmp "$R2" "$\n" TrimRight
	StrCmp "$R2" "$\t" TrimRight
	GoTo Done
TrimRight:
	StrCpy $R1 "$R1" -1
	Goto Loop2
Done:
	Pop $R2
	Exch $R1
FunctionEnd