def get_build_ref_markup(nav_url, jobs, content):
    '''Return build reference markup expanded by RefHudsonBuild macro.

    ex1. [[RefHudsonBuild(j3, 1)]
    >>> str(get_build_ref_markup('http://example.com/hudson/', ['j1','j2'], 'j3,1'))
    '<a class="ext-link" href="http://example.com/hudson/job/j3/1/"><span class="icon"></span>Hudson: j3#1</a>'
    
    ex2. [[RefHudsonBuild(1)] ; jobs = [j1, j2]
    >>> str(get_build_ref_markup('http://example.com/hudson/', ['j1','j2'], '1'))
    '<a class="ext-link" href="http://example.com/hudson/job/j1/1/"><span class="icon"></span>Hudson: j1#1</a>'

    Also, _markup functions must be charcter-escaped.
    >>> str(get_build_ref_markup('spam/', ['j1','j2'], '><",1'))
    '<a class="ext-link" href="spam/job/&gt;&lt;&#34;/1/"><span class="icon"></span>Hudson: &gt;&lt;&#34;#1</a>'
    >>> str(get_build_ref_markup('spam/', ['><"','j2'], '1'))
    '<a class="ext-link" href="spam/job/&gt;&lt;&#34;/1/"><span class="icon"></span>Hudson: &gt;&lt;&#34;#1</a>'

    '''
    FORMAT = '<a class="ext-link" href="%sjob/%s/%s/"><span class="icon"></span>Hudson: %s#%s</a>'
    args = map(lambda x: x.strip(), str(content).split(','))
    if len(args) == 1:
        if len(jobs) == 0:
            return ''
        job_name = Markup.escape(jobs[0].strip())
        job_no = Markup.escape(args[0])
    else:
        job_name = Markup.escape(args[0])
        job_no = Markup.escape(args[1])

    return Markup(FORMAT % (nav_url, job_name, job_no, job_name, job_no))
def get_navi_markup(disp, url, label):
    """Return the navigation element markup.

    If nav_url is true, make an element to open other window.
    >>> str(get_navi_markup(True, 'url', 'label'))
    '<a class="ext-link" href="url" target="hudson"><span class="icon"></span>label</a>'

    If nav_url is false, make an element to link only.
    >>> str(get_navi_markup(False, 'url', 'label'))
    '<a class="ext-link" href="url" ><span class="icon"></span>label</a>'

    Also, _markup functions must be charcter-escaped.
    >>> str(get_navi_markup(False, '"<>', 'label'))
    '<a class="ext-link" href="&#34;&lt;&gt;" ><span class="icon"></span>label</a>'
    >>> str(get_navi_markup(False, 'url', '"<>'))
    '<a class="ext-link" href="url" ><span class="icon"></span>&#34;&lt;&gt;</a>'
    """
    FORMAT = '<a class="ext-link" href="%s" %s><span class="icon"></span>%s</a>'
    escaped_url = Markup.escape(url)
    escaped_label = Markup.escape(label)

    if disp:
        target = 'target="hudson"'
    else:
        target = ''

    return Markup(FORMAT % (escaped_url, target, escaped_label))
def get_build_title_markup(job, build):
    '''Return build title for timeline.

    >>> str(get_build_title_markup({'name': 'jobname'}, {'number':1, 'result':'SUCCESS'}))
    '<img src="chrome/common/extlink.gif">jobname #1 - build-success</a>'

    Also, _markup functions must be charcter-escaped.
    >>> str(get_build_title_markup({'name': 'jobname'}, {'number':'><"', 'result':'SUCCESS'}))
    '<img src="chrome/common/extlink.gif">jobname #&gt;&lt;&#34; - build-success</a>'
    >>> str(get_build_title_markup({'name': '><"'}, {'number':1, 'result':'SUCCESS'}))
    '<img src="chrome/common/extlink.gif">&gt;&lt;&#34; #1 - build-success</a>'
    '''
    FORMAT = '<img src="chrome/common/extlink.gif">%s #%s - %s</a>'
    build_number = Markup.escape(str(build['number']))
    job_name = Markup.escape(job['name'])
    return Markup(FORMAT % (job_name, build_number, get_build_kind(build)))
