Установка скриншотов в каталоге на движке CNCat
17 ноября 2009 года
Установка скриншотов в каталоге на движке CNCat
Мне часто приходят письма с вопросами о скриншотах сайтов в каталоге cat.codenet.ru и мне всегда трудно было ответить на эти вопросы. Главная причина тому - постоянно меняющийся механизм генерации изображений. Изначально он был реализован на Borland C++ Builder с использованием Internet Explorer. Это связка проработала больше года, но из-за нестабильности пришлось от нее отказаться.
Вторая реализация была выполнена под Linux - Perl + Firefox. Стабильности прибавилось, но возникла вторая проблема, которая в корне изменила мой подход к этому вопросу - и проблема эта - большой входящий трафик. А хостинг-провайдеры очень не любят входящий трафик.
В итоге посчитав стоимость генерации одного скриншота и изучив предложения на рынке генерации я пришел к вводу что проще и дешевле велосипед купить, нежели изобрести.
Я изучил порядка десяти сервисов, как платных, так и бесплатных. Вот основные критерии по которым я делал отбор:
- Качество отображения скриншота. Отображение русских букв, правильный рендеринг страниц, корректное отображение Flash.
- API. Возможность построение полностью автоматизированной системы с использование оповещения (callback).
В итоге я остановился на сервисе http://webthumb.bluga.net/. API этого сервиса более менее описано на этой странице.
Теперь собственно о системе. Она построена из двух PHP скриптов - request.php и ipn.php.
Задача первого (request.php) - получить список URL сайтов из таблиц CNCat, на его базе построить список URL сайтов для которых необходимо построить скриншоты и отправить запрос на построение на сервис webthumb.bluga.net.
Задача второго (ipn.php) - скачать готовый скриншот и сохранить его на сервере. Этот скрипт вызывается сервисом генерации скриншотов по факту готовности скриншота.
Скачать исходный код: cncat-screenshots.zip (3Кб;zip). Если вы не хотите разбираться с кодом, то можете сразу перейти к инструкции по установке.
Описание аддона
config.php
Конфигурационный файл содержит основные параметры, которые изменяются в зависимости от настроек сервера и сервиса генерации скриншотов.
<?php // Секретная строка. Используется для того, чтобы // злоумышленники не смогли сымитировать сервис // генерации скриншотов $hash = "adhj3fhjj3d"; // Secret key // Полный адрес callback скрипта ipn.php $notify_url = "http://cat.codenet.ru/screenshots/ipn.php"; // Notify URL // Ширина картинки скриншота $width = 120; // Высота картинки скриншота $height = 160; // Хост API сервиса $post_host = "webthumb.bluga.net"; // Порт API сервиса $post_port = 80; // URI API сервиса $post_uri = "/api.php"; // Лог файл запросов на генерацию и ответов сервиса $logfile = "/tmp/screenshots-request.log"; // API ключ $apikey = "00000000000000000000000000000000"; // Первая часть адреса откуда можно скачать // готовый скриншот $url_prefix = "http://webthumb.bluga.net/data/"; // Вторая часть адреса откуда можно скачать // готовый скриншот. От этого параметра зависит // какого размера в каком формате буде скачан // скриншот. Подробности в описании API сервиса. $url_postix = "-thumb_medium.png"; // Каталог в котором хранятся файлы скриншотов. $output_directory = dirname(__FILE__)."/files/"; // Лог файл скрипта оповещений $ipn_logfile = "/tmp/screenshots-ipn.log"; ?>
request.php
Запрос скриншотов. Этот файл запускается по расписанию, с помощью crontab. простой строки.<?php include "../cncat_config/config.php"; include "config.php"; @mysql_connect($CNCAT["config"]["db"]["host"], $CNCAT["config"]["db"]["user"], $CNCAT["config"]["db"]["password"]); if (0==mysql_errno()) { @mysql_select_db($CNCAT["config"]["db"]["name"]); if (0==mysql_errno()) { $r=@mysql_query("SELECT item_id, link_url FROM ".$CNCAT["config"]["db"]["prefix"]."items WHERE item_status=1 AND item_type=0;"); if ($r) { $request=""; $count=0; while ($a=mysql_fetch_assoc($r)) { if (!is_file($output_directory.$a["item_id"].".png")) { if ("http://"==substr($a["link_url"],0,7)) $url=substr($a["link_url"],7); else $url=$a["link_url"]; $request.=" <request> <url>".htmlspecialchars($url)."</url> <outputType>png</outputType> <width>1280</width> <height>1024</height> <fullthumb>1</fullthumb> <customThumbnail width=\"".$width."\" height=\"".$height."\" /> <delay>5</delay> <notify>".$notify_url."?siteid=".$a["item_id"]."&secret=".$hash."</notify> </request> "; $count++; } } if ($count!=0) { $request="<webthumb>\n<apikey>".$apikey."</apikey>".$request."</webthumb>"; $fp = fsockopen($post_host,$post_port); $headers="POST ".$post_uri." HTTP/1.1\r\n"; $headers.="Host: ".$post_host."\r\n"; $headers.="Content-Length: ".strlen($request)."\r\n"; $headers.="Content-Type: text/plain; charset=utf-8; charset=UTF-8\r\n"; $headers.="\r\n"; fwrite($fp,$headers); fwrite($fp,$request); $resp=""; while (!feof($fp)) { $resp.=fread($fp,1024); } fclose($fp); } else { $resp="Nothing to do\n"; } $fw=fopen($logfile,"ab"); if ($fw) { fputs($fw,"-------[ ".date("r")."]-----------\n"); fputs($fw,$resp."\n\n"); fclose($fw); } } else { die("Query error: ".mysql_error()); } } else { die("Can't select MySql database: ".mysql_error()); } } else { die("Can't connect to MySql: ".mysql_error()); } ?>
ipn.php:
<?php include "config.php"; if ($_GET["secret"]!=$hash) exit; $log=date("r")." "; $siteid=intval($_GET["siteid"]); $id=urlencode($_GET["id"]); $url=$url_prefix.substr($id,-2)."/".substr($id,-4,-2)."/".substr($id,-6,-4)."/".$id.$url_postix; $log.=$url." "; $d=file_get_contents($url); $filename=$output_directory.$siteid.".png"; $log.=$filename; $fw=fopen($filename,"wb"); if ($fw) { fwrite($fw,$d); fclose($fw); } $log.="\n"; $fl=fopen($ipn_logfile,"ab"); if ($fl) { fputs($fl,$log); fclose($fl); } ?>
Инструкция по установке аддона
- Распакуйте файлы аддона в каталог cncat/screenshots/;
- Дайте серверу доступ на запись в каталог cncat/screenshots/files (обычно "chgrp www files;chmod g+w files");
- Зарегистрируйтесь на сервисе webthumb.bluga.net, получите API ключ. Укажите его в файле config.php;
- Проверьте и отредактируйте необходимые настройки в файле config.php;
- Добавьте обращение к скрипту cncat/screenshots/request.php в crontab. Например вот так:
2 15 1 * * wget --quiet -O=- http://path.to/screenshots/request.php >/dev/null
- Проверьте правильность генерации скриншотов прямым обращением к http://path.to/screenshots/request.php и контролем лог файлов (имен лог файлов указываются в файле config.php).
Вроде все. Нужно понимать что это не окончательное решение и для его адаптации под нужды конкретного каталога может потребоваться правка кода. Статья рассчитана на то что вы разбираетесь в PHP и способны изменить логику работы самостоятельно. Все что описано тестировалось с CNCat 4.1.3 и 4.3.2.
Вопросы можно задать через форму обратной связи.