products/CPSRSS

changeset 239:4e3bc0f69fed

Savepoint: working base view (need to update some tests)
author Georges Racinet on purity.racinet.fr <georges@racinet.fr>
date Mon, 06 Dec 2010 01:11:49 +0100
parents f5702e848eb5
children 09638c25ff91
files RSSChannel.py browser/channels.py browser/configure.zcml browser/manage_channels.pt configure.zcml tests/test_views.py
diffstat 6 files changed, 107 insertions(+), 9 deletions(-) [+]
line diff
     1.1 --- a/RSSChannel.py
     1.2 +++ b/RSSChannel.py
     1.3 @@ -98,9 +98,9 @@
     1.4      security.declareObjectProtected(View)
     1.5  
     1.6      _properties = (
     1.7 -        {'id': 'title', 'type': 'string', 'mode': 'w',
     1.8 +        {'id': 'title', 'type': 'ustring', 'mode': 'w',
     1.9           'label': 'Title'},
    1.10 -        {'id': 'description', 'type': 'text', 'mode': 'w',
    1.11 +        {'id': 'description', 'type': 'utext', 'mode': 'w',
    1.12           'label': 'Description'},
    1.13          {'id': 'channel_url', 'type': 'string', 'mode':'w',
    1.14           'label': 'Channel URL'},
     2.1 --- a/browser/channels.py
     2.2 +++ b/browser/channels.py
     2.3 @@ -19,8 +19,11 @@
     2.4  from Products.CPSonFive.browser import AqSafeBrowserView
     2.5  
     2.6  from Products.CPSUtil.id import generateId
     2.7 +
     2.8  from Products.CPSRSS.RSSChannel import RSSChannel
     2.9  from Products.CPSRSS.RSSChannelContainer import RSSChannelContainer
    2.10 +from Products.CPSRSS.RSSChannelContainer import addRSSChannelContainer
    2.11 +
    2.12  from Products.CPSRSS.interfaces import IRSSChannelContainer
    2.13  
    2.14  class ManageChannels(AqSafeBrowserView):
    2.15 @@ -52,16 +55,22 @@
    2.16          cont = self.aqSafeGet('container')
    2.17          if cont is None:
    2.18              return ()
    2.19 -        return tuple(dict(id=chan.getId(), title=chan.title)
    2.20 -                     for chan in cont.objectValues([RSSChannel.meta_type]))
    2.21 +        return cont.objectValues([RSSChannel.meta_type])
    2.22  
    2.23 -    def addChannel(self, url):
    2.24 -        """Create a channel, deriving all properties from the feed.
    2.25 +    def addChannel(self, url=None):
    2.26 +        """Create a channel from explicit url or from request form.
    2.27 +
    2.28 +        All other properties are retrieved from the feed itself.
    2.29          """
    2.30  
    2.31 +        if url is None:
    2.32 +            # taking from request
    2.33 +            url = self.request.form['channel_url']
    2.34 +
    2.35          cont = self.aqSafeGet('container')
    2.36          if cont is None:
    2.37              cont = addRSSChannelContainer(self.context)
    2.38 +            self.aqSafeSet('container', cont)
    2.39          channel = RSSChannel('channel', url).__of__(cont)
    2.40          d = channel.getData() # might be quite empty if feed has problems
    2.41  
    2.42 @@ -73,4 +82,4 @@
    2.43  
    2.44          cont._setObject(cid, channel)
    2.45          self.request.RESPONSE.redirect('/'.join((
    2.46 -                cont.absolute_url_path(), cid, 'edit.html')))
    2.47 +                self.context.absolute_url_path(), 'manage_channels.html')))
     3.1 new file mode 100644
     3.2 --- /dev/null
     3.3 +++ b/browser/configure.zcml
     3.4 @@ -0,0 +1,29 @@
     3.5 +<configure xmlns="http://namespaces.zope.org/zope"
     3.6 +           xmlns:five="http://namespaces.zope.org/five"
     3.7 +           xmlns:browser="http://namespaces.zope.org/browser">
     3.8 +
     3.9 +  <browser:page
    3.10 +    for="Products.CPSCore.interfaces.ICPSProxy"
    3.11 +    name="manage_channels.html"
    3.12 +    permission="cps.rss.ManageChannels"
    3.13 +    class=".browser.channels.ManageChannels"
    3.14 +    template="manage_channels.pt"
    3.15 +    />
    3.16 +
    3.17 +  <browser:page
    3.18 +    for="Products.CPSCore.interfaces.ICPSProxy"
    3.19 +    name="add_channel"
    3.20 +    permission="cps.rss.ManageChannels"
    3.21 +    class=".browser.channels.ManageChannels"
    3.22 +    attribute="addChannel"
    3.23 +    />
    3.24 +
    3.25 +  <!--browser:page
    3.26 +    for="Products.CPSRSS.interfaces.IRSSChannel"
    3.27 +    name="edit.html"
    3.28 +    permission="cps.rss.ManageChannels"
    3.29 +    class=".browser.channels.EditChannel"
    3.30 +    template="channel_edit.pt"
    3.31 +    /-->
    3.32 +
    3.33 +</configure>
     4.1 new file mode 100644
     4.2 --- /dev/null
     4.3 +++ b/browser/manage_channels.pt
     4.4 @@ -0,0 +1,45 @@
     4.5 +<html xmlns:tal="http://xml.zope.org/namespaces/tal"
     4.6 +      xmlns:metal="http://xml.zope.org/namespaces/metal"
     4.7 +      metal:use-macro="here/main_template/macros/master">
     4.8 + <body>
     4.9 +
    4.10 +  <metal:main fill-slot="main"
    4.11 +              tal:define="channels view/channels">
    4.12 +
    4.13 +   <h1 i18n:translate="heading_manage_rss_channels">
    4.14 +    Gestion des flux RSS
    4.15 +   </h1>
    4.16 +
    4.17 +   <p tal:condition="not:channels"
    4.18 +      i18n:translate="manage_rss_channels_no_channel">
    4.19 +    Il n'y a pas encore de flux RSS &agrave; cet emplacement.
    4.20 +   </p>
    4.21 +   <tal:block condition="channels">
    4.22 +    <h2 i18n:translate="manage_rss_channels_available">Flux disponibles</h2>
    4.23 +    <ul>
    4.24 +     <li tal:repeat="channel channels">
    4.25 +       <a tal:content="channel/title"
    4.26 +          tal:attributes="href string:${channel/absolute_url_path}/edit.html">
    4.27 +       </a>
    4.28 +       <p tal:content="channel/description"/>
    4.29 +     </li>
    4.30 +    </ul>
    4.31 +   </tal:block>
    4.32 +
    4.33 +   <h2 i18n:translate="manage_rss_channels_add_channel">Ajouter un flux</h2>
    4.34 +   <p>
    4.35 +    <form action="add_channel" enctype="multipart/form-data" method="post">
    4.36 +     <label for="new_channel_url"
    4.37 +            i18n:translate="manage_rss_channels_new_url">
    4.38 +      Adresse du flux (URL)
    4.39 +      <input id="new_channel_url" name="url" type="text" width="60" />
    4.40 +      <br/>
    4.41 +      <input type="submit" value="button_ok" name="add" class="standalone"
    4.42 +             i18n:attributes="value" />
    4.43 +      </label>
    4.44 +     </form>
    4.45 +   </p>
    4.46 +  </metal:main>
    4.47 +
    4.48 + </body>
    4.49 +</html>
     5.1 --- a/configure.zcml
     5.2 +++ b/configure.zcml
     5.3 @@ -2,6 +2,10 @@
     5.4      xmlns="http://namespaces.zope.org/zope"
     5.5      xmlns:five="http://namespaces.zope.org/five">
     5.6  
     5.7 +  <permission id="cps.rss.ManageChannels" title="Manage RSS Channels" />
     5.8 +
     5.9 +  <include file="browser/configure.zcml"/>
    5.10 +
    5.11    <adapter
    5.12        factory=".exportimport.RSSToolXMLAdapter"
    5.13        provides="Products.GenericSetup.interfaces.IBody"
    5.14 @@ -23,4 +27,5 @@
    5.15        global="False"
    5.16        />
    5.17  
    5.18 +
    5.19  </configure>
     6.1 --- a/tests/test_views.py
     6.2 +++ b/tests/test_views.py
     6.3 @@ -60,8 +60,8 @@
     6.4  
     6.5          container = addRSSChannelContainer(self.folder)
     6.6          view = self.makeView()
     6.7 -        view.addChannel(get_feed_url('zope.rss'))
     6.8 -        view.addChannel(get_feed_url('trac_cps.rss'))
     6.9 +        view.addChannel(url=get_feed_url('zope.rss'))
    6.10 +        view.addChannel(url=get_feed_url('trac_cps.rss'))
    6.11  
    6.12          self.assertEquals(view.channels(),
    6.13                            (dict(id='zope-org', title='Zope.org'),
    6.14 @@ -69,5 +69,15 @@
    6.15                                  title='CPS CMS: Ticket Query')))
    6.16  
    6.17  
    6.18 +    def test_addChannel_form_no_cont(self):
    6.19 +        # test adding a channel while there's no container yet, from form
    6.20 +        view = self.makeView()
    6.21 +        view.request.form['channel_url'] = get_feed_url('zope.rss')
    6.22 +        view.addChannel()
    6.23 +
    6.24 +        self.assertEquals(view.channels(),
    6.25 +                          (dict(id='zope-org', title='Zope.org'),))
    6.26 +
    6.27 +
    6.28  def test_suite():
    6.29      return unittest.makeSuite(ManageChannelsTestCase)