コード例 #1
0
ファイル: Feed.py プロジェクト: Kays/cia-vc
 def _render_photo(self, query_results, context, result):
     if query_results and query_results[0][0]:
         result.callback(tag('image')[
             tag('url')[ '/images/db/' + query_results[0][0] ],
             tag('title')[ place('title') ],
             tag('link')[ place('link') ],
             ])
     else:
         result.callback([])
コード例 #2
0
class InternalErrorPage(Twisted.Page):
    """An internal server error page, generated when we encounter an exception
       generating the intended page. This page should be fairly simple, so there's
       little risk in it causing an exception also.
       """
    def __init__(self, failure):
        self.failure = failure

    def preRender(self, context):
        request = context['request']
        request.setHeader('content-type', "text/html")
        request.setResponseCode(http.INTERNAL_SERVER_ERROR)

    def render_time(self, context):
        return TimeUtil.formatDateRFC822(time.time())

    def render_excType(self, context):
        return str(self.failure.value.__class__)

    def render_excValue(self, context):
        return str(self.failure.value)

    def render_traceback(self, context):
        return self.failure.getTraceback()

    def render_uri(self, context):
        return context['request'].uri

    document = tag(
        'html'
    )[tag('head')[tag('title')["Internal Server Error"], ],
      tag('body')
      [tag('h2')["Internal Server Error"],

       # Friendly message
       tag('p')
       ["Sorry, it looks like you just found a bug. If you would like to "
        "help us identify the problem, please email a copy of this page to the "
        "webmaster of this site along with a description of what happened. Thanks!"
        ],

       # Table of useful values
       tag('table', cellpadding=5)[
           tag('tr')[tag('td')[tag('b')['Current time:']],
                     tag('td')[place('time')], ],
           tag('tr')[tag('td')[tag('b')['Requested path:']],
                     tag('td')[place('uri')], ],
           tag('tr')[tag('td')[tag('b')['Exception type:']],
                     tag('td')[place('excType')], ],
           tag('tr')[tag('td')[tag('b')['Exception value:']],
                     tag('td')[place('excValue')], ], ],

       # Traceback
       tag('p')[tag('b')['Traceback:'], ],
       tag('p')[tag('pre')[place('traceback')], ], ], ]
コード例 #3
0
 def render_content(self, context):
     e = self.entries[context['args']['id']]
     return [
         tag('b')[ place('title') ],
         tag('br'),
         tag('i')[ e.feed.name ], " (", formatDate(e.date), ") ",
         tag('hr'),
         tag('p')[ e.content ],
         ]
コード例 #4
0
ファイル: Template.py プロジェクト: scanlime/cia-vc
 def _render(self, rows, result):
     """The backend for render(), called once our rows list is known"""
     if rows:
         result.callback(
             subcontext(owner=self)[
                 tag('span', _class="section")[place("title")],
                 tag('div', _class="section")[
                     tag('div', _class="sectionTop")[" "],
                     [tag('div', _class="row")[r] for r in rows], ], ])
     else:
         result.callback([])
コード例 #5
0
ファイル: Feed.py プロジェクト: Kays/cia-vc
    def render_channel(self, context, messages):
        """Generate our <channel> element and all of its children"""
        # Make a table of contents for the messages
        toc = []
        for id, content in messages:
            url = Link.MessageLink(self.target, id).getURL(context)
            toc.append(tag('rdf:li', resource=url))

        targetUrl = Link.StatsLink(self.target).getURL(context)
        return tag('channel', **{
                   'rdf:about': targetUrl,
               })[
                   tag('title')[ place('title') ],
                   tag('link')[ targetUrl ],
                   tag('description')[ place('description') ],
                   place('photo'),

                   tag('items')[
                       tag('rdf:Seq')[ toc ],
                   ],
               ]
コード例 #6
0
ファイル: Template.py プロジェクト: Justasic/cia-vc
 def _render(self, rows, result):
     """The backend for render(), called once our rows list is known"""
     if rows:
         result.callback(subcontext(owner=self)[
             tag('span', _class="section")[ place("title") ],
             tag('div', _class="section")[
                 tag('div', _class="sectionTop")[" "],
                 [tag('div', _class="row")[r] for r in rows],
             ],
         ])
     else:
         result.callback([])
