Создаем свой RSS канал с помощью Google Apps Script

от автора

Есть такой замечательный wiki ресурс по языку Tcl/Tk как wiki.tcl.tk. Есть у этого ресурса RSS лента последних изменений. Но вот беда — лента изменений самая минимальная. Там указано только кем, когда и какая страница редактировалась. Нет полных изменений и нет GUID у элементов ленты, поэтому некоторые RSS клиенты (например, Google Reader) не показывают большую часть новостей, считая их одинаковыми.

Для преобразования ленты в свой, удобный формат, выбор пал на такой специализированный инструмент, как Yahoo Pipes. Но тут постигла неудача. Для получения изменений странички, wiki строго требовала наличия cookie с именем «wikit_e» в http запросе, а научить Yahoo Pipes отсылать куки не получилось. Фокус с HTTP запросом GET и параметром в виде "?COOKIE=" так же не проходил.
В итоге, выбор пал на более гибкий инструмент — Google Apps Script. В итоге получился вот такой скрипт:

// Эта функция будет выполняться автоматически, при вызова скрипта как веб-приложения function doGet() {   // Задаем URL исходной RSS ленты   var feed = 'http://wiki.tcl.tk/rss.xml';      // Определяем ID для доступа к кэшу   var id = Utilities.base64Encode(feed);      // Определяем кэш и пробуем забрать уже собранную ленту из него   var cache = CacheService.getPublicCache();   var rss   = cache.get(id);      // Если в кэше лента не сохранена - переходим к ее созданию   if (rss == null) {     // Получаем данные RSS ленты в виде XML     var data = UrlFetchApp.fetch(feed).getContentText();     var doc = Xml.parse(data);     // Выбираем канал     var channel = doc.getElement().getElement("channel");      // Выбираем название канала, ссылку, описание ленты     var title = channel.getElement("title").getText();     var link = channel.getElement("link").getText();     var desc = channel.getElement("description").getText();     var guid, date;          // Начинаем создавать свою RSS ленту, заполняем название, ссылку и описание     rss = '<rss version="2.0">';     rss += "<channel>"     rss += "<title>" + title + "</title>\n";     rss += "<link>" + link + "</link>\n";     rss += "<description>" + desc + "</description>\n";          // Выбираем все элементы ленты и последовательно проходим по каждому     var items = channel.getElements("item");       for (var i in items) {       item  = items[i];              // Выбираем из ленты заголовок, ссылку, дату новости, описание       title = item.getElement("title").getText();       link  = item.getElement("link").getText();       // Ссылка должна указывать на diff странички       link  = link.replace(/\/(\d+)$/, "/_/diff?N=$1#diff0");       date  = item.getElement("pubDate").getText();       desc  = item.getElement("description").getText();       // Формируем GUID для элемента ленты             guid  = Utilities.base64Encode(link + date);        // Скачиваем diff страницы, используя при этом Cookie "wikit_e" как "rss"       var fullpage = UrlFetchApp.fetch(link, {"headers":{"Cookie":"wikit_e=rss"}}).getContentText();       // Вырезаем из страницы только body       var matched = fullpage.match(/<body[^>]*>([\w\W]*)<\/body>/i)[1];       // Вырезаем заголовки и подвал страницы       matched = matched.replace(/<div id='menu_area'>[\w\W]+$/i, "");       matched = matched.replace(/^[\w\W]+<div id='content'>/i, "");       // Заменяем относительные ссылки внутри документа на абсолютные       matched = matched.replace(/(href|src)=(["'])\//ig, "$1=$2http://wiki.tcl.tk/");       // Т.к. CSS в RSS не подключен, явно прописываем стили для элементов       matched = matched.replace(/class='newwikiline'/g, "style='margin:0;background:#80ff80;'");       matched = matched.replace(/class='oldwikiline'/g, "style='margin:0;background:#ffa0a0;'");       matched = matched.replace(/class='whitespacediff'/g, "style='margin:0;background:#f0f0ff;'");       matched = matched.replace(/class='wikit_categories'/g, "style='padding:2px 5px 2px 5px;text-align:left;border:1px solid gray;background-color:#DDD;'");       matched = matched.replace(/<pre>/g, "<pre style='color:#331100;background-color:#eeeeee;font-family:monospace;'>");              // Добавляем к нашей RSS ленте новость       rss += "<item>\n";       rss += "  <title>"   + title + "</title>\n";       rss += "  <link>"    + link  + "</link>\n";       rss += "  <pubDate>" + date  + "</pubDate>\n";       rss += "  <guid isPermaLink='false'>"    + guid  + "</guid>\n";       rss += "  <description><![CDATA[" + desc + "<br>\n" + matched + "]]></description>\n";       rss += "</item>\n";     };          // Завершаем создание RSS     rss += "</channel></rss>";          // Пробуем поместить нашу ленту в кэш сроком хранения 30 минут     // максимальный размер кэша - 100kb     // при превышении этого значения будет ошибка, игнорируем ее     try {       cache.put(id, rss, 1800);     } catch (e) {       Logger.log(e);     };   };      // Возвращаем клиенту нашу собранную ленту   return ContentService.createTextOutput(rss).setMimeType(ContentService.MimeType.RSS);    };

После сохранения скрипта, настраиваем уровень доступа как «Просмотреть элемент может любой пользователь, обладающий ссылкой» либо «Общедоступно в Интернете: найти и просмотреть элемент может любой пользователь». В меню «Файл->Версии…» создаем новую версию приложения. Далее, в меню «Публикация->Развернуть как веб-приложение…» выбираем сохраненную версию, в выпадающем списке «Как запускать приложение» выбираем «От моего имени», в выпадающем списке «Кто имеет доступ к приложению» выбираем «Все, включая анонимных пользователей». Получаем ссылку в виде "https://script.google.com/macros/s/<тут ID приложения>/exec", которую и используем в любой RSS читалке.

Бонусы:

  1. Пример использования Google Apps Script для автоматического перевода ленты на другой язык с помощью Google Translate
  2. Спецификация RSS 2.0

ссылка на оригинал статьи http://habrahabr.ru/post/175775/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *