-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathserver.js
More file actions
138 lines (122 loc) · 4.12 KB
/
Copy pathserver.js
File metadata and controls
138 lines (122 loc) · 4.12 KB
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
import './app/services/env.js'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import http from 'node:http'
import express from 'express'
import exphbs from 'express-handlebars'
import { Server as SocketIOServer } from 'socket.io'
import helpers from './app/helpers/index.js'
import { createRouter } from './app/routes/index.js'
import { createFileManager } from './app/services/fileManager.js'
import { createMachineManager } from './app/services/machineManager.js'
import { createPythonBridge } from './app/services/pythonBridge.js'
import { createMachineStateStore } from './app/services/machineStateStore.js'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const port = Number(process.env.PORT || 2000)
const isProd = process.env.NODE_ENV === 'PROD'
if (!process.env.SVGDIR) {
throw new Error('Missing SVGDIR in .env file. Copy .env.example and update it.')
}
const app = express()
const server = http.createServer(app)
const io = new SocketIOServer(server)
const hbs = exphbs.create({
extname: '.html',
helpers,
defaultLayout: false,
partialsDir: path.join(__dirname, 'app', 'templates', 'includes')
})
app.engine('html', hbs.engine)
app.set('view engine', 'html')
app.set('views', path.join(__dirname, 'app', 'templates'))
app.locals.layout = false
app.use(express.static(path.join(__dirname, 'app', 'public'), {
etag: true,
maxAge: isProd ? '1h' : 0
}))
app.use(express.json({ limit: '2mb' }))
app.use(express.urlencoded({ extended: true }))
const fileManager = createFileManager({
baseDir: process.env.SVGDIR
})
const pythonBridge = createPythonBridge({
pythonBin: process.env.PYTHON_BIN || 'python3',
pythonDir: path.join(__dirname, 'python')
})
const machineStateStore = createMachineStateStore({
filePath: process.env.MACHINE_STATE_FILE || path.join(__dirname, 'data', 'machine-state.json')
})
const machineManager = createMachineManager({
pythonBridge,
machineStateStore,
defaultModel: Number(process.env.DEFAULT_MODEL || 8),
defaults: {
speed: Number(process.env.DEFAULT_SPEED || 20),
handling: Number(process.env.DEFAULT_HANDLING || 1),
reordering: Number(process.env.DEFAULT_REORDERING || 0),
penlift: Number(process.env.DEFAULT_PENLIFT || 1),
webhook: process.env.DEFAULT_WEBHOOK || ''
},
virtualMachineEnabled: String(process.env.VIRTUAL_MACHINE || 'true') === 'true',
virtualMachineName: process.env.VIRTUAL_MACHINE_NAME || 'Virtual Preview Machine',
virtualMachineCount: (() => {
const raw = process.env.VIRTUAL_MACHINE_COUNT
if (raw === undefined || String(raw).trim() === '') return 1
const n = Number(raw)
return Number.isFinite(n) ? n : 1
})()
})
const broadcastEvents = [
'machines:list',
'machine:status',
'preview:result',
'plot:progress',
'plot:complete',
'plot:error'
]
for (const eventName of broadcastEvents) {
machineManager.on(eventName, (payload) => io.emit(eventName, payload))
}
io.on('connection', async (socket) => {
socket.emit('machines:list', machineManager.getMachines())
try {
const files = await fileManager.list('')
socket.emit('files:list', files)
} catch (error) {
socket.emit('files:error', { message: error.message })
}
})
app.use('/', createRouter({
io,
fileManager,
machineManager
}))
app.use((req, res) => {
res.status(404).render('static/404', {
pageTitle: 'Not Found'
})
})
// Express only treats this as an error handler when it has 4 parameters.
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
const statusCode = Number(err.statusCode || err.status || 500)
const safeMessage = statusCode >= 500 && isProd ? 'Unexpected server error' : err.message
if (!isProd) console.error(err)
if (req.originalUrl.startsWith('/api/')) {
res.status(statusCode).json({
ok: false,
errorMessage: safeMessage
})
return
}
res.status(statusCode).render('static/500', {
pageTitle: 'Server Error',
errorMessage: safeMessage
})
})
await machineManager.discoverMachines()
server.listen(port, () => {
console.log(`MVPT v2 listening on port ${port}`)
console.log(`SVG directory: ${process.env.SVGDIR}`)
})