Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/api/routes/userRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ function checkIfAnyAdminAfterRemovingUser(userIdToBeRemoved, allUser) {
function checkIfUserToBeRemovedIsLoggedIn(userIdToBeRemoved, req) {
return req.session.currentUser === userIdToBeRemoved;
}
const nullOrEmpty = (str) => str == null || str.length === 0;
userRouter.get('/', async (req, res) => {
res.body = userStorage.getUsers(false);
res.send();
Expand Down Expand Up @@ -52,7 +51,7 @@ userRouter.post('/', async (req, res) => {
res.send(new Error('Passwords does not match'));
return;
}
if (nullOrEmpty(username) || nullOrEmpty(password) || nullOrEmpty(password2)) {
if (!username?.length || !password?.length || !password2?.length) {
res.send(new Error('Username and password are mandatory.'));
return;
}
Expand Down
26 changes: 11 additions & 15 deletions lib/notification/adapter/telegram.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { markdown2Html } from '../../services/markdown.js';
import { getJob } from '../../services/storage/jobStorage.js';
import fetch from 'node-fetch';
import { chunk, truncate } from 'lodash';
import pThrottle from 'p-throttle';

const MAX_ENTITIES_PER_CHUNK = 8;
Expand Down Expand Up @@ -57,20 +58,14 @@ function getThrottled(chatId, call) {
* @param inputArray
* @param perChunk
*/
const arrayChunks = (inputArray, perChunk) =>
inputArray.reduce((all, one, i) => {
const ch = Math.floor(i / perChunk);
all[ch] = [].concat(all[ch] || [], one);
return all;
}, []);
function shorten(str, len = 30) {
return str.length > len ? str.substring(0, len) + '...' : str;
}

export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
const { token, chatId } = notificationConfig.find((adapter) => adapter.id === config.id).fields;
const job = getJob(jobKey);
const jobName = job == null ? jobKey : job.name;
const chunks = arrayChunks(newListings, MAX_ENTITIES_PER_CHUNK);

// we have to split messages into chunks, because otherwise messages are going to become too big and will fail
const chunks = chunk(newListings, MAX_ENTITIES_PER_CHUNK);

const getThrottledSend = getThrottled(chatId, async function (body) {
await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
Expand All @@ -85,11 +80,12 @@ export const send = ({ serviceName, newListings, notificationConfig, jobKey }) =

messageParagraphs.push(`<i>${jobName}</i> (${serviceName}) found <b>${newListings.length}</b> new listings:`);
messageParagraphs.push(
...chunk.map(
(o) =>
`<a href='${o.link}'><b>${shorten(o.title.replace(/\*/g, ''), 45).trim()}</b></a>\n` +
[o.address, o.price, o.size].join(' | '),
),
...chunk.map((o) => {
const normalizedTitle = o.title.replace(/\*/g, '');
const titleExcerpt = truncate(normalizedTitle, { length: 45, omission: '…' });

return `<a href='${o.link}'><b>${titleExcerpt}</b></a>\n` + [o.address, o.price, o.size].join(' | ');
}),
);

const body = {
Expand Down
8 changes: 3 additions & 5 deletions lib/provider/immoscout.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,11 @@ async function getListings(url) {
});
}

function nullOrEmpty(val) {
return val == null || val.length === 0;
}
function normalize(o) {
const title = nullOrEmpty(o.title) ? 'NO TITLE FOUND' : o.title.replace('NEU', '');
const address = nullOrEmpty(o.address) ? 'NO ADDRESS FOUND' : (o.address || '').replace(/\(.*\),.*$/, '').trim();
const id = buildHash(o.id, o.price);
const title = o.title ? o.title.replace('NEU', '') : 'NO TITLE FOUND';
const address = o.address ? o.address.replace(/\(.*\),.*$/, '').trim() : 'NO ADDRESS FOUND';

return Object.assign(o, { id, title, address });
}
function applyBlacklist(o) {
Expand Down
9 changes: 2 additions & 7 deletions lib/provider/neubauKompass.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@ import utils, { buildHash } from '../utils.js';

let appliedBlackList = [];

function nullOrEmpty(val) {
return val == null || val.length === 0;
}

function normalize(o) {
const link = nullOrEmpty(o.link)
? 'NO LINK'
: `https://www.neubaukompass.de${o.link.substring(o.link.indexOf('/neubau'))}`;
const id = buildHash(o.link, o.price);
const link = o.link ? `https://www.neubaukompass.de${o.link.substring(o.link.indexOf('/neubau'))}` : 'NO LINK';

return Object.assign(o, { id, link });
}

Expand Down
40 changes: 17 additions & 23 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ function isOneOf(word, arr) {
return arr.some((item) => lowerWord.indexOf(item.toLowerCase()) !== -1);
}

function nullOrEmpty(val) {
return val == null || val.length === 0;
}

function timeStringToMs(timeString, now) {
const d = new Date(now);
const parts = timeString.split(':');
Expand All @@ -28,13 +24,13 @@ function timeStringToMs(timeString, now) {
}

function duringWorkingHoursOrNotSet(config, now) {
const { workingHours } = config;
if (workingHours == null || nullOrEmpty(workingHours.from) || nullOrEmpty(workingHours.to)) {
return true;
}
const toDate = timeStringToMs(workingHours.to, now);
const fromDate = timeStringToMs(workingHours.from, now);
return fromDate <= now && toDate >= now;
const {workingHours} = config;
if (!workingHours?.from || !workingHours?.to) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider checking for null or empty by doing this truthy/falsy check relatively unsafe for reason mentioned above. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're making a good point generally!

In this case I think we're still good though as the check will only be true when workingHours

  • is an object (=neither null, nor undefined)
  • has a from property
  • the content of that property is truthy

Which would actually make the check more complex and safer here.

> console.log(undefined?.test)
undefined
> console.log(Boolean(undefined?.test))
false
> console.log(""?.test)
undefined
> console.log(Boolean(""?.test))
false
> console.log(''?.test23abc)
undefined
> console.log(Boolean(''?.test23abc))
false

return true;
}
const toDate = timeStringToMs(workingHours.to, now);
const fromDate = timeStringToMs(workingHours.from, now);
return fromDate <= now && toDate >= now;
}

function getDirName() {
Expand Down Expand Up @@ -70,17 +66,15 @@ export async function refreshConfig() {
}
await refreshConfig();

export { isOneOf };
export { inDevMode };
export { nullOrEmpty };
export { duringWorkingHoursOrNotSet };
export { getDirName };
export { config };
export { buildHash };
export {isOneOf};
export {inDevMode};
export {duringWorkingHoursOrNotSet};
export {getDirName};
export {config};
export {buildHash};
export default {
isOneOf,
nullOrEmpty,
duringWorkingHoursOrNotSet,
getDirName,
config,
isOneOf,
duringWorkingHoursOrNotSet,
getDirName,
config,
};
2 changes: 1 addition & 1 deletion test/services/immoscout/immoscout-web-translater.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { convertWebToMobile } from '../../../lib/services/immoscout/immoscout-web-translater.js';
import { convertWebToMobile } from '../../../lib/services/immoscout/immoscout-web-translator.js';
import { expect } from 'chai';
import { readFile } from 'fs/promises';

Expand Down
15 changes: 5 additions & 10 deletions ui/src/views/generalSettings/GeneralSettings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,16 @@ const GeneralSettings = function GeneralSettings() {
init();
}, [settings]);

const nullOrEmpty = (val) => val == null || val.length === 0;

const onStore = async () => {
if (nullOrEmpty(interval)) {
Toast.error('Interval may not be empty.');
if (!interval) {
throwMessage('Interval may not be empty.', 'error');
return;
}
if (nullOrEmpty(port)) {
Toast.error('Port may not be empty.');
if (!port) {
throwMessage('Port may not be empty.', 'error');
return;
}
if (
(!nullOrEmpty(workingHourFrom) && nullOrEmpty(workingHourTo)) ||
(nullOrEmpty(workingHourFrom) && !nullOrEmpty(workingHourTo))
) {
if ((workingHourFrom && !workingHourTo) || (!workingHourFrom && workingHourTo)) {
Toast.error('Working hours to and from must be set if either to or from has been set before.');
return;
}
Expand Down
Loading