appy.pod: improved styles mapping system: one may now express things like: 'p[text-align=center]':'StandardCentered' (ie, map an HTML tag having some CSS attributes to a specific ODT style). See verbose docstrings in styles_manager.py.
This commit is contained in:
parent
30a51b7c1d
commit
7d844070df
|
@ -5,13 +5,12 @@ from appy import Object
|
||||||
from appy.gen.layout import Table
|
from appy.gen.layout import Table
|
||||||
from appy.gen.layout import defaultFieldLayouts
|
from appy.gen.layout import defaultFieldLayouts
|
||||||
from appy.gen.po import PoMessage
|
from appy.gen.po import PoMessage
|
||||||
from appy.gen.utils import sequenceTypes, GroupDescr, Keywords, getClassName, \
|
from appy.gen.utils import GroupDescr, Keywords, getClassName, SomeObjects
|
||||||
SomeObjects
|
|
||||||
import appy.pod
|
import appy.pod
|
||||||
from appy.pod.renderer import Renderer
|
from appy.pod.renderer import Renderer
|
||||||
from appy.shared.data import countries
|
from appy.shared.data import countries
|
||||||
from appy.shared.utils import Traceback, getOsTempFolder, formatNumber, \
|
from appy.shared.utils import Traceback, getOsTempFolder, formatNumber, \
|
||||||
FileWrapper
|
FileWrapper, sequenceTypes
|
||||||
|
|
||||||
# Default Appy permissions -----------------------------------------------------
|
# Default Appy permissions -----------------------------------------------------
|
||||||
r, w, d = ('read', 'write', 'delete')
|
r, w, d = ('read', 'write', 'delete')
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import os, os.path, sys, re, time, random, types, base64, urllib
|
import os, os.path, sys, re, time, random, types, base64, urllib
|
||||||
from appy.shared import mimeTypes
|
from appy.shared import mimeTypes
|
||||||
from appy.shared.utils import getOsTempFolder
|
from appy.shared.utils import getOsTempFolder, sequenceTypes
|
||||||
from appy.shared.data import languages
|
from appy.shared.data import languages
|
||||||
import appy.gen
|
import appy.gen
|
||||||
from appy.gen import Type, Search, Selection
|
from appy.gen import Type, Search, Selection
|
||||||
from appy.gen.utils import SomeObjects, sequenceTypes, getClassName
|
from appy.gen.utils import SomeObjects, getClassName
|
||||||
from appy.gen.mixins import BaseMixin
|
from appy.gen.mixins import BaseMixin
|
||||||
from appy.gen.wrappers import AbstractWrapper
|
from appy.gen.wrappers import AbstractWrapper
|
||||||
from appy.gen.descriptors import ClassDescriptor
|
from appy.gen.descriptors import ClassDescriptor
|
||||||
|
|
|
@ -9,6 +9,7 @@ import appy.gen as gen
|
||||||
from appy.gen.utils import *
|
from appy.gen.utils import *
|
||||||
from appy.gen.layout import Table, defaultPageLayouts
|
from appy.gen.layout import Table, defaultPageLayouts
|
||||||
from appy.gen.descriptors import WorkflowDescriptor, ClassDescriptor
|
from appy.gen.descriptors import WorkflowDescriptor, ClassDescriptor
|
||||||
|
from appy.shared.utils import sequenceTypes
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class BaseMixin:
|
class BaseMixin:
|
||||||
|
|
|
@ -33,9 +33,9 @@ def convertRolesToEmails(users, portal):
|
||||||
SENDMAIL_ERROR = 'Error while sending mail: %s.'
|
SENDMAIL_ERROR = 'Error while sending mail: %s.'
|
||||||
ENCODING_ERROR = 'Encoding error while sending mail: %s.'
|
ENCODING_ERROR = 'Encoding error while sending mail: %s.'
|
||||||
|
|
||||||
from appy.gen.utils import sequenceTypes
|
|
||||||
from appy.gen.descriptors import WorkflowDescriptor
|
|
||||||
import socket
|
import socket
|
||||||
|
from appy.shared.utils import sequenceTypes
|
||||||
|
from appy.gen.descriptors import WorkflowDescriptor
|
||||||
|
|
||||||
def sendMail(obj, transition, transitionName, workflow):
|
def sendMail(obj, transition, transitionName, workflow):
|
||||||
'''Sends mail about p_transition that has been triggered on p_obj that is
|
'''Sends mail about p_transition that has been triggered on p_obj that is
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import re, os, os.path
|
import re, os, os.path
|
||||||
import appy.pod
|
|
||||||
sequenceTypes = (list, tuple)
|
|
||||||
|
|
||||||
# Function for creating a Zope object ------------------------------------------
|
# Function for creating a Zope object ------------------------------------------
|
||||||
def createObject(folder, id, className, appName, wf=True):
|
def createObject(folder, id, className, appName, wf=True):
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
import os, os.path, mimetypes
|
import os, os.path, mimetypes
|
||||||
import appy.pod
|
import appy.pod
|
||||||
from appy.gen import Type, Search, Ref, String
|
from appy.gen import Type, Search, Ref, String
|
||||||
from appy.gen.utils import sequenceTypes, createObject
|
from appy.gen.utils import createObject
|
||||||
from appy.shared.utils import getOsTempFolder, executeCommand, normalizeString
|
from appy.shared.utils import getOsTempFolder, executeCommand, \
|
||||||
|
normalizeString, sequenceTypes
|
||||||
from appy.shared.xml_parser import XmlMarshaller
|
from appy.shared.xml_parser import XmlMarshaller
|
||||||
from appy.shared.csv_parser import CsvMarshaller
|
from appy.shared.csv_parser import CsvMarshaller
|
||||||
|
|
||||||
|
|
|
@ -243,8 +243,8 @@ class Renderer:
|
||||||
for converting a chunk of XHTML content (p_xhtmlString) into a chunk
|
for converting a chunk of XHTML content (p_xhtmlString) into a chunk
|
||||||
of ODT content.'''
|
of ODT content.'''
|
||||||
stylesMapping = self.stylesManager.checkStylesMapping(stylesMapping)
|
stylesMapping = self.stylesManager.checkStylesMapping(stylesMapping)
|
||||||
# xhtmlString can only be a chunk of XHTML. So we must surround it a
|
# xhtmlString can only be a chunk of XHTML. So we must surround it with
|
||||||
# tag in order to get a XML-compliant file (we need a root tag).
|
# a tag in order to get a XML-compliant file (we need a root tag).
|
||||||
if xhtmlString == None: xhtmlString = ''
|
if xhtmlString == None: xhtmlString = ''
|
||||||
xhtmlContent = '<p>%s</p>' % xhtmlString
|
xhtmlContent = '<p>%s</p>' % xhtmlString
|
||||||
return Xhtml2OdtConverter(xhtmlContent, encoding, self.stylesManager,
|
return Xhtml2OdtConverter(xhtmlContent, encoding, self.stylesManager,
|
||||||
|
|
|
@ -191,7 +191,7 @@ class StylesManager:
|
||||||
self.paragraphStyles = self.styles.getStyles('paragraph')
|
self.paragraphStyles = self.styles.getStyles('paragraph')
|
||||||
|
|
||||||
def checkStylesAdequation(self, htmlStyle, odtStyle):
|
def checkStylesAdequation(self, htmlStyle, odtStyle):
|
||||||
'''Checks that p_odtStyle my be used for style p_htmlStyle.'''
|
'''Checks that p_odtStyle may be used for style p_htmlStyle.'''
|
||||||
if (htmlStyle in XHTML_PARAGRAPH_TAGS_NO_LISTS) and \
|
if (htmlStyle in XHTML_PARAGRAPH_TAGS_NO_LISTS) and \
|
||||||
(odtStyle in self.textStyles):
|
(odtStyle in self.textStyles):
|
||||||
raise PodError(
|
raise PodError(
|
||||||
|
@ -202,9 +202,49 @@ class StylesManager:
|
||||||
htmlStyle, odtStyle.displayName))
|
htmlStyle, odtStyle.displayName))
|
||||||
|
|
||||||
def checkStylesMapping(self, stylesMapping):
|
def checkStylesMapping(self, stylesMapping):
|
||||||
'''Checks that the given p_stylesMapping is correct. Returns the same
|
'''Checks that the given p_stylesMapping is correct, and returns the
|
||||||
dict as p_stylesMapping, but with Style instances as values, instead
|
internal representation of it. p_stylesMapping is a dict where:
|
||||||
of strings (style's display names).'''
|
* every key can be:
|
||||||
|
(1) the name of a XHTML 'paragraph-like' tag (p, h1, h2...)
|
||||||
|
(2) the name of a XHTML 'text-like' tag (span, b, i, em...)
|
||||||
|
(3) the name of a CSS class
|
||||||
|
(4) string 'h*'
|
||||||
|
* every value must be:
|
||||||
|
(a) if the key is (1), (2) or (3), value must be the display name
|
||||||
|
of an ODT style
|
||||||
|
(b) if the key is (4), value must be an integer indicating how to
|
||||||
|
map the outline level of outlined styles (ie, for mapping HTML
|
||||||
|
tag "h1" to the ODT style with outline-level=2, value must be
|
||||||
|
integer "1". In that case, h2 will be mapped to the ODT style
|
||||||
|
with outline-level=3, etc.). Note that this value can also be
|
||||||
|
negative.
|
||||||
|
* Some precision now about about keys. If key is (1) or (2),
|
||||||
|
parameters can be given between square brackets. Every such
|
||||||
|
parameter represents a CSS attribute and its value. For example, a
|
||||||
|
key can be:
|
||||||
|
p[text-align=center,color=blue]
|
||||||
|
|
||||||
|
This feature allows to map XHTML tags having different CSS
|
||||||
|
attributes to different ODT styles.
|
||||||
|
|
||||||
|
The method returns a dict which is the internal representation of
|
||||||
|
the styles mapping:
|
||||||
|
* every key can be:
|
||||||
|
(I) the name of a XHTML tag, corresponding to (1) or (2) whose
|
||||||
|
potential parameters have been removed;
|
||||||
|
(II) the name of a CSS class (=(3))
|
||||||
|
(III) string 'h*' (=(4))
|
||||||
|
* every value can be:
|
||||||
|
(i) a Styles instance that was found from the specified ODT style
|
||||||
|
display name in p_stylesMapping, if key is (I) and if only one,
|
||||||
|
non-parameterized XHTML tag was defined in p_stylesMapping;
|
||||||
|
(ii) a list of the form [ (params, Style), (params, Style),...]
|
||||||
|
if key is (I) and if one or more parameterized (or not) XHTML
|
||||||
|
tags representing the same tag were found in p_stylesMapping.
|
||||||
|
params, which can be None, is a dict whose pairs are of the
|
||||||
|
form (cssAttribute, cssValue).
|
||||||
|
(iii) an integer value (=(b)).
|
||||||
|
'''
|
||||||
res = {}
|
res = {}
|
||||||
if not isinstance(stylesMapping, dict) and \
|
if not isinstance(stylesMapping, dict) and \
|
||||||
not isinstance(stylesMapping, UserDict):
|
not isinstance(stylesMapping, UserDict):
|
||||||
|
@ -221,6 +261,16 @@ class StylesManager:
|
||||||
if (xhtmlStyleName != 'h*') and \
|
if (xhtmlStyleName != 'h*') and \
|
||||||
((not xhtmlStyleName) or (not odtStyleName)):
|
((not xhtmlStyleName) or (not odtStyleName)):
|
||||||
raise PodError(MAPPING_ELEM_EMPTY)
|
raise PodError(MAPPING_ELEM_EMPTY)
|
||||||
|
# Separate CSS attributes if any
|
||||||
|
cssAttrs = None
|
||||||
|
if '[' in xhtmlStyleName:
|
||||||
|
xhtmlStyleName, attrs = xhtmlStyleName.split('[')
|
||||||
|
xhtmlStyleName = xhtmlStyleName.strip()
|
||||||
|
attrs = attrs.strip()[:-1].split(',')
|
||||||
|
cssAttrs = {}
|
||||||
|
for attr in attrs:
|
||||||
|
name, value = attr.split('=')
|
||||||
|
cssAttrs[name.strip()] = value.strip()
|
||||||
if xhtmlStyleName in XHTML_UNSTYLABLE_TAGS:
|
if xhtmlStyleName in XHTML_UNSTYLABLE_TAGS:
|
||||||
raise PodError(UNSTYLABLE_TAG % (xhtmlStyleName,
|
raise PodError(UNSTYLABLE_TAG % (xhtmlStyleName,
|
||||||
XHTML_UNSTYLABLE_TAGS))
|
XHTML_UNSTYLABLE_TAGS))
|
||||||
|
@ -232,9 +282,123 @@ class StylesManager:
|
||||||
else:
|
else:
|
||||||
raise PodError(STYLE_NOT_FOUND % odtStyleName)
|
raise PodError(STYLE_NOT_FOUND % odtStyleName)
|
||||||
self.checkStylesAdequation(xhtmlStyleName, odtStyle)
|
self.checkStylesAdequation(xhtmlStyleName, odtStyle)
|
||||||
|
# Store this style mapping in the result.
|
||||||
|
alreadyInRes = xhtmlStyleName in res
|
||||||
|
if cssAttrs or alreadyInRes:
|
||||||
|
# I must create a complex structure (ii) for this mapping.
|
||||||
|
if not alreadyInRes:
|
||||||
|
res[xhtmlStyleName] = [(cssAttrs, odtStyle)]
|
||||||
|
else:
|
||||||
|
value = res[xhtmlStyleName]
|
||||||
|
if not isinstance(value, list):
|
||||||
|
res[xhtmlStyleName] = [(cssAttrs, odtStyle), \
|
||||||
|
(None, value)]
|
||||||
|
else:
|
||||||
|
res.insert(0, (cssAttrs, odtStyle))
|
||||||
|
else:
|
||||||
|
# I must create a simple structure (i) for this mapping.
|
||||||
res[xhtmlStyleName] = odtStyle
|
res[xhtmlStyleName] = odtStyle
|
||||||
else:
|
else:
|
||||||
res[xhtmlStyleName] = odtStyleName # In this case, it is the
|
# In this case (iii), it is the outline level, not an ODT style
|
||||||
# outline level, not an ODT style name
|
# name.
|
||||||
|
res[xhtmlStyleName] = odtStyleName
|
||||||
|
return res
|
||||||
|
|
||||||
|
def styleMatch(self, attrs, matchingAttrs):
|
||||||
|
'''p_match is a dict of attributes found on some HTML element.
|
||||||
|
p_matchingAttrs is a dict of attributes corresponding to some style.
|
||||||
|
This method returns True if p_attrs contains the winning (name,value)
|
||||||
|
pairs that match those in p_matchingAttrs. Note that ALL attrs in
|
||||||
|
p_matchingAttrs must be present in p_attrs.'''
|
||||||
|
for name, value in matchingAttrs.iteritems():
|
||||||
|
if name not in attrs: return
|
||||||
|
if value != attrs[name]: return
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getStyleFromMapping(self, elem, attrs, styles):
|
||||||
|
'''p_styles is a Style instance or a list of (cssParams, Style) tuples.
|
||||||
|
Depending on CSS attributes found in p_attrs, this method returns
|
||||||
|
the relevant Style instance.'''
|
||||||
|
if isinstance(styles, Style): return styles
|
||||||
|
hasStyleInfo = attrs and ('style' in attrs)
|
||||||
|
if not hasStyleInfo:
|
||||||
|
# If I have, at the last position in p_styles, the style related to
|
||||||
|
# no attribute at all, I return it.
|
||||||
|
lastAttrs, lastStyle = styles[-1]
|
||||||
|
if lastAttrs == None: return lastStyle
|
||||||
|
else: return
|
||||||
|
# If I am here, I have style info. Check if it corresponds to some style
|
||||||
|
# in p_styles.
|
||||||
|
infos = attrs['style'].split(';')
|
||||||
|
styleInfo = {}
|
||||||
|
for info in infos:
|
||||||
|
if not info.strip(): continue
|
||||||
|
name, value = info.split(':')
|
||||||
|
styleInfo[name.strip()] = value.strip()
|
||||||
|
for matchingAttrs, style in styles:
|
||||||
|
if self.styleMatch(styleInfo, matchingAttrs):
|
||||||
|
return style
|
||||||
|
|
||||||
|
def findStyle(self, elem, attrs, classValue, localStylesMapping):
|
||||||
|
'''Finds the ODT style that must be applied to XHTML p_elem that has
|
||||||
|
attrs p_attrs. In some cases, p_attrs is None; the value of the
|
||||||
|
"class" attribute is given instead (in p_classValue).
|
||||||
|
|
||||||
|
The global styles mapping is in self.stylesMapping; the local styles
|
||||||
|
mapping is in p_localStylesMapping.
|
||||||
|
|
||||||
|
Here are the places where we will search, ordered by
|
||||||
|
priority (highest first):
|
||||||
|
(1) local styles mapping (CSS style in "class" attr)
|
||||||
|
(2) " (HTML elem)
|
||||||
|
(3) global styles mapping (CSS style in "class" attr)
|
||||||
|
(4) " (HTML elem)
|
||||||
|
(5) ODT style that has the same name as CSS style in "class" attr
|
||||||
|
(6) Predefined pod-specific ODT style that has the same name as
|
||||||
|
CSS style in "class" attr
|
||||||
|
(7) ODT style that has the same outline level as HTML elem.
|
||||||
|
'''
|
||||||
|
res = None
|
||||||
|
cssStyleName = None
|
||||||
|
if attrs and attrs.has_key('class'):
|
||||||
|
cssStyleName = attrs['class']
|
||||||
|
if classValue:
|
||||||
|
cssStyleName = classValue
|
||||||
|
# (1)
|
||||||
|
if localStylesMapping.has_key(cssStyleName):
|
||||||
|
res = localStylesMapping[cssStyleName]
|
||||||
|
# (2)
|
||||||
|
if (not res) and localStylesMapping.has_key(elem):
|
||||||
|
styles = localStylesMapping[elem]
|
||||||
|
res = self.getStyleFromMapping(elem, attrs, styles)
|
||||||
|
# (3)
|
||||||
|
if (not res) and self.stylesMapping.has_key(cssStyleName):
|
||||||
|
res = self.stylesMapping[cssStyleName]
|
||||||
|
# (4)
|
||||||
|
if (not res) and self.stylesMapping.has_key(elem):
|
||||||
|
styles = self.stylesMapping[elem]
|
||||||
|
res = self.getStyleFromMapping(elem, attrs, styles)
|
||||||
|
# (5)
|
||||||
|
if (not res) and self.styles.has_key(cssStyleName):
|
||||||
|
res = self.styles[cssStyleName]
|
||||||
|
# (6)
|
||||||
|
if (not res) and self.podSpecificStyles.has_key(cssStyleName):
|
||||||
|
res = self.podSpecificStyles[cssStyleName]
|
||||||
|
# (7)
|
||||||
|
if not res:
|
||||||
|
# Try to find a style with the correct outline level
|
||||||
|
if elem in XHTML_HEADINGS:
|
||||||
|
# Is there a delta that must be taken into account ?
|
||||||
|
outlineDelta = 0
|
||||||
|
if localStylesMapping.has_key('h*'):
|
||||||
|
outlineDelta += localStylesMapping['h*']
|
||||||
|
elif self.stylesMapping.has_key('h*'):
|
||||||
|
outlineDelta += self.stylesMapping['h*']
|
||||||
|
outlineLevel = int(elem[1]) + outlineDelta
|
||||||
|
# Normalize the outline level
|
||||||
|
if outlineLevel < 1: outlineLevel = 1
|
||||||
|
res = self.styles.getParagraphStyleAtLevel(outlineLevel)
|
||||||
|
if res:
|
||||||
|
self.checkStylesAdequation(elem, res)
|
||||||
return res
|
return res
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -496,8 +496,6 @@ class Xhtml2OdtConverter:
|
||||||
self.xhtmlString = xhtmlString
|
self.xhtmlString = xhtmlString
|
||||||
self.encoding = encoding # Todo: manage encoding that is not utf-8
|
self.encoding = encoding # Todo: manage encoding that is not utf-8
|
||||||
self.stylesManager = stylesManager
|
self.stylesManager = stylesManager
|
||||||
self.odtStyles = stylesManager.styles
|
|
||||||
self.globalStylesMapping = stylesManager.stylesMapping
|
|
||||||
self.localStylesMapping = localStylesMapping
|
self.localStylesMapping = localStylesMapping
|
||||||
self.odtChunk = None
|
self.odtChunk = None
|
||||||
self.xhtmlParser = XhtmlParser(XhtmlEnvironment(renderer), self)
|
self.xhtmlParser = XhtmlParser(XhtmlEnvironment(renderer), self)
|
||||||
|
@ -507,59 +505,6 @@ class Xhtml2OdtConverter:
|
||||||
return self.xhtmlParser.env.res
|
return self.xhtmlParser.env.res
|
||||||
|
|
||||||
def findStyle(self, elem, attrs=None, classValue=None):
|
def findStyle(self, elem, attrs=None, classValue=None):
|
||||||
'''Finds the ODT style that must be applied to XHTML p_elem that has
|
return self.stylesManager.findStyle(elem, attrs, classValue,
|
||||||
attrs p_attrs. In some cases, p_attrs is not given; the value of the
|
self.localStylesMapping)
|
||||||
"class" attribute is given instead (in p_classValue).
|
|
||||||
|
|
||||||
Here are the places where we will search, ordered by
|
|
||||||
priority (highest first):
|
|
||||||
(1) local styles mapping (CSS style in "class" attr)
|
|
||||||
(2) " (HTML elem)
|
|
||||||
(3) global styles mapping (CSS style in "class" attr)
|
|
||||||
(4) " (HTML elem)
|
|
||||||
(5) ODT style that has the same name as CSS style in "class" attr
|
|
||||||
(6) Prefefined pod-specific ODT style that has the same name as
|
|
||||||
CSS style in "class" attr
|
|
||||||
(7) ODT style that has the same outline level as HTML elem.'''
|
|
||||||
res = None
|
|
||||||
cssStyleName = None
|
|
||||||
if attrs and attrs.has_key('class'):
|
|
||||||
cssStyleName = attrs['class']
|
|
||||||
if classValue:
|
|
||||||
cssStyleName = classValue
|
|
||||||
# (1)
|
|
||||||
if self.localStylesMapping.has_key(cssStyleName):
|
|
||||||
res = self.localStylesMapping[cssStyleName]
|
|
||||||
# (2)
|
|
||||||
elif self.localStylesMapping.has_key(elem):
|
|
||||||
res = self.localStylesMapping[elem]
|
|
||||||
# (3)
|
|
||||||
elif self.globalStylesMapping.has_key(cssStyleName):
|
|
||||||
res = self.globalStylesMapping[cssStyleName]
|
|
||||||
# (4)
|
|
||||||
elif self.globalStylesMapping.has_key(elem):
|
|
||||||
res = self.globalStylesMapping[elem]
|
|
||||||
# (5)
|
|
||||||
elif self.odtStyles.has_key(cssStyleName):
|
|
||||||
res = self.odtStyles[cssStyleName]
|
|
||||||
# (6)
|
|
||||||
elif self.stylesManager.podSpecificStyles.has_key(cssStyleName):
|
|
||||||
res = self.stylesManager.podSpecificStyles[cssStyleName]
|
|
||||||
# (7)
|
|
||||||
else:
|
|
||||||
# Try to find a style with the correct outline level
|
|
||||||
if elem in XHTML_HEADINGS:
|
|
||||||
# Is there a delta that must be taken into account ?
|
|
||||||
outlineDelta = 0
|
|
||||||
if self.localStylesMapping.has_key('h*'):
|
|
||||||
outlineDelta += self.localStylesMapping['h*']
|
|
||||||
elif self.globalStylesMapping.has_key('h*'):
|
|
||||||
outlineDelta += self.globalStylesMapping['h*']
|
|
||||||
outlineLevel = int(elem[1]) + outlineDelta
|
|
||||||
# Normalize the outline level
|
|
||||||
if outlineLevel < 1: outlineLevel = 1
|
|
||||||
res = self.odtStyles.getParagraphStyleAtLevel(outlineLevel)
|
|
||||||
if res:
|
|
||||||
self.stylesManager.checkStylesAdequation(elem, res)
|
|
||||||
return res
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from appy import Object
|
from appy import Object
|
||||||
from appy.gen.utils import sequenceTypes
|
from appy.shared.utils import sequenceTypes
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
WRONG_LINE = 'Line number %d in file %s does not have the right number of ' \
|
WRONG_LINE = 'Line number %d in file %s does not have the right number of ' \
|
||||||
|
|
|
@ -5,8 +5,7 @@ from StringIO import StringIO
|
||||||
from mimetypes import guess_type
|
from mimetypes import guess_type
|
||||||
from base64 import encodestring
|
from base64 import encodestring
|
||||||
from appy import Object
|
from appy import Object
|
||||||
from appy.shared.utils import copyData
|
from appy.shared.utils import copyData, sequenceTypes
|
||||||
from appy.gen.utils import sequenceTypes
|
|
||||||
from appy.shared.xml_parser import XmlUnmarshaller, XmlMarshaller
|
from appy.shared.xml_parser import XmlUnmarshaller, XmlMarshaller
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
a website by SAP requiring a login/password.'''
|
a website by SAP requiring a login/password.'''
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from appy.gen.utils import sequenceTypes
|
from appy.shared.utils import sequenceTypes
|
||||||
|
|
||||||
class SapError(Exception): pass
|
class SapError(Exception): pass
|
||||||
SAP_MODULE_ERROR = 'Module pysap was not found (you can get it at ' \
|
SAP_MODULE_ERROR = 'Module pysap was not found (you can get it at ' \
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import os, os.path, re, time, sys, traceback, unicodedata, shutil
|
import os, os.path, re, time, sys, traceback, unicodedata, shutil
|
||||||
|
sequenceTypes = (list, tuple)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class FolderDeleter:
|
class FolderDeleter:
|
||||||
|
|
|
@ -24,6 +24,7 @@ from xml.sax.handler import ContentHandler, ErrorHandler, feature_external_ges,\
|
||||||
from xml.sax.xmlreader import InputSource
|
from xml.sax.xmlreader import InputSource
|
||||||
from appy.shared import UnicodeBuffer, xmlPrologue
|
from appy.shared import UnicodeBuffer, xmlPrologue
|
||||||
from appy.shared.errors import AppyError
|
from appy.shared.errors import AppyError
|
||||||
|
from appy.shared.utils import sequenceTypes
|
||||||
|
|
||||||
# Constants --------------------------------------------------------------------
|
# Constants --------------------------------------------------------------------
|
||||||
CONVERSION_ERROR = '"%s" value "%s" could not be converted by the XML ' \
|
CONVERSION_ERROR = '"%s" value "%s" could not be converted by the XML ' \
|
||||||
|
@ -420,7 +421,6 @@ class XmlMarshaller:
|
||||||
xmlEntities = {'<': '<', '>': '>', '&': '&', '"': '"',
|
xmlEntities = {'<': '<', '>': '>', '&': '&', '"': '"',
|
||||||
"'": '''}
|
"'": '''}
|
||||||
trueFalse = {True: 'True', False: 'False'}
|
trueFalse = {True: 'True', False: 'False'}
|
||||||
sequenceTypes = (tuple, list)
|
|
||||||
fieldsToMarshall = 'all'
|
fieldsToMarshall = 'all'
|
||||||
fieldsToExclude = []
|
fieldsToExclude = []
|
||||||
atFiles = ('image', 'file') # Types of archetypes fields that contain files.
|
atFiles = ('image', 'file') # Types of archetypes fields that contain files.
|
||||||
|
@ -549,12 +549,12 @@ class XmlMarshaller:
|
||||||
elif fieldType == 'dict': self.dumpDict(res, value)
|
elif fieldType == 'dict': self.dumpDict(res, value)
|
||||||
elif isRef:
|
elif isRef:
|
||||||
if value:
|
if value:
|
||||||
if type(value) in self.sequenceTypes:
|
if type(value) in sequenceTypes:
|
||||||
for elem in value:
|
for elem in value:
|
||||||
self.dumpField(res, 'url', elem.absolute_url())
|
self.dumpField(res, 'url', elem.absolute_url())
|
||||||
else:
|
else:
|
||||||
self.dumpField(res, 'url', value.absolute_url())
|
self.dumpField(res, 'url', value.absolute_url())
|
||||||
elif type(value) in self.sequenceTypes:
|
elif type(value) in sequenceTypes:
|
||||||
# The previous condition must be checked before this one because
|
# The previous condition must be checked before this one because
|
||||||
# referred objects may be stored in lists or tuples, too.
|
# referred objects may be stored in lists or tuples, too.
|
||||||
for elem in value: self.dumpField(res, 'e', elem)
|
for elem in value: self.dumpField(res, 'e', elem)
|
||||||
|
@ -603,7 +603,7 @@ class XmlMarshaller:
|
||||||
if self.objectType != 'popo':
|
if self.objectType != 'popo':
|
||||||
if fType: res.write(' type="%s"' % fType)
|
if fType: res.write(' type="%s"' % fType)
|
||||||
# Dump other attributes if needed
|
# Dump other attributes if needed
|
||||||
if type(fieldValue) in self.sequenceTypes:
|
if type(fieldValue) in sequenceTypes:
|
||||||
res.write(' count="%d"' % len(fieldValue))
|
res.write(' count="%d"' % len(fieldValue))
|
||||||
if fType == 'file':
|
if fType == 'file':
|
||||||
if hasattr(fieldValue, 'content_type'):
|
if hasattr(fieldValue, 'content_type'):
|
||||||
|
@ -662,7 +662,7 @@ class XmlMarshaller:
|
||||||
elif self.fieldsToMarshall == 'all':
|
elif self.fieldsToMarshall == 'all':
|
||||||
mustDump = True
|
mustDump = True
|
||||||
else:
|
else:
|
||||||
if (type(self.fieldsToMarshall) in self.sequenceTypes) \
|
if (type(self.fieldsToMarshall) in sequenceTypes) \
|
||||||
and (fieldName in self.fieldsToMarshall):
|
and (fieldName in self.fieldsToMarshall):
|
||||||
mustDump = True
|
mustDump = True
|
||||||
if mustDump:
|
if mustDump:
|
||||||
|
@ -679,7 +679,7 @@ class XmlMarshaller:
|
||||||
elif self.fieldsToMarshall == 'all_with_metadata':
|
elif self.fieldsToMarshall == 'all_with_metadata':
|
||||||
mustDump = True
|
mustDump = True
|
||||||
else:
|
else:
|
||||||
if (type(self.fieldsToMarshall) in self.sequenceTypes) \
|
if (type(self.fieldsToMarshall) in sequenceTypes) \
|
||||||
and (field.getName() in self.fieldsToMarshall):
|
and (field.getName() in self.fieldsToMarshall):
|
||||||
mustDump = True
|
mustDump = True
|
||||||
if mustDump:
|
if mustDump:
|
||||||
|
@ -695,7 +695,7 @@ class XmlMarshaller:
|
||||||
# Dump only needed fields
|
# Dump only needed fields
|
||||||
if field.name in self.fieldsToExclude: continue
|
if field.name in self.fieldsToExclude: continue
|
||||||
if (field.type == 'Ref') and field.isBack: continue
|
if (field.type == 'Ref') and field.isBack: continue
|
||||||
if (type(self.fieldsToMarshall) in self.sequenceTypes) \
|
if (type(self.fieldsToMarshall) in sequenceTypes) \
|
||||||
and (field.name not in self.fieldsToMarshall): continue
|
and (field.name not in self.fieldsToMarshall): continue
|
||||||
# Determine field type
|
# Determine field type
|
||||||
fieldType = 'basic'
|
fieldType = 'basic'
|
||||||
|
|
Loading…
Reference in a new issue