예제 #4
0
    def process_request(self, req):
        req.hdf['trac.href.blog'] = req.href.blog()

        entries = []
        for page_name in WikiSystem(self.env).get_pages(prefix='Blog'):
            page = WikiPage(self.env, page_name)
            title = page_name
            text = page.text

            match = title_split_match(page.text)
            if match:
                title = match.group(1)
                text = match.group(2)

            comments = text.count('[[SimpleBlogComment(')
            cutoff = text.find('[[SimpleBlogComment(')
            if cutoff >= 0:
                text = text[:cutoff].rstrip()
            description = wiki_to_html(text, self.env, req)

            original = self._get_original_post_info(page_name)
            event = {
                'href': self.env.href.wiki(page_name),
                'title': title,
                'description': description,
                'escaped': Markup.escape(unicode(description)),
                'date': format_datetime(original['time']),
                'rfcdate': http_date(original['time']),
                'author': original['author'],
                'comment': original['comment'],
                'comments': comments,
                }
            if page.version > 1:
                event['updated.version'] = page.version
                event['updated.date'] = format_datetime(page.time)
                event['updated.rfcdate'] = http_date(page.time)
                event['updated.author'] = page.author
                event['updated.comment'] = page.comment
            entries.append((original['time'], event))

        entries.sort()
        entries.reverse()
        max_count = 20
        if len(entries) > max_count:
            entries = entries[:max_count]

        events = []
        for date, event in entries:
            events.append(event)
        req.hdf['blog.events'] = events

        format = req.args.get('format')
        if format == 'rss':
            return 'blog_rss.cs', 'application/rss+xml'

        add_link(req, 'alternate', self.env.href.blog(format='rss'),
                 'RSS Feed', 'application/rss+xml', 'rss')
        return 'blog.cs', None
예제 #5
0
    def process_request(self, req):
        req.hdf['trac.href.blog'] = req.href.blog()

        entries = []
        for page_name in WikiSystem(self.env).get_pages(prefix='Blog'):
            page = WikiPage(self.env, page_name)
            title = page_name
            text = page.text

            match = title_split_match(page.text)
            if match:
                title = match.group(1)
                text = match.group(2)

            comments = text.count('[[SimpleBlogComment(')
            cutoff = text.find('[[SimpleBlogComment(')
            if cutoff >= 0:
                text = text[:cutoff].rstrip()
            description = wiki_to_html(text, self.env, req)

            original = self._get_original_post_info(page_name)
            event = {
                'href': self.env.href.wiki(page_name),
                'title': title,
                'description': description,
                'escaped': Markup.escape(unicode(description)),
                'date': format_datetime(original['time']),
                'rfcdate': http_date(original['time']),
                'author': original['author'],
                'comment': original['comment'],
                'comments': comments,
            }
            if page.version > 1:
                event['updated.version'] = page.version
                event['updated.date'] = format_datetime(page.time)
                event['updated.rfcdate'] = http_date(page.time)
                event['updated.author'] = page.author
                event['updated.comment'] = page.comment
            entries.append((original['time'], event))

        entries.sort()
        entries.reverse()
        max_count = 20
        if len(entries) > max_count:
            entries = entries[:max_count]

        events = []
        for date, event in entries:
            events.append(event)
        req.hdf['blog.events'] = events

        format = req.args.get('format')
        if format == 'rss':
            return 'blog_rss.cs', 'application/rss+xml'

        add_link(req, 'alternate', self.env.href.blog(format='rss'),
                 'RSS Feed', 'application/rss+xml', 'rss')
        return 'blog.cs', None
