Applied patch from Frederic Peters for bug https://bugs.launchpad.net/appy/+bug/485815 and another bugfix.
This commit is contained in:
parent
1227f0ed5e
commit
3a7b5be03b
|
@ -1,3 +1,6 @@
|
||||||
|
0.5.4 (2010-03-24)
|
||||||
|
- Improved gen search screens and many more minor bugfixes and features.
|
||||||
|
|
||||||
0.5.3 (2010-02-15)
|
0.5.3 (2010-02-15)
|
||||||
- Improved gen/pod integration by adding a Pod field for appy.gen applications.
|
- Improved gen/pod integration by adding a Pod field for appy.gen applications.
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
developer the real classes used by the underlying web framework.'''
|
developer the real classes used by the underlying web framework.'''
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import os, os.path, time, mimetypes, unicodedata, random
|
import os, os.path, time, mimetypes, random
|
||||||
import appy.pod
|
import appy.pod
|
||||||
from appy.gen import Search
|
from appy.gen import Search
|
||||||
from appy.gen.utils import sequenceTypes
|
from appy.gen.utils import sequenceTypes
|
||||||
from appy.shared.utils import getOsTempFolder, executeCommand
|
from appy.shared.utils import getOsTempFolder, executeCommand, normalizeString
|
||||||
from appy.shared.xml_parser import XmlMarshaller
|
from appy.shared.xml_parser import XmlMarshaller
|
||||||
|
|
||||||
# Some error messages ----------------------------------------------------------
|
# Some error messages ----------------------------------------------------------
|
||||||
|
@ -256,18 +256,7 @@ class AbstractWrapper:
|
||||||
def normalize(self, s, usage='fileName'):
|
def normalize(self, s, usage='fileName'):
|
||||||
'''Returns a version of string p_s whose special chars have been
|
'''Returns a version of string p_s whose special chars have been
|
||||||
replaced with normal chars.'''
|
replaced with normal chars.'''
|
||||||
# We work in unicode. Convert p_s to unicode if not unicode.
|
return normalizeString(s, usage)
|
||||||
if isinstance(s, str): s = s.decode('utf-8')
|
|
||||||
elif not isinstance(s, unicode): s = unicode(s)
|
|
||||||
if usage == 'fileName':
|
|
||||||
# Remove any char that can't be found within a file name under
|
|
||||||
# Windows.
|
|
||||||
res = ''
|
|
||||||
for char in s:
|
|
||||||
if char not in self.unwantedChars:
|
|
||||||
res += char
|
|
||||||
s = res
|
|
||||||
return unicodedata.normalize('NFKD', s).encode("ascii","ignore")
|
|
||||||
|
|
||||||
def search(self, klass, sortBy='', maxResults=None, noSecurity=False,
|
def search(self, klass, sortBy='', maxResults=None, noSecurity=False,
|
||||||
**fields):
|
**fields):
|
||||||
|
|
33
gen/utils.py
33
gen/utils.py
|
@ -196,4 +196,37 @@ class SomeObjects:
|
||||||
if self.noSecurity: getMethod = '_unrestrictedGetObject'
|
if self.noSecurity: getMethod = '_unrestrictedGetObject'
|
||||||
else: getMethod = 'getObject'
|
else: getMethod = 'getObject'
|
||||||
self.objects = [getattr(b, getMethod)() for b in brains]
|
self.objects = [getattr(b, getMethod)() for b in brains]
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
class Keywords:
|
||||||
|
'''This class allows to handle keywords that a user enters and that will be
|
||||||
|
used as basis for performing requests in a Zope ZCTextIndex.'''
|
||||||
|
|
||||||
|
toRemove = '?-+*()'
|
||||||
|
def __init__(self, keywords, operator='AND'):
|
||||||
|
# Clean the p_keywords that the user has entered.
|
||||||
|
words = keywords.strip()
|
||||||
|
if words == '*': words = ''
|
||||||
|
for c in self.toRemove: words = words.replace(c, ' ')
|
||||||
|
self.keywords = words.split()
|
||||||
|
# Store the operator to apply to the keywords (AND or OR)
|
||||||
|
self.operator = operator
|
||||||
|
|
||||||
|
def merge(self, other, append=False):
|
||||||
|
'''Merges our keywords with those from p_other. If p_append is True,
|
||||||
|
p_other keywords are appended at the end; else, keywords are appended
|
||||||
|
at the begin.'''
|
||||||
|
for word in other.keywords:
|
||||||
|
if word not in self.keywords:
|
||||||
|
if append:
|
||||||
|
self.keywords.append(word)
|
||||||
|
else:
|
||||||
|
self.keywords.insert(0, word)
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
'''Returns the keywords as needed by the ZCTextIndex.'''
|
||||||
|
if self.keywords:
|
||||||
|
op = ' %s ' % self.operator
|
||||||
|
return op.join(self.keywords)+'*'
|
||||||
|
return ''
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -23,6 +23,7 @@ from UserDict import UserDict
|
||||||
|
|
||||||
import appy.pod
|
import appy.pod
|
||||||
from appy.pod import PodError
|
from appy.pod import PodError
|
||||||
|
from appy.shared import mimeTypesExts
|
||||||
from appy.shared.xml_parser import XmlElement
|
from appy.shared.xml_parser import XmlElement
|
||||||
from appy.shared.utils import FolderDeleter, executeCommand
|
from appy.shared.utils import FolderDeleter, executeCommand
|
||||||
from appy.pod.pod_parser import PodParser, PodEnvironment, OdInsert
|
from appy.pod.pod_parser import PodParser, PodEnvironment, OdInsert
|
||||||
|
@ -230,11 +231,6 @@ class Renderer:
|
||||||
return ifFalse
|
return ifFalse
|
||||||
|
|
||||||
imageFormats = ('png', 'jpeg', 'jpg', 'gif')
|
imageFormats = ('png', 'jpeg', 'jpg', 'gif')
|
||||||
mimeTypes = {
|
|
||||||
'application/vnd.oasis.opendocument.text': 'odt',
|
|
||||||
'application/msword': 'doc', 'text/rtf': 'rtf',
|
|
||||||
'application/pdf' : 'pdf', 'image/png': 'png',
|
|
||||||
'image/jpeg': 'jpg', 'image/gif': 'gif'}
|
|
||||||
ooFormats = ('odt',)
|
ooFormats = ('odt',)
|
||||||
def importDocument(self, content=None, at=None, format=None,
|
def importDocument(self, content=None, at=None, format=None,
|
||||||
anchor='as-char'):
|
anchor='as-char'):
|
||||||
|
@ -256,8 +252,8 @@ class Renderer:
|
||||||
format = os.path.splitext(at)[1][1:]
|
format = os.path.splitext(at)[1][1:]
|
||||||
else:
|
else:
|
||||||
# If format is a mimeType, convert it to an extension
|
# If format is a mimeType, convert it to an extension
|
||||||
if self.mimeTypes.has_key(format):
|
if mimeTypesExts.has_key(format):
|
||||||
format = self.mimeTypes[format]
|
format = mimeTypesExts[format]
|
||||||
isImage = False
|
isImage = False
|
||||||
if format in self.ooFormats:
|
if format in self.ooFormats:
|
||||||
importer = OdtImporter
|
importer = OdtImporter
|
||||||
|
@ -322,6 +318,8 @@ class Renderer:
|
||||||
stylesMapping = self.stylesManager.checkStylesMapping(stylesMapping)
|
stylesMapping = self.stylesManager.checkStylesMapping(stylesMapping)
|
||||||
self.stylesManager.stylesMapping = stylesMapping
|
self.stylesManager.stylesMapping = stylesMapping
|
||||||
except PodError, po:
|
except PodError, po:
|
||||||
|
self.contentParser.env.currentBuffer.content.close()
|
||||||
|
self.stylesParser.env.currentBuffer.content.close()
|
||||||
if os.path.exists(self.tempFolder):
|
if os.path.exists(self.tempFolder):
|
||||||
FolderDeleter.delete(self.tempFolder)
|
FolderDeleter.delete(self.tempFolder)
|
||||||
raise po
|
raise po
|
||||||
|
@ -395,7 +393,10 @@ class Renderer:
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print WARNING_FINALIZE_ERROR % str(e)
|
print WARNING_FINALIZE_ERROR % str(e)
|
||||||
resultOdtName = os.path.join(self.tempFolder, 'result.odt')
|
resultOdtName = os.path.join(self.tempFolder, 'result.odt')
|
||||||
resultOdt = zipfile.ZipFile(resultOdtName, 'w')
|
try:
|
||||||
|
resultOdt = zipfile.ZipFile(resultOdtName,'w', zipfile.ZIP_DEFLATED)
|
||||||
|
except RuntimeError:
|
||||||
|
resultOdt = zipfile.ZipFile(resultOdtName,'w')
|
||||||
os.chdir(self.unzipFolder)
|
os.chdir(self.unzipFolder)
|
||||||
for dir, dirnames, filenames in os.walk('.'):
|
for dir, dirnames, filenames in os.walk('.'):
|
||||||
for f in filenames:
|
for f in filenames:
|
||||||
|
|
|
@ -7,7 +7,17 @@ appyPath = os.path.realpath(os.path.dirname(appy.__file__))
|
||||||
mimeTypes = {'odt': 'application/vnd.oasis.opendocument.text',
|
mimeTypes = {'odt': 'application/vnd.oasis.opendocument.text',
|
||||||
'doc': 'application/msword',
|
'doc': 'application/msword',
|
||||||
'rtf': 'text/rtf',
|
'rtf': 'text/rtf',
|
||||||
'pdf': 'application/pdf'}
|
'pdf': 'application/pdf'
|
||||||
|
}
|
||||||
|
mimeTypesExts = {
|
||||||
|
'application/vnd.oasis.opendocument.text': 'odt',
|
||||||
|
'application/msword' : 'doc',
|
||||||
|
'text/rtf' : 'rtf',
|
||||||
|
'application/pdf' : 'pdf',
|
||||||
|
'image/png' : 'png',
|
||||||
|
'image/jpeg' : 'jpg',
|
||||||
|
'image/gif' : 'gif'
|
||||||
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class UnmarshalledObject:
|
class UnmarshalledObject:
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA.
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import os, os.path, sys, traceback
|
import os, os.path, sys, traceback, unicodedata
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class FolderDeleter:
|
class FolderDeleter:
|
||||||
|
@ -76,4 +76,22 @@ def executeCommand(cmd, ignoreLines=None):
|
||||||
res = '\n'.join(keptLines)
|
res = '\n'.join(keptLines)
|
||||||
childStdIn.close(); childStdOut.close(); childStdErr.close()
|
childStdIn.close(); childStdOut.close(); childStdErr.close()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
unwantedChars = ('\\', '/', ':', '*', '?', '"', '<', '>', '|', ' ')
|
||||||
|
def normalizeString(s, usage='fileName'):
|
||||||
|
'''Returns a version of string p_s whose special chars have been
|
||||||
|
replaced with normal chars.'''
|
||||||
|
# We work in unicode. Convert p_s to unicode if not unicode.
|
||||||
|
if isinstance(s, str): s = s.decode('utf-8')
|
||||||
|
elif not isinstance(s, unicode): s = unicode(s)
|
||||||
|
if usage == 'fileName':
|
||||||
|
# Remove any char that can't be found within a file name under
|
||||||
|
# Windows.
|
||||||
|
res = ''
|
||||||
|
for char in s:
|
||||||
|
if char not in unwantedChars:
|
||||||
|
res += char
|
||||||
|
s = res
|
||||||
|
return unicodedata.normalize('NFKD', s).encode("ascii","ignore")
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue