Перенос мероприятий из Контакта на сайт под Drupal


Возникла задача - переносить мероприятия (они же события) из социальной сети Вконтакт на сайт под друпалом.

После некоторых поисков и размышлений на эту тему, нашлось два модуля под друпал - Node import и Node import via cron.

  • Node import - позволяет импортировать разные данные из CSV, TXT и т.д. в Drupal
  • Node import via cron - позволяет автоматизировать импорт данных по расписанию, т.е. по крону

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

Т.к. PHP не знал, да еще и забыл полностью, а как при этом еще и с сайтами работают, представление имею очень слабое, то на написание скрипта ушло около суток и скрипт получился не очень красивым. Зато вполне четко работающий.

Что скрипт делает:

  • Анализирует список всех мероприятий с заданных страниц социальной сети Вконтакт
  • Получает заголовок, время начала, аватарку и маленькие фотографии мероприятия
  • Немного форматировать текст мероприятия в более красивый вид
  • В начала текста вставляет аватарку мероприятия
  • В конце текста вставляет все фотографии мероприятия

Чего скрипт не умеет делать и с чем бывают проблемы:

  • Скачивать фотографии и копировать у нужную папку - постараюсь исправить.
  • В некоторых местах вырезает кавычки - если руки дойдут, тоже постараюсь исправить, но второстепеннее

#!/usr/local/bin/php

<?php
$user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2.13) ' .
           'Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)';
$cookie = '';

$login = 'your_login';
$password = 'your_passwd';
$file_event="event_old_list.txt";

$page_list[]='http://vkontakte.ru/groups?tab=inv';

$ch = curl_init();

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, 'http://login.vk.com/?act=login');
$post = array(
           'act' => 'login',
           'q' => '',
           'al_frame' => '1',
           'expire' => '',
           'captcha_sid' => '',
           'captcha_key' => '',
           'from_host' => 'vkontakte.ru',
           'email' => $login,
           'pass' => $password
       );

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$answer = curl_exec($ch);
$sid = substr($answer, strpos($answer, "setCookieEx('sid', '") + 20, 60);
$cookie = 'remixsid=' . $sid;
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
curl_setopt($ch, CURLOPT_URL, 'http://vkontakte.ru/');
$answer = curl_exec($ch);

$event_list=array();
foreach($page_list as $cur_page)
       $event_list = array_merge($event_list,event_get_from_page($ch,$cur_page));
$event_list=event_get_new($event_list,$file_event);
event_list_save($event_list,$file_event);

foreach($event_list as $ae)
{
       $url='http://vkontakte.ru/'.$ae;
       curl_setopt($ch, CURLOPT_URL, $url);
       $answer = curl_exec($ch);
       $answer=iconv("CP1251//IGNORE","KOI8-R//IGNORE",$answer);
       $event_html=explode("\n",$answer);
       $event["link"]=$url;
       $event["title"]=html_entity_decode(get_title($event_html));
       $event["avatar"]=get_avatar($event_html);
       $event["descriptions"]=html_entity_decode(get_descriptions($event_html));
       $event["time"]=get_time($event_html);
       $event["photo"]=get_photo($event_html);
# Тут выбрать нужно ли перекодировать результат и из какой кодировки.
#       echo event_print($event)."\n";
#       echo iconv("KOI8-R", "UTF-8", event_print($event))."\n";
}
$answer = curl_exec($ch);
curl_close($ch);

////////////////////////////////////////////////////////////////////////////
//   Используемые функции.
//  Получение заголовка из текста
function get_title($html)
{
       foreach($html as $ae)
               if(preg_match("/top_header..(.*)<.div/", $ae,$matches))
                       return $matches[1];
}

//  Получения ссылки на аватар события
function get_avatar($html)
{
       foreach($html as $key => $ae)
               if(preg_match("/group_avatar/", $ae,$matches))
                       if(preg_match("/(http:\/\/.*\.jpg)/", $html[$key+1],$matches))
                               return $matches[1];
}

// Получение описания события
function get_descriptions($html)
{
    foreach($html as $key => $ae)
       if(preg_match("/Описание:/", $ae,$matches))
          if(preg_match("/class=\"labeled fl_l\">(.*)<\/div>/", $html[$key+1],$matches))
             {
// Удаляем короткий вид, если есть полный.
                $str=preg_replace("/.*<a href=\"\" onclick.*unshown\">/","",$matches[1]);
// Выделяем жирным те строки которые считаем необходимыми
                $text_b[]="Начало";
                $text_b[]="Вход";
                $text_b[]="Билет";

                foreach($text_b as $text_b_cur)
                {
                     if(preg_match("/($text_b_cur.*<.*>)/",$str))
                          $str=preg_replace("/($text_b_cur.*<.*>)/","<strong>\${1}</strong>",$str);
                     else
                          $str=preg_replace("/($text_b_cur.*)/","<strong>\${1}</strong>",$str);
                }
// Меняем форматирование немного
                $str=preg_replace("/<span>/","",$str);
                $str=preg_replace("/<br><br>/","</p><p>",$str);
                $str=preg_replace("/<\/span>/","",$str);
                $str=preg_replace("/<span class=\"short_text\">/","",$str);
                return $str;
             }
}


