[cig-commits] r5917 - in cs/buildbot/trunk/buildbot/forms: . extras

leif at geodynamics.org leif at geodynamics.org
Fri Jan 26 14:35:59 PST 2007


Author: leif
Date: 2007-01-26 14:35:58 -0800 (Fri, 26 Jan 2007)
New Revision: 5917

Added:
   cs/buildbot/trunk/buildbot/forms/datastructures.py
Modified:
   cs/buildbot/trunk/buildbot/forms/extras/widgets.py
   cs/buildbot/trunk/buildbot/forms/fields.py
   cs/buildbot/trunk/buildbot/forms/forms.py
   cs/buildbot/trunk/buildbot/forms/util.py
   cs/buildbot/trunk/buildbot/forms/widgets.py
Log:
Broke the dependencies between buildbot.forms and Django.  The added
file 'datastructures.py' is from django/utils/datastructures.py
(r4431).


Added: cs/buildbot/trunk/buildbot/forms/datastructures.py
===================================================================
--- cs/buildbot/trunk/buildbot/forms/datastructures.py	2007-01-26 21:36:20 UTC (rev 5916)
+++ cs/buildbot/trunk/buildbot/forms/datastructures.py	2007-01-26 22:35:58 UTC (rev 5917)
@@ -0,0 +1,248 @@
+class MergeDict(object):
+    """
+    A simple class for creating new "virtual" dictionaries that actualy look
+    up values in more than one dictionary, passed in the constructor.
+    """
+    def __init__(self, *dicts):
+        self.dicts = dicts
+
+    def __getitem__(self, key):
+        for dict in self.dicts:
+            try:
+                return dict[key]
+            except KeyError:
+                pass
+        raise KeyError
+
+    def __contains__(self, key):
+        return self.has_key(key)
+
+    def get(self, key, default):
+        try:
+            return self[key]
+        except KeyError:
+            return default
+
+    def getlist(self, key):
+        for dict in self.dicts:
+            try:
+                return dict.getlist(key)
+            except KeyError:
+                pass
+        raise KeyError
+
+    def items(self):
+        item_list = []
+        for dict in self.dicts:
+            item_list.extend(dict.items())
+        return item_list
+
+    def has_key(self, key):
+        for dict in self.dicts:
+            if dict.has_key(key):
+                return True
+        return False
+
+class SortedDict(dict):
+    "A dictionary that keeps its keys in the order in which they're inserted."
+    def __init__(self, data=None):
+        if data is None: data = {}
+        dict.__init__(self, data)
+        self.keyOrder = data.keys()
+
+    def __setitem__(self, key, value):
+        dict.__setitem__(self, key, value)
+        if key not in self.keyOrder:
+            self.keyOrder.append(key)
+
+    def __delitem__(self, key):
+        dict.__delitem__(self, key)
+        self.keyOrder.remove(key)
+
+    def __iter__(self):
+        for k in self.keyOrder:
+            yield k
+
+    def items(self):
+        return zip(self.keyOrder, self.values())
+
+    def keys(self):
+        return self.keyOrder[:]
+
+    def values(self):
+        return [dict.__getitem__(self, k) for k in self.keyOrder]
+
+    def update(self, dict):
+        for k, v in dict.items():
+            self.__setitem__(k, v)
+
+    def setdefault(self, key, default):
+        if key not in self.keyOrder:
+            self.keyOrder.append(key)
+        return dict.setdefault(self, key, default)
+
+    def value_for_index(self, index):
+        "Returns the value of the item at the given zero-based index."
+        return self[self.keyOrder[index]]
+
+class MultiValueDictKeyError(KeyError):
+    pass
+
+class MultiValueDict(dict):
+    """
+    A subclass of dictionary customized to handle multiple values for the same key.
+
+    >>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']})
+    >>> d['name']
+    'Simon'
+    >>> d.getlist('name')
+    ['Adrian', 'Simon']
+    >>> d.get('lastname', 'nonexistent')
+    'nonexistent'
+    >>> d.setlist('lastname', ['Holovaty', 'Willison'])
+
+    This class exists to solve the irritating problem raised by cgi.parse_qs,
+    which returns a list for every key, even though most Web forms submit
+    single name-value pairs.
+    """
+    def __init__(self, key_to_list_mapping=()):
+        dict.__init__(self, key_to_list_mapping)
+
+    def __repr__(self):
+        return "<MultiValueDict: %s>" % dict.__repr__(self)
+
+    def __getitem__(self, key):
+        """
+        Returns the last data value for this key, or [] if it's an empty list;
+        raises KeyError if not found.
+        """
+        try:
+            list_ = dict.__getitem__(self, key)
+        except KeyError:
+            raise MultiValueDictKeyError, "Key %r not found in %r" % (key, self)
+        try:
+            return list_[-1]
+        except IndexError:
+            return []
+
+    def __setitem__(self, key, value):
+        dict.__setitem__(self, key, [value])
+
+    def __copy__(self):
+        return self.__class__(dict.items(self))
+
+    def __deepcopy__(self, memo=None):
+        import copy
+        if memo is None: memo = {}
+        result = self.__class__()
+        memo[id(self)] = result
+        for key, value in dict.items(self):
+            dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo))
+        return result
+
+    def get(self, key, default=None):
+        "Returns the default value if the requested data doesn't exist"
+        try:
+            val = self[key]
+        except KeyError:
+            return default
+        if val == []:
+            return default
+        return val
+
+    def getlist(self, key):
+        "Returns an empty list if the requested data doesn't exist"
+        try:
+            return dict.__getitem__(self, key)
+        except KeyError:
+            return []
+
+    def setlist(self, key, list_):
+        dict.__setitem__(self, key, list_)
+
+    def setdefault(self, key, default=None):
+        if key not in self:
+            self[key] = default
+        return self[key]
+
+    def setlistdefault(self, key, default_list=()):
+        if key not in self:
+            self.setlist(key, default_list)
+        return self.getlist(key)
+
+    def appendlist(self, key, value):
+        "Appends an item to the internal list associated with key"
+        self.setlistdefault(key, [])
+        dict.__setitem__(self, key, self.getlist(key) + [value])
+
+    def items(self):
+        """
+        Returns a list of (key, value) pairs, where value is the last item in
+        the list associated with the key.
+        """
+        return [(key, self[key]) for key in self.keys()]
+
+    def lists(self):
+        "Returns a list of (key, list) pairs."
+        return dict.items(self)
+
+    def values(self):
+        "Returns a list of the last value on every key list."
+        return [self[key] for key in self.keys()]
+
+    def copy(self):
+        "Returns a copy of this object."
+        return self.__deepcopy__()
+
+    def update(self, *args, **kwargs):
+        "update() extends rather than replaces existing key lists. Also accepts keyword args."
+        if len(args) > 1:
+            raise TypeError, "update expected at most 1 arguments, got %d", len(args)
+        if args:
+            other_dict = args[0]
+            if isinstance(other_dict, MultiValueDict):
+                for key, value_list in other_dict.lists():
+                    self.setlistdefault(key, []).extend(value_list)
+            else:
+                try:
+                    for key, value in other_dict.items():
+                        self.setlistdefault(key, []).append(value)
+                except TypeError:
+                    raise ValueError, "MultiValueDict.update() takes either a MultiValueDict or dictionary"
+        for key, value in kwargs.iteritems():
+            self.setlistdefault(key, []).append(value)
+
+class DotExpandedDict(dict):
+    """
+    A special dictionary constructor that takes a dictionary in which the keys
+    may contain dots to specify inner dictionaries. It's confusing, but this
+    example should make sense.
+
+    >>> d = DotExpandedDict({'person.1.firstname': ['Simon'],
+            'person.1.lastname': ['Willison'],
+            'person.2.firstname': ['Adrian'],
+            'person.2.lastname': ['Holovaty']})
+    >>> d
+    {'person': {'1': {'lastname': ['Willison'], 'firstname': ['Simon']},
+    '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}}
+    >>> d['person']
+    {'1': {'firstname': ['Simon'], 'lastname': ['Willison'],
+    '2': {'firstname': ['Adrian'], 'lastname': ['Holovaty']}
+    >>> d['person']['1']
+    {'firstname': ['Simon'], 'lastname': ['Willison']}
+
+    # Gotcha: Results are unpredictable if the dots are "uneven":
+    >>> DotExpandedDict({'c.1': 2, 'c.2': 3, 'c': 1})
+    >>> {'c': 1}
+    """
+    def __init__(self, key_to_list_mapping):
+        for k, v in key_to_list_mapping.items():
+            current = self
+            bits = k.split('.')
+            for bit in bits[:-1]:
+                current = current.setdefault(bit, {})
+            # Now assign value to current position
+            try:
+                current[bits[-1]] = v
+            except TypeError: # Special-case if current isn't a dict.
+                current = {bits[-1] : v}

