예제 #1
0
    def filter_stream(self, req, method, filename, stream, data):
        """Return a filtered Genshi event stream, or the original unfiltered
        stream if no match.

        `req` is the current request object, `method` is the Genshi render
        method (xml, xhtml or text), `filename` is the filename of the template
        to be rendered, `stream` is the event stream and `data` is the data for
        the current template.

        See the Genshi documentation for more information.
        """
        if filename == 'ticket.html':
            ticket = data['ticket']
            if ticket.exists:
                if req.perm.has_permission('SENSITIVE_VIEW'):
                    qry = DBSession().query(CustomerRequest)
                    if not qry.get(ticket.values.get('customerrequest')).active:
                        div = tag.div(
                            tag.div(
                                tag.strong(u'Heads up! '),
                                tag.span(u'This ticket is assigned to an inactive customer request.',),
                                class_="alert alert-info"),
                            id='inactive_cr_ticket')
                        return stream | Transformer("//div[@id='ticket']").before(div)
        return stream
예제 #2
0
    def filter_stream(self, req, method, filename, stream, data):
        """
        Wrap the banner and mainnav in a single banner_wrapper div
        """

        add_stylesheet(req, "http://fonts.googleapis.com/css?family=Ubuntu")
        add_stylesheet(req, "lightertheme/theme.css")

        stream |= Transformer("//div[@id='banner']").wrap(tag.div(class_="banner_wrapper banner_wrapper_first"))
        stream |= Transformer("//div[@id='mainnav']").wrap(tag.div(class_="banner_wrapper banner_wrapper_second"))
        stream |= Transformer("//div[@class='banner_wrapper banner_wrapper_first']").append(tag.hr())
        return stream

        filter = Transformer("//div[@id='banner']")
        stream |= (
            filter.wrap(tag.div(id="banner_wrapper"))
            .end()
            .select("//div[@id='mainnav']")
            .cut(buffer, accumulate=True)
            .end()
            .buffer()
            .select("//div[@id='banner_wrapper']")
            .append(tag.hr())
            .append(buffer)
            .end()
        )

        return stream
    def filter_stream(self, req, method, filename, stream, data):
        if filename == 'browser.html' and req.method == 'GET':

            # we can only work from the 'dir' view at the moment
            if data.get('file'):
                return stream

            # TODO check that contextmenu's InternalNameHolder is enabled, as our js needs it?
            add_stylesheet(req, 'sourcesharer/filebox.css')
            add_javascript(req, 'sourcesharer/filebox.js')
            # Render the filebox template for stream insertion

            # TODO introduce a new interface to allow putting extra buttons into this filebox?
            tmpl = TemplateLoader(self.get_templates_dirs()).load('filebox.html')
            filebox = tmpl.generate(href=req.href, reponame=data['reponame'] or '', rev=data['rev'], files=[])
            # Wrap and float dirlist table, add filebox div
            # TODO change the id names, left/right seems a bit generic to assume we can have to ourselves
            stream |= Transformer('//table[@id="dirlist"]').wrap(tag.div(id="outer",style="clear:both")).wrap(tag.div(id="left"))
            stream |= Transformer('//div[@id="outer"]').append(tag.div(filebox, id="right"))

            is_svn_repo = False
            if 'repos' in data:
                is_svn_repo = isinstance(data.get('repos'), 
                                    (SvnCachedRepository, 
                                    SubversionRepository)) or False
            if is_svn_repo:
                add_ctxtnav(req, tag.a(_(tag.i(class_="fa fa-envelope-o")), " Send", href="", title=_("Send selected files"), id='share-files', class_='alt-button share-files-multiple'),
                    category='ctxtnav', order=10)

        return stream
예제 #4
0
 def _render_full_format(self, formatter, post_list, post_instances,
                         heading, max_size, show_meta):
     """ Renters full blog posts. """
     out = tag.div(class_="blog")
     out.append(tag.div(heading, class_="blog-list-title"))
     for post in post_instances:
         data = {
             'post':
             post,
             'blog_personal_blog':
             self.config.getbool('fullblog', 'personal_blog'),
             'list_mode':
             True,
             'show_meta':
             show_meta,
             'execute_blog_macro':
             True
         }
         if max_size:
             data['blog_max_size'] = max_size
         out.append(
             Chrome(self.env).render_template(formatter.req,
                                              'fullblog_macro_post.html',
                                              data=data,
                                              fragment=True))
     return out
예제 #5
0
 def expand_macro(self, formatter, name, content, args=None):
     hint = '|| yyyy-mm-ddThh:mm:ss || yyyy-mm-ddThh:mm:ss || message'
     pattern = "\s*||(.*)||(.*)||(.*)".replace('|', '\|')
     pattern = re.compile(pattern)
     try:
         if content == None:
             return tag.div('ShowWhen Macro is not supported. Use WikiProcessor-style instead.', \
                            class_="system-message")
         now = datetime.now(utc)
         for line in content.split('\n'):
             matched = pattern.match(line)
             if matched:
                 result = matched.groups()
                 by, to, text = result
                 by, to = parse_date(by, None,
                                     hint), parse_date(to, None, hint)
                 self.env.log.debug('parsed time range: %s / %s' % (by, to))
                 if by <= now and now <= to:
                     return format_to_html(self.env, formatter.context,
                                           text)
         return None
     except Exception, e:
         return tag.div(tag.strong(e.title),
                        ': ' + e.message,
                        class_="system-message")
예제 #6
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
예제 #7
0
    def _reminder_tags(self, req, data):
        if 'ticket' not in data or not data['ticket'].id:
            return None

        ticket = data['ticket']

        if ticket['status'] == 'closed':
            return None

        li_tags = [tag.li(self._format_reminder(req, ticket, *args)) for args in self._get_reminders(ticket.id)]
        if li_tags:
            list_tags = tag.ul(li_tags, class_="reminders")
        else:
            list_tags = []

        add_form = self._reminder_add_form(req)

        if not list_tags and not add_form:
            return None

        return \
            tag.div(
                tag.h2("Reminders", class_="foldable"),
                tag.div(
                    list_tags,
                    add_form,
                ),
                id="reminders",
            )
예제 #8
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.get_header("X-Moz") == "prefetch":
         return stream
     if filename == "ticket.html":
         if not self.check_permissions(req):
             return stream
         chrome = Chrome(self.env)
         filter = Transformer('//fieldset[@id="properties"]')
         # add a hidden div to hold the ticket_fields input
         snippet = tag.div(style="display:none;")
         snippet = tag.input(type="hidden", id="field-ticket_fields", name="field_ticket_fields", value=','.join(data['ticket_fields']))
         stream = stream | filter.after(snippet)
         if req.path_info != '/newticket':
             # insert the ticket field groups after the standard trac 'Change Properties' field group
             stream = stream | filter.after(chrome.render_template(req, 'ticket_fields_datatable.html', data, fragment=True))
     elif filename == "admin_enums.html":
         if not self.check_permissions(req) or not req.args.get('path_info'):
             return stream
         for k,v in {'cat_id':'ticket', 'panel_id':'type'}.iteritems():
             if k not in req.args or req.args.get(k) != v:
                 return stream
         if 'ticket_fields' in data:
             chrome = Chrome(self.env)
             filter = Transformer('//div[@class="buttons"]')
             # add a hidden div to hold the ticket_fields input
             snippet = tag.div(style="display:none;")
             snippet = tag.input(type="hidden", id="field-ticket_fields", name="field_ticket_fields", value=','.join(data['ticket_fields']))
             stream = stream | filter.before(snippet)
             stream = stream | filter.before(chrome.render_template(req, 'ticket_fields_datatable.html', data, fragment=True))
     return stream
예제 #9
0
  def render_statistics(self,ticketlist):
    # fallback if preconditions are not holding
    if len(ticketlist) == 0 or self.statistics_fields == []:
      return tag.span()
    
    # create a new map 
    statistics_values = {}
    for field in self.statistics_fields:
      statistics_values[field] = 0
    
    # map containing titles
    field_titles = {}
    for field in self.statistics_fields:
      field_titles[field] = 'sum of "%s"' % (field,)
    
    # summarize the field values of each ticket
    html = tag.div()
    for ticket in ticketlist:
      for field in self.statistics_fields:
        try:
          statistics_values[field] += int(ticket.getfield(field))
        except:
          field_titles[field] = '"%s" could not be parsed to number' % (field,)

    # create html construct
    separator = ''
    for field in self.statistics_fields:
      html(separator, tag.span('%s' % (statistics_values[field],), title=field_titles[field]) )
      separator = '/'

    return tag.div(html, class_='pptableticketperdaystatistics')
예제 #10
0
    def process_request(self, req):
        """Redirect to pre-selected target."""
        if self.redirect_target or self._check_redirect(req):
            target = self.redirect_target

            # Check for self-redirect:
            if target and target == req.href(req.path_info):
                message = tag.div('Please ',
                                  tag.a("change the redirect target",
                                        href=target + "?action=edit"),
                                  ' to another page.',
                                  class_="system-message")
                data = {
                    'title': "Page redirects to itself!",
                    'message': message,
                    'type': 'TracError',
                }
                req.send_error(data['title'],
                               status=409,
                               env=self.env,
                               data=data)
                raise RequestDone

            # Check for redirect pair, i.e. A->B, B->A
            if target and target == req.href.wiki(
                    req.args.get('redirectedfrom', '')):
                message = tag.div(
                    'Please change the redirect target from either ',
                    tag.a("this page",
                          href=req.href(req.path_info, action="edit")),
                    ' or ',
                    tag.a("the redirecting page",
                          href=target + "?action=edit"),
                    '.',
                    class_="system-message")
                data = {
                    'title': "Redirect target redirects back to this page!",
                    'message': message,
                    'type': 'TracError',
                }
                req.send_error(data['title'],
                               status=409,
                               env=self.env,
                               data=data)
                raise RequestDone

            # Add back link information for internal links:
            if target and target[0] == '/':
                redirectfrom = "redirectedfrom=" + req.path_info[6:]
                # anchor should be the last in url
                # according to http://trac.edgewall.org/ticket/8072
                tgt, query, anchor = self.split_link(target)
                if not query:
                    query = "?" + redirectfrom
                else:
                    query += "&" + redirectfrom
                target = tgt + query + anchor
            req.redirect(target)
            raise RequestDone
        raise TracError("Invalid redirect target!")
예제 #11
0
  def render_statistics(self,ticketlist):
    # fallback if preconditions are not holding
    if len(ticketlist) == 0 or self.statistics_fields == []:
      return tag.span()
    
    # create a new map 
    statistics_values = {}
    for field in self.statistics_fields:
      statistics_values[field] = 0
    
    # map containing titles
    field_titles = {}
    for field in self.statistics_fields:
      field_titles[field] = 'sum of "%s"' % (field,)
    
    # summarize the field values of each ticket
    html = tag.div()
    for ticket in ticketlist:
      for field in self.statistics_fields:
        try:
          statistics_values[field] += int(ticket.getfield(field))
        except:
          field_titles[field] = '"%s" could not be parsed to number' % (field,)

    # create html construct
    separator = ''
    for field in self.statistics_fields:
      html(separator, tag.span('%s' % (statistics_values[field],), title=field_titles[field]) )
      separator = '/'

    return tag.div(html, class_='pptableticketperdaystatistics')
예제 #12
0
    def _reminder_tags(self, req, data):
        if 'ticket' not in data or not data['ticket'].id:
            return None

        ticket = data['ticket']

        if ticket['status'] == 'closed':
            return None

        li_tags = [
            tag.li(self._format_reminder(req, ticket, *args))
            for args in self._get_reminders(ticket.id)
        ]
        if li_tags:
            list_tags = tag.ul(li_tags, class_="reminders")
        else:
            list_tags = []

        add_form = self._reminder_add_form(req)

        if not list_tags and not add_form:
            return None

        return \
            tag.div(
                tag.h2("Reminders", class_="foldable"),
                tag.div(
                    list_tags,
                    add_form,
                ),
                id="reminders",
            )
예제 #13
0
파일: monit.py 프로젝트: kopernikus/systrac
 def render_timeline_event(self, context, field, event):
     #self.log.debug("Monit: render_timeline_event() called")
     evt, srv, monit = event[3]
     if field == 'url':
         return context.href.monit('event', evt['id'])
     elif field == 'title':
         return tag(tag.em('New ', srv_types.get(evt['type'], ''), ' event'))
     elif field == 'description':
         if srv and monit:
             markup = tag.div('Event on ', tag.b(monit['localhostname']),
                              ' for service ', tag.b(srv['name']), '(type %s) ' % srv_types.get(evt['type'], ''),
                               tag.em(evt['message']))
             self.log.debug("Monit markup for Timeline -> %s" % str(markup))
         elif srv:
             markup =  tag.div('Event on ', tag.b('unknown'), ' for service ',
                       tag.b(srv['name']), '(type %s) ' % srv_types.get(evt['type'], ''),
                       tag.em(evt['message']))
         else:
             markup = tag.div('Event on ', tag.b('unknown'), ' for service ', 
                      tag.b('unknown'), '(type unknown)',
                      tag.em(evt['message']))
                      
             self.log.debug("Monit markup for Timeline -> %s" % str(markup))
             
         return markup
예제 #14
0
    def filter_stream(self, req, method, filename, stream, data):
        """
        Wrap the banner and mainnav in a single banner_wrapper div
        """

        add_stylesheet(req, 'http://fonts.googleapis.com/css?family=Ubuntu')
        add_stylesheet(req, 'lightertheme/theme.css')

        stream |= Transformer("//div[@id='banner']").wrap(
            tag.div(class_="banner_wrapper banner_wrapper_first"))
        stream |= Transformer("//div[@id='mainnav']").wrap(
            tag.div(class_="banner_wrapper banner_wrapper_second"))
        stream |= Transformer(
            "//div[@class='banner_wrapper banner_wrapper_first']").append(
                tag.hr())
        return stream

        filter = Transformer("//div[@id='banner']")
        stream |= filter.wrap(tag.div(
            id="banner_wrapper")).end().select("//div[@id='mainnav']").cut(
                buffer, accumulate=True).end().buffer().select(
                    "//div[@id='banner_wrapper']").append(
                        tag.hr()).append(buffer).end()

        return stream
    def render_ticket_action_control(self, req, ticket, action):
        config = self.parse_config()
        assert action in config

        control = []
        hints = []

        data = config[action]
        
        action_name = action # @@TODO: config'able label/name

        chrome = Chrome(self.env)

        from trac.ticket.web_ui import TicketModule
        prepared_fields = TicketModule(self.env)._prepare_fields(req, ticket)

        for field in data.get('fields', []):
            id = "action_%s_%s" % (action, field)

            operation = data.get('operations', {}).get(field, "change")
            assert operation in ["change", "unset"]
            if operation == "unset":
                hints.append("%s will be unset" % field) # @@TODO: i18n
                continue
            assert operation == "change"
            current_value = ticket._old.get(field, ticket[field]) or ""

            rendered_control = ''
            prepared_field = [pfield for pfield in prepared_fields 
                              if pfield['name'] == field]
            if len(prepared_field):
                prepared_field = prepared_field[0]

                # we can't use chrome.render_template here, or it will blow away
                # key scripts like jquery.js and trac.js in the eventual 'primary' template
                # that's rendered by process_request
                template = chrome.load_template("ticket_fields.html", method="xhtml")
                rendered_control = template.generate(ticket=ticket, field=prepared_field)
                if rendered_control:
                    rendered_control = Markup(rendered_control)
            control.append(tag.label(field,
                                     rendered_control or tag.input(
                        name=id, id=id,
                        type='text', value=current_value)))

        current_status = ticket._old.get('status', ticket['status'])
        new_status = data['status'].get(current_status) or \
            data['status']['*']

        if new_status != '*':
            hints.append("Next status will be %s" % new_status) # @@TODO: i18n

        add_script(req, "workflow_ticketfields/workflow_ticketfields.js")
        return (action_name, tag.div(*[tag.div(element, style=("display: inline-block; "
                                                               "margin-right: 1em"))
                                       for element in control],
                                      class_="workflow_ticket_fields",
                                      style="margin-left: 2em; display: none"), 
                '. '.join(hints) + '.' if hints else '')
