FILE 1: /home/breaking-news-generator.digitalprank.com/public_html/tool_config.json code JSON { "tool": { "identity": { "slug": "breaking-news-generator", "name": "Breaking News Generator", "category": "prank", "tagline": "Create hilarious custom headlines and breaking news alerts!", "description": "Design funny or outrageous breaking news images using AI. Enter your custom headline, choose a style, and generate a professional-looking image.", "keywords": ["custom news", "prank", "breaking news", "headline generator", "news meme", "digital prank"] }, "features": { "bulk_enabled": false, "history_enabled": true, "export_enabled": true, "api_enabled": true }, "fields": [ { "id": "headline_text", "type": "text", "label": "Custom Headline", "placeholder": "e.g., Man Arrested for Arguing with His Own Echo", "required": true, "validation": { "pattern": "^.{10,200}$", "min_length": 10, "max_length": 200 }, "pro_only": false, "help_text": "Write your custom headline. Keep it under 200 characters." }, { "id": "subheadline_text", "type": "text", "label": "Subheadline (optional)", "placeholder": "e.g., Witnesses say the conversation got heated.", "required": false, "validation": { "pattern": "^.{0,300}$", "max_length": 300 }, "pro_only": true, "help_text": "Add a custom subheadline for extra realism (Pro feature)." }, { "id": "template_style", "type": "select", "label": "Template Style", "default": "cnn_style", "options": [ { "value": "cnn_style", "label": "CNN Style" }, { "value": "bbc_style", "label": "BBC Style" }, { "value": "fox_style", "label": "Fox News Style" }, { "value": "mobile_tweet", "label": "Twitter/X Breaking Post (Pro)" }, { "value": "tv_ticker", "label": "TV News Ticker (Pro)" }, { "value": "youtube_breaking", "label": "YouTube Stream Screenshot (Pro)" } ], "pro_only": false, "help_text": "Choose the visual style of the news output." }, { "id": "custom_logo", "type": "file", "label": "Upload Custom Logo (optional)", "required": false, "pro_only": true, "help_text": "Upload your own logo to replace the default one (PNG recommended)." }, { "id": "output_format", "type": "select", "label": "Export Format", "default": "png", "options": [ { "value": "png", "label": "PNG Image" }, { "value": "jpg", "label": "JPG Image" }, { "value": "pdf", "label": "PDF (Pro)" }, { "value": "mp4", "label": "MP4 Animation (Pro)" } ], "pro_only": false, "help_text": "Choose your preferred file format." } ], "limits": { "tier_daily": { "free": 3, "basic": 25, "gold": 100, "ultimate": -1 }, "rate_limit_per_minute": 8, "max_concurrent_requests": 2 }, "database": { "tool_specific_table": "custom_news_history", "store_results": true, "enable_history": true, "retention_days": 30 }, "billing": { "credit_cost": 1, "one_off_enabled": true, "one_off_price_cents": 75, "bill_on": "success" }, "ui": { "theme": { "primary_color": "#cc0000", "secondary_color": "#1a1a1a" }, "layout": { "show_sidebar_ads": true, "form_style": "wizard", "result_display": "inline" } }, "dependencies": { "php_extensions": ["gd", "json", "mbstring"], "system_packages": ["imagemagick", "ffmpeg"], "python_packages": ["pillow", "moviepy"], "external_apis": ["openai", "ollama"], "requires_internet": false }, "seo": { "meta_title": "Breaking News Generator | Create Funny Headlines | DigitalPrank.com", "meta_description": "Generate hilarious custom news headlines and images with realistic news templates. Perfect for pranks, memes, and viral content. Try free!", "canonical_url": "https://digitalprank.com/tools/breaking-news-generator", "structured_data": { "type": "WebApplication", "category": "Entertainment" } }, "help": { "quick_start": [ "Step 1: Type your custom headline.", "Step 2: Pick a template style.", "Step 3: Customize with logo and subheadline (Pro).", "Step 4: Click 'Generate'.", "Step 5: Download and share!" ], "faq": [ { "question": "Is this tool meant to spread misinformation?", "answer": "Absolutely not. This tool is for comedy, entertainment, and parody only. It should never be used to deceive or manipulate others." }, { "question": "Can I upload my own news channel logo?", "answer": "Yes, Pro users can upload a custom logo to personalize the output." }, { "question": "Can I generate videos instead of images?", "answer": "Yes, animated breaking news MP4 exports are available to Pro users." } ], "examples": [ { "title": "Local Hero Rescues Cat with Drone", "description": "A silly headline for a CNN-style custom news image.", "input": { "headline_text": "Drone Pilot Saves Cat from Tree, Demands Superhero Status", "template_style": "cnn_style" } }, { "title": "Aliens Demand WiFi Password", "description": "Great for a tweet-style breaking news screenshot.", "input": { "headline_text": "UFOs Land in Texas, Request WiFi and Snacks", "template_style": "mobile_tweet" } } ] }, "monitoring": { "track_usage": true, "track_performance": true, "error_reporting": true, "analytics_events": [ "news_generated", "template_selected", "pro_upgrade" ] }, "security": { "input_sanitization": true, "csrf_protection": true, "rate_limiting": true, "blocked_domains": [], "max_input_length": 500, "allowed_file_types": ["png", "jpg", "jpeg", "pdf"] }, "version": { "schema": "3.0.0", "tool": "1.0.0", "api_version": "v1" } } } FILE 2: /home/breaking-news-generator.digitalprank.com/public_html/processor.php code PHP false, 'message' => 'Configuration file not found.']); exit; } $config = json_decode(file_get_contents($config_path), true)['tool']; $tool_slug = $config['identity']['slug']; // --- DATABASE CONNECTION --- $db_host = 'localhost'; $db_name = 'digitalprank_db'; $db_user = 'dp_user'; $db_pass = '#$Dealer2355'; try { $pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Database connection failed.']); exit; } // --- UNIVERSAL FUNCTIONS (placeholders, assuming they exist as described) --- require_once '/home/cdn.digitalprank.com/public_html/php/universal_functions.php'; // --- MAIN PROCESSING LOGIC --- header('Content-Type: application/json'); $response = [ 'success' => false, 'message' => 'An unknown error occurred.', 'data' => null, 'usage' => [], 'access' => [], 'features' => [] ]; try { $start_time = microtime(true); $input = $_POST; $user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null; $user_ip = $_SERVER['REMOTE_ADDR']; // 1. Get User Access & Usage Limits $access = getUserAccessLevel($pdo, $user_id, $tool_slug); $limit = $config['limits']['tier_daily'][$access['tier']]; checkDailyUsage($pdo, $tool_slug, $user_ip, $user_id, $limit); // 2. Fetch Field Overrides $overrides = getToolOverrides($pdo, $tool_slug); $access['field_permissions'] = applyOverrides($config['fields'], $overrides, $access['tier']); // 3. CSRF Check (assuming a token is passed from the form) if (!isset($input['csrf_token']) || !isset($_SESSION['csrf_token']) || $input['csrf_token'] !== $_SESSION['csrf_token']) { throw new Exception('Invalid session token. Please refresh the page.'); } // {{TOOL_PROCESSING_START}} // 4. Input Validation & Tool-Specific Logic $validated_input = []; $errors = []; // Headline Text if (empty($input['headline_text']) || !preg_match('/^.{10,200}$/', $input['headline_text'])) { $errors['headline_text'] = 'Headline must be between 10 and 200 characters.'; } else { $validated_input['headline_text'] = htmlspecialchars($input['headline_text']); } // Subheadline Text (Pro) $validated_input['subheadline_text'] = ''; if (!empty($input['subheadline_text'])) { if (!$access['has_pro_access']) { $errors['subheadline_text'] = 'Subheadlines are a Pro feature.'; } elseif (!preg_match('/^.{0,300}$/', $input['subheadline_text'])) { $errors['subheadline_text'] = 'Subheadline cannot exceed 300 characters.'; } else { $validated_input['subheadline_text'] = htmlspecialchars($input['subheadline_text']); } } // Template Style $pro_templates = ['mobile_tweet', 'tv_ticker', 'youtube_breaking']; if (empty($input['template_style']) || !in_array($input['template_style'], array_column($config['fields'][2]['options'], 'value'))) { $errors['template_style'] = 'Invalid template selected.'; } elseif (in_array($input['template_style'], $pro_templates) && !$access['has_pro_access']) { $errors['template_style'] = 'This template style is a Pro feature.'; } else { $validated_input['template_style'] = $input['template_style']; } // Output Format $pro_formats = ['pdf', 'mp4']; if (empty($input['output_format']) || !in_array($input['output_format'], array_column($config['fields'][4]['options'], 'value'))) { $errors['output_format'] = 'Invalid output format selected.'; } elseif (in_array($input['output_format'], $pro_formats) && !$access['has_pro_access']) { $errors['output_format'] = 'This export format is a Pro feature.'; } else { $validated_input['output_format'] = $input['output_format']; } // Custom Logo (Pro) $validated_input['custom_logo_path'] = null; if (isset($_FILES['custom_logo']) && $_FILES['custom_logo']['error'] === UPLOAD_ERR_OK) { if (!$access['has_pro_access']) { $errors['custom_logo'] = 'Custom logos are a Pro feature.'; } else { $allowed_types = ['image/png', 'image/jpeg']; if (!in_array($_FILES['custom_logo']['type'], $allowed_types) || $_FILES['custom_logo']['size'] > 2097152) { // 2MB limit $errors['custom_logo'] = 'Invalid file. Please upload a PNG or JPG under 2MB.'; } else { $upload_dir = __DIR__ . '/uploads/'; if (!is_dir($upload_dir)) mkdir($upload_dir, 0755, true); $logo_filename = uniqid('logo_') . '-' . basename($_FILES['custom_logo']['name']); $validated_input['custom_logo_path'] = $upload_dir . $logo_filename; if (!move_uploaded_file($_FILES['custom_logo']['tmp_name'], $validated_input['custom_logo_path'])) { $errors['custom_logo'] = 'Failed to upload custom logo.'; } } } } if (!empty($errors)) { http_response_code(400); $response['message'] = 'Please correct the errors.'; $response['data'] = ['errors' => $errors]; echo json_encode($response); exit; } // 5. Image Generation $template_path = __DIR__ . '/assets/templates/' . $validated_input['template_style'] . '.png'; $font_path = __DIR__ . '/assets/fonts/Helvetica-Bold.ttf'; $output_dir = __DIR__ . '/output/'; if (!is_dir($output_dir)) mkdir($output_dir, 0755, true); $unique_id = uniqid(); $image_path = $output_dir . $unique_id . '.png'; $final_output_path = $output_dir . $unique_id . '.' . $validated_input['output_format']; // Define coordinates and text properties per template $template_configs = [ 'cnn_style' => ['headline' => ' -pointsize 72 -fill white -gravity South -annotate +0+200', 'subheadline' => ' -pointsize 36 -fill lightgray -gravity South -annotate +0+150'], 'bbc_style' => ['headline' => ' -pointsize 68 -fill black -gravity Center -annotate +0+50', 'subheadline' => ' -pointsize 34 -fill dimgray -gravity Center -annotate +0+120'], 'fox_style' => ['headline' => ' -pointsize 80 -fill white -gravity West -annotate +100+100', 'subheadline' => ' -pointsize 40 -fill yellow -gravity West -annotate +100+200'], 'mobile_tweet' => ['headline' => ' -pointsize 48 -fill black -gravity NorthWest -annotate +50+300', 'subheadline' => ''], 'tv_ticker' => ['headline' => ' -pointsize 60 -fill white -background "#CC0000" -gravity Center label:"BREAKING NEWS: %s" -gravity South -composite', 'subheadline' => ''], 'youtube_breaking' => ['headline' => ' -pointsize 55 -fill white -gravity SouthWest -annotate +80+80', 'subheadline' => ''] ]; $cfg = $template_configs[$validated_input['template_style']]; $escaped_headline = escapeshellarg($validated_input['headline_text']); $cmd = "convert " . escapeshellarg($template_path) . " -font " . escapeshellarg($font_path); // Special handling for ticker to create a label if ($validated_input['template_style'] == 'tv_ticker') { $cmd .= sprintf($cfg['headline'], $validated_input['headline_text']); } else { $cmd .= $cfg['headline'] . " " . $escaped_headline; if (!empty($validated_input['subheadline_text']) && !empty($cfg['subheadline'])) { $escaped_subheadline = escapeshellarg($validated_input['subheadline_text']); $cmd .= $cfg['subheadline'] . " " . $escaped_subheadline; } } if ($validated_input['custom_logo_path']) { $cmd .= " " . escapeshellarg($validated_input['custom_logo_path']) . " -gravity NorthEast -geometry +50+50 -composite"; } $cmd .= " " . escapeshellarg($image_path); shell_exec($cmd); if (!file_exists($image_path)) { throw new Exception('Image generation failed.'); } // 6. Output Conversion (PDF/MP4) if ($validated_input['output_format'] === 'pdf') { shell_exec("convert " . escapeshellarg($image_path) . " " . escapeshellarg($final_output_path)); } elseif ($validated_input['output_format'] === 'mp4') { $python_executable = __DIR__ . '/venv/bin/python'; $script_path = __DIR__ . '/generate_video.py'; shell_exec(escapeshellcmd($python_executable) . " " . escapeshellarg($script_path) . " --input " . escapeshellarg($image_path) . " --output " . escapeshellarg($final_output_path)); } else { // For JPG/PNG, just rename if needed if ($image_path !== $final_output_path) { rename($image_path, $final_output_path); } } if (!file_exists($final_output_path)) { throw new Exception('Final output conversion failed.'); } $output_url = 'https://' . $tool_slug . '.digitalprank.com/output/' . basename($final_output_path); // {{TOOL_PROCESSING_END}} // 7. Log Usage & Finalize Response $processing_time = microtime(true) - $start_time; $log_output = ['url' => $output_url]; if ($config['database']['store_results']) { $stmt = $pdo->prepare("INSERT INTO custom_news_history (user_id, headline, subheadline, template, output_file, created_at) VALUES (?, ?, ?, ?, ?, NOW())"); $stmt->execute([$user_id, $validated_input['headline_text'], $validated_input['subheadline_text'], $validated_input['template_style'], $output_url]); $log_output['history_id'] = $pdo->lastInsertId(); } logUsage($pdo, $tool_slug, $user_ip, $user_id, 'generate', $input, $log_output, $processing_time, 'success'); $response['success'] = true; $response['message'] = 'News generated successfully!'; $response['data'] = ['url' => $output_url, 'format' => $validated_input['output_format']]; $response['usage'] = getDailyUsage($pdo, $tool_slug, $user_ip, $user_id); $response['access'] = $access; } catch (Exception $e) { $processing_time = microtime(true) - $start_time; logUsage($pdo, $tool_slug, $user_ip, $user_id, 'generate_failed', $input, ['error' => $e->getMessage()], $processing_time, 'failed'); http_response_code(500); $response['message'] = $e->getMessage(); } echo json_encode($response); FILE 3: /home/breaking-news-generator.digitalprank.com/public_html/tool_form.php code PHP <?php echo htmlspecialchars($config['identity']['name']); ?> - DigitalPrank

