<commit_before>const mongo = require('../../helpers/mongo.js')
const async = require('gw2e-async-promises')
const recipeCalculation = require('gw2e-recipe-calculation')
const legendaries = require('../../static/legendaries.js')
const precursors = require('../../static/precursors.js')

async function craftingPrices (job, done) {
  job.log(`Starting job`)

  let recipes = await mongo.collection('recipe-trees').find().toArray()
  let prices = await mongo.collection('items').find(
    {tradable: true, 'buy.price': {$gt: 0}, 'sell.price': {$gt: 0}},
    {_id: 0, id: 1, 'buy.price': 1, 'sell.price': 1}
  ).toArray()
  job.log(`Calculating crafting prices for ${recipes.length} recipes`)

  // Build the price arrays
  let sellPrices = {}
  let buyPrices = {}
  prices.map(item => {
    buyPrices[item.id] = item.buy.price
    sellPrices[item.id] = item.sell.price
  })
  buyPrices = recipeCalculation.useVendorPrices(buyPrices)
  sellPrices = recipeCalculation.useVendorPrices(sellPrices)
  job.log(`Generated buy and sell prices`)

  // Go through the recipes and update the items with
  // the cheapest crafting price
  let updateFunctions = recipes.map(recipe =>
    () => craftingPrice(recipe, buyPrices, sellPrices)
  )
  job.log(`Generated update functions`)

  await async.parallel(updateFunctions)
  job.log(`Updated crafting prices`)
  done()
}

// Add all the crafting prices for a single item
async function craftingPrice (recipe, buyPrices, sellPrices) {
  let item = {
    crafting: calculateCraftingPrice(recipe, buyPrices, sellPrices)
  }

  // If the item is a legendary add an additional
  // crafting object without precursor crafting
  if (legendaries.indexOf(recipe.id) !== -1) {
    item.craftingWithoutPrecursors = calculateCraftingPrice(recipe, buyPrices, sellPrices, precursors)
  }

  await mongo.collection('items').updateMany({id: recipe.id}, {$set: item})
}

// Actually calculate the crafting price for a recipe
function calculateCraftingPrice (recipe, buyPrices, sellPrices, ignoreItems = []) {
  let buyCraftPrice = recipeCalculation.cheapestTree(1, recipe, buyPrices, {}, ignoreItems).craftPrice
  let sellCraftPrice = recipeCalculation.cheapestTree(1, recipe, sellPrices, {}, ignoreItems).craftPrice
  let output = Math.ceil(recipe.output)

  // Calculate the normal crafting prices
  let prices = {
    buy: Math.round(buyCraftPrice / output),
    sell: Math.round(sellCraftPrice / output)
  }

  // Calculate the crafting price without daily cooldowns
  if (needsDailyCooldowns(recipe)) {
    ignoreItems = ignoreItems.concat(recipeCalculation.static.buyableDailyCooldowns)
    buyCraftPrice = recipeCalculation.cheapestTree(1, recipe, buyPrices, {}, ignoreItems).craftPrice<commit_msg>Clean up crafting prices<commit_after>const mongo = require('../../helpers/mongo.js')
const async = require('gw2e-async-promises')
const recipeCalculation = require('gw2e-recipe-calculation')
const legendaries = require('../../static/legendaries.js')
const precursors = require('../../static/precursors.js')

async function craftingPrices (job, done) {
  job.log(`Starting job`)

  let recipes = await mongo.collection('recipe-trees').find().toArray()
  job.log(`Calculating crafting prices for ${recipes.length} recipes`)

  let prices = await getPrices()
  job.log(`Generated buy and sell prices`)

  recipes = recipes.map(recipe => craftingPrice(recipe, prices.buyPrices, prices.sellPrices))
  job.log(`Calculated recipe crafting prices`)

  let updateFunctions = recipes.map(recipe =>
    () => mongo.collection('items').updateMany({id: recipe.id}, {$set: recipe})
  )
  job.log(`Generated update functions`)

  await async.parallel(updateFunctions)
  job.log(`Updated crafting prices`)
  done()
}

async function getPrices () {
  let prices = await mongo.collection('items').find(
    {tradable: true, 'buy.price': {$gt: 0}, 'sell.price': {$gt: 0}},
    {_id: 0, id: 1, 'buy.price': 1, 'sell.price': 1}
  ).toArray()

  // Build the price maps
  let sellPrices = {}
  let buyPrices = {}
  prices.map(item => {
    buyPrices[item.id] = item.buy.price
    sellPrices[item.id] = item.sell.price
  })

  // Make sure we use vendor prices
  buyPrices = recipeCalculation.useVendorPrices(buyPrices)
  sellPrices = recipeCalculation.useVendorPrices(sellPrices)

  return {sellPrices: sellPrices, buyPrices: buyPrices}
}

// Add all the crafting prices for a single item
function craftingPrice (recipe, buyPrices, sellPrices) {
  let prices = {
    crafting: calculateCraftingPrice(recipe, buyPrices, sellPrices)
  }

  // If the item is a legendary add an additional key without precursor crafting
  if (legendaries.indexOf(recipe.id) !== -1) {
    prices.craftingWithoutPrecursors = calculateCraftingPrice(recipe, buyPrices, sellPrices, precursors)
  }

  return {id: recipe.id, ...prices}
}

// Actually calculate the crafting price for a recipe
function calculateCraftingPrice (recipe, buyPrices, sellPrices, ignoreItems = []) {
  let buyCraftPrice = recipeCalculation.cheapestTree(1, recipe, buyPrices, {}, ignoreItems).craftPrice
  let sellCraftPrice = recipeCalculation.cheapestTree(1, recipe, sellPrices, {}, ignoreItems).craftPrice
  let output = Math.ceil(recipe.output)

  // Calculate the normal crafting prices
  let prices = {
    buy: Math.round(buyCraftPrice / output),
    sell: Math.round(sellCraftPrice / output)
  }

  // Calculate the crafting price without daily cooldowns
  if (needsDailyCooldowns(recipe)) {
    ignoreItems = ignoreItems.concat(recipeCalculation.static.buyableDailyCooldowns)
    buyCraftPrice = recipeCalculation.cheapestTree(1, recipe, buyPrices, {}, ignoreItems).craftPrice
{'fraction_non_alphanumeric': 0.1271953166577967, 'fraction_numerical': 0.004257583821181479, 'mean_word_length': 4.554679802955665, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 10, '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': '2251573', 'n_tokens_mistral': 1859, 'n_tokens_neox': 1734, 'n_words': 432}