示例#1
0
 def _link_crash(self, req, uuid, show_uuid=False, sysinfo=False):
     ret = None
     try:
         crash = CrashDump(env=self.env, uuid=uuid)
         if sysinfo:
             href = req.href('crash', crash.uuid, 'sysinfo_report')
             title = 'CrashId#%i (%s)' % (crash.id, crash.uuid)
         else:
             if show_uuid:
                 title = str(crash.uuid)
             else:
                 title = 'CrashId#%i (%s)' % (crash.id, crash.uuid)
             href = req.href('crash', crash.uuid)
         if show_uuid:
             ret = \
                 tag.a(
                     str(crash.uuid),
                     class_=crash['status'],
                     href=href,
                     title=title,
                     style="white-space: nowrap"
                 )
         else:
             ret = \
                 tag.a(
                     'CrashId#%i' % crash.id,
                     class_=crash['status'],
                     href=href,
                     title=crash.uuid
                 )
     except ResourceNotFound:
         pass
     return ret
示例#2
0
    def filter_stream(self, req, method, filename, stream, data):
        project_id = self.env.config.get('por-dashboard', 'project-id')
        if project_id:
            project = DBSession().query(Project).get(project_id)
            # XXX se project is None, 404

            stream |= Transformer(".//div[@id='trac-before-subnav']").prepend(tag.ul(
                    tag.li(tag.a("Home", href="/")),
                    tag.li(
                            tag.span(" / ", class_="divider"),
                            tag.a(project.customer.name, href="/admin/Customer/%s" % project.customer.id)
                        ),
                    tag.li(
                            tag.span(" / ", class_="divider"),
                            tag.a(project.name, href="/admin/Project/%s" % project.id)
                        ),
                    tag.li(
                            tag.span(" / ", class_="divider"),
                            tag.a('Trac', href="/trac/%s" % project.id),
                            class_='active'
                        ),
                    class_="breadcrumb noprint",
                ))

        return stream
示例#3
0
    def render_timeline_event(self, context, field, event):
        """Display the title of the event in the given context.

        Full description here http://trac.edgewall.org/browser/trunk/trac/timeline/api.py
        """
        if field == 'url':
            return event[3]['url']
        elif field == 'title':
            return "Build %s #%s was %s" % (event[3]['builder'], event[3]['num'], event[0])
        elif field == 'description':
            data = event[3]
            msg = tag.span()
            if data['source'] and data["rev"]:
                rev_msg = tag.div("rev: ",
                    tag.a(data['rev'][:7], href=context.href("/browser/%s" % data['source'], rev=data['rev'])),
                    " ",    
                    tag.a(tag.img(src=context.href("/chrome/common/changeset.png")),
                          href=context.href("/changeset/%s/%s" % (data['rev'], data['source'])))
                    )
                msg.append(rev_msg)

            if 'error' in event[3] and  event[3]['error']:
                error_msg = tag.div(event[3]['error'], " ")
                if 'error_log' in event[3] and event[3]['error_log']:
                    error_msg.append(tag.a("Log", href=event[3]['error_log']))
                msg.append(error_msg)
            return msg
示例#4
0
def _ticket_links(env, formatter, t, a_class=""):
    """Build links to tickets."""
    tkt_id = str(t.get("id"))
    status = t.get("status")
    summary = to_unicode(t.get("summary"))
    owner = to_unicode(t.get("owner"))
    description = to_unicode(t.get("description"))
    url = t.get("href")

    if status == "closed":
        a_class = a_class + "closed"
    else:
        a_class = a_class + "open"

    # Reduce content for tooltips.
    markup = format_to_html(env, formatter.context, description)
    extractor = TextExtractor()
    extractor.feed(markup)
    tip = tag.span(shorten_line(extractor.getvalue()))

    ticket = tag.a("#" + tkt_id, href=url)
    ticket(tip, class_="tip", target="_blank")
    ticket = tag.div(ticket, class_=a_class, align="left")
    # Fix stripping of regular leading space in IE.
    blank = " "
    ticket(Markup(blank), summary, " (", owner, ")")

    summary = tag(summary, " (", owner, ")")
    ticket_short = tag.span(tag.a("#" + tkt_id, href=url, target="_blank", title_=summary), class_=a_class)
    return ticket, ticket_short
示例#5
0
 def _format_link(self, formatter, ns, pagename, label, ignore_missing,
                  original_label=None):
     pagename, query, fragment = formatter.split_link(pagename)
     version = None
     if '@' in pagename:
         pagename, version = pagename.split('@', 1)
     if version and query:
         query = '&' + query[1:]
     pagename = pagename.strip('/') or 'WikiStart'
     if 'WIKI_VIEW' in formatter.perm('wiki', pagename, version):
         href = formatter.href.wiki(pagename, version=version) + query \
                + fragment
         if self.has_page(pagename):
             return tag.a(label, href=href, class_='wiki')
         else:
             if ignore_missing:
                 return original_label or label
             if 'WIKI_CREATE' in formatter.perm('wiki', pagename, version):
                 return tag.a(label + '?', class_='missing wiki',
                              href=href, rel='nofollow')
             else:
                 return tag.a(label + '?', class_='missing wiki')
     elif ignore_missing and not self.has_page(pagename):
         return label
     else:
         return tag.a(label, class_='forbidden wiki',
                      title=_("no permission to view this wiki page"))
示例#6
0
    def render_bookmarker(self, req):
        if 'action' in req.args and \
                req.args['action'] in self.nonbookmarkable_actions:
            return

        resource = self._get_resource_uri(req)
        bookmark = self.get_bookmark(req, resource)

        if bookmark:
            class_ = 'bookmark_on'
            title = 'Delete Bookmark'
            href = req.href.bookmark('delete', resource)
        else:
            class_ = 'bookmark_off'
            title = 'Bookmark this page'
            href = req.href.bookmark('add', resource)
        anchor = tag.a(u'\u200b', id='bookmark_this', class_=class_,
                       title=title, href=href, data_list=req.href.bookmark())
        req.chrome.setdefault('ctxtnav', []).insert(0, anchor)

        add_script(req, 'bookmark/js/tracbookmark.js')
        add_stylesheet(req, 'bookmark/css/tracbookmark.css')

        menu = self._get_bookmarks_menu(req)
        item = tag.span(tag.a('Bookmarks', href=req.href.bookmark()),
                        menu, id='bookmark_menu')
        add_ctxtnav(req, item)
示例#7
0
    def expand_macro(self, formatter, name, content):
        env = formatter.env
        req = formatter.req
        if not 'VOTE_VIEW' in req.perm:
            return
        # Simplify function calls.
        format_author = partial(Chrome(self.env).format_author, req)
        if not content:
            args = []
            compact = None
            kw = {}
            top = 5
        else:
            args, kw = parse_args(content)
            compact = 'compact' in args and True
            top = as_int(kw.get('top'), 5, min=0)

        if name == 'LastVoted':
            lst = tag.ul()
            for i in self.get_votes(req, top=top):
                resource = Resource(i[0], i[1])
                # Anotate who and when.
                voted = ('by %s at %s'
                         % (format_author(i[3]),
                            format_datetime(to_datetime(i[4]))))
                lst(tag.li(tag.a(
                    get_resource_description(env, resource, compact and
                                             'compact' or 'default'),
                    href=get_resource_url(env, resource, formatter.href),
                    title=(compact and '%+i %s' % (i[2], voted) or None)),
                    (not compact and Markup(' %s %s' % (tag.b('%+i' % i[2]),
                                                        voted)) or '')))
            return lst

        elif name == 'TopVoted':
            realm = kw.get('realm')
            lst = tag.ul()
            for i in self.get_top_voted(req, realm=realm, top=top):
                if 'up-only' in args and i[2] < 1:
                    break
                resource = Resource(i[0], i[1])
                lst(tag.li(tag.a(
                    get_resource_description(env, resource, compact and
                                             'compact' or 'default'),
                    href=get_resource_url(env, resource, formatter.href),
                    title=(compact and '%+i' % i[2] or None)),
                    (not compact and ' (%+i)' % i[2] or '')))
            return lst

        elif name == 'VoteList':
            lst = tag.ul()
            resource = resource_from_path(env, req.path_info)
            for i in self.get_votes(req, resource, top=top):
                vote = ('at %s' % format_datetime(to_datetime(i[4])))
                lst(tag.li(
                    compact and format_author(i[3]) or
                    Markup(u'%s by %s %s' % (tag.b('%+i' % i[2]),
                                             tag(format_author(i[3])), vote)),
                    title=(compact and '%+i %s' % (i[2], vote) or None)))
            return lst
    def get_content(self, req, entry, data):
        
        # Make sure that repository is a Subversion repository, since
        # we're relying for now on Subversion to provide WebDAV
        # support.
        if not is_subversion_repository(data.get('repos')):
            return None
        # don't show up in the menu if the user is browsing a non-HEAD revision
        if data.get('stickyrev'):
            return None

        reponame = data['reponame'] or ''
        ext = os.path.splitext(entry.name)[1][1:]

        if not entry.isdir and ext in self.office_file_extensions:

            path = self.get_subversion_path(entry)
            href = self.get_subversion_href(data, path)

            if re.search('(MSIE |Trident/)',
                         req.environ.get('HTTP_USER_AGENT', '')):
                # for IE, we'll use ActiveX as this may work with older Office installations
                return tag.a(tag.i(class_="fa fa-edit"),
                             ' %s with Microsoft Office' % self._verb,
                             href=href,
                             class_=self._link_class)
            else:
                # otherwise, let's try https://msdn.microsoft.com/en-us/library/office/dn906146.aspx
                # which is Office 2010 SP2 and above
                application = self.office_file_extensions[ext]
                return tag.a(tag.i(class_="fa fa-edit"),
                             ' %s with Microsoft %s' % (self._verb, application.title()),
                             href="ms-%s:%s|u|%s" % (application, self._href_mode, href))
示例#9
0
 def get_navigation_items(self, req):
     if req.authname and req.authname != 'anonymous':
         yield ('metanav', 'openidlogin', 'logged in as %s' % (req.session.get('name') or req.authname))
         yield ('metanav', 'openidlogout',
                tag.a('Logout', href=req.href.openidlogout()))
     else:
         yield ('metanav', 'openidlogin', tag.a(('OpenID Login'), href=req.href.openidlogin()))
示例#10
0
 def nav_pager(d):
     return tag.span(
         tag.a(u'\u25c4', href=nav_href(d - timedelta(days=1))),
         tag.a(_("Current month"),
               href=nav_href(get_today(req.tz))),
         tag.a(u'\u25ba', href=nav_href(d + timedelta(days=31))),
         class_='ticketcalendar-pager')
示例#11
0
    def prevnext_ctxnav(self, req, prev_label, next_label, up_label=None):
        links = req.chrome["links"]
        prev_link = next_link = None

        if not any(lnk in links for lnk in ("prev", "up", "next")):  # Short circuit
            return

        if "prev" in links:
            prev = links["prev"][0]
            prev_link = tag.a(prev_label, href=prev["href"], title=prev["title"], class_="prev")

        add_ctxtnav(
            req, tag.span("", prev_link or prev_label, id="leftarrow", class_=not prev_link and "missing" or None)
        )

        if up_label and "up" in links:
            up = links["up"][0]
            add_ctxtnav(req, tag.a(up_label, href=up["href"], title=up["title"]))

        if "next" in links:
            next_ = links["next"][0]
            next_link = tag.a(next_label, href=next_["href"], title=next_["title"], class_="next")

        add_ctxtnav(
            req, tag.span(next_link or next_label, "", id="rightarrow", class_=not next_link and "missing" or None)
        )
示例#12
0
  def expand_macro(self,formatter,name,content):
    citelist = getattr(formatter, CITELIST,[])
    columns = ['itemTypeID','firstCreator','year', 'publicationTitle','volume','issue','pages','title','url']
    model = ZoteroModelProvider(self.env)
    item_ids = model.get_items_ids_by_keys( citelist )
    item_data = model.get_item_columns_by_iids(item_ids,columns)
    refs = []

    for itemID, itemTypeID, firstCreator, year, publicationTitle, volume, issue, pages, title, url in item_data:
        prefix = ''
        if firstCreator and firstCreator != 'None':
            prefix += firstCreator
        if year and year != 'None':
            prefix += ' ' + year + '. '
        titlehref = ''
        if title and title != 'None':
            titlehref = tag.a(title, href = formatter.req.href.zotero('item/' + str(itemID)))
        suffix = ''
        if publicationTitle and publicationTitle != 'None':
            suffix += '. ' + publicationTitle
        if volume and volume != 'None':
            suffix += ', ' + str(volume)
        if pages and pages != 'None':
            suffix += ': ' + pages + '.'
        ref = []
        if url and url != 'None':
            ref = tag.li( tag.span( prefix ), tag.span(titlehref), tag.span(suffix),
                    tag.br(),tag.span(tag.a(url, href=url ),style = 'font-size:x-small;') )
        else: 
            ref = tag.li( tag.span( prefix ), tag.span(titlehref), tag.span(suffix) )
    
        refs.append(ref)

    return tag.div(tag.ol(refs),id='References')
