← back to Animate Museum Posts

src/duplicateTracker.js

82 lines

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

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

const DATA_DIR = path.join(__dirname, '..', 'data');
const POSTED_FILE = path.join(DATA_DIR, 'posted-artworks.json');
const MAX_ENTRIES = 1000;
const DUPLICATE_WINDOW_DAYS = 30;

function ensureDataDir() {
  if (!fs.existsSync(DATA_DIR)) {
    fs.mkdirSync(DATA_DIR, { recursive: true });
  }
}

function loadPostedArtworks() {
  ensureDataDir();
  try {
    if (fs.existsSync(POSTED_FILE)) {
      return JSON.parse(fs.readFileSync(POSTED_FILE, 'utf-8'));
    }
  } catch (error) {
    console.error('Error loading posted artworks:', error.message);
  }
  return [];
}

function savePostedArtworks(artworks) {
  ensureDataDir();
  // Keep only last MAX_ENTRIES
  const trimmed = artworks.slice(-MAX_ENTRIES);
  fs.writeFileSync(POSTED_FILE, JSON.stringify(trimmed, null, 2));
}

export function isRecentlyPosted(objectNumber) {
  const posted = loadPostedArtworks();
  const cutoff = Date.now() - (DUPLICATE_WINDOW_DAYS * 24 * 60 * 60 * 1000);

  return posted.some(entry => {
    if (entry.objectNumber !== objectNumber) return false;
    const postedTime = new Date(entry.postedAt).getTime();
    return postedTime > cutoff;
  });
}

export function markAsPosted(artwork, tweetId) {
  const posted = loadPostedArtworks();

  posted.push({
    objectNumber: artwork.objectNumber,
    title: artwork.title,
    artist: artwork.artist,
    museum: artwork.museum || artwork.sourceMuseum,
    tweetId: tweetId,
    postedAt: new Date().toISOString()
  });

  savePostedArtworks(posted);
  console.log(`Marked as posted: ${artwork.objectNumber}`);
}

export function getRecentPosts(limit = 10) {
  const posted = loadPostedArtworks();
  return posted.slice(-limit).reverse();
}

export function getStats() {
  const posted = loadPostedArtworks();
  const cutoff = Date.now() - (DUPLICATE_WINDOW_DAYS * 24 * 60 * 60 * 1000);
  const recent = posted.filter(p => new Date(p.postedAt).getTime() > cutoff);

  return {
    totalPosted: posted.length,
    recentCount: recent.length,
    oldestEntry: posted[0]?.postedAt || null,
    newestEntry: posted[posted.length - 1]?.postedAt || null
  };
}