import { exec } from 'child_process'; import { promisify } from 'util'; import path from 'path'; import { Recipe, RecipeImportResponse } from '@basil/shared'; const execAsync = promisify(exec); export class ScraperService { async scrapeRecipe(url: string): Promise { try { // Call Python recipe-scrapers script (path relative to working directory /app/packages/api) const scriptPath = 'scripts/scrape_recipe.py'; const { stdout, stderr } = await execAsync(`python3 ${scriptPath} "${url}"`, { timeout: 30000, // 30 second timeout }); if (stderr && !stdout) { throw new Error(`Python script error: ${stderr}`); } // Parse the JSON output from the Python script const result: RecipeImportResponse = JSON.parse(stdout); // Add source URL if not present if (result.recipe) { result.recipe.sourceUrl = url; } return result; } catch (error) { console.error('Error scraping recipe:', error); return { success: false, error: error instanceof Error ? error.message : 'Failed to scrape recipe', recipe: {}, }; } } }