<commit_before>'use strict';
exports.info = {
  desc: 'Search messages for user/role mentions and posts results via DM.',
  usage: '[number]',
  aliases: [],
};

const moment = require('moment');
const logger = require('winston');
const utils = require('../utilities');

exports.run = (client, msg, params = []) => {
  // Exit if not ran in normal text channel (no DMs)
  if (msg.channel.type !== 'text') {
    msg.reply('Unable to get **mentions** from a DM channel.');
    utils.finish(msg, exports.name);
    return;
  }
  // Set amount of messages to retrieve
  let max = parseInt(params[0]) || 500;
  // Don't allow over 10k messages to be searched
  if (max > 10000) {
    max = 10000;
  }
  const responses = [];
  let count = 0;
  const delay = 1000;
  const roles = msg.member.roles;

  msg.channel.sendMessage(':mailbox_with_mail:');
  msg.author.sendMessage(`Searching for @ mentions in **#${msg.channel.name}**. Estimated time: ` +
    `${Math.floor((delay / 1000) * (max / 100))} seconds.`);

  function next(err, lastMessage) {
    if (err) {
      return;
    }
    count += 100;
    if (count >= max || !lastMessage) {
      utils.time(msg, 'io');
      processLogs();
    } else {
      getLogs(lastMessage);
    }
  }

  utils.time(msg, 'cpu');
  getLogs(msg);

  function getLogs(m) {
    setTimeout(() => {
      msg.channel.fetchMessages({ limit: 100, before: m.id })
        .then((messages) => {
          if (messages.size !== 100) {
            extractMentions(messages);
            next(null, null);
            return;
          }
          extractMentions(messages);
          next(null, messages[messages.length - 1]);
        })
        .catch(e => {
          logger.error('There was an error searching for @ mentions', e);
          next(true);
        });
    }, delay);
  }

  function extractMentions(messages) {
    messages.forEach(m => {
      if (m.mentions.everyone) {
        responses.push(m);
        return;
      }
      if (m.isMentioned(msg.author)) {
        responses.push(m);
        return;
      }
      roles.some(r => {
        if (m.isMentioned(r)) {
          m.content = m.content.replace(/<@&\d+>/g, `@${r.name}`);
          responses.push(m);
          return true;
        }
        return false;
      });
    });
  }

  function processLogs() {
    if (responses.length === 0) {
      msg.author.sendMessage(`\`\`No mentions were found in #${msg.channel.name}.\`\``);
      utils.finish(msg, exports.name);
      return;
    }
    const chunks = [];
    const header = `\`\`\`Mentions from #${msg.channel.name}.\`\`\`\n`;

    function nextChunk(start) {
      if (start) {
        chunk(start);
      } else {
        chunks.forEach(c => {
          msg.author.sendMessage(header + c, { disableEveryone: false });
        });
        utils.finish(msg, exports.name);
      }
    }

    chunk(responses.length - 1);

    function chunk(start) {
      let str = '';
      for (let i = start; i >= 0; i--) {
        const dur = moment(responses[i].timestamp).fromNow();
        const strToAdd = `\`\`${responses[i].author.username} - ${dur}\`\`\n${responses[i].content}\n\n`;
        const combinedLength = str.length + strToAdd.length + header.length;
        if (combinedLength > 2000) {
          chunks.push(str);
          nextChunk(i);
          return;
        } else {
          str += strToAdd;
        }
      }
      chunks.push(str);
      nextChunk(null);
    }
  }
};<commit_msg>Updated mentions command<commit_after>'use strict';
exports.info = {
  desc: 'Search messages for user/role mentions and posts results via DM.',
  usage: '[number]',
  aliases: [],
};

const moment = require('moment');
const logger = require('winston');
const utils = require('../utilities');

exports.run = (client, msg, params = []) => new Promise(async(resolve, reject) => {
  // Exit if not ran in normal text channel (no DMs)
  if (msg.channel.type === 'dm') {
    utils.dmDenied(msg).then(resolve).catch(reject);
    return;
  }
  // Set amount of messages to retrieve
  let max = parseInt(params[0]) || 500;
  // Don't allow over 10k messages to be searched
  if (max > 10000) {
    max = 10000;
  }

  const delay = 1000;
  msg.channel.sendMessage(':mailbox_with_mail:');
  msg.author.sendMessage(`Searching for @ mentions in **#${msg.channel.name}**. Estimated time: ` +
    `${Math.floor((delay / 1000) * (max / 100))} seconds.`);

  const responses = [];
  let count = 0;
  let id = msg.channel.lastMessageID;
  let messages;

  while (count < max) {
    try {
      messages = await msg.channel.fetchMessages({ limit: 100, before: id });
      id = messages.first().id;
      responses.concat(messages);
    } catch (err) {
      logger.error(err);
    }
    count += 100;
    await dwell(delay);
  }
  const mentions = extractMentions(msg, messages);
  processMentions(msg, mentions).then(resolve).catch(reject);
});


function dwell(d) {
  return new Promise(resolve => setTimeout(resolve, d));
}

function extractMentions(msg, messages) {
  const mentions = [];
  messages.forEach(m => {
    if (m.mentions.everyone) {
      mentions.push(m);
      return;
    }
    if (m.isMentioned(msg.author)) {
      mentions.push(m);
      return;
    }
    msg.member.roles.some(r => {
      if (m.isMentioned(r)) {
        m.content = m.content.replace(/<@&\d+>/g, `@${r.name}`);
        mentions.push(m);
        return true;
      }
      return false;
    });
  });
  return mentions;
}

function processMentions(msg, mentions) {
  return new Promise((resolve, reject) => {
    if (mentions.length === 0) {
      msg.author.sendMessage(`\`\`No mentions were found in #${msg.channel.name}.\`\``)
        .then(resolve).catch(reject);
      return;
    }
    const header = `\`\`\`Mentions from #${msg.channel.name}.\`\`\`\n`;
    const chunks = [];
    let str = '';
    logger.debug('mentions to mention:', mentions.length);
    mentions.reverse().forEach(message => {
      const dur = moment(message.createdAt).fromNow();
      const strToAdd = `\`\`${message.author.username} - ${dur}\`\`\n${message.content}\n\n`;
      const combinedLength = str.length + strToAdd.length + header.length;
      if (combinedLength < 1950) {
        str += strToAdd;
      } else {
        chunks.push(str);
        str = '';
      }
    });
    chunks.push(str);
    chunks.forEach(c => {
      msg.author.sendMessage(header + c);
    });
  });
}
{'fraction_non_alphanumeric': 0.17148663435985617, 'fraction_numerical': 0.0131311552290136, 'mean_word_length': 2.4031914893617023, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 25, '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': '617600', 'n_tokens_mistral': 2189, 'n_tokens_neox': 2094, 'n_words': 460}