// Получение времени начала события
function get_time($html)
{
       foreach($html as $key => $ae)
               if(preg_match("/Начало:/", $ae,$matches))
                       if(preg_match("/class=\"labeled fl_l\">(.*)<\/div/", $html[$key+1],$matches))
       {
               $matches=explode(" ",$matches[1]);
               if (count($matches)==4)
                       return $matches[0]."/".$matches[1]."/".date('Y')." - ".$matches[3];
               else
                       return $matches[0]."/".$matches[1]."/".$matches[2]." - ".$matches[4];
       }
}

// Получение ссылок на маленьких фотографии с события
function get_photo($html)
{
$start_position=0;
$end_position=0;
$link=array();
       foreach($html as $key => $ae)
       {
               if(preg_match("/group_photos_table/", $ae,$matches))
               {
                       $start_position=$key;
               }
               if (($start_position > 0) &&(preg_match("/div/", $ae)) )
               {
                       $end_position=$key;
                       break;
               }
       }

       for (;$start_position<$end_position;$start_position++)
       {
               if(preg_match("/x_src: &quot;(http:\/\/.*\.jpg)&quot;, y_src:/", $html[$start_position],$matches))
                       $link[]=$matches[1];
       }
       return $link;
}

// Вывод события в строку
function event_print($event)
{
       $result=$event["link"].",";
// В заголовок добавляем день и месяц
       $str=explode("/",$event["time"]);
       $body=$str[0]." ".$str[1]." / ".$event["title"];
// Заменяем кавычки на двойные кавчки
       $body=str_replace('"','""',$body);
       $result=$result."\"".$body."\",";
// Формируем основной текст публикации
$body="<p><img alt=\"".$event["title"]."\" src=\"".$event["avatar"]."\" style=\"float: left; margin-left: 10px; margin-right: 10px;\">";
// Вставляем ссылку на оригинал и вставляем отделение анонса (тизера) от фотографий.
$body=$body.$event["descriptions"]."</p><p>Ссылка на <a href=\"".$event["link"]."\">событие во Вконтакте</a>.</p><!--break-->";
// Выводим фотографии под кат.
        if (count($event["photo"])>0)
               foreach($event["photo"] as $ae)
                       $body=$body."<p><img alt=\"".$event["title"]."\" src=\"".$ae."\" style=\"width: 100%; height: 100%; float: left; margin-left: 10px; margin-right: 10px; margin-bottom: 10px; margin-top: 10px;\"></p>";

$body=str_replace('"','""',$body);
$result=$result."\"".$body."\",";
 
// Выводим время публикации
$result=$result.",";
       $result=$result.month2dig($event["time"]).",";
// При наличии фотографий, выводим ссылки на них списком
if (count($event["photo"])>0)
               foreach($event["photo"] as $ae)
                       $result=$result.$ae." ";
return $result;
}

// Переводим из буквенного названия месяца в числовой
function month2dig($str,$separate='/')
{
$month = array(
'01' => 'января',
'02' => 'февраля',
'03' => 'марта',
'04' => 'апреля',
'05' => 'мая',
'06' => 'июня',
'07' => 'июля',
'08' => 'августа',
'09' => 'сентября',
'10' => 'октября',
'11' => 'ноября',
'12' => 'декабря'
);
               $str=explode($separate,$str);
               $str[1] = array_search($str[1],$month);
               return $str[0]."/".$str[1]."/".$str[2];
}
 
// Получаем список только новых событий.
function event_get_new($event_list,$event_list_file)
{
       $event_list=array_unique($event_list);
       sort($event_list);

// Получаем и сортируем старый список событий
       $event_list_old=explode(" ",rtrim(file_get_contents($event_list_file)));
       sort($event_list_old);

       $event_list_new=array_diff($event_list,$event_list_old);
       return $event_list_new;

}
// Сохраняем список обработанных мероприятий.
function event_list_save($event_list,$event_list_file)
{
       $event_list_old=array_unique(explode(" ",rtrim(file_get_contents($event_list_file))));
       sort($event_list_old);
       file_put_contents($event_list_file, join(' ', $event_list_old)." add ".join(' ', $event_list));
}
 
// Получаем список всех мероприятий со страницы во Вконтакте
function event_get_from_page($ch,$url_page)
{
       curl_setopt($ch, CURLOPT_URL, $url_page);
       $answer = curl_exec($ch);
       $html = explode("\n",$answer);
       foreach($html as $html_string)
               if(preg_match("/(event\d{3,})/", $html_string,$matches)) $event_list[]=$matches[1];
       return $event_list;
}
?>