| 1 | import sys |
|---|
| 2 | from types import StringTypes |
|---|
| 3 | from logging import NOTSET, DEBUG, INFO, ERROR |
|---|
| 4 | from logging import Logger, StreamHandler, Formatter |
|---|
| 5 | from StringIO import StringIO |
|---|
| 6 | from zope.component import getAdapter |
|---|
| 7 | from Acquisition import aq_base, aq_inner |
|---|
| 8 | |
|---|
| 9 | from quintagroup.canonicalpath.interfaces import ICanonicalPath |
|---|
| 10 | from quintagroup.canonicalpath.interfaces import ICanonicalLink |
|---|
| 11 | from quintagroup.canonicalpath.adapters import PROPERTY_LINK |
|---|
| 12 | from quintagroup.canonicalpath.adapters import PROPERTY_PATH |
|---|
| 13 | from quintagroup.canonicalpath.adapters import DefaultPropertyAdapter |
|---|
| 14 | |
|---|
| 15 | class CanonicalConvertor(object): |
|---|
| 16 | """Convert canonical link to canonical path and vice versa.""" |
|---|
| 17 | |
|---|
| 18 | def __init__(self, portal_url): |
|---|
| 19 | """Create instanse of convertor. |
|---|
| 20 | - *portal_url* (string), add in the front of canonical path property |
|---|
| 21 | value for get canonical link. |
|---|
| 22 | - *logger_name* - name of the logger |
|---|
| 23 | """ |
|---|
| 24 | self._initLogger() |
|---|
| 25 | self.portal_url = portal_url |
|---|
| 26 | |
|---|
| 27 | # General APIs |
|---|
| 28 | def getLogs(self): |
|---|
| 29 | self._inout.flush() |
|---|
| 30 | return self._inout.getvalue() |
|---|
| 31 | |
|---|
| 32 | def cleanupLogs(self): |
|---|
| 33 | self._inout = StringIO() |
|---|
| 34 | |
|---|
| 35 | def convertILinkToPath(self, obj): |
|---|
| 36 | """Convert canonical link to canonical path""" |
|---|
| 37 | return self._convert(obj, ICanonicalLink, ICanonicalPath, |
|---|
| 38 | self._convertL2P) |
|---|
| 39 | |
|---|
| 40 | def convertIPathToLink(self, obj): |
|---|
| 41 | """Convert canonical path to canonical link""" |
|---|
| 42 | return self._convert(obj, ICanonicalPath, ICanonicalLink, |
|---|
| 43 | self._convertP2L) |
|---|
| 44 | |
|---|
| 45 | def convertPLinkToPath(self, obj, prop=PROPERTY_LINK): |
|---|
| 46 | """Convert canonical link, got from the *prop* parameter |
|---|
| 47 | to canonical path. |
|---|
| 48 | """ |
|---|
| 49 | return self._convert(obj, prop, ICanonicalPath, |
|---|
| 50 | self._convertL2P) |
|---|
| 51 | |
|---|
| 52 | def convertPPathToLink(self, obj, prop=PROPERTY_PATH): |
|---|
| 53 | """Convert canonical path, got from the *prop* parameter |
|---|
| 54 | to canonical link. |
|---|
| 55 | """ |
|---|
| 56 | return self._convert(obj, prop, ICanonicalLink, |
|---|
| 57 | self._convertP2L) |
|---|
| 58 | |
|---|
| 59 | # Service methods |
|---|
| 60 | def _convert(self, obj, src_iface, dst_iface, converter): |
|---|
| 61 | """Convert canonical from source canonical interface |
|---|
| 62 | to destination canonical interface. |
|---|
| 63 | |
|---|
| 64 | Return True is successfull, False otherwise. |
|---|
| 65 | Log results in logger. |
|---|
| 66 | """ |
|---|
| 67 | src_msg = type(src_iface) in StringTypes and src_iface or src_iface.__name__ |
|---|
| 68 | msg = "Migrate %s into %s for %s object: " \ |
|---|
| 69 | % (src_msg, dst_iface.__name__, obj.absolute_url()) |
|---|
| 70 | try: |
|---|
| 71 | src = self._getOrMakeAdapter(obj, src_iface) |
|---|
| 72 | dst = getAdapter(obj, dst_iface) |
|---|
| 73 | # XXX: Check is this correct work XXX |
|---|
| 74 | obj = aq_base(aq_inner(obj)) |
|---|
| 75 | # XXX |
|---|
| 76 | converter(src, dst) |
|---|
| 77 | except Exception: |
|---|
| 78 | import sys |
|---|
| 79 | et, em, etr = map(str, sys.exc_info()) |
|---|
| 80 | lev = ERROR |
|---|
| 81 | msg += "ERROR: %s: %s" % (et, em) |
|---|
| 82 | else: |
|---|
| 83 | lev = INFO |
|---|
| 84 | msg += "SUCCESS" |
|---|
| 85 | self._logger.log(lev, msg) |
|---|
| 86 | |
|---|
| 87 | return lev == INFO and True or False |
|---|
| 88 | |
|---|
| 89 | def _getOrMakeAdapter(self, obj, arg): |
|---|
| 90 | """Function return adapter for process of the property. |
|---|
| 91 | Adapter get by interface (if arg is not a string - interface assumed) |
|---|
| 92 | OR if arg is string - adapter created from DefaultCanonicalAdapter. |
|---|
| 93 | """ |
|---|
| 94 | if type(arg) in StringTypes: |
|---|
| 95 | adapter = DefaultPropertyAdapter(obj) |
|---|
| 96 | adapter.prop = arg |
|---|
| 97 | return adapter |
|---|
| 98 | else: |
|---|
| 99 | return getAdapter(obj, arg) |
|---|
| 100 | |
|---|
| 101 | def _convertP2L(self, src, dst): |
|---|
| 102 | """Convert canonical path to canonical link.""" |
|---|
| 103 | cpath = src.getProp() |
|---|
| 104 | cpath = cpath.startswith('/') and cpath or '/' + cpath |
|---|
| 105 | dst.canonical_link = self.portal_url + cpath |
|---|
| 106 | src.delProp() |
|---|
| 107 | |
|---|
| 108 | def _convertL2P(self, src, dst): |
|---|
| 109 | """Convert canonical link to canonical path.""" |
|---|
| 110 | raise NotImplementedError( |
|---|
| 111 | "Convertion from canonical link to canonical path not implemented") |
|---|
| 112 | |
|---|
| 113 | def _initLogger(self): |
|---|
| 114 | self._inout = StringIO() |
|---|
| 115 | handler = StreamHandler(self._inout) |
|---|
| 116 | handler.setLevel(DEBUG) |
|---|
| 117 | formatter = Formatter(fmt="[%(asctime)s]: %(message)s", |
|---|
| 118 | datefmt="%H:%M:%S") |
|---|
| 119 | handler.setFormatter(formatter) |
|---|
| 120 | self._logger = Logger("quintagroup.canonicalpath", NOTSET) |
|---|
| 121 | self._logger.addHandler(handler) |
|---|
| 122 | |
|---|