Для преобразования ленты в свой, удобный формат, выбор пал на такой специализированный инструмент, как 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 читалке.
Бонусы:
- Пример использования Google Apps Script для автоматического перевода ленты на другой язык с помощью Google Translate
- Спецификация RSS 2.0
ссылка на оригинал статьи http://habrahabr.ru/post/175775/
Добавить комментарий