From f86bdd6dfa6f873c9e72263fa0eef200998c631f Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Tue, 17 Jun 2025 17:52:09 +0300 Subject: [PATCH 1/7] [bug] Fix handling of null entries in imgurls; For bug 75266 --- DocService/sources/canvasservice.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index a807e819..8e6417e8 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -735,7 +735,7 @@ function* commandImgurls(ctx, conn, cmd, outputData) { var urlSource = urls[i]; var urlParsed; var data = undefined; - if (urlSource.startsWith('data:')) { + if (urlSource?.startsWith('data:')) { let delimiterIndex = urlSource.indexOf(','); if (-1 != delimiterIndex) { let dataLen = urlSource.length - (delimiterIndex + 1); @@ -777,10 +777,10 @@ function* commandImgurls(ctx, conn, cmd, outputData) { } } - data = yield utilsDocService.fixImageExifRotation(ctx, data); - var outputUrl = {url: 'error', path: 'error'}; if (data) { + data = yield utilsDocService.fixImageExifRotation(ctx, data); + let format = formatChecker.getImageFormat(ctx, data); let formatStr; let isAllow = false; From e768c416c0aa2e459aadaee9e1cc16f24059b0da Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Wed, 18 Jun 2025 16:16:08 +0300 Subject: [PATCH 2/7] [bug] Rename button state labels; Fix bug 75325 --- branding/info/js/ai-integration.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/branding/info/js/ai-integration.js b/branding/info/js/ai-integration.js index 48cd3486..9dd5e6a3 100644 --- a/branding/info/js/ai-integration.js +++ b/branding/info/js/ai-integration.js @@ -276,7 +276,7 @@ const AIIntegration = { const btnResetActions = document.getElementById('ai-btn-reset-actions'); if (btnResetActions) { const originalText = btnResetActions.textContent; - btnResetActions.textContent = res ? 'Actions Reset!' : 'Reset Failed!'; + btnResetActions.textContent = res ? 'Tasks Reset!' : 'Reset Failed!'; btnResetActions.disabled = true; setTimeout(() => { btnResetActions.textContent = originalText; @@ -293,7 +293,7 @@ const AIIntegration = { const btnResetAllSettings = document.getElementById('ai-btn-reset-all-settings'); if (btnResetAllSettings) { const originalText = btnResetAllSettings.textContent; - btnResetAllSettings.textContent = res ? 'Settings Reset!' : 'Reset Failed!'; + btnResetAllSettings.textContent = res ? 'Defaults Restored!' : 'Restore Failed!'; btnResetAllSettings.disabled = true; setTimeout(() => { btnResetAllSettings.textContent = originalText; From 69f923c7bbc8ff1e07cbc36865891cb39d8a3a44 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Wed, 25 Jun 2025 15:42:39 +0300 Subject: [PATCH 3/7] [bug] Move runtimeConfig init to server start; Fix bug 75439 --- Common/sources/runtimeConfigManager.js | 16 ++++++---------- DocService/sources/DocsCoServer.js | 5 ++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Common/sources/runtimeConfigManager.js b/Common/sources/runtimeConfigManager.js index 0001e3b1..7c48386b 100644 --- a/Common/sources/runtimeConfigManager.js +++ b/Common/sources/runtimeConfigManager.js @@ -46,7 +46,6 @@ const configFileName = path.basename(configFilePath); // Initialize cache with TTL and check for expired keys every minute const nodeCache = new NodeCache(cfgRuntimeConfig.cache); -let isInitConfigWatcher = false; /** * Get runtime configuration for the current context @@ -54,10 +53,7 @@ let isInitConfigWatcher = false; * @returns {Object} Runtime configuration object */ async function getConfigFromFile(ctx) { - if (!isInitConfigWatcher) { - isInitConfigWatcher = true; - initConfigWatcher(ctx); - } + try { const configData = await fs.readFile(configFilePath, 'utf8'); return JSON.parse(configData); @@ -116,20 +112,20 @@ function handleConfigFileChange(eventType, filename) { /** * Initialize the configuration directory watcher */ -function initConfigWatcher(ctx) { +function initRuntimeConfigWatcher(ctx) { try { const configDir = path.dirname(configFilePath); const watcher = fsWatch.watch(configDir, handleConfigFileChange); watcher.on('error', (err) => { - ctx.logger.error(`initConfigWatcher error: ${err.message}`); + ctx.logger.error(`initRuntimeConfigWatcher error: ${err.message}`); }); - ctx.logger.info(`initConfigWatcherWatching for changes in: ${configDir}`); + ctx.logger.info(`watching for runtime config changes in: ${configDir}`); } catch (watchErr) { - ctx.logger.error(`initConfigWatcher error: ${watchErr.message}`); + ctx.logger.error(`initRuntimeConfigWatcher error: ${watchErr.message}`); } } - module.exports = { + initRuntimeConfigWatcher, getConfig, saveConfig }; diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 0987dc20..6b48f3f0 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -101,6 +101,7 @@ const pubsubService = require('./pubsubRabbitMQ'); const wopiClient = require('./wopiClient'); const queueService = require('./../../Common/sources/taskqueueRabbitMQ'); const operationContext = require('./../../Common/sources/operationContext'); +const runtimeConfigManager = require('./../../Common/sources/runtimeConfigManager'); const tenantManager = require('./../../Common/sources/tenantManager'); const { notificationTypes, ...notificationService } = require('../../Common/sources/notificationService'); const aiProxyHandler = require('./ai/aiProxyHandler'); @@ -3999,7 +4000,9 @@ exports.install = function(server, callbackFunction) { ); }); }); - + + //Initialize watch here to avoid circular import with operationContext + runtimeConfigManager.initRuntimeConfigWatcher(operationContext.global); void aiProxyHandler.getPluginSettings(operationContext.global); }; exports.setLicenseInfo = async function(globalCtx, data, original) { From 914af69953d4a5af6b0ffb0e55ca8788b54fcf6c Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 27 Jun 2025 12:28:49 +0300 Subject: [PATCH 4/7] [bug] Remove priority decrease for PDF, XPS, and DJVU conversions (browser opening) --- DocService/sources/canvasservice.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 8e6417e8..378e48f5 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -538,15 +538,7 @@ function* commandOpen(ctx, conn, cmd, outputData, opt_upsertRes, opt_bIsRestore) dataQueue.setCtx(ctx); dataQueue.setCmd(cmd); dataQueue.setToFile('Editor.bin'); - var priority = constants.QUEUE_PRIORITY_HIGH; - var formatIn = formatChecker.getFormatFromString(cmd.getFormat()); - //decrease pdf, djvu, xps convert priority becase long open time - if (constants.AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF === formatIn || - constants.AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU === formatIn || - constants.AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS === formatIn) { - priority = constants.QUEUE_PRIORITY_LOW; - } - yield* docsCoServer.addTask(dataQueue, priority); + yield* docsCoServer.addTask(dataQueue, constants.QUEUE_PRIORITY_HIGH); } else { yield* commandOpenFillOutput(ctx, conn, cmd, outputData, opt_bIsRestore); } From e0bcffda130b81d7610c45084638dc04487f8c9e Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Mon, 30 Jun 2025 00:27:41 +0300 Subject: [PATCH 5/7] [bug] Set noDelay=true if the client intentionally closes connection or server shuts down; For bug 75503 --- DocService/sources/DocsCoServer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 6b48f3f0..03f601de 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -1984,7 +1984,9 @@ exports.install = function(server, callbackFunction) { if (needSaveChanges && !conn.encrypted) { // Send changes to save server let user_lcid = utilsDocService.localeToLCID(conn.lang); - yield createSaveTimer(ctx, docId, tmpUser.idOriginal, userIndex, user_lcid, undefined, getIsShutdown()); + //noDelay=true if the client intentionally closes connection or server shuts down + const noDelay = !reason || getIsShutdown(); + yield createSaveTimer(ctx, docId, tmpUser.idOriginal, userIndex, user_lcid, undefined, noDelay); } else if (needSendStatus) { yield* cleanDocumentOnExitNoChanges(ctx, docId, tmpUser.idOriginal, userIndex); } else { From 0f6412b6a4ed0cb64f6fbf862c8088f1ff325f46 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Mon, 30 Jun 2025 14:05:23 +0300 Subject: [PATCH 6/7] Fix bug 75287 --- dictionaries/update.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dictionaries/update.py b/dictionaries/update.py index 37f51471..b614d635 100644 --- a/dictionaries/update.py +++ b/dictionaries/update.py @@ -76,9 +76,12 @@ for file in filesReplace: testDevelopVersion = sdkjsDirectory + "/.git" if not os.path.isdir(testDevelopVersion): print("Not in develop version, skipping x2t cache update") + x2tDir = curDirectory + "/../FileConverter/bin" + cur_dir = os.getcwd() + os.chdir(x2tDir) x2tBin = curDirectory + "/../FileConverter/bin/x2t" if ("windows" == platform.system().lower()): - x2tBin += ".exe" - subprocess.call([x2tBin, "-create-js-cache"], stderr=subprocess.STDOUT, shell=True) - command = x2tBin + " -create-js-cache" - subprocess.call(command, stderr=subprocess.STDOUT, shell=True) + subprocess.call(["x2t.exe", "-create-js-cache"], stderr=subprocess.STDOUT, shell=True) + else: + subprocess.call("x2t -create-js-cache", stderr=subprocess.STDOUT, shell=True) + os.chdir(cur_dir) From c7d0d7f9914439c7daf9cc0c50b52f688ebb3cfb Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Tue, 1 Jul 2025 19:08:59 +0300 Subject: [PATCH 7/7] [bug] Support empty runtimeConfig.filePath to disable runtime config --- Common/sources/runtimeConfigManager.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Common/sources/runtimeConfigManager.js b/Common/sources/runtimeConfigManager.js index 7c48386b..1d9a8282 100644 --- a/Common/sources/runtimeConfigManager.js +++ b/Common/sources/runtimeConfigManager.js @@ -53,7 +53,9 @@ const nodeCache = new NodeCache(cfgRuntimeConfig.cache); * @returns {Object} Runtime configuration object */ async function getConfigFromFile(ctx) { - + if (!configFilePath) { + return null; + } try { const configData = await fs.readFile(configFilePath, 'utf8'); return JSON.parse(configData); @@ -85,6 +87,9 @@ async function getConfig(ctx) { * @returns {Object} Saved configuration object */ async function saveConfig(ctx, config) { + if (!configFilePath) { + throw new Error('runtimeConfig.filePath is not specified'); + } await fs.mkdir(path.dirname(configFilePath), { recursive: true }); let newConfig = await getConfig(ctx); newConfig = utils.deepMergeObjects(newConfig || {}, config); @@ -113,15 +118,19 @@ function handleConfigFileChange(eventType, filename) { * Initialize the configuration directory watcher */ function initRuntimeConfigWatcher(ctx) { + if (!configFilePath) { + ctx.logger.info(`runtimeConfig.filePath is not specified`); + return; + } try { const configDir = path.dirname(configFilePath); const watcher = fsWatch.watch(configDir, handleConfigFileChange); watcher.on('error', (err) => { - ctx.logger.error(`initRuntimeConfigWatcher error: ${err.message}`); + ctx.logger.warn(`initRuntimeConfigWatcher error: ${err.message}`); }); ctx.logger.info(`watching for runtime config changes in: ${configDir}`); } catch (watchErr) { - ctx.logger.error(`initRuntimeConfigWatcher error: ${watchErr.message}`); + ctx.logger.warn(`initRuntimeConfigWatcher error: ${watchErr.message}`); } } module.exports = {