Skip to content

Commit

Permalink
Added createTempFile to sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
klein0r committed May 9, 2024
1 parent aa5d322 commit 5e04177
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -44,6 +44,7 @@ Since v5.5.0 of the JavaScript adapter the following locations (relative to the
-->
### **WORK IN PROGRESS**

* (klein0r) Added createTempFile to sandbox
* (klein0r) Fixed log message on script start
* (klein0r) Added instance/from to log window (like in admin)

Expand Down
15 changes: 15 additions & 0 deletions docs/en/javascript.md
Expand Up @@ -1926,6 +1926,21 @@ httpPost(
);
```
### createTempFile
```js
httpGet('https://raw.githubusercontent.com/ioBroker/ioBroker.javascript/master/admin/javascript.png', { responseType: 'arraybuffer' }, async (err, response) => {
if (err) {
console.error(err);
} else {
const tempFilePath = createTempFile('javascript.png', response.data);
console.log(`Saved to ${tempFilePath}`);

// Use the new path in other scripts (e.g. sendTo)
}
});
```
## Global script variables
### scriptName
`scriptName` - The name of the script.
Expand Down
5 changes: 5 additions & 0 deletions lib/javascript.d.ts
Expand Up @@ -1335,6 +1335,11 @@ declare global {
function httpPostAsync(url: string, data: object | string): Promise<iobJS.httpResponse>;
function httpPostAsync(url: string, data: object | string, options: iobJS.HttpRequestOptions): Promise<iobJS.httpResponse>;

/**
* Creates a temp directory for the current script and saves a new file with given content
*/
function createTempFile(fileName: string, data: string | ArrayBuffer) : string;

/**
* Subscribe to the changes of the matched states.
*/
Expand Down
23 changes: 23 additions & 0 deletions lib/sandbox.js
Expand Up @@ -1273,6 +1273,29 @@ function sandBox(script, name, verbose, debug, context) {
}
});
},
createTempFile: function(fileName, data) {
const os = mods.os;
const path = mods.path;
const fs = mods.fs;

let tempDirPath = context.tempDirectories?.[sandbox.scriptName];

if (!tempDirPath) {
// create temp directory
tempDirPath = fs.mkdtempSync(path.join(os.tmpdir(), `${sandbox.scriptName.substring('script.js.'.length)}-`));
context.tempDirectories[sandbox.scriptName] = tempDirPath;

sandbox.verbose && sandbox.log(`createTempFile(fileName=${fileName}, tempDirPath=${tempDirPath}) created temp directory in ${os.tmpdir()}`, 'info');
}

const filePath = path.join(tempDirPath, fileName);

fs.writeFileSync(filePath, data);

sandbox.verbose && sandbox.log(`createTempFile(fileName=${fileName}, tempDirPath=${tempDirPath}, filePath=${filePath})`, 'info');

return filePath;
},
subscribe: function (pattern, callbackOrId, value) {
if ((typeof pattern === 'string' && pattern[0] === '{') || (typeof pattern === 'object' && pattern.period)) {
return sandbox.schedule(pattern, callbackOrId);
Expand Down
17 changes: 16 additions & 1 deletion main.js
Expand Up @@ -262,7 +262,7 @@ const context = {
subscriptionsFile: [],
subscriptionsObject: [],
subscribedPatterns: {},
subscribedPatternsFile: {},
subscribedPatternsFile: {},
adapterSubs: {},
cacheObjectEnums: {},
isEnums: false, // If some subscription wants enum
Expand All @@ -277,6 +277,7 @@ const context = {
scripts: {},
messageBusHandlers: {},
logSubscriptions: {},
tempDirectories: {},
folderCreationVerifiedObjects: {},
updateLogSubscriptions,
convertBackStringifiedValues,
Expand Down Expand Up @@ -1032,6 +1033,8 @@ function main() {
!debugMode && patchFont()
.then(patched => patched && adapter.log.debug('Font patched'));

adapter.log.debug(`config.subscribe (Do not subscribe all states on start): ${adapter.config.subscribe}`);

// correct jsonConfig for admin
adapter.getForeignObject(`system.adapter.${adapter.namespace}`, (err, obj) => {
if (obj && obj.common) {
Expand Down Expand Up @@ -1957,6 +1960,18 @@ function stop(name, callback) {
delete context.messageBusHandlers[name];
}

if (context.tempDirectories[name]) {
try {
mods.fs.rmSync(context.tempDirectories[name], { recursive: true });

adapter.log.debug(`Removed temp directory of ${name}: ${context.tempDirectories[name]}`);
} catch (err) {
adapter.log.warn(`Unable to remove temp directory of ${name}: ${context.tempDirectories[name]}`);
}

delete context.tempDirectories[name];
}

if (context.logSubscriptions[name]) {
delete context.logSubscriptions[name];
updateLogSubscriptions();
Expand Down
44 changes: 44 additions & 0 deletions test/testFunctions.js
Expand Up @@ -604,6 +604,50 @@ describe.only('Test JS', function () {
});
});

it('Test JS: create a temp directory must work', function (done) {
this.timeout(3000);
const os = require('node:os');
const fs = require('node:fs');

// add script
const script = {
_id: 'script.js.test_createTempFile',
type: 'script',
common: {
name: 'test create temp file',
enabled: true,
verbose: true,
engine: 'system.adapter.javascript.0',
engineType: 'Javascript/js',
source: `createState('testCreateTempFile', '-', () => {\n` +
` const filePath = createTempFile('test.txt', 'CONTENT_OK');\n` +
` setState('testCreateTempFile', { val: filePath, ack: true });\n` +
`});`,
},
native: {}
};
const onStateChanged = function (id, state) {
if (id === 'javascript.0.testCreateTempFile' && state.ack) {
const tempFilePath = state.val;

expect(tempFilePath).to.be.a('string');
expect(tempFilePath.startsWith(os.tmpdir())).to.be.true;
expect(fs.existsSync(tempFilePath)).to.be.true;

// Check content
const fileContent = fs.readFileSync(tempFilePath);
expect(fileContent).to.be.equal('CONTENT_OK');

removeStateChangedHandler(onStateChanged);
done();
}
};
addStateChangedHandler(onStateChanged);
objects.setObject(script._id, script, err => {
expect(err).to.be.not.ok;
});
});

it('Test JS: test getAstroDate', function (done) {
this.timeout(6000);
const types = [
Expand Down

0 comments on commit 5e04177

Please sign in to comment.