← back to Animate Museum Posts

src/fetchFromRijksmuseum.js

102 lines

import axios from 'axios';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';

dotenv.config();

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

const RIJKS_API_BASE = 'https://www.rijksmuseum.nl/api/nl/collection';

export async function fetchFromRijksmuseum() {
  const apiKey = process.env.RIJKSMUSEUM_API_KEY;

  if (!apiKey || apiKey === '0') {
    throw new Error('Rijksmuseum API key not configured');
  }

  try {
    console.log('Fetching from Rijksmuseum...');

    // Get collection with images only, top pieces
    const response = await axios.get(RIJKS_API_BASE, {
      params: {
        key: apiKey,
        imgonly: true,
        toppieces: true,
        ps: 50,  // 50 results per page
        p: Math.floor(Math.random() * 10) + 1  // Random page 1-10
      },
      timeout: 30000
    });

    if (!response.data || !response.data.artObjects || response.data.artObjects.length === 0) {
      throw new Error('No artworks found from Rijksmuseum');
    }

    // Pick random artwork with valid image
    const artworks = response.data.artObjects.filter(a => a.webImage && a.webImage.url);
    if (artworks.length === 0) {
      throw new Error('No artworks with images found');
    }

    const artwork = artworks[Math.floor(Math.random() * artworks.length)];

    console.log(`Downloading: ${artwork.title}`);
    const imageResponse = await axios.get(artwork.webImage.url, {
      responseType: 'arraybuffer',
      timeout: 30000,
      headers: {
        'User-Agent': 'Mozilla/5.0 (compatible; MuseumBot/1.0)'
      }
    });

    if (!imageResponse.data || imageResponse.data.length < 1000) {
      throw new Error('Failed to download image');
    }

    // Save to output directory
    const outputDir = path.join(__dirname, '..', 'output');
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }

    const timestamp = Date.now();
    const fileName = `rijks_${timestamp}.jpg`;
    const filePath = path.join(outputDir, fileName);
    fs.writeFileSync(filePath, imageResponse.data);

    // Return normalized metadata
    const metadata = {
      title: artwork.title || 'Untitled',
      artist: artwork.principalOrFirstMaker || 'Unknown Artist',
      year: artwork.dating?.presentingDate || 'Date Unknown',
      description: artwork.longTitle || '',
      objectNumber: artwork.objectNumber,
      imageUrl: artwork.webImage.url,
      localPath: filePath,
      fileName: fileName,
      museum: 'Rijksmuseum, Amsterdam',
      creditLine: 'Rijksmuseum (Public Domain)',
      dimensions: []
    };

    console.log(`Rijksmuseum: Fetched "${metadata.title}" by ${metadata.artist}`);
    return metadata;

  } catch (error) {
    console.error('Rijksmuseum fetch failed:', error.message);
    throw error;
  }
}

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