createrepo: initial comments and a UTF-8 patch
Ville Skyttä <[email protected]>
| Newsgroups | gmane.linux.rpm.metadata |
|---|---|
| Message-ID | <[email protected]> |
I tried out createrepo yesterday somewhat, here's initial comments: Issue 1: It does not currently do a decent job in UTF-8'ifying content. Not that it would generate broken XML, but for example the UTF-8 "ä" in my surname turns in to two "?"s, when it's already UTF-8 in a RPM header! Patch attached. This is a simplified version of what I use in fancix, and the idea originates to decode() Skip Montanaro's query.py at http://manatee.mojam.com/~skip/python/query.py The other gotcha in the patch is that when adding content to a libxml2 tree, one does not need to XML escape it. AFAIK that happens automatically correctly at serialization time. XML escaping would be only needed when printing stuff directly somewhere outside of the libxml objects; that is not currently done so I nuked xmlCleanString() altogether. While at it, I added explicit encodings to serialize() calls. With this patch applied, the output is improved quite a bit here. Add new encodings to the list in utf8String() if you like. Issue 2: The name "author" attribute in <changelog> is not a very good choice IMO. RPM defines it as the "name" of the changelog entry. It is very common that for RPMs the author attribute will contain stuff like "John Doe <john at doe dot com> - 2.6.8-0.1", ie. it's not only the author -> suggesting changing "author" to "name" unless it causes too much problems. Issue 3: $ createrepo . [...] Saving Primary metadata Saving file lists metadata Saving other metadata $ echo foo > repodata/foo.txt $ createrepo . [...] Saving Primary metadata Saving file lists metadata Saving other metadata Could not remove old metadata dir: .olddata Error was [Errno 39] Directory not empty: '.olddata' $ createrepo . Old data directory exists, please remove: .olddata Bug or feature? _______________________________________________ Rpm-metadata mailing list [email protected] https://lists.dulug.duke.edu/mailman/listinfo/rpm-metadata
createrepo-utf8.patch
(text/x-patch, 5.4 KB)
Index: dumpMetadata.py
===================================================================
RCS file: /cvsroot/metadata/cvs-root/generate/dumpMetadata.py,v
retrieving revision 1.21
diff -a -u -r1.21 dumpMetadata.py
--- dumpMetadata.py 23 Jul 2004 18:45:02 -0000 1.21
+++ dumpMetadata.py 24 Jul 2004 09:03:32 -0000
@@ -86,28 +86,29 @@
def utf8String(string):
"""hands back a unicoded string"""
+ if isinstance(string, unicode):
+ return string
try:
- string = unicode(string)
+ x = unicode(string, 'ascii')
+ return string
except UnicodeError:
- newstring = ''
- for char in string:
- if ord(char) > 127:
- newstring = newstring + '?'
+ encodings = ['utf-8', 'iso-8859-1', 'iso-8859-15', 'iso-8859-2']
+ for enc in encodings:
+ try:
+ x = unicode(string, enc)
+ except UnicodeError:
+ pass
else:
- newstring = newstring + char
- return unicode(newstring)
- else:
- return string
+ if x.encode(enc) == string:
+ return x.encode('utf-8')
+ newstring = ''
+ for char in string:
+ if ord(char) > 127:
+ newstring = newstring + '?'
+ else:
+ newstring = newstring + char
+ return newstring
-def xmlCleanString(doc, string):
- """hands back a special-char encoded and utf8 cleaned string
- Takes a libxml2 document object and the string to clean
- document object is needed to not require expensive get_doc function
- """
- string = utf8String(string)
- string = doc.encodeSpecialChars(string)
- return string
-
def byteranges(file):
"""takes an rpm file or fileobject and returns byteranges for location of the header"""
@@ -506,7 +507,6 @@
value = utf8String(value)
value = re.sub("\n$", '', value)
entry = pkgNode.newChild(None, tag, None)
- value = xmlCleanString(doc, value)
entry.addContent(value)
time = pkgNode.newChild(None, 'time', None)
@@ -526,7 +526,6 @@
value = utf8String(value)
value = re.sub("\n$", '', value)
entry = format.newChild(formatns, tag, None)
- value = xmlCleanString(doc, value)
entry.addContent(value)
hr = format.newChild(formatns, 'header-range', None)
@@ -580,11 +579,11 @@
for file in rpmObj.usefulFiles():
files = format.newChild(None, 'file', None)
- file = xmlCleanString(doc, file)
+ file = utf8String(file)
files.addContent(file)
for directory in rpmObj.usefulDirs():
files = format.newChild(None, 'file', None)
- directory = xmlCleanString(doc, directory)
+ directory = utf8String(directory)
files.addContent(directory)
files.newProp('type', 'dir')
@@ -601,16 +600,16 @@
version.newProp('rel', str(rpmObj.tagByName('release')))
for file in rpmObj.filenames:
files = pkg.newChild(None, 'file', None)
- file = xmlCleanString(doc, file)
+ file = utf8String(file)
files.addContent(file)
for directory in rpmObj.dirnames:
files = pkg.newChild(None, 'file', None)
- directory = xmlCleanString(doc, directory)
+ directory = utf8String(directory)
files.addContent(directory)
files.newProp('type', 'dir')
for ghost in rpmObj.ghostnames:
files = pkg.newChild(None, 'file', None)
- ghost = xmlCleanString(doc, ghost)
+ ghost = utf8String(ghost)
files.addContent(ghost)
files.newProp('type', 'ghost')
return pkg
@@ -627,8 +626,7 @@
clogs = rpmObj.changelogLists()
for (name, time, text) in clogs:
clog = pkg.newChild(None, 'changelog', None)
- text = xmlCleanString(doc, text)
- clog.addContent(text)
+ clog.addContent(utf8String(text))
clog.newProp('author', utf8String(name))
clog.newProp('date', str(time))
return pkg
Index: genpkgmetadata.py
===================================================================
RCS file: /cvsroot/metadata/cvs-root/generate/genpkgmetadata.py,v
retrieving revision 1.23
diff -a -u -r1.23 genpkgmetadata.py
--- genpkgmetadata.py 23 Jul 2004 19:41:28 -0000 1.23
+++ genpkgmetadata.py 24 Jul 2004 09:03:33 -0000
@@ -288,7 +288,7 @@
errorprint(_('\nAn error occurred creating primary metadata: %s') % e)
continue
else:
- output = node.serialize(None, cmds['pretty'])
+ output = node.serialize('UTF-8', cmds['pretty'])
basefile.write(output)
basefile.write('\n')
node.unlinkNode()
@@ -301,7 +301,7 @@
errorprint(_('\nAn error occurred creating filelists: %s') % e)
continue
else:
- output = node.serialize(None, cmds['pretty'])
+ output = node.serialize('UTF-8', cmds['pretty'])
flfile.write(output)
flfile.write('\n')
node.unlinkNode()
@@ -314,7 +314,7 @@
errorprint(_('\nAn error occurred: %s') % e)
continue
else:
- output = node.serialize(None, cmds['pretty'])
+ output = node.serialize('UTF-8', cmds['pretty'])
otherfile.write(output)
otherfile.write('\n')
node.unlinkNode()