Index: /waeup/branches/ulif-rewrite/src/waeup/utils/importexport.txt
===================================================================
--- /waeup/branches/ulif-rewrite/src/waeup/utils/importexport.txt	(revision 4158)
+++ /waeup/branches/ulif-rewrite/src/waeup/utils/importexport.txt	(revision 4159)
@@ -141,2 +141,134 @@
     >>> import os
     >>> os.unlink('myexport.xml')
+
+
+Importing CSV data
+==================
+
+The WAeUP portal supports import of CSV data for several different
+data types like faculties, students, and the like.
+
+Obtaining importers
+-------------------
+
+Before we actually do real imports, we have to provide so-called
+importers, that will do the job for us. Let's see how that works.
+
+We first create an object into that we can import something:
+
+    >>> import grok
+    >>> from waeup.interfaces import IWAeUPObject
+    >>> class MyContainer(grok.Container):
+    ...   #grok.implements(IWAeUPObject)
+    ...   def foo(self):
+    ...     print "Boo!"
+
+We get a suitable importer for certain objects by asking for an
+adapter to `IWAeUPCSVImporter`:
+
+    >>> from waeup.interfaces import IWAeUPCSVImporter
+
+If, however, we try to create an importer for our container, we won't
+find one right now:
+
+    >>> mycontainer = MyContainer()
+    >>> importer = IWAeUPCSVImporter(mycontainer)
+    Traceback (most recent call last):
+    ...
+    TypeError: ('Could not adapt', <MyContainer ...>, 
+                <InterfaceClass ...IWAeUPCSVImporter>)
+
+The reason is, that there is simply no importer defined for
+`MyContainer` objects.
+
+As an importer must take care for the specific structure of objects
+that receive the data, we must first define an importer for our
+special container class:
+
+    >>> import grok
+    >>> from waeup.utils.importexport import CSVImporter
+    >>> class MyImporter(CSVImporter):
+    ...   grok.context(MyContainer)
+    ...   datatype = u'My Stuff'
+    ...   column_terms = ['col1', 'col2']
+    ...   def doImport(self, filepath, clear_old_data=True,
+    ...                                overwrite=True):
+    ...     print "Data imported!"
+
+This importer derives from `CSVImporter`. The `CSVImporter` base class
+makes our importer automatically an adapter. Therefore we have to give
+the type of object we provide this importer for by using
+`grok.context()`.
+
+Instances of our importer will have an instance variable
+`self.context` available, which will hold the specific object into
+which data should be imported.
+
+The `datatype` string gives a description of the kind of importer we
+define. It might be used by UI components to offer services of this
+importer.
+
+The `column_terms` class variable holds the column headings we expect
+in a received CSV file.
+
+Our importer should also comply with the IWAeUPCSVImporter interface,
+therefore we defined a `doImport` method.
+
+To register our importer with the framework, we have to ``grok`` it
+first. Note, that in normal use this is done automatically on startup
+by the Grok framework:
+
+    >>> grok.testing.grok_component('MyImporter', MyImporter)
+    True
+
+Now we can get an importer:
+
+    >>> importer = IWAeUPCSVImporter(mycontainer)
+    >>> importer
+    <MyImporter object at 0x...>
+
+This importer is rather useless as it does not do much:
+
+    >>> importer.doImport('nonsense')
+    Data imported!
+
+This is a shameless lie. You might, however, get an idea of how to
+build your own, real importer.
+
+From the baseclass, however, we get some functionality out-of-the-box:
+We can validate files (without importing them):
+
+    >>> open('mydata.csv', 'wb').write(
+    ... """col1,col2
+    ... item1,item2
+    ... """)
+
+    >>> importer.validate('mydata.csv')
+    True
+
+If we deliver a misformatted file, the validator will notice that:
+
+    >>> open('crapdata.csv', 'wb').write("""
+    ... col1,blah
+    ... item1,item2
+    ... """)
+
+    >>> importer.validate('crapdata.csv')
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Validation Error: ... could not be found: col2'
+
+Apparently our input file lacks a ``col2`` column.
+
+The WAeUP portal already comes with a set of better suited
+importers. As they rely pretty much on the data structures they are
+built for, they are normally defined in the approriate code pieces
+where also the data structure itself is handled. So you can find an
+importer for faculty CSV data in the `facultycontainer` module.
+
+Clean up:
+
+    >>> import os
+    >>> os.unlink('crapdata.csv')
+    >>> os.unlink('mydata.csv')
+