Modified: cs/buildbot/trunk/buildbot/forms/extras/widgets.py
===================================================================
--- cs/buildbot/trunk/buildbot/forms/extras/widgets.py	2007-01-26 21:36:20 UTC (rev 5916)
+++ cs/buildbot/trunk/buildbot/forms/extras/widgets.py	2007-01-26 22:35:58 UTC (rev 5917)
@@ -2,8 +2,16 @@
 Extra HTML Widget classes
 """
 
-from django.newforms.widgets import Widget, Select
-from django.utils.dates import MONTHS
+from buildbot.forms.widgets import Widget, Select
+
+#from django.utils.dates import MONTHS
+from buildbot.forms.util import gettext as _
+MONTHS = {
+    1:_('January'), 2:_('February'), 3:_('March'), 4:_('April'), 5:_('May'), 6:_('June'),
+    7:_('July'), 8:_('August'), 9:_('September'), 10:_('October'), 11:_('November'),
+    12:_('December')
+}
+
 import datetime
 
 __all__ = ('SelectDateWidget',)

Modified: cs/buildbot/trunk/buildbot/forms/fields.py
===================================================================
--- cs/buildbot/trunk/buildbot/forms/fields.py	2007-01-26 21:36:20 UTC (rev 5916)
+++ cs/buildbot/trunk/buildbot/forms/fields.py	2007-01-26 22:35:58 UTC (rev 5917)
@@ -2,8 +2,7 @@
 Field classes
 """
 
