140 lines
6.6 KiB
PHP
140 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* WEVIA Tools Hub v1.0 — Local alternatives to ToolFK
|
|
* QR Code, AI Image Gen (CF Workers AI), OCR, URL Shortener, Image Compress
|
|
*/
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
|
|
|
|
require_once '/opt/wevads/vault/credentials.php';
|
|
|
|
$action = $_GET['action'] ?? $_POST['action'] ?? 'status';
|
|
$outDir = '/var/www/weval/wevia-ia/downloads/';
|
|
if (!is_dir($outDir)) mkdir($outDir, 0755, true);
|
|
|
|
switch ($action) {
|
|
|
|
// ─── QR CODE GENERATOR ───
|
|
case 'qrcode':
|
|
$text = $_POST['text'] ?? $_GET['text'] ?? '';
|
|
if (empty($text)) { die(json_encode(['error' => 'text required'])); }
|
|
$safe = preg_replace('/[^a-zA-Z0-9]/', '_', substr($text, 0, 20));
|
|
$fname = "qr_{$safe}_" . substr(md5($text), 0, 6) . ".png";
|
|
$path = $outDir . $fname;
|
|
$escaped = escapeshellarg($text);
|
|
shell_exec("python3 -c \"
|
|
import qrcode
|
|
from PIL import Image
|
|
qr = qrcode.QRCode(version=1, box_size=10, border=4, error_correction=qrcode.constants.ERROR_CORRECT_H)
|
|
qr.add_data($escaped)
|
|
qr.make(fit=True)
|
|
img = qr.make_image(fill_color='#7c3aed', back_color='white')
|
|
img.save('$path')
|
|
\"");
|
|
if (file_exists($path)) {
|
|
echo json_encode(['success' => true, 'url' => "/wevia-ia/downloads/$fname", 'type' => 'qrcode']);
|
|
} else {
|
|
echo json_encode(['error' => 'QR génération failed']);
|
|
}
|
|
break;
|
|
|
|
// ─── AI IMAGE GENERATION (Cloudflare Workers AI) ───
|
|
case 'image':
|
|
$prompt = $_POST['prompt'] ?? $_GET['prompt'] ?? '';
|
|
if (empty($prompt)) { die(json_encode(['error' => 'prompt required'])); }
|
|
|
|
// Try CF Workers AI first
|
|
$cfAccount = ''; // Need account ID
|
|
$cfToken = defined('CF_KEY') ? CF_KEY : '';
|
|
|
|
// Fallback: Use Groq/Cerebras to generate an SVG illustration
|
|
$ch = curl_init('https://api.groq.com/openai/v1/chat/completions');
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 3,
|
|
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . GROQ_KEY],
|
|
CURLOPT_POSTFIELDS => json_encode([
|
|
'model' => 'llama-3.3-70b-versatile',
|
|
'messages' => [
|
|
['role' => 'system', 'content' => 'Tu es un illustrateur SVG expert. Genere UNIQUEMENT du code SVG (pas de texte avant/apres). Le SVG doit avoir viewBox="0 0 800 600", des formes geometriques, des degrades, des couleurs professionnelles. Cree une illustration detaillee et artistique.'],
|
|
['role' => 'user', 'content' => "Cree une illustration SVG pour: $prompt"]
|
|
],
|
|
'max_tokens' => 2000, 'temperature' => 0.8
|
|
])
|
|
]);
|
|
$r = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
|
|
|
if ($code == 200 && $r) {
|
|
$d = json_decode($r, true);
|
|
$svg = trim($d['choices'][0]['message']['content'] ?? '');
|
|
// Extract SVG if wrapped in code block
|
|
if (preg_match('/```(?:svg)?\s*(.*?)```/s', $svg, $m)) $svg = trim($m[1]);
|
|
if (strpos($svg, '<svg') !== false) {
|
|
$fname = 'img_' . substr(md5($prompt), 0, 8) . '.html';
|
|
$html = '<!DOCTYPE html><html><head><meta charset="UTF-8"><style>body{margin:0;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#fafafa}</style></head><body>' . $svg . '</body></html>';
|
|
file_put_contents($outDir . $fname, $html);
|
|
echo json_encode(['success' => true, 'url' => "/wevia-ia/downloads/$fname", 'type' => 'svg_illustration', 'provider' => 'WEVIA ImageGen']);
|
|
} else {
|
|
// Fallback to picsum
|
|
$seed = substr(md5($prompt), 0, 10);
|
|
echo json_encode(['success' => true, 'url' => "https://picsum.photos/seed/$seed/1024/768", 'type' => 'photo', 'provider' => 'picsum']);
|
|
}
|
|
} else {
|
|
echo json_encode(['error' => 'Image génération failed']);
|
|
}
|
|
break;
|
|
|
|
// ─── URL SHORTENER ───
|
|
case 'shorten':
|
|
$url = $_POST['url'] ?? $_GET['url'] ?? '';
|
|
if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) { die(json_encode(['error' => 'valid URL required'])); }
|
|
$code = substr(md5($url . time()), 0, 6);
|
|
$shortDir = '/var/www/html/s/';
|
|
if (!is_dir($shortDir)) mkdir($shortDir, 0755, true);
|
|
file_put_contents($shortDir . $code . '.php', "<?php header('Location: " . addslashes($url) . "'); exit;");
|
|
$shortUrl = "https://weval-consulting.com/s/$code.php";
|
|
echo json_encode(['success' => true, 'short_url' => $shortUrl, 'original' => $url]);
|
|
break;
|
|
|
|
// ─── IMAGE COMPRESS ───
|
|
case 'compress':
|
|
if (empty($_FILES['image'])) { die(json_encode(['error' => 'image file required'])); }
|
|
$tmp = $_FILES['image']['tmp_name'];
|
|
$fname = 'comp_' . substr(md5(time()), 0, 8) . '.jpg';
|
|
$path = $outDir . $fname;
|
|
$quality = intval($_POST['quality'] ?? 75);
|
|
shell_exec("python3 -c \"
|
|
from PIL import Image
|
|
img = Image.open('$tmp')
|
|
img = img.convert('RGB')
|
|
img.save('$path', 'JPEG', quality=$quality, optimize=True)
|
|
\"");
|
|
if (file_exists($path)) {
|
|
$origSize = filesize($tmp);
|
|
$newSize = filesize($path);
|
|
$ratio = round((1 - $newSize/$origSize) * 100);
|
|
echo json_encode(['success' => true, 'url' => "/wevia-ia/downloads/$fname", 'original_size' => $origSize, 'compressed_size' => $newSize, 'reduction' => "$ratio%"]);
|
|
} else {
|
|
echo json_encode(['error' => 'Compression failed']);
|
|
}
|
|
break;
|
|
|
|
// ─── STATUS ───
|
|
case 'status':
|
|
default:
|
|
echo json_encode([
|
|
'service' => 'WEVIA Tools Hub',
|
|
'version' => '1.0',
|
|
'tools' => [
|
|
'qrcode' => ['status' => 'live', 'method' => 'POST/GET', 'params' => 'text', 'output' => 'PNG'],
|
|
'image' => ['status' => 'live', 'method' => 'POST/GET', 'params' => 'prompt', 'output' => 'SVG/PNG'],
|
|
'shorten' => ['status' => 'live', 'method' => 'POST/GET', 'params' => 'url', 'output' => 'short URL'],
|
|
'compress' => ['status' => 'live', 'method' => 'POST', 'params' => 'image file + quality', 'output' => 'JPEG'],
|
|
],
|
|
'replaces' => 'ToolFK (12 tools)',
|
|
'advantage' => 'No Cloudflare, no auth, instant response'
|
|
]);
|
|
break;
|
|
}
|