Example #1
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get('u', _current_user_email())
        if not _logged_in_user_has_permission_for(user_email):
            # TODO(csilvers): return a 403 here instead.
            raise RuntimeError('You do not have permissions to view user'
                               ' settings for %s' % user_email)
        # We won't put() the new user until the settings are saved.
        user = _get_or_create_user(user_email, put_new_user=False)
        try:
            user.key()
            is_new_user = False
        except db.NotSavedError:
            is_new_user = True

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': user.email,
            'is_admin': users.is_current_user_admin(),
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            'user': user,
            'is_new_user': is_new_user,
            'redirect_to': self.request.get('redirect_to', ''),
            # We could get this from user, but we want to replace
            # commas with newlines for printing.
            'wants_to_view': user.wants_to_view.replace(',', '\n'),
        }
        self.render_response('settings.html', template_values)
Example #2
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get('u', _current_user_email())
        if not _logged_in_user_has_permission_for(user_email):
            # TODO(csilvers): return a 403 here instead.
            raise RuntimeError('You do not have permissions to view user'
                               ' settings for %s' % user_email)
        # We won't put() the new user until the settings are saved.
        user = _get_or_create_user(user_email, put_new_user=False)
        try:
            user.key()
            is_new_user = False
        except db.NotSavedError:
            is_new_user = True

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': user.email,
            'is_admin': users.is_current_user_admin(),
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            'user': user,
            'is_new_user': is_new_user,
            'redirect_to': self.request.get('redirect_to', ''),
            # We could get this from user, but we want to replace
            # commas with newlines for printing.
            'wants_to_view': user.wants_to_view.replace(',', '\n'),
        }
        self.render_response('settings.html', template_values)
Example #3
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get("u", _current_user_email())
        if not _logged_in_user_has_permission_for(user_email):
            # TODO(csilvers): return a 403 here instead.
            raise RuntimeError("You do not have permissions to view user" " settings for %s" % user_email)
        # We won't put() the new user until the settings are saved.
        user = _get_or_create_user(user_email, put_new_user=False)
        try:
            user.key()
            is_new_user = False
        except db.NotSavedError:
            is_new_user = True

        template_values = {
            "logout_url": users.create_logout_url("/"),
            "message": self.request.get("msg"),
            "username": user.email,
            "is_admin": users.is_current_user_admin(),
            "view_week": util.existingsnippet_monday(_TODAY_FN()),
            "user": user,
            "is_new_user": is_new_user,
            "redirect_to": self.request.get("redirect_to", ""),
            # We could get this from user, but we want to replace
            # commas with newlines for printing.
            "wants_to_view": user.wants_to_view.replace(",", "\n"),
        }
        self.render_response("settings.html", template_values)
Example #4
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get('u', _current_user_email())
        user = util.get_user(user_email)

        if not user:
            template_values = {
                'login_url': users.create_login_url(self.request.uri),
                'logout_url': users.create_logout_url('/'),
                'username': user_email,
            }
            self.render_response('new_user.html', template_values)
            return

        snippets = util.snippets_for_user(user_email)

        if not _can_view_private_snippets(_current_user_email(), user_email):
            snippets = [snippet for snippet in snippets if not snippet.private]
        snippets = util.fill_in_missing_snippets(snippets, user, user_email,
                                                 _TODAY_FN())
        snippets.reverse()  # get to newest snippet first

        template_values = {
            'logout_url':
            users.create_logout_url('/'),
            'message':
            self.request.get('msg'),
            'username':
            user_email,
            'is_admin':
            users.is_current_user_admin(),
            'domain':
            user_email.split('@')[-1],
            'view_week':
            util.existingsnippet_monday(_TODAY_FN()),
            # Snippets for the week of <one week ago> are due today.
            'one_week_ago':
            _TODAY_FN().date() - datetime.timedelta(days=7),
            'eight_days_ago':
            _TODAY_FN().date() - datetime.timedelta(days=8),
            'editable': (_logged_in_user_has_permission_for(user_email)
                         and self.request.get('edit', '1') == '1'),
            'user':
            user,
            'snippets':
            snippets,
            'null_snippet_text':
            models.NULL_SNIPPET_TEXT,
            'null_category':
            models.NULL_CATEGORY,
        }
        self.render_response('user_snippets.html', template_values)
