<commit_before>const config = require('../../config.js')
const Joi = require('@hapi/joi')
const createLogger = require('../../util/logger/create.js')
const schema = Joi.object({
  status: Joi.string().valid('online', 'idle', 'invisible', 'dnd'),
  activity: Joi.object({
    name: Joi.string(),
    type: Joi.string().valid('PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM_STATUS'),
    url: Joi.string().when('type', {
      is: 'STREAMING',
      then: Joi.string().required()
    })
  })
})

function getPresenceFromArgs (args) {
  const status = args[0]
  const activityType = args[1]
  const activityName = args[2]
  const activityURL = args[3]
  const presenceData = {}
  if (status) {
    presenceData.status = status
  }
  if (activityType) {
    presenceData.activity = {
      type: activityType
    }
    if (activityName) {
      presenceData.activity.name = activityName
    }
    if (activityURL) {
      presenceData.activity.url = activityURL
    }
  }
  return presenceData
}

function setConfig (presenceData) {
  if (presenceData.status) {
    config.bot.status = presenceData.status
  }
  if (presenceData.activity.type) {
    config.bot.activityType = presenceData.activity.type
  }
  if (presenceData.activity.name) {
    config.bot.activityName = presenceData.activity.name
  }
  if (presenceData.activity.url) {
    config.bot.streamActivityURL = presenceData.activity.url
  }
}

module.exports = async (message) => {
  const args = message.content.split(' ').map(s => s.trim()).filter(s => s)
  args.shift()
  if (args.length === 0) {
    return message.channel.send(`Insufficient number of arguments.`)
  }
  const presenceData = getPresenceFromArgs(args)
  const results = schema.validate(presenceData, {
    abortEarly: false
  })
  if (results.error) {
    const str = results.error.details.map(d => d.message).join('\n')
    return message.channel.send(`Invalid format. Errors:\n\n${str}`)
  }
  setConfig(presenceData)
  await message.client.user.setPresence(presenceData)
  await message.client.shard.broadcastEval(`
    const path = require('path');
    const appDir = path.dirname(require.main.filename);
    const config = require(appDir + '/src/config.js');
    config.bot = JSON.parse(\`${JSON.stringify(config.bot)}\`)
  `)
  const log = createLogger(message.guild.shard.id)
  log.owner({
    user: message.author,
    presenceData
  }, `Set presence`)
  await message.channel.send(`Successfully changed presence.`)
}<commit_msg>Fix setpresence not accepting multi-word names<commit_after>const config = require('../../config.js')
const Joi = require('@hapi/joi')
const createLogger = require('../../util/logger/create.js')
const schema = Joi.object({
  status: Joi.string().valid('online', 'idle', 'invisible', 'dnd'),
  activity: Joi.object({
    name: Joi.string(),
    type: Joi.string().valid('PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM_STATUS'),
    url: Joi.string().when('type', {
      is: 'STREAMING',
      then: Joi.string().required()
    })
  })
})

function getPresenceFromArgs (args) {
  const status = args[0]
  const activityType = args[1]
  const activityName = args[1] === 'STREAMING' ? args.slice(2, args.length - 1).join(' ') : args.slice(2).join(' ')
  const activityURL = args[1] === 'STREAMING' ? args[args.length - 1] : ''
  const presenceData = {}
  if (status) {
    presenceData.status = status
  }
  if (activityType) {
    presenceData.activity = {
      type: activityType
    }
    if (activityName) {
      presenceData.activity.name = activityName
    }
    if (activityURL) {
      presenceData.activity.url = activityURL
    }
  }
  return presenceData
}

function setConfig (presenceData) {
  if (presenceData.status) {
    config.bot.status = presenceData.status
  }
  if (presenceData.activity.type) {
    config.bot.activityType = presenceData.activity.type
  }
  if (presenceData.activity.name) {
    config.bot.activityName = presenceData.activity.name
  }
  if (presenceData.activity.url) {
    config.bot.streamActivityURL = presenceData.activity.url
  }
}

module.exports = async (message) => {
  const args = message.content.split(' ').map(s => s.trim()).filter(s => s)
  args.shift()
  if (args.length === 0) {
    return message.channel.send(`Insufficient number of arguments.`)
  }
  const presenceData = getPresenceFromArgs(args)
  const results = schema.validate(presenceData, {
    abortEarly: false
  })
  if (results.error) {
    const str = results.error.details.map(d => d.message).join('\n')
    return message.channel.send(`Invalid format. Errors:\n\n${str}`)
  }
  setConfig(presenceData)
  await message.client.user.setPresence(presenceData)
  await message.client.shard.broadcastEval(`
    const path = require('path');
    const appDir = path.dirname(require.main.filename);
    const config = require(appDir + '/src/config.js');
    config.bot = JSON.parse(\`${JSON.stringify(config.bot)}\`)
  `)
  const log = createLogger(message.guild.shard.id)
  log.owner({
    user: message.author,
    presenceData
  }, `Set presence`)
  await message.channel.send(`Successfully changed presence. It may be some time until it shows due to rate limiting.`)
}
{'fraction_non_alphanumeric': 0.1541586073500967, 'fraction_numerical': 0.0027079303675048355, 'mean_word_length': 3.6046304541406946, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '6867504', 'n_tokens_mistral': 1674, 'n_tokens_neox': 1686, 'n_words': 333}