Back to index

moin  1.9.0~rc2
__init__.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - Utility Functions
00004     General helper functions that are not directly wiki related.
00005 
00006     @copyright: 2004 Juergen Hermann, Thomas Waldmann
00007     @license: GNU GPL, see COPYING for details.
00008 """
00009 
00010 import os, sys, re, random
00011 
00012 # do the pickle magic once here, so we can just import from here:
00013 # cPickle can encode normal and Unicode strings
00014 # see http://docs.python.org/lib/node66.html
00015 try:
00016     import cPickle as pickle
00017 except ImportError:
00018     import pickle
00019 
00020 # Set pickle protocol, see http://docs.python.org/lib/node64.html
00021 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
00022 
00023 
00024 #############################################################################
00025 ### XML helper functions
00026 #############################################################################
00027 
00028 g_xmlIllegalCharPattern = re.compile('[\x01-\x08\x0B-\x0D\x0E-\x1F\x80-\xFF]')
00029 g_undoUtf8Pattern = re.compile('\xC2([^\xC2])')
00030 g_cdataCharPattern = re.compile('[&<\'\"]')
00031 g_textCharPattern = re.compile('[&<]')
00032 g_charToEntity = {
00033     '&': '&amp;',
00034     '<': '&lt;',
00035     "'": '&apos;',
00036     '"': '&quot;'
00037 }
00038 
00039 def TranslateCDATA(text):
00040     """
00041         Convert a string to a CDATA-encoded one
00042         Copyright (c) 1999-2000 FourThought, http://4suite.com/4DOM
00043     """
00044     new_string, num_subst = re.subn(g_undoUtf8Pattern, lambda m: m.group(1), text)
00045     new_string, num_subst = re.subn(g_cdataCharPattern, lambda m, d=g_charToEntity: d[m.group()], new_string)
00046     new_string, num_subst = re.subn(g_xmlIllegalCharPattern, lambda m: '&#x%02X;' % ord(m.group()), new_string)
00047     return new_string
00048 
00049 def TranslateText(text):
00050     """
00051         Convert a string to a PCDATA-encoded one (do minimal encoding)
00052         Copyright (c) 1999-2000 FourThought, http://4suite.com/4DOM
00053     """
00054     new_string, num_subst = re.subn(g_undoUtf8Pattern, lambda m: m.group(1), text)
00055     new_string, num_subst = re.subn(g_textCharPattern, lambda m, d=g_charToEntity: d[m.group()], new_string)
00056     new_string, num_subst = re.subn(g_xmlIllegalCharPattern, lambda m: '&#x%02X;' % ord(m.group()), new_string)
00057     return new_string
00058 
00059 
00060 #############################################################################
00061 ### Misc
00062 #############################################################################
00063 
00064 def rangelist(numbers):
00065     """ Convert a list of integers to a range string in the form
00066         '1,2-5,7'.
00067     """
00068     numbers = numbers[:]
00069     numbers.sort()
00070     numbers.append(999999)
00071     pattern = ','
00072     for i in range(len(numbers)-1):
00073         if pattern[-1] == ',':
00074             pattern = pattern + str(numbers[i])
00075             if numbers[i] + 1 == numbers[i+1]:
00076                 pattern = pattern + '-'
00077             else:
00078                 pattern = pattern + ','
00079         elif numbers[i] + 1 != numbers[i+1]:
00080             pattern = pattern + str(numbers[i]) + ','
00081 
00082     if pattern[-1] in ',-':
00083         return pattern[1:-1]
00084     return pattern[1:]
00085 
00086 def IsWin9x():
00087     """ Returns true if run on Windows 95, 98 or ME. """
00088     if hasattr(sys, 'getwindowsversion'):
00089         if sys.getwindowsversion()[3] == 1:
00090             return True
00091     elif 'command' in os.environ.get('comspec', ''):
00092         return True
00093     return False
00094 
00095 
00096 class simpleIO:
00097     """ A simple StringIO replacement for code that calls us
00098         with ascii, Unicode and iso-8859-1 data. Wee, that is fun. """
00099 
00100     def __init__(self):
00101         self.buffer = []
00102 
00103     def write(self, foo):
00104         if not isinstance(foo, unicode):
00105             foo = foo.decode("iso-8859-1", "replace")
00106         self.buffer.append(foo)
00107 
00108     def getvalue(self):
00109         return u''.join(self.buffer)
00110 
00111     def close(self):
00112         self.buffer = None
00113 
00114 
00115 def random_string(length, allowed_chars=None):
00116     """ Generate a random string with given length consisting
00117         of the given characters.
00118 
00119         @param length: length of the string
00120         @param allowed_chars: string with allowed characters or None
00121                               to indicate all 256 byte values should be used
00122         @return: random string
00123     """
00124     if allowed_chars is None:
00125         return ''.join([chr(random.randint(0, 255)) for dummy in xrange(length)])
00126 
00127     return ''.join([random.choice(allowed_chars) for dummy in xrange(length)])