2018-09-01 01:50:29 +02:00
< ? php
/**
* Connects to an spee . ch style server to host assets via the LBRY Protocol
*
* Visit https :// github . com / lbryio / spee . ch for more info
*
* @ package LBRYPress
*/
2018-09-01 03:14:12 +02:00
class LBRY_Speech
2018-09-01 01:50:29 +02:00
{
2018-09-11 22:10:15 +02:00
/**
2018-09-14 02:34:11 +02:00
* HTML Parser
* @ var LBRY_Speech_Parser
2018-09-11 22:10:15 +02:00
*/
2018-09-14 02:34:11 +02:00
private $parser = null ;
2018-09-01 03:14:12 +02:00
2018-09-14 02:34:11 +02:00
public function __construct ()
2018-09-01 03:14:12 +02:00
{
2018-10-31 19:17:42 +01:00
$this -> parser = new LBRY_Speech_Parser ();
2018-10-28 19:21:22 +01:00
2018-10-31 19:17:42 +01:00
if ( is_admin ()) {
add_action ( 'save_post' , array ( $this , 'upload_media' ), 10 , 2 );
2018-10-28 19:21:22 +01:00
}
2018-10-31 20:48:58 +01:00
// Replace the image srcsets
add_filter ( 'wp_calculate_image_srcset' , array ( $this -> parser , 'replace_image_srcset' ), 10 , 5 );
// Core filter for lots of image source calls
add_filter ( 'wp_get_attachment_image_src' , array ( $this -> parser , 'replace_attachment_image_src' ), 10 , 3 );
// Replace any left over urls with speech urls
add_filter ( 'the_content' , array ( $this -> parser , 'replace_urls_with_speech' ));
2018-09-01 03:14:12 +02:00
}
2018-09-14 02:42:38 +02:00
/**
* Uploads assets to the speech server
2018-10-26 01:30:24 +02:00
* @ param int $post_id The ID of the post to
* @ return bool True if successful , false if not or if no Speech URL available
2018-09-14 02:42:38 +02:00
*/
2018-10-26 18:46:28 +02:00
public function upload_media ( $post_id , $post )
2018-09-14 02:42:38 +02:00
{
2018-10-26 18:46:28 +02:00
// Only check post_type of Post
if ( 'post' !== $post -> post_type ) {
2018-10-31 19:17:42 +01:00
return false ;
2018-10-26 18:46:28 +02:00
}
2018-09-14 02:42:38 +02:00
$speech_url = get_option ( LBRY_SETTINGS )[ LBRY_SPEECH ];
// Die if we don't have a spee.ch url
if ( ! $speech_url || $speech_url === '' ) {
2018-10-26 01:30:24 +02:00
return false ;
}
2018-10-26 08:34:13 +02:00
$all_media = $this -> find_media ( $post_id );
2018-10-26 01:30:24 +02:00
2018-11-12 21:38:16 +01:00
// error_log(print_r($all_media, true));
2018-11-09 01:29:08 +01:00
2018-10-31 21:07:21 +01:00
// IDEA: Notify user if post save time will take a while
2018-10-26 08:34:13 +02:00
if ( $all_media ) {
2018-10-29 23:51:18 +01:00
$requests = array ();
// Build all the Curl Requests
2018-10-26 08:34:13 +02:00
foreach ( $all_media as $media ) {
2018-10-27 23:49:44 +02:00
$params = array (
'name' => $media -> name ,
'file' => $media -> file ,
'title' => $media -> title ,
'type' => $media -> type
);
2018-10-29 18:10:43 +01:00
// Pull Channel and Password from config file for now
// COMBAK: This will change in the future
2018-10-27 23:49:44 +02:00
if ( LBRY_SPEECH_CHANNEL && LBRY_SPEECH_CHANNEL_PASSWORD ) {
$params [ 'channelName' ] = LBRY_SPEECH_CHANNEL ;
$params [ 'channelPassword' ] = LBRY_SPEECH_CHANNEL_PASSWORD ;
}
2018-10-29 23:51:18 +01:00
$ch = $this -> build_request ( 'publish' , $params );
$requests [] = array (
'request' => $ch ,
'media' => $media
);
}
2018-10-28 18:09:22 +01:00
2018-10-29 23:51:18 +01:00
// Init the curl multi handle
$mh = curl_multi_init ();
// Add each request to the multi handle
foreach ( $requests as $request ) {
curl_multi_add_handle ( $mh , $request [ 'request' ]);
}
// Execute all requests simultaneously
$running = null ;
do {
curl_multi_exec ( $mh , $running );
} while ( $running );
// Close the handles
foreach ( $requests as $request ) {
curl_multi_remove_handle ( $mh , $request [ 'request' ]);
}
curl_multi_close ( $mh );
2018-10-27 23:49:44 +02:00
2018-10-29 23:51:18 +01:00
// Run through responses, and upload meta as necessary
foreach ( $requests as $request ) {
$result = json_decode ( curl_multi_getcontent ( $request [ 'request' ]));
$media = $request [ 'media' ];
$response_code = curl_getinfo ( $request [ 'request' ], CURLINFO_RESPONSE_CODE );
try {
// check we got a success code
if ( $response_code != '200' ) {
if ( ! empty ( $result ) && ! $result -> success && $result -> message ) {
throw new \Exception ( " API Issue with message: " . $result -> message );
} else {
throw new \Exception ( " Speech URL Connection Issue | Code: " . $response_code , 1 );
}
2018-10-27 23:49:44 +02:00
}
2018-10-29 23:51:18 +01:00
// Update image meta
if ( $result && $result -> success ) {
$meta = wp_get_attachment_metadata ( $media -> id );
if ( $media -> image_size ) {
2018-11-09 19:34:12 +01:00
$meta [ 'sizes' ][ $media -> image_size ][ LBRY_SPEECH_ASSET_URL ] = $result -> data -> serveUrl ;
2018-10-29 23:51:18 +01:00
} else {
2018-11-09 19:34:12 +01:00
$meta [ LBRY_SPEECH_ASSET_URL ] = $result -> data -> serveUrl ;
2018-10-29 23:51:18 +01:00
}
wp_update_attachment_metadata ( $media -> id , $meta );
} else { // Something unhandled happened here
throw new \Exception ( " Unknown Speech Upload issue for asset " );
}
} catch ( \Exception $e ) {
$image_size = $media -> image_size ? $media -> image_size : 'full' ;
2018-10-31 19:17:42 +01:00
error_log ( 'Failed to upload asset with ID ' . $media -> id . ' for size ' . $image_size . ' to supplied speech URL.' );
2018-11-12 21:38:16 +01:00
LBRY () -> daemon -> logger -> log ( 'Speech Upload' , 'Failed to upload asset with ID ' . $media -> id . ' for size ' . $image_size . ' to supplied speech URL. Message | ' . $e -> getMessage ());
2018-10-29 23:51:18 +01:00
error_log ( $e -> getMessage ());
2018-10-27 23:49:44 +02:00
}
2018-10-26 01:30:24 +02:00
}
}
}
/**
* Finds all media attached to a post
* @ param int $post_id The post to search
2018-10-26 08:34:13 +02:00
* @ return array An array of Speech Media Objects
2018-10-26 01:30:24 +02:00
*/
2018-10-31 19:17:42 +01:00
private function find_media ( $post_id )
2018-10-26 01:30:24 +02:00
{
2018-10-26 09:43:34 +02:00
$all_media = array ();
2018-10-27 21:28:20 +02:00
$content = get_post_field ( 'post_content' , $post_id );
2018-10-26 08:34:13 +02:00
2018-10-31 19:17:42 +01:00
$images = $this -> parser -> scrape_images ( $content );
2018-10-27 21:28:20 +02:00
2018-10-31 19:17:42 +01:00
// Get all the image ID's
$image_ids = array ();
foreach ( $images as $image ) {
$new_id = $this -> parser -> get_attachment_id_from_tag ( 'image' , $image );
if ( $new_id ) {
$image_ids [] = $new_id ;
}
}
// Don't forget the featured image
2018-11-09 01:29:08 +01:00
error_log ( $post_id );
2018-10-31 19:17:42 +01:00
if ( $featured_id = get_post_thumbnail_id ( $post_id )) {
$image_ids = array_merge ( $image_ids , array ( $featured_id ));
}
2018-10-26 08:34:13 +02:00
2018-10-31 19:17:42 +01:00
// Throw each image into a media object
foreach ( $image_ids as $attachment_id ) {
2018-10-27 23:49:44 +02:00
2018-10-31 19:17:42 +01:00
// Create main image media object
$meta = wp_get_attachment_metadata ( $attachment_id );
2018-10-27 21:28:20 +02:00
2018-10-31 19:17:42 +01:00
// If we don't have meta, get out because none of this will work
if ( ! $meta ) {
break ;
2018-10-27 21:28:20 +02:00
}
2018-10-31 19:17:42 +01:00
if ( ! $this -> is_published ( $meta )) {
$all_media [] = new LBRY_Speech_Media ( $attachment_id );
}
2018-10-29 22:55:26 +01:00
2018-10-31 19:17:42 +01:00
// COMBAK: find a way to make this more efficient?
// Create a media object for each image size
// Get images sizes for this attachment, as not all image sizes implemented
$image_sizes = wp_get_attachment_metadata ( $attachment_id )[ 'sizes' ];
2018-10-27 23:49:44 +02:00
2018-10-31 19:17:42 +01:00
foreach ( $image_sizes as $size => $meta ) {
2018-10-27 23:49:44 +02:00
if ( ! $this -> is_published ( $meta )) {
2018-10-31 19:17:42 +01:00
$all_media [] = new LBRY_Speech_Media ( $attachment_id , array ( 'image_size' => $size ));
2018-10-27 23:49:44 +02:00
}
2018-10-31 19:17:42 +01:00
}
}
2018-10-27 23:49:44 +02:00
2018-10-31 19:17:42 +01:00
$videos = $this -> parser -> scrape_videos ( $content );
2018-10-27 23:49:44 +02:00
2018-10-31 19:17:42 +01:00
$video_ids = array ();
foreach ( $videos as $video ) {
$new_id = $this -> parser -> get_attachment_id_from_tag ( 'mp4' , $video );
if ( $new_id ) {
$video_ids [] = $new_id ;
2018-10-26 09:43:34 +02:00
}
2018-10-26 01:30:24 +02:00
}
2018-10-27 21:28:20 +02:00
// Parse video tags based on wordpress shortcode for local embedds
2018-10-31 19:17:42 +01:00
foreach ( $video_ids as $attachment_id ) {
$meta = wp_get_attachment_metadata ( $attachment_id );
2018-10-27 21:28:20 +02:00
2018-10-31 19:17:42 +01:00
if ( ! $this -> is_published ( $meta )) {
$all_media [] = new LBRY_Speech_Media ( $attachment_id );
2018-10-26 09:43:34 +02:00
}
}
return $all_media ;
}
2018-10-27 23:49:44 +02:00
/**
2018-10-31 19:17:42 +01:00
* Checks meta to see if a spee . ch url exists
* @ param array $meta An array of meta which would possibly contain a speech_asset_url
* @ return boolean Whether or not its published to speech
2018-10-27 23:49:44 +02:00
*/
2018-10-31 19:17:42 +01:00
public function is_published ( $meta )
2018-10-27 23:49:44 +02:00
{
2018-11-09 19:34:12 +01:00
if ( key_exists ( LBRY_SPEECH_ASSET_URL , $meta ) && $meta [ LBRY_SPEECH_ASSET_URL ] !== '' ) {
2018-10-27 23:49:44 +02:00
return true ;
}
return false ;
}
2018-10-26 01:30:24 +02:00
/**
2018-10-29 23:51:18 +01:00
* Builds a cURL request to the Speech URL
2018-10-31 19:17:42 +01:00
* @ param string $method The method to call on the Speech API
* @ param array $params The Parameters to send the Speech API Call
* @ return string The cURL object pointer
2018-10-26 01:30:24 +02:00
*/
2018-10-29 23:51:18 +01:00
private function build_request ( $method , $params = array ())
2018-10-26 01:30:24 +02:00
{
$speech_url = get_option ( LBRY_SETTINGS )[ LBRY_SPEECH ];
// Die if no URL
if ( ! $speech_url ) {
2018-10-29 23:51:18 +01:00
return false ;
2018-09-14 02:42:38 +02:00
}
2018-10-26 01:30:24 +02:00
$address = $speech_url . '/api/claim/' . $method ;
// Send it via curl
$ch = curl_init ();
curl_setopt ( $ch , CURLOPT_URL , $address );
curl_setopt ( $ch , CURLOPT_POST , true );
curl_setopt ( $ch , CURLOPT_POSTFIELDS , $params );
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
curl_setopt ( $ch , CURLOPT_AUTOREFERER , false );
curl_setopt ( $ch , CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );
curl_setopt ( $ch , CURLOPT_SAFE_UPLOAD , true );
curl_setopt ( $ch , CURLOPT_HEADER , false );
2018-10-24 20:49:46 +02:00
2018-10-29 23:51:18 +01:00
return $ch ;
2018-09-14 02:42:38 +02:00
}
2018-09-01 01:50:29 +02:00
}