Example #5
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get('u', _current_user_email())
        user = util.get_user(user_email)

        if not user:
            # If there are no app settings, set those up before setting
            # up the user settings.
            if users.is_current_user_admin():
                try:
                    models.AppSettings.get()
                except ValueError:
                    self.redirect("/admin/settings?redirect_to=user_setting"
                                  "&msg=Welcome+to+the+snippet+server!+"
                                  "Please+take+a+moment+to+configure+it.")
                    return

            template_values = {
                'new_user': True,
                'login_url': users.create_login_url(self.request.uri),
                'logout_url': users.create_logout_url('/'),
                'username': user_email,
            }
            self.render_response('new_user.html', template_values)
            return

        snippets = util.snippets_for_user(user_email)

        if not _can_view_private_snippets(_current_user_email(), user_email):
            snippets = [snippet for snippet in snippets if not snippet.private]
        snippets = util.fill_in_missing_snippets(snippets, user,
                                                 user_email, _TODAY_FN())
        snippets.reverse()                  # get to newest snippet first

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': user_email,
            'is_admin': users.is_current_user_admin(),
            'domain': user_email.split('@')[-1],
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            # Snippets for the week of <one week ago> are due today.
            'one_week_ago': _TODAY_FN().date() - datetime.timedelta(days=7),
            'eight_days_ago': _TODAY_FN().date() - datetime.timedelta(days=8),
            'editable': (_logged_in_user_has_permission_for(user_email) and
                         self.request.get('edit', '1') == '1'),
            'user': user,
            'snippets': snippets,
            'null_category': models.NULL_CATEGORY,
        }
        self.render_response('user_snippets.html', template_values)
Example #6
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get('u', _current_user_email())
        user = util.get_user(user_email)

        if not user:
            # If there are no app settings, set those up before setting
            # up the user settings.
            if users.is_current_user_admin():
                try:
                    models.AppSettings.get()
                except ValueError:
                    self.redirect("/admin/settings?redirect_to=user_setting"
                                  "&msg=Welcome+to+the+snippet+server!+"
                                  "Please+take+a+moment+to+configure+it.")
                    return

            template_values = {
                'new_user': True,
                'login_url': users.create_login_url(self.request.uri),
                'logout_url': users.create_logout_url('/'),
                'username': user_email,
            }
            self.render_response('new_user.html', template_values)
            return

        snippets = util.snippets_for_user(user_email)

        if not _can_view_private_snippets(_current_user_email(), user_email):
            snippets = [snippet for snippet in snippets if not snippet.private]
        snippets = util.fill_in_missing_snippets(snippets, user,
                                                 user_email, _TODAY_FN())
        snippets.reverse()                  # get to newest snippet first

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': user_email,
            'is_admin': users.is_current_user_admin(),
            'domain': user_email.split('@')[-1],
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            # Snippets for the week of <one week ago> are due today.
            'one_week_ago': _TODAY_FN().date() - datetime.timedelta(days=7),
            'eight_days_ago': _TODAY_FN().date() - datetime.timedelta(days=8),
            'editable': (_logged_in_user_has_permission_for(user_email) and
                         self.request.get('edit', '1') == '1'),
            'user': user,
            'snippets': snippets,
            'null_category': models.NULL_CATEGORY,
        }
        self.render_response('user_snippets.html', template_values)
Example #7
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        user_email = self.request.get("u", _current_user_email())
        user = util.get_user(user_email)

        if not user:
            # If there are no app settings, set those up before setting
            # up the user settings.
            if users.is_current_user_admin():
                try:
                    models.AppSettings.get()
                except ValueError:
                    self.redirect(
                        "/admin/settings?redirect_to=user_setting"
                        "&msg=Welcome+to+the+snippet+server!+"
                        "Please+take+a+moment+to+configure+it."
                    )
                    return

            template_values = {
                "new_user": True,
                "login_url": users.create_login_url(self.request.uri),
                "logout_url": users.create_logout_url("/"),
                "username": user_email,
            }
            self.render_response("new_user.html", template_values)
            return

        snippets = util.snippets_for_user(user_email)

        if not _can_view_private_snippets(_current_user_email(), user_email):
            snippets = [snippet for snippet in snippets if not snippet.private]
        snippets = util.fill_in_missing_snippets(snippets, user, user_email, _TODAY_FN())
        snippets.reverse()  # get to newest snippet first

        template_values = {
            "logout_url": users.create_logout_url("/"),
            "message": self.request.get("msg"),
            "username": user_email,
            "is_admin": users.is_current_user_admin(),
            "domain": user_email.split("@")[-1],
            "view_week": util.existingsnippet_monday(_TODAY_FN()),
            # Snippets for the week of <one week ago> are due today.
            "one_week_ago": _TODAY_FN().date() - datetime.timedelta(days=7),
            "eight_days_ago": _TODAY_FN().date() - datetime.timedelta(days=8),
            "editable": (_logged_in_user_has_permission_for(user_email) and self.request.get("edit", "1") == "1"),
            "user": user,
            "snippets": snippets,
            "null_category": models.NULL_CATEGORY,
        }
        self.render_response("user_snippets.html", template_values)
