Wednesday, 17 December 2025

Script code firefly_autodownload_firefox_blob_final.js

 const { firefox } = require('playwright');
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');

const PROMPT_FILE = 'prompts.txt';
const USER_DATA_DIR = path.join(__dirname, 'firefox-profile');
const DOWNLOAD_DIR = path.join(__dirname, 'downloads');

const IMAGES_PER_PROMPT = 1;
const MAX_WAIT = 45000; // maksimal tunggu per prompt (ms)
const POLL_INTERVAL = 1000; // cek tiap 1 detik

const savedBlobs = new Set();

(async () => {
  // === Persiapan folder ===
  if (!fs.existsSync(DOWNLOAD_DIR)) fs.mkdirSync(DOWNLOAD_DIR);

  // === Launch Firefox persistent ===
  const context = await firefox.launchPersistentContext(USER_DATA_DIR, {
    headless: false
  });

  const page = context.pages()[0] || await context.newPage();

  await page.goto('https://firefly.adobe.com/generate/image', {
    waitUntil: 'domcontentloaded'
  });

  console.log('šŸ‘‰ Login Adobe Firefly MANUAL');
  console.log('šŸ‘‰ Atur Model & Aspect Ratio');
  console.log('šŸ‘‰ Tekan ENTER di terminal');
  await new Promise(r => process.stdin.once('data', r));

  // === Prompt box ===
  const promptBox = page.locator('textarea[aria-label="Prompt"]');
  await promptBox.waitFor({ state: 'visible', timeout: 60000 });

  // === Load prompts ===
  const prompts = fs.readFileSync(PROMPT_FILE, 'utf-8')
    .split(/\r?\n/)
    .map(l => l.trim())
    .filter(Boolean);

  console.log(`šŸ”„ Total prompt: ${prompts.length}`);

  // === Loop prompt ===
  for (let i = 0; i < prompts.length; i++) {
    console.log(`\n▶ Prompt ${i + 1}/${prompts.length}`);
    console.log('⏳ Generating...');

    await promptBox.fill('');
    await promptBox.fill(prompts[i]);
    await page.keyboard.press('Enter');

    // ===== POLLING MANUAL (ANTI TIMEOUT) =====
    const start = Date.now();
    let foundNewBlob = false;

    while (Date.now() - start < MAX_WAIT) {
      const blobs = await page.$$eval(
        'img[src^="blob:"]',
        imgs => imgs.map(img => img.src)
      );

      for (const blob of blobs) {
        if (!savedBlobs.has(blob)) {
          foundNewBlob = true;
          break;
        }
      }

      if (foundNewBlob) break;
      await page.waitForTimeout(POLL_INTERVAL);
    }

    if (!foundNewBlob) {
      console.log('⚠️ Tidak ditemukan blob baru, skip prompt ini');
      continue;
    }

    // ===== DOWNLOAD BLOBS TERBARU =====
    const images = page.locator('img[src^="blob:"]');
    const total = await images.count();

    let saved = 0;

    // scan dari belakang (gambar terbaru)
    for (let j = total - 1; j >= 0 && saved < IMAGES_PER_PROMPT; j--) {
      const img = images.nth(j);
      const blobUrl = await img.getAttribute('src');
      if (!blobUrl || savedBlobs.has(blobUrl)) continue;

      const buffer = await page.evaluate(async (url) => {
        const res = await fetch(url);
        const blob = await res.blob();
        return new Uint8Array(await blob.arrayBuffer());
      }, blobUrl);

      savedBlobs.add(blobUrl);
      saved++;

      const safePrompt = prompts[i]
        .slice(0, 40)
        .replace(/[^a-z0-9]+/gi, '_')
        .toLowerCase();

      const filename = `firefly_${i + 1}_${safePrompt}.png`;
      await fsp.writeFile(
        path.join(DOWNLOAD_DIR, filename),
        Buffer.from(buffer)
      );

      console.log(`✅ Saved: ${filename}`);
    }

    await page.waitForTimeout(1000);
  }

  console.log('\nšŸŽ‰ SEMUA PROMPT SELESAI');
})();

Share:

0 comments:

Post a Comment