-from django.utils.translation import gettext
-from util import ErrorList, ValidationError, smart_unicode
+from util import gettext, ErrorList, ValidationError, smart_unicode
 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
 import datetime
 import re
@@ -272,12 +271,7 @@
     r'(?::\d+)?' # optional port
     r'(?:/?|/\S+)$', re.IGNORECASE)
 
-try:
-    from django.conf import settings
-    URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT
-except ImportError:
-    # It's OK if Django settings aren't configured.
-    URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
+URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
 
 class URLField(RegexField):
     def __init__(self, max_length=None, min_length=None, required=True, verify_exists=False, widget=None, label=None,
@@ -292,7 +286,6 @@
             return value
         if self.verify_exists:
             import urllib2
-            from django.conf import settings
             headers = {
                 "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
                 "Accept-Language": "en-us,en;q=0.5",

Modified: cs/buildbot/trunk/buildbot/forms/forms.py
===================================================================
--- cs/buildbot/trunk/buildbot/forms/forms.py	2007-01-26 21:36:20 UTC (rev 5916)
+++ cs/buildbot/trunk/buildbot/forms/forms.py	2007-01-26 22:35:58 UTC (rev 5917)
@@ -2,11 +2,10 @@
 Form classes
 """
 
-from django.utils.datastructures import SortedDict, MultiValueDict
-from django.utils.html import escape
+from datastructures import SortedDict, MultiValueDict
 from fields import Field
 from widgets import TextInput, Textarea, HiddenInput, MultipleHiddenInput
-from util import flatatt, StrAndUnicode, ErrorDict, ErrorList, ValidationError
+from util import escape, flatatt, StrAndUnicode, ErrorDict, ErrorList, ValidationError
 
 __all__ = ('BaseForm', 'Form')
 

Modified: cs/buildbot/trunk/buildbot/forms/util.py
===================================================================
--- cs/buildbot/trunk/buildbot/forms/util.py	2007-01-26 21:36:20 UTC (rev 5916)
+++ cs/buildbot/trunk/buildbot/forms/util.py	2007-01-26 22:35:58 UTC (rev 5917)
@@ -1,6 +1,16 @@
-from django.conf import settings
-from django.utils.html import escape
 
+DEFAULT_CHARSET = 'utf-8'
+
+# from django.utils.translation import gettext
+gettext = lambda x: x
+
+# from django.utils.html
+def escape(html):
+    "Returns the given HTML with ampersands, quotes and carets encoded"
+    if not isinstance(html, basestring):
+        html = str(html)
+    return html.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')
+
 # Converts a dictionary to a single string with key="value", XML-style with
 # a leading space. Assumes keys do not need to be XML-escaped.
 flatatt = lambda attrs: u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()])
@@ -9,7 +19,7 @@
     if not isinstance(s, basestring):
         s = unicode(str(s))
     elif not isinstance(s, unicode):
-        s = unicode(s, settings.DEFAULT_CHARSET)
+        s = unicode(s, DEFAULT_CHARSET)
     return s
 
 class StrAndUnicode(object):
@@ -20,7 +30,7 @@
     Useful as a mix-in.
     """
     def __str__(self):
-        return self.__unicode__().encode(settings.DEFAULT_CHARSET)
+        return self.__unicode__().encode(DEFAULT_CHARSET)
 
 class ErrorDict(dict):
     """

Modified: cs/buildbot/trunk/buildbot/forms/widgets.py
===================================================================
--- cs/buildbot/trunk/buildbot/forms/widgets.py	2007-01-26 21:36:20 UTC (rev 5916)
+++ cs/buildbot/trunk/buildbot/forms/widgets.py	2007-01-26 22:35:58 UTC (rev 5917)
@@ -9,10 +9,8 @@
     'MultiWidget', 'SplitDateTimeWidget',
 )
 
-from util import flatatt, StrAndUnicode, smart_unicode
-from django.utils.datastructures import MultiValueDict
-from django.utils.html import escape
-from django.utils.translation import gettext
+from util import gettext, escape, flatatt, StrAndUnicode, smart_unicode
+from datastructures import MultiValueDict
 from itertools import chain
 
 try:



More information about the cig-commits mailing list