示例#13
0
    def post_process_request(self, req, template, data, content_type):
        if 'BLOG_VIEW' not in req.perm:
            return (template, data, content_type)

        if '_blog_watch_message_' in req.session:
            add_notice(req, req.session['_blog_watch_message_'])
            del req.session['_blog_watch_message_']

        if req.authname == "anonymous":
            return (template, data, content_type)

        # FullBlogPlugin sets the blog_path arg in pre_process_request
        name = req.args.get('blog_path')
        if not name:
            return (template, data, content_type)

        klass = self.__class__.__name__

        attrs = SubscriptionAttribute.find_by_sid_class_and_target(
            self.env, req.session.sid, req.session.authenticated, klass, name)
        if attrs:
            add_ctxtnav(req, tag.a(_('Unwatch This'),
                href=req.href.blog_watch(name)))
        else:
            add_ctxtnav(req, tag.a(_('Watch This'),
                href=req.href.blog_watch(name)))

        return (template, data, content_type)
示例#14
0
 def render_voter(self, req):
     resource = self.normalise_resource(req.path_info)
     vote = self.get_vote(req, resource)
     up = tag.img(src=req.href.chrome('vote/' + self.image_map[vote][0]), 
                  alt='Up-vote')
     down = tag.img(src=req.href.chrome('vote/' + self.image_map[vote][1]), 
                  alt='Down-vote')         
     if 'VOTE_MODIFY' in req.perm and get_reporter_id(req) != 'anonymous':
         down = tag.a(down, id='downvote',
                      href=req.href.vote('down', resource),
                      title='Down-vote')
         up = tag.a(up, id='upvote', href=req.href.vote('up', resource),
                    title='Up-vote')
         add_script(req, 'vote/js/tracvote.js')
         shown = req.session.get('shown_vote_message')
         if not shown:
             add_notice(req, 'You can vote for resources on this Trac '
                        'install by clicking the up-vote/down-vote arrows '
                        'in the context navigation bar.')
             req.session['shown_vote_message'] = '1'
     body, title = self.format_votes(resource)
     votes = tag.span(body, id='votes')
     add_stylesheet(req, 'vote/css/tracvote.css')
     elm = tag.span(up, votes, down, id='vote', title=title)
     req.chrome.setdefault('ctxtnav', []).insert(0, elm)
    def filter_stream(self, req, method, filename, stream, data):
        """
        filter project fields to have it 
        correctly display on the ticket.html
        """

        if filename == 'ticket.html':
            project = [ field for field in data['fields'] if field['name'] == 'project' ][0] 
            ticket_id = data['ticket'].id
            if ticket_id is None: # new ticket
                field = 'none'
            else:
                proj = self.getProjectByTicketId(ticket_id)
                if proj == 'none':
                     field = 'none'
                else: 
                     field = tag.a(proj['name'], href=req.href('c_projects', proj['id']), title="Project for ticket %s" % data['ticket'].id)
            project['rendered'] = field
            stream |= Transformer("//input[@id='field-project']").replace(field)

            customer = [ c_field for c_field in data['fields'] if c_field['name'] == 'customer' ][0]
            if ticket_id is None: # new ticket
                c_field = 'none'
            else:
                if proj != 'none':
                    cust = self.getCustomerByProjectId(proj['id'])
                    c_field = tag.a(cust['name'], href=req.href('cust','projects', cust['id']), title="Customer for ticket %s" % data['ticket'].id)
                else: 
                    c_field = 'none'
            customer['rendered'] = c_field

            stream |= Transformer("//input[@id='field-customer']").replace(c_field)

        return stream
示例#16
0
文件: chrome.py 项目: exocad/exotrac
    def test_attributes_preserved_in_navigation_item(self):
        class TestNavigationContributor1(Component):
            implements(INavigationContributor)
            def get_active_navigation_item(self, req):
                return None
            def get_navigation_items(self, req):
                yield 'mainnav', 'test1', \
                      tag.a('Test 1', href='test1', target='blank')
        class TestNavigationContributor2(Component):
            implements(INavigationContributor)
            def get_active_navigation_item(self, req):
                return None
            def get_navigation_items(self, req):
                yield 'mainnav', 'test2', \
                      tag.a('Test 2', href='test2', target='blank')
        req = Request(abs_href=Href('http://example.org/trac.cgi'),
                      href=Href('/trac.cgi'), base_path='/trac.cgi',
                      path_info='/',
                      add_redirect_listener=lambda listener: None)
        self.env.config.set('mainnav', 'test1.label', 'Test One')
        self.env.config.set('mainnav', 'test2.label', 'Test Two')
        self.env.config.set('mainnav', 'test2.href', 'testtwo')

        chrome = Chrome(self.env)
        items = chrome.prepare_request(req)['nav']['mainnav']

        item = self._get_navigation_item(items, 'test1')
        self.assertEqual(str(tag.a('Test One', href='test1', target='blank')),
                         str(item['label']))
        item = self._get_navigation_item(items, 'test2')
        self.assertEqual(str(tag.a('Test Two', href='testtwo',
                                   target='blank')),
                         str(item['label']))
示例#17
0
 def _format_link(self, formatter, ns, target, label, match=None):
     try:
         paste = Paste(self.env, id=target)
         return tag.a(label, title=paste.title,
                      href=formatter.href.pastebin(paste.id), class_='paste')
     except Exception, e:
         return tag.a(label, class_='missing paste')
示例#18
0
文件: api.py 项目: exocad/exotrac
    def _format_exomine_link(self, formatter, ns, target, label):
        # Wiki support for short exomine links:
        #    exomine:3234    -> ​https://secure.exocad.com/exomine/issues/3234
        #    exomine:3234:12 -> ​https://secure.exocad.com/exomine/issues/3234#note-12
        def get_url(ticket, comment=None):
            base_exomine_url = ""
            href = "https://secure.exocad.com/exomine/issues/{0}".format(ticket)
            if comment is not None:
                href += "#note-{0}".format(comment)
            return href

        try:
            if ":" in target:
                arr = target.split(":")
                if len(arr) == 2:
                    href = get_url(arr[0], arr[1])
                    title = _("Comment %(cnum)s for exomine ticket #%(id)s", cnum=arr[1], id=arr[0])
                    return tag.a(tag.span(class_="icon") + label, href=href, title=title, class_="ext-link")
            else:
                href = get_url(target)
                title = _("exomine ticket #%(id)s", id=target)
                return tag.a(tag.span(class_="icon") + label, href=href, title=title, class_="ext-link")
        except ValueError:
            pass
        return tag.a(label, class_="unable to parse")  # Todo: Add this class
示例#19
0
    def _format_comment_link(self, formatter, ns, target, label):
        resource = None
        if ':' in target:
            elts = target.split(':')
            if len(elts) == 3:
                cnum, realm, id = elts
                if cnum != 'description' and cnum and not cnum[0].isdigit():
                    realm, id, cnum = elts # support old comment: style
                resource = formatter.resource(realm, id)
        else:
            resource = formatter.resource
            cnum = target

        if resource and resource.realm == 'ticket':
            id = as_int(resource.id, None)
            if id is not None:
                href = "%s#comment:%s" % (formatter.href.ticket(resource.id),
                                          cnum)
                title = _("Comment %(cnum)s for Ticket #%(id)s", cnum=cnum,
                          id=resource.id)
                if 'TICKET_VIEW' in formatter.perm(resource):
                    for status, in self.env.db_query(
                            "SELECT status FROM ticket WHERE id=%s", (id,)):
                        return tag.a(label, href=href, title=title,
                                     class_=status)
                return tag.a(label, href=href, title=title)
        return label
示例#20
0
    def expand_macro(self, formatter, name, content):
        attachment_type = ""
        if content:
            argv = [arg.strip() for arg in content.split(',')]
            if len(argv) > 0:
                attachment_type = argv[0]

        db = self.env.get_db_cnx()
        if db == None:
           return "No DB connection"
        
        attachmentFormattedList=""

        cursor = db.cursor()

        if attachment_type == None or attachment_type == "":
            cursor.execute("SELECT type,id,filename,size,time,"
                           "description,author,ipnr FROM attachment")
        else:
            cursor.execute("SELECT type,id,filename,size,time,"
                           "description,author,ipnr FROM attachment "
                           "WHERE type=%s", (attachment_type, ))
        
        formatters={"wiki": formatter.href.wiki, "ticket": formatter.href.ticket}
        types={"wiki": "", "ticket": "ticket "}

        return tag.ul(
                      [tag.li(
                          tag.a(filename, href=formatter.href.attachment(type + "/" + id + "/" + filename)), 
                          " (", tag.span(pretty_size(size), title=size), ") - added by ",
                          tag.em(author), " to ",
                          tag.a(types[type] + " " + id, href=formatters[type](id)), " ")
                    for type,id,filename,size,time,description,author,ipnr in cursor if self._has_perm(type, id, filename, formatter.context)])

        return attachmentFormattedList
示例#21
0
 def _format_link(self, formatter, ns, target, label, fullmatch=None):
     intertrac = formatter.shorthand_intertrac_helper(ns, target, label,
                                                      fullmatch)
     if intertrac:
         return intertrac
     try:
         link, params, fragment = formatter.split_link(target)
         r = Ranges(link)
         if len(r) == 1:
             num = r.a
             ticket = formatter.resource('ticket', num)
             from trac.ticket.model import Ticket
             if Ticket.id_is_valid(num) and \
                     'TICKET_VIEW' in formatter.perm(ticket):
                 # TODO: watch #6436 and when done, attempt to retrieve 
                 #       ticket directly (try: Ticket(self.env, num) ...)
                 cursor = formatter.db.cursor() 
                 cursor.execute("SELECT type,summary,status,resolution "
                                "FROM ticket WHERE id=%s", (str(num),)) 
                 for type, summary, status, resolution in cursor:
                     title = self.format_summary(summary, status,
                                                 resolution, type)
                     href = formatter.href.ticket(num) + params + fragment
                     return tag.a(label, class_='%s ticket' % status, 
                                  title=title, href=href)
         else:
             ranges = str(r)
             if params:
                 params = '&' + params[1:]
             return tag.a(label, title='Tickets '+ranges,
                          href=formatter.href.query(id=ranges) + params)
     except ValueError:
         pass
     return tag.a(label, class_='missing ticket')
示例#22
0
    def expand_macro(self, formatter, name, content):
        interwikis = []
        for k in sorted(self.keys()):
            prefix, url, title = self[k]
            interwikis.append({
                'prefix':
                prefix,
                'url':
                url,
                'title':
                title,
                'rc_url':
                self._expand_or_append(url, ['RecentChanges']),
                'description':
                url if title == prefix else title
            })

        return tag.table(
            tag.tr(tag.th(tag.em(_("Prefix"))), tag.th(tag.em(_("Site")))), [
                tag.tr(
                    tag.td(tag.a(w['prefix'], href=w['rc_url'])),
                    tag.td(tag.a(w['description'], href=w['url'])))
                for w in interwikis
            ],
            class_="wiki interwiki")
示例#23
0
    def _format_sha_link(self, formatter, sha, label):
        # FIXME: this function needs serious rethinking...

        reponame = ''

        context = formatter.context
        while context:
            if context.resource.realm in ('source', 'changeset'):
                reponame = context.resource.parent.id
                break
            context = context.parent

        try:
            repos = self.env.get_repository(reponame)

            if not repos:
                raise Exception("Repository '%s' not found" % reponame)

            sha = repos.normalize_rev(sha) # in case it was abbreviated
            changeset = repos.get_changeset(sha)
            return tag.a(label, class_='changeset',
                         title=shorten_line(changeset.message),
                         href=formatter.href.changeset(sha, repos.reponame))
        except Exception, e:
            return tag.a(label, class_='missing changeset',
                         title=to_unicode(e), rel='nofollow')
