def render_preference_panel(self, req, panel):

        agreed = ProjectMessageRecord.get_user_records(self.env, req.authname)
        for m in agreed:
            m['agreed_at'] = m['agreed_at'].strftime("%Y-%m-%d %H:%M")
        disagreed = ProjectMessage.get_unagreed_messages(self.env, req.authname)

        data = {
            'agreed': agreed,
            'unagreed': disagreed,
        }

        return 'project_message_prefs.html', data
    def filter_stream(self, req, method, filename, stream, data):
        """
        Check for alert messages to show authenticated user.

        If there are any project messages that the authenticated user has not 
        seen, which are selected to be viewed as alert based notifications, 
        we add the necessary mark-up and javscript.
        """

        if req.authname != 'anonymous':

            timeout_exceeded = self._timeout_limit_exceeded(req)
            if timeout_exceeded or timeout_exceeded is None:

                # we can check for alert notifications
                unagreed = ProjectMessage.get_unagreed_messages(self.env, 
                            req.authname, 'Alert')
                if unagreed:
                    # we only shown one notification at a time currently
                    msg = unagreed[0]
                    msg['message'] = format_to_html(self.env, 
                                        Context.from_request(req), msg['message'])
                    alert_markup = tag(
                                    tag.div(
                                        tag.i(
                                            class_="alert-icon fa fa-info-circle"
                                        ),
                                        tag.ul(
                                            tag.li(msg['message'],
                                                class_="alert-message"
                                            ),
                                        ),
                                        tag.button(msg['button'],
                                            class_="close btn btn-mini",
                                            type="button",
                                            data_dismiss="alert"
                                        ),
                                        class_="project-message cf alert alert-info alert-dismissable individual"
                                    ),
                                    tag.form(
                                        tag.input(
                                            name="name",
                                            value=msg['name'],
                                            type="text",
                                        ),
                                        tag.input(
                                            name="agree",
                                            value=True,
                                            type="text",
                                        ),
                                        class_="hidden",
                                        method="post",
                                        action="",
                                    ),
                                  )

                    stream |= Transformer("//*[@id='main']/*[1]").before(alert_markup)
                    add_script(req, 'projectmessage/js/project_message.js')

                # if the timeout has been exceeded or does not exist yet, 
                # and there are no notifications to show, we update the 
                # session attribute table
                if not ProjectMessage.get_unagreed_messages(self.env, req.authname):
                    stamp = str(to_utimestamp(datetime.now(pytz.utc)))
                    req.session['project_message_timeout'] = stamp
                    req.session.save()

        return stream