How do I search through raw data for matching data? - javascript

Right now, I coded a function to go like this
async function checkPlayerScam(ign) {
const UUID = await getUUID(ign);
if(MATCHING){
playerIsScammer = true
}
else {
playerIsScammer = false
}
}
The MATCHING is just a placeholder at the moment. I want to check their UUID, and make sure it isn't in this list: https://raw.githubusercontent.com/skyblockz/pricecheckbot/master/scammer.json
Any idea how? It needs to be relatively fast
EDIT: It'd also be cool if I could get the reason from the list, but that's not as necessary

https://lodash.com/docs/#find
Use lodash _.find to
const uuid = '000c97aaf948417a9a74d6858c01aaae'; // uuid you want to find
const scammer = _.find(scammersList, o => o.uuid === uuid);
if (scammer) { // if scammer found
console.log(scammer);
console.log(scammer.reason)
}

For anyone wondering, this is how I solved it:
async function checkPlayerScam(ign) {
const UUID = await getUUID(ign);
const response = await fetch(`https://raw.githubusercontent.com/skyblockz/pricecheckbot/master/scammer.json`);
const result = await responsejson();
if (result[UUID] = null) {
playerIsScammer == False
}
else{
playerIsScammer == True
}
}

This function will fetch the data, then check if the uuid 1d0c0ef4295047b39f0fa899c485bd00 exists. Assuming that you already fetched the data somewhere else and stored it, all you need to do is check if a given uuid exists by adding the following line where you please:
!!data[uuidToCheck]
uuidToCheck should be the uuid string that you are looking for.
This line will return true if the uuid exists and false otherwise.
In terms of the spacetime complexity, this function runs in constant time [O(1)] and O(N) space. This is the fastest time you can get it to run.
data[uuidToCheck].reason will return the reason.
async function playerIsScammer(uuidToCheck) {
uuidToCheck = '1d0c0ef4295047b39f0fa899c485bd00';
const response = await fetch('https://raw.githubusercontent.com/skyblockz/pricecheckbot/master/scammer.json');
if (response.ok){
let data = await response.json();
if(!!data[uuidToCheck])
return data[uuidToCheck].reason;
return false
}
}

Related

How can I give an object a temporary mark in Sequelize model

I use Sequelize to load items from database. The item contain a number type attribute called tValue, if tValue is null, then I need to assign a value to it, if not null, then do nothing and then pass all items to a function and it will return a new array.
What I want is to revert those updated items, make them back to null tValue before I save this list of array to database.
The issues is I don't know which item originally contain null tValue, because all of them have value now.
Can I give an object a temporary mark, so I can revert those items with mark.
The code snippet I do to assign value is like this
const mustHaveTValueArray = await Promise.all(
samples.map(async (s) => {
if (!s.tValue) {
console.warn(`sample ${s.id} do not have a t value`);
await s.update({ tValue: randomValue });
return s;
} else {
return s;
}
})
);
mustHaveTValueArray will be passed to a function, and return a new array
const newArray = reorderFunction(mustHaveTValueArray)
Each element in newArray now have valid tValue, how can I detect those originally have null tValue
the idea just come up in my head, guys
let temporaryIds = [];
const mustHaveTValueArray = await Promise.all(
samples.map(async (s) => {
if (!s.tValue) {
console.warn(`sample ${s.id} do not have a t value`);
await s.update({ tValue: randomValue });
temporaryIds.push(s.id);
return s;
} else {
return s;
}
})
);
Then I can use this temporaryIds to find which one originally have null tValue, like this
const finalArray = await Promise.all(
newArray.map(async (n) => {
if (temporaryIds.includes(n.id)) {
console.log('revert');
await n.update({ tValue: null });
return n;
} else {
return n;
}
})
);
what do you think, is it this make sense to you, guys
22/10/22 update:
model.update actually is calling set and then calling save, so what I need to do, I should use set instead of update, otherwise it will write db which is not my purpose. setis perfectly fit my situation, instruction from official document:
Set is used to update values on the instance (the sequelize
representation of the instance that is, remember that nothing will be
persisted before you actually call save). In its most basic form set
will update a value stored in the underlying dataValues object.
so updated code would be
const mustHaveTValueArray =
samples.map((s) => {
if (!s.tValue) {
console.warn(`sample ${s.id} do not have a t value`);
s.set({ tValue: randomValue });
return s;
} else {
return s;
}
});
And I can do whatever I want with mustHaveTValueArray
question solved

Check if ipfs data exists

Using the ipfs-http-client I can successfully add data using the below method. The console.log(added) returns an object with the path, cid, and size keys.
However, the console.log(exists) line returns Object [AsyncGenerator] {}.
I would like to be able to check if a data string exists. Is this possible?
import { create as ipfsHttpClient } from 'ipfs-http-client'
const ipfsClient = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0')
const handleData = async (data) => {
const added = await ipfsClient.add(data)
console.log(added)
const exists = await ipfsClient.get(data)
console.log(exists)
}
handleData('hello world')
The get method returns AsyncIterable<Uint8Array> object, which may be what you're printing out. To get each bytes, you will have to loop over it:
const cid = 'QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF'
for await (const buf of ipfs.get(cid)) {
// do something with buf
console.log(buf);
}
If all you care about is whether the data exists, you can just call next() method on the iterator and check for null or error.
const exists = (await ipfs.get(cid)).next() !== null

