From 3039453148fab51c1b6bceba4016d5472a637005 Mon Sep 17 00:00:00 2001 From: Ismael Carnales Date: Wed, 18 Feb 2009 18:38:26 +0000 Subject: [PATCH] added newitem with new item model and fields --HG-- extra : convert_revision : svn%3Ab85faa78-f9eb-468e-a121-7cced6da292c%40867 --- .../trunk/scrapy/contrib/newitem/__init__.py | 2 + .../contrib/{item => newitem}/fields.py | 20 ++++++++- scrapy/trunk/scrapy/contrib/newitem/models.py | 42 +++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 scrapy/trunk/scrapy/contrib/newitem/__init__.py rename scrapy/trunk/scrapy/contrib/{item => newitem}/fields.py (80%) create mode 100644 scrapy/trunk/scrapy/contrib/newitem/models.py diff --git a/scrapy/trunk/scrapy/contrib/newitem/__init__.py b/scrapy/trunk/scrapy/contrib/newitem/__init__.py new file mode 100644 index 000000000..0fda6a309 --- /dev/null +++ b/scrapy/trunk/scrapy/contrib/newitem/__init__.py @@ -0,0 +1,2 @@ +from scrapy.contrib.newitem.models import Item +from scrapy.contrib.newitem.fields import * diff --git a/scrapy/trunk/scrapy/contrib/item/fields.py b/scrapy/trunk/scrapy/contrib/newitem/fields.py similarity index 80% rename from scrapy/trunk/scrapy/contrib/item/fields.py rename to scrapy/trunk/scrapy/contrib/newitem/fields.py index e22d842a3..2352e115f 100644 --- a/scrapy/trunk/scrapy/contrib/item/fields.py +++ b/scrapy/trunk/scrapy/contrib/newitem/fields.py @@ -1,15 +1,31 @@ +import datetime +import decimal import re + class ItemFieldValueError(Exception): pass class ItemField(object): - def __init__(self, required=False): + def __init__(self, required=False, default=None): self.required = required + self.default = default def to_python(self, value): - pass + """ + Converts the input value into the expected Python data type. + Subclasses should override this. + """ + return value + + def from_list(self, list): + "Converts the input list into the expected Python data type." + return self.to_python(list.join('')) + + def default_value(self): + "Returns the default value for this field" + return self.default or self.to_python(None) class BooleanItemField(ItemField): diff --git a/scrapy/trunk/scrapy/contrib/newitem/models.py b/scrapy/trunk/scrapy/contrib/newitem/models.py new file mode 100644 index 000000000..acbd70b6b --- /dev/null +++ b/scrapy/trunk/scrapy/contrib/newitem/models.py @@ -0,0 +1,42 @@ +from scrapy.contrib.newitem.fields import ItemField + + +class Item(object): + """ + This is the base class for all scraped items. + """ + + def __init__(self): + self._values = {} + self._fields = self._get_fields() + + def _get_fields(self): + return dict(i for i in self.__class__.__dict__.iteritems() if + isinstance(i[1], ItemField)) + + def __setattr__(self, name, value): + if not name.startswith('_') and name in self._fields.keys(): + self._values[name] = self._fields[name].to_python(value) + else: + # for now setting values that are not fields is permitted + object.__setattr__(self, name, value) + + def __getattribute__(self, name): + if not name.startswith('_') and name in self._fields.keys(): + try: + return self._values[name] + except KeyError: + # what to to in this case? + # maybe return a default value: + # return self._fields[name].default_value() + return None + else: + return object.__getattribute__(self, name) + + def __repr__(self): + """ + Generate the following format so that items can be deserialized + easily: ClassName({'attrib': value, ...}) + """ + reprdict = dict((field, getattr(self, field)) for field in self._fields) + return "%s(%s)" % (self.__class__.__name__, repr(reprdict))