예제 #6
0
    def get_timeline_events(self, req, start, stop, filters):
        format = req.args.get('format')

        href = format == 'rss' and req.abs_href or req.href

        # Ticket changes
        if 'worklog' in filters:
            add_stylesheet(req, "worklog/worklogplugin.css")
            db = self.env.get_db_cnx()
            cursor = db.cursor()

            cursor.execute(
                """SELECT wl.user,wl.ticket,wl.time,wl.starttime,wl.comment,wl.kind,wl.humankind,t.summary,t.status
                             FROM (
                             
                             SELECT user, ticket, starttime AS time, starttime, comment, 'workstart' AS kind, 'started' AS humankind
                             FROM work_log

                             UNION

                             SELECT user, ticket, endtime AS time, starttime, comment, 'workstop' AS kind, 'stopped' AS humankind
                             FROM work_log

                             ) AS wl
                             INNER JOIN ticket t ON t.id = wl.ticket 
                                 AND wl.time>=%s AND wl.time<=%s 
                           ORDER BY wl.time""" % (start, stop))
            previous_update = None
            for user, ticket, time, starttime, comment, kind, humankind, summary, status in cursor:
                summary = Markup.escape(summary)
                time = float(time)
                starttime = float(starttime)
                if format == 'rss':
                    title = Markup('%s %s working on Ticket #%s (%s): %s' % \
                                   (user, humankind, ticket, summary, comment))
                else:
                    title = Markup('%s %s working on Ticket <em title="%s">#%s</em>' % \
                                   (user, humankind, summary, ticket))
                message = ''
                if kind == 'workstop':
                    started = datetime.fromtimestamp(starttime)
                    finished = datetime.fromtimestamp(time)
                    if comment:
                        message = wiki_to_oneliner(
                            comment, self.env, db, shorten=True) + Markup(
                                '<br />(Time spent: %s)' %
                                pretty_timedelta(started, finished))
                    else:
                        message = 'Time spent: %s' % pretty_timedelta(
                            started, finished)
                yield kind, href.ticket(ticket), title, time, user, message
예제 #7
0
 def _make_js(self, req):
     """Generate the needed Javascript."""
     adds = []
     for adder in self.ctxtnav_adders:
         if adder.match_ctxtnav_add(req):
             for add in adder.get_ctxtnav_adds(req):
                 if isinstance(add, Markup):
                     adds.append(Markup(add.replace("'","\\'")))
                 else:
                     href, text = add
                     adds.append(Markup('<a href="%s">%s</a>'%(href,Markup.escape(text,False))))
     js = ""
     for add in adds:
         js += "add_ctxtnav('%s');\n"%add
     return """<script type="text/javascript">%s</script>"""%js
예제 #8
0
    def get_timeline_events(self, req, start, stop, filters):
        format = req.args.get('format')

        href = format == 'rss' and req.abs_href or req.href

        # Ticket changes
        if 'worklog' in filters:
            add_stylesheet(req, "worklog/worklogplugin.css")
            db = self.env.get_db_cnx()
            cursor = db.cursor()

            cursor.execute("""SELECT wl.user,wl.ticket,wl.time,wl.starttime,wl.comment,wl.kind,wl.humankind,t.summary,t.status
                             FROM (
                             
                             SELECT user, ticket, starttime AS time, starttime, comment, 'workstart' AS kind, 'started' AS humankind
                             FROM work_log

                             UNION

                             SELECT user, ticket, endtime AS time, starttime, comment, 'workstop' AS kind, 'stopped' AS humankind
                             FROM work_log

                             ) AS wl
                             INNER JOIN ticket t ON t.id = wl.ticket 
                                 AND wl.time>=%s AND wl.time<=%s 
                           ORDER BY wl.time"""
                           % (start, stop))
            previous_update = None
            for user,ticket,time,starttime,comment,kind,humankind,summary,status in cursor:
                summary = Markup.escape(summary)
                time = float(time)
                starttime = float(starttime)
                if format == 'rss':
                    title = Markup('%s %s working on Ticket #%s (%s): %s' % \
                                   (user, humankind, ticket, summary, comment))
                else:
                    title = Markup('%s %s working on Ticket <em title="%s">#%s</em>' % \
                                   (user, humankind, summary, ticket))
                message = ''
                if kind == 'workstop':
                    started = datetime.fromtimestamp(starttime)
                    finished = datetime.fromtimestamp(time)
                    if comment:
                        message = wiki_to_oneliner(comment, self.env, db, shorten=True) + Markup('<br />(Time spent: %s)' % pretty_timedelta(started, finished))
                    else:
                        message = 'Time spent: %s' % pretty_timedelta(started, finished)
                yield kind, href.ticket(ticket), title, time, user, message
예제 #9
0
 def _make_js(self, req):
     """Generate the needed Javascript."""
     adds = []
     for adder in self.ctxtnav_adders:
         if adder.match_ctxtnav_add(req):
             for add in adder.get_ctxtnav_adds(req):
                 if isinstance(add, Markup):
                     adds.append(Markup(add.replace("'", "\\'")))
                 else:
                     href, text = add
                     adds.append(
                         Markup('<a href="%s">%s</a>' %
                                (href, Markup.escape(text, False))))
     js = ""
     for add in adds:
         js += "add_ctxtnav('%s');\n" % add
     return """<script type="text/javascript">%s</script>""" % js