コード例 #7
0
class Hello(Twisted.Page):
    isLeaf = 1
    document = tag('html')[tag('head')[tag('title')["Hi"], ],
                           tag('body')[tag('h3')["Hello World!"],
                                       tag('p')[place("dataTable")]], ]

    def render_dataTable(self, context):
        data = []

        for id in BZFlag.Players.keys():
            player = BZFlag.Players[id]
            data.append([
                id, player.callsign, player.wins - player.losses, player.team
            ])

        return MyTable(data, [
            Nouvelle.IndexedColumn('id', 0),
            Nouvelle.IndexedColumn('callsign', 1),
            Nouvelle.IndexedColumn('score', 2),
            Nouvelle.IndexedColumn('team', 3),
        ],
                       id='players')
コード例 #8
0
ファイル: MessageViewer.py プロジェクト: scanlime/cia-vc
class MessagePage(Template.Page):
    """A page that views one message from the stats database"""
    mainTitle = 'Archived Message'

    def __init__(self, statsPage, id):
        self.statsPage = statsPage
        self.id = id
        Template.Page.__init__(self)
        self.putChild('xml', UnformattedMessagePage(self.statsPage.target, self.id))

    def parent(self):
        return self.statsPage

    def preRender(self, context):
        # Load the message once, so multiple components can share it
        xml = self.statsPage.target.messages.getMessageById(self.id)
        if xml:
            self.message = Message.Message(xml)
        else:
            self.message = None

        context['component'] = self.statsPage.component

    def render_subTitle(self, context):
        return ["for ",
                self.statsPage.render_mainTitle(context)]

    def render_message(self, context):
        if not self.message:
            context['request'].setResponseCode(404)
	    return self.notFoundMessage

        # Try to format it using several media, in order of decreasing preference.
        # The 'xhtml-long' formatter lets messages define a special formatter to
        # use when an entire page is devoted to their one message, possibly showing
        # it in greater detail. 'xhtml' is the formatter most messages should have.
        # 'plaintext' is a nice fallback.
        #
        # This default list of media to try can be overridden with an argument in our URL.

        if 'media' in context['args']:
            mediaList = context['args']['media'][0].split()
        else:
            mediaList = ('xhtml-long', 'xhtml', 'plaintext')

        for medium in mediaList:
            try:
                formatted = Formatters.getFactory().findMedium(
                    medium, self.message).formatMessage(self.message)
            except Message.NoFormatterError:
                continue
            return formatted

        # Still no luck? Display a warning message and a pretty-printed XML tree
        return [
            tag('h1')[ "No formatter available" ],
            XML.htmlPrettyPrint(self.message.xml),
            ]

    def render_leftColumn(self, context):
        return [
            EnvelopeSection(self.statsPage.target, self.message),
            LinksSection(self.statsPage.target, self.id),
            Info.Clock(),
            ]

    notFoundMessage = [
        tag('h1')[ "Not Found" ],
        tag('p')[
            "This message was not found in our database. The number could be "
            "incorrect, or the message may be old enough that it was deleted "
            "from the database. Each stats target archives a fixed number of messages, "
            "so you might be able to find another copy of it on a different stats "
            "target with less traffic."
        ]
    ]

    mainColumn = [
        Template.pageBody[ place('message') ],
        ]
コード例 #9
0
ファイル: Feed.py プロジェクト: Kays/cia-vc
 def render_form(self, context):
     return tag('form',
                action = Link.RSSLink(self.statsPage.target).getURL(context),
                )[place('formContent')]
