Orb/python/orb/filerenamer.py
changeset 2 932c358ece3e
child 4 468f4c8d3d5b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/python/orb/filerenamer.py	Fri Apr 23 20:45:58 2010 +0100
@@ -0,0 +1,139 @@
+# 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
+import logging
+from cStringIO import StringIO
+from xml.etree import ElementTree as etree
+from lib import scan, main, XmlParser, StubXmlParser
+from optparse import OptionParser
+
+__version__ = '0.1'
+
+
+UNSAFE_CHARS = ("\n", "\t", ":", "?", ",", "=", ".", "\\", "/", "[", "]", "|", "<", ">", "+", ";", '"', "-")
+
+
+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(), publishing_target="mode"):
+        self.parser = xmlparser
+        self.publishing_target = publishing_target
+    
+    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)
+        if self.publishing_target == "mode":
+            filename = self._escape(filename) 
+            newfilename = "=".join((filename, id, '1', 'en', ''))
+            ext = ext if ext == ".ditamap" else ".reference"
+        elif self.publishing_target == "ditaot":
+            newfilename = id
+            ext = ext = ext if ext == ".ditamap" else ".xml"
+        return newfilename + ext
+
+
+def rename(indir, publishing_target):
+    fr = FileRenamer(publishing_target=publishing_target)
+    for filepath in scan(indir):
+        newfilename = os.path.join(os.path.dirname(filepath), fr.rename(filepath))
+        try:
+            os.chmod(filepath, stat.S_IWRITE)
+        except Exception, e:
+            logging.error('Unable to make file \"%s\" writable, error was: %s' % (filepath, e))
+            continue
+        else:
+            logging.debug("Renaming %s to %s" % (filepath, newfilename))
+            try:
+                os.rename(filepath, newfilename)
+            except Exception, e:
+                logging.error('Unable to rename file \"%s\" to \"%s\", error was: %s' % (filepath, newfilename, e))
+
+def main():        
+    usage = "usage: %prog <Path to the XML content> <publishing_target>\n"
+    parser = OptionParser(usage, version='%prog ' + __version__)
+    parser.add_option("-p", dest="publishing_target", type="choice", choices=["mode", "ditaot"], default="mode", 
+                          help="Publishing Target: mode|ditaot, [default: %default]")
+    parser.add_option("-l", "--loglevel", type="int", default=30, help="Log Level (debug=10, info=20, warning=30, [error=40], critical=50)")
+    (options, args) = parser.parse_args()
+    if len(args) < 1:
+        parser.print_help()
+        parser.error("Please supply the path to the XML content")
+        
+    if options.loglevel:
+        logging.basicConfig(level=options.loglevel)
+    
+    rename(args[0],options.publishing_target)
+
+if __name__ == '__main__':
+    sys.exit(main())
+
+######################################
+# Test code
+######################################
+
+class TestFileRenamer(unittest.TestCase):
+    def test_i_can_return_a_files_new_mode_name(self):
+        fr = FileRenamer(xmlparser=StubXmlParser(),publishing_target="mode")
+        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_mode_name(self,publishing_target="mode"):
+        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")        
+
+    def test_i_can_return_a_files_new_ditaot_name(self):
+        fr = FileRenamer(xmlparser=StubXmlParser(),publishing_target="ditaot")
+        newfile = fr.rename("hello.xml")
+        self.assertEquals(newfile, "GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F.xml")
+
+    def test_i_can_return_a_ditamaps_new_ditaot_name(self):
+        fr = FileRenamer(xmlparser=StubXmlParser(),publishing_target="ditaot")
+        newfile = fr.rename("hello.ditamap")
+        self.assertEquals(newfile, "GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F.ditamap")