예제 #16
0
 def render_col_tree(self, req, col_root, model):
     return tag.div( 
         tag.div( 
             tag.a( 'Collapse All', href = '?#' ), ' | ',
             tag.a( 'Expand All', href = '?#' ), 
             id = 'sidetreecontrol', style = 'font-size:xx-small;'),
         tag.div( tag.a( 'Library', href = req.href.zotero('collection') ) ),      
         self.render_child_col( req, col_root, model ),
         id="coltree", class_="treeview")
    def render(self, ticketset):
        '''
      Generate HTML List
      TODO: improve computation of ticket set
    '''
        orderedtickets = {}
        field = 'due_close'
        weekdays = ['PLACEHOLDER', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']

        r = ''
        div = tag.div()

        div(class_=self.cssclass + ' projectplanrender')

        # check for missing parameters
        missingparameter = False
        if self.rows == []:
            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() == '':
            div(
                tag.div(
                    'Missing parameter "rowtype": specifies the ticket attribute that should be showed.',
                    class_='ppwarning'))
            missingparameter = True
        if self.segments == []:
            div(
                tag.div(
                    'Missing parameter: use a semicolon-separated list to input the "segments".',
                    class_='ppwarning'))
            missingparameter = True
        if missingparameter:
            return div

        # init the matrix
        for segment in self.segments:
            orderedtickets[segment] = {}
            for o in self.rows:
                orderedtickets[segment][o] = []

        # fill up matrix
        self.macroenv.tracenv.log.debug('number of tickets: ' +
                                        str(len(ticketset.getIDList())))
        for tid in ticketset.getIDList():
            try:
                ticket = ticketset.getTicket(tid)
                orderedtickets[ticket.getfield(field)][ticket.getfield(
                    self.rowtype)].append(ticket)
            except Exception, e:
                self.macroenv.tracenv.log.debug('fill up matrix: #' +
                                                str(tid) + ' ' + repr(e))
                pass
예제 #18
0
    def expand_macro(self, formatter, names, content):
        if not content:
            edit = ''
            text = "''Gringlet Name Missing''"
            acl = ''
        elif not re.match(r'^[a-zA-Z0-9]+$', content):
            edit = ''
            text = tag.em(
                "Invalid Gringlet Name - only letters and numbers allowed")
            acl = ''
        else:
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            cursor.execute(
                'SELECT text,acl FROM gringotts WHERE name=%s AND version='
                '(SELECT MAX(version) FROM gringotts WHERE name=%s)',
                (content, content))

        try:
            text, acl = cursor.fetchone()
            key = str(self.config.get('gringotts', 'key'))
            k = ezPyCrypto.key(key)
            text = wiki_to_html(k.decStringFromAscii(text), self.env,
                                formatter.req)
            edit = 'Edit'
        except:
            edit = 'Create'
            text = tag.em("No Gringlet called \"%s\" found" % content)
            acl = ''

        if acl:
            if not validate_acl(formatter.req, acl):
                text = tag.em(
                    "You do not have permission to view the \"%s\" Gringlet." %
                    content)
                edit = ''

        control = None
        if edit:
            control = tag.div(tag.a(edit,
                                    href=(formatter.href.gringotts() + "/" +
                                          content + "?action=edit")),
                              class_="gringottcontrol")

        # Use eight divs for flexible frame styling
        return tag.div(tag.div(tag.div(tag.div(tag.div(tag.div(
            tag.div(tag.div(tag.div(text, class_="gringottcontent") + control,
                            class_="gringott"),
                    class_="gringott"),
            class_="gringott"),
                                                       class_="gringott"),
                                               class_="gringott"),
                                       class_="gringott"),
                               class_="gringott"),
                       class_="gringottframe")
예제 #19
0
파일: wiki.py 프로젝트: nyuhuhuu/trachacks
  def expand_macro(self, formatter, names, content):
    if not content:
      edit = ''
      text = "''Gringlet Name Missing''"
      acl = ''
    elif not re.match(r'^[a-zA-Z0-9]+$', content):
      edit = ''
      text = tag.em("Invalid Gringlet Name - only letters and numbers allowed")
      acl = ''
    else:
      db = self.env.get_db_cnx()
      cursor = db.cursor()
      cursor.execute('SELECT text,acl FROM gringotts WHERE name=%s AND version='
                     '(SELECT MAX(version) FROM gringotts WHERE name=%s)',
                     (content, content))

    try:
      text,acl = cursor.fetchone()
      key = str(self.config.get('gringotts', 'key'))
      k = ezPyCrypto.key(key)
      text = wiki_to_html(k.decStringFromAscii(text), self.env, formatter.req)
      edit = 'Edit'
    except:
      edit = 'Create'
      text = tag.em("No Gringlet called \"%s\" found" % content)
      acl = ''
    
    if acl:
      if not validate_acl(formatter.req, acl):
        text = tag.em("You do not have permission to view the \"%s\" Gringlet." % content)
        edit = ''
    
    control = None
    if edit:
      control = tag.div(tag.a(edit, href=(formatter.href.gringotts() + "/" + content + "?action=edit")), class_="gringottcontrol")
    
    
    # Use eight divs for flexible frame styling
    return tag.div(
            tag.div(
             tag.div(
              tag.div(
               tag.div(
                tag.div(
                 tag.div(
                  tag.div(
                   tag.div(text, class_="gringottcontent") + control,
                  class_="gringott"),
                 class_="gringott"),
                class_="gringott"),
               class_="gringott"),
              class_="gringott"),
             class_="gringott"),
            class_="gringott"),
           class_="gringottframe")
예제 #20
0
  def expand_macro(self, formatter, name, content, args):

    title = 'Color Scheme'
    classes = 'colormacro' 

    if args and 'title' in args:
      title = args['title']

    if args and 'class' in args:
      classes  += ' ' + args['class']


    tbody = []
    have_comment = False
    colors = self._parse_arguments(content)

    for color in colors:
      if len(color['title']) > 0:
        have_comment = True
      ## Create row
      tbody.append(
        [
          tag.td()(tag.strong(color['title'])),
          tag.td(
              style='background-color:' + color['orig']
            )(
              tag.div(style='color: black')(color['hex']),
              tag.div(style='color: white')(color['hex'])
          ),
          tag.td(
              style='background-color:' + color['orig']
            )(
              tag.div(style='color: black')(color['rgbp']),
              tag.div(style='color: white')(color['rgbp'])
          ),
        ]
      )
      ## end for loop

    if len(tbody) > 0:
      colcount = len(tbody[0])
      if not have_comment:
        colcount -= 1
      
      table = tag.table(class_=classes)
      table()(tag.thead()(tag.th(colspan='%d' % colcount)(title)))
      ## Attach row in table.
      if have_comment:
        table()(tag.tbody(class_='colorlist')([tag.tr(row) for row in tbody]))
      else:
        table()(tag.tbody(class_='colorlist')([tag.tr(row[1:]) for row in tbody]))

      return table;
    else:
      return tag.div(class_='colormacro')('Nothing to display')
예제 #21
0
    def expand_macro(self, formatter, name, text, args):
        if not text:
            raw_actions = self.config.options('ticket-workflow')
        else:
            if args is None:
                text = '\n'.join([line.lstrip() for line in text.split(';')])
            if '[ticket-workflow]' not in text:
                text = '[ticket-workflow]\n' + text
            parser = RawConfigParser()
            try:
                parser.readfp(StringIO(text))
            except ParsingError as e:
                return system_message(_("Error parsing workflow."), unicode(e))
            raw_actions = list(parser.items('ticket-workflow'))
        actions = parse_workflow_config(raw_actions)
        states = list(
            set([
                state for action in actions.itervalues()
                for state in action['oldstates']
            ] + [action['newstate'] for action in actions.itervalues()]))
        action_labels = [attrs['label'] for attrs in actions.values()]
        action_names = actions.keys()
        edges = []
        for name, action in actions.items():
            new_index = states.index(action['newstate'])
            name_index = action_names.index(name)
            for old_state in action['oldstates']:
                old_index = states.index(old_state)
                edges.append((old_index, new_index, name_index))

        args = args or {}
        width = args.get('width', 800)
        height = args.get('height', 600)
        graph = {
            'nodes': states,
            'actions': action_labels,
            'edges': edges,
            'width': width,
            'height': height
        }
        graph_id = '%012x' % id(graph)
        req = formatter.req
        add_script(req, 'common/js/excanvas.js', ie_if='IE')
        add_script(req, 'common/js/workflow_graph.js')
        add_script_data(req, {'graph_%s' % graph_id: graph})
        return tag(
            tag.div('',
                    class_='trac-workflow-graph trac-noscript',
                    id='trac-workflow-graph-%s' % graph_id,
                    style="display:inline-block;width:%spx;height:%spx" %
                    (width, height)),
            tag.noscript(
                tag.div(_("Enable JavaScript to display the workflow graph."),
                        class_='system-message')))
예제 #22
0
 def _render(self, req, ticket, exists):
     if exists:
         message = self.changesets.format()
         return tag.div(tag.h2(_("Repository Changesets"),
                               class_='foldable'),
                        tag.div(message, id='changelog'),
                        class_=self.collapsed and 'collapsed')
     else:
         message = _("(none)")
         return tag.div(tag.h2(_("Repository Changesets"), ' ', message,
                               class_='foldable'))
예제 #23
0
    def expand_macro(self, formatter, name, content):
        req = formatter.req
        query_string = TicketQueryMacro.parse_args(content)[0]

        kwargs = dict([item.split('=') for item in content.split(',')[1:]])

        try:
            query = Query.from_string(self.env, query_string)
        except QuerySyntaxError as e:
            raise MacroError(e)

        try:
            tickets = query.execute(req)
        except QueryValueError as e:
            raise MacroError(e)

        # Formats above had their own permission checks, here we need to
        # do it explicitly:

        tickets = [t for t in tickets
                   if 'TICKET_VIEW' in req.perm(self.realm, t['id'])]

        tickets = map(lambda x: Ticket(self.env, x['id']), tickets)

        schedule_info = {'test': TicketScheduleSystem(self.env).get_schedule(tickets)}

        add_script(req, 'ticketrelation/js/bundle.js')
        add_stylesheet(req, 'ticketrelation/css/schedule.css')

        random_id = str(random.randint(0, 10000))

        config = {
            'url': req.base_url,
            'startDate': kwargs.get('startdate', None),
            'finishDate': kwargs.get('finishdate', None),
            'showUnavailable': kwargs.get('showunavailable', 1)
        }

        return tag.div(tag.div(
            tag.schedule(**{':schedule': 'schedule', ':config': 'config'}), class_='schedule_container', id='schedule_container_' + random_id),
            tag.script("""         
                $(window).load(function() {
                    var data = %s;
                    var config = %s;
                    var app = new window.Vue({
                        el: '#schedule_container_%s',
                        data: {
                            schedule: data,
                            config: config,
                        }
                    });
                });""" % (json.dumps(schedule_info, cls=DateTimeEncoder), json.dumps(config, cls=DateTimeEncoder), random_id))
        )
예제 #24
0
    def filter_stream(self, req, method, filename, stream, data):
        if filename in ('browser.html', 'dir_entries.html'):
            if 'path' not in data:
                # Probably an upstream error
                return stream
            # provide a link to the svn repository at the top of the Browse Source listing
            if self.env.is_component_enabled('contextmenu.contextmenu.SubversionLink'):
                content = SubversionLink(self.env).get_content(req, data['path'], stream, data)
                if content:
                    stream |= Transformer('//div[@id="content"]/h1').after(content)
            # No dir entries; we're showing a file
            if not data['dir']:
                return stream
            # FIXME: The idx is only good for finding rows, not generating element ids.
            # Xhr rows are only using dir_entries.html, not browser.html.
            # The xhr-added rows' ids are added using js (see expand_dir.js)
            add_stylesheet(req, 'contextmenu/contextmenu.css')
            add_script(req, 'contextmenu/contextmenu.js')
            if 'up' in data['chrome']['links']:
                # Start appending stuff on 2nd tbody row when we have a parent dir link
                row_index = 2
                # Remove colspan and insert an empty cell for checkbox column
                stream |= Transformer('//table[@id="dirlist"]//td[@colspan="5"]').attr('colspan', None).before(tag.td())
            else:
                # First row = //tr[1]
                row_index = 1

            for idx, entry in enumerate(data['dir']['entries']):
                menu = tag.div(tag.span(Markup('&#9662;'), style='color: #bbb'),
                               tag.div(class_='ctx-foldable', style='display:none'),
                               id='ctx%s' % idx, class_='context-menu')
                for provider in sorted(self.context_menu_providers, key=lambda x: x.get_order(req)):
                    content = provider.get_content(req, entry, stream, data)
                    if content:
                        menu.children[1].append(tag.div(content))
                ## XHR rows don't have a tbody in the stream
                if data['xhr']:
                    path_prefix = ''
                else:
                    path_prefix = '//table[@id="dirlist"]//tbody'
                # Add the menu
                stream |= Transformer('%s//tr[%d]//td[@class="name"]' % (path_prefix, idx + row_index)).prepend(menu)
                if provider.get_draw_separator(req):
                    menu.children[1].append(tag.div(class_='separator'))
                # Add td+checkbox
                cb = tag.td(tag.input(type='checkbox', id="cb%s" % idx, class_='fileselect'))
                stream |= Transformer('%s//tr[%d]//td[@class="name"]' % (path_prefix, idx + row_index)).before(cb)

            stream |= Transformer('//th[1]').before(tag.th())

        return stream
예제 #25
0
    def format(self, entries, label):
        div = tag.div(class_="references")
        div.append(tag.h1(id='references')(label))
        count = 0
        for key, value in entries:
            count = count + 1
            sortkey = tag.span(class_="key")
            sortkey.append("[" + str(count) + "]")
            element = tag.div(class_=value["type"])
            element.append(sortkey)
            element.append(self.format_entry(key, value))
            div.append(element)

        return div
예제 #26
0
    def format(self, entries, label):
        div = tag.div(class_="references")
        div.append(tag.h1(id="references")(label))
        count = 0
        for key, value in entries:
            count = count + 1
            sortkey = tag.span(class_="key")
            sortkey.append("[" + str(count) + "]")
            element = tag.div(class_=value["type"])
            element.append(sortkey)
            element.append(self.format_entry(key, value))
            div.append(element)

        return div
예제 #27
0
    def get_html(self, macroenv, req, content):
        def get_time(starttime, macroenv):
            '''
	computes the computing time of the macro
	returned as HTML construct to be embeeded in HTML output
      '''
            duration = (datetime.now() - starttime).microseconds / 1000
            macroenv.tracenv.log.debug('macro computation time: %s ms: %s ' %
                                       (duration, macroenv.macrokw))
            return (tag.span('It took %s ms to generate this visualization. ' %
                             (duration, ),
                             class_='ppstat'))

        #macroenv = PPEnv( env, req, content )
        macrostart = datetime.now()
        if content == None:
            content = ''

        ts = ppFilter(macroenv).get_tickets()

        if macroenv.get_args('ppforcereload') == '1':
            noteForceReload = tag.span('The visualization was recreated.',
                                       class_='ppforcereloadinfo')
        else:
            noteForceReload = tag.span()

        renderer = ppRender(macroenv)

        # show text in the headline
        moretitle = ''
        macroenv.tracenv.log.debug(
            'macroenv label=%s (%s)' %
            (macroenv.get_args('label'), macroenv.tracreq.args))
        if macroenv.macrokw.get('label', None) != None:  # use parameter: label
            moretitle = macroenv.macrokw.get('label', '')
        else:
            moretitle = renderer.getHeadline()  # get the pre-defined headline

        return tag.div(
            tag.h5(tag.a(name=macroenv.macroid)('%s' % (moretitle, ))),
            renderer.render(ts),
            tag.div(
                tag.div(
                    get_time(macrostart, macroenv), noteForceReload,
                    tag.span(
                        tag.a('Force recreation of the visualization.',
                              href='?ppforcereload=1',
                              class_='ppforcereload')))),
            style=macroenv.macrokw.get('style', '')  # CSS style
        )
예제 #28
0
    def process_request(self, req):
        """Redirect to pre-selected target."""
        if self.redirect_target or self._check_redirect(req):
            target = self.redirect_target

            # Check for self-redirect:
            if target and target == req.href(req.path_info):
                message = tag.div('Please ',
                     tag.a( "change the redirect target",
                            href = target + "?action=edit" ),
                     ' to another page.',
                     class_ = "system-message")
                data = { 'title':"Page redirects to itself!",
                         'message':message,
                         'type':'TracError',
                       }
                req.send_error(data['title'], status=409, env=self.env, data=data)
                raise RequestDone

            # Check for redirect pair, i.e. A->B, B->A
            if target and target == req.href.wiki(req.args.get('redirectedfrom','')):
                message = tag.div('Please change the redirect target from either ',
                     tag.a( "this page", href = req.href(req.path_info, action="edit")),
                     ' or ',
                     tag.a( "the redirecting page", href = target + "?action=edit" ),
                     '.',
                     class_ = "system-message")
                data = { 'title':"Redirect target redirects back to this page!",
                         'message':message,
                         'type':'TracError',
                       }
                req.send_error(data['title'], status=409, env=self.env, data=data)
                raise RequestDone

            # Add back link information for internal links:
            if target and target[0] == '/':
                redirectfrom =  "redirectedfrom=" + req.path_info[6:]
                # anchor should be the last in url
                # according to http://trac.edgewall.org/ticket/8072
                tgt, query, anchor= self.split_link(target)
                if not query:
                    query  = "?" + redirectfrom
                else:
                    query += "&" + redirectfrom
                target = tgt + query + anchor
            req.redirect(target)
            raise RequestDone
        raise TracError("Invalid redirect target!")
예제 #29
0
  def expand_macro(self, formatter, name, content, args):
    title = 'Color Gradient'
    classes = 'colorgradient';

    if args and 'title' in args:
      title = args['title']

    if args and 'class' in args:
      classes  += ' ' + args['class']

    colors = self._parse_arguments(content)

    lastcolor = {}
    tbody = []

    for color in colors:
      if 'orig' in lastcolor:
        tbody.append(self._create_gradient(lastcolor, color))
        
      tbody.append([
        tag.td(
          style='background-color:' + color['orig']
        )(
          tag.div(style='color: black')(color['hex']),
          tag.div(style='color: white')(color['hex'])
        ),
        tag.td(
          style='background-color:' + color['orig']
        )(
          tag.div(style='color: black')(color['rgbp']),
          tag.div(style='color: white')(color['rgbp'])
        )
      ])

      lastcolor = color

    ## end for loop

    if len(tbody) > 0:
      
      table = tag.table(class_=classes)
      table()(tag.thead()(tag.th(colspan="2")(title)))
     
      table()(tag.tbody(class_='colorgradient')([tag.tr()(td) for td in tbody]))

      return table;
    else:
      return tag.div(class_='colorgradient')('Nothing to display')
예제 #30
0
        def gentd(week_idx, day_info):
            day = day_info['date']
            tt = day_info['milestones'] + day_info['tickets']
            if len(tt) < 6:
                ttshow = tt
                ttall = []
            else:
                ttshow = tt[:4]
                ttall = tt

            tdclass = []
            if day == today:
                tdclass.append('today')
            if day.weekday() in (5, 6):
                tdclass.append('weekend')

            formatted_day = format_date(day, format='long', locale=locale)

            td = tag.td(class_=' '.join(tdclass),
                        data_for_start_date=day.strftime(start_date_format),
                        data_for_due_date=day.strftime(due_date_format),
                        data_fdate=formatted_day)

            label = []
            if day == today:
                label.append(tag.span(_("Today"), class_='today'))
            label.append(
                tag.span(unicode(day.day),
                         class_=('day normal', 'day')[day == today]))
            td(tag.div(label))
            if ttshow:
                td(tag.ul([genli(t) for t in ttshow]))

            if ttall:
                id = 'calendar-more-%s' % str(day)
                td(
                    tag.a(_("%d more tickets...") % (len(ttall) - 4),
                          href='#' + id,
                          class_='show-all-list'),
                    tag.div(tag.h4(formatted_day),
                            tag.ul([genli(t) for t in ttall]),
                            class_='ticketcalendar-popup-list',
                            id=id,
                            data_title=format_date(day,
                                                   locale=locale,
                                                   format='full')))

            return td
예제 #31
0
    def expand_macro(self, formatter, name, text, args):
        if not text:
            raw_actions = self.config.options('ticket-workflow')
        else:
            if args is None:
                text = '\n'.join([line.lstrip() for line in text.split(';')])
            if '[ticket-workflow]' not in text:
                text = '[ticket-workflow]\n' + text
            parser = RawConfigParser()
            try:
                parser.readfp(StringIO(text))
            except ParsingError as e:
                return system_message(_("Error parsing workflow."),
                                      unicode(e))
            raw_actions = list(parser.items('ticket-workflow'))
        actions = parse_workflow_config(raw_actions)
        states = list(set(
            [state for action in actions.itervalues()
                   for state in action['oldstates']] +
            [action['newstate'] for action in actions.itervalues()]))
        action_labels = [attrs['label'] for attrs in actions.values()]
        action_names = actions.keys()
        edges = []
        for name, action in actions.items():
            new_index = states.index(action['newstate'])
            name_index = action_names.index(name)
            for old_state in action['oldstates']:
                old_index = states.index(old_state)
                edges.append((old_index, new_index, name_index))

        args = args or {}
        width = args.get('width', 800)
        height = args.get('height', 600)
        graph = {'nodes': states, 'actions': action_labels, 'edges': edges,
                 'width': width, 'height': height}
        graph_id = '%012x' % id(graph)
        req = formatter.req
        add_script(req, 'common/js/excanvas.js', ie_if='IE')
        add_script(req, 'common/js/workflow_graph.js')
        add_script_data(req, {'graph_%s' % graph_id: graph})
        return tag(
            tag.div('', class_='trac-workflow-graph trac-noscript',
                    id='trac-workflow-graph-%s' % graph_id,
                    style="display:inline-block;width:%spx;height:%spx" %
                          (width, height)),
            tag.noscript(
                tag.div(_("Enable JavaScript to display the workflow graph."),
                        class_='system-message')))
예제 #32
0
 def expand_macro(self, formatter, name, content, args=None):
     # pylint: disable=too-many-function-args
     args = args or {}
     reponame = args.get('repository') or ''
     rev = args.get('revision')
     # pylint: disable=no-member
     repos = RepositoryManager(self.env).get_repository(reponame)
     try:
         changeset = repos.get_changeset(rev)
         message = changeset.message
         rev = changeset.rev
         resource = repos.resource
     except Exception:  # pylint: disable=broad-except
         message = content
         resource = Resource('repository', reponame)
     if ChangesetModule(self.env).wiki_format_messages:
         return tag.div(format_to_html(self.env,
                                       formatter.context.child(
                                           'changeset',
                                           rev,
                                           parent=resource),
                                       message,
                                       escape_newlines=True),
                        class_='message')
     else:
         return tag.pre(message, class_='message')
예제 #33
0
파일: macros.py 프로젝트: exocad/exotrac
    def expand_macro(self, formatter, name, content):
        from trac.mimeview.api import Mimeview
        mime_map = Mimeview(self.env).mime_map
        mime_type_filter = ''
        args, kw = parse_args(content)
        if args:
            mime_type_filter = args.pop(0).strip().rstrip('*')

        mime_types = {}
        for key, mime_type in mime_map.iteritems():
            if (not mime_type_filter or
                mime_type.startswith(mime_type_filter)) and key != mime_type:
                mime_types.setdefault(mime_type, []).append(key)

        return tag.div(class_='mimetypes')(
            tag.table(class_='wiki')(
                tag.thead(tag.tr(
                    tag.th(_("MIME Types")),  # always use plural
                    tag.th(tag.a("WikiProcessors",
                                 href=formatter.context.href.wiki(
                                     'WikiProcessors'))))),
                tag.tbody(
                    tag.tr(tag.th(tag.tt(mime_type),
                                  style="text-align: left"),
                           tag.td(tag.code(
                               ' '.join(sorted(mime_types[mime_type])))))
                    for mime_type in sorted(mime_types.keys()))))
예제 #34
0
    def expand_macro(self, formatter, name, content):
        req = formatter.req
        stats_provider, kwargs, is_preview_with_self = self._parse_macro_content(content, req)

        if is_preview_with_self:
            # previewing newticket, without a number but with a reference
            # to current ticket number; show a helpful message
            return tag.div('Progress meter will be inserted here in final ticket')

        # Create & execute the query string
        qstr = '&'.join(['%s=%s' % item
                               for item in kwargs.iteritems()])
        query = Query.from_string(self.env, qstr, max=0)
        try:
            constraints = query.constraints[0]
        except IndexError:
            constraints = query.constraints

        # Calculate stats
        qres = query.execute(req)
        tickets = apply_ticket_permissions(self.env, req, qres)

        stats = get_ticket_stats(stats_provider, tickets)
        stats_data = query_stats_data(req, stats, constraints)

        # ... and finally display them
        add_stylesheet(req, 'common/css/roadmap.css')
        chrome = Chrome(self.env)
        return chrome.render_template(req, 'progressmeter.html', stats_data,
                                      fragment=True)
예제 #35
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.path_info.startswith('/ticket'):
         button = tag.div(
             tag.input(type="submit",
                       title=_("Translate to %s") %
                       req.locale.get_display_name(),
                       value=_("Translate"),
                       forward=_("Translate"),
                       backward=_("Untranslate"),
                       working=_("Working"),
                       name="translate",
                       class_="translate"))
         button(class_="inlinebuttons")
         script = tag.script('')
         script(src='https://www.google.com/jsapi?key=' + self.googleApiKey)
         script(type='text/javascript')
         stream |= Transformer('//head').prepend(script)
         stream |= Transformer(
             '//div[@id="content"]/div[@id="ticket"]/div[@class="description"]/h3'
         ).after(button)
         stream |= Transformer(
             '//div[@id="content"]/div/div[@id="changelog"]/div[@class="change"]/h3'
         ).after(button)
         add_stylesheet(req, 'translate/translate.css')
         add_script_data(req, {'googleApiKey': self.googleApiKey})
         add_script_data(req, {'sessionLanguage': req.locale.language})
         add_script(req, 'translate/translate.js')
     return stream
예제 #36
0
    def get_html(self, total, horas_semanas):
        valor_hora = self.data['valor_hora']
        text = ['Horas trabajadas: %.2f' % total,
                'Precio en dolares (U$S%s): %.2f' % (valor_hora, total * valor_hora)]
        text.extend(['Horas semana %s: %.2f' % (nro+1, horas) for nro, horas in horas_semanas.items()])
        div = tag.div()
        ul = tag.ul()
        for li in text:
            ul.append(tag.li(li))

        if 'date' in self.data:
            link = tag.a('@netlandish: Grinch report',
                         href=self._get_grinch_report_url())
            ul.append(link)
        div.append(ul)

        img = tag.img(src=self._get_google_chart(horas_semanas))
        div.append(img)

        ul = tag.ul()
        for project, hours in self.hours.iteritems():
            ul.append(tag.li('{0}: {1}'.format(project.title(), hours)))
        div.append(ul)

        return div
 def expand_macro(self, formatter, name, content, args=None):
     args = args or {}
     reponame = args.get('repository') or ''
     rev = args.get('revision')
     repos = RepositoryManager(self.env).get_repository(reponame)
     try:
         changeset = repos.get_changeset(rev)
         message = changeset.message
         rev = changeset.rev
         resource = repos.resource
     except Exception:
         message = content
         resource = Resource('repository', reponame)
     if formatter.context.resource.realm == 'ticket':
         ticket_re = CommitTicketUpdater.ticket_re
         if not any(int(tkt_id) == int(formatter.context.resource.id)
                    for tkt_id in ticket_re.findall(message)):
             return tag.p(_("(The changeset message doesn't reference this "
                            "ticket)"), class_='hint')
     if ChangesetModule(self.env).wiki_format_messages:
         return tag.div(format_to_html(self.env,
             formatter.context.child('changeset', rev, parent=resource),
             message, escape_newlines=True), class_='message')
     else:
         return tag.pre(message, class_='message')
예제 #38
0
    def expand_macro(self, formatter, name, content):
        min_depth, max_depth = 1, 6
        title = None
        inline = 0
        if content:
            argv = [arg.strip() for arg in content.split(',')]
            if len(argv) > 0:
                depth = argv[0]
                if '-' in depth:
                    min_depth, max_depth = [int(d)
                                            for d in depth.split('-', 1)]
                else:
                    min_depth = max_depth = int(depth)
                if len(argv) > 1:
                    title = argv[1].strip()
                    if len(argv) > 2:
                        inline = argv[2].strip().lower() == 'inline'

        # TODO: - integrate the rest of the OutlineFormatter directly here
        #       - use formatter.wikidom instead of formatter.source
        out = StringIO()
        oformatter = OutlineFormatter(self.env, formatter.context)
        oformatter.format(formatter.source, out, max_depth, min_depth,
                          shorten=not inline)
        outline = Markup(out.getvalue())

        if title:
            outline = tag.h4(title) + outline
        if not inline:
            outline = tag.div(outline, class_='wiki-toc')
        return outline
예제 #39
0
    def filter_stream(self, req, method, filename, stream, data):
        # check preconditions
        if filename != 'ticket.html':
            return stream
        transformer = Transformer()
        # build 'Hide these fields' Area
        hide_names = req.session.get('hidefieldchanges', [])
        hide_fields = []
        for field in data['fields']:
            name = field['name']
            checkbox = name in hide_names \
                and tag.input(type='checkbox', checked=True, name=name) \
                or tag.input(type='checkbox', name=name)
            hide_fields.append(tag.label(checkbox, field['label']))
            hide_fields.append(tag.br)
        hide_fields.append(tag.input(name='submit', type='submit', value='Hide these fields'))
        transformer = transformer \
            .select('//div[@id="changelog"]') \
            .before(tag.form(tag.input(value='hide changes', id='hidechangesbutton', type='button', style_='float: right;'),
                             tag.div(hide_fields, style='display: none', id='hidefields'),
                             action='#', class_='inlinebuttons hidechanges')).end()
        # build 'show all changes' button
#        showallbutton = tag.input(value='show all', name='showall', class_='showallbutton', type='submit', style_='float: right;')
#        showallbutton = tag.form(showallbutton, action='#', method='get', class_='inlinebuttons hidechanges')
#        transformer = transformer.select('//div[@id="changelog"]').before(showallbutton).end()
        # build 'hide customfield' buttons
        hidebutton = tag.input(value='hide', name="hide", class_='hidebutton', style_='display: none', type='submit')
        hidebutton = tag.form(hidebutton, action='#', method='get', class_='inlinebuttons hidefieldchanges')
        transformer = transformer \
            .select('//div[@id="changelog"]/div[@class="change"]/ul[@class="changes"]/li') \
            .prepend(hidebutton).end()
        # return filtered stream
        return stream | transformer
예제 #40
0
 def _clone_form(self, req, ticket, data):
     fields = {}
     for f in data.get('fields', []):
         name = f['name']
         if name == 'summary':
             fields['summary'] = _("%(summary)s (cloned)",
                                   summary=ticket['summary'])
         elif name == 'description':
             fields['description'] = \
                 _("Cloned from #%(id)s:\n----\n%(description)s",
                   id=ticket.id, description=ticket['description'])
         else:
             fields[name] = ticket[name]
     return tag.form(tag.div(tag.input(
         type="submit",
         name="clone",
         value=captioned_button(req, '+#', _("Clone")),
         title=_("Create a copy of this ticket")), [
             tag.input(type="hidden", name='field_' + n, value=v)
             for n, v in fields.iteritems()
         ],
                             tag.input(type="hidden",
                                       name='preview',
                                       value=''),
                             class_="inlinebuttons"),
                     method="post",
                     action=req.href.newticket())
예제 #41
0
    def expand_macro(self, formatter, name, args):
        curpage = formatter.resource.id

        # scoped TOC (e.g. TranslateRu/Guide or 0.X/Guide ...)
        prefix = ''
        guideprefix = GUIDE_NAME + '/'
        data = {
            'guide': GUIDE_NAME,
        }
        idx = curpage.find('/')
        if idx > 0:
            prefix = curpage[:idx + 1]
        if prefix.endswith(guideprefix):
            prefix = prefix[:len(prefix) - len(guideprefix)]
        ws = WikiSystem(self.env)
        return tag.div(
            tag.h4(_('Table of Contents')),
            tag.ul([
                tag.li(tag.a(title,
                             href=formatter.href.wiki(prefix + ref % data),
                             class_=(not ws.has_page(prefix + ref % data)
                                     and 'missing')),
                       class_=(prefix + ref % data == curpage and 'active'))
                for ref, title in self.TOC
            ]),
            class_='wiki-toc')
예제 #42
0
 def _process_edit(self, req, stream, method, tags):
     stage = 1
     elm = tag.div([
         tag.label('Tag under: (',
                   tag.a('view all tags', href=req.href.tags()),
                   ')',
                   for_='tags'),
         tag.br(),
         tag.input(title='Comma separated list of tags',
                   type='text',
                   id='tags',
                   size='30',
                   name='tags',
                   value=', '.join(tags)),
     ],
                   class_='field')
     for kind, data, pos in stream:
         yield kind, data, pos
         if stage == 1 and \
            kind is START and \
            data[0].localname == 'input' and \
            data[1].get('id') == 'comment':
             stage = 2
         elif stage == 2 and \
              kind is END and \
              data.localname == 'div':
             for e in elm.generate():
                 yield e
             stage = None
예제 #43
0
파일: macro.py 프로젝트: weese/seqan
 def expand_macro(self, formatter, name, content, args):
     add_stylesheet(formatter.req, 'text_boxes/css/text_boxes.css')
     # TODO(holtgrew): Actually, we would like to add a style sheet but this does not work. Thus we use a style tag below.
     #add_stylesheet(formatter.req, 'text_boxes/css/text_boxes.css')
     className = CLASSES.get(name, 'ShellBox')
     if name in ['TextIcon']:
         args = trac.wiki.parse_args(content)
         if not args or not args[0]:  # Handle case of empty entry.
             return None
         DEFAULT = 'gray'
         COLOR_CLASSES = ['green', 'red', 'yellow', 'black', 'gray', 'blue']
         color_class_name = args[1].get('color', DEFAULT)
         if not color_class_name in COLOR_CLASSES:
             color_class_name = DEFAULT
         return tag.span(args[0],
                         class_=('text_icon %s' % color_class_name))
     elif name in ['MenuTrace']:
         args = trac.wiki.parse_args(content)
         if not args[0]:
             return None
         result = tag.span(args[0][0], class_='menu_item')
         for text in args[0][1:]:
             result += tag.span(u' \u25B8 ', class_='arrow')
             result += tag.span(text, class_='menu_item')
         return tag.span(result, class_='menu_trace')
     elif name in [
             'WarningBox', 'InfoBox', 'ImportantBox', 'AssignmentBox'
     ]:
         content_html = self.format_wiki(formatter, content)
         return tag.div(genshi.core.Markup(content_html), class_=className)
     else:
         return tag.pre(content, class_='wiki ' + className)
예제 #44
0
 def _render(self, formatter, cols, name_pat, size, header, limit):
     #noinspection PyArgumentList
     icon = Icons(self.env)
     icon_dir = icon.icon_location(size)[1]
     files = fnmatch.filter(os.listdir(icon_dir), '%s.png' % name_pat)
     icon_names = [os.path.splitext(p)[0] for p in files]
     if limit:
         displayed_icon_names = reduce_names(icon_names, limit)
     else:
         displayed_icon_names = icon_names
     icon_table = render_table(displayed_icon_names, cols,
                               lambda name: icon._render_icon(formatter,
                                                              name, size))
     if not len(icon_names):
         message = 'No %s icon matches %s' % (SIZE_DESCR[size], name_pat)
     elif len(icon_names) == 1:
         message = 'Showing the only %s icon matching %s' % \
                   (SIZE_DESCR[size], name_pat)
     elif len(displayed_icon_names) == len(icon_names):
         message = 'Showing all %d %s icons matching %s' % \
                   (len(icon_names), SIZE_DESCR[size], name_pat)
     else:
         message = 'Showing %d of %d %s icons matching %s' % \
                   (len(displayed_icon_names), len(icon_names),
                    SIZE_DESCR[size], name_pat)
     return tag.div(tag.p(tag.small(message)) if header else '', icon_table)
예제 #45
0
파일: macro.py 프로젝트: nyuhuhuu/trachacks
 def expand_macro(self, formatter, name, content):
     add_stylesheet(formatter.req, 'notebox/css/notebox.css')
     args, kwargs = parse_args(content)
     width = len(args) > 2 and args[2] or '70%'
     return tag.div(format_to_html(self.env, formatter.context, args[1]), 
                    class_='notebox-%s' % (args[0],),
                    style='width: %s' % (width,))
예제 #46
0
 def expand_macro(self, formatter, name, arguments):
     self.mc.options(arguments)
     extras = self.mc.extras()
     extra = ''
     if 'extra' in extras:
         extra = extras['extra']
     return tag.div(
         tag.h3('[[%s(%s)]]' % ( name, arguments )),
         tag.table(
           tag.tr(
             tag.th('Name'), tag.th('Value'), tag.th('Qualified'),
             tag.th('Default?'), tag.th('Macroarg?'), tag.th('Extra?'),
             tag.th('Known?'), tag.th('Default'), tag.th('Documentation')
           ),
           self._show_option('text', self.mo_text,
                             TracMacroConfigExample.mo_text),
           self._show_option('bool', self.mo_bool,
                             TracMacroConfigExample.mo_bool),
           self._show_option('int', self.mo_int,
                             TracMacroConfigExample.mo_int),
           self._show_option('list', self.mo_list,
                             TracMacroConfigExample.mo_list),
           self._show_option('nodtext', self.mo_nodtext,
                             TracMacroConfigExample.mo_nodtext),
           self._show_option('nodbool', self.mo_nodbool,
                             TracMacroConfigExample.mo_nodbool),
           self._show_option('nodint', self.mo_nodint,
                             TracMacroConfigExample.mo_nodint),
           self._show_option('nodlist', self.mo_nodlist,
                             TracMacroConfigExample.mo_nodlist),
           self._show_extra('extra', extra),
           border=1, cellpadding=1, cellspacing=0
         )
     )
예제 #47
0
    def _format_reminder(self,
                         req,
                         ticket,
                         id,
                         time,
                         author,
                         origin,
                         description,
                         delete_button=True):
        now = to_datetime(None)
        time = to_datetime(time)
        if now >= time:
            when = tag(tag.strong("Right now"), " (pending)")
        else:
            when = tag("In ", tag.strong(pretty_timedelta(time)), " (",
                       format_date(time), ")")

        if description:
            context = Context.from_request(req, ticket.resource)
            desc = tag.div(format_to_oneliner(self.env, context, description),
                           class_="description")
        else:
            desc = tag()

        return tag(
            self._reminder_delete_form(req, id) if delete_button else None,
            when, " - added by ",
            tag.em(Chrome(self.env).authorinfo(req, author)), " ",
            tag.span(pretty_timedelta(origin),
                     title=format_datetime(
                         origin, req.session.get('datefmt', 'iso8601'),
                         req.tz)), " ago.", desc)
예제 #48
0
    def expand_macro(self, formatter, name, args):
        from trac.config import Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        registry = Option.get_registry(self.compmgr)
        sections = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                sections.setdefault(section, {})[key] = option

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             tag.table(class_='wiki')(
                 tag.tbody(tag.tr(tag.td(tag.tt(option.name)),
                                  tag.td(format_to_oneliner(
                                      self.env, formatter.context,
                                      to_unicode(option.__doc__))))
                           for option in sorted(sections[section].itervalues(),
                                                key=lambda o: o.name)
                           if option.name.startswith(key_filter))))
            for section in sorted(sections))
    def filter_stream(self, req, method, filename, stream, data):
        notice = self.get_notice()

        if notice:
            stream |= Transformer(self.insert_after).after(tag.div(notice, id="project-notice"))

        return stream