if else in loop bringing up errors in typescript

I have this function that is supposed to get referral codes from users. User gives a code and the referral code checked if it exists in the database then evaluated if
it does not match the current user, so that one should not refer himself and
it is a match with one of the codes in the database
This code however just does not find a match even if the code given is in the database. If the referral code matches the one of the current user, it works correctly and points that out i.e one cannot refer themselves.
But if the referral code is a match to that of another user which is how a referral system should work, it still says no match.
How can I remove this error
export const getID = functions.https.onCall(async(data, context) => {
const db = admin.firestore();
const usersSnapshot = await db.collection("user").get();
const allUIDs = usersSnapshot.docs.map(doc => doc.data().userID);
const userID = context.auth.uid;
const providedID = "cNx7IuY6rZlR9mYSfb1hY7ROFY2";
//db.collection("user").doc(providedID).collection("referrals").doc(userID);
await check();
function check() {
let result;
allUIDs.forEach(idFromDb => {
if (providedID === idFromDb && (idFromDb === userID)) {
result = "ownmatch";
} else if (providedID === idFromDb && (idFromDb !== userID)) {
result = "match";
} else {
result = "nomatch";
}
});
return result;
}
if (check() === "match") {
return {
message: `Match Found`,
};
} else if (check() === "ownmatch") {
return {
message: `Sorry, you can't use your own invite code`,
};
} else {
return {
message: `No User with that ID`
};
}
});
(This is not an answer, but a simple refactoring.)
This is what your code is currently doing (roughly, I didn't run it):
const resultMsgs = {
nomatch: 'No User With That ID',
ownmatch: 'Sorry, you can\'t use your own invite code',
match: 'Match Found',
}
function check(uids, providedId, userId) {
let result
uids.forEach(idFromDb => {
if (providedId !== idFromDb) {
result = 'nomatch'
return
}
if (userID === idFromDb) {
result = 'ownmatch'
return
}
result = 'match'
})
return result
}
export const getID = functions
.https
.onCall(async (data, context) => {
const userId = context.auth.uid
const providedId = 'cNx7IuY6rZlR9mYSfb1hY7ROFY2'
const db = admin.firestore()
const user = await db.collection('user').get()
const uids = user.docs.map(doc => doc.data().userId)
const checkResult = check(uids, providedId, userId)
return { message: resultMsgs[checkResult] }
})
(I removed the seemingly-spurious db collection operation.)
Your forEach is iterating over all of the uuids, but result will be set to whatever the last comparison was. Perhaps this is correct, but:
If you're looking for any match, this is not what you want.
If you're looking for all matches, this is not what you want.
If you're looking to match the last UUID, it's what you want, but an odd way to go about it.
So:
If you want any matches, use... ahem any form of an any function.
If you want all matches, use any form of an all function.
If you want the first match, then just check the first element.
If you want the complete set of comparisons then you'll need to use map instead of forEach, and handle each result appropriately, whatever that means in your case.
In any event, I'd recommend breaking up your code more cleanly. It'll be much easier to reason about, and fix.

How to make the if conditions look cleaner?

Is there a way to make this if conditions look cleaner and easily to add more Query search in the future as in Open–closed principle?
For example:
if (event.queryParameters["name"]) {
result = await getResultByName(event.queryParameters["name"]);
} else if (event.queryParameters["emailAddress"]) {
result = await getResultByEmail(event.queryParameters["emailAddress"]);
} else if (event.queryParameters["param1"]) {
result = await getResultByParam1(event.queryParameters["param1"]);
} else if (event.queryParameters["something1"] && event.queryParameters["something2"]) {
result = await getResultBySomething(event.queryParameters["something1"], event.queryParameters["something2"]);
}
As you can see it look really messy.
Make a table of entries and use Array.prototype.find():
const lut = [
{ keys: ['name'], getResultBy: getResultByName },
{ keys: ['emailAddress'], getResultBy: getResultByEmail },
{ keys: ['param1'], getResultBy: getResultByParam1 },
{ keys: ['something1', 'something2'], getResultBy: getResultBySomething }
]
const params = event.queryParameters
const entry = lut.find(
({ keys }) => keys.every(key => key in params)
)
if (entry) {
const { keys, getResultBy } = entry
const result = await getResultBy(...keys.map(key => params[key]))
...
}
The problem with the original code is that it isn't DRY, and so any incremental modification will inevitably repeat what was already written.
Compare the following two incremental changes:
...
{ keys: ['fizz', 'buzz', 'fizzbuzz'], getResultBy: getResultByFizzBuzz }
...
else if (params.fizz && params.buzz && params.fizzbuzz) {
result = await getResultByFizzBuzz(params.fizz, params.buzz, params.fizzbuzz);
}
And tell me which one you'd rather be typing every time you go back and add a new function.
Since values are different and functions are different, there's not much place for improvement.
There's no necessity for bracket notation and there's no reason to reference event object every time.
It could be written as:
const { queryParameters } = event;
if (queryParameters.name) {
result = await getResultByName(queryParameters.name);
} else if ...
No other improvements can be made, unless the same case occurs in several places and could be DRYed up:
const paramHandlers = [
{ handler: getResultByName, paramNames: ['name'] },
...
];
Then paramHandlers can be iterated to check if paramNames match event.queryParameters properties.
So what you have looks perfectly readable, simple, and clean. You could create an event handler list if you need more flexibility:
eventHandlers = [nameHandler, emailHandler, ...];
var result;
for (var handler of eventHandlers) {
if (result = handler(event)) break;
}
In this example, the event handlers are functions that return a result if the event was consumed and processing should end. In your case your result can be a Promise or any arbitrary value.

node.js resolve promise and return value

I use the Microsoft bot framework to come up with a "simple" PoC bot. I used a tutorial as a basis and extend it.
I've a couple of basic functions for differet intents (ie. greetings, goodbye, etc) and one with some more logic in it (reqstatus).
The simple ones (ie greeting.js) return the answer nicely but the more complex one doesn't (reqstatus.js). Running the main code of reqstatus.js (without the first "const getReqStatus = (entity) => {") in a standalone script works.
server.js (main) -> see call in "if (intent) {"...
const getFeelings = require('./intents/feelings.js')
const getGoodbyes = require('./intents/goodbyes.js')
const getGreetings = require('./intents/greetings.js')
const getHelp = require('./intents/help.js')
const getReqStatus = require('./intents/reqstatus.js')
...
const bot = new builder.UniversalBot(connector)
// Intents based on definitions on recast
const INTENTS = {
feelings: getFeelings,
goodbyes: getGoodbyes,
greetings: getGreetings,
help: getHelp,
reqstatus: getReqStatus,
}
// Event when Message received
bot.dialog('/', (session) => {
recastClient.textRequest(session.message.text)
.then(res => {
const intent = res.intent()
const entity = res.get('request_number')
console.log(`UserName: ${session.message.user.name}`)
console.log(`Msg: ${session.message.text}`)
console.log(`Intent: ${intent.slug}`)
if (intent) {
INTENTS[intent.slug](entity)
.then(res => session.send(res))
.catch(err => session.send(err))
}
})
.catch(() => session.send('Sorry I didn\'t get that. '))
})
...
greetings.js -> Returns the string ok
const getGreetings = () => {
const answers = ['Hi, my name is SuperBot. Nice to meet you!', ]
return Promise.resolve((answers))
}
module.exports = getGreetings
reqstatus.js -> Does not return anything
const getReqStatus = (entity) => {
var request = require('request');
var request_number = entity.toLowerCase()
var output = [];
// Processing
var lineReader = require('readline').createInterface({
input: fs.createReadStream('netreqs.csv')
});
lineReader.on('line', function (line) {
var jsonFromLine = {};
var lineSplit = line.split(';');
jsonFromLine.req = lineSplit[0];
jsonFromLine.req_count = lineSplit[1];
jsonFromLine.req_type = lineSplit[2];
//...
var req_lowever = jsonFromLine.req.toLowerCase()
if (req_lowever == request_number) {
output.push( `Your request ${jsonFromLine.req} was received`);
// simplified
}
});
// Output
lineReader.on('close', function (line) {
if (output == '') {
output.push( `I was not able to find a request like ${request_number}.`);
}
console.log(output); // list output
return Promise.resolve(output);
});
}
module.exports = getReqStatus
I also tried to put getReqStatus in a function but that also didn't work.
After a lot of trying and googling I'm still stuck and wanted to ask the experts here. Thanks a lot in advance.
I think that the problem is that your getReqStatus isn't really returning anything. In your example getGreetings function you're actually returning Promise.resolve(answers) as the return value of that function.
However, in your getReqStatus function, you just set up a listener lineReader close event:
lineReader.on('close', function (line) {
if (output == '') {
output.push( `I was not able to find a request like ${request_number}.`);
}
console.log(output); // list output
return Promise.resolve(output);
});
You're returning a Promise resolved inside the anonymous callback function you're passing to lineReader.on() as second parameter. That is not the return value from the getReqStatus function itself, so that getReqStatus is not returning anything, as expected.
The code of that function runs correctly as standalone code, as you say, just because it sets the listener properly and it does what it has to do. However, that code just doesn't return a Promise when wrapped in a function.
What you would need is to return a Promise that wraps the lineReader.on close handler, like:
function getReqStatus(){
//...code
return new Promise( function(resolve , reject ){
lineReader.on('close', function (line) {
if (output == '') {
output.push( `I was not able to find a request like ${request_number}.`);
}
console.log(output); // list output
return resolve(output);
});
});
}
I say would because I really don't know if this code will work, I don't have any kind of experience with the Microsoft Bot framework and not used at all with the readline module. However, even if this doesn't solve your problem, I hope it will help you a bit understanding why your function doesn't return a Promise and how could you fix it.

Categories