Back to index

plone3  3.1.7
txtfilter.py
Go to the documentation of this file.
00001 from wicked.fieldevent.interfaces import ITxtFilter, IField
00002 from wicked.fieldevent.interfaces import ITxtFilterList, EndFiltrationException
00003 from wicked import utils
00004 from zope.component import queryMultiAdapter, subscribers
00005 from zope.interface import implements
00006 from interfaces import ITxtFilter
00007 
00008 
00009 def txtfilter_output(field, instance, event):
00010     """a run once subscriber to process text in a pipeline"""
00011     
00012     if getattr(event, '_txtfiltered_', False):
00013         return
00014     
00015     filter_names = queryMultiAdapter((field, instance, event), ITxtFilterList)
00016     if not filter_names:
00017         return
00018 
00019     txts = subscribers((field, instance, event), ITxtFilter)
00020     txtmap = dict([(f.name, f) for f in txts])
00021 
00022     for name in filter_names:
00023         try:
00024             txtfilter = txtmap.get(name, None)
00025             if callable(txtfilter):
00026                 txtfilter()
00027         except EndFiltrationException, e:
00028             break
00029         
00030     event._txtfiltered_=True
00031 
00032 
00033 class TxtFilter(object):
00034     """Abstract Base for Filtration
00035     """
00036     implements(ITxtFilter)
00037     
00038     name = None    # required
00039     pattern = None
00040     
00041     def __init__(self, field, context, event):
00042         self.context = context
00043         self.field = field
00044         self.event = event
00045 
00046     @utils.memoize
00047     def findall(self, value):
00048         for pattern in self.patterns:
00049             val = pattern.findall(value)
00050             if len(val):
00051                 return val
00052         return val
00053         
00054     @utils.memoizedproperty
00055     def patterns(self):
00056         if not isinstance(self.pattern, list):
00057             return [self.pattern]
00058         return self.pattern
00059 
00060     @utils.memoizedproperty
00061     def chunks(self):
00062         """Simple text replacement via co-op with the modules"""
00063         for pattern in self.patterns:
00064             val=pattern.split(self.event.value)
00065             if len(val)>1:
00066                 return val
00067         return val
00068 
00069     @utils.memoizedproperty
00070     def dynamic(self):
00071         """tricky ben saller split"""
00072         return self.chunks[1::2]
00073 
00074     @utils.memoizedproperty
00075     def filtered_chunks(self):
00076         return [self._filterCore(d, **self.event.kwargs) for d in self.dynamic]
00077 
00078     @property
00079     def filtered_text(self):
00080         """join the two lists (knowing that len(text) == subs+1)"""
00081         return ''.join(ijoin(self.chunks[::2], self.filtered_chunks))
00082     
00083     def __call__(self):
00084         if len(self.chunks) == 1: # fastpath
00085             return 
00086 
00087         # set value reference (accessing filtered_text does the work)
00088         self.event.value = self.filtered_text
00089 
00090     def _filterCore(self,  chunk, **kwargs):
00091         """Subclasses override this to provide specific impls"""
00092         return ''
00093 
00094 
00095 def ijoin(a,b):
00096     """yield a0,b0,a1,b1.. if len(a) = len(b)+1"""
00097     yield(a[0])
00098     for i in range(1,len(a)):
00099         yield(b[i-1])
00100         yield(a[i])