← back to Wine Finder

scripts/setup-wine-cron.js

116 lines

#!/usr/bin/env node

/**
 * Setup Cron Job for Wine Crawling
 *
 * Creates a cron job that runs daily at 6:00 AM to crawl wine data
 * from multiple sources across the US.
 */

const { exec } = require('child_process');
const path = require('path');
const fs = require('fs');

const PROJECT_DIR = path.resolve(__dirname, '..');
const CRAWLER_SCRIPT = path.join(PROJECT_DIR, 'crawler', 'wine-crawler.js');
const LOG_DIR = path.join(PROJECT_DIR, 'logs');
const LOG_FILE = path.join(LOG_DIR, 'wine-crawler.log');

// Ensure log directory exists
if (!fs.existsSync(LOG_DIR)) {
  fs.mkdirSync(LOG_DIR, { recursive: true });
  console.log(`✓ Created log directory: ${LOG_DIR}`);
}

// Cron schedule: Daily at 6:00 AM
const CRON_SCHEDULE = '0 6 * * *';

// Get Node.js path
exec('which node', (error, stdout) => {
  if (error) {
    console.error('✗ Error finding Node.js path:', error);
    process.exit(1);
  }

  const nodePath = stdout.trim();
  console.log(`✓ Node.js path: ${nodePath}`);

  // Construct cron command
  const cronCommand = `${CRON_SCHEDULE} ${nodePath} ${CRAWLER_SCRIPT} >> ${LOG_FILE} 2>&1`;

  console.log('\n' + '='.repeat(70));
  console.log('WINE CRAWLER CRON JOB SETUP');
  console.log('='.repeat(70));
  console.log();
  console.log('Schedule:        Daily at 6:00 AM');
  console.log('Cron Expression: ' + CRON_SCHEDULE);
  console.log('Script:          ' + CRAWLER_SCRIPT);
  console.log('Log File:        ' + LOG_FILE);
  console.log();
  console.log('Cron Entry:');
  console.log('-'.repeat(70));
  console.log(cronCommand);
  console.log('-'.repeat(70));
  console.log();

  // Check if cron job already exists
  exec('crontab -l', (error, stdout) => {
    let existingCrontab = '';

    if (!error) {
      existingCrontab = stdout;

      // Check if wine crawler cron already exists
      if (existingCrontab.includes('wine-crawler.js')) {
        console.log('⚠ Wine crawler cron job already exists in crontab');
        console.log();
        console.log('Current crontab entries for wine-crawler.js:');
        console.log('-'.repeat(70));
        existingCrontab.split('\n').forEach(line => {
          if (line.includes('wine-crawler.js')) {
            console.log(line);
          }
        });
        console.log('-'.repeat(70));
        console.log();
        console.log('To update, remove the old entry and run this script again.');
        console.log('To remove: crontab -e (then delete the wine-crawler.js line)');
        process.exit(0);
      }
    }

    // Add new cron job
    const newCrontab = existingCrontab + '\n' + cronCommand + '\n';

    // Write new crontab
    const tempFile = '/tmp/crontab-wine.txt';
    fs.writeFileSync(tempFile, newCrontab);

    exec(`crontab ${tempFile}`, (error) => {
      fs.unlinkSync(tempFile);

      if (error) {
        console.error('✗ Error installing cron job:', error);
        process.exit(1);
      }

      console.log('✓ Wine crawler cron job installed successfully!');
      console.log();
      console.log('The crawler will run daily at 6:00 AM and:');
      console.log('  • Search 20+ wine queries across 7 data sources');
      console.log('  • Crawl K&L Wine, Total Wine, Vivino, and more');
      console.log('  • Deduplicate and save to Google Sheets');
      console.log('  • Create local backup JSON files');
      console.log('  • Log all activity to ' + LOG_FILE);
      console.log();
      console.log('To view current crontab:  crontab -l');
      console.log('To edit crontab:          crontab -e');
      console.log('To remove cron job:       crontab -e (delete the wine-crawler.js line)');
      console.log('To view logs:             tail -f ' + LOG_FILE);
      console.log();
      console.log('To test the crawler now:  node ' + CRAWLER_SCRIPT);
      console.log('='.repeat(70));
    });
  });
});