Восстановление топиков из кеша поисковой ситемы Yandex

Доброго времени суток, хочу поделиться модулем для доставания содержимого топиков сайта из кеша Яндекса.

Я занимаюсь разработкой сайта на базе livestreet My Equipment и на днях случилась трагедия, упала база данных.
Подобное уже было у некоторых участников сообщества. И как оказалось мой хостер не делает бекапов, а у меня их не было. Вот и пришлось доставать топики за два месяца из кеша поисковой системы.

Так, как я особо раньше не углубляйся в код движка решил заодно и с ним познакомиться.

Задачи передо мной стояли следующие:
1) Получить и разобрать поисковую выдачу Яндекса на предмет страниц сохраненных в кеше
2) Разобрать содержимое текста страниц сохраненных в кеше Яндекса
3) Сохранить содержимое страниц в базу и при этом восстановить стары url страниц, что бы пользователи и поисковики находили их по старым адресам.

Ну что же вроде пока все просто и ясно. Открыв пример создания собственного модуля я начал писать.

Первое что я решил сделать, так это посмотреть, как можно сохранить страницу с заданным идентификатором. Оказалось такой функции нет. Тогда я решил подправить исходники. Слава богу, что код открытый. Использую я Livestreet версии 0.3 по этому инструкции будут для этой версии движка.

1) Идем в модуль топиков (classes\modules\topic\Topic.class.php)

Находим объявление функции AddTopic, у меня это 44 строка

public function AddTopic(TopicEntity_Topic $oTopic)


Меняем на

public function AddTopic(TopicEntity_Topic $oTopic,$needId=null) 

Что бы можно было вставлять записи с заданным идентификатором
2) Нужно немного поменять маппер модуля для топиков (classes\modules\topic\mapper\Topic.mapper.class.php )
Ищем функцию AddTopic (у меня это 44 строка)

	public function AddTopic(TopicEntity_Topic $oTopic) {
		$sql = "INSERT INTO ".DB_TABLE_TOPIC." 
			(blog_id,
			user_id,
			topic_type,
			topic_title,			
			topic_tags,
			topic_date_add,
			topic_user_ip,
			topic_publish,
			topic_publish_draft,
			topic_publish_index,
			topic_cut_text,
			topic_forbid_comment,			
			topic_text_hash
			)
			VALUES(?d,  ?d,	?,	?,	?,  ?, ?, ?d, ?d, ?d, ?, ?, ?)
		";			
		if ($iId=$this->oDb->query($sql,$oTopic->getBlogId(),$oTopic->getUserId(),$oTopic->getType(),$oTopic->getTitle(),
			$oTopic->getTags(),$oTopic->getDateAdd(),$oTopic->getUserIp(),$oTopic->getPublish(),$oTopic->getPublishDraft(),$oTopic->getPublishIndex(),$oTopic->getCutText(),$oTopic->getForbidComment(),$oTopic->getTextHash())) 
		{
			$oTopic->setId($iId);
			$this->AddTopicContent($oTopic);
			return $iId;
		}		
		return false;
	}


Меняем её на
public function AddTopic(TopicEntity_Topic $oTopic,$needId=null) {
        if($needId==null)
        {
            $sql = "INSERT INTO ".DB_TABLE_TOPIC." 
                (blog_id,
                user_id,
                topic_type,
                topic_title,
                topic_tags,
                topic_date_add,
                topic_user_ip,
                topic_publish,
                topic_publish_draft,
                topic_publish_index,
                topic_cut_text,
                topic_forbid_comment,
                topic_text_hash
                )
                VALUES(?d,  ?d,	?,	?,	?,  ?, ?, ?d, ?d, ?d, ?, ?, ?)
            ";
            if ($iId=$this->oDb->query($sql,$oTopic->getBlogId(),$oTopic->getUserId(),$oTopic->getType(),$oTopic->getTitle(),
                $oTopic->getTags(),$oTopic->getDateAdd(),$oTopic->getUserIp(),$oTopic->getPublish(),$oTopic->getPublishDraft(),$oTopic->getPublishIndex(),$oTopic->getCutText(),$oTopic->getForbidComment(),$oTopic->getTextHash()))
            {
                $oTopic->setId($iId);
                $this->AddTopicContent($oTopic);
                return $iId;
            }
        }else
        {
            $sql="select count(*) as cnt from ".DB_TABLE_TOPIC." where topic_id='".$needId."'";
            $aRow=$this->oDb->query($sql);
            //echo $needId;
            //print_r($aRow);
            if($aRow[0]['cnt']>0)
            {
                return false;                
            }

            $sql = "INSERT INTO ".DB_TABLE_TOPIC."
                (blog_id,
                user_id,
                topic_type,
                topic_title,
                topic_tags,
                topic_date_add,
                topic_user_ip,
                topic_publish,
                topic_publish_draft,
                topic_publish_index,
                topic_cut_text,
                topic_forbid_comment,
                topic_text_hash,
                topic_id
                )
                VALUES(?d,  ?d,	?,	?,	?,  ?, ?, ?d, ?d, ?d, ?, ?, ?,?d)
            ";
            if ($iId=$this->oDb->query($sql,$oTopic->getBlogId(),$oTopic->getUserId(),$oTopic->getType(),$oTopic->getTitle(),
                $oTopic->getTags(),$oTopic->getDateAdd(),$oTopic->getUserIp(),$oTopic->getPublish(),$oTopic->getPublishDraft(),$oTopic->getPublishIndex(),$oTopic->getCutText(),$oTopic->getForbidComment(),$oTopic->getTextHash(),$needId))
            {
                $oTopic->setId($needId);
                $this->AddTopicContent($oTopic);
                return $needId;
            }
        }
		return false;
	}


3) Возвращаемся к функции в файле classes\modules\topic\Topic.class.php AddTopic
и меняем в ней первую строчку с

if ($sId=$this->oMapperTopic->AddTopic($oTopic)) {

на

if ($sId=$this->oMapperTopic->AddTopic($oTopic,$needId)) {


Вот теперь у нас есть возможность вставлять топик с нужным идентификатором, если имеется запись в базе с таким же идентификатором, то она не будет перезаписана.

Теперь все готово к установке модуля. Сразу хочу заметить, что модуль не локализован и весь текст напрямую вшит в шаблоны. Так же он работает очень долго, что бы не привлекать внимание Яндекса, но это настраиваемо.

Для того что бы его установить:
1) Скачиваем его отсюда
2) Прочитать файл readme из скаченного архива.
3) Установить модуль и восстановить потерянные топики.

Он достанет по возможности все топики, которые в кеше поисковика. Расставит каты, выставит нужные даты, названия блогов и пользователей. Для работы этого модуля нужен:curl, mb_string, iconv. Надеюсь он будет полезен не только мне. Спасибо за внимание.

7 комментариев

avatar
что за хостер такой?
  • ozz
  • 0
avatar
Американский, у них там кризис, видимо места на серверах не хватает
avatar

avatar
Нее, я бабочек не использую. Модуль написаны в стандартной IDE
avatar
Я не о IDE, а о способе (месте) хранения данных.
avatar
Админы делятся на две группы: те кто еще не делает бекапов и те кто их уже делает. Вот после этого я перешел из 1 группы во 2.

А так поступил потому, что нужно было спасать положение. Вот и спас.
avatar
залейте пожалуста снова модуль ссыль сдохла
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.