Example #8
0
    def get(self):
        my_domain = _current_user_email().split("@")[-1]
        app_settings = models.AppSettings.get(create_if_missing=True, domains=[my_domain])

        template_values = {
            "logout_url": users.create_logout_url("/"),
            "message": self.request.get("msg"),
            "username": _current_user_email(),
            "is_admin": users.is_current_user_admin(),
            "view_week": util.existingsnippet_monday(_TODAY_FN()),
            "redirect_to": self.request.get("redirect_to", ""),
            "settings": app_settings,
            "slack_slash_commands": (slacklib.command_usage().strip()),
        }
        self.render_response("app_settings.html", template_values)
Example #9
0
    def get(self):
        my_domain = _current_user_email().split('@')[-1]
        app_settings = models.AppSettings.get(create_if_missing=True,
                                              domains=[my_domain])

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': _current_user_email(),
            'is_admin': users.is_current_user_admin(),
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            'redirect_to': self.request.get('redirect_to', ''),
            'settings': app_settings,
            'slack_slash_commands': (slacklib.command_usage().strip())
        }
        self.render_response('app_settings.html', template_values)
Example #10
0
    def get(self):
        my_domain = _current_user_email().split('@')[-1]
        app_settings = models.AppSettings.get(create_if_missing=True,
                                              domains=[my_domain])

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': _current_user_email(),
            'is_admin': users.is_current_user_admin(),
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            'redirect_to': self.request.get('redirect_to', ''),
            'settings': app_settings,
            'slack_slash_commands': (
                slacklib.command_usage().strip())
        }
        self.render_response('app_settings.html', template_values)
Example #11
0
def _get_email_to_current_snippet_map(today):
    """Return a map from email to True if they've written snippets this week.

    Goes through all users registered on the system, and checks if
    they have a snippet in the db for the appropriate snippet-week for
    'today'.  If so, they get entered into the return-map with value
    True.  If not, they have value False.

    Note that users whose 'wants_email' field is set to False will not
    be included in either list.

    Arguments:
      today: a datetime.datetime object representing the
        'current' day.  We use the normal algorithm to determine what is
        the most recent snippet-week for this day.

    Returns:
      a map from email (user.email for each user) to True or False,
      depending on if they've written snippets for this week or not.
    """
    user_q = models.User.all()
    users = user_q.fetch(1000)
    retval = {}
    for user in users:
        if not user.wants_email:  # ignore this user
            continue
        retval[user.email] = False  # assume the worst, for now

    week = util.existingsnippet_monday(today)
    snippets_q = models.Snippet.all()
    snippets_q.filter('week = ', week)
    snippets = snippets_q.fetch(1000)
    for snippet in snippets:
        if snippet.email in retval:  # don't introduce new keys here
            retval[snippet.email] = True

    return retval
Example #12
0
def _get_email_to_current_snippet_map(today):
    """Return a map from email to True if they've written snippets this week.

    Goes through all users registered on the system, and checks if
    they have a snippet in the db for the appropriate snippet-week for
    'today'.  If so, they get entered into the return-map with value
    True.  If not, they have value False.

    Note that users whose 'wants_email' field is set to False will not
    be included in either list.

    Arguments:
      today: a datetime.datetime object representing the
        'current' day.  We use the normal algorithm to determine what is
        the most recent snippet-week for this day.

    Returns:
      a map from email (user.email for each user) to True or False,
      depending on if they've written snippets for this week or not.
    """
    user_q = models.User.all()
    users = user_q.fetch(1000)
    retval = {}
    for user in users:
        if not user.wants_email:         # ignore this user
            continue
        retval[user.email] = False       # assume the worst, for now

    week = util.existingsnippet_monday(today)
    snippets_q = models.Snippet.all()
    snippets_q.filter('week = ', week)
    snippets = snippets_q.fetch(1000)
    for snippet in snippets:
        if snippet.email in retval:      # don't introduce new keys here
            retval[snippet.email] = True

    return retval
