<commit_before>"use strict";

const db = requireDb();
const tmp = require('tmp');
const cdn = require('dumonda-me-server-lib').cdn;
const fs = require('fs');
const eMail = require('dumonda-me-server-lib').eMail;
const logger = require('dumonda-me-server-lib').logging.getLogger(__filename);

const LIMIT = 10;

const getUserImage = async function (userId) {
    let imageData, userImage = tmp.fileSync({postfix: '.jpg'});
    imageData = await cdn.getObject(`profileImage/${userId}/profile.jpg`, process.env.BUCKET_PRIVATE);
    fs.writeFileSync(userImage.name, imageData.Body);
    return userImage;
};

const removeSendingEmailPending = async function (emails, userId) {
    if (Array.isArray(emails) && emails.length > 0) {
        await db.cypher()
            .match(`(invitedUser:InvitedUser)<-[sendingPending:SENDING_EMAIL_PENDING]-(:User {userId: {userId}})`)
            .where(`invitedUser.emailNormalized IN {emails}`)
            .delete(`sendingPending`)
            .end({emails, userId}).send();
    }
};

const sendEMails = async function (users) {
    for (let user of users) {
        let sentInvitations = [], userImage;
        try {
            userImage = await getUserImage(user.userId);
            for (let userToInvite of user.emails) {
                let unsubscribeLink = `${process.env.DUMONDA_ME_DOMAIN}unsubscribe/invitedUser/${userToInvite}`;
                await eMail.sendEMail('invitePerson',
                    {unsubscribeLink, userImage, name: user.name}, 'de', userToInvite);
                sentInvitations.push(userToInvite);
            }
        } catch (error) {
            logger.error(`Failed to send invitation from user ${user.userId} ${error}`);
        } finally {
            if (userImage && typeof userImage.removeCallback === 'function') {
                userImage.removeCallback();
            }
            await removeSendingEmailPending(sentInvitations, user.userId);
        }
    }

};

let invitationJobIsRunning = false;

const sendInvitations = async function () {
    let skip = 0, users = [];
    if (!invitationJobIsRunning) {
        try {
            invitationJobIsRunning = true;
            do {
                users = await db.cypher()
                    .match(`(invitedUser:InvitedUser)<-[:SENDING_EMAIL_PENDING]-(user:User)`)
                    .return(`collect(DISTINCT invitedUser.emailNormalized) AS emails, 
                     user.userId AS userId, user.name AS name`)
                    .orderBy(`user.userId`)
                    .skip(skip)<commit_msg>Remove callback function removed. Library does it anyway. Otherwise an error is generated in Linux.<commit_after>"use strict";

const db = requireDb();
const tmp = require('tmp');
const cdn = require('dumonda-me-server-lib').cdn;
const fs = require('fs');
const eMail = require('dumonda-me-server-lib').eMail;
const logger = require('dumonda-me-server-lib').logging.getLogger(__filename);

const LIMIT = 10;

const getUserImage = async function (userId) {
    let imageData, userImage = tmp.fileSync({postfix: '.jpg'});
    imageData = await cdn.getObject(`profileImage/${userId}/profile.jpg`, process.env.BUCKET_PRIVATE);
    fs.writeFileSync(userImage.name, imageData.Body);
    return userImage;
};

const removeSendingEmailPending = async function (emails, userId) {
    if (Array.isArray(emails) && emails.length > 0) {
        await db.cypher()
            .match(`(invitedUser:InvitedUser)<-[sendingPending:SENDING_EMAIL_PENDING]-(:User {userId: {userId}})`)
            .where(`invitedUser.emailNormalized IN {emails}`)
            .delete(`sendingPending`)
            .end({emails, userId}).send();
    }
};

const sendEMails = async function (users) {
    for (let user of users) {
        let sentInvitations = [], userImage;
        try {
            userImage = await getUserImage(user.userId);
            for (let userToInvite of user.emails) {
                let unsubscribeLink = `${process.env.DUMONDA_ME_DOMAIN}unsubscribe/invitedUser/${userToInvite}`;
                await eMail.sendEMail('invitePerson',
                    {unsubscribeLink, userImage, name: user.name}, 'de', userToInvite);
                sentInvitations.push(userToInvite);
            }
        } catch (error) {
            logger.error(`Failed to send invitation from user ${user.userId} ${error}`);
        } finally {
            await removeSendingEmailPending(sentInvitations, user.userId);
        }
    }

};

let invitationJobIsRunning = false;

const sendInvitations = async function () {
    let skip = 0, users = [];
    if (!invitationJobIsRunning) {
        try {
            invitationJobIsRunning = true;
            do {
                users = await db.cypher()
                    .match(`(invitedUser:InvitedUser)<-[:SENDING_EMAIL_PENDING]-(user:User)`)
                    .return(`collect(DISTINCT invitedUser.emailNormalized) AS emails, 
                     user.userId AS userId, user.name AS name`)
                    .orderBy(`user.userId`)
                    .skip(skip)
{'fraction_non_alphanumeric': 0.12795080341202142, 'fraction_numerical': 0.0015869867089863122, 'mean_word_length': 2.575886524822695, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3730968', 'n_tokens_mistral': 1475, 'n_tokens_neox': 1488, 'n_words': 305}