Skip to main content
Glama

mcp-pinterest

import fs from 'node:fs'; import path from 'node:path'; import axios from 'axios'; import { generateFileName, DEFAULT_FILENAME_TEMPLATE } from './filename-template.js'; // 从环境变量获取代理设置 const PROXY_SERVER = process.env.MCP_PINTEREST_PROXY_SERVER || ''; const PROXY_ENABLED = !!PROXY_SERVER; // 如果设置了代理服务器,配置axios使用代理 const axiosConfig = { timeout: 30000, // 30秒超时 headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' } }; // 如果启用了代理,添加代理配置 if (PROXY_ENABLED) { // 从代理字符串中提取协议、主机和端口 // 格式应该是 "http://host:port" 或 "socks5://host:port" const proxyMatch = PROXY_SERVER.match(/^(https?|socks[45]):\/\/([^:]+):(\d+)/i); if (proxyMatch) { const [, protocol, host, port] = proxyMatch; console.log(`下载图片使用代理: ${protocol}://${host}:${port}`); axiosConfig.proxy = { protocol, host, port: Number.parseInt(port, 10) }; } else { console.warn(`代理格式无效: ${PROXY_SERVER},格式应为 "http://host:port" 或 "socks5://host:port"`); } } /** * 下载Pinterest图片到指定目录,带有重试机制 * @param {Object} pinterestResult - Pinterest搜索结果对象 * @param {string} pinterestResult.id - 图片ID * @param {string} pinterestResult.image_url - 图片URL * @param {string} downloadDir - 下载目录路径 * @param {Object} [options] - 可选配置项 * @param {string} [options.filenameTemplate=DEFAULT_FILENAME_TEMPLATE] - 文件名模板 * @param {number} [options.maxRetries=3] - 最大重试次数 * @param {number} [options.index] - 在批量下载中的索引(可选) * @returns {Promise<Object>} 下载结果 */ export async function downloadImage(pinterestResult, downloadDir, options = {}) { const { filenameTemplate = DEFAULT_FILENAME_TEMPLATE, maxRetries = 3, index } = options; let retries = 0; let lastError = null; while (retries <= maxRetries) { try { // 确保下载目录存在 if (!fs.existsSync(downloadDir)) { await fs.promises.mkdir(downloadDir, { recursive: true }); } // 从URL中提取图片ID let imageId = pinterestResult.id; if (!imageId) { // 如果没有ID,从URL中提取 const urlParts = pinterestResult.image_url.split('/'); imageId = urlParts[urlParts.length - 1].split('.')[0]; } // 获取文件扩展名 const fileExtension = pinterestResult.image_url.split('.').pop().split('?')[0] || 'jpg'; // 使用模板生成文件名 const fileName = generateFileName(filenameTemplate, { imageId, fileExtension, index }); const outputPath = path.join(downloadDir, fileName); // 使用配置好的axios下载图片 const requestConfig = { ...axiosConfig, responseType: 'arraybuffer' }; const response = await axios.get(pinterestResult.image_url, requestConfig); // 保存图片到文件 await fs.promises.writeFile(outputPath, Buffer.from(response.data)); return { success: true, id: imageId, path: outputPath, url: pinterestResult.image_url }; } catch (error) { lastError = error; // 是否值得重试的错误 const isRetryableError = error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT' || error.message.includes('Connection closed') || error.message.includes('timeout') || (error.response && error.response.status >= 500); if (isRetryableError && retries < maxRetries) { // 计算指数退避延迟时间 (1s, 2s, 4s, ...) const delay = 2 ** retries * 1000; // Only log errors when not in a test environment if (process.env.NODE_ENV !== 'test') { console.log(`下载重试 (${retries + 1}/${maxRetries}) 延迟 ${delay}ms: ${pinterestResult.image_url}`); } await new Promise(resolve => setTimeout(resolve, delay)); retries++; } else { // 达到最大重试次数或不可重试的错误 if (process.env.NODE_ENV !== 'test') { console.error(`下载图片失败 (重试了 ${retries} 次): ${error.message}`); } throw error; } } } // 如果所有重试都失败了 throw lastError; } /** * 批量下载Pinterest图片 * @param {Array} results - Pinterest搜索结果数组 * @param {string} downloadDir - 下载目录路径 * @param {Object} [options] - 可选配置项 * @param {string} [options.filenameTemplate=DEFAULT_FILENAME_TEMPLATE] - 文件名模板 * @param {number} [options.maxRetries=3] - 最大重试次数 * @returns {Promise<Object>} 批量下载结果 */ export async function batchDownload(results, downloadDir, options = {}) { const { filenameTemplate = DEFAULT_FILENAME_TEMPLATE, maxRetries = 3 } = options; // 确保下载目录存在 if (!fs.existsSync(downloadDir)) { await fs.promises.mkdir(downloadDir, { recursive: true }); } const downloadResults = { success: true, total: results.length, downloadedCount: 0, failedCount: 0, downloaded: [], failed: [] }; // 批量下载图片 for (let i = 0; i < results.length; i++) { const result = results[i]; try { if (result?.image_url) { const downloadResult = await downloadImage(result, downloadDir, { filenameTemplate, maxRetries, index: i + 1 }); downloadResults.downloaded.push(downloadResult); downloadResults.downloadedCount++; } } catch (error) { downloadResults.failed.push({ url: result?.image_url ?? 'unknown', error: error.message }); downloadResults.failedCount++; } } return downloadResults; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/terryso/mcp-pinterest'

If you have feedback or need assistance with the MCP directory API, please join our Discord server