summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2019-08-12 18:28:55 +0300
committerAndrew Dolgov <[email protected]>2019-08-12 18:28:55 +0300
commit81ce2ff5268812feebc51a6b8fa2c56998f783de (patch)
tree63cfc4903456161ad6fd0389e05b0a6e92f05a04
initial
-rw-r--r--README.md1
-rw-r--r--init.php249
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;
+ }
+}