示例#24
0
    def prevnext_ctxnav(self, req, prev_label, next_label, up_label=None):
        links = req.chrome['links']
        prev_link = next_link = None

        if not any(lnk in links for lnk in ('prev', 'up', 'next')): # Short circuit
            return

        if 'prev' in links:
            prev = links['prev'][0]
            prev_link = tag.a(prev_label, href=prev['href'], title=prev['title'],
                              class_='prev')

        add_ctxtnav(req, tag.span('', prev_link or prev_label, id='leftarrow',
                                  class_=not prev_link and 'missing' or None))

        if up_label and 'up' in links:
            up = links['up'][0]
            add_ctxtnav(req, tag.a(up_label, href=up['href'], title=up['title']))

        if 'next' in links:
            next_ = links['next'][0]
            next_link = tag.a(next_label, href=next_['href'], title=next_['title'],
                              class_='next')

        add_ctxtnav(req, tag.span(next_link or next_label, '', id='rightarrow',
                                  class_=not next_link and 'missing' or None))
示例#25
0
 def get_navigation_items(self, req):
     if req.authname and req.authname != "anonymous":
         if not self.env.is_component_enabled(LoginModule):
             yield ("metanav", "openidlogin", "logged in as %s" % (req.session.get("name") or req.authname))
             yield ("metanav", "openidlogout", tag.a("Logout", href=req.href.openidlogout()))
     else:
         yield ("metanav", "openidlogin", tag.a(("OpenID Login"), href=req.href.openidlogin()))
示例#26
0
 def _link_refs(self, req, refs_text, verbose_link=False):
     items_tag = None
     items, verbose_items = [], []
     elem = verbose_elem = "#%s" % refs_text
     try:
         c = self.cursor
         c.execute("SELECT id,name FROM assets_feature WHERE id ='%s'" % refs_text)
         row = c.fetchone()
         if row:
             title = shorten_line(row[1])
             attr = {
                 "class_": "assigned",
                 "href": "/splice/tractab/SPLICE/projects/feature/" + str(row[0]),
                 "title": title,
             }
             elem = tag.a("#%s %s" % (refs_text, title), **attr)
             verbose_elem = tag.a("#%s %s" % (refs_text, title), **attr)
     except ResourceNotFound:
         pass  # not supposed to happen, just in case
     items.extend([elem, ", "])
     verbose_items.extend([verbose_elem, tag.br()])
     if items:
         items_tag = [tag.span(items[:-1], id="tref_ticketid")]
         if verbose_link:
             vattr = {"id": "tref_summary", "class_": "tref-display-none"}
             items_tag.append(tag.span(verbose_items[:-1], **vattr))
     return tag(items_tag)
示例#27
0
 def get_navigation_items(self, req):
     if 'WIKI_VIEW' in req.perm('wiki'):
         yield ('mainnav', 'wiki',
                tag.a(_('Wiki'), href=req.href.wiki(), accesskey=1))
         yield ('metanav', 'help',
                tag.a(_('Help/Guide'), href=req.href.wiki('TracGuide'),
                      accesskey=6))
示例#28
0
    def expand_macro(self, formatter, name, content):
        offset = +1
        label = None
        if content is not None:
            if ',' in content:
                offset, label = content.split(',', 1)
            elif content and content[0] in '+-':
                offset = content
            else:
                label = content
            try:
                offset = int(offset)
            except ValueError:
                offset = 0
        mp = MyPageModule(self.env)
        base = mp.get_mypage_base(formatter.perm.username)
        all_mypages = mp.get_all_mypages(base)
        r = formatter.resource
        if r.realm == 'wiki' and r.id.startswith(base):
            mypage = r.id
        else:
            tzinfo = getattr(formatter.context.req, 'tz', None)
            now = datetime.now(tzinfo or localtz)
            today = format_date(now, 'iso8601', tzinfo)
            mypage = '/'.join([base, today])
        selected = base
        idx = bisect(all_mypages, mypage)

        # adjust to actual position if mypage exists
        if 0 <= idx - 1 < len(all_mypages) and all_mypages[idx -1] == mypage:
            idx -= 1
        self.log.debug("Reference is %s, pos %d in %r",
                       mypage, idx, all_mypages)

        # Special cases: at the beginning or at the end, the
        # predecessors resp. successors are "missing"
        missing = False
        if idx >= len(all_mypages) - 1 and offset > 0:
            missing, tooltip = True, _("(at the end)")
        elif idx < 1 and offset < 0:
            missing, tooltip = True, _("(at the beginning)")
        if missing:
            if not label:
                label, tooltip = tooltip, None
            return tag.a(label, title=tooltip, class_='missing')

        # Link to the targeted `MyPage` page
        idx += offset
        selected = all_mypages[max(0, min(idx, len(all_mypages) - 1))]
        self.log.debug("With offset %d, going to %d (adjusted to %d)",
                       offset, idx, max(0, min(idx, len(all_mypages) - 1)))
        selected_day = selected.split('/')[-1]
        try:
            tooltip = _("MyPage for %(day)s",
                        day=format_date(parse_date(selected_day)))
        except TracError:
            tooltip = _("non-day page '%(special)'", special=selected_day)
        return tag.a(label if label is not None else selected, title=tooltip,
                     href=formatter.href.wiki(selected))
示例#29
0
 def get_navigation_items(self, req):
     if req.perm.has_permission('SCREENSHOTS_VIEW'):
         if self.mainnav_title:
             yield ('mainnav', 'screenshots', tag.a(self.mainnav_title,
               href = req.href.screenshots()))
         if self.metanav_title:
             yield ('metanav', 'screenshots', tag.a(self.metanav_title,
               href = req.href.screenshots()))
示例#30
0
 def _format_link(self, formatter, ns, target, label):
     try:
         link, params, fragment = formatter.split_link(target)
         review = formatter.resource('review', link)
         return tag.a(label, href=self.get_resource_url(review, formatter.href))
     except ValueError:
         pass
     return tag.a(label, class_='missing review')
示例#31
0
 def get_navigation_items(self, req):
     if 'TAGS_VIEW' in req.perm:
         label = tag_("Tags")
         yield ('mainnav', 'tags',
                builder.a(label, href=req.href.tags(), accesskey='T'))
示例#32
0
    def render_widget(self, name, context, options):
        """Gather timeline events and render data in compact view
        """
        data = None
        req = context.req
        try:
            timemdl = self.env[TimelineModule]
            admin_page = tag.a(_("administration page."),
                               title=_("Plugin Administration Page"),
                               href=req.href.admin('general/plugin'))
            if timemdl is None:
                return 'widget_alert.html', {
                    'title': _("Activity"),
                    'data': {
                        'msglabel':
                        _("Warning"),
                        'msgbody':
                        tag_(
                            "The TimelineWidget is disabled because the "
                            "Timeline component is not available. "
                            "Is the component disabled? "
                            "You can enable from the %(page)s",
                            page=admin_page),
                        'dismiss':
                        False,
                    }
                }, context

            params = ('from', 'daysback', 'doneby', 'precision', 'filters',
                      'max', 'realm', 'id')
            start, days, user, precision, filters, count, realm, rid = \
                self.bind_params(name, options, *params)
            if context.resource.realm == 'ticket':
                if days is None:
                    # calculate a long enough time daysback
                    ticket = Ticket(self.env, context.resource.id)
                    ticket_age = datetime.now(utc) - ticket.time_created
                    days = ticket_age.days + 1
                if count is None:
                    # ignore short count for ticket feeds
                    count = 0
            if count is None:
                count = self.default_count

            fakereq = dummy_request(self.env, req.authname)
            fakereq.args = {
                'author': user or '',
                'daysback': days or '',
                'max': count,
                'precision': precision,
                'user': user
            }
            if filters:
                fakereq.args.update(dict((k, True) for k in filters))
            if start is not None:
                fakereq.args['from'] = start.strftime('%x %X')

            wcontext = context.child()
            if (realm, rid) != (None, None):
                # Override rendering context
                resource = Resource(realm, rid)
                if resource_exists(self.env, resource) or \
                        realm == rid == '':
                    wcontext = context.child(resource)
                    wcontext.req = req
                else:
                    self.log.warning("TimelineWidget: Resource %s not found",
                                     resource)
            # FIXME: Filter also if existence check is not conclusive ?
            if resource_exists(self.env, wcontext.resource):
                module = FilteredTimeline(self.env, wcontext)
                self.log.debug('Filtering timeline events for %s',
                               wcontext.resource)
            else:
                module = timemdl
            data = module.process_request(fakereq)[1]
        except TracError, exc:
            if data is not None:
                exc.title = data.get('title', _('Activity'))
            raise
