pinokiod 3.8.68 → 3.8.69
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/kernel/api/index.js +2 -2
- package/kernel/bin/caddy.js +1 -1
- package/kernel/bin/index.js +0 -3
- package/kernel/index.js +16 -0
- package/kernel/peer.js +18 -0
- package/kernel/procs.js +8 -6
- package/kernel/router/index.js +37 -22
- package/package.json +1 -1
- package/server/index.js +83 -16
- package/server/views/file_explorer.ejs +1 -1
- package/server/views/index.ejs +2 -2
- package/server/views/{proxy.ejs → network.ejs} +41 -32
- package/server/views/prototypes.ejs +1 -1
package/kernel/api/index.js
CHANGED
|
@@ -186,7 +186,7 @@ class Api {
|
|
|
186
186
|
type: "disconnect"
|
|
187
187
|
})
|
|
188
188
|
console.timeEnd("stop 4")
|
|
189
|
-
|
|
189
|
+
this.kernel.refresh()
|
|
190
190
|
return true
|
|
191
191
|
}
|
|
192
192
|
async startScripts() {
|
|
@@ -1074,7 +1074,7 @@ class Api {
|
|
|
1074
1074
|
})
|
|
1075
1075
|
}
|
|
1076
1076
|
}
|
|
1077
|
-
|
|
1077
|
+
this.kernel.refresh()
|
|
1078
1078
|
} catch (e) {
|
|
1079
1079
|
ondata({ raw: e.toString() })
|
|
1080
1080
|
}
|
package/kernel/bin/caddy.js
CHANGED
package/kernel/bin/index.js
CHANGED
|
@@ -347,12 +347,9 @@ class Bin {
|
|
|
347
347
|
// process.stdout.write(stream.raw)
|
|
348
348
|
// console.log("conda list check", { stream })
|
|
349
349
|
})
|
|
350
|
-
console.log("> res", res)
|
|
351
350
|
|
|
352
351
|
let lines = res.response.split(/[\r\n]+/)
|
|
353
|
-
console.log("> lines", lines)
|
|
354
352
|
for(let line of lines) {
|
|
355
|
-
console.log("> start", start)
|
|
356
353
|
if (start) {
|
|
357
354
|
let chunks = line.split(/\s+/).filter(x => x)
|
|
358
355
|
if (chunks.length > 2) {
|
package/kernel/index.js
CHANGED
|
@@ -258,6 +258,22 @@ class Kernel {
|
|
|
258
258
|
log(data, group, info) {
|
|
259
259
|
this.log_queue.push({ data, group, info })
|
|
260
260
|
}
|
|
261
|
+
async refresh(broadcast) {
|
|
262
|
+
console.log("kernel.refresh", { broadcast })
|
|
263
|
+
await Promise.all([
|
|
264
|
+
// refresh proc info
|
|
265
|
+
this.processes.refresh(),
|
|
266
|
+
// refresh peer info
|
|
267
|
+
this.peer.refresh()
|
|
268
|
+
])
|
|
269
|
+
// refresh router info
|
|
270
|
+
await this.router.refresh()
|
|
271
|
+
|
|
272
|
+
if (broadcast) {
|
|
273
|
+
// broadcast to peers
|
|
274
|
+
await this.peer.broadcast()
|
|
275
|
+
}
|
|
276
|
+
}
|
|
261
277
|
async clearLog(group) {
|
|
262
278
|
let relativePath = path.relative(this.homedir, group)
|
|
263
279
|
for(let type of ["info", "buf", "cleaned"]) {
|
package/kernel/peer.js
CHANGED
|
@@ -45,6 +45,24 @@ class PeerDiscovery {
|
|
|
45
45
|
return null
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
async _broadcast(host) {
|
|
49
|
+
try {
|
|
50
|
+
let res = await axios.post(`http://${host}:${this.default_port}/pinokio/peer/refresh`, {
|
|
51
|
+
timeout: 2000
|
|
52
|
+
})
|
|
53
|
+
return res.data
|
|
54
|
+
} catch (e) {
|
|
55
|
+
return null
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// notify peers to refresh my info
|
|
59
|
+
async braodcast() {
|
|
60
|
+
let res = await Promise.all(Array.from(this.peers).map((host) => {
|
|
61
|
+
return this._broadcast(host)
|
|
62
|
+
}))
|
|
63
|
+
return res
|
|
64
|
+
}
|
|
65
|
+
// refresh peer info
|
|
48
66
|
async refresh() {
|
|
49
67
|
this.info = {}
|
|
50
68
|
let peer_info = await Promise.all(Array.from(this.peers).map((host) => {
|
package/kernel/procs.js
CHANGED
|
@@ -23,8 +23,6 @@ class Procs {
|
|
|
23
23
|
if (!line.startsWith(' TCP')) return;
|
|
24
24
|
const parts = line.trim().split(/\s+/);
|
|
25
25
|
const [ , localAddress, , state, pid ] = parts;
|
|
26
|
-
if (pids.has(pid)) return;
|
|
27
|
-
pids.add(pid)
|
|
28
26
|
if (state !== 'LISTENING') return;
|
|
29
27
|
const chunks = localAddress.split(":")
|
|
30
28
|
const port = chunks.pop()
|
|
@@ -34,13 +32,13 @@ class Procs {
|
|
|
34
32
|
} else {
|
|
35
33
|
ip = localAddress
|
|
36
34
|
}
|
|
35
|
+
if (pids.has(pid+"/"+port)) return;
|
|
36
|
+
pids.add(pid+"/"+port)
|
|
37
37
|
results.push({ port, pid, ip });
|
|
38
38
|
} else {
|
|
39
39
|
if (!/LISTEN/.test(line)) return;
|
|
40
40
|
const parts = line.trim().split(/\s+/);
|
|
41
41
|
const pid = parts[1];
|
|
42
|
-
if (pids.has(pid)) return;
|
|
43
|
-
pids.add(pid)
|
|
44
42
|
|
|
45
43
|
const match = line.match(/([^\s]+:\d+)\s/);
|
|
46
44
|
const localAddress = match?.[1];
|
|
@@ -54,6 +52,8 @@ class Procs {
|
|
|
54
52
|
}
|
|
55
53
|
//const portMatch = line.match(/:(\d+)\s/);
|
|
56
54
|
//const port = portMatch?.[1];
|
|
55
|
+
if (pids.has(pid+"/"+port)) return;
|
|
56
|
+
pids.add(pid+"/"+port)
|
|
57
57
|
if (pid && port) results.push({ port, pid, ip });
|
|
58
58
|
}
|
|
59
59
|
});
|
|
@@ -100,14 +100,16 @@ class Procs {
|
|
|
100
100
|
const name = fullname.split(path.sep).pop()
|
|
101
101
|
return { port, pid , name, fullname, ip }
|
|
102
102
|
})
|
|
103
|
+
list = list.filter((item) => {
|
|
104
|
+
return item.name.toLowerCase() !== "caddy"
|
|
105
|
+
})
|
|
103
106
|
resolve(list)
|
|
104
107
|
});
|
|
105
108
|
});
|
|
106
109
|
})
|
|
107
110
|
console.log( { list } )
|
|
108
111
|
console.timeEnd("Get list")
|
|
109
|
-
this.
|
|
110
|
-
return this.list
|
|
112
|
+
this.info = list
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
module.exports = Procs
|
package/kernel/router/index.js
CHANGED
|
@@ -24,7 +24,7 @@ class Router {
|
|
|
24
24
|
this.default_port = "42000"
|
|
25
25
|
this.default_host = "127.0.0.1"
|
|
26
26
|
|
|
27
|
-
this.
|
|
27
|
+
this.mapping = {}
|
|
28
28
|
this.port_mapping = {} // 127.0.0.1 => 192.168,..
|
|
29
29
|
this.local_network_mapping = {}
|
|
30
30
|
}
|
|
@@ -39,12 +39,12 @@ class Router {
|
|
|
39
39
|
console.log(">this._mapping", this._mapping)
|
|
40
40
|
}
|
|
41
41
|
info() {
|
|
42
|
-
console.log("#### this.
|
|
42
|
+
console.log("#### this.mapping", this.mapping)
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
let mapping = {}
|
|
46
|
-
for(let host in this.
|
|
47
|
-
let internal_maps = this.
|
|
46
|
+
for(let host in this.mapping) {
|
|
47
|
+
let internal_maps = this.mapping[host]
|
|
48
48
|
if (!mapping[host]) {
|
|
49
49
|
mapping[host] = {}
|
|
50
50
|
}
|
|
@@ -115,6 +115,8 @@ class Router {
|
|
|
115
115
|
*/
|
|
116
116
|
|
|
117
117
|
console.log("count", count)
|
|
118
|
+
|
|
119
|
+
let new_config
|
|
118
120
|
|
|
119
121
|
if (count > 0) {
|
|
120
122
|
let ports = await this.kernel.ports(count)
|
|
@@ -148,23 +150,27 @@ class Router {
|
|
|
148
150
|
}
|
|
149
151
|
|
|
150
152
|
async refresh() {
|
|
151
|
-
|
|
153
|
+
console.log("router.refresh")
|
|
154
|
+
console.time("router.refresh")
|
|
155
|
+
console.log("> procs", this.kernel.processes.info)
|
|
156
|
+
console.log("> peers", this.kernel.peer.info)
|
|
157
|
+
this._mapping = {}
|
|
152
158
|
// this.port_mapping = {} // 127.0.0.1 => 192.168,..
|
|
153
159
|
// this.local_network_mapping = {}
|
|
154
160
|
|
|
161
|
+
let old_config = this.config
|
|
162
|
+
|
|
155
163
|
// 1. Localhost handling
|
|
156
164
|
this.localhost_home_router.handle()
|
|
157
165
|
this.localhost_variable_router.handle(this.kernel.memory.local)
|
|
158
|
-
let
|
|
159
|
-
for(let proc of procs) {
|
|
166
|
+
for(let proc of this.kernel.processes.info) {
|
|
160
167
|
this.localhost_port_router.handle(proc)
|
|
161
168
|
}
|
|
169
|
+
this.mapping = this._mapping
|
|
162
170
|
|
|
163
171
|
// 2. Peers handling
|
|
164
|
-
let
|
|
165
|
-
|
|
166
|
-
for(let host in peers) {
|
|
167
|
-
let peer = peers[host]
|
|
172
|
+
for(let host in this.kernel.peer.info) {
|
|
173
|
+
let peer = this.kernel.peer.info[host]
|
|
168
174
|
if (peer.host === this.kernel.peer.host) {
|
|
169
175
|
this.peer_home_router.handle(peer)
|
|
170
176
|
this.peer_variable_router.handle(peer)
|
|
@@ -174,19 +180,28 @@ class Router {
|
|
|
174
180
|
}
|
|
175
181
|
}
|
|
176
182
|
// replace :PORT_PLACEHOLDER with available ports
|
|
177
|
-
console.log("CONFIG BEFORE", JSON.stringify(this.config, null, 2))
|
|
178
183
|
|
|
179
|
-
await this.fill()
|
|
180
184
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
185
|
+
await this.fill()
|
|
186
|
+
this.mapping = this._mapping
|
|
187
|
+
console.timeEnd("router.refresh")
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
// compare old config with new config
|
|
191
|
+
// if it hasn't changed, don't do anything
|
|
192
|
+
// if it has changed, refresh
|
|
193
|
+
|
|
194
|
+
if (JSON.stringify(this.config) === JSON.stringify(old_config)) {
|
|
195
|
+
console.log("config hasn't updated")
|
|
196
|
+
} else {
|
|
197
|
+
console.log("config has updated")
|
|
198
|
+
let response = await axios.post('http://127.0.0.1:2019/load', this.config, {
|
|
199
|
+
headers: { 'Content-Type': 'application/json' }
|
|
200
|
+
}).catch((e) => {
|
|
201
|
+
console.log("EEEEEEEEEEEEE", e)
|
|
202
|
+
})
|
|
203
|
+
console.log("Caddy Response", { response })
|
|
204
|
+
}
|
|
190
205
|
}
|
|
191
206
|
}
|
|
192
207
|
module.exports = Router
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -2621,22 +2621,76 @@ class Server {
|
|
|
2621
2621
|
id: req.params.id
|
|
2622
2622
|
})
|
|
2623
2623
|
}))
|
|
2624
|
-
this.app.get("/
|
|
2625
|
-
|
|
2626
|
-
let
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2624
|
+
this.app.get("/network", ex(async (req, res) => {
|
|
2625
|
+
let list = []
|
|
2626
|
+
let peers_info = await this.kernel.peer.refresh()
|
|
2627
|
+
console.log({ peers_info })
|
|
2628
|
+
let info = this.kernel.router.info()
|
|
2629
|
+
console.log("33 info", info)
|
|
2630
|
+
let remote_peers = Object.keys(this.kernel.peer.info).filter(x => x !== this.kernel.peer.host)
|
|
2631
|
+
let nodes = [this.kernel.peer.host].concat(remote_peers)
|
|
2632
|
+
for(let host of nodes) {
|
|
2633
|
+
let processes = []
|
|
2634
|
+
try {
|
|
2635
|
+
let procs = this.kernel.peer.info[host].proc
|
|
2636
|
+
let router = this.kernel.peer.info[host].router
|
|
2637
|
+
let port_mapping = this.kernel.peer.info[host].port_mapping
|
|
2638
|
+
console.log("&&", { procs })
|
|
2639
|
+
for(let proc of procs) {
|
|
2640
|
+
let internal_port = proc.ip.split(":")[1]
|
|
2641
|
+
let external_port = port_mapping[internal_port]
|
|
2642
|
+
if (external_port) {
|
|
2643
|
+
let external_ip = `${host}:${external_port}`
|
|
2644
|
+
console.log({ internal_port, external_port, external_ip })
|
|
2645
|
+
processes.push({
|
|
2646
|
+
//proxy: this.kernel.caddy.mapping[item.ip] || [],
|
|
2647
|
+
router: router[external_ip] || [],
|
|
2648
|
+
external_ip,
|
|
2649
|
+
...proc
|
|
2650
|
+
})
|
|
2651
|
+
} else {
|
|
2652
|
+
processes.push({
|
|
2653
|
+
router: [],
|
|
2654
|
+
...proc
|
|
2655
|
+
})
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
} catch (e) {
|
|
2659
|
+
console.log(">>e", e)
|
|
2636
2660
|
}
|
|
2637
|
-
|
|
2661
|
+
list.push({
|
|
2662
|
+
host,
|
|
2663
|
+
name: this.kernel.peer.info[host].name,
|
|
2664
|
+
platform: this.kernel.peer.info[host].platform,
|
|
2665
|
+
processes
|
|
2666
|
+
})
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
// if (this.kernel.processes.info) {
|
|
2670
|
+
// console.log("proc info", this.kernel.processes.info)
|
|
2671
|
+
// list = this.kernel.processes.info.map((item) => {
|
|
2672
|
+
// console.log("item", item)
|
|
2673
|
+
// console.log("item.ip", item.ip)
|
|
2674
|
+
// let internal_port = item.ip.split(":")[1]
|
|
2675
|
+
// let external_port = this.kernel.router.port_mapping[internal_port]
|
|
2676
|
+
// if (external_port) {
|
|
2677
|
+
// let external_ip = `${this.kernel.peer.host}:${external_port}`
|
|
2678
|
+
// console.log({ internal_port, external_port, external_ip })
|
|
2679
|
+
// return {
|
|
2680
|
+
// //proxy: this.kernel.caddy.mapping[item.ip] || [],
|
|
2681
|
+
// router: info[this.kernel.peer.host][external_ip] || [],
|
|
2682
|
+
// external_ip,
|
|
2683
|
+
// ...item
|
|
2684
|
+
// }
|
|
2685
|
+
// } else {
|
|
2686
|
+
// return {
|
|
2687
|
+
// router: [],
|
|
2688
|
+
// ...item
|
|
2689
|
+
// }
|
|
2690
|
+
// }
|
|
2691
|
+
// })
|
|
2692
|
+
// }
|
|
2638
2693
|
|
|
2639
|
-
let peers_info = await this.kernel.peer.refresh()
|
|
2640
2694
|
let peers = []
|
|
2641
2695
|
for(let host in peers_info) {
|
|
2642
2696
|
let peer_info = peers_info[host]
|
|
@@ -2728,12 +2782,13 @@ class Server {
|
|
|
2728
2782
|
}
|
|
2729
2783
|
}
|
|
2730
2784
|
|
|
2731
|
-
console.log("
|
|
2785
|
+
console.log("network", JSON.stringify(list, null, 2))
|
|
2732
2786
|
|
|
2733
|
-
res.render("
|
|
2787
|
+
res.render("network", {
|
|
2734
2788
|
ip: this.kernel.peer.current_ip,
|
|
2735
2789
|
peers,
|
|
2736
2790
|
list,
|
|
2791
|
+
port_mapping: this.kernel.router.port_mapping,
|
|
2737
2792
|
// port_mapping: this.kernel.caddy.port_mapping,
|
|
2738
2793
|
// ip_mapping: this.kernel.caddy.ip_mapping,
|
|
2739
2794
|
lan: this.kernel.router.local_network_mapping,
|
|
@@ -3263,14 +3318,22 @@ class Server {
|
|
|
3263
3318
|
*/
|
|
3264
3319
|
|
|
3265
3320
|
}))
|
|
3321
|
+
this.app.post("/pinokio/peer/refresh", ex(async (req, res) => {
|
|
3322
|
+
// refresh and broadcast
|
|
3323
|
+
await this.kernel.refresh(true)
|
|
3324
|
+
res.json({ success: true })
|
|
3325
|
+
}))
|
|
3266
3326
|
this.app.get("/pinokio/peer", ex((req, res) => {
|
|
3327
|
+
console.log("/pinokio/peer", { proc: this.kernel.processes.info })
|
|
3267
3328
|
res.json({
|
|
3268
3329
|
home: this.kernel.homedir,
|
|
3269
3330
|
arch: this.kernel.arch,
|
|
3270
3331
|
platform: this.kernel.platform,
|
|
3271
3332
|
name: this.kernel.peer.name,
|
|
3272
3333
|
host: this.kernel.peer.host,
|
|
3334
|
+
port_mapping: this.kernel.router.port_mapping,
|
|
3273
3335
|
//router: this.kernel.router.info(),
|
|
3336
|
+
proc: this.kernel.processes.info,
|
|
3274
3337
|
router: this.kernel.router.published(),
|
|
3275
3338
|
memory: this.kernel.memory
|
|
3276
3339
|
})
|
|
@@ -3862,6 +3925,8 @@ class Server {
|
|
|
3862
3925
|
this.kernel.shell.reset(() => {
|
|
3863
3926
|
process.exit()
|
|
3864
3927
|
})
|
|
3928
|
+
} else {
|
|
3929
|
+
process.exit()
|
|
3865
3930
|
}
|
|
3866
3931
|
})
|
|
3867
3932
|
process.on('SIGTERM', () => {
|
|
@@ -3870,6 +3935,8 @@ class Server {
|
|
|
3870
3935
|
this.kernel.shell.reset(() => {
|
|
3871
3936
|
process.exit()
|
|
3872
3937
|
})
|
|
3938
|
+
} else {
|
|
3939
|
+
process.exit()
|
|
3873
3940
|
}
|
|
3874
3941
|
})
|
|
3875
3942
|
// process.on('exit', () => {
|
|
@@ -235,7 +235,7 @@ body.dark .browser-options-row {
|
|
|
235
235
|
</div>
|
|
236
236
|
<% } %>
|
|
237
237
|
<div class='browser-options-row'>
|
|
238
|
-
<a href="/
|
|
238
|
+
<a href="/network" class='btn'><div><i class="fa-solid fa-gauge"></i> Configure</div></a>
|
|
239
239
|
<div class='flexible'>
|
|
240
240
|
<h3><i class="fa-solid fa-wifi"></i> Local Sharing</h3>
|
|
241
241
|
<div>Serve Pinokio, installed apps, and even external apps (example: Ollama) to any device on the same network.</div>
|
package/server/views/index.ejs
CHANGED
|
@@ -228,7 +228,7 @@ body.dark .browser-options-row {
|
|
|
228
228
|
<!--
|
|
229
229
|
<a class='btn2' id='explore'><div><i class="fa-solid fa-globe"></i></div><div>Discover</div></a>
|
|
230
230
|
-->
|
|
231
|
-
<a href="/
|
|
231
|
+
<a href="/network" class='btn2'><div><i class="fa-solid fa-wifi"></i></div><div>Wifi Sharing</div></a>
|
|
232
232
|
<a class='btn2' href="https://portal.pinokio.computer/" target="_blank"><div><i class="fa-solid fa-question"></i></div><div>Help</div></a>
|
|
233
233
|
<% if (agent === "electron") { %>
|
|
234
234
|
<a class='btn2' data-filepath="<%=filepath%>"><div><i class="fa-regular fa-folder-open"></i></div><div>Files</div></a>
|
|
@@ -288,7 +288,7 @@ body.dark .browser-options-row {
|
|
|
288
288
|
</div>
|
|
289
289
|
<% } %>
|
|
290
290
|
<div class='browser-options-row'>
|
|
291
|
-
<a href="/
|
|
291
|
+
<a href="/network" class='btn'><div><i class="fa-solid fa-gauge"></i> Configure</div></a>
|
|
292
292
|
<div class='flexible'>
|
|
293
293
|
<h3><i class="fa-solid fa-wifi"></i> Local Sharing</h3>
|
|
294
294
|
<div>Serve Pinokio, installed apps, and even external apps (example: Ollama) to any device on the same network.</div>
|
|
@@ -173,7 +173,7 @@ body.dark .browser-options-row {
|
|
|
173
173
|
}
|
|
174
174
|
.container {
|
|
175
175
|
display: grid;
|
|
176
|
-
grid-template-columns: repeat(
|
|
176
|
+
grid-template-columns: repeat(<%=list.length%>, 1fr);
|
|
177
177
|
}
|
|
178
178
|
.dark .container-row {
|
|
179
179
|
background: rgba(255, 255, 255, 0.04);
|
|
@@ -209,7 +209,7 @@ td:first-child, th:first-child {
|
|
|
209
209
|
}
|
|
210
210
|
.container-row td {
|
|
211
211
|
font-size: 14px;
|
|
212
|
-
padding:
|
|
212
|
+
padding: 2px;
|
|
213
213
|
}
|
|
214
214
|
@media only screen and (max-width: 480px) {
|
|
215
215
|
.btn2 {
|
|
@@ -244,6 +244,7 @@ td:first-child, th:first-child {
|
|
|
244
244
|
<main>
|
|
245
245
|
<div class='header-label'><i class='fa-solid fa-wifi'></i> Networking</div>
|
|
246
246
|
<div class='desc'>Serve Pinokio, installed apps, and even external apps to any device on the same network.</div>
|
|
247
|
+
<!--
|
|
247
248
|
<div class='header-container'>
|
|
248
249
|
<div class='header-label-sub'><i class="fa-solid fa-podcast"></i> Local Network</div>
|
|
249
250
|
<% peers.forEach((item) => { %>
|
|
@@ -252,39 +253,45 @@ td:first-child, th:first-child {
|
|
|
252
253
|
</a>
|
|
253
254
|
<% }) %>
|
|
254
255
|
</div>
|
|
256
|
+
-->
|
|
255
257
|
<div class='container'>
|
|
256
|
-
|
|
257
|
-
<div class='
|
|
258
|
-
|
|
259
|
-
<
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
</
|
|
278
|
-
|
|
258
|
+
<% list.forEach(({ host, name, platform, processes }) => { %>
|
|
259
|
+
<div class='container-row'>
|
|
260
|
+
<!--
|
|
261
|
+
<div class='header-label-sub'><i class="fa-solid fa-microchip"></i> System</div>
|
|
262
|
+
-->
|
|
263
|
+
<div class='header-label-sub'><%=name%> (<%=platform%>, <%=host%>)</div>
|
|
264
|
+
<table>
|
|
265
|
+
<tr>
|
|
266
|
+
<th>Server</th>
|
|
267
|
+
<th>https</th>
|
|
268
|
+
<th>http</th>
|
|
269
|
+
</tr>
|
|
270
|
+
<% processes.forEach((item) => { %>
|
|
271
|
+
<tr>
|
|
272
|
+
<td class='title'><%=item.name%></td>
|
|
273
|
+
<td>
|
|
274
|
+
<% item.router.forEach((domain) => { %>
|
|
275
|
+
<div>
|
|
276
|
+
<a target="_blank" href="https://<%=domain%>">https://<%=domain%></a>
|
|
277
|
+
</div>
|
|
278
|
+
<% }) %>
|
|
279
|
+
</td>
|
|
280
|
+
<td>
|
|
279
281
|
<div>
|
|
280
|
-
<a target="_blank" href="http
|
|
282
|
+
<a target="_blank" href="http://localhost:<%=item.port%>">http://localhost:<%=item.port%></a>
|
|
281
283
|
</div>
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
284
|
+
<% if (item.external_ip) { %>
|
|
285
|
+
<div>
|
|
286
|
+
<a target="_blank" href="http://<%=item.external_ip%>">http://<%=item.external_ip%></a>
|
|
287
|
+
</div>
|
|
288
|
+
<% } %>
|
|
289
|
+
</td>
|
|
290
|
+
</tr>
|
|
291
|
+
<% }) %>
|
|
292
|
+
</table>
|
|
293
|
+
</div>
|
|
294
|
+
<% }) %>
|
|
288
295
|
<div class='container-row hidden'>
|
|
289
296
|
<div class='header-label-sub'><i class="fa-solid fa-microchip"></i> System Programs</div>
|
|
290
297
|
<div class='line align-top'>
|
|
@@ -333,6 +340,7 @@ td:first-child, th:first-child {
|
|
|
333
340
|
</div>
|
|
334
341
|
<% }) %>
|
|
335
342
|
</div>
|
|
343
|
+
<!--
|
|
336
344
|
<div class='container-row'>
|
|
337
345
|
<div class='header-label-sub'><i class="fa-solid fa-dice-d6"></i> Pinokio</div>
|
|
338
346
|
<% apps.forEach((item) => { %>
|
|
@@ -358,6 +366,7 @@ td:first-child, th:first-child {
|
|
|
358
366
|
</a>
|
|
359
367
|
<% }) %>
|
|
360
368
|
</div>
|
|
369
|
+
-->
|
|
361
370
|
</div>
|
|
362
371
|
</main>
|
|
363
372
|
<script>
|
|
@@ -196,7 +196,7 @@ body.dark .browser-options-row {
|
|
|
196
196
|
<input type='search' class="flexible" placeholder='Filter downloaded apps'>
|
|
197
197
|
</form>
|
|
198
198
|
<div class='nav-btns'>
|
|
199
|
-
<a href="/
|
|
199
|
+
<a href="/network" class='btn2'><div><i class="fa-solid fa-wifi"></i></div><div>Wifi Sharing</div></a>
|
|
200
200
|
<a class='btn2' href="https://portal.pinokio.computer/" target="_blank"><div><i class="fa-solid fa-question"></i></div><div>Help</div></a>
|
|
201
201
|
<button class='btn2' id='genlog'><div><i class="fa-solid fa-laptop-code"></i></div><div>Debug</div></button>
|
|
202
202
|
<a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><div><i class="fa-solid fa-download"></i></div><div>Download logs</div></a>
|