import axios from 'axios'; import * as cheerio from 'cheerio'; import AdmZip from 'adm-zip'; export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } const { url } = req.body; if (!url) { return res.status(400).json({ error: 'URL is required' }); } try { // 1. Fetch the DeviantArt page // Note: In production, you might need to handle headers or proxies to mimic a browser const response = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } }); const html = response.data; const $ = cheerio.load(html); // 2. Extract image URL // DeviantArt structures change frequently. This attempts to find the main image. let imageUrl = ''; // Try to find the image in the standard embed structure const imgElement = $('.dev-view-deviation img').first(); if (imgElement.length && imgElement.attr('src')) { imageUrl = imgElement.attr('src'); } else { // Fallback: Look for any large image in the content const fallbackImg = $('img[src*="deviantart.net"]').filter((i, el) => { const src = $(el).attr('src'); return src && !src.includes('avatar') && !src.includes('symbol'); }).first(); if (fallbackImg.length) { imageUrl = fallbackImg.attr('src'); } } if (!imageUrl) { return res.status(404).json({ error: 'Could not find an image on the provided page. Ensure it is a direct artwork link.' }); } // Clean up URL (remove query parameters for better fetching) const cleanImageUrl = imageUrl.split('?')[0]; // 3. Download the image const imageResponse = await axios.get(cleanImageUrl, { responseType: 'arraybuffer', headers: { 'Referer': url, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } }); const imageBuffer = Buffer.from(imageResponse.data); // 4. Create ZIP file const zip = new AdmZip(); const extension = cleanImageUrl.split('.').pop().split('?')[0] || 'jpg'; const fileName = `deviantart_image.${extension}`; zip.addFile(fileName, imageBuffer); // 5. Convert ZIP to buffer const zipBuffer = zip.toBuffer(); // 6. Mock MediaFire Upload Logic // Note: Actual MediaFire API requires API keys and OAuth tokens which cannot be securely embedded here. // For the purpose of this functional demo, we serve the file directly from this endpoint. // In a real scenario, you would send 'zipBuffer' to MediaFire's upload API here. // Set headers to trigger browser download res.setHeader('Content-Type', 'application/zip'); res.setHeader('Content-Disposition', `attachment; filename="deviantart_download.zip"`); res.setHeader('Content-Length', zipBuffer.length); return res.send(zipBuffer); } catch (error) { console.error('Processing error:', error.message); if (error.response) { return res.status(error.response.status).json({ error: `Failed to fetch DeviantArt page: ${error.response.status}` }); } return res.status(500).json({ error: 'An error occurred while processing the image. The link might be invalid or protected.' }); } }