const fs = require('fs') const config = require('./config') const random = require('./random') const classes = require('./classes') const score = require('./score') let batchCount = 1 // Counter to track how many things we've generated let extraProfilesToGenerate = 0 let extraProfileCount = 0 // Counter to track how many EXTRA profiles we've generated let generatedResponseCount = 0 // Counter to track every response generated // Values for responsess as strings const possibleResponses = { not_important: null, some_what_important: null, important: null, very_important: null, extremely_important: null, mandatory: null, } for (let i = 0; i < Object.keys(possibleResponses).length; i++) { const key = Object.keys(possibleResponses)[i] possibleResponses[key] = config.scoreVals[i].toString() } /** * Our initial file setup */ const write = async (batchNum, outputDataObject) => { await fs.writeFile(`${config.mockOutputPath}_${batchNum}.js`, '', () => {}) fs.appendFile( `${config.mockOutputPath}_${batchNum}.js`, config.header + 'module.exports = ' + JSON.stringify(outputDataObject), err => { if (err) { console.error(err) return } }, ) } // Helper functions // const preComputedScores = score.precomputed const generate = (classObj, amount, meta) => { const instances = [] for (let i = 0; i < amount; i++) { let startFrom = meta?.starting ? meta.starting - config.batchSize : 0 instances.push(new classObj(i + startFrom + 1, meta)) } return instances } console.log('\nStarting...\n---') /** * Generate Users */ const generateUsers = () => { let users = generate(classes.User, config.batchSize, { starting: config.batchSize * batchCount, }) users.forEach(user => { user.is_poster = random.number(100) > config.percentageOfSeekers ? 1 : 0 if (user.is_poster) { extraProfilesToGenerate = extraProfilesToGenerate + random.number(2) } user.user_name = random.name() + ' ' + random.name() user.user_email = random.email() var mediaArray = [] for (let i=0; i < 3; i++) { mediaArray.push(random.media()) } // TODO: make this a table // user.user_media = mediaArray }) console.log('COMPLETED: Generated Users...') return users } /** * Generate Profiles */ const generateProfiles = jobPosterIds => { let profiles = generate(classes.Profile, config.batchSize, { starting: config.batchSize * batchCount, profile_id: extraProfileCount, }) // Generate extra job posting profiles // attributed to random user.is_poster === true // TODO: Clean this up. Hard to read... if (extraProfilesToGenerate > 0) { let extras = [] for (let l = 0; l < extraProfilesToGenerate; l++) { const generatedExtraProfiles = generate(classes.Profile, 1, { user_id: jobPosterIds.length > 1 ? random.valFrom(jobPosterIds) : jobPosterIds[0], profile_id: config.batchSize * batchCount + extraProfileCount + l, }) extras = [...extras, ...generatedExtraProfiles] } extras.forEach(profile => { profiles.push(profile) extraProfileCount++ }) } console.log('COMPLETED: Generated Profiles...') return profiles } /** * Generate Responses */ const generateResponses = profiles => { // Generate responses first, before filling in details let responses = generate( classes.Response, (config.batchSize + extraProfilesToGenerate) * config.questions, { starting: generatedResponseCount + config.batchSize }, ) profiles.forEach((profile, i) => { const startingIndex = i * config.questions for (let k = 0; k < config.questions; k++) { const resToEdit = responses[startingIndex + k] resToEdit.response_key_id = k + 1 resToEdit.profile_id = profile.profile_id resToEdit.val = k + 1 == config.questions ? random.valFrom(config.possibleZipcodes) : random.valFrom(Object.values(possibleResponses)) } }) generatedResponseCount = generatedResponseCount + responses.length console.log('COMPLETED: Generated Responses...') return responses } /** * Our main generator loop */ for ( let batch = config.batchSize; batch <= config.total; batch += config.batchSize ) { const users = generateUsers() let jobPosterIds = users .filter(user => user.is_poster > 0) .map(user => user.user_id) // Guarentee ONE job poster if (!jobPosterIds.length) { random.valFrom(users).is_poster = 1 jobPosterIds = users .filter(user => user.is_poster > 0) .map(user => user.user_id) } const profiles = generateProfiles(jobPosterIds) const responses = generateResponses(profiles) write(config.batchSize * batchCount, { users, profiles, responses }) batchCount++ } /** * Score all the profiles! */ // const compareProfileResponses = (seeker, potentialMatch) => { // const checkValCb = res => { // const val = parseInt(res.val) // return isNaN(val) ? 0 : val // } // const filterBy = idToCheckFor => { // return responses // .filter( // response => // response.profile_id == idToCheckFor && // response.val.length < 4, // ) // .map(checkValCb) // } // const seekerResponses = filterBy(seeker.profile_id) // const potentialMatchResponses = filterBy(potentialMatch.profile_id) // const cachedScores = [] // seekerResponses.forEach(seekerResponse => { // potentialMatchResponses.forEach(potentialResponse => { // cachedScores.push( // preComputedScores[seekerResponse][potentialResponse], // ) // }) // }) // return Math.round( // cachedScores.reduce((a, b) => a + b) / cachedScores.length, // ) // } // const scoreProfile = (profile, potentialMatchList) => { // return potentialMatchList // .map(profileToCompare => { // return { // match_queue_id: null, // profile_id: profile.profile_id, // target_id: profileToCompare.profile_id, // is_deleted: false, // score: compareProfileResponses(profile, profileToCompare), // } // }) // .sort((a, b) => a.score - b.score) // } // const scoreAll = () => { // process.stdout.write('\nScoring Profiles') // let scores = [] // const posterProfiles = profiles.filter(profile => // jobPosterIds.includes(profile.user_id), // ) // const seekerProfiles = profiles.filter( // profile => !jobPosterIds.includes(profile.user_id), // ) // process.stdout.write('.') // for (let i = 0; i < seekerProfiles.length; i++) { // const scored = scoreProfile(seekerProfiles[i], posterProfiles) // scores.push(...scored) // } // process.stdout.write('.') // for (let j = 0; j < posterProfiles.length; j++) { // const scored = scoreProfile(posterProfiles[j], seekerProfiles) // scores.push(...scored) // } // process.stdout.write('.') // console.log('\n\nCOMPLETED: Scoring Profiles...') // return scores.reverse() // } // const match_queues = scoreAll().map((score, i) => { // score.match_queue_id = i + 1 // // Comment out next line to see the scores // delete score.score // return score // }) console.log('---\nFINISHED...\n===\n')