matlab-proxy 0.10.1__py3-none-any.whl → 0.12.0__py3-none-any.whl
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.
Potentially problematic release.
This version of matlab-proxy might be problematic. Click here for more details.
- matlab_proxy/app.py +75 -22
- matlab_proxy/app_state.py +74 -53
- matlab_proxy/constants.py +15 -2
- matlab_proxy/gui/asset-manifest.json +6 -6
- matlab_proxy/gui/index.html +1 -1
- matlab_proxy/gui/static/css/{main.aa888962.css → main.47712126.css} +2 -2
- matlab_proxy/gui/static/css/{main.aa888962.css.map → main.47712126.css.map} +1 -1
- matlab_proxy/gui/static/js/{main.fbc5c728.js → main.ea1ebdce.js} +3 -3
- matlab_proxy/gui/static/js/main.ea1ebdce.js.map +1 -0
- matlab_proxy/matlab/startup.m +2 -2
- matlab_proxy/settings.py +17 -8
- {matlab_proxy-0.10.1.dist-info → matlab_proxy-0.12.0.dist-info}/METADATA +3 -2
- {matlab_proxy-0.10.1.dist-info → matlab_proxy-0.12.0.dist-info}/RECORD +18 -18
- matlab_proxy/gui/static/js/main.fbc5c728.js.map +0 -1
- /matlab_proxy/gui/static/js/{main.fbc5c728.js.LICENSE.txt → main.ea1ebdce.js.LICENSE.txt} +0 -0
- {matlab_proxy-0.10.1.dist-info → matlab_proxy-0.12.0.dist-info}/LICENSE.md +0 -0
- {matlab_proxy-0.10.1.dist-info → matlab_proxy-0.12.0.dist-info}/WHEEL +0 -0
- {matlab_proxy-0.10.1.dist-info → matlab_proxy-0.12.0.dist-info}/entry_points.txt +0 -0
- {matlab_proxy-0.10.1.dist-info → matlab_proxy-0.12.0.dist-info}/top_level.txt +0 -0
matlab_proxy/app.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2024 The MathWorks, Inc.
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import json
|
|
5
5
|
import mimetypes
|
|
6
6
|
import pkgutil
|
|
7
7
|
import sys
|
|
8
|
+
import uuid
|
|
8
9
|
|
|
9
10
|
import aiohttp
|
|
10
11
|
from aiohttp import client_exceptions, web
|
|
@@ -19,6 +20,7 @@ from matlab_proxy.util import mwi
|
|
|
19
20
|
from matlab_proxy.util.mwi import environment_variables as mwi_env
|
|
20
21
|
from matlab_proxy.util.mwi import token_auth
|
|
21
22
|
from matlab_proxy.util.mwi.exceptions import AppError, InvalidTokenError, LicensingError
|
|
23
|
+
from matlab_proxy.constants import IS_CONCURRENCY_CHECK_ENABLED
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
mimetypes.add_type("font/woff", ".woff")
|
|
@@ -93,28 +95,45 @@ def marshal_error(error):
|
|
|
93
95
|
return {"message": error.__str__, "logs": "", "type": error.__class__.__name__}
|
|
94
96
|
|
|
95
97
|
|
|
96
|
-
async def create_status_response(
|
|
97
|
-
|
|
98
|
+
async def create_status_response(
|
|
99
|
+
app, loadUrl=None, client_id=None, transfer_session=False, is_desktop=False
|
|
100
|
+
):
|
|
101
|
+
"""Send a generic status response about the state of server, MATLAB, MATLAB Licensing and the client session status.
|
|
98
102
|
|
|
99
103
|
Args:
|
|
100
104
|
app (aiohttp.web.Application): Web Server
|
|
101
105
|
loadUrl (String, optional): Represents the root URL. Defaults to None.
|
|
106
|
+
client_id (String, optional): Represents the unique client_id when concurrency check is enabled. Defaults to None.
|
|
107
|
+
transfer_session (Boolean, optional): Represents whether the connection should be transfered or not when concurrency check is enabled. Defaults to False.
|
|
108
|
+
is_desktop (Boolean, optional): Represents whether the request is made by the desktop app or some other kernel. Defaults to False.
|
|
102
109
|
|
|
103
110
|
Returns:
|
|
104
|
-
JSONResponse: A JSONResponse object containing the generic state of the server, MATLAB and
|
|
111
|
+
JSONResponse: A JSONResponse object containing the generic state of the server, MATLAB, MATLAB Licensing and the client session status.
|
|
105
112
|
"""
|
|
106
113
|
state = app["state"]
|
|
107
|
-
|
|
108
|
-
{
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
status = {
|
|
115
|
+
"matlab": {
|
|
116
|
+
"status": await state.get_matlab_state(),
|
|
117
|
+
"version": state.settings["matlab_version"],
|
|
118
|
+
},
|
|
119
|
+
"licensing": marshal_licensing_info(state.licensing),
|
|
120
|
+
"loadUrl": loadUrl,
|
|
121
|
+
"error": marshal_error(state.error),
|
|
122
|
+
"warnings": state.warnings,
|
|
123
|
+
"wsEnv": state.settings.get("ws_env", ""),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if IS_CONCURRENCY_CHECK_ENABLED and is_desktop:
|
|
127
|
+
if not client_id:
|
|
128
|
+
client_id = str(uuid.uuid4())
|
|
129
|
+
status["clientId"] = client_id
|
|
130
|
+
|
|
131
|
+
if not state.active_client or transfer_session:
|
|
132
|
+
state.active_client = client_id
|
|
133
|
+
|
|
134
|
+
status["isActiveClient"] = True if state.active_client == client_id else False
|
|
135
|
+
|
|
136
|
+
return web.json_response(status)
|
|
118
137
|
|
|
119
138
|
|
|
120
139
|
@token_auth.authenticate_access_decorator
|
|
@@ -150,13 +169,21 @@ async def get_env_config(req):
|
|
|
150
169
|
"""
|
|
151
170
|
state = req.app["state"]
|
|
152
171
|
config = state.settings["env_config"]
|
|
153
|
-
config["authEnabled"] = state.settings["mwi_is_token_auth_enabled"]
|
|
154
172
|
|
|
155
173
|
config["useMOS"] = mwi_env.Experimental.should_use_mos_html()
|
|
156
174
|
config["useMRE"] = mwi_env.Experimental.should_use_mre_html()
|
|
157
|
-
|
|
175
|
+
config["isConcurrencyEnabled"] = IS_CONCURRENCY_CHECK_ENABLED
|
|
158
176
|
# In a previously authenticated session, if the url is accessed without the token(using session cookie), send the token as well.
|
|
159
|
-
config["
|
|
177
|
+
config["authentication"] = {
|
|
178
|
+
"enabled": state.settings["mwi_is_token_auth_enabled"],
|
|
179
|
+
"status": True if await token_auth.authenticate_request(req) else False,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
config["matlab"] = {
|
|
183
|
+
"version": state.settings["matlab_version"],
|
|
184
|
+
"supported_versions": constants.SUPPORTED_MATLAB_VERSIONS,
|
|
185
|
+
}
|
|
186
|
+
|
|
160
187
|
return web.json_response(config)
|
|
161
188
|
|
|
162
189
|
|
|
@@ -172,7 +199,17 @@ async def get_status(req):
|
|
|
172
199
|
Returns:
|
|
173
200
|
JSONResponse: JSONResponse object containing information about the server, MATLAB and MATLAB Licensing.
|
|
174
201
|
"""
|
|
175
|
-
|
|
202
|
+
# The client sends the CLIENT_ID as a query parameter if the concurrency check has been set to true.
|
|
203
|
+
client_id = req.query.get("MWI_CLIENT_ID", None)
|
|
204
|
+
transfer_session = json.loads(req.query.get("TRANSFER_SESSION", "false"))
|
|
205
|
+
is_desktop = req.query.get("IS_DESKTOP", False)
|
|
206
|
+
|
|
207
|
+
return await create_status_response(
|
|
208
|
+
req.app,
|
|
209
|
+
client_id=client_id,
|
|
210
|
+
transfer_session=transfer_session,
|
|
211
|
+
is_desktop=is_desktop,
|
|
212
|
+
)
|
|
176
213
|
|
|
177
214
|
|
|
178
215
|
# @token_auth.authenticate_access_decorator
|
|
@@ -198,7 +235,7 @@ async def authenticate(req):
|
|
|
198
235
|
|
|
199
236
|
return web.json_response(
|
|
200
237
|
{
|
|
201
|
-
"
|
|
238
|
+
"status": is_authenticated,
|
|
202
239
|
"error": error,
|
|
203
240
|
}
|
|
204
241
|
)
|
|
@@ -263,11 +300,20 @@ async def set_licensing_info(req):
|
|
|
263
300
|
await state.set_licensing_nlm(data.get("connectionString"))
|
|
264
301
|
|
|
265
302
|
elif lic_type == "mhlm":
|
|
303
|
+
# If matlab version could not be determined on startup update
|
|
304
|
+
# the value received from the front-end.
|
|
305
|
+
if not state.settings.get(
|
|
306
|
+
"matlab_version_determined_on_startup"
|
|
307
|
+
) and data.get("matlabVersion"):
|
|
308
|
+
state.settings["matlab_version"] = data.get("matlabVersion")
|
|
309
|
+
|
|
266
310
|
await state.set_licensing_mhlm(
|
|
267
311
|
data.get("token"), data.get("emailAddress"), data.get("sourceId")
|
|
268
312
|
)
|
|
313
|
+
|
|
269
314
|
elif lic_type == "existing_license":
|
|
270
315
|
state.set_licensing_existing_license()
|
|
316
|
+
|
|
271
317
|
else:
|
|
272
318
|
raise Exception(
|
|
273
319
|
'License type must be "NLM" or "MHLM" or "ExistingLicense"!'
|
|
@@ -325,11 +371,18 @@ async def licensing_info_delete(req):
|
|
|
325
371
|
# Removing license information implies terminating MATLAB
|
|
326
372
|
await state.stop_matlab()
|
|
327
373
|
|
|
374
|
+
# When removing licensing data, if matlab version was fetched from the user, remove it
|
|
375
|
+
# on the server side to have a complete 'reset'.
|
|
376
|
+
if state.licensing["type"] == "mhlm" and not state.settings.get(
|
|
377
|
+
"matlab_version_determined_on_startup"
|
|
378
|
+
):
|
|
379
|
+
state.settings["matlab_version"] = None
|
|
380
|
+
|
|
328
381
|
# Unset licensing information
|
|
329
382
|
state.unset_licensing()
|
|
330
383
|
|
|
331
|
-
# Persist
|
|
332
|
-
state.
|
|
384
|
+
# Persist config information
|
|
385
|
+
state.persist_config_data()
|
|
333
386
|
|
|
334
387
|
return await create_status_response(req.app)
|
|
335
388
|
|
matlab_proxy/app_state.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2024 The MathWorks, Inc.
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import contextlib
|
|
@@ -17,7 +17,6 @@ from matlab_proxy.settings import (
|
|
|
17
17
|
from matlab_proxy.constants import (
|
|
18
18
|
CONNECTOR_SECUREPORT_FILENAME,
|
|
19
19
|
MATLAB_LOGS_FILE_NAME,
|
|
20
|
-
VERSION_INFO_FILE_NAME,
|
|
21
20
|
)
|
|
22
21
|
from matlab_proxy.util import mw, mwi, system, windows
|
|
23
22
|
from matlab_proxy.util.mwi import environment_variables as mwi_env
|
|
@@ -85,6 +84,7 @@ class AppState:
|
|
|
85
84
|
|
|
86
85
|
# Initialize with the error state from the initialization of settings
|
|
87
86
|
self.error = settings["error"]
|
|
87
|
+
self.warnings = settings["warnings"]
|
|
88
88
|
|
|
89
89
|
if self.error is not None:
|
|
90
90
|
self.logs["matlab"].clear()
|
|
@@ -100,40 +100,44 @@ class AppState:
|
|
|
100
100
|
# This variable can be either "up" or "down"
|
|
101
101
|
self.embedded_connector_state = "down"
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
# Specific to concurrent session and is used to track the active client/s that are currently
|
|
104
|
+
# connected to the backend
|
|
105
|
+
self.active_client = None
|
|
106
|
+
|
|
107
|
+
def __get_cached_config_file(self):
|
|
108
|
+
"""Get the cached config file
|
|
105
109
|
|
|
106
110
|
Returns:
|
|
107
|
-
Path : Path object to cached
|
|
111
|
+
Path : Path object to cached config file
|
|
108
112
|
"""
|
|
109
113
|
return self.settings["matlab_config_file"]
|
|
110
114
|
|
|
111
|
-
def
|
|
112
|
-
"""Deletes the cached
|
|
115
|
+
def __delete_cached_config_file(self):
|
|
116
|
+
"""Deletes the cached config file"""
|
|
113
117
|
try:
|
|
114
|
-
logger.info(f"Deleting any cached
|
|
115
|
-
os.remove(self.
|
|
118
|
+
logger.info(f"Deleting any cached config files!")
|
|
119
|
+
os.remove(self.__get_cached_config_file())
|
|
116
120
|
except FileNotFoundError:
|
|
117
121
|
# The file being absent is acceptable.
|
|
118
122
|
pass
|
|
119
123
|
|
|
120
|
-
def
|
|
121
|
-
"""Reset licensing variable of the class and removes the cached
|
|
122
|
-
logger.info(f"Resetting cached
|
|
124
|
+
def __reset_and_delete_cached_config(self):
|
|
125
|
+
"""Reset licensing variable of the class and removes the cached config file."""
|
|
126
|
+
logger.info(f"Resetting cached config information...")
|
|
123
127
|
self.licensing = None
|
|
124
|
-
self.
|
|
128
|
+
self.__delete_cached_config_file()
|
|
125
129
|
|
|
126
130
|
async def __update_and_persist_licensing(self):
|
|
127
|
-
"""Update entitlements from mhlm servers and persist
|
|
131
|
+
"""Update entitlements from mhlm servers and persist config data
|
|
128
132
|
|
|
129
133
|
Returns:
|
|
130
134
|
Boolean: True when entitlements were updated and persisted successfully. False otherwise.
|
|
131
135
|
"""
|
|
132
136
|
successful_update = await self.update_entitlements()
|
|
133
137
|
if successful_update:
|
|
134
|
-
self.
|
|
138
|
+
self.persist_config_data()
|
|
135
139
|
else:
|
|
136
|
-
self.
|
|
140
|
+
self.__reset_and_delete_cached_config()
|
|
137
141
|
return successful_update
|
|
138
142
|
|
|
139
143
|
async def init_licensing(self):
|
|
@@ -158,8 +162,8 @@ class AppState:
|
|
|
158
162
|
f"!!! Launching MATLAB without providing any additional licensing information. This requires MATLAB to have been activated on the machine from which its being launched !!!"
|
|
159
163
|
)
|
|
160
164
|
|
|
161
|
-
# Delete old
|
|
162
|
-
self.
|
|
165
|
+
# Delete old config info from cache to ensure its wiped out first before persisting new info.
|
|
166
|
+
self.__delete_cached_config_file()
|
|
163
167
|
|
|
164
168
|
# NLM Connection String set in environment
|
|
165
169
|
elif self.settings.get("nlm_conn_str", None) is not None:
|
|
@@ -171,17 +175,25 @@ class AppState:
|
|
|
171
175
|
"conn_str": nlm_licensing_str,
|
|
172
176
|
}
|
|
173
177
|
|
|
174
|
-
# Delete old
|
|
175
|
-
self.
|
|
178
|
+
# Delete old config info from cache to ensure its wiped out first before persisting new info.
|
|
179
|
+
self.__delete_cached_config_file()
|
|
176
180
|
|
|
177
181
|
# If NLM connection string is not present or if an existing license is not being used,
|
|
178
182
|
# then look for persistent LNU info
|
|
179
|
-
elif self.
|
|
180
|
-
with open(self.
|
|
183
|
+
elif self.__get_cached_config_file().exists():
|
|
184
|
+
with open(self.__get_cached_config_file(), "r") as f:
|
|
181
185
|
logger.debug("Found cached licensing information...")
|
|
182
186
|
try:
|
|
183
|
-
# Load can throw if the file is empty
|
|
184
|
-
|
|
187
|
+
# Load can throw if the file is empty or expected fields in the json object are missing.
|
|
188
|
+
cached_data = json.loads(f.read())
|
|
189
|
+
licensing = cached_data["licensing"]
|
|
190
|
+
matlab = cached_data["matlab"]
|
|
191
|
+
|
|
192
|
+
# If Matlab version could not be determined on startup and 'version' is available in
|
|
193
|
+
# cached config, update it.
|
|
194
|
+
if not self.settings["matlab_version"]:
|
|
195
|
+
self.settings["matlab_version"] = matlab["version"]
|
|
196
|
+
|
|
185
197
|
if licensing["type"] == "nlm":
|
|
186
198
|
# Note: Only NLM settings entered in browser were cached.
|
|
187
199
|
self.licensing = {
|
|
@@ -219,15 +231,15 @@ class AppState:
|
|
|
219
231
|
"Using cached Online Licensing to launch MATLAB."
|
|
220
232
|
)
|
|
221
233
|
else:
|
|
222
|
-
self.
|
|
234
|
+
self.__reset_and_delete_cached_config()
|
|
223
235
|
elif licensing["type"] == "existing_license":
|
|
224
236
|
logger.info("Using cached existing license to launch MATLAB")
|
|
225
237
|
self.licensing = licensing
|
|
226
238
|
else:
|
|
227
239
|
# Somethings wrong, licensing is neither NLM or MHLM
|
|
228
|
-
self.
|
|
240
|
+
self.__reset_and_delete_cached_config()
|
|
229
241
|
except Exception as e:
|
|
230
|
-
self.
|
|
242
|
+
self.__reset_and_delete_cached_config()
|
|
231
243
|
|
|
232
244
|
async def get_matlab_state(self):
|
|
233
245
|
"""Determine the state of MATLAB to be down/starting/up.
|
|
@@ -255,7 +267,10 @@ class AppState:
|
|
|
255
267
|
xvfb_process = self.processes["xvfb"]
|
|
256
268
|
|
|
257
269
|
if system.is_linux():
|
|
258
|
-
|
|
270
|
+
# If Xvfb is on system PATH, check if it up and running.
|
|
271
|
+
if self.settings["is_xvfb_available"] and (
|
|
272
|
+
xvfb_process is None or xvfb_process.returncode is not None
|
|
273
|
+
):
|
|
259
274
|
logger.debug(
|
|
260
275
|
"Xvfb has not started"
|
|
261
276
|
if xvfb_process is None
|
|
@@ -355,12 +370,12 @@ class AppState:
|
|
|
355
370
|
|
|
356
371
|
# TODO Validate connection string
|
|
357
372
|
self.licensing = {"type": "nlm", "conn_str": conn_str}
|
|
358
|
-
self.
|
|
373
|
+
self.persist_config_data()
|
|
359
374
|
|
|
360
375
|
def set_licensing_existing_license(self):
|
|
361
376
|
"""Set the licensing type to NLM and the connection string."""
|
|
362
377
|
self.licensing = {"type": "existing_license"}
|
|
363
|
-
self.
|
|
378
|
+
self.persist_config_data()
|
|
364
379
|
|
|
365
380
|
async def set_licensing_mhlm(
|
|
366
381
|
self,
|
|
@@ -461,17 +476,6 @@ class AppState:
|
|
|
461
476
|
"MHLM licensing must be configured to update entitlements!"
|
|
462
477
|
)
|
|
463
478
|
|
|
464
|
-
# TODO: Updating entitlements requires the matlab version. If it
|
|
465
|
-
# could not be determined at server startup, take input from the user
|
|
466
|
-
# for the MATLAB version they intend to start and update settings.
|
|
467
|
-
|
|
468
|
-
# As MHLM licensing requires matlab version to update entitlements, if it couldn't be determined
|
|
469
|
-
# for now show an error to the user to set MWI_CUSTOM_MATLAB_ROOT env var.
|
|
470
|
-
if self.settings["matlab_version"] is None:
|
|
471
|
-
raise UIVisibleFatalError(
|
|
472
|
-
f"Could not find {VERSION_INFO_FILE_NAME} file at MATLAB root. Set {mwi_env.get_env_name_custom_matlab_root()} to a valid MATLAB root path"
|
|
473
|
-
)
|
|
474
|
-
|
|
475
479
|
try:
|
|
476
480
|
# Fetch an access token
|
|
477
481
|
access_token_data = await mw.fetch_access_token(
|
|
@@ -532,19 +536,23 @@ class AppState:
|
|
|
532
536
|
async def update_user_selected_entitlement_info(self, entitlement_id):
|
|
533
537
|
self.licensing["entitlement_id"] = entitlement_id
|
|
534
538
|
logger.debug(f"Successfully set {entitlement_id} as the entitlement_id")
|
|
535
|
-
self.
|
|
539
|
+
self.persist_config_data()
|
|
536
540
|
|
|
537
|
-
def
|
|
538
|
-
"""Saves
|
|
541
|
+
def persist_config_data(self):
|
|
542
|
+
"""Saves config information to file"""
|
|
539
543
|
if self.licensing is None:
|
|
540
|
-
self.
|
|
544
|
+
self.__delete_cached_config_file()
|
|
541
545
|
|
|
542
546
|
elif self.licensing["type"] in ["mhlm", "nlm", "existing_license"]:
|
|
543
547
|
logger.debug("Saving licensing information...")
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
+
cached_config_file = self.__get_cached_config_file()
|
|
549
|
+
cached_config_file.parent.mkdir(parents=True, exist_ok=True)
|
|
550
|
+
config = {
|
|
551
|
+
"licensing": self.licensing,
|
|
552
|
+
"matlab": {"version": self.settings["matlab_version"]},
|
|
553
|
+
}
|
|
554
|
+
with open(cached_config_file, "w") as f:
|
|
555
|
+
f.write(json.dumps(config))
|
|
548
556
|
|
|
549
557
|
def create_logs_dir_for_MATLAB(self):
|
|
550
558
|
"""Creates the root folder where MATLAB writes the ready file and updates attibutes on self."""
|
|
@@ -671,9 +679,22 @@ class AppState:
|
|
|
671
679
|
# DDUX info for MATLAB
|
|
672
680
|
matlab_env["MW_CONTEXT_TAGS"] = self.settings.get("mw_context_tags")
|
|
673
681
|
|
|
682
|
+
# Update DISPLAY env variable for MATLAB only if it was supplied by Xvfb.
|
|
674
683
|
if system.is_linux():
|
|
675
|
-
|
|
676
|
-
|
|
684
|
+
if self.settings.get("matlab_display", None):
|
|
685
|
+
matlab_env["DISPLAY"] = self.settings["matlab_display"]
|
|
686
|
+
logger.info(
|
|
687
|
+
f"Using the display number supplied by Xvfb process:{matlab_env['DISPLAY']} for launching MATLAB"
|
|
688
|
+
)
|
|
689
|
+
else:
|
|
690
|
+
if "DISPLAY" in matlab_env:
|
|
691
|
+
logger.info(
|
|
692
|
+
f"Using the existing DISPLAY environment variable with value:{matlab_env['DISPLAY']} for launching MATLAB"
|
|
693
|
+
)
|
|
694
|
+
else:
|
|
695
|
+
logger.info(
|
|
696
|
+
"No DISPLAY environment variable found. Launching MATLAB without it."
|
|
697
|
+
)
|
|
677
698
|
|
|
678
699
|
# The matlab ready file is written into this location(self.mwi_logs_dir) by MATLAB
|
|
679
700
|
# The mwi_logs_dir is where MATLAB will write any subsequent logs
|
|
@@ -968,8 +989,8 @@ class AppState:
|
|
|
968
989
|
self.error = None
|
|
969
990
|
self.logs["matlab"].clear()
|
|
970
991
|
|
|
971
|
-
# Start Xvfb process
|
|
972
|
-
if system.is_linux():
|
|
992
|
+
# Start Xvfb process on linux if possible
|
|
993
|
+
if system.is_linux() and self.settings["is_xvfb_available"]:
|
|
973
994
|
xvfb = await self.__start_xvfb_process()
|
|
974
995
|
|
|
975
996
|
# xvfb variable would be None if creation of the process failed.
|
matlab_proxy/constants.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# Copyright 2023 The MathWorks, Inc.
|
|
2
|
-
from typing import Final
|
|
1
|
+
# Copyright 2023-2024 The MathWorks, Inc.
|
|
2
|
+
from typing import Final, List
|
|
3
3
|
|
|
4
4
|
"""This module defines project-level constants"""
|
|
5
5
|
|
|
@@ -12,3 +12,16 @@ MATLAB_LOGS_FILE_NAME: Final[str] = "matlab_logs.txt"
|
|
|
12
12
|
# This constant is meant for internal use within matlab-proxy
|
|
13
13
|
# Clients of this package should use settings.py::get_process_startup_timeout() function
|
|
14
14
|
DEFAULT_PROCESS_START_TIMEOUT: Final[int] = 600
|
|
15
|
+
|
|
16
|
+
SUPPORTED_MATLAB_VERSIONS: Final[List[str]] = [
|
|
17
|
+
"R2020b",
|
|
18
|
+
"R2021a",
|
|
19
|
+
"R2021b",
|
|
20
|
+
"R2022a",
|
|
21
|
+
"R2022b",
|
|
22
|
+
"R2023a",
|
|
23
|
+
"R2023b",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
# This constant when set to True restricts the number of active sessions to one
|
|
27
|
+
IS_CONCURRENCY_CHECK_ENABLED: Final[bool] = True
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
|
-
"main.css": "./static/css/main.
|
|
4
|
-
"main.js": "./static/js/main.
|
|
3
|
+
"main.css": "./static/css/main.47712126.css",
|
|
4
|
+
"main.js": "./static/js/main.ea1ebdce.js",
|
|
5
5
|
"static/media/mathworks-pictograms.svg?20181009": "./static/media/mathworks-pictograms.f6f087b008b5a9435f26.svg",
|
|
6
6
|
"static/media/MATLAB-env-blur.png": "./static/media/MATLAB-env-blur.4fc94edbc82d3184e5cb.png",
|
|
7
7
|
"static/media/mathworks.svg?20181004": "./static/media/mathworks.80a3218e1ba29f0573fb.svg",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"index.html": "./index.html",
|
|
35
35
|
"static/media/gripper.svg": "./static/media/gripper.9defbc5e76d0de8bb6e0.svg",
|
|
36
36
|
"static/media/arrow.svg": "./static/media/arrow.0c2968b90bd9a64c8c3f.svg",
|
|
37
|
-
"main.
|
|
38
|
-
"main.
|
|
37
|
+
"main.47712126.css.map": "./static/css/main.47712126.css.map",
|
|
38
|
+
"main.ea1ebdce.js.map": "./static/js/main.ea1ebdce.js.map"
|
|
39
39
|
},
|
|
40
40
|
"entrypoints": [
|
|
41
|
-
"static/css/main.
|
|
42
|
-
"static/js/main.
|
|
41
|
+
"static/css/main.47712126.css",
|
|
42
|
+
"static/js/main.ea1ebdce.js"
|
|
43
43
|
]
|
|
44
44
|
}
|
matlab_proxy/gui/index.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MATLAB"/><meta name="internal_mw_identifier" content="MWI_MATLAB_PROXY_IDENTIFIER"/><link rel="manifest" href="./manifest.json"/><title>MATLAB</title><script defer="defer" src="./static/js/main.
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MATLAB"/><meta name="internal_mw_identifier" content="MWI_MATLAB_PROXY_IDENTIFIER"/><link rel="manifest" href="./manifest.json"/><title>MATLAB</title><script defer="defer" src="./static/js/main.ea1ebdce.js"></script><link href="./static/css/main.47712126.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|