예제 #50
0
    def filter_stream(self, req, method, filename, stream, data):
        """Return a filtered Genshi event stream, or the original unfiltered
        stream if no match.

        `req` is the current request object, `method` is the Genshi render
        method (xml, xhtml or text), `filename` is the filename of the template
        to be rendered, `stream` is the event stream and `data` is the data for
        the current template.

        See the Genshi documentation for more information.
        """
        # move these someplace sensible?
        form_id = "acctmgr_registerform" # id of the registration form
        msg = "Please enter the text below to prove you're not a machine."

        if filename == "register.html":
            word = random_word(self.dict_file)
            req.session['captcha'] = word
            req.session.save()
            if self.captcha_type == 'png':
                captcha = '<img src="%s"/>' % req.href('captcha.png')
            else:
                captcha = skimpyAPI.Pre(word).data()
            content = "<p>%s</p><p>%s</p>" % (msg, captcha)
            content += '<label>Confirm: <input type="text" name="captcha" class="textwidget" size="20"/></label>'
            stream |= Transformer('//form[@id="%s"]/fieldset[1]' % form_id).append(tag.div(Markup(content)))

        return stream
예제 #51
0
 def expand_macro(self, formatter, name, content, args={}):
     reponame = args.get("repository") or ""
     rev = args.get("revision")
     repos = RepositoryManager(self.env).get_repository(reponame)
     try:
         changeset = repos.get_changeset(rev)
         message = changeset.message
         rev = changeset.rev
         resource = repos.resource
     except Exception:
         message = content
         resource = Resource("repository", reponame)
     if formatter.context.resource.realm == "ticket":
         ticket_re = CommitTicketUpdater.ticket_re
         if not any(int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)):
             return tag.p("(The changeset message doesn't reference this " "ticket)", class_="hint")
     if ChangesetModule(self.env).wiki_format_messages:
         return tag.div(
             format_to_html(
                 self.env, formatter.context.child("changeset", rev, parent=resource), message, escape_newlines=True
             ),
             class_="message",
         )
     else:
         return tag.pre(message, class_="message")