示例#33
0
            if trac_version < trac_tags[0]:
                args = fakereq, self.env.get_db_cnx(), rptid
            else:
                args = fakereq, rptid
            data = rptmdl._render_view(*args)[1]
        except ResourceNotFound, exc:
            raise InvalidIdentifier(unicode(exc))
        except RequestDone:
            raise TracError('Cannot execute report. Redirection needed')
        except TracError, exc:
            if data is not None:
                exc.title = data.get('title', 'TracReports')
            raise
        else:
            title = data.get('title', '%s {%s}' % (_('Report'), rptid))
            rptctx = Context.from_request(fakereq, 'report', rptid)
            return 'widget_grid.html', \
                    {
                        'title' : title,
                        'data' : data,
                        'ctxtnav' : [
                            tag.a(_('More'), href=req.href('report', rptid)),
                            ('REPORT_MODIFY' in req.perm(rptctx.resource)) and \
                                tag.a(_('Edit'), href=req.href('report', rptid, action='edit')) or None,
                            ],
                        'altlinks' : fakereq.chrome.get('links', {}).get('alternate')
                    }, \
                    rptctx

    render_widget = pretty_wrapper(render_widget, check_widget_name)
    def render(self, ticketset):
        return_div = tag.div(class_=self.cssclass + ' projectplanrender')

        # check for missing parameters
        missingparameter = False
        if self.rows == [] or self.rows == None:
            return_div(
                tag.div(
                    'Missing parameter "rows": use a semicolon-separated list to input the "'
                    + self.rowtype + '".',
                    class_='ppwarning'))
            missingparameter = True
        if self.rowtype == None or str(self.rowtype).strip() == '':
            return_div(
                tag.div(
                    'Missing parameter "rowtype": specifies the ticket attribute that should be showed at the rows.',
                    class_='ppwarning'))
            missingparameter = True
        if self.cols == [] or self.cols == None:
            return_div(
                tag.div(
                    'Missing parameter: use a semicolon-separated list to input the "cols".',
                    class_='ppwarning'))
            missingparameter = True
        if self.coltype == None or str(self.coltype).strip() == '':
            return_div(
                tag.div(
                    'Missing parameter "coltype": specifies the ticket attribute that should be showed in the columns.',
                    class_='ppwarning'))
            missingparameter = True
        if missingparameter:
            return return_div

        #ul = tag.ul()
        #for tid in ticketset.getIDSortedList():
        #ticket = ticketset.getTicket(tid)
        #ul( tag.li(tid, " ",ticket.getfield('component') , " ", ticket.getfield('owner') ))
        #return_div(ul)
        def getstatistictitle(statusdict):
            mytitle = ''
            mysum = 0
            for status in statusdict:
                mytitle += "%s: %s\n" % (status, str(statusdict[status]))
                mysum += int(statusdict[status])
            mytitle += "%s: %s" % ('number', mysum)
            return mytitle

        def setKV(myStruct, myKey, newValue):
            '''
        shortcut to set the values correctly
        used to reduce the code needed while using a list as key of a dict
      '''
            myStruct[str(myKey)] = newValue

        def tableKeyPrettyPrint(mylist):
            '''
        transform a list of keys to a user readable string
        in: ['a','b'] --> out: 'a|b'
      '''
            return '|'.join(mylist)

        def tableKeyQueryParameter(parameter, mylist):
            '''
        transform a list of keys to a Trac query string parameter  (OR)
        in: x, ['a','b'] --> out: 'x=a&x=b'
      '''
            return '&'.join(["%s=%s" % (parameter, s) for s in mylist])

        chartheight = 80
        chartwidth = 170

        data = {}
        statistics = {}

        # init table data
        for row in self.rows:
            colstatistics = {}
            colkeys = {}
            for col in self.cols:
                # colkeys[col] = []
                setKV(colkeys, col, [])
                # colstatistics[col] = {}
                setKV(colstatistics, col, {})
            # data[row] = colkeys
            setKV(data, row, colkeys)
            # statistics[row] = colstatistics
            setKV(statistics, row, colstatistics)

        for tid in ticketset.getIDSortedList():
            ticket = ticketset.getTicket(tid)
            ticket_rowtype = ticket.getfield(self.rowtype)
            ticket_coltype = ticket.getfield(self.coltype)

            # determine the data cell where the ticket has to be added, keep in mind that rows and cols are list of lists
            for row in self.rows:
                for col in self.cols:
                    if ticket_rowtype in row and ticket_coltype in col:
                        data[str(row)][str(col)].append(
                            ticket
                        )  # save tickets at precise values of row and col
                        self.log_debug('row:%s col:%s append:%s' %
                                       (row, col, tid))

            # if ticket_rowtype in self.rows and ticket_coltype in self.cols :

        # create HTML table
        table = tag.table(class_="data pptableticketperday",
                          border="1",
                          style='width:auto;')

        # create HTML table head
        thead = tag.thead()
        tr = tag.tr()
        tr(tag.th("%s vs %s" % (self.rowtype, self.coltype)))
        for colkey in self.cols:
            tr(
                tag.th(tag.h4(
                    tag.a(tableKeyPrettyPrint(colkey),
                          href=self.macroenv.tracenv.href() +
                          ('/query?%s&order=%s' % (tableKeyQueryParameter(
                              self.coltype, colkey), self.rowtype)))),
                       title="%s is %s" %
                       (self.coltype, tableKeyPrettyPrint(colkey)))
            )  # first line with all colkeys
        if self.showsummarypiechart:
            tr(tag.th(tag.h4("Ticket Overview")))
        thead(tr)
        table(thead)

        # create HTML table body
        tbody = tag.tbody()
        counter = 0

        for rowkey in self.rows:
            # switch line color
            if counter % 2 == 1:
                class_ = 'odd'
            else:
                class_ = 'even'
            counter += 1
            tr = tag.tr(class_=class_)  # new line

            td = tag.td()  # new cell
            td(tag.h5(
                tag.a(tableKeyPrettyPrint(rowkey),
                      href=self.macroenv.tracenv.href() +
                      ('/query?%s&order=%s' % (tableKeyQueryParameter(
                          self.rowtype, rowkey), self.coltype)))),
               title="%s is %s" %
               (self.rowtype,
                tableKeyPrettyPrint(rowkey)))  # first cell contains row key
            tr(td)
            for colkey in self.cols:
                td = tag.td()
                for ticket in data[str(rowkey)][str(colkey)]:
                    td(tag.span(self.createTicketLink(ticket),
                                class_='ticket_inner'),
                       " ",
                       mytitle="%s is %s and %s is %s" %
                       (self.rowtype, rowkey, self.coltype,
                        colkey))  # mytitle might be used later by javascript
                    if not statistics[str(rowkey)][str(colkey)].has_key(
                            ticket.getstatus()):
                        statistics[str(rowkey)][str(colkey)][
                            ticket.getstatus()] = 0
                    statistics[str(rowkey)][str(colkey)][
                        ticket.getstatus()] += 1
                tr(td)

            # compute statistics
            rowstatistics = {}
            count = 0
            for colkey in statistics[str(rowkey)]:
                for status in statistics[str(rowkey)][str(colkey)]:
                    if not rowstatistics.has_key(status):
                        rowstatistics[status] = 0
                    try:
                        rowstatistics[status] += statistics[str(rowkey)][str(
                            colkey)][status]
                        count += statistics[str(rowkey)][str(colkey)][status]
                    except:
                        pass

            if self.showsummarypiechart:
                tr(
                    tag.td(tag.img(src=self.createGoogleChartFromDict(
                        'ColorForStatus',
                        rowstatistics,
                        '%s tickets' % (count, ),
                        height=chartheight)),
                           class_='ppstatistics',
                           title=getstatistictitle(rowstatistics)))  # Summary

            tbody(tr)
        table(tbody)

        # create HTML table foot
        if self.showsummarypiechart:
            fullstatistics = {}
            tfoot = tag.tfoot()
            tr = tag.tr()

            tr(tag.td(tag.h5('Ticket Overview')))

            # create statistics for col
            fullcount = 0
            for colkey in self.cols:
                colstatistics = {}
                colcount = 0
                for rowkey in self.rows:
                    for status in statistics[str(rowkey)][str(colkey)]:
                        if not fullstatistics.has_key(status):
                            fullstatistics[status] = 0
                        if not colstatistics.has_key(status):
                            colstatistics[status] = 0
                        try:
                            colstatistics[status] += statistics[str(rowkey)][
                                str(colkey)][status]
                            colcount += statistics[str(rowkey)][str(
                                colkey)][status]
                            fullstatistics[status] += statistics[str(rowkey)][
                                str(colkey)][status]
                            fullcount += statistics[str(rowkey)][str(
                                colkey)][status]
                        except:
                            pass
                tr(
                    tag.td(
                        tag.img(src=self.createGoogleChartFromDict(
                            'ColorForStatus',
                            colstatistics,
                            '%s tickets' % (colcount, ),
                            height=chartheight)),
                        title=getstatistictitle(colstatistics)))  # Col Summary
            tr(
                tag.td(
                    tag.img(src=self.createGoogleChartFromDict(
                        'ColorForStatus',
                        fullstatistics,
                        '%s tickets' % (fullcount, ),
                        height=chartheight)),
                    class_='ppstatistics',
                    title=getstatistictitle(fullstatistics)))  # Full Summary
            tfoot(tr)
            table(tfoot)

        return_div(table)

        return return_div
示例#35
0
    def expand_macro(self, formatter, name, content, realms=[]):
        """Evaluate macro call and render results.

        Calls from web-UI come with pre-processed realm selection.
        """
        env = self.env
        req = formatter.req
        tag_system = TagSystem(env)

        all_realms = set([p.get_taggable_realm()
                         for p in tag_system.tag_providers])
        if not all_realms:
            # Tag providers are required, no result without at least one.
            return ''
        args, kw = parse_args(content)

        query = args and args[0].strip() or None
        if not realms:
            # Check macro arguments for realms (typical wiki macro call).
            realms = 'realm' in kw and kw['realm'].split('|') or []
        if query:
            # Add realms from query expression.
            realms.extend(query_realms(query, all_realms))
            # Remove redundant realm selection for performance.
            if set(realms) == all_realms:
                query = re.sub('(^|\W)realm:\S+(\W|$)', ' ', query).strip()
        if name == 'TagCloud':
            # Set implicit 'all tagged realms' as default.
            if not realms:
                realms = all_realms
            if query:
                all_tags = Counter()
                # Require per resource query including view permission checks.
                for resource, tags in tag_system.query(req, query):
                    all_tags.update(tags)
            else:
                # Allow faster per tag query, side steps permission checks.
                all_tags = tag_system.get_all_tags(req, realms=realms)
            mincount = 'mincount' in kw and kw['mincount'] or None
            return self.render_cloud(req, all_tags,
                                     caseless_sort=self.caseless_sort,
                                     mincount=mincount, realms=realms)
        elif name == 'ListTagged':
            if content and _OBSOLETE_ARGS_RE.search(content):
                data = {'warning': 'obsolete_args'}
            else:
                data = {'warning': None}
            context = formatter.context
            # Use TagsQuery arguments (most likely wiki macro calls).
            cols = 'cols' in kw and kw['cols'] or self.default_cols
            format = 'format' in kw and kw['format'] or self.default_format
            if not realms:
                # Apply ListTagged defaults to macro call w/o realm.
                realms = list(set(all_realms)-set(self.exclude_realms))
                if not realms:
                    return ''
            query = '(%s) (%s)' % (query or '', ' or '.join(['realm:%s' % (r)
                                                             for r in realms]))
            env.log.debug('LISTTAGGED_QUERY: %s', query)
            query_result = tag_system.query(req, query)
            if not query_result:
                return ''

            def _link(resource):
                if resource.realm == 'tag':
                    # Keep realm selection in tag links.
                    return builder.a(resource.id,
                                     href=self.get_href(req, realms,
                                                        tag=resource))
                elif resource.realm == 'ticket':
                    # Return resource link including ticket status dependend
                    #   class to allow for common Trac ticket link style.
                    ticket = Ticket(env, resource.id)
                    return builder.a('#%s' % ticket.id,
                                     class_=ticket['status'],
                                     href=formatter.href.ticket(ticket.id),
                                     title=shorten_line(ticket['summary']))
                return render_resource_link(env, context, resource, 'compact')

            if format == 'table':
                cols = [col for col in cols.split('|')
                        if col in self.supported_cols]
                # Use available translations from Trac core.
                try:
                    labels = TicketSystem(env).get_ticket_field_labels()
                    labels['id'] = _('Id')
                except AttributeError:
                    # Trac 0.11 neither has the attribute nor uses i18n.
                    labels = {'id': 'Id', 'description': 'Description'}
                labels['realm'] = _('Realm')
                labels['tags'] = _('Tags')
                headers = [{'label': labels.get(col)}
                           for col in cols]
                data.update({'cols': cols,
                             'headers': headers})

            results = sorted(query_result, key=lambda r: \
                             embedded_numbers(to_unicode(r[0].id)))
            results = self._paginate(req, results, realms)
            rows = []
            for resource, tags in results:
                desc = tag_system.describe_tagged_resource(req, resource)
                # Fallback to resource provider method.
                desc = desc or get_resource_description(env, resource,
                                                        context=context)
                tags = sorted(tags)
                wiki_desc = format_to_oneliner(env, context, desc)
                if tags:
                    rendered_tags = [_link(Resource('tag', tag))
                                     for tag in tags]
                    if 'oldlist' == format:
                        resource_link = _link(resource)
                    else:
                        resource_link = builder.a(wiki_desc,
                                                  href=get_resource_url(
                                                  env, resource, context.href))
                        if 'table' == format:
                            cells = []
                            for col in cols:
                                if col == 'id':
                                    cells.append(_link(resource))
                                # Don't duplicate links to resource in both.
                                elif col == 'description' and 'id' in cols:
                                    cells.append(wiki_desc)
                                elif col == 'description':
                                    cells.append(resource_link)
                                elif col == 'realm':
                                    cells.append(resource.realm)
                                elif col == 'tags':
                                    cells.append(
                                        builder([(tag, ' ')
                                                 for tag in rendered_tags]))
                            rows.append({'cells': cells})
                            continue
                rows.append({'desc': wiki_desc,
                             'rendered_tags': None,
                             'resource_link': _link(resource)})
            data.update({'format': format,
                         'paginator': results,
                         'results': rows,
                         'tags_url': req.href('tags')})

            # Work around a bug in trac/templates/layout.html, that causes a
            # TypeError for the wiki macro call, if we use add_link() alone.
            add_stylesheet(req, 'common/css/search.css')

            return Chrome(env).render_template(
                req, 'listtagged_results.html', data, 'text/html', True)