', $field['id'], $field['id'], htmlspecialchars($field['placeholder']), $field['required'] ? 'required' : '', $disabled ); break; case 'select': echo ""; break; case 'file': echo sprintf( '', $field['id'], $field['id'], $disabled ); break; } ?>

Your Breaking News!

FILE 4: /home/breaking-news-generator.digitalprank.com/public_html/diagnostic.php code PHP $description$icon " . ($status ? 'OK' : 'FAIL') . "$message"; } function check_exec($command) { $path = shell_exec("command -v $command"); return !empty($path); } ?> System Diagnostic: Breaking News Generator

System Diagnostic: Breaking News Generator

'; $config_path = __DIR__ . '/tool_config.json'; $config_exists = file_exists($config_path); check("tool_config.json exists", $config_exists); if ($config_exists) { $config_content = file_get_contents($config_path); $config_data = json_decode($config_content, true); $config_valid = json_last_error() === JSON_ERROR_NONE; check("JSON is valid", $config_valid, json_last_error_msg()); if($config_valid) { check("Tool slug is present", isset($config_data['tool']['identity']['slug'])); } } // 2. Database echo ''; $db_host = 'localhost'; $db_name = 'digitalprank_db'; $db_user = 'dp_user'; $db_pass = '#$Dealer2355'; try { $pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass); check("Database connection", true, "Connected to $db_name@$db_host successfully."); $tables_to_check = [ 'wp_digitalprank_tools', 'wp_digitalprank_usage', 'wp_digitalprank_usage_log', 'wp_pms_member_subscriptions', 'wp_digitalprank_entitlements', 'wp_digitalprank_tool_overrides', $config_data['tool']['database']['tool_specific_table'] ?? 'custom_news_history' ]; foreach ($tables_to_check as $table) { $stmt = $pdo->query("SHOW TABLES LIKE '$table'"); check("Table '$table' exists", $stmt->rowCount() > 0); } } catch (PDOException $e) { check("Database connection", false, $e->getMessage()); } // 3. Dependencies echo ''; if ($config_valid) { // PHP Extensions foreach ($config_data['tool']['dependencies']['php_extensions'] as $ext) { check("PHP Extension: $ext", extension_loaded($ext)); } // System Packages foreach ($config_data['tool']['dependencies']['system_packages'] as $pkg) { check("System Package: $pkg", check_exec($pkg), shell_exec("command -v $pkg")); } // Python Packages $venv_python = __DIR__ . '/venv/bin/python'; $python_ok = file_exists($venv_python); check("Python venv exists", $python_ok); if ($python_ok && !empty($config_data['tool']['dependencies']['python_packages'])) { foreach ($config_data['tool']['dependencies']['python_packages'] as $pkg) { $check_cmd = "$venv_python -c \"import $pkg\" 2>&1"; $output = shell_exec($check_cmd); check("Python Package: $pkg", empty($output), $output); } } } else { check("Dependency checks skipped", false, "Config file is invalid."); } // 4. File System & Permissions echo ''; $output_dir = __DIR__ . '/output'; $uploads_dir = __DIR__ . '/uploads'; check("Output directory exists", is_dir($output_dir)); check("Output directory is writable", is_writable($output_dir), decoct(fileperms($output_dir) & 0777)); check("Uploads directory exists", is_dir($uploads_dir)); check("Uploads directory is writable", is_writable($uploads_dir), decoct(fileperms($uploads_dir) & 0777)); // 5. Tool Specific Functionality Test echo ''; $test_image_path = __DIR__ . '/output/diag_test.png'; $test_cmd = "convert -size 400x100 xc:blue -fill white -gravity center -pointsize 20 -annotate +0+0 'DIAGNOSTIC TEST' " . escapeshellarg($test_image_path); shell_exec($test_cmd); $image_created = file_exists($test_image_path); check("ImageMagick test", $image_created, "Test command executed. Check output/diag_test.png"); if ($image_created) { unlink($test_image_path); } ?>
Check Status Details
Configuration
Database
Dependencies
File System
Functionality Test
FILE 5: /home/breaking-news-generator.digitalprank.com/public_html/help.md code Markdown # Breaking News Generator Help Generate hilarious custom news headlines and images with realistic news templates. Perfect for pranks, memes, and viral content. ### Quick Start Guide Follow these simple steps to create your custom breaking news image: 1. **Step 1:** Type your custom headline. 2. **Step 2:** Pick a template style. 3. **Step 3:** Customize with logo and subheadline (Pro). 4. **Step 4:** Click 'Generate'. 5. **Step 5:** Download and share! ### Features * **Custom Headline:** The main text for your breaking news. Must be between 10 and 200 characters. (Available to all users) * **Subheadline (optional):** Add a smaller line of text for more detail and realism. (Pro feature) * **Template Style:** Choose the visual look of your news graphic. We offer styles mimicking popular news outlets. Some advanced styles like Twitter/X posts and TV tickers are for Pro users. * **Upload Custom Logo (optional):** Replace the default template logo with your own. We recommend a transparent PNG. (Pro feature) * **Export Format:** Download your creation as a PNG or JPG image. Pro users can also export as a high-quality PDF or an animated MP4 video. ### Frequently Asked Questions (FAQ) **Q: Is this tool meant to spread misinformation?** > A: Absolutely not. This tool is for comedy, entertainment, and parody only. It should never be used to deceive or manipulate others. All generated images are for personal, non-commercial use. **Q: Can I upload my own news channel logo?** > A: Yes, Pro users can upload a custom logo to personalize the output. **Q: Can I generate videos instead of images?** > A: Yes, animated breaking news MP4 exports are available to Pro users. ### Usage Examples Here are a couple of ideas to get you started: **1. Local Hero Rescues Cat with Drone** * **Description:** A silly headline for a CNN-style custom news image. * **Input:** * **Headline:** `Drone Pilot Saves Cat from Tree, Demands Superhero Status` * **Template Style:** `CNN Style` **2. Aliens Demand WiFi Password** * **Description:** Great for a tweet-style breaking news screenshot. * **Input:** * **Headline:** `UFOs Land in Texas, Request WiFi and Snacks` * **Template Style:** `Twitter/X Breaking Post (Pro)` FILE 6: /home/digitalprank.com/public_html/blog/data/tools/breaking-news-generator.json code JSON { "slug": "breaking-news-generator", "name": "Breaking News Generator", "meta_title": "Breaking News Generator | Create Funny Headlines | DigitalPrank.com", "meta_description": "Generate hilarious custom news headlines and images with realistic news templates. Perfect for pranks, memes, and viral content. Try free!", "canonical_url": "https://digitalprank.com/tools/breaking-news-generator", "datePublished": "2025-09-26", "dateModified": "2025-09-26", "author": { "@type": "Organization", "name": "DigitalPrank" }, "keywords": ["custom news", "prank", "breaking news", "headline generator", "news meme", "digital prank", "funny news", "parody news"], "long_description": "Unleash your creativity and humor with the Breaking News Generator. This tool allows you to craft your own hilarious and absurd news headlines and instantly turn them into realistic-looking news graphics. Perfect for creating memes to share on social media, making jokes with friends, or adding a funny touch to a presentation. Choose from various templates inspired by major news networks, add your own text, and even upload a custom logo for the ultimate personalized prank.", "features_list": [ { "name": "Custom Headlines & Subheadlines", "description": "Write any outrageous headline you can think of. Pro users can add a subheadline for extra detail.", "is_pro": false }, { "name": "Multiple News Templates", "description": "Select from a variety of styles including CNN, BBC, and Fox News look-alikes.", "is_pro": false }, { "name": "Pro Template Pack", "description": "Pro users get access to exclusive templates like Twitter/X posts, TV news tickers, and YouTube stream screenshots.", "is_pro": true }, { "name": "Custom Logo Upload", "description": "Brand your custom news with your own logo. A powerful feature for Pro users.", "is_pro": true }, { "name": "Multiple Export Formats", "description": "Download your final image as a PNG or JPG. Pro users can also export as a PDF or an animated MP4 video.", "is_pro": true } ], "how_to_guide": { "title": "How to Create Your Custom News Graphic", "steps": [ "Enter your main headline in the 'Custom Headline' text box.", "Optionally, add a subheadline if you are a Pro user.", "Select your desired visual style from the 'Template Style' dropdown.", "Choose your export format (PNG, JPG, or PDF/MP4 for Pro users).", "Click 'Generate' and wait for your masterpiece to appear.", "Click the 'Download' button to save and share your creation." ] }, "use_cases": [ "Creating viral memes for social media platforms like Instagram, Twitter, and Facebook.", "Making personalized jokes for friends' birthdays or special occasions.", "Adding a humorous visual element to presentations or creative projects.", "Generating funny, shareable content for your blog or website." ], "disclaimer": "This tool is for entertainment and parody purposes only. DigitalPrank does not condone the creation or dissemination of misinformation. Please use responsibly.", "structured_data": { "@context": "https://schema.org", "@type": "WebApplication", "name": "Breaking News Generator", "description": "Generate hilarious custom news headlines and images with realistic news templates. Perfect for pranks, memes, and viral content.", "applicationCategory": "EntertainmentApplication", "operatingSystem": "Any (Web-based)", "url": "https://digitalprank.com/tools/breaking-news-generator", "offers": { "@type": "Offer", "price": "0.00", "priceCurrency": "USD" } } } FILE 7: /home/breaking-news-generator.digitalprank.com/public_html/deploy.sh code Bash #!/bin/bash set -e TOOL_SLUG="breaking-news-generator" TOOL_DIR="/home/${TOOL_SLUG}.digitalprank.com/public_html" VHOST_DIR="/usr/local/lsws/conf/vhosts" VHOST_CONF="${VHOST_DIR}/${TOOL_SLUG}/vhost.conf" DB_NAME="digitalprank_db" DB_USER="dp_user" DB_PASS="#$Dealer2355" WEB_USER="www-data" echo "--- Starting deployment for ${TOOL_SLUG} ---" # 1. Install System and PHP Dependencies echo "--> Installing system packages..." sudo apt-get update sudo apt-get install -y imagemagick ffmpeg python3-venv php8.1-gd php8.1-mbstring # 2. Create Directories echo "--> Setting up directories..." sudo mkdir -p ${TOOL_DIR}/{output,uploads,assets/templates,assets/fonts} sudo chown -R ${WEB_USER}:${WEB_USER} ${TOOL_DIR} sudo chmod -R 755 ${TOOL_DIR} sudo chmod -R 775 ${TOOL_DIR}/{output,uploads} # 3. Create Python Virtual Environment echo "--> Setting up Python venv..." sudo python3 -m venv ${TOOL_DIR}/venv source ${TOOL_DIR}/venv/bin/activate pip install pillow moviepy deactivate sudo chown -R ${WEB_USER}:${WEB_USER} ${TOOL_DIR}/venv # 4. Create Tool-Specific Database Table echo "--> Creating database table 'custom_news_history'..." SQL="CREATE TABLE IF NOT EXISTS \`custom_news_history\` ( \`id\` BIGINT PRIMARY KEY AUTO_INCREMENT, \`user_id\` BIGINT NULL, \`headline\` TEXT NOT NULL, \`subheadline\` TEXT NULL, \`template\` VARCHAR(100) NOT NULL, \`output_file\` VARCHAR(255) NOT NULL, \`created_at\` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, \`deleted_at\` TIMESTAMP NULL, INDEX \`user_id_idx\` (\`user_id\`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;" mysql -h localhost -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -e "${SQL}" # 5. Configure OpenLiteSpeed Virtual Host echo "--> Configuring OpenLiteSpeed vhost..." sudo mkdir -p ${VHOST_DIR}/${TOOL_SLUG} sudo cat << EOF > ${VHOST_CONF} docRoot \$VH_ROOT/public_html vhDomain ${TOOL_SLUG}.digitalprank.com vhAliases www.${TOOL_SLUG}.digitalprank.com errorlog \$VH_ROOT/logs/error.log { useServer 0 logLevel ERROR rollingSize 10M } accesslog \$VH_ROOT/logs/access.log { useServer 0 rollingSize 10M keepDays 10 } scripthandler { add lsapi:php81 php } extprocessor php81 { type lsapi address uds://tmp/lshttpd/php81.sock maxConns 35 env LSAPI_AVOID_FORK=200M initTimeout 60 retryTimeout 0 persistConn 1 respBuffer 0 autoStart 1 path /usr/local/lsws/lsphp81/bin/lsphp } context / { allowBrowse 1 location \$DOC_ROOT/ rewrite { enable 1 rules """ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] """ } } EOF # 6. Configure Log Rotation echo "--> Configuring log rotation..." sudo cat << EOF > /etc/logrotate.d/${TOOL_SLUG} /home/${TOOL_SLUG}.digitalprank.com/public_html/logs/*.log { daily missingok rotate 14 compress delaycompress notifempty create 640 ${WEB_USER} ${WEB_USER} sharedscripts postrotate if [ -f /var/run/openlitespeed.pid ]; then kill -USR1 \`cat /var/run/openlitespeed.pid\` fi endscript } EOF # 7. Restart OpenLiteSpeed echo "--> Restarting OpenLiteSpeed server..." sudo systemctl restart lsws echo "--- Deployment for ${TOOL_SLUG} complete! ---" echo "Ensure DNS for ${TOOL_SLUG}.digitalprank.com points to this server." FILE 8: /home/breaking-news-generator.digitalprank.com/public_html/generate_video.py code Python import argparse from moviepy.editor import ImageClip, CompositeVideoClip from PIL import Image def create_animated_video(image_path, output_path, duration=5): """ Creates a short video from a static image with a subtle zoom-in (Ken Burns) effect. """ try: # Get image dimensions with Image.open(image_path) as img: img_width, img_height = img.size # Create an ImageClip clip = ImageClip(image_path) # Define the zoom-in effect def resize_func(t): # Zoom from 1.0x to 1.1x over the duration scale = 1.0 + (t / duration) * 0.1 return scale # Apply the effect zoomed_clip = clip.resize(resize_func) # Create a composite clip to crop the zoomed image to original dimensions final_clip = CompositeVideoClip( [zoomed_clip.set_position(('center', 'center'))], size=(img_width, img_height) ) # Set the duration and write the final video file final_clip.set_duration(duration).write_videofile( output_path, codec='libx264', fps=24, audio=False, threads=2, logger=None ) print(f"Video created successfully at {output_path}") except Exception as e: print(f"Error creating video: {e}") exit(1) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Generate an animated MP4 from an image.") parser.add_argument("--input", required=True, help="Path to the input image file.") parser.add_argument("--output", required=True, help="Path for the output MP4 file.") parser.add_argument("--duration", type=int, default=5, help="Duration of the video in seconds.") args = parser.parse_args() create_animated_video(args.input, args.output, args.duration) Model ThinkingThoughts (experimental) Auto Expand to view model thoughts chevron_right FILE 9: /home/cdn.digitalprank.com/public_html/php/universal_functions.php code PHP 'free', 'has_pro_access' => false, 'has_ultimate_access' => false, 'entitlements' => [] ]; if (!$user_id) { return $access; } // Check subscription status $stmt = $pdo->prepare( "SELECT subscription_plan_id, status FROM wp_pms_member_subscriptions WHERE user_id = ? ORDER BY id DESC LIMIT 1" ); $stmt->execute([$user_id]); $subscription = $stmt->fetch(PDO::FETCH_ASSOC); if ($subscription && in_array($subscription['status'], ['active', 'trialing'])) { $plan_id = (int)$subscription['subscription_plan_id']; if (in_array($plan_id, [176, 186])) { $access['tier'] = 'ultimate'; $access['has_pro_access'] = true; $access['has_ultimate_access'] = true; } elseif (in_array($plan_id, [175, 185])) { $access['tier'] = 'gold'; $access['has_pro_access'] = true; } elseif (in_array($plan_id, [174, 184])) { $access['tier'] = 'basic'; $access['has_pro_access'] = true; } } // Check for specific tool entitlements (one-off purchases) $stmt = $pdo->prepare( "SELECT t.tool_id FROM wp_digitalprank_entitlements e JOIN wp_digitalprank_tools t ON e.tool_id = t.tool_id WHERE e.user_id = ? AND t.slug = ? AND e.is_active = 1 AND (e.expires_at IS NULL OR e.expires_at > NOW())" ); $stmt->execute([$user_id, $tool_slug]); if ($stmt->fetch()) { $access['entitlements'][] = $tool_slug; $access['has_pro_access'] = true; // A specific entitlement grants pro access for that tool. } return $access; } /** * Checks if the user or IP has exceeded the daily usage limit for their tier. * * @param PDO $pdo The database connection object. * @param string $tool_slug The slug of the tool. * @param string $user_ip The user's IP address. * @param int|null $user_id The user's ID. * @param int $limit The daily usage limit for the user's tier (-1 for unlimited). * @throws Exception if the usage limit is exceeded. */ function checkDailyUsage(PDO $pdo, $tool_slug, $user_ip, $user_id, $limit) { if ($limit === -1) { return; // Unlimited usage } if ($user_id) { $sql = "SELECT COUNT(*) FROM wp_digitalprank_usage_log WHERE user_id = ? AND tool_slug = ? AND status = 'success' AND timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)"; $stmt = $pdo->prepare($sql); $stmt->execute([$user_id, $tool_slug]); } else { $sql = "SELECT COUNT(*) FROM wp_digitalprank_usage_log WHERE user_id IS NULL AND ip_address = ? AND tool_slug = ? AND status = 'success' AND timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)"; $stmt = $pdo->prepare($sql); $stmt->execute([$user_ip, $tool_slug]); } $count = $stmt->fetchColumn(); if ($count >= $limit) { throw new Exception('You have exceeded your daily usage limit for this tool. Please upgrade or try again tomorrow.'); } } /** * Gets the current daily usage count for a user/IP. * * @param PDO $pdo The database connection object. * @param string $tool_slug The slug of the tool. * @param string $user_ip The user's IP address. * @param int|null $user_id The user's ID. * @return int The number of uses in the last 24 hours. */ function getDailyUsage(PDO $pdo, $tool_slug, $user_ip, $user_id) { if ($user_id) { $sql = "SELECT COUNT(*) FROM wp_digitalprank_usage_log WHERE user_id = ? AND tool_slug = ? AND status = 'success' AND timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)"; $stmt = $pdo->prepare($sql); $stmt->execute([$user_id, $tool_slug]); } else { $sql = "SELECT COUNT(*) FROM wp_digitalprank_usage_log WHERE user_id IS NULL AND ip_address = ? AND tool_slug = ? AND status = 'success' AND timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)"; $stmt = $pdo->prepare($sql); $stmt->execute([$user_ip, $tool_slug]); } return (int)$stmt->fetchColumn(); } /** * Logs a tool usage event to the database. * * @param PDO $pdo The database connection object. * @param string $tool_slug The slug of the tool. * @param string $user_ip The user's IP address. * @param int|null $user_id The user's ID. * @param string $action_type The type of action (e.g., 'generate', 'failed'). * @param array $input_data The user's input. * @param array $output_data The result of the action. * @param float $processing_time The time taken in seconds. * @param string $status The final status ('success', 'failed', 'partial'). */ function logUsage(PDO $pdo, $tool_slug, $user_ip, $user_id, $action_type, $input_data, $output_data, $processing_time, $status) { // General usage log for analytics $sql_usage = "INSERT INTO wp_digitalprank_usage (user_id, tool_slug, action, credits_used, processing_time, ip_address, session_id, user_agent) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; $stmt_usage = $pdo->prepare($sql_usage); $stmt_usage->execute([ $user_id, $tool_slug, $action_type, ($status === 'success' ? 1 : 0), $processing_time, $user_ip, session_id(), $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown' ]); // Detailed log for history and debugging $sql_log = "INSERT INTO wp_digitalprank_usage_log (user_id, tool_slug, action_type, ip_address, session_id, user_agent, input_data, output_data, processing_time, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; $stmt_log = $pdo->prepare($sql_log); $stmt_log->execute([ $user_id, $tool_slug, $action_type, $user_ip, session_id(), $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown', json_encode($input_data), json_encode($output_data), $processing_time, $status ]); } /** * Fetches all active field overrides for a specific tool. * * @param PDO $pdo The database connection object. * @param string $tool_slug The slug of the tool. * @return array An associative array of overrides. */ function getToolOverrides(PDO $pdo, $tool_slug) { $sql = "SELECT o.field_id, o.tier_required, o.override_type FROM wp_digitalprank_tool_overrides o JOIN wp_digitalprank_tools t ON o.tool_id = t.tool_id WHERE t.slug = ? AND o.is_active = 1"; $stmt = $pdo->prepare($sql); $stmt->execute([$tool_slug]); return $stmt->fetchAll(PDO::FETCH_ASSOC); } /** * Applies database overrides to the default JSON field configuration. * * @param array $fields The fields array from tool_config.json. * @param array $overrides The overrides from the getToolOverrides function. * @param string $user_tier The user's current tier ('free', 'basic', 'gold', 'ultimate'). * @return array The final, filtered list of fields the user can access. */ function applyOverrides(array $fields, array $overrides, string $user_tier): array { $final_fields = []; $tier_levels = ['free' => 0, 'basic' => 1, 'gold' => 2, 'ultimate' => 3]; $user_level = $tier_levels[$user_tier]; $override_map = []; foreach($overrides as $o) { $override_map[$o['field_id']] = $o; } foreach ($fields as $field) { $field_id = $field['id']; $is_accessible = true; if (isset($override_map[$field_id])) { $override = $override_map[$field_id]; if ($override['override_type'] === 'disabled') { $is_accessible = false; } elseif ($override['override_type'] === 'tier') { $required_level = $tier_levels[$override['tier_required']]; if ($user_level < $required_level) { $is_accessible = false; } } } else { // Default pro_only check from JSON if no override exists if ($field['pro_only'] && $user_level < $tier_levels['basic']) { $is_accessible = false; } } $field['is_accessible'] = $is_accessible; $final_fields[] = $field; } return $final_fields; } Model ThinkingThoughts (experimental) Auto Expand to view model thoughts chevron_right FILE 10: /home/breaking-news-generator.digitalprank.com/public_html/setup_assets.sh code Bash #!/bin/bash set -e TOOL_SLUG="breaking-news-generator" TOOL_DIR="/home/${TOOL_SLUG}.digitalprank.com/public_html" ASSETS_DIR="${TOOL_DIR}/assets" TPL_DIR="${ASSETS_DIR}/templates" FONT_DIR="${ASSETS_DIR}/fonts" WEB_USER="www-data" echo "--- Setting up required assets for ${TOOL_SLUG} ---" # 1. Ensure directories exist echo "--> Verifying directories..." sudo mkdir -p ${TPL_DIR} ${FONT_DIR} # 2. Install font package and copy font # We'll use the DejaVu font which is widely available and has good coverage. echo "--> Installing fonts and copying to assets..." sudo apt-get update sudo apt-get install -y fonts-dejavu-core if [ -f "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" ]; then sudo cp /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf "${FONT_DIR}/Helvetica-Bold.ttf" echo "Font successfully copied." else echo "ERROR: Font file not found. Please install 'fonts-dejavu-core' manually and copy the font." exit 1 fi # 3. Generate placeholder template images echo "--> Generating placeholder news templates..." # CNN Style (Red) sudo convert -size 1280x720 xc:"#CC0000" \ -fill white -gravity South -pointsize 30 -annotate +0+50 "CNN STYLE TEMPLATE" \ -gravity NorthEast -pointsize 20 -annotate +20+20 "LOGO" \ "${TPL_DIR}/cnn_style.png" # BBC Style (White with Red Bar) sudo convert -size 1280x720 xc:white \ -fill red -draw "rectangle 0,620 1280,720" \ -fill black -gravity center -pointsize 30 -annotate +0+0 "BBC STYLE TEMPLATE" \ "${TPL_DIR}/bbc_style.png" # Fox News Style (Blue with Lower Third) sudo convert -size 1280x720 xc:"#003366" \ -fill "#00000080" -draw "rectangle 0,550 1280,720" \ -fill white -gravity South -pointsize 30 -annotate +0+50 "FOX NEWS STYLE TEMPLATE" \ "${TPL_DIR}/fox_style.png" # Twitter/X Post (Light Gray BG) sudo convert -size 800x600 xc:"#E1E8ED" \ -fill black -gravity center -pointsize 30 -annotate +0+0 "TWITTER/X STYLE TEMPLATE" \ -bordercolor "#CCD6DD" -border 1 \ "${TPL_DIR}/mobile_tweet.png" # TV News Ticker (Placeholder Image with transparent bar area) sudo convert -size 1280x720 canvas:lightblue \ -fill black -gravity center -pointsize 30 -annotate +0+-50 "TV TICKER BACKGROUND" \ -fill "#00000000" -draw "rectangle 0,600 1280,720" \ "${TPL_DIR}/tv_ticker.png" # YouTube Stream Screenshot (Video placeholder) sudo convert -size 1280x720 xc:black \ -fill white -gravity center -pointsize 30 -annotate +0+0 "YOUTUBE STREAM TEMPLATE" \ -fill red -draw "rectangle 50,650 150,690" \ -fill white -gravity SouthWest -pointsize 20 -annotate +60+45 "LIVE" \ "${TPL_DIR}/youtube_breaking.png" echo "All placeholder templates created." # 4. Set Ownership echo "--> Setting ownership for assets directory..." sudo chown -R ${WEB_USER}:${WEB_USER} ${ASSETS_DIR} sudo chmod -R 755 ${ASSETS_DIR} echo "--- Asset setup complete! ---" FILE 11: /home/breaking-news-generator.digitalprank.com/public_html/.gitignore code Code # Generated content and user uploads /output/ /uploads/ # Python virtual environment /venv/ # Log files *.log logs/*.log # System files .DS_Store Thumbs.db # Editor backup files *~ *.swp *.swo Model ThinkingThoughts (experimental) Auto Expand to view model thoughts chevron_right FILE 12: /home/breaking-news-generator.digitalprank.com/public_html/history.php code PHP setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare( "SELECT headline, subheadline, template, output_file, created_at FROM {$db_table} WHERE user_id = ? AND deleted_at IS NULL ORDER BY created_at DESC LIMIT 50" ); $stmt->execute([$user_id]); $history_items = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { $error_message = 'Database error: Could not retrieve history.'; } ?> My History - <?php echo htmlspecialchars($config['identity']['name']); ?>