コード例 #10
0
ファイル: Template.py プロジェクト: scanlime/cia-vc
class Page(Nouvelle.Twisted.Page):
    """A template for pages using our CSS- all pages have a heading with
       title, subtitle, and site name. The content of each page is in
       columns holding sections, while each page shares certain navigation
       features- section tabs at the top, and a 'breadcrumbs' display
       linking to and showing a page's parent pages.
       """
    siteName = "CIA.vc"
    mainTitle = None
    subTitle = []
    leftColumn = []
    mainColumn = []
    extraHeaders = []

    # Placeholders for site-specific customization
    site_belowLeftColumn = []
    site_bottomOfFooter = []

    titleElements = [
        tag('div', _class="mainTitle")[place("mainTitle")],
        tag('div', _class="subTitle")[place("subTitle")],
    ]

    logoElements = [
        tag('a', _class="sitename",
            href="/")[tag('img',
                          src='/media/img/nameplate-24.png',
                          width=87,
                          height=24,
                          alt='CIA.vc'), ],
    ]

    document = [
        xml('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" '
            '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n'),
        tag('html', xmlns="http://www.w3.org/1999/xhtml")
        [tag('head')
         [tag('title')[place("pageTitle")],
          place('baseTag'),
          xml('<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />'
              ),
          tag('link',
              rel='stylesheet',
              href='/media/css/old-site.css',
              type='text/css'),
          tag('link',
              rel='shortcut icon',
              href='/favicon.ico',
              type='image/png'),
          tag('script', type='text/javascript', src='/media/js/base.js')[" "],
          place('extraHeaders'), ],
         tag('body')
         [tag('div', _class="heading"
              )[tag('div', _class="topRight")[
                  tag('input', type='text', id='search'),
                  place("tabs"),
                  place('logoElements'), ],
                tag('div', _class="topLeft")[
                    place('titleElements'), ],
                tag('div', _class="tabBar")[place("breadcrumbs")], ],

          # The page body. We really shouldn't still be using a table for this...
          tag('table', _class="columns")[tag('tr')[
              tag('td', _class="left")[place("templateLeftColumn"), ],
              tag('td', _class="main")[place("mainColumn")], ]],
          tag('div', _class="footer")[

              # Legal goop
              tag('p', _class='smallprint')
              [xml("The CIA.vc server is Copyright &copy; 2003-2007 "),
               EmailLink('mailto:[email protected]')["Micah Dowty"],
               ", and released under the ",
               tag('a', _href='/doc/COPYING')["GNU GPL"], ".",
               tag('br'
                   ),
               "All hosted messages and metadata are owned by their respective authors.",
               ],

              # More optional text
              place("site_bottomOfFooter"), ],
          xml('<script type="text/javascript">'
              'CIASearch.init("/api/search/", "search", "Search CIA.vc");'
              '</script>'), ], ],
    ]

    def render_pageTitle(self, context):
        # Wait for the title and site name to resolve into strings so we can mess with them a bit more
        result = defer.Deferred()
        defer.gatherResults([
            defer.maybeDeferred(self.render_mainTitle, context),
            defer.maybeDeferred(self.render_siteName, context),
        ]).addCallback(self._render_pageTitle, context,
                       result).addErrback(result.errback)
        return result

    def _render_pageTitle(self, titleAndSite, context, result):
        # Now that the title and site name have fully resolved, we can apply some heuristics...
        title, siteName = titleAndSite

        if title is None:
            result.callback(siteName)
            return

        if type(title) in types.StringTypes and type(
                siteName) in types.StringTypes:
            # The title and site are plain strings. If it starts with or ends with the site name,
            # just use it as-is to avoid being overly redundant.
            if title == siteName or title.startswith(
                    siteName + " ") or title.endswith(" " + siteName):
                result.callback(title)
                return

        # Otherwise, stick the title and site name together
        result.callback([title, ' - ', siteName])

    def render_templateLeftColumn(self, context):
        """A sneaky little rendering function that runs render_leftColumn,
           but then sticks in the site_* modifiers where possible. Note that
           this won't work if render_leftColumn returns a Deferred, but
           nothing in the CIA server does this yet.
           """
        return self.render_leftColumn(context) + self.site_belowLeftColumn

    def render_siteName(self, context):
        return self.siteName

    def render_mainTitle(self, context):
        return self.mainTitle

    def render_subTitle(self, context):
        return self.subTitle

    def render_leftColumn(self, context):
        return self.leftColumn

    def render_mainColumn(self, context):
        return self.mainColumn

    def render_breadcrumbs(self, context):
        places = [self.render_mainTitle(context)]
        node = self.parent()
        # If we don't at least have a parent node, breadcrumbs
        # are going to be pretty useless. Just stick in a
        # non-breaking space as a placeholder.
        if not node:
            return xml("&nbsp;")
        while node:
            places.insert(0, breadcrumbSeparator)
            places.insert(0, node.render_link(context))
            node = node.parent()
        return places

    def render_baseTag(self, context):
        """Return an HTML <base> tag pointing at this page's original URL.
           This keeps the page from breaking if it's saved to disk or copied elsewhere.
           """
        return tag('base', href=context['request'].prePathURL())

    def render_link(self, context):
        """Return a serializable object that should be used to link to this page.
           By default, this returns a plain link with the page's title, pointing
           to the page's URL.
           """
        return tag('a',
                   href=self.getURL(context))[self.render_mainTitle(context)]

    def parent(self):
        """Pages must implement this to return their parent page.
           This is used for the default implementation of breadcrumbs.
           """
        pass

    def render_tabs(self, context):
        """The page's tabs show all named components"""
        tabs = []
        for component in context['request'].site.components:
            if component.name:
                tabs.append(
                    tag('li')[xml('&raquo; '),
                              tag('a', href=component.url)[component.name], ])

        return tag('ul', _class='heading')[tabs]

    def getURL(self, context):
        """Retrieve a URL suitable for linking to this page."""
        pass