示例#36
0
文件: io.py 项目: woodem/woo
 def __call__(self, obj, depth=0, dontRender=False):
     from genshi.builder import tag
     if depth > self.maxDepth:
         raise RuntimeError("Maximum nesting depth %d exceeded" %
                            self.maxDepth)
     kw = self.padding.copy()
     if depth > 0: kw.update(width='100%')
     # was [1:] to omit leading woo./wooExtra., but that is not desirable
     objInExtra = obj.__class__.__module__.startswith('wooExtra.')
     if self.hideWooExtra and objInExtra:
         head = tag.span(tag.b(obj.__class__.__name__),
                         title=_ensureUnicode(obj.__class__.__doc__))
     else:
         head = tag.b('.'.join(obj.__class__.__module__.split('.')[0:]) +
                      '.' + obj.__class__.__name__)
         head = tag.a(head,
                      href=woo.document.makeObjectUrl(obj),
                      title=_ensureUnicode(obj.__class__.__doc__))
     ret = tag.table(tag.th(head, colspan=3, align='left'),
                     frame='box',
                     rules='all',
                     **kw)
     # get all attribute traits first
     traits = obj._getAllTraits()
     for trait in traits:
         if trait.hidden or (self.hideNoGui and trait.noGui
                             ) or trait.noDump or (trait.hideIf and eval(
                                 trait.hideIf, globals(), {'self': obj})):
             continue
         # start new group (additional line)
         if trait.startGroup:
             ret.append(
                 tag.tr(
                     tag.td(tag.i(u'▸ %s' %
                                  _ensureUnicode(trait.startGroup)),
                            colspan=3)))
         attr = getattr(obj, trait.name)
         if self.showDoc: tr = tag.tr(tag.td(_ensureUnicode(trait.doc)))
         else:
             try:
                 if self.hideWooExtra and objInExtra:
                     label = tag.span(tag.b(trait.name),
                                      title=_ensureUnicode(trait.doc))
                 else:
                     label = tag.a(trait.name,
                                   href=woo.document.makeObjectUrl(
                                       obj, trait.name),
                                   title=_ensureUnicode(trait.doc))
                 tr = tag.tr(tag.td(label))
             except UnicodeEncodeError:
                 print(
                     'ERROR: UnicodeEncodeError while formatting the attribute ',
                     obj.__class__.__name__ + '.' + trait.name)
                 print('ERROR: the docstring is', trait.doc)
                 raise
         # tr=tag.tr(tag.td(trait.name if not self.showDoc else trait.doc.decode('utf-8')))
         # nested object
         if isinstance(attr, woo.core.Object):
             tr.append(
                 [tag.td(self(attr, depth + 1), align='justify'),
                  tag.td()])
         # sequence of objects (no units here)
         elif hasattr(attr, '__len__') and len(attr) > 0 and isinstance(
                 attr[0], woo.core.Object):
             tr.append(
                 tag.td(tag.ol([tag.li(self(o, depth + 1)) for o in attr])))
         else:
             # !! make deepcopy so that the original object is not modified !!
             import copy
             attr = copy.deepcopy(attr)
             if not trait.multiUnit:  # the easier case
                 if not trait.prefUnit: unit = u'−'
                 else:
                     unit = _ensureUnicode(trait.prefUnit[0][0])
                     # create new list, where entries are multiplied by the multiplier
                     if type(attr) == list:
                         attr = [a * trait.prefUnit[0][1] for a in attr]
                     else:
                         attr = attr * trait.prefUnit[0][1]
             else:  # multiple units
                 unit = []
                 wasList = isinstance(attr, list)
                 if not wasList: attr = [attr]  # handle uniformly
                 for i in range(len(attr)):
                     attr[i] = [
                         attr[i][j] * trait.prefUnit[j][1]
                         for j in range(len(attr[i]))
                     ]
                 for pu in trait.prefUnit:
                     unit.append(_ensureUnicode(pu[0]))
                 if not wasList: attr = attr[0]
                 unit = ', '.join(unit)
             # sequence type, or something similar
             if hasattr(attr,
                        '__len__') and not isinstance(attr, (str, bytes)):
                 if len(attr) > 0:
                     tr.append(
                         tag.td(self.htmlSeq(attr, insideTable=False),
                                align='right'))
                 else:
                     tr.append(tag.td(tag.i('[empty]'), align='right'))
             else:
                 tr.append(
                     tag.td(float2str(attr)
                            if isinstance(attr, float) else str(attr),
                            align='right'))
             if unit:
                 tr.append(tag.td(unit, align='right'))
         ret.append(tr)
     if depth > 0 or dontRender: return ret
     r1 = ret.generate().render('xhtml', encoding='ascii')
     if isinstance(r1, bytes): r1 = r1.decode('ascii')
     return r1 + u'\n'
示例#37
0
 def get_navigation_items(self, req):
     if XMailPermissions.checkPermissions(self,req):
         yield ('mainnav', self.MY_PATH,
                tag.a('XMail', href=req.href.xmail()))
示例#38
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content, strict=False)

        if len(args) == 1:
            hat = args[0].lower()
            title = TITLES.get(hat, '')

        elif len(args) == 2:
            hat = args[0].lower()
            title = args[1]

        # An simple Exception would probabl;y be better, see http://../ for examples.
        if len(args) == 0 or hat not in ('black', 'blue', 'green', 'red',
                                         'white', 'yellow', 'intro', 'cite'):
            raise TracError(
                'Invalid parameters, see http://trac-hacks.org/wiki/SixhatsMacro#Examples for example uses.'
            )
            #tags = [tag.strong()('Error: Invalid parameters, see the following examples:')]
            #tags.extend([tag.pre()(i) for i in HELP.splitlines()])
            #return tag.div(class_='system-message')(*tags)

        if hat == 'cite':
            if not title:
                title = "The best way to learn the Six Hats method is to read Edward de Bono's "
            url = get_absolute_url(
                formatter.href.base,
                'htdocs://sixhats/pdf/six_thinking_hats.pdf')
            return tag.p()(title, tag.a(href=url)('Six Thinking Hats'), '.')

        # Not too sure if a plugin should be self-documenting.
        if hat == 'intro':
            hide = kwargs.get('hide')

            tags = []
            tags.append(
                tag.h1(id='SixHatsIntroduction')('Six Hats Introduction'))
            tags.append(
                tag.blockquote(
                    tag.
                    p("There is nothing more sad and wasteful than a roomful of intelligent and highly paid people waiting for a chance to attack something the speaker has said. With the Six Hats method the fullest use is made of everyone's intelligence, experience and information. The Six Hats also removes all 'ego' from the discussion process."
                      )))
            tags.append(
                tag.p(
                    'The Six Thinking Hats represent directions of thought. They are used to request thinking in a paticular direction, ',
                    tag.strong('not'),
                    ' as a description or label to classify your thinking afterwards. They are ',
                    tag.strong('not'),
                    ' used to characterize people. A person is not a black hat, but he or she might prefer to think with the black hat on. It is desirable for everyone to become skilled in the use of all the hats.'
                ))
            tags.append(self.expand_macro(formatter, name, 'cite'))
            tags.append(tag.h1(id='Summary')('Summary'))
            tags.append(self.expand_macro(formatter, name, 'white,size=m'))

            li = [
                tag.li('The white hat is neutral and objective.'),
                tag.li('It focusses on facts and figures.'),
            ]

            sub_li = [
                tag.li('What information do we have?'),
                tag.li('What information do we need?'),
                tag.li('What information is missing?'),
                tag.li('What questions do we need to ask?'),
                tag.li('How are we going to get the information we need?')
            ]

            li.append(
                tag.li('Questions to ask with the white hat on:',
                       tag.ul(*sub_li)))
            li.extend([
                tag.
                li('The information can range from hard verifiable facts and figures to soft information such as 3rd party opinions and feelings. Your own opinions and feelings are placed under the red hat.'
                   ),
                tag.li('Whose fact is it?'),
                tag.li('Is the information a fact, a likelyhood or a believe?')
            ])

            sub_li = [
                tag.li('Always true'),
                tag.li('Usually true'),
                tag.li('Generally true'),
                tag.li('By and large'),
                tag.li('More often than not'),
                tag.li('About half the time'),
                tag.li('Often'),
                tag.li('Sometimes true'),
                tag.li('Occastionally true'),
                tag.li('Been known to happen'),
                tag.li('Never true'),
                tag.li('Cannot be true (contradictory)')
            ]

            li.append(
                tag.
                li('How true is the fact? Frame the information appropriatly:',
                   tag.ul(*sub_li)))
            li.append(
                tag.
                li('Split the facts into two groups: checked facts and believed facts.'
                   ))
            tags.append(tag.ul(*li))

            tags.append(self.expand_macro(formatter, name, 'red,size=m'))

            li = [
                tag.li(
                    'The red hat is subjective and generally non-rational.'),
                tag.li('It exposes and legitimizes emotions and feelings.'),
                tag.
                li('It allows people to express their opinions, hunches, intuitions and impressions. (a function of their experience)'
                   ),
                tag.
                li("Resist the temptation to justify your emotions. You don't need to give a reason or a logical basis."
                   ),
                tag.
                li('If emotions and feelings are not permitted as inputs in the thinking process, they will lurk in the background and affect all the thinking in a hidden way.'
                   ),
                tag.
                li('The red hat makes feelings visible so that they can become part of the thinking map and also part of the value system that chooses the route on the map.'
                   )
            ]

            sub_li = [
                tag.
                li('Ordinary emotions such as fear and dislike to more subtle ones such as suspicion.'
                   ),
                tag.
                li('Complex judgements that go into such type of feelings as a hunch, intuition, sense, taste, aesthetic feeling and other not visibly justified types of feeling.'
                   )
            ]

            li.append(
                tag.li('The red hat covers two broad types of feelings:',
                       tag.ol(*sub_li)))
            tags.append(tag.ul(*li))

            tags.append(self.expand_macro(formatter, name, 'black,size=m'))

            li = [
                tag.
                li('The black hat is critical and logical (negative judgements).'
                   ),
                tag.
                li("It's perhaps the most important hat, the hat of survival, of caution and of being careful."
                   ),
                tag.
                li('It points out how something does not fit our experience, our resources, our policy, our stragegy, our ethics, our values, etc.'
                   ),
                tag.
                li('It protects us from wasting energy and money, it seeks to avoid dangers, problems, obstacles and difficulties.'
                   ),
                tag.
                li('There must be a logical basis for the criticism and reasons must be capable of standing on their own.'
                   ),
                tag.
                li('It focuses on why something may not work or may not be the right thing to do.'
                   ),
            ]

            sub_li = [
                tag.li('Be as causious and as fiercely critical as possible.'),
                tag.li(
                    'Point out errors or deficiencies in the thinking process.'
                ),
                tag.li('Question the strength of the evidence.'),
                tag.li('What are the risks?'),
            ]

            li.append(
                tag.li(
                    'In order to get the full value from any suggestion or idea, it is important that the black hat be done thoroughly:',
                    tag.ul(*sub_li)))
            li.extend([
                tag.
                li('Black hat thinking is not argument and must not be allowed to degenerate into argument.'
                   ),
                tag.li(
                    tag.strong('Caution:'),
                    ' There are people who overuse the black hat and who spend all their time trying to find fault. The fault is not in the black hat but in the abuse, overuse or misuse of the black hat.'
                )
            ])

            tags.append(tag.ul(*li))

            tags.append(self.expand_macro(formatter, name, 'yellow,size=m'))

            li = [
                tag.
                li('The yellow hat is optimistic and logical (positive judgements).'
                   )
            ]

            sub_li = [
                tag.li('The generation of proposals.'),
                tag.li('The positive assessment of proposals.'),
                tag.li("Developing or 'building up' of proposals.")
            ]

            li.append(
                tag.li('The yellow hat is concerned with:', tag.ol(*sub_li)))
            li.extend([
                tag.
                li('Under the yellow hat a thinker deliberatly sets out to find whatever benefit there may be in a suggestion.'
                   ),
                tag.
                li('It is a waste of time setting out to be creative if you are not going to recognize a good idea.'
                   ),
                tag.li('Value and benefit are by no means always obvious.'),
                tag.
                li('Since the yellow hat is logical you should give a reason for the value you put forward.'
                   ),
                tag.
                li('The emphasis of yellow hat thinking is on exploration and positive speculation, oppertunity seeking.'
                   ),
                tag.
                li("Yellow hat thinking is concerned with the positive attitude of getting the job done, let's make it happen."
                   )
            ])

            tags.append(tag.ul(*li))

            tags.append(self.expand_macro(formatter, name, 'green,size=m'))

            li = [
                tag.li('The green hat is creative, sometimes illogical.'),
                tag.
                li('The green hat is concerned with new ideas and new ways of looking at things, new perceptions.'
                   ),
                tag.
                li("Under the green hat we lay out options, alternatives and 'possibilities'."
                   ),
                tag.
                li('It corrects the faults found under the black hat and find noval ways the exploit the opportunities identified under the yellow hat.'
                   ),
                tag.
                li('You use the green hat to deliberately go after new ideas instead of waiting for them to come to you.'
                   ),
                tag.
                li('Sometimes you may be required to put forward provocations, illogical ideas, in order to provoke new concepts.'
                   ),
                tag.
                li('Under the green hat we use ideas as stepping stones, for their movement value, moving us to new ideas.'
                   ),
                tag.li('Use random words and ', tag.em('Po'), '.')
            ]

            tags.append(tag.ul(*li))

            tags.append(self.expand_macro(formatter, name, 'blue,size=m'))

            li = [
                tag.
                li('The blue hat is for meta-thinking, thinking about thinking.'
                   ),
                tag.
                li('Wearing the blue hat we are no longer thinking about the subject; instead, we are thinking about the thinking needed to explore the subject.'
                   ),
                tag.
                li('The blue hat thinker is like the conductor of an orchestra.'
                   ),
                tag.
                li("Generally the blue hat is worn by the facilitator, chairperson or leader of the session, it's a permanent role."
                   ),
                tag.
                li('The blue hat is for the organization and management of thinking, it also controls the process of thinking.'
                   ),
                tag.
                li('The initial blue hat defines the problem, list constraints and sets the agenda, the sequence of the other hats to be used.'
                   ),
                tag.
                li('Blue hat thinking stops arguments, enforces the discipline and keep people focussed on map making.'
                   ),
                tag.
                li('The final blue hat is responsible for summaries, overviews and conclusions.'
                   )
            ]

            tags.append(tag.ul(*li))

            fedoras = tag.a('fedoras',
                            href=get_absolute_url(
                                formatter.href.base,
                                'htdocs://sixhats/img/source/fedoras.svg'))
            hardhats = tag.a('hardhats',
                             href=get_absolute_url(
                                 formatter.href.base,
                                 'htdocs://sixhats/img/source/hardhats.svg'))
            tophats = tag.a('tophats',
                            href=get_absolute_url(
                                formatter.href.base,
                                'htdocs://sixhats/img/source/tophats.svg'))

            tags.append(
                tag.p(
                    'PS. If you wish to use any of these images in your own documents rather use the high quality vectors: ',
                    fedoras, ', ', hardhats, ' and ', tophats, '.'))

            if hide:
                add_script(formatter.req, 'sixhats/js/hide.js')

                if hide.lower() == 'hide':
                    return ''.join([
                        str(i) for i in
                        ('- ',
                         tag.a(id='hide', href='#', style='font-size: 8pt;')(
                             'show six hats introduction'), ' -',
                         tag.div(
                             id='introduction', style='display: none;', *tags))
                    ])
                else:
                    return ''.join([
                        str(i) for i in (
                            '- ',
                            tag.a(id='hide', href='#', style='font-size: 8pt;')
                            ('hide six hats introduction'), ' -',
                            tag.div(id='introduction', *tags))
                    ])
            else:
                return tag.div(id='introduction', *tags)

        id = kwargs.get('id', squish_string(title))
        size = kwargs.get('size', 'large')
        type = kwargs.get('type', 'hardhat').lower()
        h = kwargs.get('h')

        if type in ('fedora', 'hardhat', 'tophat'):
            if size.endswith('%'):
                percentage = float(size.strip('%')) / 100.0
                width, height = SIZES[type]['l']
            else:
                percentage = 1
                width, height = SIZES[type][size[0]]

            width = int(width * percentage)
            height = int(height * percentage)

        if h:
            if h == '1':
                root = tag.h1
            elif h == '2':
                root = tag.h2
            elif h == '3':
                root = tag.h3
            elif h == '4':
                root = tag.h4
            else:
                root = tag.h5
        else:
            s0 = size[0]
            if s0 == 'l':
                root = tag.h1
            elif s0 == 'm':
                root = tag.h2
            elif s0 == 's':
                root = tag.h3
            else:
                root = tag.h1

        url = get_absolute_url(
            formatter.href.base,
            'htdocs://sixhats/img/%(type)s/%(hat)s.jpg' % {
                'type': type,
                'hat': hat
            })

        if id:
            return root(id=id)(tag.img(src=url, width=width, height=height),
                               title)
        else:
            return root()(tag.img(src=url, width=width, height=height), title)
