Add tab completion for userid fields

This commit is contained in:
David Bartley 2007-12-18 01:24:58 -05:00
parent 7c6c3d00a7
commit 7a282739e2
7 changed files with 78 additions and 56 deletions

View File

@ -53,7 +53,8 @@ class IntroPage(WizardPanel):
class InfoPage(WizardPanel): class InfoPage(WizardPanel):
def init_widgets(self): def init_widgets(self):
self.group = WordEdit("Club or Group: ") self.group = LdapWordEdit(csclub_uri, csclub_base, 'uid',
"Club or Group: ")
self.widgets = [ self.widgets = [
urwid.Text( "Club or Group Information"), urwid.Text( "Club or Group Information"),
urwid.Divider(), urwid.Divider(),
@ -75,7 +76,8 @@ class ChangeMember(WizardPanel):
state['data'] = data state['data'] = data
WizardPanel.__init__(self, state) WizardPanel.__init__(self, state)
def init_widgets(self): def init_widgets(self):
self.userid = WordEdit("Username: ") self.userid = LdapWordEdit(csclub_uri, csclub_base, 'uid',
"Username: ")
data = self.state['data'] data = self.state['data']
self.widgets = [ self.widgets = [

View File

@ -1,40 +0,0 @@
import ldap
class LdapFilter:
def __init__(self, widget):
self.widget = widget
def set_ldap_filter(self, ldap_uri, ldap_base, ldap_attr, ldap_map):
try:
self.ldap = ldap.initialize(ldap_uri)
self.ldap.simple_bind_s("", "")
except ldap.LDAPError:
return
self.base = ldap_base
self.attr = ldap_attr
self.map = ldap_map
def keypress(self, size, key):
if self.ldap != None:
if key == 'enter' or key == 'down' or key == 'up':
attr = self.escape(self.attr)
search = self.escape(self.widget.get_edit_text(self))
ldfilter = '(%s=%s)' % (attr, search)
try:
matches = self.ldap.search_s(self.base,
ldap.SCOPE_SUBTREE, ldfilter)
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 self.widget.keypress(self, size, key)
def escape(self, value):
value = str(value)
value = value.replace('\\', '\\5c').replace('*', '\\2a')
value = value.replace('(', '\\28').replace(')', '\\29')
value = value.replace('\x00', '\\00')
return value

View File

@ -36,13 +36,10 @@ class ClubIntroPage(WizardPanel):
class InfoPage(WizardPanel): class InfoPage(WizardPanel):
def init_widgets(self): def init_widgets(self):
self.userid = LdapFilterWordEdit("UWuserid: ")
self.name = SingleEdit("Full name: ") self.name = SingleEdit("Full name: ")
self.program = SingleEdit("Program of Study: ") self.program = SingleEdit("Program of Study: ")
self.userid.set_ldap_filter( self.userid = LdapFilterWordEdit(uwldap_uri, uwldap_base, 'uid',
"ldap://uwldap.uwaterloo.ca/", "dc=uwaterloo,dc=ca", {'cn':self.name, 'ou':self.program}, "UWuserid: ")
"uid", {'cn':self.name, 'ou':self.program}
)
self.widgets = [ self.widgets = [
urwid.Text( "Member Information - Please Check ID" ), urwid.Text( "Member Information - Please Check ID" ),
urwid.Divider(), urwid.Divider(),

View File

@ -36,7 +36,8 @@ class InfoPage(WizardPanel):
positions = members.list_positions() positions = members.list_positions()
self.position_widgets = {} self.position_widgets = {}
for (position, text) in position_data: for (position, text) in position_data:
widget = WordEdit("%s: " % text) widget = LdapWordEdit(csclub_uri, csclub_base, 'uid',
"%s: " % text)
if position in positions: if position in positions:
widget.set_edit_text(','.join(positions[position].keys())) widget.set_edit_text(','.join(positions[position].keys()))
else: else:

View File

@ -16,7 +16,8 @@ class IntroPage(WizardPanel):
class UserPage(WizardPanel): class UserPage(WizardPanel):
def init_widgets(self): def init_widgets(self):
self.userid = WordEdit("Username: ") self.userid = LdapWordEdit(csclub_uri, csclub_base, 'uid',
"Username: ")
self.widgets = [ self.widgets = [
urwid.Text( "Member Information" ), urwid.Text( "Member Information" ),

View File

@ -17,7 +17,8 @@ class IntroPage(WizardPanel):
class YouPage(WizardPanel): class YouPage(WizardPanel):
def init_widgets(self): def init_widgets(self):
you = pwd.getpwuid(os.getuid()).pw_name you = pwd.getpwuid(os.getuid()).pw_name
self.userid = WordEdit("Username: ", you) self.userid = LdapWordEdit(csclub_uri, csclub_base, 'uid',
"Username: ", you)
self.widgets = [ self.widgets = [
urwid.Text( "Member Information" ), urwid.Text( "Member Information" ),

View File

@ -1,6 +1,11 @@
import urwid import urwid, ldap
from ceo.urwid.ldapfilter import *
from ceo.urwid.window import raise_back, push_window from ceo.urwid.window import raise_back, push_window
import ceo.ldapi as ldapi
uwldap_uri = "ldap://uwldap.uwaterloo.ca/"
uwldap_base = "dc=uwaterloo,dc=ca"
csclub_uri = "ldap://ldap1.csclub.uwaterloo.ca/ ldap://ldap2.csclub.uwaterloo.ca"
csclub_base = "dc=csclub,dc=uwaterloo,dc=ca"
def menu_items(items): def menu_items(items):
return [ urwid.AttrWrap( ButtonText( cb, data, txt ), 'menu', 'selected') for (txt, cb, data) in items ] return [ urwid.AttrWrap( ButtonText( cb, data, txt ), 'menu', 'selected') for (txt, cb, data) in items ]
@ -47,10 +52,65 @@ class WordEdit(SingleEdit):
def valid_char(self, ch): def valid_char(self, ch):
return urwid.Edit.valid_char(self, ch) and ch != ' ' return urwid.Edit.valid_char(self, ch) and ch != ' '
class LdapFilterWordEdit(LdapFilter, WordEdit): class LdapWordEdit(WordEdit):
def __init__(self, *args): ldap = None
LdapFilter.__init__(self, WordEdit) tabbing = False
WordEdit.__init__(self, *args) 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' and self.ldap != None:
if self.tabbing:
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:
search = ldapi.escape(self.get_edit_text())
matches = self.ldap.search_s(self.base,
ldap.SCOPE_SUBTREE, '(%s=%s*)' % (self.attr, search))
self.choices = []
for match in matches:
(_, attrs) = match
self.choices += attrs['uid']
if len(self.choices) > 0:
self.index = 0
self.tabbing = True
text = self.choices[self.index]
self.set_edit_text(text)
self.set_edit_pos(len(text))
except ldap.LDAPError, e:
pass
else:
self.tabbing = False
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): class PassEdit(SingleEdit):
def get_text(self): def get_text(self):