Skip to content

Commit

Permalink
Merge pull request #21 from berchj/dev
Browse files Browse the repository at this point in the history
Dev into release
  • Loading branch information
berchj authored Jul 20, 2024
2 parents ca92e0c + 7dd3f46 commit 7044f52
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 190 deletions.
8 changes: 6 additions & 2 deletions .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"plugins": ["./ai-entries/"],
"phpVersion": "7.4"
"plugins": [
"./ai-entries/",
"https://downloads.wordpress.org/plugin/plugin-check.zip"
],
"phpVersion": "7.4",
"core": null
}
2 changes: 1 addition & 1 deletion ai-entries/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Contributors: Julio Bermúdez
Tested up to: 6.6
Stable tag: 1.0.3
Stable tag: 1.0.7
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Tags: plugin best practices, accessibility, performance, security, automation
Expand Down
2 changes: 1 addition & 1 deletion ai-entries/ai-entries.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Plugin Name: AI Entries
* Description: Automates the creation of standard WordPress posts.
* Version: 1.0.3
* Version: 1.0.7
* Requires at least: 5.2
* Requires PHP: 7.2
* Author: Julio Bermúdez
Expand Down
148 changes: 89 additions & 59 deletions ai-entries/includes/class-ai-entries-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,93 @@

class AIEntries_API
{
public static $responses = array();
public static function fetch_news()
{
$api_base_url = 'https://newsapi.org/v2/everything';

// Construir la URL completa con los parámetros
$url = add_query_arg(array(
'q' => get_option('AIEntries_question', ''),
'apiKey' => get_option('AIEntries_news_api_key', ''),
'pageSize' => get_option('AIEntries_num_calls', 1),
), $api_base_url);

// Realizar la solicitud GET utilizando wp_remote_get
$response = wp_remote_get($url, array('headers' => array('User-Agent' => get_option('AIEntries_news_api_key', ''))));

// Verificar si la solicitud fue exitosa
if (is_wp_error($response)) {
return "Error: " . $response->get_error_message();
}

$body = wp_remote_retrieve_body($response);

// Decodificar el cuerpo de la respuesta JSON
$data = json_decode($body, true);

// Devolver los datos decodificados
return $data['articles'];
}

public static function call($question, $api_key, $category_name, $iterator = "")
{
// URL for the API call
$url = 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent?key=' . $api_key;

// Request arguments
$args = array(
'timeout' => 60,
'body' => wp_json_encode(array(
"contents" => array(
array(
"parts" => array(
array(
"text" => "List 1 " . $iterator . " article about " . $question . ". Using this JSON schema :{'title': str,'content':str} (Return only the JSON String without spaces) the title must be good for SEO and the content must be in html string",
$news_articles = self::fetch_news();

foreach ($news_articles as $key => $value) {
// URL for the API call
$url = 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent?key=' . $api_key;

// Request arguments
$args = array(
'timeout' => 60,
'body' => wp_json_encode(array(
"contents" => array(
array(
"parts" => array(
array(
"text" => "Analize this article : {'title':'" . wp_json_encode($value['title']) . "','description':'" . wp_json_encode($value['description']) . "','content':'" . wp_json_encode($value['content']) . "'} . Now write 1 related original article in english using this JSON schema : {'title': str,'content':str} (Return only the JSON String without spaces) the title must be good for SEO and the content must be in html string",
),
),
),
),
)),
'headers' => array(
'Content-Type' => 'application/json',
),
)),
'headers' => array(
'Content-Type' => 'application/json',
),
'method' => 'POST',
);

// Response
$response = wp_remote_post($url, $args);

// If anything goes wrong
if (is_wp_error($response)) {
return new WP_Error('api_error', $response->get_error_message());
}
'method' => 'POST',
);

// Retrieve body
$body = wp_remote_retrieve_body($response);
// Response
$response = wp_remote_post($url, $args);

// Format data
if (empty($body)) {
return new WP_Error('api_error', 'Empty response from API.');
}
// If anything goes wrong
if (is_wp_error($response)) {
return new WP_Error('api_error', $response->get_error_message());
}

$data = json_decode($body, true);
// Retrieve body
$body = wp_remote_retrieve_body($response);
// Format data
if (empty($body)) {
return new WP_Error('api_error', 'Empty response from API.');
}

if (!isset($data['candidates'][0]['content']['parts'][0]['text'])) {
return new WP_Error('api_error', 'Invalid API response structure.');
}
$data = json_decode($body, true);

// AI Post
$article = json_decode($data['candidates'][0]['content']['parts'][0]['text'], true);
if (!isset($data['candidates'][0]['content']['parts'][0]['text'])) {
return new WP_Error('api_error', 'Invalid API response structure.');
}

if (!isset($article['title']) || !isset($article['content'])) {
return new WP_Error('api_error', 'API response does not contain title or content.');
// AI Post
$article = json_decode($data['candidates'][0]['content']['parts'][0]['text'], true);

if (!isset($article['title']) || !isset($article['content'])) {
return new WP_Error('api_error', 'API response does not contain title or content.');
}

self::create_new_entry($article['title'], $article['content'], $category_name);
}

return self::create_new_entry($article['title'], $article['content'], $category_name);
}

private static function create_new_entry($title, $content, $category_name)
Expand Down Expand Up @@ -86,36 +117,38 @@ private static function create_new_entry($title, $content, $category_name)
if (is_wp_error($post_id)) {
return new WP_Error('insert_error', $post_id->get_error_message());
} else {
$base64_image = self::generate_post_image_with_AI($title);
self::set_featured_image_from_base64($base64_image, $post_id);

self::generate_post_image_with_AI($title, $post_id);
//self::set_featured_image_from_base64($base64_image, $post_id);

wp_clear_scheduled_hook('AIEntries_daily_cron_job');

wp_schedule_event(strtotime('now') + (1 * 60 * 60) , 'hourly', 'AIEntries_daily_cron_job');
wp_schedule_event(strtotime('now') + (1 * 60 * 60), 'hourly', 'AIEntries_daily_cron_job');

array_push(self::$responses,get_post($post_id));

return get_post($post_id);
}
}
return new WP_Error('permission_error', 'You do not have permission to publish posts.');
}

private static function generate_post_image_with_AI($title)
private static function generate_post_image_with_AI($title, $post_id)
{
$base_url = 'https://api.stability.ai';
$url = "$base_url/v1/generation/stable-diffusion-v1-6/text-to-image";
$api_key_stable_diffusion = get_option('AIEntries_api_key_stable_diffusion', '');

$body = wp_json_encode(array(
"text_prompts" => array(array("text" => $title)),
"text_prompts" => array(array("text" => $title .'. without texts in the image.')),
"cfg_scale" => 7,
"height" => 1024,
"width" => 1024,
"samples" => 1,
"steps" => 30,
));

$response = wp_remote_post($url, array(
'timeout' => 600,
$response = wp_remote_post($url, array(
'timeout'=>600,
'method' => 'POST',
'headers' => array(
'Content-Type' => 'application/json',
Expand All @@ -124,17 +157,15 @@ private static function generate_post_image_with_AI($title)
),
'body' => $body,
));

if (is_wp_error($response)) {
return '';
}

$body_request = json_decode($response['body'], true);
return $body_request['artifacts'][0]['base64'];
}

$base64_image = $body_request['artifacts'][0]['base64'];

private static function set_featured_image_from_base64($base64_image, $post_id)
{
if (!is_int($post_id)) {
return false;
}
Expand Down Expand Up @@ -173,10 +204,9 @@ private static function set_featured_image_from_base64($base64_image, $post_id)
require_once ABSPATH . 'wp-admin/includes/image.php';

$attach_data = wp_generate_attachment_metadata($attach_id, $file_path);

wp_update_attachment_metadata($attach_id, $attach_data);
set_post_thumbnail($post_id, $attach_id);

return true;
set_post_thumbnail($post_id, $attach_id);
}

}
89 changes: 29 additions & 60 deletions ai-entries/includes/class-ai-entries-cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,7 @@

class AIEntries_Cron
{
// Function to check and run the function every 5 minutes
public static function my_six_hour_function()
{

AIEntries_Cron::daily_task(); // Execute the function

}

// Function to check and run the function every 6 hours
public static function check_six_hour_function()
{
$last_executed_time = get_transient('last_six_hour_execution');

// Check if it's time to run the function (6 hours have passed)
if (!$last_executed_time || $last_executed_time < strtotime('-6 hours')) {
AIEntries_Cron::my_six_hour_function(); // Execute the function
set_transient('last_six_hour_execution', strtotime('now')); // Update the last execution time
}
}

public function daily_task()
public static function daily_task()
{
$question = get_option('AIEntries_question', '');
$num_calls = get_option('AIEntries_num_calls', 1);
Expand All @@ -44,54 +24,43 @@ public static function show_all_cron_tasks()
if (empty($cron)) {
return 'No tasks scheduled.';
}

$output = '<table border="1 | 0" style="text-align:center;width:100%">';
$output .= '<tr><th> <h2>Next Excecution</h2> </th><th> <h2>Hook Name</h2> </th><th> <h2>Function Name</h2> </th></tr>';

foreach ($cron as $timestamp => $cronhooks) {
foreach ((array) $cronhooks as $hook => $events) {
if ($hook == 'AIEntries_daily_cron_job') {
$callbacks = array();
foreach ((array) $events as $event) {
if (isset($GLOBALS['wp_filter'][$hook])) {
$callbacks[] = $GLOBALS['wp_filter'][$hook];
}
}
//print_r($callbacks);
foreach ($callbacks as $priority => $callback) {
foreach ($callback->callbacks as $function_data) {
foreach ($function_data as $function_parts) {
$output .= '<tr>';
$output .= '<td><p>' . esc_html(gmdate('Y-m-d H:i:s', $timestamp)) . '</p></td>';
$output .= '<td><p>' . esc_html($hook) . '</p></td>';
$output .= '<td><p>' . esc_html(strval($function_parts['function'][1] ? $function_parts['function'][1] : $function_parts['function'][0])) . '</p></td>';
$output .= '</tr>';
if (wp_next_scheduled('AIEntries_daily_cron_job')) {
$output = '<table border="1 | 0" style="text-align:center;width:100%">';
$output .= '<tr><th> <h2>Next Excecution</h2> </th><th> <h2>Hook Name</h2> </th><th> <h2>Function Name</h2> </th></tr>';
foreach ($cron as $timestamp => $cronhooks) {
foreach ((array) $cronhooks as $hook => $events) {
if ($hook == 'AIEntries_daily_cron_job') {
$callbacks = array();
foreach ((array) $events as $event) {
if (isset($GLOBALS['wp_filter'][$hook])) {
$callbacks[] = $GLOBALS['wp_filter'][$hook];
}

}
}
/* // Suponiendo que $array contiene el array proporcionado
foreach ($callbacks as $priority => $callbacks) {
foreach ($callbacks as $callback_name => $callback_info) {
$function_info = $callback_info['function'];
// Obtener el objeto/clase y el nombre de la función
$function_object = $function_info[0];
$function_name = $function_info[1];
//print_r($callbacks);
foreach ($callbacks as $priority => $callback) {
foreach ($callback->callbacks as $function_data) {
foreach ($function_data as $function_parts) {
$output .= '<tr>';
$output .= '<td><p>' . esc_html(gmdate('Y-m-d H:i:s', $timestamp)) . '</p></td>';
$output .= '<td><p>' . esc_html($hook) . '</p></td>';
$output .= '<td><p>' . esc_html(strval($function_parts['function'][1] ? $function_parts['function'][1] : $function_parts['function'][0])) . '</p></td>';
$output .= '</tr>';
}

echo 'Prioridad: ' . $priority . '<br>';
echo 'Función: ' . $function_object . '::' . $function_name . '<br>';
}
}

}
} */
}

}

}
}
echo wp_kses_post($output);
}

if (!wp_next_scheduled('AIEntries_daily_cron_job')) {
echo "\n \n No excecutions scheduled for: " . esc_html($hook_name);
return "\n \n No excecutions scheduled";
}
echo esc_html($output);

}
}
Loading

0 comments on commit 7044f52

Please sign in to comment.