Merge commit 'public/master' into ceod
[public/pyceo-broken.git] / ceo / urwid / widgets.py
index ca52416..cf1f31c 100644 (file)
@@ -1,6 +1,15 @@
-import urwid
-from ceo.urwid.ldapfilter import *
+import urwid, ldap
 from ceo.urwid.window import raise_back, push_window
+import ceo.ldapi as ldapi
+
+#Todo: kill ButtonText because no one uses it except one place and we can probably do that better anyway
+
+csclub_uri = "ldap://ldap1.csclub.uwaterloo.ca/ ldap://ldap2.csclub.uwaterloo.ca"
+csclub_base = "dc=csclub,dc=uwaterloo,dc=ca"
+
+def make_menu(items):
+    items = [ urwid.AttrWrap( ButtonText( cb, data, txt ), 'menu', 'selected') for (txt, cb, data) in items ]
+    return urwid.ListBox( items )
 
 def push_wizard(name, pages, dimensions=(50, 10)):
     state = {}
@@ -26,6 +35,15 @@ class ButtonText(urwid.Text):
         else:
             return key
 
+#DONTUSE
+class CaptionedText(urwid.Text):
+    def __init__(self, caption, *args, **kwargs):
+        self.caption = caption
+        urwid.Text.__init__(self, *args, **kwargs)
+    def render(self, *args, **kwargs):
+        self.set_text(self.caption + self.get_text()[0])
+        urwid.Text.render(*args, **kwargs)
+
 class SingleEdit(urwid.Edit):
     def keypress(self, size, key):
         if key == 'enter':
@@ -44,10 +62,68 @@ class WordEdit(SingleEdit):
     def valid_char(self, ch):
         return urwid.Edit.valid_char(self, ch) and ch != ' '
 
-class LdapFilterWordEdit(LdapFilter, WordEdit):
-    def __init__(self, *args):
-        LdapFilter.__init__(self, WordEdit)
-        WordEdit.__init__(self, *args)
+class LdapWordEdit(WordEdit):
+    ldap = None
+    index = None
+
+    def __init__(self, uri, base, attr, *args):
+        try:
+            self.ldap = ldap.initialize(uri)
+            self.ldap.simple_bind_s("", "")
+        except ldap.LDAPError:
+            return WordEdit.__init__(self, *args)
+        self.base = base
+        self.attr = ldapi.escape(attr)
+        return WordEdit.__init__(self, *args)
+
+    def keypress(self, size, key):
+        if (key == 'tab' or key == 'shift tab') and self.ldap != None:
+            if self.index != None:
+                if key == 'tab':
+                    self.index = (self.index + 1) % len(self.choices)
+                elif key == 'shift tab':
+                    self.index = (self.index - 1) % len(self.choices)
+                text = self.choices[self.index]
+                self.set_edit_text(text)
+                self.set_edit_pos(len(text))
+            else:
+                try:
+                    text = self.get_edit_text()
+                    search = ldapi.escape(text)
+                    matches = self.ldap.search_s(self.base,
+                        ldap.SCOPE_SUBTREE, '(%s=%s*)' % (self.attr, search))
+                    self.choices = [ text ]
+                    for match in matches:
+                        (_, attrs) = match
+                        self.choices += attrs['uid']
+                    self.choices.sort()
+                    self.index = 0
+                    self.keypress(size, key)
+                except ldap.LDAPError, e:
+                    pass
+        else:
+            self.index = None
+            return WordEdit.keypress(self, size, key)
+
+class LdapFilterWordEdit(LdapWordEdit):
+    def __init__(self, uri, base, attr, map, *args):
+        LdapWordEdit.__init__(self, uri, base, attr, *args)
+        self.map = map
+    def keypress(self, size, key):
+        if self.ldap != None:
+            if key == 'enter' or key == 'down' or key == 'up':
+                search = ldapi.escape(self.get_edit_text())
+                try:
+                    matches = self.ldap.search_s(self.base,
+                        ldap.SCOPE_SUBTREE, '(%s=%s)' % (self.attr, search))
+                    if len(matches) > 0:
+                        (_, attrs) = matches[0]
+                        for (k, v) in self.map.items():
+                            if attrs.has_key(k) and len(attrs[k]) > 0:
+                                v.set_edit_text(attrs[k][0])
+                except ldap.LDAPError:
+                    pass
+        return LdapWordEdit.keypress(self, size, key)
 
 class PassEdit(SingleEdit):
     def get_text(self):