Запуск скрипта Python в WordPress

19

У меня установлена ​​WordPress для личного блога, и я постепенно портирую все небольшие веб-фрагменты, которые я написал за эти годы, на страницы блога.

Одной из таких страниц является http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py, представляющий собой простой скрипт на python, который возвращает список слов - я хотел бы встроить это поведение в страницу wordpress. - Может ли кто-нибудь указать мне правильное направление для более простого способа запуска пятна Python в WordPress?

РЕДАКТИРОВАТЬ - после замечательного ответа ниже, я получил много дальше ... но, к сожалению, до сих пор не совсем там ...

У меня есть питон, который выполняется на сервере ...

projecttoomanycooks server [~/public_html/joereddington/wp-content/plugins]#./hello.py 
Hello World!

и он находится в том же каталоге, что и активированный плагин ...

Код Python ... который имеет следующий код ...

#!/usr/bin/python
print("Hello World!")

Php:

<?php
/**
 * Plugin Name: Joe's python thing.
 * Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
 * Description: A brief description of the Plugin.
 * Version: The Plugin's Version Number, e.g.: 1.0
 * Author: Name Of The Plugin Author
 * Author URI: http://URI_Of_The_Plugin_Author
 * License: A "Slug" license name e.g. GPL2
 */
/*from http://wordpress.stackexchange.com/questions/120259/running-a-python-scri
pt-within-wordpress/120261?noredirect=1#120261  */
add_shortcode( 'python', 'embed_python' );

function embed_python( $attributes )
{
    $data = shortcode_atts(
        array(
            'file' => 'hello.py'
        ),
        $attributes
    );
    $handle = popen( __DIR__ . '/' . $data['file'], 'r');
    $read   = fread($handle, 2096);
    pclose($handle);

    return $read;
}
Джо
источник
1
Если это очень простой скрипт, я думаю, я бы просто переписал его на PHP как плагин / шаблон WordPress ;-) Но в некоторых случаях люди используют iframes для встраивания внешних страниц.
Birgire
iframe это напрямую? :]
Джесси
Это просто случайность, или ваш код на Python действительно смешан с PHP?
fuxia
Я вставил трассировку терминала, файлы, отображаемые с помощью команды «more» ... немного приведут в порядок ...
Joe

Ответы:

20

Вы можете использовать popen()для чтения или записи в сценарии Python (это работает с любым другим языком тоже). Если вам нужно взаимодействие (передача переменных), используйте proc_open().

Простой пример для печати Hello World! в плагине WordPress

Создайте плагин, зарегистрируйте шорткод:

<?php # -*- coding: utf-8 -*-
/* Plugin Name: Python embedded */

add_shortcode( 'python', 'embed_python' );

function embed_python( $attributes )
{
    $data = shortcode_atts(
        [
            'file' => 'hello.py'
        ],
        $attributes
    );

    $handle = popen( __DIR__ . '/' . $data['file'], 'r' );
    $read = '';

    while ( ! feof( $handle ) )
    {
        $read .= fread( $handle, 2096 );
    }

    pclose( $handle );

    return $read;
}

Теперь вы можете использовать этот шорткод в редакторе сообщений с помощью [python]или [python file="filename.py"].

Поместите скрипты Python, которые вы хотите использовать, в тот же каталог, что и файл плагина. Вы также можете поместить их в каталог и настроить путь в обработчике шорткода.

Теперь создайте сложный скрипт на Python, например:

print("Hello World!")

И это все. Используйте шорткод и получите такой вывод:

введите описание изображения здесь

Фуксия
источник
В правильном ответе пропущено, что первая строка скрипта python, по крайней мере, в моем случае, должна быть #! / Usr / bin / env python
MikeiLL
1
@MikeiLL Это зависит от системы пользователя, поэтому я умышленно ее исключил.
fuxia
в основном делает дыру в безопасности. Если вы можете передавать по конвейеру на python, вы также можете передавать по конвейеру к любому другому процессу, и это может быть использовано для эскалации любого более тривиального эксплойта.
Марк Каплун
3

Я следовал примеру сценария из первого ответа, но не получал никаких выводов или ошибок.

Я изменил эту строку:

$handle = popen( __DIR__ . '/' . $data['file'], 'r' );

к этому:

$handle = popen( __DIR__ . '/' . $data['file'] . ' 2>&1', 'r' );

а затем получил сообщение «Отказано в разрешении».

На консоли я побежал

chmod 777 hello.py

обновил страницу, и все заработало отлично.

Это может быть проблемой, которую Джо видел выше. Мне не хватает представителя, чтобы комментировать, извините. Надеюсь, это кому-нибудь поможет.

thepotoo
источник
Не делайте разрешения 777. Просто сделайте его исполняющим. chmod +x filename.pyбудет делать
Tessaracter
2

Вот небольшой скрипт, который использует, proc_openкак отмечено выше, для отправки одной простой текстовой переменной в скрипт Python:

add_shortcode( 'execute_python', 'execute_python_with_argv' );

function execute_python_with_argv( $attributes ){

$description = array (     
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr
);

$application_system = "python ";
$application_path .= plugin_dir_path( __FILE__ );
$application_name .= "hello.py";
$separator = " ";

$application = $application_system.$application_path.$application_name.$separator;

$argv1 = '"output to receive back from python script"';
$pipes = array();

$proc = proc_open ( $application.$argv1 , $description , $pipes );

//echo proc_get_status($proc)['pid'];

if (is_resource ( $proc ))
{
    echo "Stdout : " . stream_get_contents ( $pipes [1] ); //Reading stdout buffer
    fclose ( $pipes [1] ); //Closing stdout buffer
    fclose ( $pipes [2] ); //Closing stderr buffer

    $return_value = proc_close($proc);
    echo "<br/>command returned: $return_value<br/>";
}

$application_test = glitch_player_DIR.$application_name;

echo "<br/>Is ".$application_test." executable? ".is_executable($application_test)." ";
echo "readable? ".is_readable($application_test)." ";
echo "writable? ".is_writable($application_test)." ";

} //EOF main/shortcode function

Внизу добавлено несколько тестов, чтобы увидеть, является ли файл python rwx. Я думаю, что лучший способ отправить сообщение - argvиспользовать fwrite, но после этого урока у меня ничего не вышло .

Вот скрипт Python, который я использовал. Как отмечено в комментариях выше, #!/usr/bin/env pythonможет потребоваться что-то подобное , в зависимости от сервера.

#!/usr/bin/env python

from sys import argv

script, what_he_said = argv

print "This is what you submitted: %s \n \n Isn't that amazing, man? " % what_he_said
MikeiLL
источник