[Zope3-checkins] SVN: Zope3/trunk/src/zope/fssync/ Fixed some
encoding problems on OS X.
Uwe Oestermeier
uwe_oestermeier at iwm-kmrc.de
Tue Mar 6 12:16:45 EST 2007
Log message for revision 73012:
Fixed some encoding problems on OS X.
Changed:
U Zope3/trunk/src/zope/fssync/copier.py
U Zope3/trunk/src/zope/fssync/fsmerger.py
U Zope3/trunk/src/zope/fssync/fssync.py
U Zope3/trunk/src/zope/fssync/fsutil.py
U Zope3/trunk/src/zope/fssync/main.py
U Zope3/trunk/src/zope/fssync/merger.py
U Zope3/trunk/src/zope/fssync/metadata.py
U Zope3/trunk/src/zope/fssync/snarf.py
-=-
Modified: Zope3/trunk/src/zope/fssync/copier.py
===================================================================
--- Zope3/trunk/src/zope/fssync/copier.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/copier.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -56,7 +56,7 @@
def listDirectory(self, dir):
return [fn
- for fn in os.listdir(dir)
+ for fn in fsutil.listdir(dir)
if fn != "@@Zope"
if not self.sync.fsmerger.ignore(fn)]
Modified: Zope3/trunk/src/zope/fssync/fsmerger.py
===================================================================
--- Zope3/trunk/src/zope/fssync/fsmerger.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/fsmerger.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -118,7 +118,7 @@
rentrynames = self.metadata.getnames(remotedir)
lentry = self.metadata.getentry(localdir)
rentry = self.metadata.getentry(remotedir)
-
+
if not lentrynames and not rentrynames:
if not lentry:
@@ -181,7 +181,7 @@
return
lnames = dict([(normcase(name), name)
- for name in os.listdir(localdir)])
+ for name in fsutil.listdir(localdir)])
else:
if flag == "removed":
self.reportdir("R", localdir)
@@ -198,7 +198,7 @@
if exists(remotedir):
rnames = dict([(normcase(name), name)
- for name in os.listdir(remotedir)])
+ for name in fsutil.listdir(remotedir)])
else:
rnames = {}
Modified: Zope3/trunk/src/zope/fssync/fssync.py
===================================================================
--- Zope3/trunk/src/zope/fssync/fssync.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/fssync.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -577,7 +577,7 @@
raise Error("can't add '%s': its parent is not registered", path)
if "path" not in pentry:
raise Error("can't add '%s': its parent has no 'path' key", path)
- zpath = pentry["path"]
+ zpath = fsutil.encode(pentry["path"])
if not zpath.endswith("/"):
zpath += "/"
zpath += tail
@@ -704,7 +704,7 @@
if entry:
# Recurse down the directory
namesdir = {}
- for name in os.listdir(target):
+ for name in fsutil.listdir(target):
ncname = normcase(name)
if ncname != fsutil.nczope:
namesdir[ncname] = name
Modified: Zope3/trunk/src/zope/fssync/fsutil.py
===================================================================
--- Zope3/trunk/src/zope/fssync/fsutil.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/fsutil.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -32,6 +32,8 @@
"""
import os
+import sys
+import unicodedata
class Error(Exception):
"""User-level error, e.g. non-existent file.
@@ -117,3 +119,43 @@
"""
if not os.path.isdir(path):
os.makedirs(path)
+
+def normalize(name):
+ """Normalize a filename to normalization form C.
+
+ Linux and (most?) other Unix-like operating systems use the normalization
+ form C (NFC) for UTF-8 encoding by default but do not enforce this.
+ Darwin, the base of Macintosh OSX, enforces normalization form D (NFD),
+ where a few characters are encoded in a different way.
+ """
+ if sys.platform == 'darwin':
+ if isinstance(name, unicode):
+ name = unicodedata.normalize("NFC", name)
+ elif sys.getfilesystemencoding() == 'utf-8':
+ name = unicode(name, encoding='utf-8')
+ name = unicodedata.normalize("NFC", name)
+ name = name.encode('utf-8')
+ return name
+
+def encode(path, encoding=None):
+ """Encodes a path in its normalized form.
+
+ Uses the filesystem encoding as a default encoding. Assumes that the given path
+ is also encoded in the filesystem encoding.
+ """
+ fsencoding = sys.getfilesystemencoding()
+ if encoding is None:
+ encoding = fsencoding
+ if isinstance(path, unicode):
+ return normalize(path).encode(encoding)
+ return unicode(path, encoding=fsencoding).encode(encoding)
+
+def listdir(path):
+ """Returns normalized filenames on OS X (see normalize above).
+
+ The standard file and os.path operations seem to work with both
+ encodings on OS X. Therefore we provide our own listdir, making sure
+ that the more common NFC encoding is used.
+ """
+ return [normalize(name) for name in os.listdir(path)]
+
Modified: Zope3/trunk/src/zope/fssync/main.py
===================================================================
--- Zope3/trunk/src/zope/fssync/main.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/main.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -43,8 +43,8 @@
from zope.fssync.command import Command, Usage
from zope.fssync.fssync import FSSync
+from zope.fssync import fsutil
-
def main():
"""Main program.
Modified: Zope3/trunk/src/zope/fssync/merger.py
===================================================================
--- Zope3/trunk/src/zope/fssync/merger.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/merger.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -203,9 +203,12 @@
'Spurious' or 'Nonexistent'.
"""
+
+
+
lmeta = self.getentry(local)
rmeta = self.getentry(remote)
-
+
# Special-case sticky conflict
if "conflict" in lmeta:
return ("Nothing", "Conflict")
@@ -214,7 +217,6 @@
if not lmeta and not rmeta:
if exists(local):
- # Local unregistered file
return ("Nothing", "Spurious")
else:
# Why are we here?
Modified: Zope3/trunk/src/zope/fssync/metadata.py
===================================================================
--- Zope3/trunk/src/zope/fssync/metadata.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/metadata.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -31,6 +31,8 @@
from xml.sax import ContentHandler, parse, parseString
from xml.sax.saxutils import quoteattr
+import fsutil
+
case_insensitive = (normcase("ABC") == normcase("abc"))
class Metadata(object):
@@ -130,6 +132,7 @@
If there's no matching entry, an empty entry is created.
"""
+ name = fsutil.encode(name)
if name in self.entries:
return self.entries[name]
if case_insensitive:
@@ -154,13 +157,15 @@
names.sort()
for name in names:
entry = entries[name]
+ name = fsutil.encode(name, 'utf-8')
sio.write(" <entry name=")
- sio.write(quoteattr(name).encode('utf-8'))
+ sio.write(quoteattr(name))
for k, v in entry.iteritems():
if v is None:
continue
- sio.write("\n %s=%s"
- % (k.encode('utf-8'), quoteattr(v).encode('utf-8')))
+ k = fsutil.encode(k, 'utf-8')
+ v = fsutil.encode(v, 'utf-8')
+ sio.write("\n %s=%s" % (k, quoteattr(v)))
sio.write("\n />\n")
sio.write("</entries>\n")
return sio.getvalue()
@@ -203,6 +208,7 @@
raise InvalidEntriesFile("illegal element nesting")
else:
entryname = attrs.getValue("name")
+ entryname = fsutil.encode(entryname)
entry = {}
for n in attrs.getNames():
if n != "name":
@@ -214,6 +220,7 @@
"<entries> must be the document element")
else:
raise InvalidEntriesFile("unknown element <%s>" % name)
+
self.stack.append(name)
def endElement(self, name):
Modified: Zope3/trunk/src/zope/fssync/snarf.py
===================================================================
--- Zope3/trunk/src/zope/fssync/snarf.py 2007-03-06 16:52:59 UTC (rev 73011)
+++ Zope3/trunk/src/zope/fssync/snarf.py 2007-03-06 17:16:44 UTC (rev 73012)
@@ -31,6 +31,7 @@
"""
import os
+import fsutil
class Snarfer(object):
@@ -59,7 +60,7 @@
if filter is None:
def filter(fspath):
return True
- names = os.listdir(root)
+ names = fsutil.listdir(root)
names.sort()
for name in names:
fspath = os.path.join(root, name)
@@ -92,6 +93,7 @@
Raises IOError if reading istr returns an EOF condition before
size bytes have been read.
"""
+ path = fsutil.encode(path, 'utf-8')
self.ostr.write("%d %s\n" % (size, path))
copybytes(size, istr, self.ostr)
More information about the Zope3-Checkins
mailing list