Author: adc
Date: Sun Sep 15 20:19:58 2013
New Revision: 1523497
URL: http://svn.apache.org/r1523497
Log:
Added Person object
Added:
labs/panopticon/src/asf/person.py
labs/panopticon/tests/test_person.py
Added: labs/panopticon/src/asf/person.py
URL:
http://svn.apache.org/viewvc/labs/panopticon/src/asf/person.py?rev=1523497&view=auto
==============================================================================
--- labs/panopticon/src/asf/person.py (added)
+++ labs/panopticon/src/asf/person.py Sun Sep 15 20:19:58 2013
@@ -0,0 +1,109 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+"""
+ Power to the People!
+"""
+
+import email.utils
+import hashlib
+
+from asf.data import ldap
+
+
+class PersonError(ValueError):
+ pass
+
+
+_PICTURE_URL_TEMPLATE = 'https://secure.gravatar.com/avatar/{0}?r=g&d=mm'
+
+MAPPING = {
+ 'uid': 'username',
+ 'cn': 'fullname',
+ 'mail': 'email',
+ 'asf-altEmail': 'alt_emails',
+}
+
+
+def picture_url(email_address):
+ return
_PICTURE_URL_TEMPLATE.format(str(hashlib.md5(email_address.strip().lower()).hexdigest()))
+
+
+class Person(object):
+ """Describe a person (in LDAP).
+
+ :param username: The username to lookup.
+ :param fault_in_via_ldap: Should group data be autopopulated from LDAP?
[default: True].
+
+ """
+
+ def __init__(self, username, fault_in_via_ldap=True):
+ #: The user's LDAP username.
+ self.username = username
+
+ #: The user's LDAP full name.
+ self.fullname = None
+
+ #: The user's email address
+ self.email = None
+
+ if fault_in_via_ldap:
+ res = ldap.LDAP().find_by_username(self.username)
+ # Ensure username is valid account
+ if not res:
+ raise PersonError('%s is not a valid LDAP account.' %
self.username)
+ Person.populate_from_ldap_results(self, res)
+
+ # We need to override equals and hash to use Person in a set.
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.username ==
other.username
+
+ def __hash__(self):
+ return hash((self.username,))
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ @property
+ def email_string(self):
+ """ The user's name + email. """
+ return email.utils.formataddr((self.fullname, '%[email protected]' %
self.username))
+
+ @property
+ def picture_url(self):
+ return picture_url('%[email protected]' % self.username)
+
+ @classmethod
+ def find_by_email(cls, email):
+ """ Returns an instance of :class:`Person` with the corresponding
email."""
+ username = ldap.LDAP().search_first('(asf-altEmail=%s)' % email, 'uid')
+ return None if not username else Person(username)
+
+ @staticmethod
+ def populate_from_ldap_results(person, result):
+ """ Populate a :class:`Person` object from an LDAP search result. """
+
+ if result:
+ for field, method in MAPPING.iteritems():
+ if field in result:
+ if len(result[field]) > 1:
+ setattr(person, method, tuple(result[field]))
+ else:
+ setattr(person, method, result[field][0])
+
+ return person
Added: labs/panopticon/tests/test_person.py
URL:
http://svn.apache.org/viewvc/labs/panopticon/tests/test_person.py?rev=1523497&view=auto
==============================================================================
--- labs/panopticon/tests/test_person.py (added)
+++ labs/panopticon/tests/test_person.py Sun Sep 15 20:19:58 2013
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+from nose.tools import assert_equals, assert_raises
+
+from asf.person import picture_url, Person
+
+
+def test_picture_url():
+
assert_equals('https://secure.gravatar.com/avatar/e2291d07bb2caeb7337c30872259104d?r=g&d=mm',
picture_url('[email protected]'))
+
+
+def test_find_by_email():
+ person = Person.find_by_email('[email protected]')
+
+ assert person
+ assert_equals('jim', person.username)
+ assert_equals('Jim Jagielski <[email protected]>', person.email_string)
+
assert_equals('https://secure.gravatar.com/avatar/18b8b347cb5f1beb1b600c1455e92403?r=g&d=mm',
person.picture_url)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]