예제 #10
0
    def _generate_blog(self, req, *args, **kwargs):
        """Extract the blog pages and fill the HDF.

        *args is a list of tags to use to limit the blog scope
        **kwargs are any aditional keyword arguments that are needed
        """
        tallies = {}
        tags = TagEngine(self.env).tagspace.wiki
        try:
            union = kwargs['union']
        except KeyError:
            union = False
        # Formatting
        read_post = "[wiki:%s Read Post]"
        entries = {}
        if not len(args):
            tlist = [self.env.config.get('blog', 'default_tag', 'blog')]
        else:
            tlist = args
        if union:
            blog = tags.get_tagged_names(tlist, operation='union')
        else:
            blog = tags.get_tagged_names(tlist, operation='intersection')
        macropage = req.args.get('page', None)

        poststart, postend, default_times = self._get_time_range(req, **kwargs)
        mark_updated = self._choose_value('mark_updated',
                                          req,
                                          kwargs,
                                          convert=bool_val)
        if not mark_updated and (not isinstance(mark_updated, bool)):
            mark_updated = bool_val(
                self.env.config.get('blog', 'mark_updated', True))
        macro_bl = self.env.config.get('blog', 'macro_blacklist',
                                       '').split(',')
        macro_bl = [name.strip() for name in macro_bl if name.strip()]
        macro_bl.append('BlogShow')

        # Get the email addresses of all known users and validate the "poster"
        # BlogShow optional argument at the same time (avoids looping the user
        # list twice).
        is_poster = None
        limit_poster = self._choose_value('poster', req, kwargs, convert=None)
        email_map = {}
        for username, name, email in self.env.get_known_users():
            if email:
                email_map[username] = email
            if limit_poster != None:
                if username == limit_poster:
                    is_poster = username

        num_posts = self._choose_value('num_posts', req, kwargs, convert=int)
        if num_posts and default_times:
            poststart = sys.maxint
            postend = 0
        for blog_entry in blog:
            if blog_entry == macropage:
                continue
            try:
                page = WikiPage(self.env, version=1, name=blog_entry)
                version, post_time, author, comment, ipnr = page.get_history(
                ).next()
                # if we're limiting by poster, do so now so that the calendar
                # only shows the number of entries the specific poster made.
                if is_poster != None:
                    if is_poster != author:
                        continue

                self._add_to_tallies(tallies, post_time, blog_entry)
                page = WikiPage(self.env, name=blog_entry)
                version, modified, author, comment, ipnr = page.get_history(
                ).next()
            except:
                self.log.debug("Error loading wiki page %s" % blog_entry,
                               exc_info=True)
                continue
            if poststart >= post_time >= postend:
                time_format = self.env.config.get('blog', 'date_format') \
                              or '%x %X'
                timeStr = format_datetime(post_time, format=time_format)
                fulltext = page.text
                # remove comments in blog view:
                del_comments = re.compile('==== Comment.*\Z', re.DOTALL)
                fulltext = del_comments.sub('', fulltext)
                # remove the [[AddComment...]] tag, otherwise it would appeare
                # more than one and crew up the blog view:
                del_addcomment = re.compile('\[\[AddComment.*\Z', re.DOTALL)
                fulltext = del_addcomment.sub('', fulltext)
                # limit length of preview:
                post_size = self._choose_value('post_size', req, kwargs, int)
                if not post_size and (not isinstance(post_size, int)):
                    post_size = int(
                        self.env.config.get('blog', 'post_size', 1024))
                text = self._trim_page(fulltext, blog_entry, post_size)
                pagetags = [
                    x for x in tags.get_name_tags(blog_entry) if x not in tlist
                ]
                tagtags = []
                for i, t in enumerate(pagetags[:3]):
                    d = {
                        'link': t,
                        'name': t,
                        'last': i == (len(pagetags[:3]) - 1),
                    }
                    tagtags.append(d)
                    continue
                # extract title from text:
                match = _title_split_match(fulltext)
                if match:
                    title = match.group(1)
                    fulltext = match.group(2)
                else:
                    title = blog_entry
                html_text = wiki_to_html(fulltext, self.env, req)
                rss_text = Markup.escape(to_unicode(html_text))
                data = {
                    'name':
                    blog_entry,
                    'title':
                    title,
                    'href':
                    self.env.href.wiki(blog_entry),
                    'wiki_link':
                    wiki_to_oneliner(read_post % blog_entry, self.env),
                    'time':
                    timeStr,
                    'date':
                    http_date(post_time),
                    #                        'date'      : http_date(page.time),
                    'author':
                    author,
                    'wiki_text':
                    wiki_to_nofloat_html(text,
                                         self.env,
                                         req,
                                         macro_blacklist=macro_bl),
                    'rss_text':
                    rss_text,
                    'comment':
                    wiki_to_oneliner(comment, self.env),
                    'tags': {
                        'present': len(pagetags),
                        'tags': tagtags,
                        'more': len(pagetags) > 3 or 0,
                    },
                }
                if author:
                    # For RSS, author must be an email address
                    if author.find('@') != -1:
                        data['author.email'] = author
                    elif email_map.has_key(author):
                        data['author.email'] = email_map[author]

                if (modified != post_time) and mark_updated:
                    data['modified'] = 1
                    mod_str = format_datetime(modified, format=time_format)
                    data['mod_time'] = mod_str
                entries[post_time] = data
            continue
        tlist = entries.keys()
        tlist.sort()
        tlist.reverse()
        if num_posts and (num_posts <= len(tlist)):
            tlist = tlist[:num_posts]
        if tlist:
            entries[tlist[-1]]['last'] = 1
        req.hdf['blog.entries'] = [entries[x] for x in tlist]
        bloglink = self.env.config.get('blog', 'new_blog_link',
                                       'New Blog Post')
        req.hdf['blog.newblog'] = bloglink
        hidecal = self._choose_value('hidecal', req, kwargs)
        if not hidecal:
            self._generate_calendar(req, tallies)
        req.hdf['blog.hidecal'] = hidecal
        # Insert /wiki/BlogHeader into /blog.  If the page does not exist,
        # this'll be a no-op
        blog_header = WikiPage(self.env, name='BlogHeader').text
        req.hdf['blog.header'] = Mimeview(self.env).render(
            req, 'text/x-trac-wiki', blog_header)
