def _GetActiveElections(self, election_type):
    if election_type not in freesidemodels.GetAllElectionTypes():
      raise Error('Invalid election type')

    return getattr(freesidemodels, election_type).all().filter(
      'vote_end >=', datetime.datetime.now(timezones.UTC())).fetch(1000)
  def get(self):
    now = datetime.datetime.now(timezones.UTC())
    current_elections = map(
      self._GetActiveElections, freesidemodels.GetAllElectionTypes())

    # Flatten the current_elections list
    current_elections = [
      election for elections in current_elections for election in elections]

    voting = []
    nominating = []
    ended = []
    user = self.session['user']

    # Sort current elections by voting and nominating
    for election in current_elections:
      nominate_start = election.nominate_start.replace(tzinfo=timezones.UTC())
      nominate_end = election.nominate_end.replace(tzinfo=timezones.UTC())
      vote_start = election.vote_start.replace(tzinfo=timezones.UTC())
      vote_end = election.vote_end.replace(tzinfo=timezones.UTC())

      if nominate_start < now < nominate_end:
        eligible = []
        nominees = []
        has_nominated = user.key() in election.nominators
        for member in member_util.GetActiveMembers():
          if member.key() not in election.nominees and member.key() != user.key():
            eligible.append(member)

        for nomineekey in election.nominees:
          nominees.append(db.get(nomineekey))

        nominating.append(
            {'election': election,
             'eligible': eligible,
             'nominate_end': nominate_end.astimezone(timezones.Eastern()),
             'nominees': nominees,
             'has_nominated': has_nominated})
      elif vote_start < now < vote_end:
        eligible = []
        has_voted = user.key() in election.voters
        for nominee in election.nominees:
            eligible.append(db.get(nominee))

        voting.append(
            {'election': election,
             'eligible': eligible,
             'has_voted': has_voted,
             'vote_end': vote_end.astimezone(timezones.Eastern())})
      elif vote_end < now:
        total_votes = len(election.votes)
        vote_totals = {}
        for vote in election.votes:
          member = db.get(vote)
          if member.username in vote_totals:
            vote_totals[member.username] += 1
          else:
            vote_totals[member.username] = 1

        ended.append(
            {'election': election,
             'totals': sorted(vote_totals.iteritems(),
                              key=operator.itemgetter(1),
                              reverse=True),
             'vote_end': vote_end.astimezone(timezones.Eastern())})

    template_values = {
        'voting': voting,
        'nominating': nominating,
        'ended': ended}
    self.RenderTemplate('vote.html', template_values)
class AdminPage(FreesideHandler):
  """The admin page request hanndler."""

  admintasks = {
    'AddMember': 'Add Member',
    'AddElection': 'Add Election',
    'ResetPassword': '******',
  }
  electiontypes = freesidemodels.GetAllElectionTypes()
  positions = ['President', 'Treasurer', 'Secretary', 'Board Member']

  def ResetPassword(self):
    """Scramble a members password and email it to them."""
    memberkey = self.request.get('resetmember')
    member = db.get(memberkey)
    # check that the member is active
    if not member_util.IsActiveMember(member):
      template_values = {'errortxt': 'Member is not active'}
      self.RenderTemplate('error.html', template_values)
      return
    # check that the members email address is valid
    if not mail.is_email_valid(member.email):
      template_values = {'errortxt': 'Members email is not valid'}
      self.RenderTemplate('error.html', template_values)
      return
    member_util.ResetAndEmailPassword(member)
    self.redirect('/admin?&task=ResetPassword')

  def AddMember(self):
    """Add a new member to the database."""
    #member_dict = dict(
    #  (p, self.request.get(p)) for p, cls in freesidemodels.Member._properties)
    member = member_util.SaveMember(
      member_util.MakeMember(
        username=self.request.get('username'),
        firstname=self.request.get('firstname'),
        lastname=self.request.get('lastname'),
        email=self.request.get('email'),
        password=self.request.get('password'),
        starving=self.request.get('starving') == 'True'))
    self.redirect('/admin')

  def _ParseDate(self, date_str, tzinfo=timezones.Eastern()):
    """Parses a date string in format "MM/DD/YYYY".

    Args:
      date_str: date string in format "MM/DD/YYYY"
      tzinfo: datetime.tzinfo, timezone for the date
    Returns:
      datetime.datetime
    """
    month, day, year = map(int, date_str.split('/'))
    return datetime.datetime(
      year=year, month=month, day=day, hour=0, minute=0, second=0)

  def AddElection(self):
    """Creates a new election."""
    # TODO(dknowles): Move this to election_util
    nominate_start = self._ParseDate(self.request.get('nomination_start'))
    nominate_end = self._ParseDate(self.request.get('nomination_end'))
    vote_start = self._ParseDate(self.request.get('vote_start'))
    vote_end = self._ParseDate(self.request.get('vote_end'))

    if not nominate_start < nominate_end <= vote_start < vote_end:
      raise Error('Dates are not in order.')

    election_type = self.request.get('election_type')
    if election_type not in self.electiontypes:
      raise Error('Invalid election type.')

    new_election = getattr(freesidemodels, election_type)(
      position=self.request.get('position'),
      nominate_start=nominate_start,
      nominate_end=nominate_end,
      vote_start=vote_start,
      vote_end=vote_end,
      description=self.request.get('description'))
    new_election.put()
    self.redirect('/admin')

  @RedirectIfUnauthorized
  @RedirectIfNotAdmin
  def get(self):
    template_values = {
      'admintasks': self.admintasks.items(),
      'admintask': self.request.get('task'),
      'electiontypes': self.electiontypes,
      'positions': self.positions,
      }
    if template_values['admintask'] == 'ResetPassword':
      members = sorted(member_util.GetActiveMembers(), key=lambda m: m.username)
      template_values['members'] = members
    self.RenderTemplate('admin.html', template_values)

  @RedirectIfUnauthorized
  @RedirectIfNotAdmin
  def post(self):
    task = self.request.get('task')
    if task not in self.admintasks:
      self.redirect('./')
    else:
      getattr(self, task)()