#!/usr/bin/python3

import uuid

from scrapy import signals
from scrapy.exceptions import DropItem

from feeds.exporters import AtomExporter


class AtomAutogenerateIdPipeline(object):
    """Autogenerate the id field in case it is missing."""
    def process_item(self, item, spider):
        if 'id' in item:
            return item
        else:
            if 'link' in item:
                item['id'] = uuid.uuid5(uuid.NAMESPACE_DNS, item['link']).urn
                return item
            else:
                raise DropItem('A link is required to autogenerate the feed '
                               'id for: {}'.format(item))


class AtomCheckRequiredFieldsPipeline(object):
    """Check presence of required fields."""
    def process_item(self, item, spider):
        for required in ('id', 'title', 'link'):
            if required in item:
                return item
            else:
                raise DropItem('The required field "{}" is missing in: {}.'.
                               format(required, item))


class AtomExportPipeline(object):
    """Export items as atom feeds."""
    def __init__(self, output_path):
        self._output_path = output_path
        self._exporters = {}

    @classmethod
    def from_crawler(cls, crawler):
        pipeline = cls(
            output_path=crawler.settings.get('ATOM_OUTPUT_PATH', 'output'),
        )
        crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
        crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
        return pipeline

    def spider_opened(self, spider):
        self._exporters[spider] = AtomExporter(self._output_path, spider.name)
        self._exporters[spider].start_exporting()

    def spider_closed(self, spider):
        self._exporters[spider].finish_exporting()
        self._exporters.pop(spider)

    def process_item(self, item, spider):
        self._exporters[spider].export_item(item)
        return item

# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 smartindent autoindent

@@ -134,16 +134,54 @@
 xporter%0A
+from feeds.items import FeedEntryItem%0A
 %0A%0Aclass 
@@ -819,109 +819,203 @@
     
-for required in ('id', 'title', 'link'):%0A            if required in item:%0A                return
+def raise_if_missing(name, item):%0A            if name not in item:%0A                raise DropItem('The required field %22%7B%7D%22 is missing in: %7B%7D.'.%0A                               format(name,
  item
+))%0A
 %0A   
@@ -1023,149 +1023,335 @@
     
-    else:%0A                raise DropItem('The required field %22%7B%7D%22 is missing in: %7B%7D.'.%0A                               format(required, item))
+# Required fields for all items%0A        for required in ('id', 'title', 'link'):%0A            raise_if_missing(required, item)%0A%0A        # Required fields for FeedEntryItems%0A        if isinstance(item, FeedEntryItem):%0A            for required in ('updated',):%0A                raise_if_missing(required, item)%0A%0A        return item
 %0A%0A%0Ac

Make updated a required field