Executando um script python no wordpress

19

Eu tenho uma instalação do WordPress para um blog pessoal e gradualmente estou portando todos os pequenos bits da web que escrevi ao longo dos anos para as páginas do blog.

Uma dessas páginas é http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py, que é um script python simples que retorna uma lista de palavras - eu gostaria de incorporar esse comportamento em uma página do wordpress - alguém poderia me apontar na direção certa para a maneira mais fácil de executar um ponto de python no wordpress?

EDIT - seguindo a maravilhosa resposta abaixo, eu tenho muito mais ... mas infelizmente ainda não estou lá ...

Eu tenho python que executa no servidor ...

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

e está no mesmo diretório do plugin ativado ...

O código python ... que tem o seguinte código ...

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

O 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;
}
Joe
fonte
11
Se é um script muito simples, acho que o reescrevo no PHP como um plugin / modelo do WordPress ;-) Mas, em alguns casos, as pessoas usam iframes para incorporar páginas externas.
birgire
iframe diretamente? :]
Jesse
Isso é apenas um acidente ou o seu código python está realmente misturado ao PHP?
Fuxia
Colei o traço terminal, com os arquivos que estão sendo exibidos pelo comando 'mais' ... vai arrumar um pouco ...
Joe

Respostas:

20

Você pode usar popen()para ler ou gravar em um script Python (isso funciona com qualquer outra linguagem também). Se você precisar de interação (passando variáveis), use proc_open().

Um exemplo simples para imprimir Hello World! em um plugin do WordPress

Crie o plugin, registre um código curto:

<?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;
}

Agora você pode usar esse código curto no editor de postagem com [python]ou [python file="filename.py"].

Coloque os scripts Python que você deseja usar no mesmo diretório que o arquivo de plug-in. Você também pode colocá-los em um diretório e ajustar o caminho no manipulador de códigos curtos.

Agora crie um script Python complexo como este:

print("Hello World!")

E isso é tudo. Use o código curto e obtenha esta saída:

insira a descrição da imagem aqui

fuxia
fonte
Resposta correta omite que a primeira linha do script do python, pelo menos no meu caso, precisa ser # / usr / bin / env python!
MikeiLL
11
@ MikeiLL Isso depende do sistema do usuário, então eu o deixei de fora deliberadamente.
fuxia
basicamente fazendo uma brecha na segurança. Se você pode canalizar para python, também pode canalizar para qualquer outro processo e isso pode ser usado para escalar qualquer exploração mais trivial.
precisa saber é o seguinte
3

Eu segui o script de exemplo da primeira resposta, mas não obtive resultados ou erros.

Eu mudei esta linha:

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

para isso:

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

e, em seguida, recebeu uma mensagem "permissão negada".

No console, eu corri

chmod 777 hello.py

atualizou a página e tudo funcionou perfeitamente.

Esse pode ser o problema que Joe estava vendo acima. Não tenho representante suficiente para comentar, desculpe. Espero que isso ajude alguém.

thepotoo
fonte
Não faça a permissão 777. Apenas faça-o executar. chmod +x filename.pyvai fazer
Tessaracter
2

Aqui está um pequeno script que usa proc_opencomo mencionado acima, para enviar uma variável de texto simples para um script 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

Adicionados alguns testes na parte inferior para ver se o arquivo python é rwx. Eu acho que uma maneira melhor de enviar o argvseria usando fwrite, mas não estava funcionando para mim após este tutorial .

Aqui está o script python que eu usei. Conforme observado nos comentários acima, algo como #!/usr/bin/env pythonpode ser necessário, dependendo do servidor.

#!/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
fonte