diff -r 000000000000 -r 42188c7ea2d9 Orb/python/doxygen/filerenamer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orb/python/doxygen/filerenamer.py Thu Jan 21 17:29:01 2010 +0000 @@ -0,0 +1,162 @@ +# Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. +# This component and the accompanying materials are made available under the terms of the License +# "Eclipse Public License v1.0" which accompanies this distribution, +# and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# System Documentation Tools +# Description: +# +import os.path +import sys +import unittest +import xml +import stat +from cStringIO import StringIO +from xml.etree import ElementTree as etree +from lib import scan, main + + +__version__ = '0.1' + + +UNSAFE_CHARS = ("\n", "\t", ":", "?", ",", "=", ".", "\\", "/", "[", "]", "|", "<", ">", "+", ";", '"', "-") + + +class XmlParser(object): + """ + Simple class that reads an XML and returns its id + + >>> xp = XmlParser() + >>> xp.parse(StringIO("some content")) + 'rootid' + """ + def parse(self, xmlfile): + try: + root = etree.parse(xmlfile).getroot() + except xml.parsers.expat.ExpatError, e: + sys.stderr.write("ERROR: %s could not be parse: %s\n" % (xmlfile, str(e))) + return "" + if 'id' not in root.attrib: + return "" + return root.attrib['id'] + + +class FileRenamer(object): + """ + Given an xml file this class returns a MODE compatable filename + + >>> fr = FileRenamer(xmlparser=StubXmlParser()) + >>> fr.rename(r"c:\\temp\\xml\\class_c_active_scheduler.xml") + 'class_c_active_scheduler=GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F=1=en=.reference' + """ + def __init__(self, xmlparser=XmlParser()): + self.parser = xmlparser + + def _escape(self, filename): + for char in UNSAFE_CHARS: + filename = filename.replace(char, "") + filename = filename.encode('unicode-escape', 'ignore') + filename = filename.replace(" ", "-") + return filename + + def rename(self, xmlfile): + """ + Return DITA MODE compliant filename. + Format of resultant filenames is: + title=identifier=version=language=resolution.extension + Examples: + Test-Document=GUID-1234=1=en=.reference + """ + id = self.parser.parse(xmlfile) + filename = os.path.basename(xmlfile) + filename, ext = os.path.splitext(filename) + filename = self._escape(filename) + newfilename = "=".join((filename, id, '1', 'en', '')) + ext = ext if ext == ".ditamap" else ".reference" + return newfilename + ext + + +def rename(indir): + fr = FileRenamer() + for filepath in scan(indir): + newfilename = os.path.join(os.path.dirname(filepath), fr.rename(filepath)) + os.chmod(filepath, stat.S_IWRITE) + #print "Renaming %s to %s" % (filepath, newfilename) + os.rename(filepath, newfilename) + + +if __name__ == '__main__': + sys.exit(main(rename, __version__)) + +###################################### +# Test code +###################################### +class StubXmlParser(object): + def parse(self, path): + return "GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F" + + +class TestXmlParser(unittest.TestCase): + def test_i_issue_a_warning_and_continue_if_a_file_is_invalid(self): + xml = XmlParser() + try: + xml.parse(StringIO("")) + except Exception: + self.fail("I shouldn't have raised an exception") + + def test_i_issue_a_warning_and_continue_if_a_file_does_not_have_an_id(self): + xml = XmlParser() + try: + id = xml.parse(StringIO(brokencxxclass)) + except Exception: + self.fail("I shouldn't have raised an exception") + self.assertTrue(id == "") + + def test_i_return_a_files_id(self): + xml = XmlParser() + id = xml.parse(StringIO(cxxclass)) + self.assertTrue(id == "class_c_active_scheduler") + + +class TestFileRenamer(unittest.TestCase): + def test_i_can_return_a_files_new_name(self): + fr = FileRenamer(xmlparser=StubXmlParser()) + newfile = fr.rename("hello.xml") + self.assertTrue(newfile == "hello=GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F=1=en=.reference") + + def test_i_can_return_a_ditamaps_new_name(self): + fr = FileRenamer(xmlparser=StubXmlParser()) + newfile = fr.rename("hello.ditamap") + self.assertTrue(newfile == "hello=GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F=1=en=.ditamap") + + + def test_i_can_return_a_files_new_name_if_passed_an_absolute_path(self): + fr = FileRenamer(xmlparser=StubXmlParser()) + newfile = fr.rename("c:\\temp\\xml\\hello.xml") + self.assertTrue(newfile == "hello=GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F=1=en=.reference") + + def test_i_can_remove_incompatable_characters_from_a_filename(self): + fr = FileRenamer(xmlparser=StubXmlParser()) + newfile = fr.rename("hello:?,=..xml") + self.assertTrue(newfile == "hello=GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F=1=en=.reference") + + +brokencxxclass = """ + + + CActiveScheduler + + +""" + +cxxclass = """ + + + CActiveScheduler + + +""" \ No newline at end of file