← back to Animate Museum Posts

src/fetchFromMuseums.js

94 lines

import { fetchFromRijksmuseum } from './fetchFromRijksmuseum.js';
import { fetchFromMet } from './fetchFromMet.js';
import { fetchFromAIC } from './fetchFromAIC.js';
import { fetchRandomArtwork } from './fetchArtwork.js';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Museum sources with weights
const MUSEUMS = [
  { name: 'Rijksmuseum', fetch: fetchFromRijksmuseum, weight: 3, requiresKey: true },
  { name: 'Metropolitan Museum', fetch: fetchFromMet, weight: 3, requiresKey: false },
  { name: 'Art Institute Chicago', fetch: fetchFromAIC, weight: 3, requiresKey: false },
  { name: 'Hardcoded Collection', fetch: fetchRandomArtwork, weight: 1, requiresKey: false }
];

function selectRandomMuseum() {
  // Filter out museums that require keys we don't have
  const available = MUSEUMS.filter(m => {
    if (m.requiresKey && m.name === 'Rijksmuseum') {
      const key = process.env.RIJKSMUSEUM_API_KEY;
      return key && key !== '0';
    }
    return true;
  });

  // Weighted random selection
  const totalWeight = available.reduce((sum, m) => sum + m.weight, 0);
  let random = Math.random() * totalWeight;

  for (const museum of available) {
    random -= museum.weight;
    if (random <= 0) {
      return museum;
    }
  }

  return available[available.length - 1];
}

export async function fetchFromMuseums() {
  const errors = [];

  // Try random museum first
  const primaryMuseum = selectRandomMuseum();
  console.log(`Trying primary source: ${primaryMuseum.name}`);

  try {
    const artwork = await primaryMuseum.fetch();
    artwork.sourceMuseum = primaryMuseum.name;
    console.log(`Success from ${primaryMuseum.name}`);
    return artwork;
  } catch (error) {
    console.error(`${primaryMuseum.name} failed:`, error.message);
    errors.push({ museum: primaryMuseum.name, error: error.message });
  }

  // Fallback cascade
  const fallbackOrder = ['Metropolitan Museum', 'Art Institute Chicago', 'Hardcoded Collection'];

  for (const museumName of fallbackOrder) {
    if (museumName === primaryMuseum.name) continue;

    const museum = MUSEUMS.find(m => m.name === museumName);
    if (!museum) continue;

    console.log(`Fallback: Trying ${museum.name}...`);

    try {
      const artwork = await museum.fetch();
      artwork.sourceMuseum = museum.name;
      console.log(`Success from ${museum.name} (fallback)`);
      return artwork;
    } catch (error) {
      console.error(`${museum.name} failed:`, error.message);
      errors.push({ museum: museum.name, error: error.message });
    }
  }

  // Log all errors
  console.error('All museum sources failed:', errors);
  throw new Error('All museum sources failed');
}

// Test if run directly
if (process.argv[1] === fileURLToPath(import.meta.url)) {
  fetchFromMuseums()
    .then(m => console.log('Success:', JSON.stringify(m, null, 2)))
    .catch(e => console.error('Failed:', e.message));
}