コード例 #11
0
class Counters(Template.Section):
    """A Section displaying the counters from a StatsTarget"""
    title = "event counters"

    rows = [
        [
            'The last message was received ',
            Template.value[place('value', 'forever', 'lastEventTime',
                                 'relativeDate')],
            ' ago at ',
            Template.value[place('value', 'forever', 'lastEventTime', 'date')],
        ],
        [
            Template.value[place('value', 'today', 'eventCount')],
            ' messages so far today, ',
            Template.value[place('value', 'yesterday', 'eventCount')],
            ' messages yesterday',
        ],
        [
            Template.value[place('value', 'thisWeek', 'eventCount')],
            ' messages so far this week, ',
            Template.value[place('value', 'lastWeek', 'eventCount')],
            ' messages last week',
        ],
        [
            Template.value[place('value', 'thisMonth', 'eventCount')],
            ' messages so far this month, ',
            Template.value[place('value', 'lastMonth', 'eventCount')],
            ' messages last month',
        ],
        [
            Template.value[place('value', 'forever', 'eventCount')],
            ' messages since the first one, ',
            Template.value[place('value', 'forever', 'firstEventTime',
                                 'relativeDate')],
            ' ago',
            place('averagePeriod', 'forever'),
        ],
    ]

    def __init__(self, target):
        self.counters = target.counters

    def render_rows(self, context):
        """If this target has received at least one event, render the rows normally..
           otherwise, hide this section completely.
           """
        result = defer.Deferred()
        self.counters.getCounter('forever').addCallback(
            self._render_rows, result).addErrback(result.errback)
        return result

    def _render_rows(self, foreverCounter, result):
        if foreverCounter and foreverCounter['eventCount'] > 0:
            result.callback(self.rows)
        else:
            result.callback([])

    def render_value(self, context, counterName, valueName, filter=None):
        """Fetch a counter value, rendering its value optionally via
           a filter function. 'filter' is a string which will be used to
           look up a filter_* method from this class.
           """
        result = defer.Deferred()
        self.counters.getCounter(counterName).addCallback(
            self._render_value, valueName, filter,
            result).addErrback(result.errback)
        return result

    def _render_value(self, counter, valueName, filter, result):
        if counter:
            value = counter.get(valueName, 0)
        else:
            value = 0
        if filter:
            value = getattr(self, 'filter_' + filter)(value)
        result.callback(value)

    def filter_date(self, value):
        return TimeUtil.formatDate(value)

    def filter_relativeDate(self, value):
        return TimeUtil.formatDuration(time.time() - value)

    def render_averagePeriod(self, context, counterName):
        result = defer.Deferred()
        self.counters.getCounter(counterName).addCallback(
            self._render_averagePeriod, result).addErrback(result.errback)
        return result

    def _render_averagePeriod(self, counter, result):
        if not counter:
            result.callback('')
            return
        events = counter.get('eventCount', 0)
        first = counter.get('firstEventTime')
        if events < 2 or not first:
            result.callback('')
            return
        result.callback([
            ', for an average of ',
            Template.value[TimeUtil.formatDuration(
                (time.time() - first) / events)],
            ' between messages',
        ])