Uruchamianie skryptu python w wordpress

19

Mam instalację WordPress na osobistym blogu i stopniowo przenoszę wszystkie małe fragmenty sieci, które pisałem przez lata na stronach blogu.

Jedną z takich stron jest http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py, który jest prostym skryptem Pythona, który zwraca listę słów - chciałbym osadzić to zachowanie na stronie wordpress - czy ktoś mógłby skierować mnie w dobrym kierunku, jeśli chodzi o łatwy sposób na uruchomienie Pythona w Wordpress?

EDYCJA - po cudownej odpowiedzi poniżej mam znacznie więcej ... ale niestety nadal nie całkiem tam ...

Mam python, który wykonuje się na serwerze ...

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

i znajduje się w tym samym katalogu, co aktywowana wtyczka ...

Kod python ... który ma następujący kod ...

#!/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;
}
Joe
źródło
1
Jeśli jest to bardzo prosty skrypt, myślę, że po prostu przepisałbym go w PHP jako wtyczkę / szablon WordPress ;-) Ale w niektórych przypadkach ludzie używają iframe do osadzania stron zewnętrznych.
birgire
iframe to bezpośrednio? :]
Jesse
Czy to tylko wypadek, czy twój kod Pythona jest naprawdę pomieszany z PHP?
fuxia
Wkleiłem ślad terminala, a pliki wyświetlane za pomocą polecenia „więcej”… posprzątasz trochę…
Joe,

Odpowiedzi:

20

Możesz użyć popen()do odczytu lub zapisu w skrypcie Python (działa to również z każdym innym językiem). Jeśli potrzebujesz interakcji (zmienne przekazujące) użyj proc_open().

Prosty przykład do wydrukowania Hello World! we wtyczce WordPress

Utwórz wtyczkę, zarejestruj krótki kod:

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

Teraz możesz użyć tego krótkiego kodu w edytorze postów za pomocą [python]lub [python file="filename.py"].

Umieść skrypty Pythona, których chcesz użyć, w tym samym katalogu, co plik wtyczki. Możesz także umieścić je w katalogu i dostosować ścieżkę w module obsługi krótkich kodów.

Teraz utwórz skomplikowany skrypt w języku Python:

print("Hello World!")

I to wszystko. Użyj krótkiego kodu i uzyskaj następujące dane wyjściowe:

wprowadź opis zdjęcia tutaj

fuxia
źródło
Prawidłowa odpowiedź pomija pierwszą linię skryptu python, przynajmniej w moim przypadku, musi to być #! /
Usr
1
@MikeiLL To zależy od systemu użytkownika, więc celowo go pominąłem.
fuxia
w zasadzie zrobienie dziury w zabezpieczeniach. Jeśli możesz potokować do Pythona, możesz również potokować do dowolnego innego procesu, a to może być użyte do eskalacji bardziej trywialnego exploita.
Mark Kaplun,
3

Śledziłem przykładowy skrypt od pierwszej odpowiedzi, ale nie otrzymywałem żadnych danych wyjściowych ani błędów.

Zmieniłem tę linię:

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

do tego:

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

a następnie dostał komunikat „odmowa zezwolenia”.

Na konsoli pobiegłem

chmod 777 hello.py

odświeżyła stronę i wszystko działało idealnie.

To może być problem, który Joe widział powyżej. Przepraszam, nie mam wystarczającej liczby przedstawicieli, aby skomentować Mam nadzieję, że to komuś pomoże.

thepotoo
źródło
Nie rób pozwolenia 777. Po prostu zrób to. chmod +x filename.pyzrobi
Tessaracter
2

Oto mały skrypt, który używa, proc_openjak wspomniano powyżej, do wysłania jednej prostej zmiennej tekstowej do skryptu 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

Dodano kilka testów na dole, aby sprawdzić, czy plik python jest rwx. Myślę, że lepszym sposobem na wysłanie argvbyłoby użycie fwrite, ale nie działało to dla mnie po tym samouczku .

Oto skrypt, którego użyłem. Jak wspomniano w komentarzach powyżej #!/usr/bin/env python, w zależności od serwera może być konieczne coś podobnego .

#!/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
źródło