Spaces:
Sleeping
Sleeping
| const axios = require('axios'); | |
| class AnimeConverter { | |
| constructor() { | |
| this.baseURL = 'https://api.anifun.ai/aitools'; | |
| this.tempURL = 'https://temp.anifun.ai'; | |
| this.headers = { | |
| 'Accept': 'application/json, text/plain, */*', | |
| 'Content-Type': 'application/json', | |
| 'fp': '3bb76e9ae8e3349d2b18784710f9fcf2', | |
| 'fp1': '5J0h1+bPFg4F6qVNO46PpRwyoEoxaViPWymZNXDJBp8Na7vNifH6jre49yHOnzRP', | |
| 'x-guide': 'rYJ2cO93MBTiPlC0ipi8WySUJwAa30Kvjigyvz41a6kCR7hopnzY512gBRd8nGkFB7dNAKkf01jW/3LvfyC9e8U5HZtWnDPoql58VJXOm2VSGyEXPmTzWIkG2PhDFhZnbn/nM3hrjh2YI84k2dpT7q8Hq3tLZ1qV2Yegucrs0hI=', | |
| 'theme-version': '83EmcUoQTUv50LhNx0VrdcK8rcGexcP35FcZDcpgWsAXEyO4xqL5shCY6sFIWB2Q', | |
| 'X-code': Date.now().toString() | |
| }; | |
| this.models = { | |
| 'meina': 'MeinaHentai_v4.safetensors', | |
| 'anime': 'animeModel_v1.safetensors', | |
| 'manga': 'mangaStyle_v2.safetensors' | |
| }; | |
| } | |
| async uploadImage(imageUrl) { | |
| const imageResponse = await axios.get(imageUrl, { | |
| responseType: 'arraybuffer', | |
| timeout: 45000 | |
| }); | |
| const FormData = require('form-data'); | |
| const formData = new FormData(); | |
| formData.append('file', Buffer.from(imageResponse.data), { | |
| filename: 'image.jpg', | |
| contentType: 'image/jpeg' | |
| }); | |
| const response = await axios.post(`${this.baseURL}/upload-img`, formData, { | |
| headers: { | |
| ...this.headers, | |
| ...formData.getHeaders() | |
| }, | |
| timeout: 60000 | |
| }); | |
| if (response.data.code !== 200) { | |
| throw new Error(`Upload failed: ${response.data.message}`); | |
| } | |
| return response.data.data.path; | |
| } | |
| async createTask(imagePath, model) { | |
| const modelName = this.models[model] || this.models['meina']; | |
| const response = await axios.post(`${this.baseURL}/of/create`, { | |
| fn_name: 'demo-photo2anime', | |
| call_type: 3, | |
| input: { | |
| source_image: imagePath, | |
| model: modelName, | |
| request_from: 16 | |
| }, | |
| data: '', | |
| request_from: 16, | |
| origin_from: '68d425c58e76bc6c' | |
| }, { | |
| headers: { | |
| ...this.headers, | |
| 'X-code': Date.now().toString() | |
| }, | |
| timeout: 30000 | |
| }); | |
| if (response.data.code !== 200) { | |
| throw new Error(`Task creation failed: ${response.data.message}`); | |
| } | |
| return response.data.data.task_id; | |
| } | |
| async checkStatus(taskId, maxRetries = 60) { | |
| for (let i = 0; i < maxRetries; i++) { | |
| const response = await axios.post(`${this.baseURL}/of/check-status`, { | |
| task_id: taskId, | |
| fn_name: 'demo-photo2anime', | |
| call_type: 3, | |
| request_from: 16, | |
| origin_from: '68d425c58e76bc6c' | |
| }, { | |
| headers: { | |
| ...this.headers, | |
| 'X-code': Date.now().toString() | |
| }, | |
| timeout: 25000 | |
| }); | |
| if (response.data.code !== 200) { | |
| throw new Error(`Status check failed: ${response.data.message}`); | |
| } | |
| const status = response.data.data.status; | |
| if (status === 2) { | |
| return `${this.tempURL}/${response.data.data.result_image}`; | |
| } | |
| await new Promise(resolve => setTimeout(resolve, 3000)); | |
| } | |
| throw new Error('Processing timeout'); | |
| } | |
| async convert(imageUrl, model = 'meina') { | |
| const imagePath = await this.uploadImage(imageUrl); | |
| const taskId = await this.createTask(imagePath, model); | |
| const resultUrl = await this.checkStatus(taskId); | |
| return resultUrl; | |
| } | |
| } | |
| const handler = async (req, res) => { | |
| try { | |
| const { image, key, model } = req.query; | |
| if (!image || !key) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: 'Missing required parameters: image and key' | |
| }); | |
| } | |
| const modelType = model || 'meina'; | |
| const validModels = ['meina', 'anime', 'manga']; | |
| if (!validModels.includes(modelType)) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: 'Invalid model parameter', | |
| availableModels: validModels | |
| }); | |
| } | |
| const converter = new AnimeConverter(); | |
| const resultUrl = await converter.convert(image, modelType); | |
| res.json({ | |
| author: 'Herza', | |
| success: true, | |
| data: { | |
| model: modelType, | |
| url: resultUrl | |
| } | |
| }); | |
| } catch (error) { | |
| res.status(500).json({ | |
| success: false, | |
| error: error.message | |
| }); | |
| } | |
| }; | |
| module.exports = { | |
| name: 'Image to Anime Converter', | |
| description: 'Convert photos to anime style using AI', | |
| type: 'GET', | |
| routes: ['api/AI/img2anime'], | |
| tags: ['ai', 'image', 'anime', 'converter'], | |
| main: ['AI'], | |
| parameters: ['image', 'key'], | |
| enabled: true, | |
| limit: 3, | |
| handler | |
| }; |