Plugin Directory

Changeset 3437923


Ignore:
Timestamp:
01/12/2026 04:06:05 PM (3 months ago)
Author:
samukbg
Message:

Tagging version 1.2.8

Location:
post2podcast
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • post2podcast/tags/1.2.8/includes/class-post2podcast-api.php

    r3437893 r3437923  
    1010    public function __construct() {
    1111        add_action('wp_ajax_post2podcast_generate_podcast_audio', array($this, 'generate_podcast_audio'));
     12    }
     13
     14    /**
     15     * Convert memory string (e.g. '256M', '1G') to bytes
     16     */
     17    private function return_bytes($val) {
     18        if (empty($val)) return 0;
     19
     20        $val = trim($val);
     21        $last = strtolower($val[strlen($val)-1]);
     22        $val = (int) $val;
     23
     24        switch($last) {
     25            case 'g':
     26                $val *= 1024;
     27            case 'm':
     28                $val *= 1024;
     29            case 'k':
     30                $val *= 1024;
     31        }
     32
     33        return $val;
    1234    }
    1335
     
    113135
    114136    public function generate_podcast_audio() {
     137        // Increase memory limit for large audio processing
     138        $current_memory = ini_get('memory_limit');
     139        $memory_in_bytes = $this->return_bytes($current_memory);
     140        $required_memory = 512 * 1024 * 1024; // 512MB
     141
     142        if ($memory_in_bytes > 0 && $memory_in_bytes < $required_memory) {
     143            @ini_set('memory_limit', '512M');
     144            error_log("Post2Podcast: Increased memory limit from {$current_memory} to 512M for audio generation");
     145        }
     146
     147        // Increase max execution time
     148        $current_time_limit = ini_get('max_execution_time');
     149        if ($current_time_limit < 1800 && $current_time_limit != 0) {
     150            @set_time_limit(1800); // 30 minutes
     151            error_log("Post2Podcast: Increased execution time limit from {$current_time_limit}s to 1800s");
     152        }
     153
    115154        if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
    116155            error_log("P2P_SSE: generate_podcast_audio action started.");
     
    331370                    throw new Exception('Audio generation failed on server: ' . $error_detail);
    332371                }
     372
     373                // Validate audio content is not empty
     374                if (empty($job_response['audio_content'])) {
     375                    throw new Exception('Audio generation failed: Server returned empty audio content');
     376                }
     377
    333378                $audio_content = base64_decode($job_response['audio_content']);
     379
     380                // Validate decoded audio content
     381                if ($audio_content === false || strlen($audio_content) < 1000) {
     382                    throw new Exception('Audio generation failed: Invalid or corrupted audio data (size: ' . strlen($audio_content) . ' bytes)');
     383                }
     384
    334385                $audio_duration_seconds = $job_response['duration'] ?? 0;
    335386                $filename = $job_response['filename'] ?? 'podcast-' . $post_id . '-' . time() . '.mp3';
    336387
    337                 $this->log('Saving generated audio file...');
     388                $this->log('Saving generated audio file... (Size: ' . number_format(strlen($audio_content)) . ' bytes)');
    338389                $upload_dir_info = wp_upload_dir();
    339390                $audio_dir = $upload_dir_info['basedir'] . '/post2podcast';
    340391                if (!file_exists($audio_dir)) wp_mkdir_p($audio_dir);
    341392                $filepath = $audio_dir . '/' . $filename;
    342                 file_put_contents($filepath, $audio_content);
     393
     394                // Write audio file
     395                $bytes_written = file_put_contents($filepath, $audio_content);
     396
     397                if ($bytes_written === false || $bytes_written === 0) {
     398                    throw new Exception('Failed to write audio file to disk');
     399                }
     400
     401                // Verify the file was written correctly
     402                if (!file_exists($filepath) || filesize($filepath) < 1000) {
     403                    throw new Exception('Audio file was not saved correctly (expected size: ' . strlen($audio_content) . ', actual: ' . (file_exists($filepath) ? filesize($filepath) : 0) . ')');
     404                }
     405
     406                $this->log('Audio file saved successfully: ' . $filepath . ' (' . number_format(filesize($filepath)) . ' bytes)');
    343407                $audio_url = $upload_dir_info['baseurl'] . '/post2podcast/' . $filename;
    344408
     
    678742        );
    679743
     744        $start_time = microtime(true);
    680745        $response = wp_remote_post($url, $args);
     746        $elapsed_time = round(microtime(true) - $start_time, 2);
    681747
    682748        if (is_wp_error($response)) {
    683749            $error_message = $response->get_error_message();
    684             error_log("Post2Podcast WP HTTP API Error (post2podcast_start_sync_generation): " . $error_message);
    685             return new WP_Error('connection_error', 'Connection error: ' . $error_message);
     750            error_log("Post2Podcast WP HTTP API Error (post2podcast_start_sync_generation) after {$elapsed_time}s: " . $error_message);
     751            return new WP_Error('connection_error', 'Connection error after ' . $elapsed_time . 's: ' . $error_message);
    686752        }
    687753
    688754        $status_code = wp_remote_retrieve_response_code($response);
    689755        $response_body = wp_remote_retrieve_body($response);
     756        $response_size = strlen($response_body);
     757
     758        error_log("Post2Podcast: Received response after {$elapsed_time}s - Status: {$status_code}, Size: " . number_format($response_size) . " bytes");
    690759
    691760        if ($status_code >= 400) {
     
    700769
    701770        $decoded = json_decode($response_body, true);
     771
     772        // Check for JSON decode errors
     773        if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
     774            $json_error = json_last_error_msg();
     775            error_log("Post2Podcast JSON Decode Error: {$json_error}. Response size: " . number_format($response_size) . " bytes. First 500 chars: " . substr($response_body, 0, 500));
     776            return new WP_Error('json_decode_failed', 'Failed to parse server response: ' . $json_error . '. Response may be truncated or corrupted.');
     777        }
    702778
    703779        // Check if the response indicates a server-side error even with 200 status
     
    706782            error_log("Post2Podcast API Error: " . $error_msg);
    707783            return new WP_Error('generation_failed', $error_msg);
     784        }
     785
     786        // Log audio content size if present
     787        if (isset($decoded['audio_content'])) {
     788            $audio_size = strlen($decoded['audio_content']);
     789            error_log("Post2Podcast: Received audio_content in response: " . number_format($audio_size) . " characters (base64)");
    708790        }
    709791
  • post2podcast/tags/1.2.8/post2podcast.php

    r3437893 r3437923  
    44 * Plugin server URI: https://github.com/samukbg/post2podcast-server
    55 * Description: Convert WordPress posts into podcast episodes with AI voices
    6  * Version: 1.2.7
     6 * Version: 1.2.8
    77 * Author: Samuel Bezerra
    88 * Author URI: https://github.com/samukbg
     
    2020
    2121// Define plugin constants
    22 define('POST2PODCAST_VERSION', '1.2.7');
     22define('POST2PODCAST_VERSION', '1.2.8');
    2323define('POST2PODCAST_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2424define('POST2PODCAST_PLUGIN_URL', plugin_dir_url(__FILE__));
  • post2podcast/tags/1.2.8/readme.txt

    r3437893 r3437923  
    55Tested up to: 6.8
    66Requires PHP: 7.4
    7 Stable tag: 1.2.7
     7Stable tag: 1.2.8
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    274274== Changelog ==
    275275
     276= 1.2.8 =
     277* CRITICAL FIX: Corrupted MP3 files with long articles - audio now generates completely without truncation
     278* FIXED: HTTP timeout issues on backend server (increased to 30 minutes for long audio generation)
     279* FIXED: PHP memory and execution time limits automatically increased to handle large audio files
     280* IMPROVED: Comprehensive audio validation - validates base64 encoding, decoded content size, and file integrity
     281* IMPROVED: Enhanced logging with timing, response sizes, and detailed error diagnostics
     282* IMPROVED: Backend server timeouts extended to 30 minutes for long-running audio generation
     283* IMPROVED: Automatic memory increase to 512MB for processing large audio files
     284* IMPROVED: Better JSON decode error handling to detect truncated responses
     285
    276286= 1.2.7 =
    277287* FIXED: Error handling now properly detects and reports server failures instead of showing 100% progress
  • post2podcast/trunk/includes/class-post2podcast-api.php

    r3437893 r3437923  
    1010    public function __construct() {
    1111        add_action('wp_ajax_post2podcast_generate_podcast_audio', array($this, 'generate_podcast_audio'));
     12    }
     13
     14    /**
     15     * Convert memory string (e.g. '256M', '1G') to bytes
     16     */
     17    private function return_bytes($val) {
     18        if (empty($val)) return 0;
     19
     20        $val = trim($val);
     21        $last = strtolower($val[strlen($val)-1]);
     22        $val = (int) $val;
     23
     24        switch($last) {
     25            case 'g':
     26                $val *= 1024;
     27            case 'm':
     28                $val *= 1024;
     29            case 'k':
     30                $val *= 1024;
     31        }
     32
     33        return $val;
    1234    }
    1335
     
    113135
    114136    public function generate_podcast_audio() {
     137        // Increase memory limit for large audio processing
     138        $current_memory = ini_get('memory_limit');
     139        $memory_in_bytes = $this->return_bytes($current_memory);
     140        $required_memory = 512 * 1024 * 1024; // 512MB
     141
     142        if ($memory_in_bytes > 0 && $memory_in_bytes < $required_memory) {
     143            @ini_set('memory_limit', '512M');
     144            error_log("Post2Podcast: Increased memory limit from {$current_memory} to 512M for audio generation");
     145        }
     146
     147        // Increase max execution time
     148        $current_time_limit = ini_get('max_execution_time');
     149        if ($current_time_limit < 1800 && $current_time_limit != 0) {
     150            @set_time_limit(1800); // 30 minutes
     151            error_log("Post2Podcast: Increased execution time limit from {$current_time_limit}s to 1800s");
     152        }
     153
    115154        if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
    116155            error_log("P2P_SSE: generate_podcast_audio action started.");
     
    331370                    throw new Exception('Audio generation failed on server: ' . $error_detail);
    332371                }
     372
     373                // Validate audio content is not empty
     374                if (empty($job_response['audio_content'])) {
     375                    throw new Exception('Audio generation failed: Server returned empty audio content');
     376                }
     377
    333378                $audio_content = base64_decode($job_response['audio_content']);
     379
     380                // Validate decoded audio content
     381                if ($audio_content === false || strlen($audio_content) < 1000) {
     382                    throw new Exception('Audio generation failed: Invalid or corrupted audio data (size: ' . strlen($audio_content) . ' bytes)');
     383                }
     384
    334385                $audio_duration_seconds = $job_response['duration'] ?? 0;
    335386                $filename = $job_response['filename'] ?? 'podcast-' . $post_id . '-' . time() . '.mp3';
    336387
    337                 $this->log('Saving generated audio file...');
     388                $this->log('Saving generated audio file... (Size: ' . number_format(strlen($audio_content)) . ' bytes)');
    338389                $upload_dir_info = wp_upload_dir();
    339390                $audio_dir = $upload_dir_info['basedir'] . '/post2podcast';
    340391                if (!file_exists($audio_dir)) wp_mkdir_p($audio_dir);
    341392                $filepath = $audio_dir . '/' . $filename;
    342                 file_put_contents($filepath, $audio_content);
     393
     394                // Write audio file
     395                $bytes_written = file_put_contents($filepath, $audio_content);
     396
     397                if ($bytes_written === false || $bytes_written === 0) {
     398                    throw new Exception('Failed to write audio file to disk');
     399                }
     400
     401                // Verify the file was written correctly
     402                if (!file_exists($filepath) || filesize($filepath) < 1000) {
     403                    throw new Exception('Audio file was not saved correctly (expected size: ' . strlen($audio_content) . ', actual: ' . (file_exists($filepath) ? filesize($filepath) : 0) . ')');
     404                }
     405
     406                $this->log('Audio file saved successfully: ' . $filepath . ' (' . number_format(filesize($filepath)) . ' bytes)');
    343407                $audio_url = $upload_dir_info['baseurl'] . '/post2podcast/' . $filename;
    344408
     
    678742        );
    679743
     744        $start_time = microtime(true);
    680745        $response = wp_remote_post($url, $args);
     746        $elapsed_time = round(microtime(true) - $start_time, 2);
    681747
    682748        if (is_wp_error($response)) {
    683749            $error_message = $response->get_error_message();
    684             error_log("Post2Podcast WP HTTP API Error (post2podcast_start_sync_generation): " . $error_message);
    685             return new WP_Error('connection_error', 'Connection error: ' . $error_message);
     750            error_log("Post2Podcast WP HTTP API Error (post2podcast_start_sync_generation) after {$elapsed_time}s: " . $error_message);
     751            return new WP_Error('connection_error', 'Connection error after ' . $elapsed_time . 's: ' . $error_message);
    686752        }
    687753
    688754        $status_code = wp_remote_retrieve_response_code($response);
    689755        $response_body = wp_remote_retrieve_body($response);
     756        $response_size = strlen($response_body);
     757
     758        error_log("Post2Podcast: Received response after {$elapsed_time}s - Status: {$status_code}, Size: " . number_format($response_size) . " bytes");
    690759
    691760        if ($status_code >= 400) {
     
    700769
    701770        $decoded = json_decode($response_body, true);
     771
     772        // Check for JSON decode errors
     773        if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
     774            $json_error = json_last_error_msg();
     775            error_log("Post2Podcast JSON Decode Error: {$json_error}. Response size: " . number_format($response_size) . " bytes. First 500 chars: " . substr($response_body, 0, 500));
     776            return new WP_Error('json_decode_failed', 'Failed to parse server response: ' . $json_error . '. Response may be truncated or corrupted.');
     777        }
    702778
    703779        // Check if the response indicates a server-side error even with 200 status
     
    706782            error_log("Post2Podcast API Error: " . $error_msg);
    707783            return new WP_Error('generation_failed', $error_msg);
     784        }
     785
     786        // Log audio content size if present
     787        if (isset($decoded['audio_content'])) {
     788            $audio_size = strlen($decoded['audio_content']);
     789            error_log("Post2Podcast: Received audio_content in response: " . number_format($audio_size) . " characters (base64)");
    708790        }
    709791
  • post2podcast/trunk/post2podcast.php

    r3437893 r3437923  
    44 * Plugin server URI: https://github.com/samukbg/post2podcast-server
    55 * Description: Convert WordPress posts into podcast episodes with AI voices
    6  * Version: 1.2.7
     6 * Version: 1.2.8
    77 * Author: Samuel Bezerra
    88 * Author URI: https://github.com/samukbg
     
    2020
    2121// Define plugin constants
    22 define('POST2PODCAST_VERSION', '1.2.7');
     22define('POST2PODCAST_VERSION', '1.2.8');
    2323define('POST2PODCAST_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2424define('POST2PODCAST_PLUGIN_URL', plugin_dir_url(__FILE__));
  • post2podcast/trunk/readme.txt

    r3437893 r3437923  
    55Tested up to: 6.8
    66Requires PHP: 7.4
    7 Stable tag: 1.2.7
     7Stable tag: 1.2.8
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    274274== Changelog ==
    275275
     276= 1.2.8 =
     277* CRITICAL FIX: Corrupted MP3 files with long articles - audio now generates completely without truncation
     278* FIXED: HTTP timeout issues on backend server (increased to 30 minutes for long audio generation)
     279* FIXED: PHP memory and execution time limits automatically increased to handle large audio files
     280* IMPROVED: Comprehensive audio validation - validates base64 encoding, decoded content size, and file integrity
     281* IMPROVED: Enhanced logging with timing, response sizes, and detailed error diagnostics
     282* IMPROVED: Backend server timeouts extended to 30 minutes for long-running audio generation
     283* IMPROVED: Automatic memory increase to 512MB for processing large audio files
     284* IMPROVED: Better JSON decode error handling to detect truncated responses
     285
    276286= 1.2.7 =
    277287* FIXED: Error handling now properly detects and reports server failures instead of showing 100% progress
Note: See TracChangeset for help on using the changeset viewer.