示例#39
0
 def get_navigation_items(self, req):
     if 'TIMELINE_VIEW' in req.perm:
         yield ('mainnav', 'timeline',
                tag.a(_("Timeline"), href=req.href.timeline(), accesskey=2))
示例#40
0
 def get_navigation_items(self, req):
     if 'TICKET_GRAPH' in req.perm:
         yield ('mainnav', 'ticketgraph',
                tag.a(_('Ticket Graph'), href=req.href.ticketgraph()))
示例#41
0
文件: api.py 项目: Logan-lu/trac
 def annotate_row(self, context, row, lineno, line, data):
     lineno += data['offset']
     id = data['id'] % lineno
     if data['marks'] and lineno in data['marks']:
         row(class_='hilite')
     row.append(tag.th(id=id)(tag.a(lineno, href='#' + id)))
示例#42
0
 def get_navigation_items(self, req):
     if 'REPORT_VIEW' in req.perm:
         yield ('mainnav', 'tickets', tag.a(_('View Tickets'),
                                            href=req.href.report()))
示例#43
0
 def annotate_row(self, context, row, lineno, line, data):
     row.append(
         tag.th(id='L%s' % lineno)(tag.a(lineno,
                                         href='javascript:setLineNum(%s)' %
                                         lineno)))
示例#44
0
    def filter_stream(self, req, method, filename, stream, data):
        """
        Quick and dirty solution - modify page on the fly to inject special field. It would be
        nicer if we can do it by creating custom field as this depends on page structure.
        """
        #embed(header='Ticket Stream Filter')
        if filename == 'ticket.html':
            # Disable any direct bounty input
            filter = Transformer('.//input[@id="field-bounty"]')
            stream |= filter.attr("disabled", "disabled")

            ticket = data.get('ticket')
            if ticket and ticket.exists:
                identifier = ticket.id
                user = req.authname if req.authname != 'anonymous' else None
                request = self.call_api('GET', '/issue/%s' % identifier)
                fragment = tag()
                sponsorships = {}
                status = self.convert_status(ticket.values['status'])
                owner = ticket.values['owner']
                tooltip = None
                if request != None and (request.status_code == 200
                                        or request.status_code == 404):
                    sponsorships = self.get_sponsorships(identifier)

                    pledged_amount = sum_amounts(sponsorships.values())
                    user_sponsorship = sponsorships.get(user, Sponsorship())

                    # Bounty
                    tooltip = u"Pledged: %d\u20ac" % pledged_amount

                    if status == 'STARTED' or status == 'COMPLETED':
                        confirmed_amount = sum_amounts(
                            sponsorships.values(),
                            ('CONFIRMED', 'VALIDATED', 'REJECTED',
                             'TRANSFERRED', 'REFUNDED'))
                        tooltip += u" \nConfirmed: %d\u20ac" % confirmed_amount
                    if status == 'COMPLETED':
                        validated_amount = sum_amounts(sponsorships.values(),
                                                       'VALIDATED')
                        tooltip += u" \nValidated: %d\u20ac" % validated_amount

                    # Action
                    action = None
                    if (((status == 'STARTED' or status == 'COMPLETED')
                         and user_sponsorship.status == 'PLEDGED') or
                        (status == 'STARTED' and user != None and user != owner
                         and user_sponsorship.status == None)):
                        response = self.call_api('GET',
                                                 '/config/payment_gateways')
                        gateways = response.json().get('gateways')
                        gateway_tags = []
                        if 'DUMMY' in gateways:
                            gateway_tags.append(
                                tag.input(type="submit",
                                          value="Payment Card",
                                          name='DUMMY'))
                        if 'PAYPAL_STANDARD' in gateways:
                            gateway_tags.append(
                                tag.input(type="submit",
                                          value="PayPal",
                                          name='PAYPAL_STANDARD'))
                        if 'PAYPAL_ADAPTIVE' in gateways:
                            gateway_tags.append(
                                tag.input(type="submit",
                                          value="PayPal",
                                          name='PAYPAL_ADAPTIVE'))
                        if user_sponsorship.status == 'PLEDGED':
                            action = tag.form(
                                tag.input(type="button",
                                          name="confirm",
                                          value=u"Confirm %d\u20ac" %
                                          user_sponsorship.amount,
                                          id="confirm-button"),
                                tag.span(gateway_tags, id="confirm-options"),
                                tag.input(type="submit",
                                          name="delete",
                                          value="Delete"),
                                method="post",
                                action=req.href.ticket(identifier, "confirm"))
                        else:
                            #TODO: should be separate action
                            action = tag.form(
                                tag.input(name="amount",
                                          type="text",
                                          size="3",
                                          value="0",
                                          pattern="[0-9]*",
                                          title="money amount"),
                                tag.input(type="button",
                                          value="Pledge & Confirm",
                                          id="confirm-button"),
                                tag.span(gateway_tags, id="confirm-options"),
                                method="post",
                                action=req.href.ticket(identifier, "confirm"))

                    elif status == 'COMPLETED' and user_sponsorship.status in (
                            'CONFIRMED', 'REJECTED', 'VALIDATED'):
                        action = tag.form(method="post",
                                          action=req.href.ticket(
                                              identifier, "validate"))
                        if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'REJECTED':
                            action.append(
                                tag.input(type="submit",
                                          name='validate',
                                          value=u"Validate %d\u20ac" %
                                          user_sponsorship.amount))
                        if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'VALIDATED':
                            action.append(
                                tag.input(type="submit",
                                          name='reject',
                                          value="Reject"))
                    elif (status == 'READY' and user != None):
                        if user_sponsorship.status == None:
                            action = tag.form(
                                tag.input(name="amount",
                                          type="text",
                                          size="3",
                                          value=user_sponsorship.amount,
                                          pattern="[0-9]*",
                                          title="money amount"),
                                tag.input(type="submit", value="Pledge"),
                                method="post",
                                action=req.href.ticket(identifier, "sponsor"))
                        elif user_sponsorship.status == 'PLEDGED':
                            action = tag.form(
                                tag.input(name="amount",
                                          type="text",
                                          size=3,
                                          value=user_sponsorship.amount,
                                          pattern="[0-9]*",
                                          title="money amount"),
                                tag.input(type="submit",
                                          name="update",
                                          value="Update"),
                                tag.input(type="submit",
                                          name="delete",
                                          value="Delete"),
                                method="post",
                                action=req.href.ticket(identifier,
                                                       "update_sponsorship"))

                    elif (user == None):
                        action = tag.span(
                            u"\u00A0", tag.a("Login",
                                             href=req.href.login()), " or ",
                            tag.a("Register", href=req.href.register()),
                            " to sponsor")

                    if action != None:
                        fragment.append(" ")
                        fragment.append(action)

                else:
                    error = "Connection error"
                    if request:
                        error = request.json().get("error", "Unknown error")
                    fragment.append(
                        tag.span("[BountyFunding Error]", title=error))

                #chrome = Chrome(self.env)
                #chrome.add_jquery_ui(req)

                add_stylesheet(req, 'htdocs/styles/bountyfunding.css')
                add_script(req, 'htdocs/scripts/bountyfunding.js')

                if tooltip != None:
                    filter = Transformer('.//td[@headers="h_bounty"]/text()')
                    stream |= filter.wrap(tag.span(title=tooltip))

                filter = Transformer('.//td[@headers="h_bounty"]')
                stream |= filter.attr("class", "bountyfunding")
                stream |= filter.append(fragment)

        return stream
示例#45
0
 def get_navigation_items(self, req):
     if req.perm.has_permission('BLOG_VIEW') and self.nav_bar:
         yield 'mainnav', 'blog', tag.a(self.nav_bar_text,
                                        href=req.href.blog())
示例#46
0
 def annotate_row(self, context, row, lineno, line, data):
     row.append(
         tag.th(id='L%s' % lineno)(tag.a(lineno, href='#L%s' % lineno)))
示例#47
0
文件: git_fs.py 项目: t2y/trac
    def render_property(self, name, mode, context, props):
        def sha_link(sha, label=None):
            # sha is assumed to be a non-abbreviated 40-chars sha id
            try:
                reponame = context.resource.parent.id
                repos = self.env.get_repository(reponame)
                cset = repos.get_changeset(sha)
                if label is None:
                    label = repos.display_rev(sha)

                return tag.a(label,
                             class_='changeset',
                             title=shorten_line(cset.message),
                             href=context.href.changeset(sha, repos.reponame))

            except Exception as e:
                return tag.a(sha,
                             class_='missing changeset',
                             title=to_unicode(e),
                             rel='nofollow')

        if name == 'Branches':
            branches = props[name]

            # simple non-merge commit
            return tag(*intersperse(', ', (sha_link(rev, label)
                                           for label, rev in branches)))

        elif name in ('Parents', 'Children'):
            revs = props[name]  # list of commit ids

            if name == 'Parents' and len(revs) > 1:
                # we got a merge...
                current_sha = context.resource.id
                reponame = context.resource.parent.id

                parent_links = intersperse(', ', \
                    ((sha_link(rev),
                      ' (',
                      tag.a('diff',
                            title="Diff against this parent (show the " \
                                  "changes merged from the other parents)",
                            href=context.href.changeset(current_sha, reponame,
                                                        old=rev)),
                      ')')
                     for rev in revs))

                return tag(
                    list(parent_links), tag.br(),
                    tag.span(tag(
                        "Note: this is a ", tag.strong("merge"), " changeset, "
                        "the changes displayed below "
                        "correspond to the merge itself."),
                             class_='hint'), tag.br(),
                    tag.span(tag(
                        "Use the ", tag.code("(diff)"),
                        " links above to see all the changes "
                        "relative to each parent."),
                             class_='hint'))

            # simple non-merge commit
            return tag(*intersperse(', ', map(sha_link, revs)))

        elif name in ('git-committer', 'git-author'):
            user_, time_ = props[name]
            _str = "%s (%s)" % (Chrome(self.env).format_author(
                context.req,
                user_), format_datetime(time_, tzinfo=context.req.tz))
            return unicode(_str)

        raise TracError("Internal error")
