@openardf/radio-oracle 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +48 -0
- package/jdeploy-bundle/Radio-Oracle-jdeploy.jar +0 -0
- package/jdeploy-bundle/icon.png +0 -0
- package/jdeploy-bundle/jar-runner.jar +0 -0
- package/jdeploy-bundle/jdeploy.js +643 -0
- package/jdeploy-bundle/libs/animation-core-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/animation-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/annotation-jvm-1.9.1.jar +0 -0
- package/jdeploy-bundle/libs/annotations-23.0.0.jar +0 -0
- package/jdeploy-bundle/libs/atomicfu-jvm-0.28.0.jar +0 -0
- package/jdeploy-bundle/libs/collection-jvm-1.5.0.jar +0 -0
- package/jdeploy-bundle/libs/core-common-2.2.0.jar +0 -0
- package/jdeploy-bundle/libs/desktop-jvm-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/foundation-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/foundation-layout-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/jbr-api-1.9.0.jar +0 -0
- package/jdeploy-bundle/libs/jspecify-1.0.0.jar +0 -0
- package/jdeploy-bundle/libs/kotlin-stdlib-2.3.20.jar +0 -0
- package/jdeploy-bundle/libs/kotlinx-coroutines-core-jvm-1.9.0.jar +0 -0
- package/jdeploy-bundle/libs/kotlinx-serialization-core-jvm-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/kotlinx-serialization-json-jvm-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/lifecycle-common-jvm-2.9.4.jar +0 -0
- package/jdeploy-bundle/libs/lifecycle-runtime-compose-desktop-2.9.4.jar +0 -0
- package/jdeploy-bundle/libs/lifecycle-runtime-compose-desktop-2.9.6.jar +0 -0
- package/jdeploy-bundle/libs/lifecycle-runtime-desktop-2.9.4.jar +0 -0
- package/jdeploy-bundle/libs/lifecycle-viewmodel-desktop-2.9.4.jar +0 -0
- package/jdeploy-bundle/libs/lifecycle-viewmodel-savedstate-desktop-2.9.4.jar +0 -0
- package/jdeploy-bundle/libs/material-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/material-ripple-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/navigationevent-desktop-1.0.1.jar +0 -0
- package/jdeploy-bundle/libs/runtime-annotation-jvm-1.11.1.jar +0 -0
- package/jdeploy-bundle/libs/runtime-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/runtime-desktop-1.11.1.jar +0 -0
- package/jdeploy-bundle/libs/runtime-retain-desktop-1.11.1.jar +0 -0
- package/jdeploy-bundle/libs/runtime-saveable-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/runtime-saveable-desktop-1.11.1.jar +0 -0
- package/jdeploy-bundle/libs/savedstate-compose-desktop-1.3.6.jar +0 -0
- package/jdeploy-bundle/libs/savedstate-compose-desktop-1.4.0.jar +0 -0
- package/jdeploy-bundle/libs/savedstate-desktop-1.4.0.jar +0 -0
- package/jdeploy-bundle/libs/shared-desktop.jar +0 -0
- package/jdeploy-bundle/libs/skiko-awt-0.144.6.jar +0 -0
- package/jdeploy-bundle/libs/skiko-awt-runtime-macos-arm64-0.144.6.jar +0 -0
- package/jdeploy-bundle/libs/ui-backhandler-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-geometry-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-graphics-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-text-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-tooling-preview-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-unit-desktop-1.11.0.jar +0 -0
- package/jdeploy-bundle/libs/ui-util-desktop-1.11.0.jar +0 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pavel Kolský
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Radio-Oracle
|
|
2
|
+
|
|
3
|
+
Radio-Oracle is an Android app for managing radio orienteering events on race
|
|
4
|
+
day.
|
|
5
|
+
|
|
6
|
+
Radio-Oracle is maintained by OpenARDF and derived from the MIT-licensed
|
|
7
|
+
Radio-O-Manager project by Pavel Kolský and contributors.
|
|
8
|
+
|
|
9
|
+
## What It Does
|
|
10
|
+
|
|
11
|
+
Radio-Oracle is intended to help organizers:
|
|
12
|
+
|
|
13
|
+
1. create or import races with categories, aliases, and competitors
|
|
14
|
+
2. read SportIdent cards
|
|
15
|
+
3. calculate and review results
|
|
16
|
+
4. export results
|
|
17
|
+
5. print finish tickets
|
|
18
|
+
6. send live results
|
|
19
|
+
|
|
20
|
+
## Equipment Needed
|
|
21
|
+
|
|
22
|
+
- SportIdent BSM 7 / BSM 8 reader
|
|
23
|
+
- USB to OTG adapter
|
|
24
|
+
- Bluetooth printer for ticket printout
|
|
25
|
+
|
|
26
|
+
## Supported Competition Formats
|
|
27
|
+
|
|
28
|
+
- Classics
|
|
29
|
+
- Foxoring
|
|
30
|
+
- Orienteering
|
|
31
|
+
- Sprint
|
|
32
|
+
|
|
33
|
+
## Third Party Libraries and Resources
|
|
34
|
+
|
|
35
|
+
- **Logo** - original Radio-Oracle artwork generated for this project using Codex
|
|
36
|
+
- [SortableTableView](https://github.com/ISchwarz23/SortableTableView)
|
|
37
|
+
- [kotlin-csv](https://github.com/doyaaaaaken/kotlin-csv)
|
|
38
|
+
- [UsbSerial](https://github.com/felHR85/UsbSerial)
|
|
39
|
+
- [ESCPOS-ThermalPrinter-Android](https://github.com/DantSu/ESCPOS-ThermalPrinter-Android)
|
|
40
|
+
- [Moshi](https://github.com/square/moshi)
|
|
41
|
+
- [OkHttp](https://github.com/square/okhttp)
|
|
42
|
+
- [Markwon](https://github.com/noties/Markwon)
|
|
43
|
+
|
|
44
|
+
## Credits
|
|
45
|
+
|
|
46
|
+
- OpenARDF maintains Radio-Oracle.
|
|
47
|
+
- Radio-Oracle is derived from the MIT-licensed Radio-O-Manager project by
|
|
48
|
+
Pavel Kolský, Vojtěch Kopal, and Jakub Šrom.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var os = require('os');
|
|
5
|
+
var jdeployHomeDir = process.env.JDEPLOY_HOME || path.join(os.homedir(), '.jdeploy');
|
|
6
|
+
var jarName = "Radio-Oracle-jdeploy.jar";
|
|
7
|
+
var mainClass = "{{MAIN_CLASS}}";
|
|
8
|
+
var classPath = "{{CLASSPATH}}";
|
|
9
|
+
var port = "0";
|
|
10
|
+
var warPath = "";
|
|
11
|
+
var javaVersionString = "17";
|
|
12
|
+
var tryJavaHomeFirst = false;
|
|
13
|
+
var javafx = false;
|
|
14
|
+
var bundleType = 'jre';
|
|
15
|
+
if ('{{JAVAFX}}' === 'true') {
|
|
16
|
+
javafx = true;
|
|
17
|
+
}
|
|
18
|
+
if ('{{JDK}}' === 'true') {
|
|
19
|
+
bundleType = 'jdk';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var jdk = (bundleType === 'jdk');
|
|
23
|
+
var jdkProvider = 'zulu';
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
function njreWrap() {
|
|
27
|
+
'use strict'
|
|
28
|
+
|
|
29
|
+
const fs = require('fs')
|
|
30
|
+
const crypto = require('crypto')
|
|
31
|
+
const fetch = require('node-fetch')
|
|
32
|
+
const yauzl = require('yauzl')
|
|
33
|
+
const tar = require('tar')
|
|
34
|
+
|
|
35
|
+
function createDir (dir) {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
fs.access(dir, err => {
|
|
38
|
+
if (err && err.code === 'ENOENT') {
|
|
39
|
+
fs.mkdir(dir, err => {
|
|
40
|
+
if (err) reject(err)
|
|
41
|
+
resolve()
|
|
42
|
+
})
|
|
43
|
+
} else if (!err) resolve()
|
|
44
|
+
else reject(err)
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function download (dir, url) {
|
|
50
|
+
if (url.indexOf("?") > 0 || jdkProvider === 'zulu') {
|
|
51
|
+
var ext = ".zip";
|
|
52
|
+
switch (process.platform) {
|
|
53
|
+
case 'linux':
|
|
54
|
+
ext = ".tar.gz";
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
var destName = bundleType + ext;
|
|
58
|
+
} else {
|
|
59
|
+
destName = path.basename(url);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
createDir(dir)
|
|
64
|
+
.then(() => fetch(url))
|
|
65
|
+
.then(response => {
|
|
66
|
+
// Validate HTTP status code before writing the file
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
return reject(new Error(`HTTP ${response.status}: ${response.statusText} for ${url}`))
|
|
69
|
+
}
|
|
70
|
+
const destFile = path.join(dir, destName)
|
|
71
|
+
const destStream = fs.createWriteStream(destFile)
|
|
72
|
+
response.body.pipe(destStream).on('finish', () => resolve(destFile))
|
|
73
|
+
})
|
|
74
|
+
.catch(err => reject(err))
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function downloadAll (dir, url) {
|
|
79
|
+
return download(dir, url + '.sha256.txt').then(() => download(dir, url))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function genChecksum (file) {
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
fs.readFile(file, (err, data) => {
|
|
85
|
+
if (err) reject(err)
|
|
86
|
+
|
|
87
|
+
resolve(
|
|
88
|
+
crypto
|
|
89
|
+
.createHash('sha256')
|
|
90
|
+
.update(data)
|
|
91
|
+
.digest('hex')
|
|
92
|
+
)
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function verify (file) {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
fs.readFile(file + '.sha256.txt', 'utf-8', (err, data) => {
|
|
100
|
+
if (err) reject(err)
|
|
101
|
+
|
|
102
|
+
genChecksum(file).then(checksum => {
|
|
103
|
+
checksum === data.split(' ')[0]
|
|
104
|
+
? resolve(file)
|
|
105
|
+
: reject(new Error('File and checksum don\'t match'))
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function move (file) {
|
|
112
|
+
return new Promise((resolve, reject) => {
|
|
113
|
+
const jdeployDir = jdeployHomeDir;
|
|
114
|
+
if (!fs.existsSync(jdeployDir)) {
|
|
115
|
+
fs.mkdirSync(jdeployDir);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var jreDir = path.join(jdeployDir, bundleType);
|
|
119
|
+
if (!fs.existsSync(jreDir)) {
|
|
120
|
+
fs.mkdirSync(jreDir);
|
|
121
|
+
}
|
|
122
|
+
var vs = javaVersionString;
|
|
123
|
+
if (javafx) {
|
|
124
|
+
vs += 'fx';
|
|
125
|
+
}
|
|
126
|
+
jreDir = path.join(jreDir, vs);
|
|
127
|
+
if (!fs.existsSync(jreDir)) {
|
|
128
|
+
fs.mkdirSync(jreDir);
|
|
129
|
+
}
|
|
130
|
+
const newFile = path.join(jreDir, file.split(path.sep).slice(-1)[0])
|
|
131
|
+
//console.log("Copying file "+file+" to "+newFile);
|
|
132
|
+
fs.copyFile(file, newFile, err => {
|
|
133
|
+
if (err) reject(err)
|
|
134
|
+
|
|
135
|
+
fs.unlink(file, err => {
|
|
136
|
+
if (err) reject(err)
|
|
137
|
+
resolve(newFile)
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function extractZip (file, dir) {
|
|
144
|
+
//console.log("Extracting "+file+" to "+dir);
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
yauzl.open(file, { lazyEntries: true }, (err, zipFile) => {
|
|
147
|
+
if (err) reject(err)
|
|
148
|
+
|
|
149
|
+
zipFile.readEntry()
|
|
150
|
+
zipFile.on('entry', entry => {
|
|
151
|
+
const entryPath = path.join(dir, entry.fileName)
|
|
152
|
+
|
|
153
|
+
if (/\/$/.test(entry.fileName)) {
|
|
154
|
+
fs.mkdir(entryPath, { recursive: true }, err => {
|
|
155
|
+
if (err && err.code !== 'EEXIST') reject(err)
|
|
156
|
+
|
|
157
|
+
zipFile.readEntry()
|
|
158
|
+
})
|
|
159
|
+
} else {
|
|
160
|
+
zipFile.openReadStream(entry, (err, readStream) => {
|
|
161
|
+
if (err) reject(err)
|
|
162
|
+
|
|
163
|
+
readStream.on('end', () => {
|
|
164
|
+
zipFile.readEntry()
|
|
165
|
+
})
|
|
166
|
+
readStream.pipe(fs.createWriteStream(entryPath))
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
zipFile.once('close', () => {
|
|
171
|
+
fs.unlink(file, err => {
|
|
172
|
+
if (err) reject(err)
|
|
173
|
+
resolve(dir)
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function extractTarGz (file, dir) {
|
|
181
|
+
return tar.x({ file: file, cwd: dir }).then(() => {
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
fs.unlink(file, err => {
|
|
184
|
+
if (err) reject(err)
|
|
185
|
+
resolve(dir)
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function extract (file) {
|
|
192
|
+
var dirString = jdk? 'jdk' : 'jre';
|
|
193
|
+
|
|
194
|
+
const dir = path.join(path.dirname(file), dirString)
|
|
195
|
+
//console.log("About to extract "+file+" to "+dir);
|
|
196
|
+
return createDir(dir).then(() => {
|
|
197
|
+
return path.extname(file) === '.zip'
|
|
198
|
+
? extractZip(file, dir)
|
|
199
|
+
: extractTarGz(file, dir)
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Installs a JRE copy for the app
|
|
205
|
+
* @param {number} [version = 8] - Java Version (`8`/`9`/`10`/`11`/`12`)
|
|
206
|
+
* @param {object} [options] - Installation Options
|
|
207
|
+
* @param {string} [options.os] - Operating System (defaults to current) (`windows`/`mac`/`linux`/`solaris`/`aix`)
|
|
208
|
+
* @param {string} [options.arch] - Architecture (defaults to current) (`x64`/`x32`/`ppc64`/`s390x`/`ppc64le`/`aarch64`/`sparcv9`)
|
|
209
|
+
* @param {string} [options.openjdk_impl = hotspot] - OpenJDK Implementation (`hotspot`/`openj9`)
|
|
210
|
+
* @param {string} [options.release = latest] - Release
|
|
211
|
+
* @param {string} [options.type = jre] - Binary Type (`jre`/`jdk`)
|
|
212
|
+
* @param {string} [options.heap_size] - Heap Size (`normal`/`large`)
|
|
213
|
+
* @return Promise<string> - Resolves to the installation directory or rejects an error
|
|
214
|
+
* @example
|
|
215
|
+
* const njre = require('njre')
|
|
216
|
+
*
|
|
217
|
+
* // Use default options
|
|
218
|
+
* njre.install()
|
|
219
|
+
* .then(dir => {
|
|
220
|
+
* // Do stuff
|
|
221
|
+
* })
|
|
222
|
+
* .catch(err => {
|
|
223
|
+
* // Handle the error
|
|
224
|
+
* })
|
|
225
|
+
*
|
|
226
|
+
* // or custom ones
|
|
227
|
+
* njre.install(11, { os: 'aix', arch: 'ppc64', openjdk_impl: 'openj9' })
|
|
228
|
+
* .then(dir => {
|
|
229
|
+
* // Do stuff
|
|
230
|
+
* })
|
|
231
|
+
* .catch(err => {
|
|
232
|
+
* // Handle the error
|
|
233
|
+
* })
|
|
234
|
+
*/
|
|
235
|
+
function install (version = 11, options = {}) {
|
|
236
|
+
const { openjdk_impl = 'hotspot', release = 'latest', type = 'jre', javafx = false, provider = 'zulu' } = options
|
|
237
|
+
options = { ...options, openjdk_impl, release, type }
|
|
238
|
+
|
|
239
|
+
// Determine the architecture based on the platform and environment
|
|
240
|
+
let arch = process.arch;
|
|
241
|
+
if (arch === 'arm64' || arch === 'aarch64') {
|
|
242
|
+
arch = 'aarch64'; // For ARM-based systems, standardize on aarch64
|
|
243
|
+
} else {
|
|
244
|
+
arch = 'x64'; // Default to x64 for non-ARM systems
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (provider === 'zulu') {
|
|
248
|
+
return installZulu(version, options, arch);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let url = 'https://api.adoptopenjdk.net/v2/info/releases/openjdk' + version + '?'
|
|
252
|
+
|
|
253
|
+
if (!options.os) {
|
|
254
|
+
switch (process.platform) {
|
|
255
|
+
case 'aix':
|
|
256
|
+
options.os = 'aix'
|
|
257
|
+
break
|
|
258
|
+
case 'darwin':
|
|
259
|
+
options.os = 'mac'
|
|
260
|
+
break
|
|
261
|
+
case 'linux':
|
|
262
|
+
options.os = 'linux'
|
|
263
|
+
break
|
|
264
|
+
case 'sunos':
|
|
265
|
+
options.os = 'solaris'
|
|
266
|
+
break
|
|
267
|
+
case 'win32':
|
|
268
|
+
options.os = 'windows'
|
|
269
|
+
break
|
|
270
|
+
default:
|
|
271
|
+
return Promise.reject(new Error('Unsupported operating system'))
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!options.arch) {
|
|
276
|
+
options.arch = arch; // Use the detected architecture
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
Object.keys(options).forEach(key => { url += key + '=' + options[key] + '&' })
|
|
280
|
+
|
|
281
|
+
const tmpdir = path.join(os.tmpdir(), 'njre')
|
|
282
|
+
|
|
283
|
+
return fetch(url)
|
|
284
|
+
.then(response => response.json())
|
|
285
|
+
.then(json => downloadAll(tmpdir, json.binaries[0]['binary_link']))
|
|
286
|
+
.then(verify)
|
|
287
|
+
.then(move)
|
|
288
|
+
.then(extract)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function installZulu(version = 11, options = {}, arch) {
|
|
292
|
+
const { type = 'jre', javafx = false } = options;
|
|
293
|
+
|
|
294
|
+
// Prepare the query parameters for the request
|
|
295
|
+
let q = {
|
|
296
|
+
java_version: version,
|
|
297
|
+
ext: 'zip',
|
|
298
|
+
bundle_type: type,
|
|
299
|
+
javafx: '' + javafx,
|
|
300
|
+
arch: arch, // Use the detected architecture
|
|
301
|
+
hw_bitness: '64',
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
// Base URL for the Azul API
|
|
305
|
+
const zuluBaseURL = "https://api.azul.com/zulu/download/community/v1.0/bundles/latest/binary?";
|
|
306
|
+
|
|
307
|
+
// Determine the OS
|
|
308
|
+
if (!options.os) {
|
|
309
|
+
switch (process.platform) {
|
|
310
|
+
case 'darwin':
|
|
311
|
+
q.os = 'macos';
|
|
312
|
+
break;
|
|
313
|
+
case 'linux':
|
|
314
|
+
q.os = 'linux';
|
|
315
|
+
q.ext = 'tar.gz';
|
|
316
|
+
break;
|
|
317
|
+
case 'win32':
|
|
318
|
+
case 'win64':
|
|
319
|
+
q.os = 'windows';
|
|
320
|
+
break;
|
|
321
|
+
default:
|
|
322
|
+
return Promise.reject(new Error('Unsupported operating system'));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Construct the URL for the download request
|
|
327
|
+
let url = zuluBaseURL;
|
|
328
|
+
Object.keys(q).forEach(key => { url += key + '=' + q[key] + '&' });
|
|
329
|
+
|
|
330
|
+
const tmpdir = path.join(os.tmpdir(), 'njre');
|
|
331
|
+
|
|
332
|
+
// Function to handle the download and extraction
|
|
333
|
+
const attemptDownload = (url) => {
|
|
334
|
+
return download(tmpdir, url)
|
|
335
|
+
.then(move)
|
|
336
|
+
.then(extract);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// Attempt to download and extract the JRE/JDK
|
|
340
|
+
return attemptDownload(url)
|
|
341
|
+
.catch(err => {
|
|
342
|
+
console.error("Download failed: ", err);
|
|
343
|
+
// Exit with non-zero status code to signal failure to CI/CD systems
|
|
344
|
+
process.exit(1);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
return {install:install};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
var fs = require('fs');
|
|
354
|
+
const njre = njreWrap();
|
|
355
|
+
const targetJavaVersion = parseInt(javaVersionString);
|
|
356
|
+
var shell = require("shelljs/global");
|
|
357
|
+
|
|
358
|
+
function getJavaVersion(binPath) {
|
|
359
|
+
|
|
360
|
+
var oldPath = env['PATH'];
|
|
361
|
+
if (binPath) {
|
|
362
|
+
env['PATH'] = binPath + path.delimiter + env['PATH'];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
try {
|
|
366
|
+
var javaVersionProc = exec('java -version', {silent:true});
|
|
367
|
+
if (javaVersionProc.code !== 0) {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
var stdout = javaVersionProc.stderr;
|
|
371
|
+
var regexp = /version "(.*?)"/;
|
|
372
|
+
var match = regexp.exec(stdout);
|
|
373
|
+
var parts = match[1].split('.');
|
|
374
|
+
var join = '.';
|
|
375
|
+
var versionStr = '';
|
|
376
|
+
parts.forEach(function(v) {
|
|
377
|
+
versionStr += v;
|
|
378
|
+
if (join !== null) {
|
|
379
|
+
versionStr += join;
|
|
380
|
+
join = null;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
versionStr = versionStr.replace('_', '');
|
|
384
|
+
return parseFloat(versionStr);
|
|
385
|
+
} catch (e) {
|
|
386
|
+
return false;
|
|
387
|
+
} finally {
|
|
388
|
+
env['PATH'] = oldPath;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
var getDirectories = dirPath => fs.readdirSync(dirPath).filter(
|
|
392
|
+
file => fs.statSync(path.join(dirPath, file)).isDirectory()
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
function getJavaHomeInPath(basepath) {
|
|
396
|
+
|
|
397
|
+
var dirs = null;
|
|
398
|
+
try {
|
|
399
|
+
dirs = getDirectories(basepath);
|
|
400
|
+
} catch (e) {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
if (dirs && dirs.length > 0) {
|
|
404
|
+
basepath = path.join(basepath, dirs[0]);
|
|
405
|
+
if (os.platform() != 'darwin') {
|
|
406
|
+
return basepath;
|
|
407
|
+
}
|
|
408
|
+
if (fs.existsSync(path.join(basepath, 'Contents', 'Home'))) {
|
|
409
|
+
return path.join(basepath, 'Contents', 'Home');
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
var adapterDirectories = getDirectories(basepath).filter(subdir => {
|
|
413
|
+
return subdir.match(/^zulu/) && fs.existsSync(path.join(basepath, subdir, 'Contents', 'Home'));
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
if (adapterDirectories && adapterDirectories.length > 0) {
|
|
417
|
+
return path.join(basepath, adapterDirectories[0], 'Contents', 'Home');
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function findSupportedRuntime(javaVersion, jdk, javafx) {
|
|
424
|
+
var jdeployDir = jdeployHomeDir;
|
|
425
|
+
var JAVA_HOME_OVERRIDE = env['JDEPLOY_JAVA_HOME_OVERRIDE'];
|
|
426
|
+
|
|
427
|
+
if (JAVA_HOME_OVERRIDE && fs.existsSync(JAVA_HOME_OVERRIDE)) {
|
|
428
|
+
return JAVA_HOME_OVERRIDE;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// First check for the full-meal deal
|
|
432
|
+
var _javaHomePath = getJavaHomeInPath(path.join(jdeployDir, 'jdk', javaVersion+'fx', 'jdk'));
|
|
433
|
+
if (_javaHomePath && fs.existsSync(_javaHomePath)) {
|
|
434
|
+
return _javaHomePath;
|
|
435
|
+
}
|
|
436
|
+
if (!javafx) {
|
|
437
|
+
var _javaHomePath = getJavaHomeInPath(path.join(jdeployDir, 'jdk', javaVersion, 'jdk'));
|
|
438
|
+
if (_javaHomePath && fs.existsSync(_javaHomePath)) {
|
|
439
|
+
return _javaHomePath;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (!jdk) {
|
|
444
|
+
var _javaHomePath = getJavaHomeInPath(path.join(jdeployDir, 'jre', javaVersion+'fx', 'jre'));
|
|
445
|
+
if (_javaHomePath && fs.existsSync(_javaHomePath)) {
|
|
446
|
+
return _javaHomePath;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (!jdk && !javafx) {
|
|
451
|
+
var _javaHomePath = getJavaHomeInPath(path.join(jdeployDir, 'jre', javaVersion, 'jre'));
|
|
452
|
+
if (_javaHomePath && fs.existsSync(_javaHomePath)) {
|
|
453
|
+
return _javaHomePath;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return null;
|
|
457
|
+
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function getEmbeddedJavaHome() {
|
|
461
|
+
var _platform = os.platform();
|
|
462
|
+
var _driver = '';
|
|
463
|
+
switch (_platform) {
|
|
464
|
+
case 'darwin': _platform = 'macosx'; _driver = 'Contents' + path.sep + 'Home'; break;
|
|
465
|
+
case 'win32': _platform = 'windows'; _driver = ''; break;
|
|
466
|
+
case 'linux': _driver = ''; break;
|
|
467
|
+
default:
|
|
468
|
+
fail('unsupported platform: ' + _platform);
|
|
469
|
+
}
|
|
470
|
+
var vs = javaVersionString;
|
|
471
|
+
if (javafx) {
|
|
472
|
+
vs += 'fx';
|
|
473
|
+
}
|
|
474
|
+
var typeDir = jdk ? 'jdk' : 'jre';
|
|
475
|
+
|
|
476
|
+
var jreDir = path.join(jdeployHomeDir, 'jre', vs, 'jre');
|
|
477
|
+
try {
|
|
478
|
+
var out = jreDir + path.sep + getDirectories(jreDir)[0] + (_driver ? (path.sep + _driver) : '');
|
|
479
|
+
return out;
|
|
480
|
+
} catch (e) {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
function javaVersionMatch(v1, v2) {
|
|
486
|
+
if (v1 === 8) v1 = 1.8;
|
|
487
|
+
if (v2 === 8) v2 = 1.8;
|
|
488
|
+
if (Math.floor(v1) !== Math.floor(v2)) {
|
|
489
|
+
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
if (v1 < 2) {
|
|
493
|
+
// Up to 1.8, the version would be like 1.7, 1.8, etc..
|
|
494
|
+
// So we need to check the minor version for equivalency
|
|
495
|
+
return (Math.floor(v1*10) === Math.floor(v2*10));
|
|
496
|
+
} else {
|
|
497
|
+
// Starting with Java 9, the version is like 9, 10, 11, etc..
|
|
498
|
+
// so we just compare major version.
|
|
499
|
+
return (Math.floor(v1) === Math.floor(v2));
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
var done = false;
|
|
505
|
+
if (tryJavaHomeFirst) {
|
|
506
|
+
if (env['JAVA_HOME']) {
|
|
507
|
+
var javaHomeVersion = getJavaVersion(path.join(env['JAVA_HOME'], 'bin'));
|
|
508
|
+
if (javaVersionMatch(javaHomeVersion, targetJavaVersion)) {
|
|
509
|
+
done = true;
|
|
510
|
+
env['PATH'] = path.join(env['JAVA_HOME'], 'bin') + path.delimiter + env['PATH'];
|
|
511
|
+
run(env['JAVA_HOME']);
|
|
512
|
+
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (!done) {
|
|
517
|
+
var javaVersion = getJavaVersion();
|
|
518
|
+
if (javaVersionMatch(javaVersion, targetJavaVersion)) {
|
|
519
|
+
done = true;
|
|
520
|
+
run();
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
if (!done) {
|
|
527
|
+
|
|
528
|
+
var _javaHome = findSupportedRuntime(javaVersionString, bundleType === 'jdk', javafx);
|
|
529
|
+
if (_javaHome && fs.existsSync(_javaHome)) {
|
|
530
|
+
var javaVersion = getJavaVersion(path.join(_javaHome, 'bin'));
|
|
531
|
+
if (javaVersionMatch(javaVersion, targetJavaVersion)) {
|
|
532
|
+
env['PATH'] = path.join(_javaHome, 'bin') + path.delimiter + env['PATH'];
|
|
533
|
+
env['JAVA_HOME'] = _javaHome;
|
|
534
|
+
done = true;
|
|
535
|
+
run(_javaHome);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
if (!done) {
|
|
542
|
+
console.error("Downloading java runtime environment for version "+targetJavaVersion);
|
|
543
|
+
njre.install(targetJavaVersion, {type: bundleType, javafx: javafx}).then(function(dir) {
|
|
544
|
+
var _javaHome = getJavaHomeInPath(dir);
|
|
545
|
+
if (_javaHome == null)
|
|
546
|
+
|
|
547
|
+
if (!_javaHome || !fs.existsSync(_javaHome)) {
|
|
548
|
+
throw new Error("After install, could not find java home at "+_javaHome);
|
|
549
|
+
}
|
|
550
|
+
env['JAVA_HOME'] = _javaHome;
|
|
551
|
+
|
|
552
|
+
var javaBinary = path.join(_javaHome, 'bin', 'java');
|
|
553
|
+
if (!fs.existsSync(javaBinary)) {
|
|
554
|
+
javaBinary += '.exe';
|
|
555
|
+
|
|
556
|
+
}
|
|
557
|
+
fs.chmodSync(javaBinary, 0o755);
|
|
558
|
+
|
|
559
|
+
env['PATH'] = path.join(env['JAVA_HOME'], 'bin') + path.delimiter + env['PATH'];
|
|
560
|
+
|
|
561
|
+
run(env['JAVA_HOME']);
|
|
562
|
+
}).catch(function(err) {
|
|
563
|
+
console.error("Failed to install JRE", err);
|
|
564
|
+
// Exit with non-zero status code to signal failure to CI/CD systems
|
|
565
|
+
process.exit(1);
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
function run(_javaHome) {
|
|
573
|
+
var fail = reason => {
|
|
574
|
+
console.error(reason);
|
|
575
|
+
process.exit(1);
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
classPath = classPath.split(':');
|
|
580
|
+
var classPathStr = '';
|
|
581
|
+
var first = true;
|
|
582
|
+
classPath.forEach(function(part) {
|
|
583
|
+
if (!first) classPathStr += path.delimiter;
|
|
584
|
+
first = false;
|
|
585
|
+
classPathStr += __dirname + '/' + part;
|
|
586
|
+
});
|
|
587
|
+
classPath = classPathStr;
|
|
588
|
+
|
|
589
|
+
var userArgs = process.argv.slice(2);
|
|
590
|
+
var javaArgs = [];
|
|
591
|
+
javaArgs.push('-Djdeploy.mode=npx');
|
|
592
|
+
javaArgs.push('-Djdeploy.base='+__dirname);
|
|
593
|
+
javaArgs.push('-Djdeploy.port='+port);
|
|
594
|
+
javaArgs.push('-Djdeploy.war.path='+warPath);
|
|
595
|
+
var programArgs = [];
|
|
596
|
+
userArgs.forEach(function(arg) {
|
|
597
|
+
if (arg.startsWith('-D') || arg.startsWith('-X')) {
|
|
598
|
+
javaArgs.push(arg);
|
|
599
|
+
} else {
|
|
600
|
+
programArgs.push(arg);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
var cmd = 'java';
|
|
604
|
+
|
|
605
|
+
if (!_javaHome) {
|
|
606
|
+
env['PATH'] = path.join(getEmbeddedJavaHome(), 'bin') + path.delimiter + env['PATH'];
|
|
607
|
+
if (env['JAVA_HOME']) {
|
|
608
|
+
env['PATH'] = env['JAVA_HOME'] + path.sep + 'bin' + path.delimiter + env['PATH'];
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
} else {
|
|
612
|
+
env['JAVA_HOME'] = _javaHome;
|
|
613
|
+
cmd = _javaHome + path.sep + 'bin' + path.sep + 'java';
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
javaArgs.forEach(function(arg) {
|
|
617
|
+
cmd += ' "'+arg+'"';
|
|
618
|
+
});
|
|
619
|
+
if (jarName !== '{'+'{JAR_NAME}}') {
|
|
620
|
+
cmd += ' -jar "'+__dirname+'/'+jarName+'" ';
|
|
621
|
+
} else {
|
|
622
|
+
cmd += ' -cp "'+classPath+'" '+mainClass+' ';
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
programArgs.forEach(function(arg) {
|
|
626
|
+
cmd += ' "'+arg+'"';
|
|
627
|
+
});
|
|
628
|
+
var child = exec(cmd, {async: true});
|
|
629
|
+
process.stdin.setEncoding('utf8');
|
|
630
|
+
|
|
631
|
+
process.stdin.on('readable', function() {
|
|
632
|
+
var chunk = null;
|
|
633
|
+
while (null !== (chunk = process.stdin.read())) {
|
|
634
|
+
try {
|
|
635
|
+
child.stdin.write(chunk);
|
|
636
|
+
} catch(e){}
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
child.on('close', function(code) {
|
|
640
|
+
process.exit(code);
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openardf/radio-oracle",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Desktop event administration shell for Radio-Oracle.",
|
|
5
|
+
"author": "OpenARDF",
|
|
6
|
+
"homepage": "https://github.com/OpenARDF/Radio-Oracle",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/OpenARDF/Radio-Oracle.git"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"README.md",
|
|
13
|
+
"jdeploy-bundle/**"
|
|
14
|
+
],
|
|
15
|
+
"bin": {
|
|
16
|
+
"radio-oracle": "jdeploy-bundle/jdeploy.js"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"jdeploy:prepare": "./scripts/jdeploy-prepare.sh",
|
|
20
|
+
"prejdeploy:package": "npm run jdeploy:prepare",
|
|
21
|
+
"prejdeploy:install-local": "npm run jdeploy:prepare",
|
|
22
|
+
"prejdeploy:local": "npm run jdeploy:prepare",
|
|
23
|
+
"jdeploy:package": "npx --no-install jdeploy package",
|
|
24
|
+
"jdeploy:install-local": "npx --no-install jdeploy install -y",
|
|
25
|
+
"jdeploy:verify-install": "npx --no-install jdeploy verify-installation --package-json=package.json --verbose",
|
|
26
|
+
"jdeploy:local": "npx --no-install jdeploy run --install",
|
|
27
|
+
"jdeploy:local-smoke": "./scripts/jdeploy-local-smoke.sh",
|
|
28
|
+
"jdeploy:pack-preview": "npm run jdeploy:package && npm pack --dry-run --ignore-scripts",
|
|
29
|
+
"jdeploy:release-preflight": "node ./scripts/check-jdeploy-release-ready.mjs",
|
|
30
|
+
"prepublishOnly": "node ./scripts/check-jdeploy-publish.mjs"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"shelljs": "^0.8.4"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"jdeploy": "6.1.3"
|
|
37
|
+
},
|
|
38
|
+
"jdeploy": {
|
|
39
|
+
"jar": "desktopApp/build/jdeploy/Radio-Oracle-jdeploy.jar",
|
|
40
|
+
"title": "Radio-Oracle",
|
|
41
|
+
"javaVersion": "17"
|
|
42
|
+
}
|
|
43
|
+
}
|