tum 1 year ago
parent
commit
bada0a1500
7 changed files with 766 additions and 23 deletions
  1. 1 0
      .node-version
  2. 1 0
      .python-version
  3. 28 10
      app/coi/settings.py
  4. 16 10
      app/core/models.py
  5. 1 1
      app/templates/base.html
  6. 717 0
      install.ps1
  7. 2 2
      requirements.txt

+ 1 - 0
.node-version

@@ -0,0 +1 @@
1
+v16.20.2

+ 1 - 0
.python-version

@@ -0,0 +1 @@
1
+3.8.10

+ 28 - 10
app/coi/settings.py

@@ -95,35 +95,53 @@ if DJANGO_ENV == "dev":
95 95
     DB_PASSWORD = os.environ.get('DB_PASSWORD', '')
96 96
     DB_HOST =  os.environ.get('DB_HOST', 'db')
97 97
     DB_PORT = os.environ.get('DB_PORT', '1433')
98
+    DB_DRIVER = 'ODBC Driver 18 for SQL Server'
99
+    DB_ENGINE = 'mssql'
100
+
101
+    DB2_USER =  os.environ.get('DB_USER', 'sa')
102
+    DB2_PASSWORD = os.environ.get('DB_PASSWORD', '')
103
+    DB2_HOST =  os.environ.get('DB_HOST', 'db')
104
+    DB2_PORT = os.environ.get('DB_PORT', '1433')
105
+    DB2_DRIVER = 'ODBC Driver 18 for SQL Server'
106
+    DB2_ENGINE = 'mssql'
98 107
 else:
99 108
     DB_NAME = "coi_db"
100 109
     DB_USER =  "user1"
101 110
     DB_PASSWORD = "1234"
102
-    DB_HOST =  "192.168.0.253"
111
+    DB_HOST =  "localhost\SQLEXPRESS"
103 112
     DB_PORT = '1433'
113
+    DB_DRIVER = 'ODBC Driver 17 for SQL Server'
114
+    DB_ENGINE = 'mssql'
115
+
116
+    DB2_USER =  "user1"
117
+    DB2_PASSWORD = "1234"
118
+    DB2_HOST =  "192.168.0.253"
119
+    DB2_PORT = '1433'
120
+    DB2_DRIVER = 'ODBC Driver 17 for SQL Server'
121
+    DB2_ENGINE = 'mssql'
104 122
 
105 123
 DATABASES = {
106 124
     'default': {
107
-        'ENGINE': 'mssql',
125
+        'ENGINE': DB_ENGINE,
108 126
         'NAME': DB_NAME,
109 127
         'USER': DB_USER,
110 128
         'PASSWORD': DB_PASSWORD,
111 129
         'HOST': DB_HOST,
112
-        'PORT': DB_PORT,
130
+        #'PORT': DB_PORT,
113 131
         'OPTIONS': {
114
-            'driver': 'ODBC Driver 18 for SQL Server',
132
+            'driver': DB_DRIVER,
115 133
             'extra_params':  'Encrypt=no',
116 134
         },
117 135
     },
118 136
     'OB2011DB': {
119
-        'ENGINE': 'mssql',
137
+        'ENGINE': DB2_ENGINE,
120 138
         'NAME': 'OB2011DB',
121
-        'USER': DB_USER,
122
-        'PASSWORD': DB_PASSWORD,
123
-        'HOST': DB_HOST,
124
-        'PORT': DB_PORT,
139
+        'USER': DB2_USER,
140
+        'PASSWORD': DB2_PASSWORD,
141
+        'HOST': DB2_HOST,
142
+        #'PORT': DB2_PORT,
125 143
         'OPTIONS': {
126
-            'driver': 'ODBC Driver 18 for SQL Server',
144
+            'driver': DB2_DRIVER,
127 145
             'extra_params':  'Encrypt=no',
128 146
         },
129 147
     },

+ 16 - 10
app/core/models.py

@@ -20,7 +20,7 @@ class Report(models.Model):
20 20
 
21 21
 class MgMasterView(models.Model):
22 22
     # ProcessControl.dbo.[Q-PRO-DATA]
23
-    PRO0 = models.CharField(max_length=255, null=True)
23
+    PRO0 = models.CharField(primary_key=True,max_length=255, null=False)
24 24
     PRO1 = models.CharField(max_length=255, null=True)
25 25
     PRO1C = models.CharField(max_length=255, null=True)
26 26
     PRO2 = models.CharField(max_length=255, null=True)
@@ -41,7 +41,7 @@ class MgMasterView(models.Model):
41 41
     PRO27 = models.CharField(max_length=255, null=True)
42 42
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
43 43
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
44
-    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
44
+    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
45 45
     PRO4 = models.CharField(max_length=255, null=True)
46 46
     
47 47
     # dbo.[MG-MAS-1]
@@ -96,11 +96,13 @@ class MgMasterView(models.Model):
96 96
 
97 97
     class Meta:
98 98
         managed = False
99
-        db_table = 'MgMasterView_Full_Mockup_Data'
99
+        db_table = 'mg_master_view'
100
+        app_label = "legacy"
101
+        #db_table = 'MgMasterView_Full_Mockup_Data'
100 102
 
101 103
 class VMasterView(models.Model):
102 104
     # Fields from ProcessControl.dbo.[Q-PRO-DATA]
103
-    PRO0 = models.CharField(max_length=255, null=True)
105
+    PRO0 = models.CharField(primary_key=True, max_length=255, null=False)
104 106
     PRO1 = models.CharField(max_length=255, null=True)
105 107
     PRO1C = models.CharField(max_length=255, null=True)
106 108
     PRO2 = models.CharField(max_length=255, null=True)
@@ -122,7 +124,7 @@ class VMasterView(models.Model):
122 124
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
123 125
     PRO6 = models.CharField(max_length=255, null=True)
124 126
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
125
-    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
127
+    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
126 128
     PRO4 = models.CharField(max_length=255, null=True)
127 129
     
128 130
     # Fields from dbo.[V-MAS-1]
@@ -178,7 +180,9 @@ class VMasterView(models.Model):
178 180
 
179 181
     class Meta:
180 182
         managed = False
181
-        db_table = 'VMasterView_Full_Mockup_Data'
183
+        #db_table = 'VMasterView_Full_Mockup_Data'
184
+        db_table = 'v_master_view'
185
+        app_label = "legacy"
182 186
 
183 187
 
184 188
 class VwRotateLog(models.Model):
@@ -218,7 +222,7 @@ class VwRotateResult(models.Model):
218 222
 
219 223
 class BelMasterView(models.Model):
220 224
     # Fields from ProcessControl.dbo.[Q-PRO-DATA]
221
-    PRO0 = models.CharField(max_length=255, null=True)
225
+    PRO0 = models.CharField(primary_key=True, max_length=255, null=False)
222 226
     PRO1 = models.CharField(max_length=255, null=True)
223 227
     PRO1C = models.CharField(max_length=255, null=True)
224 228
     PRO2 = models.CharField(max_length=255, null=True)
@@ -240,7 +244,7 @@ class BelMasterView(models.Model):
240 244
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
241 245
     PRO6 = models.CharField(max_length=255, null=True)
242 246
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
243
-    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
247
+    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
244 248
     PRO4 = models.CharField(max_length=255, null=True)
245 249
     
246 250
     # Fields from dbo.[BEL-MAS-1]
@@ -295,11 +299,12 @@ class BelMasterView(models.Model):
295 299
 
296 300
     class Meta:
297 301
         managed = False  # This model corresponds to a database view
302
+        app_label = "legacy"
298 303
         db_table = 'bel_master_view'  # Name of the database view
299 304
 
300 305
 class EMasterView(models.Model):
301 306
     # Fields from ProcessControl.dbo.[Q-PRO-DATA]
302
-    PRO0 = models.CharField(max_length=255, null=True)
307
+    PRO0 = models.CharField(primary_key=True, max_length=255, null=False)
303 308
     PRO1 = models.CharField(max_length=255, null=True)
304 309
     PRO1C = models.CharField(max_length=255, null=True)
305 310
     PRO2 = models.CharField(max_length=255, null=True)
@@ -321,7 +326,7 @@ class EMasterView(models.Model):
321 326
     P2 = models.CharField(max_length=255, null=True)  # PRO-P2
322 327
     PRO6 = models.CharField(max_length=255, null=True)
323 328
     SPEED = models.CharField(max_length=255, null=True)  # PRO-SPEED
324
-    PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
329
+    #PRO_TOOL = models.CharField(max_length=255, null=True)  # PRO-TOOL
325 330
     PRO4 = models.CharField(max_length=255, null=True)
326 331
     
327 332
     # Fields from dbo.[E-MAS-1]
@@ -376,6 +381,7 @@ class EMasterView(models.Model):
376 381
 
377 382
     class Meta:
378 383
         managed = False  # This model corresponds to a database view
384
+        app_label = "legacy"
379 385
         db_table = 'e_master_view'  # Name of the database view
380 386
 
381 387
 class AllProductAverageObMinMaxView(models.Model):

+ 1 - 1
app/templates/base.html

@@ -32,7 +32,7 @@
32 32
                     </button>
33 33
                     <a href="/" class="flex items-center ml-2">
34 34
                         <img src="https://flowbite.com/docs/images/logo.svg" class="h-8 mr-3" alt="Logo" />
35
-                        <span class="self-center text-xl font-semibold dark:text-white">My App</span>
35
+                        <span class="self-center text-xl font-semibold dark:text-white">MGT COI</span>
36 36
                     </a>
37 37
                 </div>
38 38
                 <div class="flex items-center space-x-4">

+ 717 - 0
install.ps1

@@ -0,0 +1,717 @@
1
+# Issue Tracker: https://github.com/ScoopInstaller/Install/issues
2
+# Unlicense License:
3
+#
4
+# This is free and unencumbered software released into the public domain.
5
+#
6
+# Anyone is free to copy, modify, publish, use, compile, sell, or
7
+# distribute this software, either in source code form or as a compiled
8
+# binary, for any purpose, commercial or non-commercial, and by any
9
+# means.
10
+#
11
+# In jurisdictions that recognize copyright laws, the author or authors
12
+# of this software dedicate any and all copyright interest in the
13
+# software to the public domain. We make this dedication for the benefit
14
+# of the public at large and to the detriment of our heirs and
15
+# successors. We intend this dedication to be an overt act of
16
+# relinquishment in perpetuity of all present and future rights to this
17
+# software under copyright law.
18
+#
19
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+# OTHER DEALINGS IN THE SOFTWARE.
26
+#
27
+# For more information, please refer to <http://unlicense.org/>
28
+
29
+<#
30
+.SYNOPSIS
31
+    Scoop installer.
32
+.DESCRIPTION
33
+    The installer of Scoop. For details please check the website and wiki.
34
+.PARAMETER ScoopDir
35
+    Specifies Scoop root path.
36
+    If not specified, Scoop will be installed to '$env:USERPROFILE\scoop'.
37
+.PARAMETER ScoopGlobalDir
38
+    Specifies directory to store global apps.
39
+    If not specified, global apps will be installed to '$env:ProgramData\scoop'.
40
+.PARAMETER ScoopCacheDir
41
+    Specifies cache directory.
42
+    If not specified, caches will be downloaded to '$ScoopDir\cache'.
43
+.PARAMETER NoProxy
44
+    Bypass system proxy during the installation.
45
+.PARAMETER Proxy
46
+    Specifies proxy to use during the installation.
47
+.PARAMETER ProxyCredential
48
+    Specifies credential for the given proxy.
49
+.PARAMETER ProxyUseDefaultCredentials
50
+    Use the credentials of the current user for the proxy server that is specified by the -Proxy parameter.
51
+.PARAMETER RunAsAdmin
52
+    Force to run the installer as administrator.
53
+.LINK
54
+    https://scoop.sh
55
+.LINK
56
+    https://github.com/ScoopInstaller/Scoop/wiki
57
+#>
58
+param(
59
+    [String] $ScoopDir,
60
+    [String] $ScoopGlobalDir,
61
+    [String] $ScoopCacheDir,
62
+    [Switch] $NoProxy,
63
+    [Uri] $Proxy,
64
+    [System.Management.Automation.PSCredential] $ProxyCredential,
65
+    [Switch] $ProxyUseDefaultCredentials,
66
+    [Switch] $RunAsAdmin
67
+)
68
+
69
+# Disable StrictMode in this script
70
+Set-StrictMode -Off
71
+
72
+function Write-InstallInfo {
73
+    param(
74
+        [Parameter(Mandatory = $True, Position = 0)]
75
+        [String] $String,
76
+        [Parameter(Mandatory = $False, Position = 1)]
77
+        [System.ConsoleColor] $ForegroundColor = $host.UI.RawUI.ForegroundColor
78
+    )
79
+
80
+    $backup = $host.UI.RawUI.ForegroundColor
81
+
82
+    if ($ForegroundColor -ne $host.UI.RawUI.ForegroundColor) {
83
+        $host.UI.RawUI.ForegroundColor = $ForegroundColor
84
+    }
85
+
86
+    Write-Output "$String"
87
+
88
+    $host.UI.RawUI.ForegroundColor = $backup
89
+}
90
+
91
+function Deny-Install {
92
+    param(
93
+        [String] $message,
94
+        [Int] $errorCode = 1
95
+    )
96
+
97
+    Write-InstallInfo -String $message -ForegroundColor DarkRed
98
+    Write-InstallInfo 'Abort.'
99
+
100
+    # Don't abort if invoked with iex that would close the PS session
101
+    if ($IS_EXECUTED_FROM_IEX) {
102
+        break
103
+    } else {
104
+        exit $errorCode
105
+    }
106
+}
107
+
108
+function Test-LanguageMode {
109
+    if ($ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage') {
110
+        Write-Output 'Scoop requires PowerShell FullLanguage mode to run, current PowerShell environment is restricted.'
111
+        Write-Output 'Abort.'
112
+
113
+        if ($IS_EXECUTED_FROM_IEX) {
114
+            break
115
+        } else {
116
+            exit $errorCode
117
+        }
118
+    }
119
+}
120
+
121
+function Test-ValidateParameter {
122
+    if ($null -eq $Proxy -and ($null -ne $ProxyCredential -or $ProxyUseDefaultCredentials)) {
123
+        Deny-Install 'Provide a valid proxy URI for the -Proxy parameter when using the -ProxyCredential or -ProxyUseDefaultCredentials.'
124
+    }
125
+
126
+    if ($ProxyUseDefaultCredentials -and $null -ne $ProxyCredential) {
127
+        Deny-Install "ProxyUseDefaultCredentials is conflict with ProxyCredential. Don't use the -ProxyCredential and -ProxyUseDefaultCredentials together."
128
+    }
129
+}
130
+
131
+function Test-IsAdministrator {
132
+    return ([Security.Principal.WindowsPrincipal]`
133
+            [Security.Principal.WindowsIdentity]::GetCurrent()`
134
+    ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
135
+}
136
+
137
+function Test-Prerequisite {
138
+    # Scoop requires PowerShell 5 at least
139
+    if (($PSVersionTable.PSVersion.Major) -lt 5) {
140
+        Deny-Install 'PowerShell 5 or later is required to run Scoop. Go to https://microsoft.com/powershell to get the latest version of PowerShell.'
141
+    }
142
+
143
+    # Scoop requires TLS 1.2 SecurityProtocol, which exists in .NET Framework 4.5+
144
+    if ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -notcontains 'Tls12') {
145
+        Deny-Install 'Scoop requires .NET Framework 4.5+ to work. Go to https://microsoft.com/net/download to get the latest version of .NET Framework.'
146
+    }
147
+
148
+    # Ensure Robocopy.exe is accessible
149
+    if (!(Test-CommandAvailable('robocopy'))) {
150
+        Deny-Install "Scoop requires 'C:\Windows\System32\Robocopy.exe' to work. Please make sure 'C:\Windows\System32' is in your PATH."
151
+    }
152
+
153
+    # Detect if RunAsAdministrator, there is no need to run as administrator when installing Scoop
154
+    if (!$RunAsAdmin -and (Test-IsAdministrator)) {
155
+        # Exception: Windows Sandbox, GitHub Actions CI
156
+        $exception = ($env:USERNAME -eq 'WDAGUtilityAccount') -or ($env:GITHUB_ACTIONS -eq 'true' -and $env:CI -eq 'true')
157
+        if (!$exception) {
158
+            Deny-Install 'Running the installer as administrator is disabled by default, see https://github.com/ScoopInstaller/Install#for-admin for details.'
159
+        }
160
+    }
161
+
162
+    # Show notification to change execution policy
163
+    $allowedExecutionPolicy = @('Unrestricted', 'RemoteSigned', 'ByPass')
164
+    if ((Get-ExecutionPolicy).ToString() -notin $allowedExecutionPolicy) {
165
+        Deny-Install "PowerShell requires an execution policy in [$($allowedExecutionPolicy -join ', ')] to run Scoop. For example, to set the execution policy to 'RemoteSigned' please run 'Set-ExecutionPolicy RemoteSigned -Scope CurrentUser'."
166
+    }
167
+
168
+    # Test if scoop is installed, by checking if scoop command exists.
169
+    if (Test-CommandAvailable('scoop')) {
170
+        Deny-Install "Scoop is already installed. Run 'scoop update' to get the latest version."
171
+    }
172
+}
173
+
174
+function Optimize-SecurityProtocol {
175
+    # .NET Framework 4.7+ has a default security protocol called 'SystemDefault',
176
+    # which allows the operating system to choose the best protocol to use.
177
+    # If SecurityProtocolType contains 'SystemDefault' (means .NET4.7+ detected)
178
+    # and the value of SecurityProtocol is 'SystemDefault', just do nothing on SecurityProtocol,
179
+    # 'SystemDefault' will use TLS 1.2 if the webrequest requires.
180
+    $isNewerNetFramework = ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -contains 'SystemDefault')
181
+    $isSystemDefault = ([System.Net.ServicePointManager]::SecurityProtocol.Equals([System.Net.SecurityProtocolType]::SystemDefault))
182
+
183
+    # If not, change it to support TLS 1.2
184
+    if (!($isNewerNetFramework -and $isSystemDefault)) {
185
+        # Set to TLS 1.2 (3072), then TLS 1.1 (768), and TLS 1.0 (192). Ssl3 has been superseded,
186
+        # https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype?view=netframework-4.5
187
+        [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192
188
+        Write-Verbose 'SecurityProtocol has been updated to support TLS 1.2'
189
+    }
190
+}
191
+
192
+function Get-Downloader {
193
+    $downloadSession = New-Object System.Net.WebClient
194
+
195
+    # Set proxy to null if NoProxy is specificed
196
+    if ($NoProxy) {
197
+        $downloadSession.Proxy = $null
198
+    } elseif ($Proxy) {
199
+        # Prepend protocol if not provided
200
+        if (!$Proxy.IsAbsoluteUri) {
201
+            $Proxy = New-Object System.Uri('http://' + $Proxy.OriginalString)
202
+        }
203
+
204
+        $Proxy = New-Object System.Net.WebProxy($Proxy)
205
+
206
+        if ($null -ne $ProxyCredential) {
207
+            $Proxy.Credentials = $ProxyCredential.GetNetworkCredential()
208
+        } elseif ($ProxyUseDefaultCredentials) {
209
+            $Proxy.UseDefaultCredentials = $true
210
+        }
211
+
212
+        $downloadSession.Proxy = $Proxy
213
+    }
214
+
215
+    return $downloadSession
216
+}
217
+
218
+function Test-isFileLocked {
219
+    param(
220
+        [String] $path
221
+    )
222
+
223
+    $file = New-Object System.IO.FileInfo $path
224
+
225
+    if (!(Test-Path $path)) {
226
+        return $false
227
+    }
228
+
229
+    try {
230
+        $stream = $file.Open(
231
+            [System.IO.FileMode]::Open,
232
+            [System.IO.FileAccess]::ReadWrite,
233
+            [System.IO.FileShare]::None
234
+        )
235
+        if ($stream) {
236
+            $stream.Close()
237
+        }
238
+        return $false
239
+    } catch {
240
+        # The file is locked by a process.
241
+        return $true
242
+    }
243
+}
244
+
245
+function Expand-ZipArchive {
246
+    param(
247
+        [String] $path,
248
+        [String] $to
249
+    )
250
+
251
+    if (!(Test-Path $path)) {
252
+        Deny-Install "Unzip failed: can't find $path to unzip."
253
+    }
254
+
255
+    # Check if the zip file is locked, by antivirus software for example
256
+    $retries = 0
257
+    while ($retries -le 10) {
258
+        if ($retries -eq 10) {
259
+            Deny-Install "Unzip failed: can't unzip because a process is locking the file."
260
+        }
261
+        if (Test-isFileLocked $path) {
262
+            Write-InstallInfo "Waiting for $path to be unlocked by another process... ($retries/10)"
263
+            $retries++
264
+            Start-Sleep -Seconds 2
265
+        } else {
266
+            break
267
+        }
268
+    }
269
+
270
+    # Workaround to suspend Expand-Archive verbose output,
271
+    # upstream issue: https://github.com/PowerShell/Microsoft.PowerShell.Archive/issues/98
272
+    $oldVerbosePreference = $VerbosePreference
273
+    $global:VerbosePreference = 'SilentlyContinue'
274
+
275
+    # Disable progress bar to gain performance
276
+    $oldProgressPreference = $ProgressPreference
277
+    $global:ProgressPreference = 'SilentlyContinue'
278
+
279
+    # PowerShell 5+: use Expand-Archive to extract zip files
280
+    Microsoft.PowerShell.Archive\Expand-Archive -Path $path -DestinationPath $to -Force
281
+    $global:VerbosePreference = $oldVerbosePreference
282
+    $global:ProgressPreference = $oldProgressPreference
283
+}
284
+
285
+function Out-UTF8File {
286
+    param(
287
+        [Parameter(Mandatory = $True, Position = 0)]
288
+        [Alias('Path')]
289
+        [String] $FilePath,
290
+        [Switch] $Append,
291
+        [Switch] $NoNewLine,
292
+        [Parameter(ValueFromPipeline = $True)]
293
+        [PSObject] $InputObject
294
+    )
295
+    process {
296
+        if ($Append) {
297
+            [System.IO.File]::AppendAllText($FilePath, $InputObject)
298
+        } else {
299
+            if (!$NoNewLine) {
300
+                # Ref: https://stackoverflow.com/questions/5596982
301
+                # Performance Note: `WriteAllLines` throttles memory usage while
302
+                # `WriteAllText` needs to keep the complete string in memory.
303
+                [System.IO.File]::WriteAllLines($FilePath, $InputObject)
304
+            } else {
305
+                # However `WriteAllText` does not add ending newline.
306
+                [System.IO.File]::WriteAllText($FilePath, $InputObject)
307
+            }
308
+        }
309
+    }
310
+}
311
+
312
+function Import-ScoopShim {
313
+    Write-InstallInfo 'Creating shim...'
314
+    # The scoop executable
315
+    $path = "$SCOOP_APP_DIR\bin\scoop.ps1"
316
+
317
+    if (!(Test-Path $SCOOP_SHIMS_DIR)) {
318
+        New-Item -Type Directory $SCOOP_SHIMS_DIR | Out-Null
319
+    }
320
+
321
+    # The scoop shim
322
+    $shim = "$SCOOP_SHIMS_DIR\scoop"
323
+
324
+    # Convert to relative path
325
+    Push-Location $SCOOP_SHIMS_DIR
326
+    $relativePath = Resolve-Path -Relative $path
327
+    Pop-Location
328
+    $absolutePath = Resolve-Path $path
329
+
330
+    # if $path points to another drive resolve-path prepends .\ which could break shims
331
+    $ps1text = if ($relativePath -match '^(\.\\)?\w:.*$') {
332
+        @(
333
+            "# $absolutePath",
334
+            "`$path = `"$path`"",
335
+            "if (`$MyInvocation.ExpectingInput) { `$input | & `$path $arg @args } else { & `$path $arg @args }",
336
+            "exit `$LASTEXITCODE"
337
+        )
338
+    } else {
339
+        @(
340
+            "# $absolutePath",
341
+            "`$path = Join-Path `$PSScriptRoot `"$relativePath`"",
342
+            "if (`$MyInvocation.ExpectingInput) { `$input | & `$path $arg @args } else { & `$path $arg @args }",
343
+            "exit `$LASTEXITCODE"
344
+        )
345
+    }
346
+    $ps1text -join "`r`n" | Out-UTF8File "$shim.ps1"
347
+
348
+    # make ps1 accessible from cmd.exe
349
+    @(
350
+        "@rem $absolutePath",
351
+        '@echo off',
352
+        'setlocal enabledelayedexpansion',
353
+        'set args=%*',
354
+        ':: replace problem characters in arguments',
355
+        "set args=%args:`"='%",
356
+        "set args=%args:(=``(%",
357
+        "set args=%args:)=``)%",
358
+        "set invalid=`"='",
359
+        'if !args! == !invalid! ( set args= )',
360
+        'where /q pwsh.exe',
361
+        'if %errorlevel% equ 0 (',
362
+        "    pwsh -noprofile -ex unrestricted -file `"$absolutePath`" $arg %args%",
363
+        ') else (',
364
+        "    powershell -noprofile -ex unrestricted -file `"$absolutePath`" $arg %args%",
365
+        ')'
366
+    ) -join "`r`n" | Out-UTF8File "$shim.cmd"
367
+
368
+    @(
369
+        '#!/bin/sh',
370
+        "# $absolutePath",
371
+        'if command -v pwsh.exe > /dev/null 2>&1; then',
372
+        "    pwsh.exe -noprofile -ex unrestricted -file `"$absolutePath`" $arg `"$@`"",
373
+        'else',
374
+        "    powershell.exe -noprofile -ex unrestricted -file `"$absolutePath`" $arg `"$@`"",
375
+        'fi'
376
+    ) -join "`n" | Out-UTF8File $shim -NoNewLine
377
+}
378
+
379
+function Get-Env {
380
+    param(
381
+        [String] $name,
382
+        [Switch] $global
383
+    )
384
+
385
+    $RegisterKey = if ($global) {
386
+        Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
387
+    } else {
388
+        Get-Item -Path 'HKCU:'
389
+    }
390
+
391
+    $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment')
392
+    $RegistryValueOption = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
393
+    $EnvRegisterKey.GetValue($name, $null, $RegistryValueOption)
394
+}
395
+
396
+function Publish-Env {
397
+    if (-not ('Win32.NativeMethods' -as [Type])) {
398
+        Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @'
399
+[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
400
+public static extern IntPtr SendMessageTimeout(
401
+    IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
402
+    uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
403
+'@
404
+    }
405
+
406
+    $HWND_BROADCAST = [IntPtr] 0xffff
407
+    $WM_SETTINGCHANGE = 0x1a
408
+    $result = [UIntPtr]::Zero
409
+
410
+    [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST,
411
+        $WM_SETTINGCHANGE,
412
+        [UIntPtr]::Zero,
413
+        'Environment',
414
+        2,
415
+        5000,
416
+        [ref] $result
417
+    ) | Out-Null
418
+}
419
+
420
+function Write-Env {
421
+    param(
422
+        [String] $name,
423
+        [String] $val,
424
+        [Switch] $global
425
+    )
426
+
427
+    $RegisterKey = if ($global) {
428
+        Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
429
+    } else {
430
+        Get-Item -Path 'HKCU:'
431
+    }
432
+
433
+    $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment', $true)
434
+    if ($val -eq $null) {
435
+        $EnvRegisterKey.DeleteValue($name)
436
+    } else {
437
+        $RegistryValueKind = if ($val.Contains('%')) {
438
+            [Microsoft.Win32.RegistryValueKind]::ExpandString
439
+        } elseif ($EnvRegisterKey.GetValue($name)) {
440
+            $EnvRegisterKey.GetValueKind($name)
441
+        } else {
442
+            [Microsoft.Win32.RegistryValueKind]::String
443
+        }
444
+        $EnvRegisterKey.SetValue($name, $val, $RegistryValueKind)
445
+    }
446
+    Publish-Env
447
+}
448
+
449
+function Add-ShimsDirToPath {
450
+    # Get $env:PATH of current user
451
+    $userEnvPath = Get-Env 'PATH'
452
+
453
+    if ($userEnvPath -notmatch [Regex]::Escape($SCOOP_SHIMS_DIR)) {
454
+        $h = (Get-PSProvider 'FileSystem').Home
455
+        if (!$h.EndsWith('\')) {
456
+            $h += '\'
457
+        }
458
+
459
+        if (!($h -eq '\')) {
460
+            $friendlyPath = "$SCOOP_SHIMS_DIR" -Replace ([Regex]::Escape($h)), '~\'
461
+            Write-InstallInfo "Adding $friendlyPath to your path."
462
+        } else {
463
+            Write-InstallInfo "Adding $SCOOP_SHIMS_DIR to your path."
464
+        }
465
+
466
+        # For future sessions
467
+        Write-Env 'PATH' "$SCOOP_SHIMS_DIR;$userEnvPath"
468
+        # For current session
469
+        $env:PATH = "$SCOOP_SHIMS_DIR;$env:PATH"
470
+    }
471
+}
472
+
473
+function Use-Config {
474
+    if (!(Test-Path $SCOOP_CONFIG_FILE)) {
475
+        return $null
476
+    }
477
+
478
+    try {
479
+        return (Get-Content $SCOOP_CONFIG_FILE -Raw | ConvertFrom-Json -ErrorAction Stop)
480
+    } catch {
481
+        Deny-Install "ERROR loading $SCOOP_CONFIG_FILE`: $($_.Exception.Message)"
482
+    }
483
+}
484
+
485
+function Add-Config {
486
+    param (
487
+        [Parameter(Mandatory = $True, Position = 0)]
488
+        [String] $Name,
489
+        [Parameter(Mandatory = $True, Position = 1)]
490
+        [String] $Value
491
+    )
492
+
493
+    $scoopConfig = Use-Config
494
+
495
+    if ($scoopConfig -is [System.Management.Automation.PSObject]) {
496
+        if ($Value -eq [bool]::TrueString -or $Value -eq [bool]::FalseString) {
497
+            $Value = [System.Convert]::ToBoolean($Value)
498
+        }
499
+        if ($null -eq $scoopConfig.$Name) {
500
+            $scoopConfig | Add-Member -MemberType NoteProperty -Name $Name -Value $Value
501
+        } else {
502
+            $scoopConfig.$Name = $Value
503
+        }
504
+    } else {
505
+        $baseDir = Split-Path -Path $SCOOP_CONFIG_FILE
506
+        if (!(Test-Path $baseDir)) {
507
+            New-Item -Type Directory $baseDir | Out-Null
508
+        }
509
+
510
+        $scoopConfig = New-Object PSObject
511
+        $scoopConfig | Add-Member -MemberType NoteProperty -Name $Name -Value $Value
512
+    }
513
+
514
+    if ($null -eq $Value) {
515
+        $scoopConfig.PSObject.Properties.Remove($Name)
516
+    }
517
+
518
+    ConvertTo-Json $scoopConfig | Set-Content $SCOOP_CONFIG_FILE -Encoding ASCII
519
+    return $scoopConfig
520
+}
521
+
522
+function Add-DefaultConfig {
523
+    # If user-level SCOOP env not defined, save to root_path
524
+    if (!(Get-Env 'SCOOP')) {
525
+        if ($SCOOP_DIR -ne "$env:USERPROFILE\scoop") {
526
+            Write-Verbose "Adding config root_path: $SCOOP_DIR"
527
+            Add-Config -Name 'root_path' -Value $SCOOP_DIR | Out-Null
528
+        }
529
+    }
530
+
531
+    # Use system SCOOP_GLOBAL, or set system SCOOP_GLOBAL
532
+    # with $env:SCOOP_GLOBAL if RunAsAdmin, otherwise save to global_path
533
+    if (!(Get-Env 'SCOOP_GLOBAL' -global)) {
534
+        if ((Test-IsAdministrator) -and $env:SCOOP_GLOBAL) {
535
+            Write-Verbose "Setting System Environment Variable SCOOP_GLOBAL: $env:SCOOP_GLOBAL"
536
+            [Environment]::SetEnvironmentVariable('SCOOP_GLOBAL', $env:SCOOP_GLOBAL, 'Machine')
537
+        } else {
538
+            if ($SCOOP_GLOBAL_DIR -ne "$env:ProgramData\scoop") {
539
+                Write-Verbose "Adding config global_path: $SCOOP_GLOBAL_DIR"
540
+                Add-Config -Name 'global_path' -Value $SCOOP_GLOBAL_DIR | Out-Null
541
+            }
542
+        }
543
+    }
544
+
545
+    # Use system SCOOP_CACHE, or set system SCOOP_CACHE
546
+    # with $env:SCOOP_CACHE if RunAsAdmin, otherwise save to cache_path
547
+    if (!(Get-Env 'SCOOP_CACHE' -global)) {
548
+        if ((Test-IsAdministrator) -and $env:SCOOP_CACHE) {
549
+            Write-Verbose "Setting System Environment Variable SCOOP_CACHE: $env:SCOOP_CACHE"
550
+            [Environment]::SetEnvironmentVariable('SCOOP_CACHE', $env:SCOOP_CACHE, 'Machine')
551
+        } else {
552
+            if ($SCOOP_CACHE_DIR -ne "$SCOOP_DIR\cache") {
553
+                Write-Verbose "Adding config cache_path: $SCOOP_CACHE_DIR"
554
+                Add-Config -Name 'cache_path' -Value $SCOOP_CACHE_DIR | Out-Null
555
+            }
556
+        }
557
+    }
558
+
559
+    # save current datatime to last_update
560
+    Add-Config -Name 'last_update' -Value ([System.DateTime]::Now.ToString('o')) | Out-Null
561
+}
562
+
563
+function Test-CommandAvailable {
564
+    param (
565
+        [Parameter(Mandatory = $True, Position = 0)]
566
+        [String] $Command
567
+    )
568
+    return [Boolean](Get-Command $Command -ErrorAction SilentlyContinue)
569
+}
570
+
571
+function Install-Scoop {
572
+    Write-InstallInfo 'Initializing...'
573
+    # Validate install parameters
574
+    Test-ValidateParameter
575
+    # Check prerequisites
576
+    Test-Prerequisite
577
+    # Enable TLS 1.2
578
+    Optimize-SecurityProtocol
579
+
580
+    # Download scoop from GitHub
581
+    Write-InstallInfo 'Downloading...'
582
+    $downloader = Get-Downloader
583
+    [bool]$downloadZipsRequired = $True
584
+
585
+    if (Test-CommandAvailable('git')) {
586
+        $old_https = $env:HTTPS_PROXY
587
+        $old_http = $env:HTTP_PROXY
588
+        try {
589
+            if ($downloader.Proxy) {
590
+                #define env vars for git when behind a proxy
591
+                $Env:HTTP_PROXY = $downloader.Proxy.Address
592
+                $Env:HTTPS_PROXY = $downloader.Proxy.Address
593
+            }
594
+            Write-Verbose "Cloning $SCOOP_PACKAGE_GIT_REPO to $SCOOP_APP_DIR"
595
+            git clone -q $SCOOP_PACKAGE_GIT_REPO $SCOOP_APP_DIR
596
+            if (-Not $?) {
597
+                throw 'Cloning failed. Falling back to downloading zip files.'
598
+            }
599
+            Write-Verbose "Cloning $SCOOP_MAIN_BUCKET_GIT_REPO to $SCOOP_MAIN_BUCKET_DIR"
600
+            git clone -q $SCOOP_MAIN_BUCKET_GIT_REPO $SCOOP_MAIN_BUCKET_DIR
601
+            if (-Not $?) {
602
+                throw 'Cloning failed. Falling back to downloading zip files.'
603
+            }
604
+            $downloadZipsRequired = $False
605
+        } catch {
606
+            Write-Warning "$($_.Exception.Message)"
607
+            $Global:LastExitCode = 0
608
+        } finally {
609
+            $env:HTTPS_PROXY = $old_https
610
+            $env:HTTP_PROXY = $old_http
611
+        }
612
+    }
613
+
614
+    if ($downloadZipsRequired) {
615
+        # 1. download scoop
616
+        $scoopZipfile = "$SCOOP_APP_DIR\scoop.zip"
617
+        if (!(Test-Path $SCOOP_APP_DIR)) {
618
+            New-Item -Type Directory $SCOOP_APP_DIR | Out-Null
619
+        }
620
+        Write-Verbose "Downloading $SCOOP_PACKAGE_REPO to $scoopZipfile"
621
+        $downloader.downloadFile($SCOOP_PACKAGE_REPO, $scoopZipfile)
622
+        # 2. download scoop main bucket
623
+        $scoopMainZipfile = "$SCOOP_MAIN_BUCKET_DIR\scoop-main.zip"
624
+        if (!(Test-Path $SCOOP_MAIN_BUCKET_DIR)) {
625
+            New-Item -Type Directory $SCOOP_MAIN_BUCKET_DIR | Out-Null
626
+        }
627
+        Write-Verbose "Downloading $SCOOP_MAIN_BUCKET_REPO to $scoopMainZipfile"
628
+        $downloader.downloadFile($SCOOP_MAIN_BUCKET_REPO, $scoopMainZipfile)
629
+
630
+        # Extract files from downloaded zip
631
+        Write-InstallInfo 'Extracting...'
632
+        # 1. extract scoop
633
+        $scoopUnzipTempDir = "$SCOOP_APP_DIR\_tmp"
634
+        Write-Verbose "Extracting $scoopZipfile to $scoopUnzipTempDir"
635
+        Expand-ZipArchive $scoopZipfile $scoopUnzipTempDir
636
+        Copy-Item "$scoopUnzipTempDir\scoop-*\*" $SCOOP_APP_DIR -Recurse -Force
637
+        # 2. extract scoop main bucket
638
+        $scoopMainUnzipTempDir = "$SCOOP_MAIN_BUCKET_DIR\_tmp"
639
+        Write-Verbose "Extracting $scoopMainZipfile to $scoopMainUnzipTempDir"
640
+        Expand-ZipArchive $scoopMainZipfile $scoopMainUnzipTempDir
641
+        Copy-Item "$scoopMainUnzipTempDir\Main-*\*" $SCOOP_MAIN_BUCKET_DIR -Recurse -Force
642
+
643
+        # Cleanup
644
+        Remove-Item $scoopUnzipTempDir -Recurse -Force
645
+        Remove-Item $scoopZipfile
646
+        Remove-Item $scoopMainUnzipTempDir -Recurse -Force
647
+        Remove-Item $scoopMainZipfile
648
+    }
649
+    # Create the scoop shim
650
+    Import-ScoopShim
651
+    # Finially ensure scoop shims is in the PATH
652
+    Add-ShimsDirToPath
653
+    # Setup initial configuration of Scoop
654
+    Add-DefaultConfig
655
+
656
+    Write-InstallInfo 'Scoop was installed successfully!' -ForegroundColor DarkGreen
657
+    Write-InstallInfo "Type 'scoop help' for instructions."
658
+}
659
+
660
+function Write-DebugInfo {
661
+    param($BoundArgs)
662
+
663
+    Write-Verbose '-------- PSBoundParameters --------'
664
+    $BoundArgs.GetEnumerator() | ForEach-Object { Write-Verbose $_ }
665
+    Write-Verbose '-------- Environment Variables --------'
666
+    Write-Verbose "`$env:USERPROFILE: $env:USERPROFILE"
667
+    Write-Verbose "`$env:ProgramData: $env:ProgramData"
668
+    Write-Verbose "`$env:SCOOP: $env:SCOOP"
669
+    Write-Verbose "`$env:SCOOP_CACHE: $SCOOP_CACHE"
670
+    Write-Verbose "`$env:SCOOP_GLOBAL: $env:SCOOP_GLOBAL"
671
+    Write-Verbose '-------- Selected Variables --------'
672
+    Write-Verbose "SCOOP_DIR: $SCOOP_DIR"
673
+    Write-Verbose "SCOOP_CACHE_DIR: $SCOOP_CACHE_DIR"
674
+    Write-Verbose "SCOOP_GLOBAL_DIR: $SCOOP_GLOBAL_DIR"
675
+    Write-Verbose "SCOOP_CONFIG_HOME: $SCOOP_CONFIG_HOME"
676
+}
677
+
678
+# Prepare variables
679
+$IS_EXECUTED_FROM_IEX = ($null -eq $MyInvocation.MyCommand.Path)
680
+
681
+# Abort when the language mode is restricted
682
+Test-LanguageMode
683
+
684
+# Scoop root directory
685
+$SCOOP_DIR = $ScoopDir, $env:SCOOP, "$env:USERPROFILE\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
686
+# Scoop global apps directory
687
+$SCOOP_GLOBAL_DIR = $ScoopGlobalDir, $env:SCOOP_GLOBAL, "$env:ProgramData\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
688
+# Scoop cache directory
689
+$SCOOP_CACHE_DIR = $ScoopCacheDir, $env:SCOOP_CACHE, "$SCOOP_DIR\cache" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
690
+# Scoop shims directory
691
+$SCOOP_SHIMS_DIR = "$SCOOP_DIR\shims"
692
+# Scoop itself directory
693
+$SCOOP_APP_DIR = "$SCOOP_DIR\apps\scoop\current"
694
+# Scoop main bucket directory
695
+$SCOOP_MAIN_BUCKET_DIR = "$SCOOP_DIR\buckets\main"
696
+# Scoop config file location
697
+$SCOOP_CONFIG_HOME = $env:XDG_CONFIG_HOME, "$env:USERPROFILE\.config" | Select-Object -First 1
698
+$SCOOP_CONFIG_FILE = "$SCOOP_CONFIG_HOME\scoop\config.json"
699
+
700
+# TODO: Use a specific version of Scoop and the main bucket
701
+$SCOOP_PACKAGE_REPO = 'https://github.com/ScoopInstaller/Scoop/archive/master.zip'
702
+$SCOOP_MAIN_BUCKET_REPO = 'https://github.com/ScoopInstaller/Main/archive/master.zip'
703
+
704
+$SCOOP_PACKAGE_GIT_REPO = 'https://github.com/ScoopInstaller/Scoop.git'
705
+$SCOOP_MAIN_BUCKET_GIT_REPO = 'https://github.com/ScoopInstaller/Main.git'
706
+
707
+# Quit if anything goes wrong
708
+$oldErrorActionPreference = $ErrorActionPreference
709
+$ErrorActionPreference = 'Stop'
710
+
711
+# Logging debug info
712
+Write-DebugInfo $PSBoundParameters
713
+# Bootstrap function
714
+Install-Scoop
715
+
716
+# Reset $ErrorActionPreference to original value
717
+$ErrorActionPreference = $oldErrorActionPreference

+ 2 - 2
requirements.txt

@@ -1,5 +1,5 @@
1
-Django
2
-mssql-django
1
+Django==4.2
2
+mssql-django==1.3
3 3
 pyodbc==4.0.39
4 4
 # For filtering and querying
5 5
 django-filter  # Simplified filtering