I am currently working on a NodeJS (Express) project to edit images' metadata with Exiftool.
To edit images' metadata with Exiftool, I've to create a JSON file containing all metadata to modify then execute the command :
exiftool -j=metadata.json pathToTheImage/image.jpg
The json file must look like that :
[{"SourceFile":"pathToTheImage/image.jpg","XMP-dc:Title":"Image's title"}]
Here's my code to do that :
const {exec} = require('child_process');
let fs = require('fs');
let uploadPath = "uploads";
let uploadName = "image.jpg";
...
app.post('/metadata/editor', (req, res) => {
let jsonToImport = [...];
fs.writeFileSync("metadata.json", JSON.stringify(jsonToImport));
exec('exiftool -j=metadata.json ' + uploadPath + '/' + uploadName, (error, stdout, stderr) => {
if (error) {
console.error(error);
return;
}
res.redirect('/metadata/checker/' + uploadName);
});
});
The problem is at the level of "writeFileSync/exec".
Independently these two lines work well, that's to say that if I've just the first line, the JSON file is well created. And if I've just the second ligne, image's metadata are well updated.
But when I execute this two lines together, the JSON file is well created but the exec line do "nothing" (or something that I can't determine).
This code uses synchronous functions, I've test it with asynchronous functions, this is the same behavior.
Currently, to do what I need, I must execute the code above to create the JSON file, then I must comment the writeFileSync line and I must reexecute the code to update image's metadata correctly.
It's really strange, I've try to read the JSON file content before the exec line but everything is ok. I've use asynchronous functions, with and without promise... there is nothing to do it doesn't work.
Thank you for your help.
I'll answer my own question:
The problem was that I use nodemon, however by default nodemon watches JSON files. But in my code I created a JSON file to use it right after. So, I created the JSON file correctly, nodemon sees it, and restarts the node server; the rest of the code does not run.
To fix this, I added an option to ignore the created files in my package.json:
"nodemonConfig": {
"ignore": [
"path/to/files/to/ingore/*"
]
}
Related
I'm trying to set up the configuration and mock files for jest to parse/ignore image files in order for the tests to pass. Just about every online resource leads me to the jest docs located: https://jestjs.io/docs/webpack#handling-static-assets
which tell you exactly how to handle the situation. However, not in my case. I've tried both options of creating mock files and using a transformer.
My current jest.config.js:
module.exports = {
projects: [
{
displayName: 'Unit',
testMatch: ["**/?(*.)+(spec|test).[tj]s?(x)"],
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
testPathIgnorePatterns: ["<rootDir>/.next/", "<rootDir>/node_modules/", "<rootDir>/cypress/"],
moduleFileExtensions: ["js", "jsx", "ts", "tsx"],
moduleDirectories: ["node_modules", "bower_components", "shared"],
moduleNameMapper: {
"^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
'^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js'
},
// transform: {
// "\\.js$": "jest",
// "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
// //'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
// }
},
{
displayName: 'Pacts',
testMatch: ["**/?(*.)+(pacttest).[tj]s?(x)"],
testPathIgnorePatterns: ["<rootDir>/.next/", "<rootDir>/node_modules/", "<rootDir>/cypress/"],
watchPathIgnorePatterns: ["pact/logs/*", "pact/pacts/*"],
}
],
};
my fileMock.js:
module.exports = 'test-file-stub';
My styleMock.js:
module.exports = {};
My fileTransformer.js:
const path = require('path');
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
},
};
//export default module.exports;
my directory:
I've been bouncing back and forth trying different options in the configurations but they pretty much all lead me to the same two errors, one when I try to use the transformer, and another without. With the transformer commented out, I get 2 errors thrown at the fileMock.js file:
TypeError: Invalid URL: test-file-stub
Failed to parse src "test-file-stub" on next/image
Both of these are referring to the suggested string for the mock. I initially thought that maybe the string was a placeholder for code to actually handle something. But after some reading, my understanding is that it's actually just supposed to be a string there. Perhaps it's a specific string dependent on my environment? And next/image is where I'm importing the image component from.
I'm prioritizing the mocking (please correct me if I'm wrong) because my understand is the mock tells jest to ignore the image file and proceed with the rest of the test while the transformer actually attempts to change the file type from js to jpg or png or whatever filetype the image is. However, I'm trying everything I can. When I try to the run the tests with the transformer portion uncommented I receive an error before any tests are even run stating:
TypeError: Jest: a transformm must export something.
(which is why there is a commented out export default statement.)
This is my first time ever attempting anything like this and I think I've reached a point where I cannot think of anything else to try. If anybody has experienced anything like this please lay some knowledge on me. I'm not sure if I have the mockfiles set up incorrectly or if it's something in the configurations.
Thanks.
I was able to work around this by creating an image URL here:
https://www.base64-image.de/
and replacing the "test-file-stub" string with the generated URL string.
module.exports = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV/TSotUHeyg4pChOogFURFHrUIRKoRaoVUHk0s/hCYNSYuLo+BacPBjserg4qyrg6sgCH6AuLk5KbpIif9LCi1iPDjux7t7j7t3gFAvMc0KjAGaXjFTibiYya6IwVeE0I9ujCAgM8uYlaQkPMfXPXx8vYvxLO9zf44uNWcxwCcSzzDDrBCvE09tVgzO+8QRVpRV4nPiUZMuSPzIdcXlN84FhwWeGTHTqTniCLFYaGOljVnR1IgniaOqplO+kHFZ5bzFWStVWfOe/IXhnL68xHWag0hgAYuQIEJBFRsooYIYrTopFlK0H/fwDzh+iVwKuTbAyDGPMjTIjh/8D353a+Unxt2kcBzoeLHtjyEguAs0arb9fWzbjRPA/wxc6S1/uQ5Mf5Jea2nRI6BnG7i4bmnKHnC5A/Q9GbIpO5KfppDPA+9n9E1ZoPcW6Fx1e2vu4/QBSFNXyRvg4BAYLlD2mse7Q+29/Xum2d8PVXFym6OczU4AAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQflCBkOKh9/wZ+SAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAAxJREFUCNdj+P//PwAF/gL+3MxZ5wAAAABJRU5ErkJggg==';
I want to keep my test data in a JSON file that I need to import in cucumber-protractor custom framework. I read we can directly require a JSON file or even use protractor params. However that doesn't work. I don't see the JSON file listed when requiring from a particular folder.
testdata.json
{
"name":"testdata",
"version":"1.0.0",
"username":"1020201",
"password":"1020201"
}
Code in the Config.js
onPrepare: function() {
var data = require('./testdata.json');
},
I don't see the testdata.json file when giving path in require though its available at the location.
I wish to access JSON data using data.name, data.version etc.
Following is my folder structure:
You should make sure your json file is located in the current directory & and in the same folder where your config file resides as you are giving this path require('./testdata.json'); -
There are many ways of setting your data variables and accessing them globally in your test scripts -
1st method: Preferred method is to use node's global object -
onPrepare: function() {
global.data = require('./testdata.json');
},
Now you could access data anywhere in your scripts.
2nd Method Is to use protractor's param object -
exports.config = {
params: {
data: require('./testdata.json');
}
};
you can then access it in the specs/test scripts using browser.params.data
I have a parse-server hosted by heroku, which has an index.js file utilized for its configuration. I want to use Mailgun to up functionality for the user to request a password reset, and I have set up the config file, following this answer, as follows:
var api = new ParseServer({
appName: 'App Name',
publicServerURL: 'https://<name>.herokuapp.com/parse',
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || 'myAppId',
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it $
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't$
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query s$
},
push: JSON.parse(process.env.SERVER_PUSH || "{}"),
verifyUserEmails: true, //causing errors
emailAdapter: { //causing errors
module: 'parse-server-simple-mailgun-adapter',
options: {
fromAddress: 'parse#example.com',
domain: '<domain>',
apiKey: '<key>',
}
}
});
This code does not work, though, because of the verifyUserEmails and emailAdapter. Removing both of them removes the "JSON text did not start with array" error. Adding either one of them back in results in the error being thrown. I have no idea why, though, since I do not see any obvious reason as to how they aren't being set up in an array correctly?
Do I need to set up the cooresponding config vars in heroku in addition to having them in the config file? I considered this, but appName and publicServerURL are not set up in this way and don't give this error.
emailAdapter.options.apiKey doesn't need a comma at the end since its the last element of it's JSON.
I wouldn't be surprised that you're also leaving in the comma at the end of verifyUserEmails when you include it improperly as well.
options: {
fromAddress: 'parse#example.com',
domain: '<domain>',
apiKey: '<key>',
}
This is not valid JSON, because there is a comma at the end of the apiKey line. The last item in a JSON object does not have a comma.
For anyone that is repeatedly running into this issue, I have figured out exactly what was going wrong. Despite the error informing me that my JSON was incorrectly formatted, it turns out it was actually that the module was misnamed. According to this post, the updated module has been renamed to '#parse/simple-mailgun-adapter'. Inserting this into the index.js, after ensuring I had ran the npm install --save #parse/simple-mailgun-adapter in my local repo, fixed the issue.
I am trying to import JSON file into Sample variable but only first few characters are displayed from Sample variable.
The sample.json is 20,00,000 characters, When i print Sample variable on Console only first 3,756 characters are printed.Is there any limitations on the characters that can be printed through console.log?
Complete data persists in Sample variable, I verified it by searching for strings that occur at the end of sample.json file
var Sample = require('./sample.json');
export default class proj extends Component {
constructor(props) {
super(props);
this.state = {
locations: [],
};
}
loadOnEvent() {
console.log(Sample);
//this.state={ locations : Sample };
}
}
Is there any other way to print data in Sample variable.
You have to convert json to string using JSON.stringify before logging.
/* ... */
loadOnEvent() {
console.log(JSON.stringify(Sample));
//this.state={ locations : Sample };
}
/* ... */
Try to use another way to load. Use fetch if file is remote or use fs if file is local.
If it is memory problem supposed by #Shota consider to use server side processing requests to json file. It is good solution to setup microservice which load json file at startup and handle requests to data struct parsed from json file.
Answer for webpack use case:
Configure webpack to use file-loader or copy-webpack-plugin for specifically this file because it enough big. Consider to load it in parallel with webpack bundle. If your application have big parts which need not each case they must be moved to separated bundles.
Can someone point to or show me a working example of Papa Parse reading a csv file.
When I try to use :
Papa.parse(file, {
complete: function(results) {
console.log("Finished:", results.data);
}
});
the file name is returned in the array instead of the data within. None of the internet examples actually work. The official demo works correctl inspecting its code I cant find it making use of the above strangely.
As #Matt mentioned in his comment, the trick is not to pass a file name, but a file object. This also was not intuitive to me at first, so here is a quick solution:
var data;
function parse() {
var file = document.getElementById('myDOMElementId').files[0];
Papa.parse(file, {
header: true,
dynamicTyping: true,
complete: function(results) {
console.log("Finished:", results.data);
data = results.data;
}
});
}
Note that you have to call the results in this way when working with a local file. If you want to work with the results elsewhere, assign it to a global variable.
I have faced the same problem and it was solved by 2 actions:
1- Adding a callback function
2- connecting to a local oython server/changing browser's security settigns
Check this:
https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally
I did not pass an object but a string with the file name/path and it worked for me.