summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-06-05 05:38:43 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-06-05 05:38:43 +0000
commit69c6e0618ad4f18d18771ef91aacbb5c5a68f3a2 (patch)
tree2456aa85d86125726127b0d4ab022f68d2fc710b
parentf052ca9d9dc273dc0f625c9a6ec6eb38d6bc0f3a (diff)
Add RSS support to the WSGI integration module.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@951655 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-cpp/trunk/modules/rss/rss-test.cpp30
-rwxr-xr-xsca-cpp/trunk/modules/wsgi/atom-test.py19
-rw-r--r--sca-cpp/trunk/modules/wsgi/atomutil.py23
-rw-r--r--sca-cpp/trunk/modules/wsgi/httputil.py58
-rwxr-xr-xsca-cpp/trunk/modules/wsgi/rss-test.py170
-rw-r--r--sca-cpp/trunk/modules/wsgi/rssutil.py119
-rwxr-xr-xsca-cpp/trunk/modules/wsgi/util-test4
7 files changed, 377 insertions, 46 deletions
diff --git a/sca-cpp/trunk/modules/rss/rss-test.cpp b/sca-cpp/trunk/modules/rss/rss-test.cpp
index 3168e1f474..9bfd620835 100644
--- a/sca-cpp/trunk/modules/rss/rss-test.cpp
+++ b/sca-cpp/trunk/modules/rss/rss-test.cpp
@@ -41,9 +41,9 @@ string itemEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<title>fruit</title>"
"<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>"
"<description>"
- "<fruit>"
+ "<item>"
"<name>Apple</name><price>$2.99</price>"
- "</fruit>"
+ "</item>"
"</description>"
"</item>\n");
@@ -56,10 +56,10 @@ string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
string incompleteEntry("<item>"
"<title>fruit</title><description>"
- "<fruit xmlns=\"http://services/\">"
+ "<Item xmlns=\"http://services/\">"
"<name xmlns=\"\">Orange</name>"
"<price xmlns=\"\">3.55</price>"
- "</fruit>"
+ "</Item>"
"</description>"
"</item>");
@@ -68,16 +68,16 @@ string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<title>fruit</title>"
"<link></link>"
"<description>"
- "<fruit xmlns=\"http://services/\">"
+ "<Item xmlns=\"http://services/\">"
"<name xmlns=\"\">Orange</name>"
"<price xmlns=\"\">3.55</price>"
- "</fruit>"
+ "</Item>"
"</description>"
"</item>\n");
bool testEntry() {
{
- const list<value> i = list<value>() + element + value("fruit")
+ const list<value> i = list<value>() + element + value("item")
+ value(list<value>() + element + value("name") + value(string("Apple")))
+ value(list<value>() + element + value("price") + value(string("$2.99")));
const list<value> a = mklist<value>(string("fruit"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
@@ -131,18 +131,18 @@ string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<title>fruit</title>"
"<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>"
"<description>"
- "<fruit>"
+ "<item>"
"<name>Apple</name><price>$2.99</price>"
- "</fruit>"
+ "</item>"
"</description>"
"</item>"
"<item>"
"<title>fruit</title>"
"<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</link>"
"<description>"
- "<fruit>"
+ "<item>"
"<name>Orange</name><price>$3.55</price>"
- "</fruit>"
+ "</item>"
"</description>"
"</item>"
"</channel>"
@@ -163,11 +163,11 @@ bool testFeed() {
{
const list<value> i = list<value>()
+ (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
- + (list<value>() + element + "fruit"
+ + (list<value>() + element + "item"
+ (list<value>() + element + "name" + "Apple")
+ (list<value>() + element + "price" + "$2.99")))
+ (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
- + (list<value>() + element + "fruit"
+ + (list<value>() + element + "item"
+ (list<value>() + element + "name" + "Orange")
+ (list<value>() + element + "price" + "$3.55")));
const list<value> a = cons<value>("Feed", cons<value>("1234", i));
@@ -178,11 +178,11 @@ bool testFeed() {
{
const list<value> i = list<value>()
+ (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
- + valueToElement(list<value>() + "fruit"
+ + valueToElement(list<value>() + "item"
+ (list<value>() + "name" + "Apple")
+ (list<value>() + "price" + "$2.99")))
+ (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
- + valueToElement(list<value>() + "fruit"
+ + valueToElement(list<value>() + "item"
+ (list<value>() + "name" + "Orange")
+ (list<value>() + "price" + "$3.55")));
const list<value> a = cons<value>("Feed", cons<value>("1234", i));
diff --git a/sca-cpp/trunk/modules/wsgi/atom-test.py b/sca-cpp/trunk/modules/wsgi/atom-test.py
index 61435bf438..81a6106519 100755
--- a/sca-cpp/trunk/modules/wsgi/atom-test.py
+++ b/sca-cpp/trunk/modules/wsgi/atom-test.py
@@ -35,6 +35,17 @@ itemEntry = \
"<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\" />" \
"</entry>\n"
+textEntry = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
+ "<title type=\"text\">item</title>" \
+ "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" \
+ "<content type=\"text\">" \
+ "Apple" \
+ "</content>" \
+ "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\" />" \
+ "</entry>\n"
+
incompleteEntry = \
"<entry xmlns=\"http://www.w3.org/2005/Atom\">" \
"<title>item</title><content type=\"text/xml\">" \
@@ -68,9 +79,13 @@ def testEntry():
s2 = writeATOMEntry(a2)
assert car(s2) == itemEntry
- a3 = readATOMEntry((incompleteEntry,))
+ a3 = readATOMEntry((textEntry,))
s3 = writeATOMEntry(a3)
- assert car(s3) == completedEntry
+ assert car(s3) == textEntry
+
+ a4 = readATOMEntry((incompleteEntry,))
+ s4 = writeATOMEntry(a4)
+ assert car(s4) == completedEntry
return True
emptyFeed = \
diff --git a/sca-cpp/trunk/modules/wsgi/atomutil.py b/sca-cpp/trunk/modules/wsgi/atomutil.py
index 0ec83ca9e0..6c0a7c9a81 100644
--- a/sca-cpp/trunk/modules/wsgi/atomutil.py
+++ b/sca-cpp/trunk/modules/wsgi/atomutil.py
@@ -28,7 +28,7 @@ def entryElementsToValues(e):
li = filter(selector((element, "'id")), e)
i = "" if isNil(li) else elementValue(car(li))
lc = filter(selector((element, "'content")), e)
- return (t, i, cadr(elementChildren(car(lc))))
+ return (t, i, elementValue(car(lc)))
# Convert a list of elements to a list of values representing ATOM entries
def entriesElementsToValues(e):
@@ -48,6 +48,14 @@ def entryValue(e):
v = elementsToValues((caddr(e),))
return cons(car(e), (cadr(e), cdr(car(v))))
+# Return true if a list of strings represents an ATOM feed
+def isATOMFeed(l):
+ if isNil(l):
+ return False
+ if car(l)[0:5] != "<?xml":
+ return False
+ return contains(car(l), "<feed")
+
# Convert a list of strings to a list of values representing an ATOM feed
def readATOMFeed(l):
f = readXML(l)
@@ -60,12 +68,21 @@ def readATOMFeed(l):
return (elementValue(car(t)), elementValue(car(i)))
return cons(elementValue(car(t)), cons(elementValue(car(i)), entriesElementsToValues(e)))
+# Convert an ATOM feed containing elements to an ATOM feed containing values
+def feedValuesLoop(e):
+ if (isNil(e)):
+ return e
+ return cons(entryValue(car(e)), feedValuesLoop(cdr(e)))
+
+def feedValues(e):
+ return cons(car(e), cons(cadr(e), feedValuesLoop(cddr(e))))
+
# Convert a list of values representy an ATOM entry to a list of elements
def entryElement(l):
return (element, "'entry", (attribute, "'xmlns", "http://www.w3.org/2005/Atom"),
(element, "'title", (attribute, "'type", "text"), car(l)),
(element, "'id", cadr(l)),
- (element, "'content", (attribute, "'type", "application/xml"), caddr(l)),
+ (element, "'content", (attribute, "'type", ("application/xml" if isList(caddr(l)) else "text")), caddr(l)),
(element, "'link", (attribute, "'href", cadr(l))))
# Convert a list of values representing ATOM entries to a list of elements
@@ -85,7 +102,7 @@ def writeATOMFeed(l):
(element, "'id", cadr(l)))
if isNil(cddr(l)):
return writeXML((f,), True)
- fe = f + entriesElements(cddr(l))
+ fe = append(f, entriesElements(cddr(l)))
return writeXML((fe,), True)
# Convert an ATOM entry containing a value to an ATOM entry containing an item element
diff --git a/sca-cpp/trunk/modules/wsgi/httputil.py b/sca-cpp/trunk/modules/wsgi/httputil.py
index 77d19eabe2..3d0c3350ef 100644
--- a/sca-cpp/trunk/modules/wsgi/httputil.py
+++ b/sca-cpp/trunk/modules/wsgi/httputil.py
@@ -29,41 +29,27 @@ from util import *
from atomutil import *
from jsonutil import *
+# JSON request id
id = 1
# Make a callable HTTP client
class client:
- def __init__(self, uri):
- self.uri = urlparse(uri)
+ def __init__(self, url):
+ self.url = urlparse(url)
def __call__(self, func, *args):
- # Connect to the configured URI
- print >> stderr, "Client POST", self.uri.geturl()
- c = None
- headers = {"Content-type": "application/json-rpc"}
- if self.uri.scheme == "https":
+ # Connect to the configured URL
+ print >> stderr, "Client POST", self.url.geturl()
+ c, headers = connect(self.url)
- # With HTTPS, use a cerficate or HTTP basic authentication
- if os.path.exists("server.key"):
- c = HTTPSConnection(self.uri.hostname, 443 if self.uri.port == None else self.uri.port, "server.key", "server.crt")
- else:
- c = HTTPSConnection(self.uri.hostname, 443 if self.uri.port == None else self.uri.port)
-
- # For HTTP basic authentication the user and password are
- # provided by htpasswd.py
- import htpasswd
- auth = 'Basic ' + b64encode(htpasswd.user + ':' + htpasswd.passwd)
- headers["Authorization"] = auth
- else:
- c = HTTPConnection(self.uri.hostname, 80 if self.uri.port == None else self.uri.port)
-
- # POST the JSON-RPC request
+ # POST a JSON-RPC request
global id
req = StringIO()
writeStrings(jsonRequest(id, func, args), req)
id = id + 1
- c.request("POST", self.uri.path, req.getvalue(), headers)
+ headers["Content-type"] = "application/json-rpc"
+ c.request("POST", self.url.path, req.getvalue(), headers)
res = c.getresponse()
print >> stderr, "Client status", res.status
if res.status != 200:
@@ -71,8 +57,28 @@ class client:
return jsonResultValue((res.read(),))
def __repr__(self):
- return repr((self.uri,))
+ return repr((self.url,))
+
+def mkclient(url):
+ return client(url)
+
+# Connect to a URL, return a connection and any authorization headers
+def connect(url):
+ if url.scheme == "https":
+
+ # With HTTPS, use a cerficate or HTTP basic authentication
+ if os.path.exists("server.key"):
+ c = HTTPSConnection(url.hostname, 443 if url.port == None else url.port, "server.key", "server.crt")
+ return c, {}
+ else:
+ c = HTTPSConnection(url.hostname, 443 if url.port == None else url.port)
-def mkclient(uri):
- return client(uri)
+ # For HTTP basic authentication the user and password are
+ # provided by htpasswd.py
+ import htpasswd
+ auth = 'Basic ' + b64encode(htpasswd.user + ':' + htpasswd.passwd)
+ return c, {"Authorization": auth}
+ else:
+ c = HTTPConnection(url.hostname, 80 if url.port == None else url.port)
+ return c, {}
diff --git a/sca-cpp/trunk/modules/wsgi/rss-test.py b/sca-cpp/trunk/modules/wsgi/rss-test.py
new file mode 100755
index 0000000000..e8a094b7d8
--- /dev/null
+++ b/sca-cpp/trunk/modules/wsgi/rss-test.py
@@ -0,0 +1,170 @@
+#!/usr/bin/python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Test RSS data conversion functions
+
+import unittest
+from elemutil import *
+from rssutil import *
+
+itemEntry = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<item>" \
+ "<title>fruit</title>" \
+ "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" \
+ "<description>" \
+ "<item>" \
+ "<name>Apple</name><price>$2.99</price>" \
+ "</item>" \
+ "</description>" \
+ "</item>\n"
+
+textEntry = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<item>" \
+ "<title>fruit</title>" \
+ "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" \
+ "<description>" \
+ "Apple" \
+ "</description>" \
+ "</item>\n"
+
+incompleteEntry = \
+ "<item>" \
+ "<title>fruit</title><description>" \
+ "<fruit xmlns=\"http://services/\">" \
+ "<name xmlns=\"\">Orange</name>" \
+ "<price xmlns=\"\">3.55</price>" \
+ "</fruit>" \
+ "</description>" \
+ "</item>"
+
+completedEntry = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<item>" \
+ "<title>fruit</title>" \
+ "<link />" \
+ "<description>" \
+ "<fruit xmlns=\"http://services/\">" \
+ "<name xmlns=\"\">Orange</name>" \
+ "<price xmlns=\"\">3.55</price>" \
+ "</fruit>" \
+ "</description>" \
+ "</item>\n"
+
+def testEntry():
+ i = (element, "'item", (element, "'name", "Apple"), (element, "'price", "$2.99"))
+ a = ("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b", i)
+ s = writeRSSEntry(a);
+ assert car(s) == itemEntry
+
+ a2 = readRSSEntry((itemEntry,))
+ s2 = writeRSSEntry(a2)
+ assert car(s2) == itemEntry
+
+ a3 = readRSSEntry((textEntry,))
+ s3 = writeRSSEntry(a3)
+ assert car(s3) == textEntry
+
+ a4 = readRSSEntry((incompleteEntry,))
+ s4 = writeRSSEntry(a4)
+ assert car(s4) == completedEntry
+ return True
+
+emptyFeed = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<rss version=\"2.0\">" \
+ "<channel>" \
+ "<title>Feed</title>" \
+ "<link>1234</link>" \
+ "<description>Feed</description>" \
+ "</channel>" \
+ "</rss>\n"
+
+itemFeed = \
+ "<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n" \
+ "<rss version=\"2.0\">" \
+ "<channel>" \
+ "<title>Feed</title>" \
+ "<link>1234</link>" \
+ "<description>Feed</description>" \
+ "<item>" \
+ "<title>fruit</title>" \
+ "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" \
+ "<description>" \
+ "<item>" \
+ "<name>Apple</name><price>$2.99</price>" \
+ "</item>" \
+ "</description>" \
+ "</item>" \
+ "<item>" \
+ "<title>fruit</title>" \
+ "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</link>" \
+ "<description>" \
+ "<item>" \
+ "<name>Orange</name><price>$3.55</price>" \
+ "</item>" \
+ "</description>" \
+ "</item>" \
+ "</channel>" \
+ "</rss>\n"
+
+def testFeed():
+ s = writeRSSFeed(("Feed", "1234"))
+ assert car(s) == emptyFeed
+
+ a2 = readRSSFeed((emptyFeed,))
+ s2 = writeRSSFeed(a2)
+ assert car(s2) == emptyFeed
+
+ i3 = (("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b",
+ (element, "'item", (element, "'name", "Apple"), (element, "'price", "$2.99"))),
+ ("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c",
+ (element, "'item", (element, "'name", "Orange"), (element, "'price", "$3.55"))))
+ a3 = cons("Feed", cons("1234", i3))
+ s3 = writeRSSFeed(a3)
+ assert car(s3) == itemFeed
+
+ i4 = (("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b",
+ valueToElement(("'item", ("'name", "Apple"), ("'price", "$2.99")))),
+ ("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c",
+ valueToElement(("'item", ("'name", "Orange"), ("'price", "$3.55")))))
+ a4 = cons("Feed", cons("1234", i4))
+ s4 = writeRSSFeed(a4)
+ assert car(s4) == itemFeed
+
+ a5 = readRSSFeed((itemFeed,));
+ s5 = writeRSSFeed(a5);
+ assert car(s5) == itemFeed
+
+ i6 = (("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b",
+ (("'name", "Apple"), ("'price", "$2.99"))),
+ ("fruit", "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c",
+ (("'name", "Orange"), ("'price", "$3.55"))))
+ a6 = cons("Feed", cons("1234", i6))
+ s6 = writeRSSFeed(feedValuesToElements(a6))
+ assert car(s6) == itemFeed
+
+ return True
+
+if __name__ == "__main__":
+ print "Testing..."
+ testEntry()
+ testFeed()
+ print "OK"
+
diff --git a/sca-cpp/trunk/modules/wsgi/rssutil.py b/sca-cpp/trunk/modules/wsgi/rssutil.py
new file mode 100644
index 0000000000..4f060d2321
--- /dev/null
+++ b/sca-cpp/trunk/modules/wsgi/rssutil.py
@@ -0,0 +1,119 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# RSS data conversion functions
+
+from util import *
+from elemutil import *
+from xmlutil import *
+
+# Convert a list of elements to a list of values representing an RSS entry
+def entryElementsToValues(e):
+ lt = filter(selector((element, "'title")), e)
+ t = "" if isNil(lt) else elementValue(car(lt))
+ li = filter(selector((element, "'link")), e)
+ i = "" if isNil(li) else elementValue(car(li))
+ lc = filter(selector((element, "'description")), e)
+ return (t, i, elementValue(car(lc)))
+
+# Convert a list of elements to a list of values representing RSS entries
+def entriesElementsToValues(e):
+ if isNil(e):
+ return e
+ return cons(entryElementsToValues(car(e)), entriesElementsToValues(cdr(e)))
+
+# Convert a list of strings to a list of values representing an RSS entry
+def readRSSEntry(l):
+ e = readXML(l)
+ if isNil(e):
+ return ()
+ return entryElementsToValues(car(e))
+
+# Convert a list of values representy an RSS entry to a value
+def entryValue(e):
+ v = elementsToValues((caddr(e),))
+ return cons(car(e), (cadr(e), cdr(car(v))))
+
+# Return true if a list of strings represents an RSS feed
+def isRSSFeed(l):
+ if isNil(l):
+ return False
+ if car(l)[0:5] != "<?xml":
+ return False
+ return contains(car(l), "<rss")
+
+# Convert a list of strings to a list of values representing an RSS feed
+def readRSSFeed(l):
+ f = readXML(l)
+ if isNil(f):
+ return ()
+ c = filter(selector((element, "'channel")), car(f))
+ t = filter(selector((element, "'title")), car(c))
+ i = filter(selector((element, "'link")), car(c))
+ e = filter(selector((element, "'item")), car(c))
+ if isNil(e):
+ return (elementValue(car(t)), elementValue(car(i)))
+ return cons(elementValue(car(t)), cons(elementValue(car(i)), entriesElementsToValues(e)))
+
+# Convert an RSS feed containing elements to an RSS feed containing values
+def feedValuesLoop(e):
+ if (isNil(e)):
+ return e
+ return cons(entryValue(car(e)), feedValuesLoop(cdr(e)))
+
+def feedValues(e):
+ return cons(car(e), cons(cadr(e), feedValuesLoop(cddr(e))))
+
+# Convert a list of values representy an RSS entry to a list of elements
+def entryElement(l):
+ return (element, "'item",
+ (element, "'title", car(l)),
+ (element, "'link", cadr(l)),
+ (element, "'description", caddr(l)))
+
+# Convert a list of values representing RSS entries to a list of elements
+def entriesElements(l):
+ if isNil(l):
+ return l
+ return cons(entryElement(car(l)), entriesElements(cdr(l)))
+
+# Convert a list of values representing an RSS entry to an RSS entry
+def writeRSSEntry(l):
+ return writeXML((entryElement(l),), True)
+
+# Convert a list of values representing an RSS feed to an RSS feed
+def writeRSSFeed(l):
+ c = ((element, "'title", car(l)),
+ (element, "'link", cadr(l)),
+ (element, "'description", car(l)))
+ ce = c if isNil(cddr(l)) else append(c, entriesElements(cddr(l)))
+ fe = (element, "'rss", (attribute, "'version", "2.0"), append((element, "'channel"), ce))
+ return writeXML((fe,), True)
+
+# Convert an RSS entry containing a value to an RSS entry containing an item element
+def entryValuesToElements(v):
+ return cons(car(v), cons(cadr(v), valuesToElements((cons("'item", caddr(v)),))))
+
+# Convert an RSS feed containing values to an RSS feed containing elements
+def feedValuesToElementsLoop(v):
+ if isNil(v):
+ return v
+ return cons(entryValuesToElements(car(v)), feedValuesToElementsLoop(cdr(v)))
+
+def feedValuesToElements(v):
+ return cons(car(v), cons(cadr(v), feedValuesToElementsLoop(cddr(v))))
+
diff --git a/sca-cpp/trunk/modules/wsgi/util-test b/sca-cpp/trunk/modules/wsgi/util-test
index cb4e2f6c8a..aa8725a200 100755
--- a/sca-cpp/trunk/modules/wsgi/util-test
+++ b/sca-cpp/trunk/modules/wsgi/util-test
@@ -32,6 +32,10 @@ if [ "$rc" = "0" ]; then
rc=$?
fi
if [ "$rc" = "0" ]; then
+ $python_prefix/bin/python rss-test.py
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
$python_prefix/bin/python json-test.py
rc=$?
fi