Source Code

app.py

from albatross import *
import addressbook
                                                                                
class App(SimpleSessionFileApp):
    '''AddressBook Albatross application'''
                                                                                
    def __init__(self, base_url = '/', base_dir = '.'):
        # Initialise base class
        SimpleSessionFileApp.__init__(
                self,
                base_url = base_url,
                template_path = base_dir,
                start_page = ListPage.name,
                secret = '-=secret=-',
                session_appid = 'AdressBook',
                session_dir = base_dir + '/sessions')
                                                                                
        # Register page(s)
        for page_class in (ListPage,):
            self.register_page(page_class.name, page_class())
                                                                                
                                                                                
class ListPage:
                                                                                
    name = 'list'
                                                                                
    def page_enter(self, ctx):
        # Sort by last_name by default
        ctx.default_session_var('_sort', 'last_name')
                                                                                
    def page_process(self, ctx):
                                                                                
        if ctx.req_equals('sort'):
            # Store the sort attribute in the session var
            ctx.locals._sort = ctx.locals.sort
                                                                                
        elif ctx.req_equals('clear_filter'):
            # Set the filter string to None
            ctx.locals.filter_string = None
                                                                                
    def page_display(self, ctx):
        # Get the list of people, sorting and filtering as necessary
        ctx.locals.people = addressbook.get_all(
                sort=ctx.locals._sort,
                filter=getattr(ctx.locals, 'filter_string', None))
        ctx.run_template('list.html')
                                                                                
                                                                                
# Create an application instance
app = App()

list.html

<html>
  <head>
    <title>Address Book</title>
  </head>
  <body>
    <p>Sorted by <al-value expr="_sort" /></p>
    <p>
      <al-form method="post">
        <al-input type="text" name="filter_string" />
        <al-input type="submit" name="filter" value="Filter" />
        <al-input type="submit" name="clear_filter" value="Clear" />
      </al-form>
    </p>
    <table>
      <tr>
        <th><al-a href="sort=first_name">First Name</al-a></th>
        <th><al-a href="sort=last_name">Last Name</al-a></th>
        <th><al-a href="sort=email">Email</al-a></th>
      </tr>
      <al-for iter="iter" expr="people">
        <al-exec expr="person = iter.value()" />
        <tr>
          <td><al-value expr="person.first_name" /></td>
          <td><al-value expr="person.last_name" /></td>
          <td><al-value expr="person.email" /></td>
        </tr>
      </al-for>
    </table>
  </body>
</html>

addressbook.py

class Person:
    '''A person'''
    def __init__(self, id, first_name, last_name, email):
        self.id = id
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
                                                                                
                                                                                
# List of people in the "database"
_people = [
    Person(1, 'Michael', 'Neel', 'a@b.c'),
    Person(2, 'Andrew', 'McNamara', 'd@e.f'),
    Person(3, 'Dave', 'Cole', 'g@h.i'),
    Person(4, 'Matt', 'Goodall', 'j@k.l'),
    Person(5, 'Sheila', 'King', 'm@n.o'),
    Person(6, 'Gregory', 'Bond', 'p@q.r'),
    ]
                                                                                
                                                                                
def get_all(sort=None, filter=None):
    '''
    Get all people in the addressbook that match the optional filter,
    optionally sorting the list by attribute name.
    '''
                                                                                
    # Use the full list to start with
    people = _people
                                                                                
    # Filter the people list to remove any that do not match
    if filter:
        filter = filter.lower()
        people = [person for person in people if matches_filter(person, filter)]                                                                                
    # Sort the remaining list by attribute name
    if sort:
        dsu = [(getattr(person, sort), person) for person in people]
        dsu.sort()
        dsu = [item[1] for item in dsu]
        people = dsu
                                                                                
    return people
                                                                                
                                                                                
def matches_filter(person, filter):
    '''
    Return 1 (True) if the filter text appears in any of the attributes
    of person
    '''
    if person.first_name.lower().find(filter) != -1 or \
        person.last_name.lower().find(filter) != -1 or \
        person.email.lower().find(filter) != -1:
        return 1
    return 0