Example #13
0
    def get(self):
        # options are 'email', 'creation_time', 'last_snippet_time'
        sort_by = self.request.get('sort_by', 'creation_time')

        # First, check if the user had clicked on a button.
        for (name, value) in self.request.params.iteritems():
            if name.startswith('hide '):
                email_of_user_to_hide = name[len('hide '):]
                # TODO(csilvers): move this get/update/put atomic into a txn
                user = util.get_user_or_die(email_of_user_to_hide)
                user.is_hidden = True
                user.put()
                time.sleep(0.1)  # encourage eventual consistency
                self.redirect('/admin/manage_users?sort_by=%s&msg=%s+hidden' %
                              (sort_by, email_of_user_to_hide))
                return
            if name.startswith('unhide '):
                email_of_user_to_unhide = name[len('unhide '):]
                # TODO(csilvers): move this get/update/put atomic into a txn
                user = util.get_user_or_die(email_of_user_to_unhide)
                user.is_hidden = False
                user.put()
                time.sleep(0.1)  # encourage eventual consistency
                self.redirect(
                    '/admin/manage_users?sort_by=%s&msg=%s+unhidden' %
                    (sort_by, email_of_user_to_unhide))
                return
            if name.startswith('delete '):
                email_of_user_to_delete = name[len('delete '):]
                user = util.get_user_or_die(email_of_user_to_delete)
                db.delete(user)
                time.sleep(0.1)  # encourage eventual consistency
                self.redirect('/admin/manage_users?sort_by=%s&msg=%s+deleted' %
                              (sort_by, email_of_user_to_delete))
                return

        user_q = models.User.all()
        results = user_q.fetch(1000)

        # Tuple: (email, is-hidden, creation-time, days since last snippet)
        user_data = []
        for user in results:
            # Get the last snippet for that user.
            last_snippet = util.most_recent_snippet_for_user(user.email)
            if last_snippet:
                seconds_since_snippet = ((_TODAY_FN().date() -
                                          last_snippet.week).total_seconds())
                weeks_since_snippet = int(
                    seconds_since_snippet /
                    datetime.timedelta(days=7).total_seconds())
            else:
                weeks_since_snippet = None
            user_data.append((user.email, user.is_hidden, user.created,
                              weeks_since_snippet))

        # We have to use 'cmp' here since we want ascending in the
        # primary key and descending in the secondary key, sometimes.
        if sort_by == 'email':
            user_data.sort(lambda x, y: cmp(x[0], y[0]))
        elif sort_by == 'creation_time':
            user_data.sort(lambda x, y: (-cmp(x[2] or datetime.datetime.min, y[
                2] or datetime.datetime.min) or cmp(x[0], y[0])))
        elif sort_by == 'last_snippet_time':
            user_data.sort(lambda x, y: (-cmp(1000 if x[3] is None else x[
                3], 1000 if y[3] is None else y[3]) or cmp(x[0], y[0])))
        else:
            raise ValueError('Invalid sort_by value "%s"' % sort_by)

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': _current_user_email(),
            'is_admin': users.is_current_user_admin(),
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            'user_data': user_data,
            'sort_by': sort_by,
        }
        self.render_response('manage_users.html', template_values)
