/**
* @class de_epages.presentation
*
*/
* Load an parse a rss file.
*
* The `de_epages.presentation.Rss()` method checks if the content of the given file is already stored on the epages server or if it
* has to be loaded. Then the feed data is parsed and the callback function is called with the parsed data.
*
* The data for the callback function is in the following format:
*
* data: {
* description: '',
* items: [
* {
* link : '',
* pubDate: '',
* text: '',
* textEncoded,
* title: '',
* audio: [],
* image: [],
* video: []
* }
* ],
* logo: {
* link : '',
* src : '',
* title: ''
* },
* name: '',
* pageLink: '',
* pubDate: '',
* version: ''
* }
*
* ### Dependencies
*
* + `de_epages`
* + `jQuery.class`
* + `ep.ajax`
*
* @param {String} url The url of the rss feed which should be loaded and parsed.
* @param {Function} function(data) Callback function which is called with the parsed data after the feed is loaded.
* @param {Boolean} [fullPath] Is the feed stored under it url on the server or is it stored under RSSFeeds inside epages
*
* @method Rss
* @static
* @member de_epages.presentation
*
* @since 6.11.0
*/
/*
* @copyright © Copyright 2006-2010, epages GmbH, All Rights Reserved.
*
* @module de_epages.presentation.rss
*/
define("de_epages/presentation/rss", [
"jquery",
"ep",
"de_epages",
"class",
"ep/ajax"
], function ($, ep, de_epages, Class) {
var mediaExpr = /(audio|image|video)/;
Class('de_epages.presentation.Rss', {
RSSCallbackFunc: null,
constructor: function( url, callbackFunc, fullPath ){
//if fullPath is given we dont need to change the rss path
this.RSSCallbackFunc = callbackFunc;
this.requestFile(url,fullPath);
},
requestFile: function(url,fullPath){
//check if file is already stored on server
var fileURL = url;
if(!fullPath){
fileURL = '/WebRoot/RssFeeds/'+url.replace(/[^A-Za-z0-9]/g,"_")+'.xml';
}
ep.ajax({
dataType: 'xml',
url: fileURL,
type: 'GET',
context: this
})
.done(function(data, textStatus, XMLHttpRequest){
this.readResponse(data);
})
.fail(function(data, textStatus, XMLHttpRequest){
this.requestFeed(url);
});
},
requestFeed: function(url){
//file is not stored on server ask server to fetch it
ep.ajax({
dataType: 'xml',
data: {
'ObjectID' : ep.config.siteId,
'ChangeAction': 'GetFeed',
'feedurl': url
},
context: this
})
.done(function(data, textStatus, XMLHttpRequest){
this.readResponse(data);
})
.fail(function(data, textStatus, XMLHttpRequest){
//if the second request although fails we do nothing
});
},
readResponse: function(data){
var itemname,
subtitle,
content,
logo,
date,
xmlData = $(data);
var feedData = {
'version': null,
'name': null,
'description': null,
'pageLink': null,
'pubDate': null,
'logo': {
'src': null,
'link': null,
'title': null
},
'items': null
};
//rss feed type detection
if(xmlData.find('rss').length){
//RSS
feedData.version = 'RSS';
itemname = 'item';
subtitle = 'description';
content = 'description';
logo = 'image';
date = 'pubDate';
}
else if(xmlData.find('feed').length){
//ATOM
feedData.version = 'ATOM';
itemname = 'entry';
subtitle = 'subtitle';
content = 'summary';
logo = 'logo';
date = 'updated';
}
//jquery has problems with xml namespaces see: http://bugs.jquery.com/ticket/155
else if(xmlData.find('rdf\\:RDF').length || xmlData.find('RDF').length){
//RDF
feedData.version = 'RDF';
itemname = 'item';
subtitle = 'description';
content = 'description';
logo = 'image';
//date = 'date'; //dc\\:date is the correct tag but we have to use only date because of the bug http://bugs.jquery.com/ticket/155
date = (xmlData.find('dc\\:date')[0] !== undefined)? "dc\\:date" : "date";
}
else{
//no valid feed
return false;
}
//detect name of feed
feedData.name = xmlData.find('title:first').text();
//detect description
var feedDesciption = xmlData.find(subtitle + ':first');
feedData.description = feedDesciption.length ? feedDesciption.text() : xmlData.find('tagline:first').text();
//detect link to feeds source page
var firstLink = xmlData.find('link:first');
feedData.pageLink = firstLink.text();
if(!feedData.pageLink){
var pageLink = xmlData.find('link[rel="alternate"]:first');
feedData.pageLink = pageLink.length ? pageLink.attr('href') : firstLink.attr('href');
}
//detect logo of feed
var firstLogoNode = xmlData.find(logo+':first');
var logoNode = firstLogoNode.length ? firstLogoNode : xmlData.find('icon:first');
if(logoNode.length){
var logoSrc = logoNode.find('url');
feedData.logo.src = logoSrc.length ? logoSrc.text() : logoNode.text();
if(!feedData.logo.src && logoNode[0].attributes[0]){
feedData.logo.src = logoNode[0].attributes[0].value;
}
var logoTitle = logoNode.find('title');
feedData.logo.title = logoTitle.length? logoTitle.text() : feedData.name;
var logoLink = logoNode.find('link');
feedData.logo.link = logoLink.length ? logoLink.text() : feedData.pageLink;
}
//detect date
feedData.pubDate = xmlData.find(date + ':first').text();
if(feedData.pubDate){
var pareDateString = feedData.pubDate;
feedData.pubDate = new Date(feedData.pubDate);
//internet explorers date function can not pare ISO 8601 strings so we have to do it on our own
if(isNaN(feedData.pubDate)){
feedData.pubDate = new Date(pareDateString.substr(0,19).replace(/-/g,"/").replace(/[TZ]/g," "));
}
}
var items = [];
xmlData.find(itemname).each(function(index, elm){
var item = {};
var tmpElm = $(elm);
//get title of news
item.title = tmpElm.find('title:first').text();
//get link of news
if(feedData.version == 'ATOM'){
var linkNode = tmpElm.find('link[rel="alternate"]:first');
item.link = linkNode.length ? linkNode.attr('href') : tmpElm.find('link:first').attr('href');
}
else{
var linkNode =tmpElm.find('link:first');
item.link = linkNode.length ? linkNode.text() : feedData.pageLink;
}
//get content of news
var textNode = tmpElm.find(content + ':first');
item.text = textNode.length ? textNode.text() : tmpElm.find('content:first').text();
if(!item.text){
textNode = tmpElm.find('content\\:encoded:first');
item.text = textNode.length ? textNode.text() : '';
}
else{
textEncodedNode = tmpElm.find('content\\:encoded:first');
item.textEncoded = textEncodedNode.length ? textEncodedNode.text(): tmpElm.find('encoded').text();
}
//get media elements of news
item.audio = [];
item.image = [];
item.video = [];
if(feedData.version == 'RSS'){
tmpElm
.find('enclosure')
.each(function(){
var elem = $(this),
type = elem
.attr('type')
.replace(/\/.*$/,'');
if( mediaExpr.test(type) ){
item[ type ].push( elem.attr('url') );
}
});
}
//get pubDate if given
var pubDateNode = tmpElm.find('pubDate:first');
item.pubDate = pubDateNode.length ? pubDateNode.text() : tmpElm.find('published:first').text();
if(item.pubDate){
item.pubDate = new Date(item.pubDate);
}
items.push(item);
});
feedData.items = items;
//give data to callback function
this.RSSCallbackFunc(feedData);
return true;
}
});
return de_epages;
});