示例#48
0
 def get_navigation_items(self, req):
     rm = RepositoryManager(self.env)
     if any(repos.is_viewable(req.perm) for repos
                                        in rm.get_real_repositories()):
         yield ('mainnav', 'browser',
                tag.a(_('Browse Source'), href=req.href.browser()))
示例#49
0
 def default_renderer(tag, count, percent):
     href = self.get_href(req, realms, tag=Resource('tag', tag))
     return builder.a(tag, rel='tag', title='%i' % count,
                      href=href, style='font-size: %ipx'
                      % int(min_px + percent * (max_px - min_px)))
示例#50
0
    def process_request(self, req):
        presel = req.args.get('preselected')
        if presel and (presel + '/').startswith(req.href.browser() + '/'):
            req.redirect(presel)

        path = req.args.get('path', '/')
        rev = req.args.get('rev', '')
        if rev.lower() in ('', 'head'):
            rev = None
        format = req.args.get('format')
        order = req.args.get('order', 'name').lower()
        desc = 'desc' in req.args
        xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest'

        rm = RepositoryManager(self.env)
        all_repositories = rm.get_all_repositories()
        reponame, repos, path = rm.get_repository_by_path(path)

        # Repository index
        show_index = not reponame and path == '/'
        if show_index:
            if repos and (as_bool(all_repositories[''].get('hidden'))
                          or not repos.is_viewable(req.perm)):
                repos = None

        if not repos and reponame:
            raise ResourceNotFound(_("Repository '%(repo)s' not found",
                                     repo=reponame))

        if reponame and reponame != repos.reponame: # Redirect alias
            qs = req.query_string
            req.redirect(req.href.browser(repos.reponame or None, path)
                         + ('?' + qs if qs else ''))
        reponame = repos.reponame if repos else None

        # Find node for the requested path/rev
        context = web_context(req)
        node = None
        changeset = None
        display_rev = lambda rev: rev
        if repos:
            try:
                if rev:
                    rev = repos.normalize_rev(rev)
                # If `rev` is `None`, we'll try to reuse `None` consistently,
                # as a special shortcut to the latest revision.
                rev_or_latest = rev or repos.youngest_rev
                node = get_existing_node(req, repos, path, rev_or_latest)
            except NoSuchChangeset as e:
                raise ResourceNotFound(e.message,
                                       _('Invalid changeset number'))
            if node:
                try:
                    # use changeset instance to retrieve branches and tags
                    changeset = repos.get_changeset(node.rev)
                except NoSuchChangeset:
                    pass

            context = context.child(repos.resource.child('source', path,
                                                   version=rev_or_latest))
            display_rev = repos.display_rev

        # Prepare template data
        path_links = get_path_links(req.href, reponame, path, rev,
                                    order, desc)

        repo_data = dir_data = file_data = None
        if show_index:
            repo_data = self._render_repository_index(
                                        context, all_repositories, order, desc)
        if node:
            if not node.is_viewable(req.perm):
                raise PermissionError('BROWSER_VIEW' if node.isdir else
                                      'FILE_VIEW', node.resource, self.env)
            if node.isdir:
                if format in ('zip',): # extension point here...
                    self._render_zip(req, context, repos, node, rev)
                    # not reached
                dir_data = self._render_dir(req, repos, node, rev, order, desc)
            elif node.isfile:
                file_data = self._render_file(req, context, repos, node, rev)

        if not repos and not (repo_data and repo_data['repositories']):
            # If no viewable repositories, check permission instead of
            # repos.is_viewable()
            req.perm.require('BROWSER_VIEW')
            raise ResourceNotFound(_("No node %(path)s", path=path))

        quickjump_data = properties_data = None
        if node and not xhr:
            properties_data = self.render_properties(
                    'browser', context, node.get_properties())
            quickjump_data = list(repos.get_quickjump_entries(rev))

        data = {
            'context': context, 'reponame': reponame, 'repos': repos,
            'repoinfo': all_repositories.get(reponame or ''),
            'path': path, 'rev': node and node.rev, 'stickyrev': rev,
            'display_rev': display_rev, 'changeset': changeset,
            'created_path': node and node.created_path,
            'created_rev': node and node.created_rev,
            'properties': properties_data,
            'path_links': path_links,
            'order': order, 'desc': 1 if desc else None,
            'repo': repo_data, 'dir': dir_data, 'file': file_data,
            'quickjump_entries': quickjump_data,
            'wiki_format_messages': \
                self.config['changeset'].getbool('wiki_format_messages'),
            'xhr': xhr,
        }
        if xhr: # render and return the content only
            return 'dir_entries.html', data, None

        if dir_data or repo_data:
            add_script(req, 'common/js/expand_dir.js')
            add_script(req, 'common/js/keyboard_nav.js')

        # Links for contextual navigation
        if node:
            if node.isfile:
                prev_rev = repos.previous_rev(rev=node.created_rev,
                                              path=node.created_path)
                if prev_rev:
                    href = req.href.browser(reponame,
                                            node.created_path, rev=prev_rev)
                    add_link(req, 'prev', href,
                             _('Revision %(num)s', num=display_rev(prev_rev)))
                if rev is not None:
                    add_link(req, 'up', req.href.browser(reponame,
                                                         node.created_path))
                next_rev = repos.next_rev(rev=node.created_rev,
                                          path=node.created_path)
                if next_rev:
                    href = req.href.browser(reponame, node.created_path,
                                            rev=next_rev)
                    add_link(req, 'next', href,
                             _('Revision %(num)s', num=display_rev(next_rev)))
                prevnext_nav(req, _('Previous Revision'), _('Next Revision'),
                             _('Latest Revision'))
            else:
                if path != '/':
                    add_link(req, 'up', path_links[-2]['href'],
                             _('Parent directory'))
                add_ctxtnav(req, tag.a(_('Last Change'),
                            href=req.href.changeset(node.created_rev, reponame,
                                                    node.created_path)))
            if node.isfile:
                annotate = data['file']['annotate']
                if annotate:
                    add_ctxtnav(req, _('Normal'),
                                title=_('View file without annotations'),
                                href=req.href.browser(reponame,
                                                      node.created_path,
                                                      rev=rev))
                if annotate != 'blame':
                    add_ctxtnav(req, _('Blame'),
                                title=_('Annotate each line with the last '
                                        'changed revision '
                                        '(this can be time consuming...)'),
                                href=req.href.browser(reponame,
                                                      node.created_path,
                                                      rev=rev,
                                                      annotate='blame'))
            add_ctxtnav(req, _('Revision Log'),
                        href=req.href.log(reponame, path, rev=rev))
            path_url = repos.get_path_url(path, rev)
            if path_url:
                if path_url.startswith('//'):
                    path_url = req.scheme + ':' + path_url
                add_ctxtnav(req, _('Repository URL'), href=path_url)

        add_stylesheet(req, 'common/css/browser.css')
        return 'browser.html', data, None
示例#51
0
    def _do_login(self, req):
        """Log the remote user in.

        This function expects to be called when the remote user name
        is available. The user name is inserted into the `auth_cookie`
        table and a cookie identifying the user on subsequent requests
        is sent back to the client.

        If the Authenticator was created with `ignore_case` set to
        true, then the authentication name passed from the web server
        in req.remote_user will be converted to lower case before
        being used. This is to avoid problems on installations
        authenticating against Windows which is not case sensitive
        regarding user names and domain names
        """
        if not req.remote_user:
            # TRANSLATOR: ... refer to the 'installation documentation'. (link)
            inst_doc = tag.a(_('installation documentation'),
                             title=_("Configuring Authentication"),
                             href=req.href.wiki('TracInstall') +
                             "#ConfiguringAuthentication")
            raise TracError(
                tag_(
                    "Authentication information not available. "
                    "Please refer to the %(inst_doc)s.",
                    inst_doc=inst_doc))
        remote_user = req.remote_user
        if self.ignore_case:
            remote_user = remote_user.lower()

        if req.authname not in ('anonymous', remote_user):
            raise TracError(
                _('Already logged in as %(user)s.', user=req.authname))

        with self.env.db_transaction as db:
            # Delete cookies older than 10 days
            db("DELETE FROM auth_cookie WHERE time < %s",
               (int(time.time()) - 86400 * 10, ))
            # Insert a new cookie if we haven't already got one
            cookie = None
            trac_auth = req.incookie.get('trac_auth')
            if trac_auth is not None:
                name = self._cookie_to_name(req, trac_auth)
                cookie = trac_auth.value if name == remote_user else None
            if cookie is None:
                cookie = hex_entropy()
                db(
                    """
                    INSERT INTO auth_cookie (cookie, name, ipnr, time)
                         VALUES (%s, %s, %s, %s)
                   """,
                    (cookie, remote_user, req.remote_addr, int(time.time())))
        req.authname = remote_user
        req.outcookie['trac_auth'] = cookie
        req.outcookie['trac_auth']['path'] = self.auth_cookie_path \
                                             or req.base_path or '/'
        if self.env.secure_cookies:
            req.outcookie['trac_auth']['secure'] = True
        req.outcookie['trac_auth']['httponly'] = True
        if self.auth_cookie_lifetime > 0:
            req.outcookie['trac_auth']['expires'] = self.auth_cookie_lifetime
示例#52
0
 def repolink(reponame, repos):
     label = reponame or _('(default)')
     return Markup(tag.a(label,
                   title=_('View repository %(repo)s', repo=label),
                   href=formatter.href.browser(repos.reponame or None)))
        counter = 0

        for o in self.rows:
            if counter % 2 == 1:
                class_ = 'odd'
            else:
                class_ = 'even'
            counter += 1
            tr = tag.tr(class_=class_)

            tr(
                tag.td(
                    tag.h5(
                        tag.a(o,
                              href=self.macroenv.tracenv.href() +
                              ('/query?%s=%s&order=status' % (
                                  self.rowtype,
                                  o,
                              ))))))  # query owner's tickets
            countStatus = {}  # summarize the status of a ticket
            for segment in self.segments:
                class_ = ''
                if calendar[segment]['date'] == currentDate:  # Today
                    class_ = 'today'
                elif calendar[segment]['isocalendar'][2] == 6:  # Saturday
                    class_ = 'saturday'
                elif calendar[segment]['isocalendar'][2] == 7:  # Sunday
                    class_ = 'sunday'
                td_div = tag.div()

                # only show the highlight, if the date is in the past
                color_class = ''
