Commit 27bf78f6 authored by Alain Takoudjou's avatar Alain Takoudjou

add jio rss feed and opml storage

opml and rss feed are splitted into two differents jio storages
parent 754e5df9
......@@ -180,7 +180,9 @@ module.exports = function (grunt) {
'src/jio.storage/localstorage.js',
'src/jio.storage/indexeddbstorage.js',
'src/jio.storage/cryptstorage.js',
'src/jio.storage/websqlstorage.js'
'src/jio.storage/websqlstorage.js',
'src/jio.storage/rssfeedstorage.js',
'src/jio.storage/opmlstorage.js'
],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
// dest: 'jio.js'
......
/*
* Copyright 2016, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint nomen: true*/
/*global jIO, RSVP, DOMParser */
(function (jIO, RSVP, DOMParser) {
"use strict";
var dummy = {getAttribute: function () { return; }};
function getOpmlOutlineAsDict(outline) {
var outline_dict = {
title: outline.getAttribute('title') || '',
htmlurl: outline.getAttribute('htmlUrl') || '',
xmlurl: outline.getAttribute('xmlUrl') || '',
url: outline.getAttribute('url') || '',
text: outline.getAttribute('text') || '',
type: outline.getAttribute('type') || '',
version: outline.getAttribute('version') || '',
created: outline.getAttribute('created') || '',
category: outline.getAttribute('category') || ''
};
return outline_dict;
}
function getOpmlDocumentId(outline) {
return outline.getAttribute('url') ||
outline.getAttribute('htmlUrl') ||
outline.getAttribute('xmlUrl') || '';
}
function getOpmlHeadAsDict(doc) {
var element;
function getElementsByTagName(name) {
return (doc.getElementsByTagName(name)[0] || dummy).textContent;
}
element = {
opml_title: getElementsByTagName('title'),
create_date: getElementsByTagName('dateCreated'),
modified_date: getElementsByTagName('dateModified'),
owner_name: getElementsByTagName('ownerName'),
owner_email: getElementsByTagName('ownerEmail'),
opml_link: getElementsByTagName('link')
};
return element;
}
function getOpmlElement(doc, id) {
var outline_list = doc.getElementsByTagName('outline'),
i,
max,
element = getOpmlHeadAsDict(doc);
for (i = 0, max = outline_list.length; i < max; i += 1) {
if (outline_list[i].getAttribute('htmlUrl') === id ||
outline_list[i].getAttribute('xmlUrl') === id ||
outline_list[i].getAttribute('url') === id) {
Object.assign(element, getOpmlOutlineAsDict(outline_list[i]));
break;
}
}
return element;
}
function getOpmlElementList(doc, options) {
var i,
max,
tmp_id,
push_method,
opml_head = {},
opml_list = [],
outline_list = doc.getElementsByTagName('outline');
if (options.include_docs === true) {
opml_head = getOpmlHeadAsDict(doc);
push_method = function (id, outline) {
var element = getOpmlOutlineAsDict(outline);
Object.assign(element, opml_head);
opml_list.push({
"id": id,
"value": {},
"doc": element
});
};
} else {
push_method = function (id) {
opml_list.push({
"id": id,
"value": {}
});
};
}
for (i = 0, max = outline_list.length; i < max; i += 1) {
if (!outline_list[i].hasChildNodes()) {
tmp_id = getOpmlDocumentId(outline_list[i]);
if (tmp_id !== '') {
push_method(tmp_id, outline_list[i]);
}
}
}
return opml_list;
}
function parseOpmlFeed(feed_url, id, options) {
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
type: "GET",
url: feed_url,
dataType: "text"
});
})
.push(function (response) {
var element,
result;
element = new DOMParser().parseFromString(
response.target.responseText,
"text/xml"
);
if (id !== undefined && id !== null) {
result = getOpmlElement(element, id);
if (result === undefined) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return result;
}
if (!options) {
options = {};
}
return getOpmlElementList(element, options);
}, function (error) {
if ((error.target !== undefined) &&
(error.target.status === 404)) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
throw error;
});
}
/**
* The JIO OPML Storage extension
*
* @class OPMLStorage
* @constructor
*/
function OPMLStorage(spec) {
if (typeof spec.url !== 'string') {
throw new TypeError("OPMLStorage 'url' is not of type string");
}
this._url = spec.url;
}
OPMLStorage.prototype.get = function (id) {
return parseOpmlFeed(this._url, id);
};
OPMLStorage.prototype.hasCapacity = function (capacity) {
return (capacity === "list") || (capacity === "include");
};
OPMLStorage.prototype.buildQuery = function (options) {
return parseOpmlFeed(this._url, undefined, options);
};
jIO.addStorage('opml', OPMLStorage);
}(jIO, RSVP, DOMParser));
/*
* Copyright 2016, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint nomen: true*/
/*global jIO, RSVP, DOMParser */
// JIO Rss Storage Description :
// {
// type: "rss",
// url: {string}
// }
(function (jIO, RSVP, DOMParser) {
"use strict";
var dummy = {getAttribute: function () { return; }};
function selectElement(element, selector) {
return (element.querySelector(selector) || dummy);
}
function getRssHeaderItemDict(element) {
var rss_channel = element.querySelector("rss > channel"),
feed_channel;
feed_channel = {
siteTitle: selectElement(
rss_channel,
"title"
).textContent,
reference: selectElement(
rss_channel,
"description"
).textContent,
siteLink: selectElement(
rss_channel,
"link"
).textContent,
lastBuildDate: selectElement(
rss_channel,
"lastBuildDate"
).textContent,
siteGenerator: selectElement(
rss_channel,
"generator"
).textContent,
siteDocs: selectElement(
rss_channel,
"docs"
).textContent
};
return feed_channel;
}
function getFeedItem(entry) {
var item;
item = {
link: selectElement(entry, "link").textContent,
date: selectElement(entry, "pubDate").textContent,
title: selectElement(entry, "title").textContent,
author: selectElement(entry, "author").textContent,
category: selectElement(entry, "category").textContent,
comments: selectElement(entry, "comments").textContent,
sourceUrl: selectElement(entry, "source").getAttribute('url'),
source: selectElement(entry, "source").textContent,
description: selectElement(entry, "description").textContent,
guid: selectElement(entry, "guid").textContent
};
return item;
}
function getRssFeedEntry(element, id) {
var item,
rss_guid_list,
i;
if (id !== undefined && id !== null) {
rss_guid_list = element.querySelectorAll("rss>channel>item>guid");
for (i = 0; i < rss_guid_list.length; i += 1) {
if (rss_guid_list[i].textContent === id) {
item = getFeedItem(rss_guid_list[i].parentNode);
Object.assign(item, getRssHeaderItemDict(element));
break;
}
}
}
return item;
}
function getRssFeedEntryList(element, options) {
var rss_entry_list,
item_list = [],
push_method,
feed_channel;
if (options.include_docs === true) {
feed_channel = getRssHeaderItemDict(element);
push_method = function (id, entry) {
var item;
if (!id) {
return;
}
item = getFeedItem(entry);
Object.assign(item, feed_channel);
item_list.push({
"id": id,
"value": {},
"doc": item
});
};
} else {
push_method = function (id) {
if (!id) {
return;
}
item_list.push({
"id": id,
"value": {}
});
};
}
rss_entry_list = element.querySelectorAll("rss > channel > item");
[].forEach.call(rss_entry_list, function (entry) {
push_method(
selectElement(entry, "guid").textContent,
entry
);
});
return item_list;
}
function parseRssFeed(feed_url, id, options) {
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
type: "GET",
url: feed_url,
dataType: "text"
});
})
.push(function (response) {
var element,
item;
element = new DOMParser().parseFromString(
response.target.responseText,
"text/xml"
);
if (id !== undefined && id !== null) {
item = getRssFeedEntry(element, id);
if (item === undefined) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return item;
}
if (!options) {
options = {};
}
return getRssFeedEntryList(element, options);
}, function (error) {
if ((error.target !== undefined) &&
(error.target.status === 404)) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
throw error;
});
}
/**
* The JIO RSSStorage Storage extension
*
* @class RSSStorage
* @constructor
*/
function RSSStorage(spec) {
if (typeof spec.url !== 'string') {
throw new TypeError("RSSStorage 'url' is not of type string");
}
this._url = spec.url;
}
RSSStorage.prototype.get = function (id) {
return parseRssFeed(this._url, id);
};
RSSStorage.prototype.hasCapacity = function (capacity) {
return (capacity === "list") || (capacity === 'include');
};
RSSStorage.prototype.buildQuery = function (options) {
return parseRssFeed(this._url, undefined, options);
};
jIO.addStorage('rss', RSSStorage);
}(jIO, RSVP, DOMParser));
This diff is collapsed.
This diff is collapsed.
......@@ -41,6 +41,8 @@
<script src="jio.storage/uuidstorage.tests.js"></script>
<script src="jio.storage/replicatestorage.tests.js"></script>
<script src="jio.storage/shastorage.tests.js"></script>
<script src="jio.storage/rssfeedstorage.test.js"></script>
<script src="jio.storage/opmlstorage.tests.js"></script>
<!--script src="jio.storage/qiniustorage.tests.js"></script-->
<!--script src="jio.storage/indexstorage.tests.js"></script-->
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment