Back to index

plone3  3.1.7
Public Member Functions | Private Member Functions | Private Attributes
plone.app.redirector.storage.RedirectionStorage Class Reference
Inheritance diagram for plone.app.redirector.storage.RedirectionStorage:
Inheritance graph
[legend]
Collaboration diagram for plone.app.redirector.storage.RedirectionStorage:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def add
def remove
def destroy
def has_path
def get
def redirects
def __iter__

Private Member Functions

def _canonical

Private Attributes

 _paths
 _rpaths

Detailed Description

Stores old paths to new paths.

Note - instead of storing "new paths" it could store object ids or
similar. In general, there is a many-to-one relationship between
"old paths" and "new paths". An "old path" points to exactly one
"new path" (where the object is now to be found), but a "new path"
can be pointed to by multiple different "old paths" (several objects
that used to be distinct are now consolidated into one).

The following tests (see test_storage.py) demonstrate its usage.

    >>> p = RedirectionStorage()

Add one redirect

    >>> p.has_path('/foo')
    False
    >>> p.add('/foo', '/bar')
    >>> p.has_path('/foo')
    True
    >>> p.get('/foo')
    '/bar'
    >>> p.has_path('/bar')
    False
    >>> p.redirects('/bar')
    ['/foo']

Note that trailing slashes are ignored:

    >>> p.has_path('/foo/')
    True
    >>> p.get('/foo/')
    '/bar'
    >>> p.redirects('/bar/')
    ['/foo']

Circular references are ignored

    >>> p.add('/circle', '/circle')
    >>> p.has_path('/circle')
    False
    >>> p.get('/circle', '_marker_')
    '_marker_'
    >>> p.redirects('/circle')
    []

Add another redirect

    >>> p.has_path('/baz')
    False
    >>> p.add('/baz', '/bar')
    >>> p.has_path('/baz')
    True
    >>> p.get('/baz')
    '/bar'
    >>> sorted(p.redirects('/bar'))
    ['/baz', '/foo']

Update a redirect

    >>> p.add('/foo', '/quux')
    >>> p.has_path('/foo')
    True
    >>> p.get('/foo')
    '/quux'
    >>> p.redirects('/bar')
    ['/baz']
    >>> p.redirects('/quux')
    ['/foo']

Remove a redirect

    >>> p.remove('/foo')
    >>> p.has_path('/foo')
    False
    >>> p.get('/foo', default='_notfound_')
    '_notfound_'
    >>> p.redirects('/quux')
    []

Update a redirect in a chain

    >>> p.add('/fred', '/foo')
    >>> p.get('/fred')
    '/foo'
    >>> sorted(p.redirects('/foo'))
    ['/fred']

    >>> p.add('/fred', '/barney')
    >>> p.get('/fred')
    '/barney'
    >>> sorted(p.redirects('/foo'))
    []
    >>> sorted(p.redirects('/barney'))
    ['/fred']

    >>> p.add('/barney', '/wilma')
    >>> p.get('/fred')
    '/wilma'
    >>> p.get('/barney')
    '/wilma'
    >>> sorted(p.redirects('/wilma'))
    ['/barney', '/fred']
    >>> sorted(p.redirects('/barney'))
    []

Destroy the target of a redirect

    >>> p.destroy('/wilma')
    >>> p.has_path('/barney')
    False
    >>> p.has_path('/fred')
    False
    >>> p.redirects('/wilma')
    []

We can get an iterator over all existing paths

    >>> iter(p)
    <OO-iterator object at ...>
    >>> sorted(p)
    ['/baz']

Now add some more

    >>> p.add('/foo', '/bar')
    >>> p.add('/barney', '/wilma')
    >>> sorted(p)
    ['/barney', '/baz', '/foo']

Definition at line 8 of file storage.py.


Constructor & Destructor Documentation

Definition at line 142 of file storage.py.

00142 
00143     def __init__(self):
00144         self._paths = OOBTree()
00145         self._rpaths = OOBTree()

Here is the caller graph for this function:


Member Function Documentation

Definition at line 209 of file storage.py.

00209 
00210     def __iter__(self):
00211         return iter(self._paths)

Here is the caller graph for this function:

def plone.app.redirector.storage.RedirectionStorage._canonical (   self,
  path 
) [private]

Definition at line 204 of file storage.py.

00204 
00205     def _canonical(self, path):
00206         if path.endswith('/'):
00207             path = path[:-1]
00208         return path

Here is the caller graph for this function:

def plone.app.redirector.storage.RedirectionStorage.add (   self,
  old_path,
  new_path 
)

Definition at line 146 of file storage.py.

00146 
00147     def add(self, old_path, new_path):
00148         old_path = self._canonical(old_path)
00149         new_path = self._canonical(new_path)
00150 
00151         if old_path == new_path:
00152             return
00153 
00154         # Forget any existing reverse paths to old_path
00155         existing_target = self._paths.get(old_path, None)
00156         if existing_target is not None and self._rpaths.has_key(existing_target):
00157             if len(self._rpaths[existing_target]) == 1:
00158                 del self._rpaths[existing_target]
00159             else:
00160                 self._rpaths[existing_target].remove(old_path)
00161 
00162         # Update any references that pointed to old_path
00163         for p in self.redirects(old_path):
00164             self._paths[p] = new_path
00165             self._rpaths.setdefault(new_path, OOSet()).insert(p)
00166 
00167         # Remove reverse paths for old_path
00168         if old_path in self._rpaths:
00169             del self._rpaths[old_path]
00170 
00171         self._paths[old_path] = new_path
00172         self._rpaths.setdefault(new_path, OOSet()).insert(old_path)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 183 of file storage.py.

00183 
00184     def destroy(self, new_path):
00185         new_path = self._canonical(new_path)
00186         for p in self._rpaths.get(new_path, []):
00187             if p in self._paths:
00188                 del self._paths[p]
00189         if self._rpaths.has_key(new_path):
00190             if new_path in self._rpaths:
00191                 del self._rpaths[new_path]

Here is the call graph for this function:

def plone.app.redirector.storage.RedirectionStorage.get (   self,
  old_path,
  default = None 
)

Definition at line 196 of file storage.py.

00196 
00197     def get(self, old_path, default=None):
00198         old_path = self._canonical(old_path)
00199         return self._paths.get(old_path, default)

Here is the call graph for this function:

Definition at line 192 of file storage.py.

00192 
00193     def has_path(self, old_path):
00194         old_path = self._canonical(old_path)
00195         return bool(self._paths.has_key(old_path))

Here is the call graph for this function:

Definition at line 200 of file storage.py.

00200 
00201     def redirects(self, new_path):
00202         new_path = self._canonical(new_path)
00203         return [a for a in self._rpaths.get(new_path, [])]

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 173 of file storage.py.

00173 
00174     def remove(self, old_path):
00175         old_path = self._canonical(old_path)
00176         new_path = self._paths.get(old_path, None)
00177         if new_path is not None and self._rpaths.has_key(new_path):
00178             if len(self._rpaths[new_path]) == 1:
00179                 del self._rpaths[new_path]
00180             else:
00181                 self._rpaths[new_path].remove(old_path)
00182         del self._paths[old_path]

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 143 of file storage.py.

Definition at line 144 of file storage.py.


The documentation for this class was generated from the following file: