I'm using gulp.js. I want to pipe the resulting JSON data from gulp-yaml, straight into gulp-ejs. My logic says that I'm probably going to have to get synchronous at some point?
What I have tried thus far:
var yaml = require('gulp-yaml');
var ejs = require('gulp-ejs');
gulp.task('yaml', function(){
return gulp.src('./path/to/template.ejs')
.pipe( ejs( gulp.src('./path/to/data.yml').pipe( yaml() ) ) )
.pipe(gulp.dest('./path/to/dest'));
});
I realise that the above is an idiotic script as I'm essentially trying to pass a stream as an argument to ejs. And as predicted, it doesn't work. I've tried numerous other things but I'm guessing someone has done this before?
I reckon gulp-data will have something to do with the solution...
You probably don't need the gulp-data plugin to achieve this; like you said you're just passing the option synchronously to the ejs plugin, and you're only needing the one yaml config file. So this is probably better:
var yaml = require('js-yaml');
var ejs = require('gulp-ejs');
var fs = require('fs');
gulp.task('ejs-with-yaml', function () {
return gulp.src('path/to/template.ejs')
.pipe(ejs(yaml.safeLoad(fs.readFileSync('path/to/data.yml', 'utf-8'))))
.pipe(gulp.dest('path/to/dest'));
});
Okay, so after a bit of head-scratching I've been able to find a solution using js-yaml and gulp-data.
var yaml = require('js-yaml');
var ejs = require('gulp-ejs');
var data = require('gulp-data');
gulp.task('ejs-with-yaml', function(){
return gulp.src('path/to/data.yml'))
.pipe(data(function(file, cb){
// throughput the stream in case of bad/absent file data
if (file.isNull()) return cb( null, file );
if (file.isStream()) return cb( new Error("Streaming not supported") );
// try and convert yaml to json
try {
json = yaml.load(String(file.contents.toString('utf8')));
} catch(e) {
console.log(e);
}
gulp.src('path/to/template.ejs').pipe(ejs(json)).pipe(gulp.dest( 'path/to/dest' ));
}));
});
Hopefully this might help others that are stuck on this. If anyone has a better solution, feel free to comment.
Related
I'm looking at automating a drag and drop scenario using Playwright. I found this code which is meant to do just this:
// Read your file into a buffer.
const buffer = readFileSync('./runtime_config/common/file.pdf');
// Create the DataTransfer and File
const dataTransfer = await scope.page.evaluateHandle((data) => {
const dt = new DataTransfer();
// Convert the buffer to a hex array
const file = new File([data.toString('hex')], 'file.pdf', { type: 'application/pdf' });
dt.items.add(file);
return dt;
}, buffer);
// Now dispatch
await page.dispatchEvent('YOUR_TARGET_SELECTOR', 'drop', { dataTransfer });
This code was found on this github post https://github.com/microsoft/playwright/issues/10667
When I try to use this code, I get an error that 'scope is not defined'
I can't see how this would work, nor does the post have any info. I've reached out to the poster but no reply yet, so thought I'd try here. Anyone know how this would work?
(I tried modify the line to be this.page.evaluateHandle((data) which doesn't error at runtime, but all I am getting is a 15B file called 'file.pdf' in the UI. I have console.log the buffer and it does appear to be valid.)
How can I make possible that the app will load all of the images from the specific folder and then put in array and choose one image randomly? When chose one then pass to the fronted to show the image. How to do that too?
I am C# developer but not long time ago I found ElectronJS and this framework does everything easier so therefore I am moving to this framework.
I did in C# programming this way:
// basic settings.
var ext = new List<string> { ".jpg", ".gif", ".png" };
// we use same directory where program is.
string targetDirectory = Directory.GetCurrentDirectory() + "\\assets\\" + "images\\" + "animals\\";
// Here we create our list of files
// New list
// Use GetFiles to getfilenames
// Filter unwanted stuff away (like our program)
if (Directory.Exists(targetDirectory))
{
Files = new List<string>
(Directory.GetFiles(targetDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(s => ext.Any(es => s.EndsWith(es))));
// Show first picture so we dont need wait 3 secs.
ChangePicture();
}
else
{
panel5.BackgroundImage = new Bitmap(Resources.doggy);
}
I don't know how to do in ElectronJS.
Thank you in advance the answers.
Alright. I found the solution.
However I don't understand the people who are giving negative reputation for the opened question. If they are giving negative reputation then they could explain why.
Well anyway, I did fix this issue with this way:
I created images.js file and added this:
var fs = require('fs');
function getRandImage() {
var files = fs.readdirSync('./assets/images/animals/')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
console.log('../assets/images/animals/' + chosenFile);
return '../assets/images/animals/' + chosenFile;
}
module.exports = { getRandImage }
I used console to see if the value is correct, otherwise others can delete that part.
Sending the data to the renderer process:
const { getRandImage } = require('./images');
child.webContents.send('random-image', getRandImage());
I did put in the preload.js file the following (I used the starter pack electronjs github to start with something):
var { ipcRenderer } = require('electron');
ipcRenderer.on('random-image', function (event, store) {
document.getElementById("randompic").src = store;
console.log(store);
});
Same here, I did use console.log just for test the value is correct and I used to change the randompic ID related image src html to the randomly chosen image.
Hopefully I did helping those people who are newbie as me.
I have a large JSON file that I would like to use as a local data source for Gridsome to generate static pages.
I would like to stream the data in rather than load it all into memory.
Something like this in gridsome.server.js:
module.exports = function (api) {
api.loadSource(async (actions) => {
const collection = actions.addCollection({
typeName: 'Posts',
})
const StreamArray = require('stream-json/streamers/StreamArray')
const fs = require('fs')
const jsonStream = StreamArray.withParser()
//internal Node readable stream option, pipe to stream-json to convert it for us
fs.createReadStream('./src/data/posts.json').pipe(jsonStream.input)
//You'll get json objects here
//Key is the array-index here
jsonStream.on('data', ({ key, value }) => {
collection.addNode(value)
})
jsonStream.on('end', ({ key, value }) => {
console.log('All Done')
})
})
}
Are there flaws in this approach? I am wondering if this might not work because of the async nature of it. Anyone tried anything similar?
Are there any flaws in this approach?
NO - this should work.
I have a stream in gulp, but I want to split the stream into two, and put half in one destination, and the other half in another.
My thoughts is that I need to fork the stream twice, filter each of the new streams, use gulp.dest on each stream, then merge them back, and return them back to gulp.
I currently have the code,
function dumpCpuProfiles(profileDirectory) {
const _ = require('highland');
const stream = _();
const cpuProfiles = stream
.fork()
.pipe(filter('*.cpuprofile'))
.pipe(gulp.dest(profileDirectory));
const noCpuProfiles = _(cpuProfiles).filter(() => false);
const otherFiles = stream
.fork()
.pipe(filter(['**', '!**/*.cpuprofile']));
return _([noCpuProfiles, otherFiles]).merge();
}
However, I get the error,
TypeError: src.pull is not a function
at /home/user/project/node_modules/highland/lib/index.js:3493:17
at Array.forEach (native)
at pullFromAllSources (/home/user/project/node_modules/highland/lib/index.js:3492:15)
at Stream._generator (/home/user/project/node_modules/highland/lib/index.js:3449:13)
at Stream._runGenerator (/home/user/project/node_modules/highland/lib/index.js:949:10)
at Stream.resume (/home/user/project/node_modules/highland/lib/index.js:811:22)
at Stream._checkBackPressure (/home/user/project/node_modules/highland/lib/index.js:713:17)
at Stream.resume (/home/user/project/node_modules/highland/lib/index.js:806:29)
at Stream.pipe (/home/user/project/node_modules/highland/lib/index.js:895:7)
at Gulp.<anonymous> (/home/user/project/gulpfile.js:189:6)
The output is a stream, so I'm not too sure what the error is about. Any help would be massively useful! Thanks!
I use this little small monkeypatching trick to achieve it
Object.prototype.fork = function(_fn) {
_fn(this);
return this;
};
Stream is only event emitter, pipe method doesn't return old stream but a new one, so you can built fork functionality very easy.
I'm using the cordova screenshot plugin : https://github.com/gitawego/cordova-screenshot to take a screenshot in my iPhone using this code :
navigator.screenshot.save(function (error, res) {
if (error) {
console.log('Screenshot error');
console.error(error);
} else {
console.log('screenshot ok', res.filePath);
}
}, 'jpg', 50, 'project-X-result');
It seems to work (i have no error) but I can't find the screenshot in the Photos Library. Is it possible to save it in this library?
How should I do? Using another plugin to move the file? (where should it be moved exactly?) Editing the plugin to save it directly in the library? (where should it be saved exactly?)
I just ran through the same problem. It took several days but I figured out how to do it.
It does involve another plugin Canvas2Image plugin. I didn't think it would work, but I was desperate and it did work in the end. Here's how I did it.
If you are getting the console.log for screenshot ok, then you are in good shape. The next thing you will need to do is install Canvas2Image with your CLI like so:
cordova plugin add https://github.com/devgeeks/Canvas2ImagePlugin.git
(or replace 'cordova' with 'phonegap' if you use that instead.)
Next, you will need to add a function (in this case saveImageToPhone()) that calls the plugin you just added to your project. This function will be called from your navigator.screenshot.save() function you already have. We will add that function call to your screenshot.save success block, right after the console.log line.
The key here is using that filePath property that we get back in the success block; That's our absolute path to the image we just saved to the temp folder in iOS. We will simply pass that path to the second function and let it do its work.
Here's those two functions from my code:
function saveScreen(){
navigator.screenshot.save(function(error,res){
if(error){
console.error(error);
}else{
console.log('ok',res.filePath);
var MEsuccess = function(msg){
console.info(msg);
} ;
var MEerror = function(err){
console.error(err);
};
saveImageToPhone(res.filePath, MEsuccess, MEerror);
}
},'jpg',90);
}
function saveImageToPhone(url, success, error) {
var canvas, context, imageDataUrl, imageData;
var img = new Image();
img.onload = function() {
canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
try {
imageDataUrl = canvas.toDataURL('image/jpeg', 1.0);
imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, '');
cordova.exec(
success,
error,
'Canvas2ImagePlugin',
'saveImageDataToLibrary',
[imageData]
);
}
catch(e) {
error(e.message);
}
};
try {
img.src = url;
}
catch(e) {
error(e.message);
}
}
Now just call the first function from wherever you wish.
If it works, you'll get a console.log right after your filePath readout that says
IMAGE SAVED!
Be careful, you might overwrite the same screenshot if you use a name as a screenshot.save parameter (after your jpg and quality parameters). My app needs to save different screenshots and have them all available later; by removing the name parameter and allowing the OS to name the file I was able to achieve just that.
I hope that helps you out, I know it caused me a lot of trouble...