""" FeedDataRouter.py

Module for routing feed data from the poller
"""
__copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
__license__ = """
Straw is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

Straw is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. """


import Event
import ImageCache

class FeedDataRouter(object):
    def __init__(self, feed):
        ImageCache.cache.signal_connect(Event.ImageUpdatedSignal,
                                              self.image_updated)
        self._feed = feed
        self._stopper = None
        # stuff we are potentially waiting for
        self._wait_data = 0
        self._wait_images = {}

    # public parts
    def start_polling(self):
        self._wait_data = 1
        self.update_process_status()

    def route_no_data(self):
        self._wait_data = 0
        self._feed.error = None
        self._stopper = None
        self.update_process_status()

    def route_all(self, header, parsed):
        needed_loading = self._feed.load_contents()
        self.route_data(header, parsed)
        self.route_extras()
        if needed_loading:
            self._feed.unload_contents()

    def route_data(self, header, parsed):
        if header:
            etag = header.getheader('etag', None)
            if etag:
                etag = etag.strip()
                self._feed.previous_etag = etag
        self._feed.channel_title = parsed.title
        self._feed.channel_description = parsed.description
        self._feed.channel_copyright = parsed.copyright
        self._feed.channel_link = parsed.link
        self._feed.channel_creator = parsed.creator
        if len(parsed.items):
            parsed.items.reverse()
            self._feed.add_items(parsed.items)
        self._feed.error = None
        self._wait_data = 0
        self._feed.poll_done()

    def route_extras(self):
        try:
            for i in self._feed.items:
                for name in i.image_keys():
                    image = i.get_image(name)
                    if image.status == image.WAITING:
                        self._wait_images[image.url] = 1
        except Exception, ex:
            # if we don't get the images, we can probably still show
            # the text
            pass
        self.update_process_status()

    def set_error(self, err):
        self._wait_data = 0
        self._feed.error = err
        self.update_process_status()
        return

    def set_stopper(self, stopper):
        self._stopper = stopper
        stopper.signal_connect(Event.PollingStoppedSignal,
                               self._polling_stopped)
    def get_stopper(self): return self._stopper
    stopper = property(get_stopper, set_stopper)

    def poll_done(self):
        self._feed.poll_done()
        self._stopper = None

    def stop_polling(self):
        if self._stopper:
            self._stopper.stop()
            self._stopper = None
        for image in self._wait_images.keys():
            ImageCache.cache.stop_transfer(image)
            del self._wait_images[image]
        self.update_process_status()
        self._feed.poll_done()

    def _polling_stopped(self, signal):
        self.poll_done()

    # private parts

    def image_updated(self, signal):
        if signal.url in self._wait_images:
            del self._wait_images[signal.url]
        self.update_process_status()

    def update_process_status(self):
        length_images = len(self._wait_images)
        if self._wait_data or length_images:
            self._feed.process_status = self._feed.STATUS_POLLING
        else:
            self._feed.process_status = self._feed.STATUS_IDLE