예제 #11
0
    def _generate_blog(self, req, *args, **kwargs):
        """Extract the blog pages and fill the HDF.

        *args is a list of tags to use to limit the blog scope
        **kwargs are any aditional keyword arguments that are needed
        """
        tallies = {}
        tags = TagEngine(self.env).tagspace.wiki
        try:
            union = kwargs['union']
        except KeyError:
            union = False
        # Formatting
        read_post = "[wiki:%s Read Post]"
        entries = {}
        if not len(args):
            tlist = [self.env.config.get('blog', 'default_tag', 'blog')]
        else:
            tlist = args
        if union:
            blog = tags.get_tagged_names(tlist, operation='union')
        else:
            blog = tags.get_tagged_names(tlist, operation='intersection')
        macropage = req.args.get('page', None)

        poststart, postend, default_times = self._get_time_range(req, **kwargs)
        mark_updated = self._choose_value('mark_updated', req, kwargs, 
                                          convert=bool_val)
        if not mark_updated and (not isinstance(mark_updated, bool)):
            mark_updated = bool_val(self.env.config.get('blog', 'mark_updated',
                                                         True))
        macro_bl = self.env.config.get('blog', 'macro_blacklist', '').split(',')
        macro_bl = [name.strip() for name in macro_bl if name.strip()]
        macro_bl.append('BlogShow')

        # Get the email addresses of all known users and validate the "poster"
        # BlogShow optional argument at the same time (avoids looping the user
        # list twice).
        is_poster = None
        limit_poster = self._choose_value('poster', req, kwargs, convert=None)
        email_map = {}
        for username, name, email in self.env.get_known_users():
            if email:
                email_map[username] = email
            if limit_poster != None:
                if username == limit_poster:
                    is_poster = username

                       
        num_posts = self._choose_value('num_posts', req, kwargs, convert=int)
        if num_posts and default_times:
            poststart = sys.maxint
            postend = 0
        for blog_entry in blog:
            if blog_entry == macropage:
                continue
            try:
                page = WikiPage(self.env, version=1, name=blog_entry)
                version, post_time, author, comment, ipnr = page.get_history(
                                                            ).next()
                # if we're limiting by poster, do so now so that the calendar
                # only shows the number of entries the specific poster made.
                if is_poster != None:
                    if is_poster != author:
                        continue

                self._add_to_tallies(tallies, post_time, blog_entry)
                page = WikiPage(self.env, name=blog_entry)
                version, modified, author, comment, ipnr = page.get_history(
                                                           ).next()
            except:
                self.log.debug("Error loading wiki page %s" % blog_entry, exc_info=True)
                continue
            if poststart >= post_time >= postend:       
                time_format = self.env.config.get('blog', 'date_format') \
                              or '%x %X'
                timeStr = format_datetime(post_time, format=time_format) 
                fulltext = page.text
                # remove comments in blog view:
                del_comments = re.compile('==== Comment.*\Z', re.DOTALL)
                fulltext = del_comments.sub('', fulltext)
                # remove the [[AddComment...]] tag, otherwise it would appeare
                # more than one and crew up the blog view:
                del_addcomment  = re.compile('\[\[AddComment.*\Z', re.DOTALL)
                fulltext = del_addcomment.sub('', fulltext)
                # limit length of preview:
                post_size = self._choose_value('post_size', req, kwargs, int)
                if not post_size and (not isinstance(post_size, int)):
                    post_size = int(self.env.config.get('blog', 'post_size', 
                                    1024))
                text = self._trim_page(fulltext, blog_entry, post_size)
                pagetags = [x for x in tags.get_name_tags(blog_entry) if x not in tlist]
                tagtags = []
                for i, t in enumerate(pagetags[:3]):
                    d = { 'link' : t,
                          'name' : t,
                          'last' : i == (len(pagetags[:3]) - 1),
                        }
                    tagtags.append(d)
                    continue
                # extract title from text:
                match = _title_split_match(fulltext)
                if match:
                    title = match.group(1)
                    fulltext = match.group(2)
                else: 
                    title = blog_entry
                html_text = wiki_to_html(fulltext, self.env, req)
                rss_text = Markup.escape(to_unicode(html_text))
                data = {
                        'name'      : blog_entry,
                        'title'     : title,
                        'href'      : self.env.href.wiki(blog_entry),
                        'wiki_link' : wiki_to_oneliner(read_post % 
                                                       blog_entry,
                                                       self.env),
                        'time'      : timeStr,
                        'date'      : http_date(post_time),
#                        'date'      : http_date(page.time),
                        'author'    : author,
                        'wiki_text' : wiki_to_nofloat_html(text, self.env, req,
                                                   macro_blacklist=macro_bl),
                        'rss_text'  : rss_text,
                        'comment'   : wiki_to_oneliner(comment, self.env),
                        'tags'      : {
                                        'present' : len(pagetags),
                                        'tags'    : tagtags,
                                        'more'    : len(pagetags) > 3 or 0,
                                      },
                       }
                if author:
                    # For RSS, author must be an email address
                    if author.find('@') != -1:
                        data['author.email'] = author
                    elif email_map.has_key(author):
                        data['author.email'] = email_map[author]
                
                if (modified != post_time) and mark_updated:
                    data['modified'] = 1
                    mod_str = format_datetime(modified, format=time_format)
                    data['mod_time'] = mod_str
                entries[post_time] = data
            continue
        tlist = entries.keys()
        tlist.sort()
        tlist.reverse()
        if num_posts and (num_posts <= len(tlist)):
            tlist = tlist[:num_posts]
        if tlist:
            entries[tlist[-1]]['last'] = 1
        req.hdf['blog.entries'] = [entries[x] for x in tlist]
        bloglink = self.env.config.get('blog', 'new_blog_link', 'New Blog Post')
        req.hdf['blog.newblog'] = bloglink
        hidecal = self._choose_value('hidecal', req, kwargs)
        if not hidecal:
            self._generate_calendar(req, tallies)
        req.hdf['blog.hidecal'] = hidecal
        # Insert /wiki/BlogHeader into /blog.  If the page does not exist,
        # this'll be a no-op
        blog_header = WikiPage(self.env, name='BlogHeader').text
        req.hdf['blog.header'] = Mimeview(self.env).render(req,
                                                           'text/x-trac-wiki',
                                                           blog_header)