diff options
author | Andrew Dolgov <[email protected]> | 2019-08-12 18:28:55 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2019-08-12 18:28:55 +0300 |
commit | 81ce2ff5268812feebc51a6b8fa2c56998f783de (patch) | |
tree | 63cfc4903456161ad6fd0389e05b0a6e92f05a04 |
initial
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | init.php | 249 |
2 files changed, 250 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..33d58b2 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +git clone to ``plugins.local/af_zz_api_resize``. diff --git a/init.php b/init.php new file mode 100644 index 0000000..af7b77c --- /dev/null +++ b/init.php @@ -0,0 +1,249 @@ +<?php +class Af_Zz_Api_Resize extends Plugin { + + /* @var PluginHost $host */ + private $host; + + function about() { + return array(1.0, + "Resizes images as requested by API clients", + "fox"); + } + + function is_public_method($method) { + return $method === "api_resize"; + } + + function init($host) { + $this->host = $host; + + $host->add_hook($host::HOOK_RENDER_ARTICLE_API, $this); + //$host->add_hook($host::HOOK_ENCLOSURE_ENTRY, $this); + } + + function hook_enclosure_entry($enc) { + if (preg_match("/image/", $enc["content_type"])) { + $enc["content_url"] = $this->rewrite_url_if_needed($enc["content_url"]); + } + + return $enc; + } + + private function make_thumbnail($input_filename, $output_filename, $dim_max_x = 600, $dim_max_y = 600, $force_stamp = false) { + + $o_im = @imagecreatefromstring(file_get_contents($input_filename)); + + if ($o_im) { + $imageinfo = @getimagesizefromstring($input_filename); + + $o_width = imagesx($o_im) ; + $o_height = imagesy($o_im) ; + + if (max($o_width, $o_height) < max($dim_max_x, $dim_max_y)) { + $t_height = $o_height; + $t_width = $o_width; + } else { + if ($o_height > $o_width) { + $t_height = $dim_max_x; + $t_width = round($o_width/$o_height * $t_height); + } else { + $t_width = $dim_max_y; + $t_height = round($o_height/$o_width * $t_width); + } + } + + // print "$o_file : $t_file : $o_height * $o_width -> $t_height * $t_width<br>"; + + $t_im = imageCreateTrueColor($t_width, $t_height); + + if ($force_stamp || ($imageinfo && $imageinfo["mime"] == "image/gif")) { + $need_stamp = true; + $need_alpha = false; + + imageFill($t_im, 0, 0, 0xffffff); + } else { + $need_stamp = false; + if ($imageinfo && $imageinfo["mime"] == "image/png") { + $need_alpha = true; + + imagealphablending($t_im, false); + imagesavealpha($t_im, true); + } + } + + imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, + $t_width, $t_height, $o_width, $o_height); + + if ($need_stamp) { + $stamp = imagecreatefrompng('images/play-outline.png'); + + if ($stamp) { + $sx = imagesx($stamp); + $sy = imagesy($stamp); + + imagecopy($t_im, $stamp, + imagesx($t_im)/2 - $sx/2, + imagesy($t_im)/2 - $sy/2, + 0, 0, + imagesx($stamp), imagesy($stamp)); + } + } + + if ($need_stamp || !$need_alpha) + @imageJpeg($t_im, $output_filename, 75); + else + @imagePng($t_im, $output_filename, 5); + + imageDestroy($o_im); + imageDestroy($t_im); + } + } + + public function api_resize() { + + $url = rewrite_relative_url(get_self_url_prefix(), $_REQUEST["url"]); + $width = (int) $_REQUEST["width"]; + + $local_filename = CACHE_DIR . "/images/" . sha1($url); + $flag_filename = CACHE_DIR . "/images/" . sha1($url) . ".flag"; + $resized_filename = CACHE_DIR . "/images/" . sha1($url) . "-$width"; + + if (!file_exists($flag_filename) || !$width) { + header("Location: $url"); + return; + } + + header("Content-Disposition: inline; filename=\"".basename($local_filename)."\""); + + if (file_exists($local_filename) && filesize($local_filename) > 0) { + + if (file_exists($resized_filename) && filesize($resized_filename) > 0) + send_local_file($resized_filename); + else { + $this->make_thumbnail($local_filename, $resized_filename, $width, $width); + + if (file_exists($resized_filename) && filesize($resized_filename) > 0 && filesize($resized_filename) < filesize($local_filename)) + send_local_file($resized_filename); + else + send_local_file($local_filename); + } + + } else { + $data = fetch_file_contents(["url" => $url, "max_size" => MAX_CACHE_FILE_SIZE]); + + if ($data) { + + if (file_put_contents($local_filename, $data)) { + $mimetype = mime_content_type($local_filename); + header("Content-type: $mimetype"); + + /* MAKE RESIZED THUMBNAIL IF NEEDED, get local_filename, send it */ + + if (file_exists($resized_filename) && filesize($resized_filename) > 0) + send_local_file($resized_filename); + else { + $this->make_thumbnail($local_filename, $resized_filename, $width, $width); + + if (file_exists($resized_filename) && filesize($resized_filename) > 0 && filesize($resized_filename) < filesize($local_filename)) + send_local_file($resized_filename); + else + send_local_file($local_filename); + } + + } else { + print $data; + } + } else { + global $fetch_last_error; + global $fetch_last_error_code; + global $fetch_last_error_content; + + if (function_exists("imagecreate") && !isset($_REQUEST["text"])) { + $img = imagecreate(450, 75); + + /*$bg =*/ imagecolorallocate($img, 255, 255, 255); + $textcolor = imagecolorallocate($img, 255, 0, 0); + + imagerectangle($img, 0, 0, 450-1, 75-1, $textcolor); + + imagestring($img, 5, 5, 5, "Proxy request failed", $textcolor); + imagestring($img, 5, 5, 30, truncate_middle($url, 46, "..."), $textcolor); + imagestring($img, 5, 5, 55, "HTTP Code: $fetch_last_error_code", $textcolor); + + header("Content-type: image/png"); + print imagepng($img); + imagedestroy($img); + + } else { + header("Content-type: text/html"); + + http_response_code(400); + + print "<h1>Proxy request failed.</h1>"; + print "<p>Fetch error $fetch_last_error ($fetch_last_error_code)</p>"; + print "<p>URL: $url</p>"; + print "<textarea cols='80' rows='25'>" . htmlspecialchars($fetch_last_error_content) . "</textarea>"; + } + } + } + } + + function rewrite_url_if_needed($url, $width) { + if (strpos($url, "data:") !== 0) { + $flag_filename = CACHE_DIR . "/images/" . sha1($url) . ".flag"; + + @touch($flag_filename); + + return get_self_url_prefix() . "/public.php?op=pluginhandler&plugin=af_zz_api_resize&pmethod=api_resize&url=" . + urlencode($url) . "&width=" . $width; + } + + return $url; + } + + function hook_render_article_api($params) { + $need_saving = false; + $width = (int) clean($_REQUEST["resize_width"]); + + $doc = new DOMDocument(); + if (@$doc->loadHTML('<?xml encoding="UTF-8">' . $params["headline"]["content"])) { + $xpath = new DOMXPath($doc); + $imgs = $xpath->query("//img[@src]"); + + foreach ($imgs as $img) { + $new_src = $this->rewrite_url_if_needed($img->getAttribute("src"), $width); + + if ($new_src != $img->getAttribute("src")) { + $img->setAttribute("src", $new_src); + $img->removeAttribute("srcset"); + + $need_saving = true; + } + } + + $vids = $xpath->query("(//picture)"); + + foreach ($vids as $vid) { + $vsrcs = $xpath->query("source", $vid); + + foreach ($vsrcs as $vsrc) { + $new_src = $this->rewrite_url_if_needed($vsrc->getAttribute("src"), $width); + + if ($new_src != $vsrc->getAttribute("src")) { + $vid->setAttribute("src", $new_src); + + $need_saving = true; + } + } + } + } + + if ($need_saving) $params["headline"]["content"] = $doc->saveHTML(); + + return $params["headline"]; + } + + function api_version() { + return 2; + } +} |