예제 #52
0
 def expand_macro(self, formatter, name, content, args={}):
     reponame = args.get('repository') or ''
     rev = args.get('revision')
     repos = RepositoryManager(self.env).get_repository(reponame)
     try:
         changeset = repos.get_changeset(rev)
         message = changeset.message
         rev = changeset.rev
         resource = repos.resource
     except Exception:
         message = content
         resource = Resource('repository', reponame)
     if formatter.context.resource.realm == 'ticket':
         ticket_re = CommitTicketUpdater.ticket_re
         if not any(
                 int(tkt_id) == int(formatter.context.resource.id)
                 for tkt_id in ticket_re.findall(message)):
             return tag.p(
                 "(The changeset message doesn't reference this "
                 "ticket)",
                 class_='hint')
     if ChangesetModule(self.env).wiki_format_messages:
         return tag.div(format_to_html(self.env,
                                       formatter.context.child(
                                           'changeset',
                                           rev,
                                           parent=resource),
                                       message,
                                       escape_newlines=True),
                        class_='message')
     else:
         return tag.pre(message, class_='message')
예제 #53
0
 def launch(self, proc_cmd, encoded_input, *args):
     """Launch a process (cmd), and returns exitcode, stdout + stderr"""
     # Note: subprocess.Popen doesn't support unicode options arguments
     # (http://bugs.python.org/issue1759845) so we have to encode them.
     # Anyway, dot expects utf-8 or the encoding specified with -Gcharset.
     encoded_cmd = proc_cmd
     proc = subprocess.Popen(encoded_cmd,
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
     if encoded_input:
         proc.stdin.write(encoded_input)
     proc.stdin.close()
     out = proc.stdout.read()
     err = proc.stderr.read()
     failure = proc.wait() != 0
     if failure or err or out:
         return (failure,
                 tag.div(tag.br(),
                         _("The command:"),
                         tag.pre(repr(' '.join(encoded_cmd))),
                         (_("succeeded but emitted the following output:"),
                          _("failed with the following output:"))[failure],
                         out and tag.pre(out),
                         err and tag.pre(err),
                         class_="system-message"))
     else:
         return (False, None)
예제 #54
0
    def expand_macro(self, formatter, name, content):
        from trac.mimeview.api import Mimeview
        mime_map = Mimeview(self.env).mime_map
        mime_type_filter = ''
        args, kw = parse_args(content)
        if args:
            mime_type_filter = args.pop(0).strip().rstrip('*')

        mime_types = {}
        for key, mime_type in mime_map.iteritems():
            if (not mime_type_filter or
                mime_type.startswith(mime_type_filter)) and key != mime_type:
                mime_types.setdefault(mime_type, []).append(key)

        return tag.div(class_='mimetypes')(
            tag.table(class_='wiki')(
                tag.thead(tag.tr(
                    tag.th(_("MIME Types")),  # always use plural
                    tag.th(tag.a("WikiProcessors",
                                 href=formatter.context.href.wiki(
                                     'WikiProcessors'))))),
                tag.tbody(
                    tag.tr(tag.th(tag.code(mime_type),
                                  style="text-align: left"),
                           tag.td(tag.code(
                               ' '.join(sorted(mime_types[mime_type])))))
                    for mime_type in sorted(mime_types.keys()))))
예제 #55
0
    def filter_stream(self, req, method, filename, stream, data):
        # Add delete buttons to the ticket form
        ticket = data.get('ticket')
        if filename == 'ticket.html' and 'TICKET_ADMIN' in req.perm(ticket.resource):

            # Add Delete button to ticket description
            if data['ticket'].values['description']:
                # Reply button and associated elements are present
                filter = Transformer("//div[@class='description']//div[@class='inlinebuttons']")
                stream |= filter.append(tag.input(type='submit', name='delete',
                                                  title="Delete this ticket", value='Delete'))
            else:
                # Reply button and associated elements not present
                filter = Transformer("//div[@class='description']/h3")
                stream |= filter.after( \
                    tag.form(tag.div(tag.input(type='submit', name='delete',
                                               title="Delete this ticket", value='Delete'),
                                     class_='inlinebuttons'
                                     ),
                             name='addreply', method='get', action='#comment')
                             )

            # Add Delete buttons to ticket comments
            stream |= Transformer("//div[@id='changelog']//div[@class='inlinebuttons']") \
                          .append(tag.input(type='submit', name='delete',
                                            title="Delete this comment", value='Delete'))

        return stream
예제 #56
0
    def embed_player(self, formatter, url, query, style):
        query_dict = xform_query(query)
        set_default_parameters(
            query_dict,
            _EMBED_FLOWPLAYER_DEFAULT_PARAMETERS
        )

        player_id = self._generate_player_id()
        swf = pathjoin(formatter.href.chrome(), EMBED_PATH_FLOWPLAYER['swf'])
        style.pop('width')  # use adaptiveRatio for player-size
        style.pop('height')  # use adaptiveRatio for player-size
        attrs = {
            'id': player_id,
            'data-swf': swf,
            'style': xform_style(style),
        }
        return tag.div(
            tag.video([
                tag.source(type=mimetypes.guess_type(url)[0], src=url),
                tag.script("""
                    $(function() {
                        $('#%s').flowplayer(%s);
                    });
                """ % (player_id, to_json(query_dict))
                ),
            ]),
            **attrs
        )
예제 #57
0
 def _render(self, formatter, cols, name_pat, size, header, limit):
     #noinspection PyArgumentList
     icon = Icons(self.env)
     icon_dir = icon.icon_location(size)[1]
     files = fnmatch.filter(os.listdir(icon_dir), name_pat + '.png')
     icon_names = [os.path.splitext(p)[0] for p in files]
     if limit:
         displayed_icon_names = reduce_names(icon_names, limit)
     else:
         displayed_icon_names = icon_names
     icon_table = render_table(displayed_icon_names, cols,
                               lambda name: icon._render_icon(formatter,
                                                              name, size))
     if not len(icon_names):
         message = 'No %s icon matches %s' % (SIZE_DESCR[size], name_pat)
     elif len(icon_names) == 1:
         message = 'Showing the only %s icon matching %s' % \
                   (SIZE_DESCR[size], name_pat)
     elif len(displayed_icon_names) == len(icon_names):
         message = 'Showing all %d %s icons matching %s' % \
                   (len(icon_names), SIZE_DESCR[size], name_pat)
     else:
         message = 'Showing %d of %d %s icons matching %s' % \
                   (len(displayed_icon_names), len(icon_names),
                    SIZE_DESCR[size], name_pat)
     return tag.div(tag.p(tag.small(message)) if header else '', icon_table)