I have a Bixby capsule in progress that lets users access both free and premium content "packs". Each pack is a file stored in a content/ directory. I want to loop over these files and read them into a variable called entitled_content.
I started from the facts capsule which uses a utility function to search a local file called content.js.
const CONTENT = []
const literature = require("../content/literature")
const enhanced = require("../content/enhanced")
const roosevelt = require("../content/roosevelt")
const ambition = require("../content/ambition")
const chaucer = require ("../content/chaucer")
//const GET_REMOTE = require('./lib/getRemoteContent.js')
var console = require('console')
console.log(roosevelt)
console.log(ambition)
console.log(chaucer)
const entitlements = ["roosevelt", "ambition", "chaucer"]
var entitled_content = []
entitlements.forEach(function (item) {
entitled_content = entitled_content.concat(item)
console.log(item); })
console.log(entitled_content)
What it does is this:
[ { tags: [ 'roosevelt' ],
text: 'Happiness is not a goal; it is a by-product. --Eleanor Roosevelt',
image: { url: 'images/' } } ]
[ { tags: [ 'ambition' ],
text: 'Ambition is but avarice on stilts, and masked. --Walter Savage Landor' } ]
[ { tags: [ 'literature' ],
text: 'A man was reading The Canterbury Tales one Saturday morning, when his wife asked What have you got there? Replied he, Just my cup and Chaucer.' },
{ tags: [ 'literature' ],
text: 'For years a secret shame destroyed my peace-- I\'d not read Eliot, Auden or MacNiece. But now I think a thought that brings me hope: Neither had Chaucer, Shakespeare, Milton, Pope. Source: Justin Richardson.' } ]
roosevelt
ambition
chaucer
[ 'roosevelt', 'ambition', 'chaucer' ]
What I want it to do is to assemble these three files roosevelt, ambition and chaucer into a single array variable entitled_content that will then be searched by the utility function. What's wrong is that this line entitled_content = entitled_content.concat(item) isn't doing what I want it to do, which is to get the entire contents of the file named "item".
Because you wrapped your variable names in quotation marks the program reads them as strings.
Change it from
const entitlements = ["roosevelt", "ambition", "chaucer"]
to
const entitlements = [roosevelt, ambition, chaucer]
Related
i have quite a problem. I have coded a help command for my bot which lists all available sommands which are stored. Now that i have some Categories of Commands i wanna make sure only people with specific permissions get to see the specific commands. I made a try but it doesn't work well, even though their role has the specific permission it doesn't show the categorys but does show the ones which are stated in the else{} line. Here is the code:
const permissionlist = [
"BAN_MEMBERS",
"KICK_MEMBERS",
"VIEW_AUDIT_LOG",
"MANAGE_CHANNELS",
"MANAGE_NICKNAMES",
"MANAGE_MESSAGES",
"MUTE_MEMBERS"
]
if(message.member.hasPermission(permissionlist)){
fs.readdirSync("./commands/").forEach((dir) => {
const commands = fs.readdirSync(`./commands/${dir}/`).filter((file) =>
file.endsWith(".js")
);
const cmds = commands.map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return //"No command name.";
let name = file.name.replace(".js", "");
return `\`${name}\``;
});
let FileData = new Object();
FileData = {
name: dir.toUpperCase(),
value: cmds.length === 0 ? "In progress." : cmds.join(" "),
};
const InvalidDirs = [
'minecraft-server',
'owner-only',
'customizable'
]
if (InvalidDirs.includes(dir)) return
categories.push(FileData)
});
}
Notice: I have all other code already prepared for the messages and the message works fine. I only need help how to make it that if a user has a specific permission out of that list that the message shows up with every other category except the ones which are stated in the InvalidDirs list.
Thanks
You can check if the GuildMember's permissions flags are included in your array:
const permissionlist = [
"BAN_MEMBERS",
"KICK_MEMBERS",
"VIEW_AUDIT_LOG",
"MANAGE_CHANNELS",
"MANAGE_NICKNAMES",
"MANAGE_MESSAGES",
"MUTE_MEMBERS"
];
if(permissionList.some(permission => message.member.permissions.FLAGS.includes(permission))){
...
}
References:
https://discord.js.org/#/docs/main/stable/class/Permissions?scrollTo=s-FLAGS
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
I'm trying to make a simple mail-merge where recipients information is inserted on top of a template pdf.
The template is 1 page, but the result can be up to several hundred pages.
I have all recipient in array objects, but need to find a way to loop over that and create a unique page for each recipient.
I'm not sure if hummus-recipe is the right tool, so would greatly appreciate any input as to how to do this.
My demo looks like this
const HummusRecipe = require('hummus-recipe')
const recepients = [
{name: "John Doe", address: "My Streetname 23", zip: "23456", city: "My City"},
{name: "Jane Doe", address: "Another Streetname 56 ", zip: "54432", city: "Her City"}
//'.......'
]
const template = 'template.pdf';
const pdfDoc = new HummusRecipe(template, 'output.pdf');
function createPdf(){
pdfDoc
.editPage(1)
.text(recepients[0].name, 30, 60)
.text(recepients[0].address, 30, 75)
.text(recepients[0].zip + ' ' + recepients[0].city, 30, 90)
.endPage()
//. appendpage(template) - tried versions of this in loops etc., but can't get it to work.
.endPDF();
}
createPdf();
This obviously only create a single page with recipient[0]. I have tried all sorts of ways to loop over using .appendpage(template), but I can't append and then edit the same page.
Any advice how to move forward from here?
After conversing with the creator of hummus-recipe and others, the solution became somewhat obvious. Its not possible to append a page and then modify it, and its not possible to modify the same page several times.
The solution then is to make the final pdf in two passes. First create a masterPdf where the template is appended in a for loop, save this file and then edit each of those pages.
I have created a working code as shown below. I have made the functions async as I need to run it on lambda an need som control over returns etc. Also this way its possible to save both the tmp-file and final pdf on AWS S3.
The code below takes about 60 seconds to create a 200 page pdf from a 1,6mb template. Any ideas for optimizations will be greatly appreciated.
const HummusRecipe = require('hummus-recipe');
const template = 'input/input.pdf';
const recipients = [
{name: 'John Doe', address: "My Streetname 23"},
{name: 'Jane Doe', address: "Another Streetname 44"},
//...etc.
]
async function createMasterPdf(recipientsLength) {
const key = `${(Date.now()).toString()}.pdf`;
const filePath = `output/tmp/${key}`;
const pdfDoc = new HummusRecipe(template, filePath)
for (i = 1; i < recipientsLength; i++) {
pdfDoc
.appendPage(template)
.endPage()
}
pdfDoc.endPDF();
return(filePath)
}
async function editMasterPdf(masterPdf, recipientsLength) {
const key = `${(Date.now()).toString()}.pdf`;
const filePath = `output/final/${key}`;
const pdfDoc = new HummusRecipe(masterPdf, filePath)
for (i = 0; i < recipientsLength; i++) {
pdfDoc
.editPage(i+1)
.text(recipients[i].name, 75, 100)
.text(recipients[i].address, 75, 115)
.endPage()
}
pdfDoc.endPDF()
return('Finished file: ' + filePath)
}
const run = async () => {
const masterPdf = await createMasterPdf(recipients.length);
const editMaster = await editMasterPdf(masterPdf, recipients.length)
console.log(editMaster)
}
run()
I am trying to choose a random word from an array of strings but cannot figure out how.
I have researched on this and here is what I have so far:
roast.js
const roastList = [
'Apples',
'Bananas',
'Pears',
];
const roast = roastList[Math.floor(Math.random() * roastList.length)];
module.exports = {
roast
};
index.js:
case 'roast':
if (!message.mentions.users.size) {
return message.reply('you need to tag a user in order to roast them!');
}
message.channel.send(`Hey ${taggedUser}, ${roast}`);
break;
I copied the code so the fruits are placeholders. I hope that I can get different fruits each time I output roast.
The problem here is that the module code will only be run one time, that means that only one "roast" will be chosen the first time the module is loaded. You want to wrap up the "roast" selection logic in a function that can be called every time you want to "roast" someone.
Consider making roast.js export a function:
const roastList = [
'Apples',
'Bananas',
'Pears'
];
module.exports = function () {
return roastList[Math.floor(Math.random() * roastList.length)];
};
Then call that function in your template:
const roast = require('./roast.js');
...
message.channel.send(`Hey ${taggedUser}, ${roast()}`);
Works for me. With the export you have defined in your example the import can be done like the following, for example.
const roast = require('./roast').roast;
If you simply export the string instead of an object containing the string, you can also do this as follows:
module.exports = roast;
...
const roast = require('./roast');
See also my repl.it for demonstration
EDIT: I have just noticed by the comments you have posted that you are probably looking for a solution where you can get a new random roast each time when a roaster is required in the chat protocol. To do this my suggestion is to export a function which returns a random roast string. See example below, I have also extended the repl.it demo.
roast3.js
const roastList = [
'Apples',
'Bananas',
'Pears',
];
function roast() {
return roastList[Math.floor(Math.random() * roastList.length)]
}
module.exports = {
roast
};
index.js
const roast3 = require('./roast3').roast;
for (x=0; x<10; x++) {
console.log(roast3())
}
const roastList = [
'Apples',
'Bananas',
'Pears',
];
const roast = roastList[Math.floor(Math.random() * roastList.length)];
console.log(roast);
This actually works.
But why do you exports it ?
I am seasoned in JavaScript, but very new to node and to Electron. I am trying to piece the technique together from code samples and what documentation I can find.
I would like to include my menu code in a separate file. The main code is in a file called renderer.js and the menu code in one called menu.js. A simple example:
// renderer.js
function doit() {
alert('hello');
}
module.exports.doit=doit; // Added
var q=require('./menu');
var q=require('./menu');
// menu.js
var template = [
{
label: 'Test',
submenu: [
{
label: 'Something',
click() {
doit();
}
}
]
}
];
const {remote} = require('electron');
const renderer=require('./renderer'); // Added
const {Menu, MenuItem} = remote;
const app=remote.app; // Addes
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
The menu is created, but when selecting the menu item, I get the message: Uncaught ReferenceError: doit is not defined.
I understand the meaning of the message, and clearly variables are not passed between the files.
How can I accomplish this?
Update: I have added some lines in the sample incorporate the accepted answer below. This now works.
Clearly I did not understand the meaning of require(). It strikes me as odd that each file can require the other. Anyway …
Thanks
If you wish to access symbols defined in one Node module from another you have to export them via module.exports:
// renderer.js
function doit() {
// ...
}
module.exports.doit = doit;
And load the module via require:
// menu.js
const { doit } = require('./renderer');
// OR: const doit = require('./renderer').doit;
var template = [
{
label: 'Test',
submenu: [
{
label: 'Something',
click() {
doit();
}
}
]
}
];
This and much more is covered in the Node API docs.
I am trying to solve the same challenge. Currently I am looking into this:
https://github.com/ragingwind/electron-menu-loader
He basically adds a property 'event' and replaces that with an event handler.
How to get the top object value in PentahoDI? I have got the other elements like Category, Subcategory, section from the following example of Json file. However, I need to capture the first root object which is x#chapter#e50de0196d77495d9b50fc05567b4a4b and x#e50de0196d77495d9b50fc05567b4a4b
{
"x#chapter#e50de0196d77495d9b50fc05567b4a4b": {
"Category": "chapter",
"SubCategory": [
"x#4eb9072cf36f4d6fa1e98717e6bb54f7",
"x#d85849fbde324690b6067f3b18c4258d",
"x#3edff1a1864f41fe8b212df2bc96bf13"
],
"Section": {
"display_name": "Week 1 Section"
}
},
"x#e50de0196d77495d9b50fc05567b4a4b": {
"category": "course",
"Subcategory": [
"x#e50de0196d77495d9b50fc05567b4a4b"
],
"Section": {
"advanced_modules": [
"google-document"
],
}
}
}
In the Fields tab of the Json Input step I have given the Names and Paths as: Category --> $..Category, Subcategory --> $..Subcategory, Section --> $..Section.
However, I am unable to get the root element as it is crucial information for us to work on it. ex (x#chapter#e50de0196d77495d9b50fc05567b4a4b and x#e50de0196d77495d9b50fc05567b4a4b)
I have used the following code to get the values of the dynamic objects but it didnt work. The following is the code I used it.
var obj = JSON.parse (JBlock) //Jblock is the one which holds the entire string.
var keys = Object.name( obj);
JSONPath is not able to get the keys of a JSON structure. This is one of my main issues with JSONPath, and I wish Pentaho had included other JSON parsing engines.
This JavaScript to be used in Modified Java Script Value works for me. Add a value in the fields editor like this:
And then a script like this:
var obj = JSON.parse(JBlock);
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var row = createRowCopy(getOutputRowMeta().size());
var idx = getInputRowMeta().size();
row[idx++] = keys[i];
putRow(row);
}
trans_Status = SKIP_TRANSFORMATION;