File size: 3,443 Bytes
f238d4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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.' 
    });
  }
}