Example #14
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        week_string = self.request.get('week')
        if week_string:
            week = datetime.datetime.strptime(week_string, '%m-%d-%Y').date()
        else:
            week = util.existingsnippet_monday(_TODAY_FN())

        snippets_q = models.Snippet.all()
        snippets_q.filter('week = ', week)
        snippets = snippets_q.fetch(1000)  # good for many users...
        # TODO(csilvers): filter based on wants_to_view

        # Get all the user records so we can categorize snippets.
        user_q = models.User.all()
        results = user_q.fetch(1000)
        email_to_category = {}
        email_to_user = {}
        for result in results:
            # People aren't very good about capitalizing their
            # categories consistently, so we enforce title-case,
            # with exceptions for 'and'.
            email_to_category[result.email] = _title_case(result.category)
            email_to_user[result.email] = result

        # Collect the snippets and users by category.  As we see each email,
        # delete it from email_to_category.  At the end of this,
        # email_to_category will hold people who did not give
        # snippets this week.
        snippets_and_users_by_category = {}
        for snippet in snippets:
            # Ignore this snippet if we don't have permission to view it.
            if (snippet.private and not _can_view_private_snippets(
                    _current_user_email(), snippet.email)):
                continue
            category = email_to_category.get(snippet.email,
                                             models.NULL_CATEGORY)
            if snippet.email in email_to_user:
                snippets_and_users_by_category.setdefault(category, []).append(
                    (snippet, email_to_user[snippet.email]))
            else:
                snippets_and_users_by_category.setdefault(category, []).append(
                    (snippet, models.User(email=snippet.email)))

            if snippet.email in email_to_category:
                del email_to_category[snippet.email]

        # Add in empty snippets for the people who didn't have any --
        # unless a user is marked 'hidden'.  (That's what 'hidden'
        # means: pretend they don't exist until they have a non-empty
        # snippet again.)
        for (email, category) in email_to_category.iteritems():
            if not email_to_user[email].is_hidden:
                snippet = models.Snippet(email=email, week=week)
                snippets_and_users_by_category.setdefault(category, []).append(
                    (snippet, email_to_user[snippet.email]))

        # Now get a sorted list, categories in alphabetical order and
        # each snippet-author within the category in alphabetical
        # order.
        # The data structure is ((category, ((snippet, user), ...)), ...)
        categories_and_snippets = []
        for (category,
             snippets_and_users) in snippets_and_users_by_category.iteritems():
            snippets_and_users.sort(key=lambda (snippet, user): snippet.email)
            categories_and_snippets.append((category, snippets_and_users))
        categories_and_snippets.sort()

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            # Used only to switch to 'username' mode and to modify settings.
            'username': _current_user_email(),
            'is_admin': users.is_current_user_admin(),
            'prev_week': week - datetime.timedelta(7),
            'view_week': week,
            'next_week': week + datetime.timedelta(7),
            'categories_and_snippets': categories_and_snippets,
        }
        self.render_response('weekly_snippets.html', template_values)
Example #15
0
    def get(self):
        # options are 'email', 'creation_time', 'last_snippet_time'
        sort_by = self.request.get('sort_by', 'creation_time')

        # First, check if the user had clicked on a button.
        for (name, value) in self.request.params.iteritems():
            if name.startswith('hide '):
                email_of_user_to_hide = name[len('hide '):]
                # TODO(csilvers): move this get/update/put atomic into a txn
                user = util.get_user_or_die(email_of_user_to_hide)
                user.is_hidden = True
                user.put()
                time.sleep(0.1)   # encourage eventual consistency
                self.redirect('/admin/manage_users?sort_by=%s&msg=%s+hidden'
                              % (sort_by, email_of_user_to_hide))
                return
            if name.startswith('unhide '):
                email_of_user_to_unhide = name[len('unhide '):]
                # TODO(csilvers): move this get/update/put atomic into a txn
                user = util.get_user_or_die(email_of_user_to_unhide)
                user.is_hidden = False
                user.put()
                time.sleep(0.1)   # encourage eventual consistency
                self.redirect('/admin/manage_users?sort_by=%s&msg=%s+unhidden'
                              % (sort_by, email_of_user_to_unhide))
                return
            if name.startswith('delete '):
                email_of_user_to_delete = name[len('delete '):]
                user = util.get_user_or_die(email_of_user_to_delete)
                db.delete(user)
                time.sleep(0.1)   # encourage eventual consistency
                self.redirect('/admin/manage_users?sort_by=%s&msg=%s+deleted'
                              % (sort_by, email_of_user_to_delete))
                return

        user_q = models.User.all()
        results = user_q.fetch(1000)

        # Tuple: (email, is-hidden, creation-time, days since last snippet)
        user_data = []
        for user in results:
            # Get the last snippet for that user.
            last_snippet = util.most_recent_snippet_for_user(user.email)
            if last_snippet:
                seconds_since_snippet = (
                    (_TODAY_FN().date() - last_snippet.week).total_seconds())
                weeks_since_snippet = int(
                    seconds_since_snippet /
                    datetime.timedelta(days=7).total_seconds())
            else:
                weeks_since_snippet = None
            user_data.append((user.email, user.is_hidden,
                              user.created, weeks_since_snippet))

        # We have to use 'cmp' here since we want ascending in the
        # primary key and descending in the secondary key, sometimes.
        if sort_by == 'email':
            user_data.sort(lambda x, y: cmp(x[0], y[0]))
        elif sort_by == 'creation_time':
            user_data.sort(lambda x, y: (-cmp(x[2] or datetime.datetime.min,
                                              y[2] or datetime.datetime.min)
                                         or cmp(x[0], y[0])))
        elif sort_by == 'last_snippet_time':
            user_data.sort(lambda x, y: (-cmp(1000 if x[3] is None else x[3],
                                              1000 if y[3] is None else y[3])
                                         or cmp(x[0], y[0])))
        else:
            raise ValueError('Invalid sort_by value "%s"' % sort_by)

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            'username': _current_user_email(),
            'is_admin': users.is_current_user_admin(),
            'view_week': util.existingsnippet_monday(_TODAY_FN()),
            'user_data': user_data,
            'sort_by': sort_by,
        }
        self.render_response('manage_users.html', template_values)