示例#54
0
    def expand_macro(self, formatter, name, content):
        args, kw = parse_args(content)
        prefix = args[0].strip() if args else None
        hideprefix = args and len(args) > 1 and args[1].strip() == 'hideprefix'
        minsize = max(int(kw.get('min', 2)), 2)
        depth = int(kw.get('depth', -1))
        start = prefix.count('/') if prefix else 0
        format = kw.get('format', '')

        def parse_list(name):
            return [inc.strip() for inc in kw.get(name, '').split(':')
                    if inc.strip()]

        includes = parse_list('include') or ['*']
        excludes = parse_list('exclude')

        if hideprefix:
            omitprefix = lambda page: page[len(prefix):]
        else:
            omitprefix = lambda page: page

        wiki = formatter.wiki

        pages = sorted(page for page in wiki.get_pages(prefix)
                       if (depth < 0 or depth >= page.count('/') - start)
                       and 'WIKI_VIEW' in formatter.perm('wiki', page)
                       and any(fnmatchcase(page, inc) for inc in includes)
                       and not any(fnmatchcase(page, exc) for exc in excludes))

        if format == 'compact':
            return tag(
                separated((tag.a(wiki.format_page_name(omitprefix(p)),
                                 href=formatter.href.wiki(p)) for p in pages),
                          ', '))

        # the function definitions for the different format styles

        # the different page split formats, each corresponding to its rendering
        def split_pages_group(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted at Camel Case word boundaries, numbers and '/'.
            """
            page_paths = []
            for page in pages:
                path = [elt.rstrip('/').strip() for elt in self.SPLIT_RE.split(
                        wiki.format_page_name(omitprefix(page), split=True))]
                page_paths.append(([elt for elt in path if elt], page))
            return page_paths

        def split_pages_hierarchy(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted according to the '/' hierarchy.
            """
            return [(wiki.format_page_name(omitprefix(page)).split("/"), page)
                    for page in pages]

        # create the group hierarchy (same for group and hierarchy formats)
        def split_in_groups(entries):
            """Transform a flat list of entries into a tree structure.
            
            `entries` is a list of `(path_elements, page_name)` pairs
            
            Return a list organized in a tree structure, in which:
              - a leaf is a page name
              - a node is a `(key, nodes)` pairs, where:
                - `key` is the leftmost of the path elements, common to the
                  grouped (path element, page_name) entries
                - `nodes` is a list of nodes or leaves
            """
            groups = []

            for key, grouper in groupby(entries, lambda (elts, name):
                                                    elts[0] if elts else ''):
                # remove key from path_elements in grouped entries for further
                # grouping
                grouped_entries = [(path_elements[1:], page_name)
                                   for path_elements, page_name in grouper]
                if key and len(grouped_entries) >= minsize:
                    subnodes = split_in_groups(sorted(grouped_entries))
                    if len(subnodes) == 1:
                        subkey, subnodes = subnodes[0]
                        node = (key + subkey, subnodes) # FIXME
                    else:
                        node = (key, subnodes)
                    groups.append(node)
                else:
                    for path_elements, page_name in grouped_entries:
                        groups.append(page_name)
            return groups
示例#55
0
 def get_navigation_items(self, req):
     if 'ROADMAP_VIEW' in req.perm:
         yield ('mainnav', 'pdashboard',
                tag.a('Metrics', href=req.href.pdashboard()))
 def expand_macro(self, formatter, name, text, args):
     try:
         comment = Comments(formatter.req, formatter.env).by_id(text)
         return tag.a(comment.link_text(), href=comment.href())
     except:
         return ''
示例#57
0
 def get_navigation_items(self, req):
     yield ('metanav', 'prefs',
            tag.a(_('Preferences'), href=req.href.prefs()))
示例#58
0
 def get_navigation_items(self, req):
     if 'ROADMAP_VIEW' in req.perm:
         yield ('mainnav', 'roadmap',
                tag.a(_('Roadmap'), href=req.href.roadmap(), accesskey=3))
示例#59
0
    def process_request(self, req):
        #ok, what are we about.
        #db = self.env.get_db_cnx()
        #ticketlist = {}  # dict of ticket->???
        #revlist = {} # dict of revision->
        repos = self.env.get_repository()

        new_path = req.args.get('new_path')
        new_rev = req.args.get('new')
        old_path = req.args.get('old_path')
        old_rev = req.args.get('old')

        new_path = repos.normalize_path(new_path)
        new_rev = repos.normalize_rev(new_rev)
        old_path = repos.normalize_path(old_path)
        old_rev = repos.normalize_rev(old_rev)

        #        if not req.perm.has_permission('TICKET_MODIFY'):
        #            return req.redirect(req.href.browser())

        old_rev = int(old_rev)
        new_rev = int(new_rev)

        ticket = req.args.get('ticket')
        try:
            ticket = int(ticket)
        except Exception:
            ticket = 0
#        req.hdf['review.ticket'] = ticket
#        req.hdf['review.tickethtml'] = tag.a(ticket, req.href.ticket(ticket))

        data = {}

        data['overall_y'] = 0
        data['ticket_id'] = req.args['ticket']
        data['ticket_href'] = req.href.ticket(req.args['ticket'])

        ticket_mgr = TicketManager(self.compmgr)

        db = self.env.get_db_cnx()
        repos = self.env.get_repository()

        revs = ticket_mgr.tkt2revs(self.log, db, repos, req,
                                   req.args['ticket'])

        if (not revs or len(revs) == 0):
            # nothing to review. shouldn't happen
            return ('nothing.html', data, 'text/html')
        elif (len(revs) == 1):
            # only one change - just do a changeset view
            return req.redirect(req.href.changeset(revs[0]))

        revcount = 0
        branches = {}
        files = {}
        # may be 0 revs.
        revisions = []

        for rev in revs:
            chgset = repos.get_changeset(rev)
            # q: (u'trunk/Locale.java', 'file', 'add', None, u'-1')  from r3
            # q: (u'trunk/util.c', 'file', 'edit', u'trunk/util.c', u'2')  from r4
            message = chgset.message or '--'
            revcount = revcount + 1
            revision = {}
            revision['rev'] = tag.a(rev, req.href.changeset(rev))
            revision['author'] = chgset.author
            revision['num'] = rev
            revision[
                'comment'] = message  #wiki_to_oneliner( message, self.env, db, shorten=False )
            rbranches = revision['branches'] = []
            for chg in chgset.get_changes():
                path = chg[0]
                if path in files:
                    item = files[path]
                else:
                    item = []
                    files[path] = item
                item.append(self.changeToRange(rev, chg))
                branch_name = self.pathToBranchName(path)
                if branch_name not in rbranches:
                    rbranches.append(branch_name)
            revisions.append(revision)
        data['revisions'] = revisions

        if (revcount > 0):
            data['revcount'] = revcount

        # print "files: %d" % len(files)
        # go throuhg each file and calculate its minimum range
        filelist = files.keys()
        filelist.sort()
        #        print 'bar to %d len of %s' % (len(filelist),str(filelist))
        for file in filelist:
            changes = files[file]
            i = 0
            #            print " looping from %d to %d over %d " % (i,len(changes)-1,len(changes))
            while len(changes) > 1 and i < (len(changes) - 1):
                if changes[i][1] == changes[i + 1][0]:
                    if changes[i][0] == -1:
                        changes[i + 1] = (changes[i][0], changes[i + 1][1],
                                          'add+commits')  # retain 'first' rev
                    else:
                        changes[i + 1] = (changes[i][0], changes[i + 1][1],
                                          'multiple commits'
                                          )  # retain 'first' rev

                    changes = changes[:i] + changes[i + 1:]  # and shift down
                    #                    print "merged: %s" % str(changes)
                    files[file] = changes
                else:
                    i = i + 1

        # now, write 'em out
        sera = 0
        #files_data = []
        for file in filelist:
            sera = sera + 1
            file_data = {}
            file_data['name'] = Markup('<a href="%s">%s</a>' %
                                       (req.href.browser(file), file))
            branch_name = self.pathToBranchName(file)
            #print "branch is: (%s)" % (branch_name)
            branches_data = branches.get(branch_name, {})
            files_data = branches_data.get('files', [])

            changes = files[file]
            cha = 0
            changes_data = []
            for change in changes:
                cha = cha + 1
                #                print "%s output %s " % (file, str(change))
                changes_data.append(self.describeChange(file, change, req, db))
            file_data['changes'] = changes_data
            if (len(changes) > 1):
                whathtml = self.describeChange(
                    file,
                    (changes[0][0], changes[len(changes) - 1][1], 'overall'),
                    req, db)
                file_data['overall'] = whathtml
                file_data['overall_y'] = 1
                data['overall_y'] = 1
            else:
                file_data['overall_y'] = 0
            files_data.append(file_data)
            # sets
            branches_data['files'] = files_data
            branches_data['len'] = len(files_data)
            branches_data['name'] = branch_name
            branches[branch_name] = branches_data

        # .. convert dict to array.
        branch_list = []
        for branch in branches:
            branch_list.append(branches[branch])
        data['branches'] = branch_list
        data['lastbranch'] = branch
        data['branchcount'] = len(branches)

        content_type = "text/html"
        add_stylesheet(req, 'icucodetools/css/icuxtn.css')
        add_script(req, 'icucodetools/js/review.js')
        return 'review.html', data, content_type
示例#60
0
  def render(self, ticketset):
    '''
      Generate HTML List
    '''
    (counttickets,ticketgrouping) = self.getTicketGrouping( ticketset )
    
    if counttickets == 0:
      return self.divWarning('No tickets available.')
   
    maxTicketsToShow = 20
    maxWidth = 400
    statuskeys = ticketgrouping.keys()
    (width,height) = self.getDimensions()
    
    framewrapper = tag.div(style="width:%spx;" % (width+10+(2*len(statuskeys)),) ) # ensures the width if the browser window is to small
    framebar = tag.div(class_="clearfix",style="height:%spx; background-color: #333; box-shadow: 4px 4px 4px #999; display: inline-block; white-space:nowrap; border: 1px solid #333; float: left;" % (height,) )
    js = tag.script()
    framebox = tag.div()
    currentPosition = 0 # offset
    myId = self.getStrongKey()
    orderedStatusKeys = self.getOrderedStatusKeys(self.orderOrg, statuskeys)
    
    for statuskey in orderedStatusKeys :
      groupingCount = len(ticketgrouping[statuskey])
      groupingPercent = int(round(float(groupingCount) / float(counttickets) * 100)) 
      groupingWidth = int(round(float(groupingCount) / float(counttickets) * width ))
      groupingColor = self.macroenv.conf.get_map_val('ColorForStatus', statuskey )

      barId = myId+'_bar_'+statuskey
      boxId = myId+'_box_'+statuskey
      
      statusTicketsWidth = max(groupingWidth,maxWidth)-10
      statusTickets = tag.div(id=boxId, style='width:%spx; border:1px solid %s;display:none;position:absolute;left:%spx;background-color:#FFF;padding:0.5ex;margin:0.5ex;box-shadow:4px 4px 4px #AAA;' % (statusTicketsWidth,groupingColor,currentPosition))
      ticketids = ticketgrouping[statuskey].keys()
      ticketids.sort(reverse=True)
      ticketTable = tag.table()
      for tid in ticketids[0:maxTicketsToShow]:
        ticketTable(tag.tr(tag.td(self.createTicketLink(ticketset.getTicket(tid))), tag.td(ticketgrouping[statuskey][tid], style="max-width:%spx"%(min(max(maxWidth,groupingWidth),width),)) ))
      # show the number of left out tickets
      if len(ticketids) > maxTicketsToShow :
        ticketTable(tag.tr(tag.td('...'),tag.td('%s more tickets' % (len(ticketids)-maxTicketsToShow,))))
      
      if groupingCount==1:
        ticketString = 'ticket'
      else:
        ticketString = 'tickets'

      statusTickets(tag.div(tag.div('%s %s: %s' % (groupingCount,ticketString,statuskey),style="float:left;font-weight:bold;"),tag.div(tag.a('X',href="javascript: return false;"),id="%s%s" % (boxId,"close"),style="float:right",class_="ppinsetshadow"),class_="clearFix"),ticketTable)

      framebar( tag.div( '', id=barId, style="float:left;border:1px solid #333;width:%spx; height:%spx; %s;" % (groupingWidth,height,self.getCSSgradient(groupingColor)) ) )
      framebox( statusTickets, style="position:absolute;" )
      # if clicked, show permanently; until clicked again; ppStore stores the current click state
      js('''$("#%s").mouseover(function() {
	  $("#%s").slideDown(200, function() {});  
	  });''' % (barId,boxId))
      js('''$("#%s").mouseout(function() { 
	  if(ppStore["%s"] == 0 || isNaN(ppStore["%s"])){ $("#%s").slideUp(400, function() {});  } 
	  }); ''' % (barId,barId,barId,boxId))
      js('''$("#%s").mouseup(function() { 
	  if ( isNaN(ppStore["%s"]) ) { ppStore["%s"]=0; }
	  ppStore["%s"] = (ppStore["%s"]+1) %% 2
	  if( ppStore["%s"] ==  1 ){ $("#%s").slideDown(100, function() {});  }
	  else { $("#%s").slideUp(100, function() {});  }
	  });''' % (barId,barId,barId,barId,barId,barId,boxId,boxId))
      js('''$("#%sclose").click(function() {
	  $("#%s").slideUp(100, function() {});  
	  });''' % (boxId,boxId))
      #js('$("#%s").mouseenter().mouseleave(function() {$("#%s").hide();  });' % (boxId,boxId))
      
      currentPosition += groupingWidth + 2 # offset is 2px
     
    return tag.div(framewrapper(framebar),tag.div(style="clear:both;"),framebox,js)