My Generation History

You haven't generated any news yet. Get started!

'; } else { echo ''.htmlspecialchars($item['headline']).''; } ?>
FILE 13: /home/breaking-news-generator.digitalprank.com/public_html/api_docs.md code Markdown # API Documentation: Breaking News Generator The Breaking News Generator API allows you to programmatically create news images and videos. This is an Ultimate-tier feature. ## Endpoint `POST https://breaking-news-generator.digitalprank.com/api/v1/generate` ## Authentication Authentication is handled via an API key passed in the request headers. You can find your API key in your DigitalPrank.com account dashboard. **Header:** `Authorization: Bearer YOUR_ULTIMATE_TIER_API_KEY` ## Request Format The request must be sent as `multipart/form-data`. ### Parameters | Parameter | Type | Required | Description | | ------------------ | --------- | -------- | ------------------------------------------------------------------------------------------------------- | | `headline_text` | string | Yes | The main headline. Must be between 10 and 200 characters. | | `subheadline_text` | string | No | The secondary headline. Max 300 characters. | | `template_style` | string | Yes | The template to use. Values: `cnn_style`, `bbc_style`, `fox_style`, `mobile_tweet`, `tv_ticker`, `youtube_breaking`. | | `output_format` | string | Yes | The desired output format. Values: `png`, `jpg`, `pdf`, `mp4`. | | `custom_logo` | file | No | A PNG or JPG file to use as a custom logo. Max 2MB. | --- ## Response Format The API returns a JSON object. ### Success Response (`200 OK`) ```json { "success": true, "message": "News generated successfully!", "data": { "url": "https://breaking-news-generator.digitalprank.com/output/633b1e3a4c5d6.png", "format": "png", "expires_at": "2025-10-26T12:00:00Z" }, "usage": { "credits_remaining": "unlimited" } } Error Response (4xx/5xx) code JSON { "success": false, "message": "Validation failed.", "data": { "errors": { "headline_text": "Headline must be between 10 and 200 characters." } } } Possible error messages include: Invalid API key or insufficient permissions. You have exceeded your rate limit. Validation failed. (with details) Image generation failed. Example cURL Request This example generates a PNG image with a headline and subheadline using the CNN style. code Bash curl -X POST \ https://breaking-news-generator.digitalprank.com/api/v1/generate \ -H "Authorization: Bearer YOUR_ULTIMATE_TIER_API_KEY" \ -F "headline_text=Local Squirrel Hoards Over 1,000 Acorns, Causes Market Panic" \ -F "subheadline_text=Economists are baffled by the sudden shortage." \ -F "template_style=cnn_style" \ -F "output_format=png" code Code ### FILE 14: /home/breaking-news-generator.digitalprank.com/public_html/assets/css/style.css ```css /* --- General Styling --- */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; background-color: #f0f2f5; color: #1c1e21; margin: 0; padding: 20px; } .container { max-width: 800px; margin: auto; background: #ffffff; padding: 20px 40px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } h1 { color: #cc0000; /* Primary Theme Color */ text-align: center; border-bottom: 2px solid #f0f2f5; padding-bottom: 15px; margin-bottom: 10px; } h2 { text-align: center; color: #333; margin-top: 0; margin-bottom: 25px; } p { line-height: 1.6; } /* --- Form Styling --- */ #toolForm .form-group { margin-bottom: 20px; } #toolForm label { display: block; font-weight: 600; margin-bottom: 8px; color: #333; } #toolForm input[type="text"], #toolForm input[type="file"], #toolForm select { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; box-sizing: border-box; font-size: 1em; transition: border-color 0.2s, box-shadow 0.2s; } #toolForm input[type="text"]:focus, #toolForm select:focus { border-color: #cc0000; box-shadow: 0 0 0 3px rgba(204, 0, 0, 0.1); outline: none; } #toolForm input[type="file"] { padding: 5px; } .help-text { font-size: 0.9em; color: #606770; margin-top: 5px; } .pro-badge { background-color: #ffc107; color: #333; padding: 3px 8px; font-size: 0.75em; border-radius: 12px; margin-left: 8px; font-weight: bold; vertical-align: middle; cursor: help; } .btn-submit, .btn-download { background-color: #cc0000; /* Primary Theme Color */ color: white; padding: 12px 20px; border: none; border-radius: 6px; cursor: pointer; font-size: 1.1em; font-weight: 600; width: 100%; transition: background-color 0.2s; } .btn-submit:hover:not(:disabled) { background-color: #a00000; } .btn-submit:disabled { background-color: #ccc; cursor: not-allowed; } .btn-download { text-decoration: none; display: inline-block; width: auto; margin-top: 10px; text-align: center; } /* --- UI Feedback --- */ .loader { border: 5px solid #f3f3f3; border-top: 5px solid #cc0000; border-radius: 50%; width: 50px; height: 50px; animation: spin 1s linear infinite; margin: 20px auto; display: none; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .result-area { margin-top: 25px; padding: 20px; border: 2px dashed #ddd; border-radius: 8px; display: none; text-align: center; background-color: #fafafa; } .error-message { color: #721c24; background-color: #f8d7da; border: 1px solid #f5c6cb; padding: 15px; border-radius: 6px; margin-top: 20px; display: none; } .error-message ul { margin: 0; padding-left: 20px; } /* --- History Page Styling --- */ .history-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; } .history-item { border: 1px solid #ddd; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 5px rgba(0,0,0,0.05); background: #fff; display: flex; flex-direction: column; } .history-preview { width: 100%; height: 150px; background-color: #eee; display:flex; align-items: center; justify-content: center; } .history-preview img, .history-preview video { width: 100%; height: 100%; object-fit: cover; } .history-details { padding: 15px; flex-grow: 1; display: flex; flex-direction: column; } .history-headline { font-weight: 600; margin: 0 0 10px 0; color: #333; font-size: 1em; } .history-meta { font-size: 0.8em; color: #606770; margin: auto 0 10px 0; } .history-template { background: #eee; padding: 2px 6px; border-radius: 4px; } .history-date { display: block; margin-top: 5px; } FILE 15: /home/breaking-news-generator.digitalprank.com/public_html/assets/js/main.js code JavaScript document.addEventListener('DOMContentLoaded', () => { const toolForm = document.getElementById('toolForm'); if (toolForm) { toolForm.addEventListener('submit', handleFormSubmit); } }); function handleFormSubmit(e) { e.preventDefault(); const form = e.target; const submitBtn = document.getElementById('submitBtn'); const loader = document.getElementById('loader'); const resultArea = document.getElementById('resultArea'); const resultContent = document.getElementById('resultContent'); const downloadBtn = document.getElementById('downloadBtn'); const errorMessage = document.getElementById('errorMessage'); // --- Client-side validation --- let isValid = true; const headline = form.querySelector('[name="headline_text"]'); if (headline.value.length < 10 || headline.value.length > 200) { displayError('Headline must be between 10 and 200 characters.'); isValid = false; } if (!isValid) return; // --- UI Reset --- submitBtn.disabled = true; submitBtn.textContent = 'Generating...'; loader.style.display = 'block'; resultArea.style.display = 'none'; errorMessage.style.display = 'none'; resultContent.innerHTML = ''; downloadBtn.style.display = 'none'; const formData = new FormData(form); fetch('processor.php', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { // Handle server-side validation errors (4xx) and server errors (5xx) return response.json().then(errData => Promise.reject(errData)); } return response.json(); }) .then(data => { if (data.success) { displayResult(data.data); } else { // This case handles successful requests that result in a logical error displayError(data.message, data.data?.errors); } }) .catch(error => { // This catches network errors and rejected promises from server errors console.error('Submission Error:', error); displayError(error.message || 'A network or server error occurred.', error.data?.errors); }) .finally(() => { loader.style.display = 'none'; submitBtn.disabled = false; submitBtn.textContent = 'Generate'; }); } function displayResult(data) { const resultArea = document.getElementById('resultArea'); const resultContent = document.getElementById('resultContent'); const downloadBtn = document.getElementById('downloadBtn'); resultArea.style.display = 'block'; if (data.format === 'mp4') { resultContent.innerHTML = ``; } else if (data.format === 'pdf') { resultContent.innerHTML = `Your PDF is ready! Open in new tab.`; } else { resultContent.innerHTML = `Generated News`; } downloadBtn.href = data.url; downloadBtn.style.display = 'inline-block'; } function displayError(message, errors = null) { const errorMessage = document.getElementById('errorMessage'); let errorHtml = message; if (errors) { errorHtml += ''; } errorMessage.innerHTML = errorHtml; errorMessage.style.display = 'block'; } FILE 3 (UPDATED): /home/breaking-news-generator.digitalprank.com/public_html/tool_form.php code PHP <?php echo htmlspecialchars($config['identity']['name']); ?> - DigitalPrank