Example #16
0
    def get(self):
        if not users.get_current_user():
            return _login_page(self.request, self)

        week_string = self.request.get('week')
        if week_string:
            week = datetime.datetime.strptime(week_string, '%m-%d-%Y').date()
        else:
            week = util.existingsnippet_monday(_TODAY_FN())

        snippets_q = models.Snippet.all()
        snippets_q.filter('week = ', week)
        snippets = snippets_q.fetch(1000)   # good for many users...
        # TODO(csilvers): filter based on wants_to_view

        # Get all the user records so we can categorize snippets.
        user_q = models.User.all()
        results = user_q.fetch(1000)
        email_to_category = {}
        email_to_user = {}
        for result in results:
            # People aren't very good about capitalizing their
            # categories consistently, so we enforce title-case,
            # with exceptions for 'and'.
            email_to_category[result.email] = _title_case(result.category)
            email_to_user[result.email] = result

        # Collect the snippets and users by category.  As we see each email,
        # delete it from email_to_category.  At the end of this,
        # email_to_category will hold people who did not give
        # snippets this week.
        snippets_and_users_by_category = {}
        for snippet in snippets:
            # Ignore this snippet if we don't have permission to view it.
            if (snippet.private and
                    not _can_view_private_snippets(_current_user_email(),
                                                   snippet.email)):
                continue
            category = email_to_category.get(
                snippet.email, models.NULL_CATEGORY
            )
            if snippet.email in email_to_user:
                snippets_and_users_by_category.setdefault(category, []).append(
                    (snippet, email_to_user[snippet.email])
                )
            else:
                snippets_and_users_by_category.setdefault(category, []).append(
                    (snippet, models.User(email=snippet.email))
                )

            if snippet.email in email_to_category:
                del email_to_category[snippet.email]

        # Add in empty snippets for the people who didn't have any --
        # unless a user is marked 'hidden'.  (That's what 'hidden'
        # means: pretend they don't exist until they have a non-empty
        # snippet again.)
        for (email, category) in email_to_category.iteritems():
            if not email_to_user[email].is_hidden:
                snippet = models.Snippet(email=email, week=week)
                snippets_and_users_by_category.setdefault(category, []).append(
                    (snippet, email_to_user[snippet.email])
                )

        # Now get a sorted list, categories in alphabetical order and
        # each snippet-author within the category in alphabetical
        # order.
        # The data structure is ((category, ((snippet, user), ...)), ...)
        categories_and_snippets = []
        for (category,
             snippets_and_users) in snippets_and_users_by_category.iteritems():
            snippets_and_users.sort(key=lambda (snippet, user): snippet.email)
            categories_and_snippets.append((category, snippets_and_users))
        categories_and_snippets.sort()

        template_values = {
            'logout_url': users.create_logout_url('/'),
            'message': self.request.get('msg'),
            # Used only to switch to 'username' mode and to modify settings.
            'username': _current_user_email(),
            'is_admin': users.is_current_user_admin(),
            'prev_week': week - datetime.timedelta(7),
            'view_week': week,
            'next_week': week + datetime.timedelta(7),
            'categories_and_snippets': categories_and_snippets,
        }
        self.render_response('weekly_snippets.html', template_values)