[PATCH] Case-insensitive MIME types

Jon Foster <[email protected]> Thu, 4 Mar 2010 18:16:21 -0000
Newsgroups gmane.comp.version-control.subversion.cvs2svn.devel
Message-ID <[email protected]>
Hi,

Our CVS repository lives on a Linux server, but most people use
Windows clients.  As a result, the file extensions are a mix
of uppercase and lowercase.  E.g. we have both .bat and .BAT
files.

So I need cvs2svn's MIME types mechanism to treat filenames in
a case-insensitive way.  I've attached a patch that adds this
option.  The default behaviour is case-sensitive, for backward
compatibility.  I haven't added a command-line option for this,
so you have to use the options file if you want case-insensitivity.

Additionally, I've added a way to specify the MIME mappings in
the options file.  This means there's only one file (options.py)
controlling the conversion, rather than two (options.py and
mime.types).  This is also in the attached patch.

I'd welcome any feedback or review of this patch.

Kind regards,

Jon


**********************************************************************
This email and its attachments may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Cabot Communications Ltd.

If you are not the intended recipient of this email and its attachments, you must take no action based upon them, nor must you copy or show them to anyone.

Cabot Communications Limited
Verona House, Filwood Road, Bristol BS16 3RY, UK
+44 (0) 1179584232

Co. Registered in England number 02817269

Please contact the sender if you believe you have received this email in error.

**********************************************************************


______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________

------------------------------------------------------
http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1667&dsMessageId=2455080

To unsubscribe from this discussion, e-mail: [[email protected]].
cvs2svn_mime_types_propset_patch.txt (text/plain, 3 KB)
Index: cvs2svn_lib/property_setters.py
===================================================================
--- cvs2svn_lib/property_setters.py	(revision 5065)
+++ cvs2svn_lib/property_setters.py	(working copy)
@@ -98,20 +98,53 @@
 
   propname = 'svn:mime-type'
 
-  def __init__(self, mime_types_file):
+  def __init__(self, mime_types_file=None, mime_mappings=None,
+               case_insensitive=False):
+    """Constructor.
+
+    mime_types_file  is a path to a MIME types file on disk, or None.
+                     Each line of the file should contain the MIME type,
+                     then a whitespace-separated list of file extensions.
+                     E.g. one line might be "text/plain txt c h cpp hpp"
+    mime_mappings    is a dictionary mapping a file extension to a MIME
+                     type.  E.g. {'txt': 'text/plain', 'cpp': 'text/plain'}
+    case_insensitive can be True to do case-insensitive comparison of
+                     extensions, or False (the default) for case-sensitive.
+                     Case insensitive comparisons can be useful if your
+                     CVS repository was mainly used by Windows users so
+                     you have a mix of uppercase and lowercase filenames.
+    """
     self.mappings = { }
+    self.case_insensitive = case_insensitive
 
-    for line in file(mime_types_file):
-      if line.startswith("#"):
-        continue
+    if mime_types_file is None and mime_mappings is None:
+      Log().error('Should specify MIME types file or dict.\n')
 
-      # format of a line is something like
-      # text/plain c h cpp
-      extensions = line.split()
-      if len(extensions) < 2:
-        continue
-      type = extensions.pop(0)
-      for ext in extensions:
+    if mime_types_file is not None:
+      for line in file(mime_types_file):
+        if line.startswith("#"):
+          continue
+
+        # format of a line is something like
+        # text/plain c h cpp
+        extensions = line.split()
+        if len(extensions) < 2:
+          continue
+        type = extensions.pop(0)
+        for ext in extensions:
+          if case_insensitive:
+            ext = ext.lower()
+          if ext in self.mappings and self.mappings[ext] != type:
+            Log().error(
+                "%s: ambiguous MIME mapping for *.%s (%s or %s)\n"
+                % (warning_prefix, ext, self.mappings[ext], type)
+                )
+          self.mappings[ext] = type
+
+    if mime_mappings is not None:
+      for ext, type in mime_mappings.iteritems():
+        if case_insensitive:
+          ext = ext.lower()
         if ext in self.mappings and self.mappings[ext] != type:
           Log().error(
               "%s: ambiguous MIME mapping for *.%s (%s or %s)\n"
@@ -135,6 +168,9 @@
     if not extension:
       extension = basename
 
+    if self.case_insensitive:
+      extension = extension.lower()
+
     mime_type = self.mappings.get(extension, None)
     if mime_type is not None:
       s_item.svn_props[self.propname] = mime_type