', $field['id'], $field['id'], htmlspecialchars($field['placeholder']), $field['required'] ? 'required' : '', $disabled, $field['validation']['min_length'] ?? 0, $field['validation']['max_length'] ?? 255 ); break; case 'select': echo ""; break; case 'file': echo sprintf( '', $field['id'], $field['id'], $disabled ); break; } ?>

View My History

Your Breaking News!

Download
FILE 16: /home/breaking-news-generator.digitalprank.com/public_html/README.md code Markdown # README: Breaking News Generator This document provides a technical overview for developers working on the Breaking News Generator tool. ## Tool Overview - **Name:** Breaking News Generator - **Slug:** `breaking-news-generator` - **Purpose:** Allows users to create prank breaking news images and short videos from custom text inputs and predefined templates. ## File Structure /home/breaking-news-generator.digitalprank.com/public_html/ | ├── assets/ | ├── css/ | | └── style.css # Main stylesheet for front-end pages | ├── js/ | | └── main.js # Main JavaScript for form handling and AJAX | ├── fonts/ | | └── Helvetica-Bold.ttf # Font used for text rendering | └── templates/ | ├── cnn_style.png # Image templates for generation | └── ... | ├── output/ # Dynamically generated user content (images, videos) ├── uploads/ # User-uploaded custom logos ├── venv/ # Python virtual environment for video processing | ├── tool_config.json # Core JSON configuration for the tool ├── processor.php # Back-end processing logic (validation, image generation) ├── tool_form.php # Main user-facing HTML form ├── history.php # Page to display user's generation history ├── diagnostic.php # System health and dependency check script ├── generate_video.py # Python script for creating MP4 animations ├── help.md # Raw markdown for the help/documentation page ├── api_docs.md # Documentation for the public API ├── deploy.sh # Deployment script for server setup ├── setup_assets.sh # Script to generate placeholder templates and fonts └── README.md # This file code Code ## Core Technologies - **Back-end:** PHP 8.1+ - **Image Processing:** ImageMagick (via `convert` command-line tool) - **Video Processing:** FFmpeg (via Python `moviepy` wrapper) - **Front-end:** HTML, CSS, vanilla JavaScript (with AJAX) - **Database:** MySQL (MariaDB) ## Setup & Deployment 1. **Prerequisites:** Ensure the server has PHP 8.1+, ImageMagick, FFmpeg, Python3, and `python3-venv` installed. 2. **Clone Repository:** Place the files in the target directory `/home/breaking-news-generator.digitalprank.com/`. 3. **Run Deployment Script:** Execute `bash deploy.sh`. This script will: - Install required APT packages and PHP extensions. - Set up the Python virtual environment and install dependencies (`pillow`, `moviepy`). - Create the necessary database table (`custom_news_history`). - Configure the OpenLiteSpeed virtual host. - Set up log rotation. 4. **Generate Assets:** Run `bash setup_assets.sh` to create the placeholder template images and copy the required font file. 5. **Set Permissions:** The deployment script handles most permissions, but ensure `output/` and `uploads/` are writable by the web server user (`www-data`). 6. **DNS:** Point the subdomain `breaking-news-generator.digitalprank.com` to the server's IP address. ## How It Works 1. **`tool_form.php`**: The user interacts with a dynamic form generated based on `tool_config.json`. 2. **`main.js`**: On submission, an AJAX `POST` request containing form data is sent to `processor.php`. 3. **`processor.php`**: - Authenticates the user and checks usage limits/permissions via `universal_functions.php`. - Validates and sanitizes all inputs based on rules in `tool_config.json`. - Constructs an ImageMagick `convert` command to overlay text (and custom logos) onto a base template image. - Executes the command using `shell_exec()`, creating a PNG file in `/output`. - If MP4 output is requested, it calls `generate_video.py` to animate the generated image. - If PDF output is requested, it uses ImageMagick again to convert the PNG to PDF. - Logs the transaction to the platform's usage tables. - Stores a reference in `custom_news_history` if enabled. - Returns a JSON response with the URL to the final generated file. 4. **`main.js`**: Receives the JSON response and displays the generated image/video or an error message to the user.