Index: /qRSS2Syndication/branches/Plone3.1/HISTORY.txt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/HISTORY.txt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/HISTORY.txt	(revision 113)
@@ -0,0 +1,18 @@
+0.4.1 2005-08-25
+      
+   * fixed RSS1 headers
+
+0.4  2005-07-27
+
+   * Fixed the getSindicatableContent script. Now if current object has custom synContentValues 
+     method then content is taken from portal_syndication. If not it will be taken from catalog 
+     based on the qRSS2 properties tab of the current object.
+
+   * Added include subfolders option.
+
+   * Added <content:encoded> support to RSS2 template. 
+  
+   * blogentry_item.pt now supports <enclosure> for ATAudio.
+
+   * Added template RSS1, rssBody1 - RSS 0.92 feed with <content:encoded> tag.
+   
Index: /qRSS2Syndication/branches/Plone3.1/README.txt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/README.txt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/README.txt	(revision 113)
@@ -0,0 +1,18 @@
+qRSS2Syndication simple product that adds RSS2 functionality to Plone. 
+   * includes support of audio and video feeds. 
+   * the syndication of ATAudio objects, mp3, wmv, ppt, jpg files using RSS 2.0 with enclosures.
+   * data in RSS2 feed sorted by effective date.
+
+DEPENDS on:
+
+   * CMFSyndication
+
+INSTALATION:
+
+1. install it with quickinstaller in Plone.
+
+
+RSS2 syndiction properties are saved into the syndication_information object 
+which is controled with portal_syndication tool
+
+
Index: /qRSS2Syndication/branches/Plone3.1/TODO.txt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/TODO.txt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/TODO.txt	(revision 113)
@@ -0,0 +1,16 @@
+get rid of getFileFieldContentType method
+listSyndicatableContent should use ExtendedPathindex in query on Plone 2.1+
+
+
+itunes related:
+---------------
+
+- add length of video file from a atvideo object to atvideo_item.pt like in ataudio_item.pt
+- add categories to the channel for itunes feed
+- add <itunes:keywords> for an item aggregated from the keywords of the object or tags(?)
+- subtitle for items and channel (maybe take first sentence of description)
+- add tab for smartfolder to configure the itunes related parameters (enable itunes support, channel image,...)
+- strip html tags from <itunes:summary> and <itunes:subtitle>, substitute <br /> and </p> with a new line (\n)
+
+maybe add a check for the type of the items (mp3, m4a, m4v, mp4, mov, ..) that itunes understand, otherwise output
+an error - dont know how to implement that, maybe its not possible at all
Index: /qRSS2Syndication/branches/Plone3.1/__init__.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/__init__.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/__init__.py	(revision 113)
@@ -0,0 +1,2 @@
+from AccessControl import allow_module
+allow_module('Products.qRSS2Syndication.utils.py')
Index: /qRSS2Syndication/branches/Plone3.1/configure.zcml
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/configure.zcml	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/configure.zcml	(revision 113)
@@ -0,0 +1,8 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:cmf="http://namespaces.zope.org/cmf">
+
+   <cmf:registerDirectory name="qrss2syndication"/>
+   <include file="profiles.zcml" />
+
+</configure>
Index: /qRSS2Syndication/branches/Plone3.1/profiles.zcml
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/profiles.zcml	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/profiles.zcml	(revision 113)
@@ -0,0 +1,13 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:genericsetup="http://namespaces.zope.org/genericsetup">
+
+  <genericsetup:registerProfile
+      name="default"
+      title="qRSS2Syndication"
+      directory="profiles/default"
+      description=''
+      provides="Products.GenericSetup.interfaces.EXTENSION"
+      />
+
+</configure>
Index: /qRSS2Syndication/branches/Plone3.1/profiles/default/actions.xml
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/profiles/default/actions.xml	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/profiles/default/actions.xml	(revision 113)
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<object name="portal_actions" meta_type="Plone Actions Tool"
+   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <object name="document_actions" meta_type="CMF Action Category">
+  <object name="rss2syndication" meta_type="CMF Action">
+   <property name="title">RSS2 Syndication</property>
+   <property name="url_expr">string:$object_url/RSS2</property>
+   <property
+      name="available_expr">python: folder==object and portal.portal_syndication.isSyndicationAllowed(object)</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+ </object>
+ <object name="folder" meta_type="CMF Action Category">
+  <object name="setup_rss2" meta_type="CMF Action">
+   <property name="title">RSS2 Setup</property>
+   <property name="url_expr">string:$object_url/setup_rss2</property>
+   <property
+      name="available_expr">python:portal.portal_syndication.isSyndicationAllowed(object)</property>
+   <property name="permissions">
+    <element value="Manage properties"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+ </object>
+</object>
Index: /qRSS2Syndication/branches/Plone3.1/profiles/default/skins.xml
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/profiles/default/skins.xml	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/profiles/default/skins.xml	(revision 113)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<object name="portal_skins" meta_type="Plone Skins Tool">
+ <object name="qrss2syndication" meta_type="Filesystem Directory View"
+    directory="Products.qRSS2Syndication:skins/qrss2syndication"/>
+ <skin-path name="*">
+  <layer name="qrss2syndication" insert-after="custom"/>
+ </skin-path>
+</object>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/RSS1.dtml
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/RSS1.dtml	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/RSS1.dtml	(revision 113)
@@ -0,0 +1,6 @@
+<dtml-if expr="portal_syndication.isSyndicationAllowed(this())"> 
+
+<dtml-var rssBody1>
+<dtml-else>
+<dtml-call "REQUEST['RESPONSE'].redirect(absolute_url()+'/rssDisabled?portal_status_message=Syndication+is+Disabled')">
+</dtml-if>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/RSS2.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/RSS2.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/RSS2.pt	(revision 113)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal"  
+     xmlns:content="http://purl.org/rss/1.0/modules/content/"
+     tal:define="results python:here.getSyndicatableContent();"
+     tal:on-error="nothing">
+<tal:x define="dummy python:request.RESPONSE.setHeader('Content-Type', 'text/xml')" />
+    <channel>
+
+        <title tal:define="portal_title here/portal_properties/title;
+            here_title here/title_or_id;
+            template_title template/title_or_id;
+            here_title python:test(portal_title != here_title, here_title, template_title)"
+            tal:content="string:$portal_title - $here_title">Title of page</title>
+        <link tal:content="here/absolute_url"></link>
+        <description tal:content="here/Description">
+        </description>
+        <language>en-us</language>
+        <generator>Plone 2.0</generator>
+
+        <tal:block repeat="res results">
+            <tal:block define="macros nocall: python:here.getItemMacros(res.portal_type); 
+                               item_path python: res.absolute_url();
+                               item_path python: res.portal_type=='ATAudio' and item_path+'/file_download/'+res.getId() or item_path;">
+                  <item>
+                      <title tal:content="res/title_or_id"></title>
+                      <link tal:content="item_path"></link>
+                      <description tal:content="res/Description">
+                      </description>
+                      <author tal:content="res/Creator"></author>
+                      <tal:repeat repeat="subj res/Subject">
+                          <category tal:content="subj">
+                          </category>
+                      </tal:repeat>
+                      <pubDate tal:content="structure python: DateTime(res.Date()).rfc822()"> </pubDate>
+                      <metal:block use-macro="macros"/>
+                  </item>
+
+            </tal:block>
+	   	
+        </tal:block>
+
+
+    </channel>
+
+</rss>
+
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/ataudio_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/ataudio_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/ataudio_item.pt	(revision 113)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <tal:define define="file res/getFile;
+                       item_size file/get_size | python: file and len(file) or 0;
+                       content_type  python:here.getFileFieldContentType(res);
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/atvideo_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/atvideo_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/atvideo_item.pt	(revision 113)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <!-- todo: check for apropriate get size of file method (expression res/getFile can kill zope) -->
+   <tal:define define="file res/getFile;
+                       item_size file/get_size | python: file and len(file) or 0;
+                       content_type  python:here.getFileFieldContentType(res);
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/bittorrentfile_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/bittorrentfile_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/bittorrentfile_item.pt	(revision 113)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <tal:define define="item_size res/get_size;
+                       content_type res/getContentType;
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/blogentry_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/blogentry_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/blogentry_item.pt	(revision 113)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:content="http://purl.org/rss/1.0/modules/content/" 
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+     <tal:repeat repeat="tag res/EntryTag">
+        <category tal:content="tag"></category>
+     </tal:repeat>
+      <content:encoded>
+        <tal:x replace="structure python:'&lt;![CDATA['+res.getBody()+']]&gt;'"/>
+      </content:encoded>
+     <tal:x tal:on-error="string:"
+           define="files python:res.objectValues('ATAudio');
+                   file python:files and files[0].getFile() or None;"
+           condition="file">
+        <tal:define define="item_size file/get_size | python: file and len(file) or 0;
+                            content_type  python:here.getFileFieldContentType(res);">
+          <enclosure tal:attributes="type content_type;
+                                     url item_path;
+                                     length item_size"/>
+        </tal:define>
+      </tal:x>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/default_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/default_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/default_item.pt	(revision 113)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/document_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/document_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/document_item.pt	(revision 113)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0"
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:content="http://purl.org/rss/1.0/modules/content/"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <content:encoded>
+       <tal:x replace="structure python:'&lt;![CDATA['+res.CookedBody()+']]&gt;'"/>
+   </content:encoded>
+ </metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/file_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/file_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/file_item.pt	(revision 113)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <tal:define define="item_size res/get_size;
+                       content_type res/getContentType;
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getFileFieldContentType.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getFileFieldContentType.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getFileFieldContentType.py	(revision 113)
@@ -0,0 +1,13 @@
+## Script (Python) "getAudioFiles"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters= object=None
+##title=
+##
+if not object:
+    return None
+from Products.qRSS2Syndication.utils import getFileContentType
+return getFileContentType(object)
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getItemMacros.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getItemMacros.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getItemMacros.py	(revision 113)
@@ -0,0 +1,16 @@
+## Script (Python) "getAudioFiles"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=etype
+##title=
+##
+
+template_id = etype.lower()+'_item'
+template = getattr(context, template_id, None)
+if template:
+    return template.macros['item']
+else:
+    return context.default_item.macros['item']
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getObjectCreator.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getObjectCreator.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getObjectCreator.py	(revision 113)
@@ -0,0 +1,17 @@
+## Script (Python) "getMemberEmail"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=MemberId
+##title=
+##
+memberlist = context.portal_membership.searchForMembers(REQUEST=None, name=MemberId)
+res = None
+if memberlist:
+    for member in memberlist:
+        if member.id == MemberId:
+            res = member
+            break
+return res
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getSynProp.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getSynProp.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getSynProp.py	(revision 113)
@@ -0,0 +1,12 @@
+## Script (Python) "getAudioFiles"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters= object=None
+##title=
+##
+from Products.qRSS2Syndication.utils import getRSS2Properties
+res=getRSS2Properties(context)
+return res
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getSyndicatableContent.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getSyndicatableContent.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/getSyndicatableContent.py	(revision 113)
@@ -0,0 +1,22 @@
+## Script (Python) "getAudioFiles"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=obj=None
+##title=
+##
+from Products.qRSS2Syndication.utils import listSyndicatableContent
+if not obj:
+   obj = context
+if hasattr(context,'synContentValues') or context.portal_type=='Topic':
+   count = int(context.portal_syndication.getMaxItems(obj))
+   res = context.portal_syndication.getSyndicatableContent(obj)
+   # has to check and cut number of items to be displayed 
+   # to prevent feed bloat 
+   count = count<len(res) and count or len(res)
+   res = res[:count]
+else:
+   res = listSyndicatableContent(obj) 
+return res
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/image_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/image_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/image_item.pt	(revision 113)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <tal:define define="item_size res/get_size;
+                       content_type  res/getContentType;
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopaudio_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopaudio_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopaudio_item.pt	(revision 113)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal"
+     xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" >
+<metal:block define-macro="item">
+   <tal:define define="item_size item/getFileSize | python: 0;
+                       content_type  res/getMimeType;">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+          <tal:block condition="itunesEnabled">
+           		<itunes:duration tal:content="res/getLengthString"></itunes:duration>
+          </tal:block>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopimage_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopimage_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopimage_item.pt	(revision 113)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <tal:define define="item_size res/get_size;
+                       content_type  res/getContentType;
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopvideo_item.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopvideo_item.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/mediacoopvideo_item.pt	(revision 113)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<rss version="2.0" 
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal" >
+<metal:block define-macro="item">
+   <!-- todo: check for apropriate get size of file method (expression res/getFile can kill zope) -->
+   <tal:define define="file res/getFile;
+                       item_size file/get_size | python: file and len(file) or 0;
+                       content_type  python:here.getFileFieldContentType(res);
+                       ">
+           <enclosure 
+               tal:attributes="type content_type;
+                               url item_path;
+                               length item_size"/>
+  </tal:define>
+</metal:block>
+</rss>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/rssBody1.pt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/rssBody1.pt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/rssBody1.pt	(revision 113)
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rdf:RDF 
+  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+  xmlns:dc="http://purl.org/dc/elements/1.1/"
+  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+  xmlns:content="http://purl.org/rss/1.0/modules/content/" 
+  xmlns="http://purl.org/rss/1.0/"
+  xmlns:tal="http://xml.zope.org/namespaces/tal">
+<tal:x define="dummy python:request.RESPONSE.setHeader('Content-Type', 'text/xml')" />
+<tal:x define="max_items here/portal_syndication/getMaxItems;
+               items python:here.getSyndicatableContent(here)[:int(max_items)];">
+<channel tal:attributes="rdf:about here/absolute_url">
+
+    <title tal:define="portal_title here/portal_properties/title;
+                       here_title here/title_or_id;
+                       template_title template/title_or_id;
+                       here_title python:test( portal_title != here_title,
+                                               here_title,
+                                               template_title )"
+           tal:content="string:$portal_title - $here_title">Title of page</title>
+  <link tal:content="here/portal_url"></link>
+  <description tal:content="here/Description">
+    
+  </description>
+  <image rdf:resource="logo.jpg" />
+  <sy:updatePeriod><tal:replace replace="here/portal_syndication/getUpdatePeriod" /></sy:updatePeriod>
+  <sy:updateFrequency><tal:replace replace="here/portal_syndication/getUpdateFrequency" /></sy:updateFrequency>
+  <sy:updateBase><tal:replace replace="python: here.portal_syndication.getHTML4UpdateBase(here)" /></sy:updateBase>
+  <items>
+    <rdf:Seq>
+          <tal:repeat repeat="item items">
+              <rdf:li tal:attributes="rdf:resource item/absolute_url" />
+          </tal:repeat>
+   </rdf:Seq>
+  </items>
+</channel>
+<tal:repeat repeat="item items">
+<item tal:attributes="rdf:about item/Identifier">
+<title tal:content="item/Title"></title>
+<link tal:content="item/Identifier"></link>
+<description tal:content="item/Description">
+</description>
+<content:encoded tal:on-error=" " tal:content="structure item/render_body">  </content:encoded>
+<dc:publisher tal:content="item/Publisher"></dc:publisher>
+<dc:creator tal:content="item/Creator"></dc:creator>
+<dc:rights tal:content="item/Rights"></dc:rights>
+<tal:repeat repeat="subj item/Subject">
+<dc:subject tal:content="subj">
+</dc:subject>
+</tal:repeat>
+<tal:repeat repeat="tag item/EntryTag"
+ tal:on-error="string:">
+<dc:subject tal:content="tag">
+</dc:subject>
+</tal:repeat>
+<dc:date tal:content="python: DateTime(item.Date()).strftime('%Y-%m-%dT%H:%M+00:00')"></dc:date>
+</item>
+</tal:repeat>
+</tal:x>
+</rdf:RDF>
+
+
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/save_rss2_setup.cpy
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/save_rss2_setup.cpy	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/save_rss2_setup.cpy	(revision 113)
@@ -0,0 +1,15 @@
+## Controller Python Script "createObject"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind state=state
+##bind subpath=traverse_subpath
+##parameters= rss2_types=(),only_published=0,include_subfolders=0, articles_number=20,REQUEST=None
+##title=
+##
+if REQUEST:
+  from Products.qRSS2Syndication.utils import setupRSS2Types
+  status,message=setupRSS2Types(context,rss2_types,only_published,include_subfolders,articles_number,REQUEST)
+return state.set(status=status, portal_status_message=message)
+    
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/save_rss2_setup.cpy.metadata
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/save_rss2_setup.cpy.metadata	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/save_rss2_setup.cpy.metadata	(revision 113)
@@ -0,0 +1,7 @@
+[default]
+title=RSS2 Setup
+
+
+[actions]
+action.success=redirect_to:string:setup_rss2
+action.failure=redirect_to:string:setup_rss2
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/setup_rss2.cpt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/setup_rss2.cpt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/setup_rss2.cpt	(revision 113)
@@ -0,0 +1,118 @@
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
+      lang="en"
+      metal:use-macro="here/main_template/macros/master"
+      i18n:domain="plone">
+
+  <body>
+
+    <div metal:fill-slot="main"
+         tal:define="errors options/state/getErrors;
+                     sy_info python:here.getSynProp();
+                     params ">
+
+      <h1 i18n:translate="heading_RSS2_setup">
+        RSS2 feeds setup
+      </h1>
+     <!-- <tal:x replace="sy_info"/>-->
+      <form name="edit_form"
+            action="."
+            method="post"
+            enctype="multipart/form-data"
+            tal:attributes="action string:${here/getId}/${template/getId}" >
+
+        <fieldset>
+
+          <legend i18n:translate="legend_setup_rss2">Setup Details</legend>
+
+         
+          <div class="field">
+
+            <label for="rss2_types" i18n:translate="label_select_RSS2_types">Select types</label>
+
+            <div class="formHelp" i18n:translate="help_select_RSS2_types">
+              Select types to be included the RSS2 feed.
+            </div>
+
+            <select name="rss2_types:list:string" 
+		    multiple="multiple" 
+		    size="20"
+		    tal:define="types here/portal_types/listTypeInfo; 
+					">
+              <metal:block tal:repeat="ctype types">
+                <option value="Document"
+                        tal:define="Id ctype/getId;
+                                    is_selected python: ctype.getId() in sy_info['rss2_types']"
+                        tal:attributes="value ctype/getId;
+					selected is_selected|nothing"
+                        tal:content="python:ctype.Title()"
+                        i18n:translate="">Document</option>
+              </metal:block>
+		
+	    </select>
+          </div>
+
+          <div class="field">
+
+            <input type="checkbox" 
+                   name="only_published" 
+                   value="1"
+                   tal:define="checked python:sy_info['only_published'] and 'checked'"
+                   tal:attributes="checked checked"/>
+
+            <label for="only_published" i18n:translate="label_only_published">Only published content</label>
+
+          </div>
+          <div class="field">
+
+            <input type="checkbox" 
+                   name="include_subfolders" 
+                   value="0"
+                   tal:define="checked python:sy_info['include_subfolders'] and 'checked'"
+                   tal:attributes="checked checked"/>
+
+            <label for="include_subfolders" i18n:translate="label_include_subfolders">Include subfolders content</label>
+
+          </div>
+
+           
+          <div class="field"
+               tal:define="error errors/articles_number|nothing;"
+               tal:attributes="class python:test(error, 'field error', 'field')">
+            <label for="articles_number" i18n:translate="label_articles_number">Articles number</label>
+
+            <div class="formHelp" i18n:translate="help_articles_number">
+              Articles number to be included the RSS2 feed.
+            </div>
+            <div tal:content="error">Validation error output</div>
+            <input type="text" 
+                   name="articles_number" 
+                   value=""                                                                        
+                   tal:define="articles_number python:request.get('articles_number',None) or sy_info['articles_number'] or 20"
+                   tal:attributes="value articles_number"/>
+          </div>
+
+
+
+          <div class="formControls">
+        
+            <input class="context"
+                   tabindex=""
+                   type="submit"
+                   name="form.button.Save"
+                   value="Save"
+                   i18n:attributes="value"
+                   tal:attributes="tabindex tabindex/next;
+                                   disabled python:test(isLocked, 'disabled', None);" />
+
+          </div>
+        </fieldset>
+
+        <input type="hidden" name="form.submitted" value="1" />
+
+      </form>
+
+     
+    </div>
+
+  </body>
+</html>
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/setup_rss2.cpt.metadata
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/setup_rss2.cpt.metadata	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/setup_rss2.cpt.metadata	(revision 113)
@@ -0,0 +1,12 @@
+[default]
+title=RSS2 Setup
+
+[security]
+View=0:Authenticated
+
+[validators]
+validators=validate_rss2_setup
+
+[actions]
+action.success..Save=traverse_to:string:save_rss2_setup
+action.failure=traverse_to:string:setup_rss2
Index: /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/validate_rss2_setup.vpy
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/validate_rss2_setup.vpy	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/skins/qrss2syndication/validate_rss2_setup.vpy	(revision 113)
@@ -0,0 +1,19 @@
+## Controlled Python Script "validate_rss2_setup"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind state=state
+##bind subpath=traverse_subpath
+##parameters=
+##title=Validates an email
+##
+articles_number = context.REQUEST.get('articles_number')
+try:
+  z = int(articles_number)
+except:
+    state.setError('articles_number', 'The articles number value should be integer')
+    return state.set(status='failure', portal_status_message='Please correct the indicated errors.')
+return state
+
+
Index: /qRSS2Syndication/branches/Plone3.1/utils.py
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/utils.py	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/utils.py	(revision 113)
@@ -0,0 +1,79 @@
+from Products.CMFCore.utils import getToolByName
+from Acquisition import aq_base
+
+
+def setupRSS2Types(context,
+                    rss2_types = (),
+                    only_published = 0,
+                    include_subfolders = 0,
+                    articles_number = 20,
+                    REQUEST = None):
+    """ Save all needed RSS2 properties into 'syndication_information' """
+    import pdb;pdb.set_trace()
+    obj=aq_base(context)
+    status = 'success'
+    message = 'Your changes have been saved'
+
+    syInfo = getattr(obj, 'syndication_information', None)
+
+    if syInfo is None:
+        message = 'Syndication is Disabled'
+        status = 'failed'
+    syInfo.rss2_types = list(rss2_types)
+    syInfo.only_published = only_published
+    syInfo.include_subfolders = include_subfolders
+    syInfo.max_items = int(articles_number)
+    return status, message
+
+def getRSS2Properties(context):
+    """ Return directory of RSS2 properties from 'syndication_information' """
+    obj=aq_base(context)
+    
+    syInfo = getattr(obj, 'syndication_information', None)
+    syPropeties={}
+    syPropeties['rss2_types'] = getattr(syInfo,'rss2_types',[])
+    syPropeties['only_published'] = getattr(syInfo,'only_published',0)
+    syPropeties['include_subfolders'] = getattr(syInfo,'include_subfolders',0)
+    syPropeties['articles_number'] =int(getattr(syInfo,'max_items',20))
+    return  syPropeties
+
+
+
+def listSyndicatableContent(context):
+    """ List folder contents - catalog query 
+        * filtered types only
+        * sort on effective
+        * take only first 'articles_number' of elements """
+    res = []
+    ps = getToolByName(context,'portal_syndication')
+    if ps.isSyndicationAllowed(context):
+        cpath = '/'.join(context.getPhysicalPath())
+        syProperties = getRSS2Properties(context)
+        types = syProperties['rss2_types']
+        only_published = syProperties['only_published']
+        include_subfolders = syProperties['include_subfolders']
+        articles_number = syProperties['articles_number']
+
+        catalog = getToolByName(context,'portal_catalog')
+        args = {'portal_type':types,
+                'path':cpath,
+                'sort_on':'effective',
+                'sort_order':'reverse',}
+        if only_published:
+            args['review_state'] = 'published'
+        if include_subfolders == 0:
+            path_length=len(cpath)+1
+            for i in catalog.searchResults(args):
+                if i.getPath()[path_length:].find('/')<0:
+                    res.append(i)
+            res = res[:articles_number]
+        else:
+            args['sort_limit'] = articles_number
+            res=catalog.searchResults(args)
+        res = [r.getObject() for r in res]
+    return res
+
+
+def getFileContentType(context):
+    """  !ATAudio specific only! Get the content type of file field method """
+    return context.Schema()['file'].getContentType(context)
Index: /qRSS2Syndication/branches/Plone3.1/version.txt
===================================================================
--- /qRSS2Syndication/branches/Plone3.1/version.txt	(revision 113)
+++ /qRSS2Syndication/branches/Plone3.1/version.txt	(revision 113)
@@ -0,0 +1,1 @@
+1.0.1
