예제 #1
0
파일: theme.py 프로젝트: mohsadki/dargest
 def product_media_data(icons, product):
     return dict(href=product.href(),
                 thumb=icons.get(product.prefix, no_thumbnail),
                 title=product.name,
                 description=format_to_html(self.env,
                                            product_ctx(product),
                                            product.description),
                 links={'extras': (([{'href': req.href.products(
                                         product.prefix, action='edit'),
                                      'title': _('Edit product %(prefix)s',
                                                 prefix=product.prefix),
                                      'icon': tag.i(class_='icon-edit'),
                                      'label': _('Edit')},]
                                    if 'PRODUCT_MODIFY' in req.perm
                                    else []) +
                                   [{'href': product.href(),
                                     'title': _('Home page'),
                                     'icon': tag.i(class_='icon-home'),
                                     'label': _('Home')},
                                    {'href': product.href.dashboard(),
                                     'title': _('Tickets dashboard'),
                                     'icon': tag.i(class_='icon-tasks'),
                                     'label': _('Tickets')},
                                    {'href': product.href.wiki(),
                                     'title': _('Wiki'),
                                     'icon': tag.i(class_='icon-book'),
                                     'label': _('Wiki')}]),
                        'main': {'href': product.href(),
                                 'title': None,
                                 'icon': tag.i(class_='icon-chevron-right'),
                                 'label': _('Browse')}})
예제 #2
0
파일: macros.py 프로젝트: exocad/exotrac
 def get_macro_descr():
     for macro_provider in formatter.wiki.macro_providers:
         names = list(macro_provider.get_macros() or [])
         if name_filter and not any(name.startswith(name_filter)
                                    for name in names):
             continue
         try:
             name_descriptions = [
                 (name, macro_provider.get_macro_description(name))
                 for name in names]
         except Exception, e:
             yield system_message(
                 _("Error: Can't get description for macro %(name)s",
                   name=names[0]), e), names
         else:
             for descr, pairs in groupby(name_descriptions,
                                         key=lambda p: p[1]):
                 if descr:
                     if isinstance(descr, (tuple, list)):
                         descr = dgettext(descr[0],
                                          to_unicode(descr[1])) \
                                 if descr[1] else ''
                     else:
                         descr = to_unicode(descr) or ''
                     if content == '*':
                         descr = format_to_oneliner(
                             self.env, formatter.context, descr,
                             shorten=True)
                     else:
                         descr = format_to_html(
                             self.env, formatter.context, descr)
                 yield descr, [name for name, descr in pairs]
 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')
예제 #4
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")
예제 #5
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
예제 #6
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,))
예제 #7
0
 def safe_wiki_to_html(context, text):
     try:
         return format_to_html(self.env, context, text)
     except Exception, e:
         self.log.error('Unable to render component documentation: %s',
                        exception_to_unicode(e, traceback=True))
         return tag.pre(text)
예제 #8
0
 def serialized(self, env, context):
     return {
         'id': self.id,
         'stack': self.stack,
         'rank': self.rank,
         'title': self.title, 
         'title_html': format_to_html(env, context, self.title),
     }
예제 #9
0
 def render(self, context, mimetype, content, filename=None, url=None):
     if url is not None:
         match = re.match(self.PREVIEW_PATTERN, urllib.unquote(str(url)))
         if match:
             path_info = match.groupdict()
             macro = unicode(self.MACRO_FORMAT % path_info, self.ENCODING)
             return format_to_html(self.env, context, macro)
     return None
예제 #10
0
    def render_timeline_event(self, context, field, event):
        ev = event[3]

        if field=='title':
            return tag(tag.em(ev[0]), ' found on ', ev[1])
        elif field=='description':
            return format_to_html(self.env, context, ev[3])
        elif field=='url':
            return ev[2]
예제 #11
0
파일: wiki.py 프로젝트: nextview/tracxmlrpc
 def getPageHTML(self, req, pagename, version=None):
     """ Return latest version of page as rendered HTML, utf8 encoded. """
     page = self._fetch_page(req, pagename, version)
     fields = {"text": page.text}
     for manipulator in self.manipulators:
         manipulator.prepare_wiki_page(req, page, fields)
     context = Context.from_request(req, page.resource, absurls=True)
     html = format_to_html(self.env, context, fields["text"])
     return "<html><body>%s</body></html>" % html.encode("utf-8")
예제 #12
0
    def _gen_ticket_entry(self, t, a_class=''):
        id = str(t.get('id'))
        status = t.get('status')
        priority = t.get('priority')
        hours = t.get(self.hours_field_name)
        summary = to_unicode(t.get('summary'))
        owner = to_unicode(t.get('owner'))
        description = to_unicode(t.get('description')[:1024])
        url = t.get('href')

        if status == 'closed':
            a_class = a_class + 'closed'
        else:
            a_class = a_class + 'open'
        
        a_class += " ticket priority-" + priority            
        
        markup = format_to_html(self.env, self.ref.context, description)
        # Escape, if requested
        if self.sanitize is True:
            try:
                description = HTMLParser(StringIO(markup)
                                           ).parse() | HTMLSanitizer()
            except ParseError:
                description = escape(markup)
        else:
            description = markup

        # Replace tags that destruct tooltips too much
        desc = self.end_RE.sub(']', Markup(description))
        desc = self.del_RE.sub('', desc)
        # need 2nd run after purging newline in table cells in 1st run
        desc = self.del_RE.sub('', desc)
        desc = self.item_RE.sub('X', desc)
        desc = self.tab_RE.sub('[|||]', desc)
        description = self.open_RE.sub('[', desc)

        tip = tag.span(Markup(description))
        ticket = '#' + id
        ticket = tag.a(ticket, href=url)
        ticket(tip, class_='tip', target='_blank')
        ticket = tag.div(ticket)
        ticket(class_=a_class, align='left', **{"data-ticketid": id})
        # fix stripping of regular leading space in IE
        blank = '&nbsp;'
        ticket(Markup(blank), summary, ' (', owner, ')')
        ticket(tag.span(str(hours) + "h", class_="hours"))

        summary = tag(summary, ' (', owner, ')')
        ticket_short = '#' + id
        ticket_short = tag.a(ticket_short, href=url)
        ticket_short(target='_blank', title_=summary)
        ticket_short = tag.span(ticket_short)
        ticket_short(class_=a_class)

        return ticket,ticket_short
예제 #13
0
파일: macro.py 프로젝트: nyuhuhuu/trachacks
 def expand_macro(self, formatter, name, content, args):
     self.log.debug("SpoilerMacro: expand_macro")
     add_stylesheet(formatter.req, 'spoiler/css/spoiler.css')
     add_javascript(formatter.req, 'spoiler/js/spoiler.js')
     if '\n' in content:
         output = tag.div(class_="spoiler")(format_to_html(self.env, formatter.context,content))
     else:
         output = tag.span(class_="spoiler")(format_to_oneliner(self.env, formatter.context,content))
     self.log.debug("SpoilerMacro: expand_macro output")
     return output
예제 #14
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, 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()

        def getdoc(option_or_section):
            doc = to_unicode(option_or_section.__doc__)
            if doc:
                doc = dgettext(option_or_section.doc_domain, doc)
            return doc

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, getdoc(section))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

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

        def default_cell(option):
            default = option.default
            if default is True:
                default = 'true'
            elif default is False:
                default = 'false'
            elif default == 0:
                default = '0.0' if isinstance(default, float) else '0'
            elif default:
                default = ', '.join(to_unicode(val) for val in default) \
                          if isinstance(default, (list, tuple)) \
                          else to_unicode(default)
            else:
                return tag.td(_("(no default)"), class_='nodefault')
            return tag.td(tag.code(default), class_='default')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context, getdoc(option))),
                        default_cell(option))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
예제 #15
0
파일: wiki.py 프로젝트: nyuhuhuu/trachacks
    def _discussion_attachment_link(self, formatter, namespace, params, label):
        id, name = params.split(':')

        # Create request context.
        context = Context.from_request(formatter.req)
        context.realm = 'discussion-wiki'

        # Get database access.
        db = self.env.get_db_cnx()
        context.cursor = db.cursor()

        if namespace == 'topic-attachment':
            return format_to_html(self.env, context,
              '[attachment:discussion:topic/%s:%s %s]' % (id, name, label))
        elif namespace == 'raw-topic-attachment':
            return format_to_html(self.env, context,
              '[raw-attachment:discussion:topic/%s:%s %s]' % (id, name, label))
        else:
            return tag.a(label, href = formatter.href.discussion('topic', id),
              title = label.replace('"', ''), class_ = 'missing')
예제 #16
0
    def wikipage_to_html(self, text, page_name, req):
        """
        Converts a wiki text to HTML, and makes some replacements in order to fix
        internal and external links and references
        """

        self.env.log.debug('WikiPrint => Start function wikipage_to_html')

        #Remove exclude expressions
        for r in EXCLUDE_RES:
            text = r.sub('', text)
        
        #Escape [[PageOutline]], to avoid wiki processing
        for r in [re.compile(r'\[\[TOC(\(.*\))?\]\]'), re.compile(r'\[\[PageOutline(\(.*\))?\]\]')]:
            text = r.sub('![[pdf-toc]]', text)
            
        for macro in self.omit_macros:
            r = re.compile(r'\[\[' + macro + r'\(.*?\]\]')
            text = r.sub('', text)
            r = re.compile(r'^\{\{\{\r?\n#!' + macro + r'\r?\n(^.*\r?\n)*?^\}\}\}', re.MULTILINE)
            text = r.sub('', text)

        link_format = req.args.get('link_format', None)
            
        if self.omit_links:
            r1 = re.compile(r'\[wiki:(.*?) (.*?)\]')
            text = r1.sub('[\g<2>]', text)            
            r2 = re.compile(r'\[wiki:(.*?)\]')
            text = r2.sub('[\g<1>]', text)            
        elif link_format:
            #Keep links to the same export format
            r = re.compile(r'(?<=\[wiki:)(.*?)(?=(?: .*?)?\])')
            text = r.sub('\g<1>?format=%s&link_format=%s' % (link_format, link_format), text)
            
        if self.rebase_links:
            r = re.compile(r'\[wiki:(.*?)\]')
            text = r.sub('[%s/wiki/\g<1>]' % self.rebase_links, text)

        self.env.log.debug('WikiPrint => Wiki input for WikiPrint: %r' % text)
        
        #First create a Context object from the wiki page
        context = Context(Resource('wiki', page_name), req.abs_href, req.perm)
        context.req = req
        
        #Now convert in that context
        page = format_to_html(self.env, context, text)
        self.env.log.debug('WikiPrint => Wiki to HTML output: %r' % page)
        
        self.env.log.debug('WikiPrint => HTML output for WikiPrint is: %r' % page)
        self.env.log.debug('WikiPrint => Finish function wikipage_to_html')

        return page
예제 #17
0
 def wiki2html(self, wiki):
     """ The easiest way to convert wiki to html """
     req = Mock(href=Href(self.env.abs_href.base),
                abs_href=self.env.abs_href,
                authname='anonymous',
                perm=MockPerm(),
                args={})
     context = Context.from_request(req, 'wiki')
     try:
         html = format_to_html(self.env, context, wiki).encode('utf8','ignore')
     except AttributeError:
         html = wiki
     return html
예제 #18
0
 def renderWiki(self, context, items, convertList):
     '''
     Convert selected wiki fields from the database into html
     Return values to calling application for publishing to the web page. 
     '''
     
     for data_row in items:
         '''
         Index through data row, process select elements of record set.
         '''
         for wikify in convertList:
             data_row[wikify] = format_to_html(self.env, context, data_row[wikify])
     return items
예제 #19
0
파일: macro.py 프로젝트: nyuhuhuu/trachacks
    def expand_macro(self, formatter, name, txt):
	db = self.env.get_db_cnx()


	txt = txt or ''
	args = txt.split(',')

        # strip off quotes and re markers 
        pagename = args[0].replace('"','')
        pagename = pagename.replace('$','')
        pagename = pagename.replace('^','')

        # get the page
        sql  = "SELECT text from wiki where name = '%s' order by version desc limit 1" % pagename
	cs = db.cursor()
	cs.execute(sql )
	
	row = cs.fetchone()
	if row == None:
		return ''
	text = row[0]

        # put in the heading if a style is provided
        if len(args) == 3:
            return tag.div(class_=args[2])(
                                tag.div(class_=args[1])(pagename),
                                format_to_html(self.env,
                                               formatter.context,
                                               text)
                                )
        if len(args) == 2:
            return tag.div(tag.div(class_=args[1])(pagename),
                           format_to_html(self.env,
                                          formatter.context,
                                          text)
                           )
        else:
            return format_to_html(self.env, formatter.context, text)
예제 #20
0
    def expand_macro(self, formatter, name, txt):

        if txt:
            sourcepage = txt.strip('"')
        else:
            sourcepage = 'Fortune Cookies'

        wikiobj = randomwiki(self.env.get_db_cnx())
        pagelist = wikiobj.getentries(sourcepage,1)
        if pagelist[0]:
            pagelist[0] = pagelist[0].replace('*','')
            return format_to_html(self.env,formatter.context,pagelist[0])
        else:
            return "Quotes not found"
예제 #21
0
파일: macro.py 프로젝트: lkraav/trachacks
    def expand_macro(self, formatter, name, content):
        """Called by the formatter when rendering the parsed wiki text."""

        # Parse access rule
        action = permissions = body = lines = None
        multiline = content.find("\n") != -1
        if multiline:
            lines = content.split("\n")
            if not lines[0] or lines[0][0] != '#':
                raise TracError('Missing permission specification')
            match = self.PARSE_RULE.match(lines[0][1:])
            if match:
                action = match.group(1)
                permissions = self.SPLIT_LIST.split(match.group(2).strip())
            else:
                raise TracError("Invalid permission specification: %s" % lines[0][1:])
        else:
            match = self.PARSE_RULE.match(content)
            if match:
                action = match.group(1)
                permissions = self.SPLIT_LIST.split(match.group(2).strip())
                body = match.group(3).lstrip()
                if not body or body[0] != ',':
                    raise TracError("Invalid permission specification: %s" % content)
                body = body[1:]
            else:
                raise TracError("Invalid permission specification: %s" % content)

        # Check access
        allow = None
        if action.lower() == "allow":
            allow = False
            for p in permissions:
                if p in formatter.req.perm:
                    allow = True
                    break
        else:
            allow = True
            for p in permissions:
                if p in formatter.req.perm:
                    allow = False
                    break

        # Process text
        if not allow:
            return ''
        elif multiline:
            return format_to_html(self.env, formatter.context, "\n".join(lines[1:]))
        else:
            return body
예제 #22
0
 def get_macro_descr():
     for macro_provider in formatter.wiki.macro_providers:
         for macro_name in macro_provider.get_macros():
             if content and macro_name != content:
                 continue
             try:
                 descr = macro_provider.get_macro_description(macro_name)
                 descr = format_to_html(self.env, formatter.context,
                                        to_unicode(descr) or '')
             except Exception, e:
                 descr = system_message(_("Error: Can't get description "
                                          "for macro %(name)s",
                                          name=macro_name), e)
             yield (macro_name, descr)
예제 #23
0
파일: macros.py 프로젝트: exocad/exotrac
    def expand_macro(self, formatter, name, content):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(content)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        def getdoc(option_or_section):
            doc = to_unicode(option_or_section.__doc__)
            if doc:
                doc = dgettext(option_or_section.doc_domain, doc)
            return doc

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, getdoc(section))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

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

        def default_cell(option):
            default = option.default
            if default is not None and default != '':
                return tag.td(tag.code(option.dumps(default)),
                              class_='default')
            else:
                return tag.td(_("(no default)"), class_='nodefault')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context, getdoc(option))),
                        default_cell(option),
                        class_='odd' if idx % 2 else 'even')
                 for idx, option in
                    enumerate(sorted(options.get(section, {}).itervalues(),
                                     key=lambda o: o.name))
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
예제 #24
0
파일: macro.py 프로젝트: nyuhuhuu/trachacks
    def expand_macro(self, formatter, name, content):
        """Called by the formatter when rendering the parsed wiki text."""
        if name in LEVELS:
            level = LEVELS[name]

            if level["action"] in formatter.req.perm:
                # authorized
                content = "\n".join((line for line in content.split("\n") if not line.startswith("#:")))
            else:
                # unauthorized
                content = "\n".join((line[2:] for line in content.split("\n") if line.startswith("#:")))

            if content:
                return tag.div(format_to_html(self.env, formatter.context, content), style=level["style"])
            else:
                return ""
예제 #25
0
def _get_wiki_html(env, data, is_new_ticket):
  wiki_page = is_new_ticket and NEW_TICKET_PAGE_NAME or MODIFY_TICKET_PAGE_NAME
  page = WikiPage(env, wiki_page)
  if len(page.text) != 0:
    text = page.text
  else:
    if is_new_ticket:
      text = 'No ticket guidelines for creating a new ticket have been specified. ' \
             'Please create [wiki:%s this wiki page] to specify these guidelines.' \
             % NEW_TICKET_PAGE_NAME
    else:
      text = 'No ticket guidelines for modifying a ticket have been specified. ' \
             'Please create [wiki:%s this wiki page] to specify these guidelines.' \
             % MODIFY_TICKET_PAGE_NAME

  return tag.div(format_to_html(env, data['context'], text), class_='ticket-guidelines')
예제 #26
0
    def expand_macro(self, formatter, name, txt):

        (sourcepage,number) = txt.split(',')
        sourcepage = sourcepage.strip('"')
        if number is None:
            number = 1
        else:
            number = int(number)

        out = ''
        wikiobj = randomwiki(self.env.get_db_cnx())
        pagelist = wikiobj.getentries(sourcepage,number)
        for page in pagelist:
            page = self.fixup_images(page,sourcepage)
            out += format_to_html(self.env,formatter.context,page)

        return out
예제 #27
0
    def expand_macro(self, formatter, name, content):
        args = content.split(',')
        num_args = len(args)

        if not (1 <= num_args <= 2):
            raise TracError('Incorrect number of arguments (two required). '
                            'Usage: [[subpage(page, [true/false])]] where '
                            'true/false determines whether or not an Edit '
                            'Section link is shown.')

        page_name = args[0].strip()

        if num_args == 2:
            edit_link = args[1].lower().strip()
            if edit_link not in ('true', 'false'):
                raise TracError('Incorrect second argument (should be "true" '
                                'or "false"). Usage: [[subpage(true/false, '
                                'page)]] where true/false determines whether '
                                'or not an Edit Section link is shown.')
            edit_link = edit_link == 'true'

        else:
            edit_link = True

        # TODO: The error raised if the wiki page
        #       doesn't exist isn't descriptive at all
        wikiparser = formatter.wikiparser
        target_url = wikiparser.link_resolvers['wiki'](formatter,
                                                       'wiki',
                                                       page_name,
                                                       None).attrib.get('href')

        wiki_body = ''
        for page_text, in self.env.db_query("""
                SELECT text FROM wiki WHERE wiki.name=%s
                ORDER BY wiki.version DESC LIMIT 1
                """, (page_name,)):
            wiki_body = format_to_html(self.env, formatter.context, page_text)
            break

        link_tag = Markup('<p><a href="%s?action=edit" class="wiki">'
                          'Edit Section</a></p>' % target_url)

        return wiki_body + (link_tag if edit_link else '')
예제 #28
0
    def expand_macro(self, formatter, name, content):
        num_args = len(content.split(','))

        if not (1 <= num_args <= 2):
            raise TracError(('Incorrect number of arguments (two required). '
                             'Usage: [[subpage(page, [true/false])]] where '
                             'true/false determines whether or not an Edit '
                             'Section link is shown.'))

        wiki_page = content.split(',')[0].strip()

        if num_args == 2:
            edit_link = content.split(',')[1].lower().strip()
            if not edit_link in ('true', 'false'):
                raise TracError(('Incorrect second argument (should be "true" '
                                 'or "false"). Usage: [[subpage(true/false, '
                                 'page)]] where true/false determines whether '
                                 'or not an Edit Section link is shown.'))
            edit_link = edit_link == 'true'

        else:
            edit_link = True

        # TODO: The error raised if the wiki page
        #       doesn't exist isn't descriptive at all
        wikiparser = formatter.wikiparser
        target_url = wikiparser.link_resolvers['wiki'](formatter,
                                                       'wiki',
                                                       wiki_page,
                                                       None).attrib.get('href')

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute(("SELECT text FROM wiki WHERE wiki.name = '%s' ORDER "
                        "BY wiki.version DESC LIMIT 1;") % (wiki_page))

        wiki_body = [page for page in cursor][0][0]
        body = format_to_html(self.env, formatter.context, wiki_body)

        link_tag = ('<p><a href="%s?action=edit" class="wiki">Edit Section</a>'
                    '</p>' % (target_url))

        return unicode(body) + (edit_link and link_tag or '')
예제 #29
0
    def process_request(self, req):
        path = req.path_info[ len("/watchlist/manual") : ].strip('/')
        if path.startswith('attachments'):
            return self.handle_attachment(req, path)

        language = path
        if not language:
            language = req.session.get('language', 'en-US')

        # Try to find a suitable language if no manual exists
        # in the requested one.
        if language not in self.manuals:
            # Try to find a main language,
            # e.g. 'xy' instead of 'xy-ZV'
            l = language.split('-')[0]
            language = 'en-US' # fallback if no other is found
            if l in self.manuals:
                language = l
            else:
                # Prefer 'en-US' before any other English dialect
                if l == 'en' and 'en-US' in self.manuals:
                    language = 'en-US'
                else:
                    # If there is none try to find
                    # any other 'xy-*' language
                    l += '-'
                    for lang in sorted(self.manuals.keys()):
                        if lang.startswith(l):
                            language = lang
                            break
            req.redirect(req.href.watchlist('manual',language))

        try:
            f = open(self.manuals[language], 'r')
            text = to_unicode( f.read() )
        except Exception as e:
            raise HTTPNotFound(e)

        wldict = dict(
                format_text=lambda text: format_to_html(self.env, Context.from_request(req), text),
                text=text)
        return ("watchlist_manual.html", wldict, "text/html")
예제 #30
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, 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 = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, dgettext(section.doc_domain,
                                        to_unicode(section.__doc__)))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

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

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context,
                            dgettext(option.doc_domain,
                                     to_unicode(option.__doc__)))),
                        tag.td(tag.code(option.default or 'false')
                                   if option.default or option.default is False
                                   else _("(no default)"),
                               class_='default' if option.default or 
                                                   option.default is False 
                                                else 'nodefault'))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
예제 #31
0
    def process_request(self, req):

        page_name = req.args.get('page')
        location = req.args.get('location')
        theme = req.args.get('theme', self.default_theme)

        page = WikiPage(self.env, page_name)
        if not page.exists:
            raise TracError('Invalid wiki page "%s"' % page.name)

        page_text = self.fixup_images_re.sub(r'[[Image(wiki:%s:\1)]]'
                                             % page.name, page.text)

        in_section = -1
        text = title = html_title = title_page = handout = ''
        slides = []

        context = Context.from_request(req, page.resource)
        
        for line in page_text.splitlines():
            match = self.heading_re.match(line)
            if match:

                # Insert accumulated text into appropriate location
                if in_section == 1:
                    title_page = format_to_html(self.env, context, text)
                elif in_section == 2:
                    text = self.fixup_re.sub(r'\1', text)
                    slides.append({'body': format_to_html(self.env, context, text),
                                   'handout': format_to_html(self.env, context, handout)})

                if match.lastgroup == 'title':
                    title = match.group(match.lastgroup)
                    html_title = format_to_html(self.env, context, title)
                    title = plaintext(html_title)
                    in_section = 1
                else:
                    in_section = 2
                text = ''

            text += line + '\n'

        if in_section == 1:
            title_page = format_to_html(self.env, context, text)
        elif in_section == 2:
            text = self.fixup_re.sub(r'\1', text)
            slides.append({'body': format_to_html(self.env, context, text),
                           'handout': format_to_html(self.env, context, handout)})

        add_stylesheet(req, 'common/css/code.css')
        add_stylesheet(req, 'common/css/diff.css')
        
        data = {
            'html_title': html_title,
            'location': location,
            'slides': slides,
            'theme': theme,
            'title': title,
            'title_page': title_page
            }

        return 'slideshow.html', data, 'text/html'
예제 #32
0
    def expand_macro(self, formatter, name, content, args=None):
        _start_time = time.time()  # save start time
        _largs, _kwargs = parse_args(content)
        _show_referrers = _largs and 'show_referrers' in _largs
        _ignored_referrers = _kwargs.get('ignored_referrers', None)
        # 'filter' is an alias for option 'ignored_referrers'
        if not _ignored_referrers:
            _ignored_referrers = _kwargs.get('filter', None)
        # default option is 'exclusive' for backward compatibility
        _filtertype = _kwargs.get('filtertype', 'exclusive')
        # get all wiki page names and their content
        self.page_names, self.page_texts = \
            self.get_wiki_pages(_ignored_referrers, _filtertype)
        _ml_parser = MissingLinksHTMLParser()
        # OrderedDict is needed to run test cases, but was only added in Python 2.7
        try:
            _missing_links = OrderedDict()
        except:
            _missing_links = dict()

        for _name, _text in zip(self.page_names, self.page_texts):
            # set up context for relative links
            formatter.resource.id = _name
            # parse formatted wiki page for missing links
            _ml_parser.feed(
                format_to_oneliner(self.env, formatter.context, _text))
            if _ml_parser.data:
                for _page in _ml_parser.data:
                    if _missing_links.has_key(_page):
                        if _missing_links[_page].count(_name) == 0:
                            _missing_links[_page] = _missing_links[_page] + \
                                                        [_name,]
                    else:
                        _missing_links[_page] = [
                            _name,
                        ]
            _ml_parser.reset()

        if _show_referrers:
            _data = '||Missing link||Referrer(s)||\n'
        else:
            _data = '||Missing link||\n'
        _missing_link_count = 0
        for _page in _missing_links:
            _data = _data + '||[[%s]]' % \
                        _page.partition('/wiki/')[2].replace('%20',' ')
            if _show_referrers:
                _first = True
                for _name in _missing_links[_page]:
                    if _first:
                        _data = _data + "||%s" % _name
                        _first = False
                    else:
                        _data = _data + ", %s" % _name
                    _missing_link_count = _missing_link_count + 1
            _data = _data + "||\n"
        # reset context for relative links
        formatter.resource.id = ''
        self.log.debug("Found %d missing pages in %s seconds'" % \
                       (_missing_link_count, (time.time() - _start_time)))
        return format_to_html(self.env, formatter.context, _data)
    def get_summary(self, req, fromdate=None, todate=None):
        def myformat_date(dte):
            if dte:
                return format_date(dte, '%e %b %Y')
            return "No date set"

        def myformat_hours(hrs, fallback='No estimate available'):
            from math import floor
            if hrs:
                hrs = float(hrs)
                if 0 != hrs:
                    neg = False
                    if hrs < 0:
                        neg = True
                        hrs *= -1
                    mins = floor((hrs - floor(hrs)) * 60)
                    s = ''
                    if neg:
                        s = '-'
                    if hrs:
                        s = "%s%sh" % (s, int(floor(hrs)))
                    if mins:
                        s = "%s %sm" % (s, int(mins))
                    return s
            return fallback

        client = self.client
        xml = etree.Element('clientsplugin')

        # Place basic client info here
        xclient = etree.SubElement(xml, 'client')
        etree.SubElement(xclient, 'name').text = client
        if fromdate:
            etree.SubElement(xclient, 'lastupdate').text = \
                myformat_date(fromdate)

        # Information about milestones
        months = {}
        xmonths = etree.SubElement(xml, 'months')

        have_data = False
        # Load in a summary of the client's tickets
        sql = ("""\
          SELECT t.id, t.summary, t.description, t.status,
            SUM(tchng.newvalue) AS totalhours,
            CONCAT(MONTHNAME(FROM_UNIXTIME(tchng.time/1000000)),
            " ",
            YEAR(FROM_UNIXTIME(tchng.time/1000000))) AS month
          FROM ticket_custom AS tcust
          INNER JOIN ticket AS t ON tcust.ticket=t.id
          INNER JOIN ticket_change AS tchng
            ON t.id=tchng.ticket
              AND tchng.field='hours'
              AND tchng.oldvalue=0
          WHERE tcust.name = 'client'
            AND tcust.value = %s
            AND tchng.time >= (UNIX_TIMESTAMP(PERIOD_ADD(EXTRACT(YEAR_MONTH FROM NOW()), -3)*100+1)*1000000)
          GROUP BY t.id, MONTH(FROM_UNIXTIME(tchng.time/1000000))
          ORDER BY tchng.time DESC;
          """)
        xsummary = etree.SubElement(xml, 'summary')
        for tid, summary, description, status, totalhours, month \
                in self.env.db_query(sql, (client,)):
            have_data = True

            if month not in months:
                xmonth = etree.SubElement(xmonths, 'month')
                etree.SubElement(xmonth, 'name').text = month
                months[month] = {'totalhours': 0, 'xml': xmonth}

            # Add hours to create a total.
            months[month]['totalhours'] += float(totalhours)

            self.log.debug("  Summarising ticket #%s in %s", tid, month)
            ticket = etree.SubElement(xsummary, 'ticket')
            etree.SubElement(ticket, 'id').text = str(tid)
            etree.SubElement(ticket, 'summary').text = summary
            ticket.append(
                etree.XML('<description>%s</description>' %
                          format_to_html(self.env, web_context(req),
                                         extract_client_text(description))))
            etree.SubElement(ticket, 'status').text = status
            etree.SubElement(ticket, 'month').text = month

            etree.SubElement(ticket, 'totalhours').text = myformat_hours(
                totalhours, 'None')

        # Put the total hours into the month info
        for month in months:
            etree.SubElement(months[month]['xml'], 'totalhours').\
                text = myformat_hours(months[month]['totalhours'])

        if self.debug:
            with open('/tmp/send-client-email.xml', 'w') as file_:
                file_.write(etree.tostring(xml, pretty_print=True))
            self.log.debug(" Wrote XML to /tmp/send-client-email.xml")

        if not have_data:
            return None

        return xml
예제 #34
0
 def expand_macro(self, formatter, name, content, args=[]):
     try:
         cols = []  # Sentinel
         group = ''  # Sentinel
         groups = {}
         lines = content.split('\r\n')
         for line in lines:
             if line.startswith('||= href =||= '):
                 cols = line[14:].split(' =||= ')
             elif line.startswith('|| group: '):
                 group = line[10:]
                 if group in [u'', u'None']:
                     group = None
                 groups[group] = []  # initialize for the group
             elif line.startswith('|| '):
                 values = iter(line[3:].split(' || '))
                 ticket = {'href': values.next()}
                 for col in cols:
                     ticket[col] = values.next()
                 groups[group].append(ticket)
             else:
                 pass
         ticketsystem = TicketSystem(self.env)
         #
         labels = ticketsystem.get_ticket_field_labels()
         headers = [{
             'name': col,
             'label': labels.get(col, _('Ticket'))
         } for col in cols]
         #
         fields = {}
         ticket_fields = ticketsystem.get_ticket_fields()
         for field in ticket_fields:
             fields[field['name']] = {
                 'label': field['label']
             }  # transform list to expected dict
         # fail safe
         fields[None] = 'NONE'
         for group in groups.keys():
             if not 'group' in fields:
                 fields[group] = group
         #
         group_name = 'group' in args and args['group'] or None
         if group_name not in fields:
             group_name = None
         query = {'group': group_name}
         #
         groups = [(name, groups[name])
                   for name in groups]  # transform dict to expected tuple
         #
         data = {
             'paginator': None,
             'headers': headers,
             'query': query,
             'fields': fields,
             'groups': groups,
         }
         add_stylesheet(formatter.req, 'common/css/report.css')
         chrome = Chrome(self.env)
         data = chrome.populate_data(formatter.req, data)
         template = chrome.load_template('query_results.html')
         content = template.generate(**data)
         # ticket id list as static
         tickets = ''
         if 'id' in cols:
             ticket_id_list = [
                 ticket.get('id') for group in groups for ticket in group[1]
             ]
             if len(ticket_id_list) > 0:
                 tickets = '([ticket:' + ','.join(
                     ticket_id_list) + ' query by ticket id])'
         return tag.div(
             content, format_to_html(self.env, formatter.context, tickets))
     except StopIteration:
         errorinfo = _('Not Enough fields in ticket: %s') % line
     except Exception:
         errorinfo = sys.exc_info()
     return tag.div(tag.div(errorinfo, class_='message'),
                    class_='error',
                    id='content')
예제 #35
0
파일: log.py 프로젝트: mugglecloud/trac
 def _format_to_html(self, authname, wiki):
     resource = Resource('wiki', 'WikiStart')
     req = MockRequest(self.env, authname=authname)
     return str(format_to_html(self.env, web_context(req, resource), wiki))
예제 #36
0
    def get_summary(self, req, fromdate=None, todate=None):
        def myformat_date(dte):
            if dte:
                return format_date(dte, '%e %b %Y')
            return 'No date set'

        def myformat_hours(hrs):
            from math import floor
            if hrs:
                hrs = float(hrs)
                if 0 != hrs:
                    neg = False
                    if hrs < 0:
                        neg = True
                    mins = floor((hrs - floor(hrs)) * 60)
                    str = ''
                    if neg:
                        str = '-'
                    if hrs:
                        str = "%s%sh" % (str, int(floor(hrs)))
                    if mins:
                        str = "%s %sm" % (str, int(mins))
                    return str
            return 'No estimate available'

        client = self.client
        xml = etree.Element('clientsplugin')

        # Place basic client info here
        xclient = etree.SubElement(xml, 'client')
        etree.SubElement(xclient, 'name').text = client
        if fromdate:
            etree.SubElement(xclient,
                             'lastupdate').text = myformat_date(fromdate)

        have_data = False
        # Load in any changes that have happend
        sql = ("""\
          SELECT t.id, t.summary, t.description, t.status, t.resolution,
            t.milestone, m.due, tchng.field, tchng.oldvalue, tchng.newvalue
          FROM ticket_custom tcust
          INNER JOIN ticket AS t ON tcust.ticket=t.id
          INNER JOIN ticket_change AS tchng ON t.id=tchng.ticket
          LEFT JOIN milestone AS m ON t.milestone=m.name
          WHERE tcust.name = 'client'
            AND tcust.value = %s
            AND tchng.field IN ('comment', 'status', 'resolution', 'milestone')
            AND tchng.time >= %s
            AND tchng.time < %s
            AND t.milestone IN (
              SELECT DISTINCT st.milestone
              FROM ticket_custom AS stcust
              INNER JOIN ticket AS st ON stcust.ticket=st.id
              INNER JOIN milestone AS sm ON st.milestone=sm.name
              WHERE stcust.name = tcust.name
              AND stcust.value = tcust.value
              AND sm.due > 0)
          ORDER BY t.time
          """)
        changes = etree.SubElement(xml, 'changes')
        lasttid = 0
        for tid, summary, description, status, resolution, milestone, \
                due, cgfield, oldvalue, newvalue \
                in self.env.db_query(sql, (client, fromdate * 1000000,
                                           todate * 1000000)):
            text = ''
            if 'status' == cgfield:
                text = 'Status changed from "%s" to "%s"' % (oldvalue,
                                                             newvalue)
            elif 'milestone' == cgfield:
                text = 'Milestone changed from "%s" to "%s" - ' \
                       'please check for revised delivery date.' \
                       % (oldvalue, newvalue)
            elif 'resolution' == cgfield:
                if oldvalue and not newvalue:
                    text = 'Resolution removed'
                elif not oldvalue and newvalue:
                    text = 'Resolution set to "%s"' % (newvalue)
                else:
                    text = 'Resolution changed from "%s" to "%s"' % (oldvalue,
                                                                     newvalue)
            elif 'comment' == cgfield:
                # Todo - extract...
                text = extract_client_text(newvalue).strip()
                if '' == text:
                    # No comments for the client here so ignore it.
                    continue
                text = "''Comment for your information:''[[BR]][[BR]]" + text
            else:
                # Client should not know any more than this
                continue

            if self.debug:
                self.log.debug("  Change notification (%s) for ticket #%s",
                               cgfield, tid)
            have_data = True
            if lasttid != tid:
                ticket = etree.SubElement(changes, 'ticket')
                etree.SubElement(ticket, 'id').text = str(tid)
                etree.SubElement(ticket, 'summary').text = summary
                ticket.append(
                    etree.XML(
                        '<description>%s</description>' %
                        format_to_html(self.env, web_context(req),
                                       extract_client_text(description))))
                etree.SubElement(ticket, 'status').text = status
                etree.SubElement(ticket, 'resolution').text = resolution
                etree.SubElement(ticket, 'milestone').text = milestone
                etree.SubElement(ticket, 'due').text = myformat_date(due)
                changelog = etree.SubElement(ticket, 'changelog')

            detail = etree.XML(
                '<detail>%s</detail>' %
                format_to_html(self.env, web_context(req)),
                extract_client_text(description))
            detail.set('field', cgfield)
            if oldvalue:
                detail.set('oldvalue', oldvalue)
            if newvalue:
                detail.set('newvalue', newvalue)
            changelog.append(detail)
            lasttid = tid

        if self.debug:
            file = open('/tmp/send-client-email.xml', 'w')
            file.write(etree.tostring(xml, pretty_print=True))
            file.close()
            self.log.debug(" Wrote XML to /tmp/send-client-email.xml")

        if not have_data:
            return None

        return xml
예제 #37
0
def wiki_to_pdf(text, env, req, base_dir, codepage):
    global IMG_CACHE
    
    env.log.debug('WikiToPdf => Start function wiki_to_pdf')

    #Remove exclude expressions
    for r in EXCLUDE_RES:
        text = r.sub('', text)
    
    env.log.debug('WikiToPdf => Wiki intput for WikiToPdf: %r' % text)
    
    context = Context.from_request(req, resource='wiki', id=req.args.get('page', 'False'))
    page = format_to_html(env, context, text)
    
    page = page.replace('<img', '<img border="0"')
    page = page.replace('?format=raw', '')

    """I need improve this... Ticket #3427"""
    page = page.replace('<a class="wiki" href="/' + env.config.get('wikitopdf', 'folder_name') + '/wiki/', '<a class="wiki" href="' 
			+ env.config.get('wikitopdf', 'link') + '/wiki/')

    page = page.replace('<pre class="wiki">', '<table align="center" width="95%" border="1" bordercolor="#d7d7d7">'
                        + '<tr><td bgcolor="#f7f7f7"><pre class="wiki">')
    page = page.replace('</pre>', '</pre></td></tr></table>')
    page = page.replace('<table class="wiki">', '<table class="wiki" border="1" width="100%">')
    tracuri = env.config.get('wikitopdf', 'trac_uri')
    tmp_dir = env.config.get('wikitopdf', 'tmp_dir')
    
    imgpos = page.find('<img')    
    if tracuri != '' and tmp_dir != '':
        # Download images so that dynamic images also work right
        # Create a random prefix
        random.seed()
        tmp_dir += '/%(#)04x_' %{"#":random.randint(0,65535)}
        # Create temp dir
        os.system('mkdir %s 2>/dev/null' % (tmp_dir))

        imgcounter = 0

        while imgpos != -1:
            addrpos = page.find('src="', imgpos)
            theimg = page[addrpos+5:]
            thepos = theimg.find('"')
            theimg = theimg[:thepos]
            if theimg[:1] == '/':
                theimg = tracuri + theimg
            try:
                newimg = IMG_CACHE[theimg]
            except:    
                #newimg = tmp_dir + '%(#)d_' %{"#":imgcounter} + theimg[theimg.rfind('/')+1:]
                file = NamedTemporaryFile(mode='w', prefix='%(#)d_' %{"#":imgcounter}, dir=tmp_dir)
                newimg = file.name
                file.close()
                theimg = xml.sax.saxutils.unescape(theimg)
                theimg = theimg.replace(" ","%20")
                urlretrieve(theimg, newimg)
                IMG_CACHE[theimg] = newimg
                env.log.debug("ISLAM the image is %s new image is %s" % ( theimg, newimg))
                imgcounter += 1
                page = page[:addrpos+5] + newimg + page[addrpos+5+thepos:]
                simgpos = page.find('<img', addrpos)
    else:
        # Use old search for images in path
        page = page.replace('raw-attachment', 'attachments')
        while imgpos != -1:
            addrpos = page.find('src="', imgpos)
#            base_dir = base_dir.encode('ascii')
            page = page[:addrpos+5] + base_dir + page[addrpos+5:]
            imgpos = page.find('<img', addrpos)
    
    # Add center tags, since htmldoc 1.9 does not handle align="center"
    (tablepos,tableend) = tagattrfind(page, 'table', 'align="center"', 0)
    while tablepos != -1:
        endpos = page.find('</table>',tablepos)
        page = page[:endpos+8] + '</center>' + page[endpos+8:]
        page = page[:tablepos] + '<center>' + page[tablepos:];
        
        endpos = page.find('</table>',tablepos)
        (tablepos,tableend) = tagattrfind(page, 'table', 'align="center"', endpos)

    # Add table around '<div class="code">'
    (tablepos,tableend) = tagattrfind(page, 'div', 'class="code"', 0)
    while tablepos != -1:
        endpos = page.find('</div>',tablepos)
        page = page[:endpos+6] + '</td></tr></table></center>' + page[endpos+6:]
        page = page[:tableend] + '<center><table align="center" width="95%" border="1" bordercolor="#d7d7d7"><tr><td>' + page[tableend:]

        endpos = page.find('</div>',tablepos)
        (tablepos,tableend) = tagattrfind(page, 'div', 'class="code"', endpos)

    # Add table around '<div class="system-message">'
    (tablepos,tableend) = tagattrfind(page, 'div', 'class="system-message"', 0)
    while tablepos != -1:
        endpos = page.find('</div>',tablepos)
        page = page[:endpos+6] + '</td></tr></table>' + page[endpos+6:]
        page = page[:tableend] + '<table width="100%" border="2" bordercolor="#dd0000" bgcolor="#ffddcc"><tr><td>' + page[tableend:]
        
        endpos = page.find('</div>',tablepos)
        (tablepos,tableend) = tagattrfind(page, 'div', 'class="system-message"', endpos)

    # Add table around '<div class="error">'
    (tablepos,tableend) = tagattrfind(page, 'div', 'class="error"', 0)
    while tablepos != -1:
        endpos = page.find('</div>',tablepos)
        page = page[:endpos+6] + '</td></tr></table>' + page[endpos+6:]
        page = page[:tableend] + '<table width="100%" border="2" bordercolor="#dd0000" bgcolor="#ffddcc"><tr><td>' + page[tableend:]

        endpos = page.find('</div>',tablepos)
        (tablepos,tableend) = tagattrfind(page, 'div', 'class="error"', endpos)

    # Add table around '<div class="important">'
    (tablepos,tableend) = tagattrfind(page, 'div', 'class="important"', 0)
    while tablepos != -1:
        endpos = page.find('</div>',tablepos)
        page = page[:endpos+6] + '</td></tr></table>' + page[endpos+6:]
        page = page[:tableend] + '<table width="100%" border="2" bordercolor="#550000" bgcolor="#ffccbb"><tr><td>' + page[tableend:]

        endpos = page.find('</div>',tablepos)
        (tablepos,tableend) = tagattrfind(page, 'div', 'class="important"', endpos)

    meta = ('<meta http-equiv="Content-Type" content="text/html; charset=%s"/>' % codepage)
    css = ''
    if env.config.get('wikitopdf', 'css_file') != '':
        css = ('<link rel="stylesheet" href="%s" type="text/css"/>' % env.config.get('wikitopdf', 'css_file')).encode(codepage)

    page = '<html><head>' + meta + css + '</head><body>' + page + '</body></html>'
    page = page.encode(codepage,'replace')
    
    env.log.debug('WikiToPdf => HTML output for WikiToPdf in charset %s is: %r' % (codepage, page))    
    env.log.debug('WikiToPdf => Finish function wiki_to_pdf')

    return page
예제 #38
0
    def expand_macro(self, formatter, name, text, args):
        template_data = {'css_class': 'trac-kanban-board'}
        template_file = 'kanbanboard.html'
        board = None

        template_data['height'] = '300px'
        if args:
            template_data['height'] = args.get('height', '300px')

        project_name = self.env.path.split('/')[-1]
        page_name = formatter.req.path_info.split('/')[-1]
        is_editable = 'WIKI_MODIFY' in formatter.req.perm and 'TICKET_MODIFY' in formatter.req.perm

        js_globals = {
            'KANBAN_BOARD_ID': page_name,
            'TRAC_PROJECT_NAME': project_name,
            'TRAC_USER_NAME': formatter.req.authname,
            'IS_EDITABLE': is_editable
        }

        if not self.ticket_fields:
            self.ticket_fields = TicketSystem(self.env).get_ticket_fields()

        if text is None:
            template_data['error'] = 'Board data is not defined'
            template_data['usage'] = format_to_html(self.env,
                                                    formatter.context,
                                                    self.__doc__)
        else:
            try:
                board = KanbanBoard(page_name, [], self.ticket_fields,
                                    self.env, self.log)
            except InvalidDataError as e:
                template_data['error'] = e.msg
                template_data['usage'] = format_to_html(
                    self.env, formatter.context, self.__doc__)
            except InvalidFieldError as e:
                template_data[
                    'error'] = 'Invalid ticket fields: %s' % ', '.join(
                        e.fields)
                valid_fields = map(lambda x: x['name'], self.ticket_fields)
                template_data[
                    'usage'] = 'Valid field names are: %s.' % ', '.join(
                        valid_fields)

        if board:
            # TICKET_FIELDS is comma-separated list of user defined ticket field names
            js_globals['TICKET_FIELDS'] = board.get_field_string()

        add_stylesheet(formatter.req, 'trackanbanboard/css/kanbanboard.css')
        add_script_data(formatter.req, js_globals)

        if 'error' in template_data:
            template_file = 'kanbanerror.html'
        else:
            add_script(formatter.req,
                       'trackanbanboard/js/libs/jquery-1.8.3.js')
            add_script(
                formatter.req,
                'trackanbanboard/js/libs/jquery-ui-1.9.2.custom.min.js')
            add_script(formatter.req,
                       'trackanbanboard/js/libs/knockout-2.2.0.js')
            add_script(formatter.req,
                       'trackanbanboard/js/libs/knockout.mapping.js')
            add_script(formatter.req,
                       'trackanbanboard/js/libs/knockout-sortable.min.js')
            add_script(formatter.req, 'trackanbanboard/js/kanbanutil.js')
            add_script(formatter.req, 'trackanbanboard/js/kanbanboard.js')
            add_stylesheet(
                formatter.req,
                'trackanbanboard/css/jquery-ui-1.9.2.custom.min.css')

        return Chrome(self.env).render_template(
            formatter.req, template_file, template_data, None,
            fragment=True).render(strip_whitespace=False)
예제 #39
0
 def _format_to_html(self, context, wikidom, **options):
     return format_to_html(self.env, context, wikidom, **options)
예제 #40
0
파일: macros.py 프로젝트: neverpanic/trac
    def expand_macro(self, formatter, name, content):
        from trac.config import ConfigSection, Option

        args, kw = parse_args(content)
        filters = {}
        for name, index in (('section', 0), ('option', 1)):
            pattern = kw.get(name, '').strip()
            if pattern:
                filters[name] = fnmatch.translate(pattern)
                continue
            prefix = args[index].strip() if index < len(args) else ''
            if prefix:
                filters[name] = re.escape(prefix)
        has_option_filter = 'option' in filters
        for name in ('section', 'option'):
            filters[name] = re.compile(filters[name], re.IGNORECASE).match \
                            if name in filters \
                            else lambda v: True
        section_filter = filters['section']
        option_filter = filters['option']

        section_registry = ConfigSection.get_registry(self.compmgr)
        option_registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in option_registry.iteritems():
            if section_filter(section) and option_filter(key):
                options.setdefault(section, {})[key] = option
        if not has_option_filter:
            for section in section_registry:
                if section_filter(section):
                    options.setdefault(section, {})
        for section in options:
            options[section] = sorted(options[section].itervalues(),
                                      key=lambda option: option.name)
        sections = [(section, section_registry[section].doc
                     if section in section_registry else '')
                    for section in sorted(options)]

        def default_cell(option):
            default = option.default
            if default is not None and default != '':
                return tag.td(tag.code(option.dumps(default)),
                              class_='default')
            else:
                return tag.td(_("(no default)"), class_='nodefault')

        def options_table(section, options):
            if options:
                return tag.table(class_='wiki')(tag.tbody(
                    tag.tr(tag.td(
                        tag.a(tag.code(option.name),
                              class_='tracini-option',
                              href='#%s-%s-option' % (section, option.name))),
                           tag.td(
                               format_to_html(self.env, formatter.context,
                                              option.doc)),
                           default_cell(option),
                           id='%s-%s-option' % (section, option.name),
                           class_='odd' if idx % 2 else 'even')
                    for idx, option in enumerate(options)))

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             options_table(section, options.get(section)))
            for section, section_doc in sections)
    def get_summary(self, req, fromdate=None, todate=None):
        def myformat_date(dte):
            if dte:
                return format_date(dte, '%e %b %Y')
            return 'No date set'

        def myformat_hours(hrs, fallback='No estimate available'):
            from math import floor
            if hrs:
                hrs = float(hrs)
                if 0 != hrs:
                    neg = False
                    if hrs < 0:
                        neg = True
                        hrs *= -1
                    mins = floor((hrs - floor(hrs)) * 60)
                    s = ''
                    if neg:
                        s = '-'
                    if hrs:
                        s = "%s%sh" % (s, int(floor(hrs)))
                    if mins:
                        s = "%s %sm" % (s, int(mins))
                    return s
            return fallback

        client = self.client
        xml = etree.Element('clientsplugin')

        # Place basic client info here
        xclient = etree.SubElement(xml, 'client')
        etree.SubElement(xclient, 'name').text = client
        if fromdate:
            etree.SubElement(xclient, 'lastupdate').text = \
                myformat_date(fromdate)

        # Information about milestones
        milestones = {}
        xmilestones = etree.SubElement(xml, 'milestones')

        db = self.env.get_read_db()
        have_data = False
        # Load in a summary of the client's tickets
        sql = ("""\
          SELECT t.id, t.summary, t.description, t.status, t.milestone,
            m.due, m.completed, m.description AS mdesc,
            tcust2.value AS estimatedhours, tcust3.value AS totalhours
          FROM ticket_custom AS tcust
          INNER JOIN ticket AS t ON tcust.ticket=t.id
          LEFT JOIN ticket_custom AS tcust2
           ON t.id=tcust2.ticket AND tcust2.name='estimatedhours'
          LEFT JOIN ticket_custom AS tcust3
           ON t.id=tcust3.ticket AND tcust3.name='totalhours'
          LEFT JOIN milestone m ON t.milestone=m.name
          WHERE tcust.name = 'client'
            AND tcust.value = %s
            AND t.milestone IN (
              SELECT DISTINCT st.milestone
              FROM ticket_custom AS stcust
              INNER JOIN ticket AS st ON stcust.ticket=st.id
              INNER JOIN milestone AS sm ON st.milestone=sm.name
              WHERE stcust.name = tcust.name
              AND stcust.value = tcust.value
              AND (sm.due > %s OR sm.completed > %s))
          ORDER BY m.due ASC
          """)
        now = int(time.time() * 1000000)
        now2 = now - (7 * 24 * 60 * 60 * 1000000)
        xsummary = etree.SubElement(xml, 'summary')
        for tid, summary, description, status, milestone, due, completed, \
                mdescription, estimatedhours, totalhours \
                in self.env.db_query(sql, (client, now, now2)):
            have_data = True
            if milestone:
                if milestone not in milestones:
                    xmilestone = etree.SubElement(xmilestones, 'milestone')
                    etree.SubElement(xmilestone, 'name').text = milestone
                    etree.SubElement(xmilestone, 'duetimestamp').text = \
                        str(due)
                    etree.SubElement(xmilestone, 'due').text = \
                        myformat_date(due)
                    if completed:
                        etree.SubElement(xmilestone, 'completed').text = \
                            myformat_date(completed)
                    if mdescription:
                        wdescription = \
                            format_to_html(self.env,
                                           web_context(req),
                                           extract_client_text(mdescription))
                        xmilestone.append(
                            etree.XML('<description>%s</description>' %
                                      wdescription))
                    else:
                        etree.SubElement(xmilestone, 'description').text = ''
                    # Store for use
                    milestones[milestone] = {'hours': 0, 'xml': xmilestone}

                # Add hours to create a total.
                if estimatedhours:
                    milestones[milestone]['hours'] += float(estimatedhours)

            self.log.debug("  Summarising ticket #%s", tid)
            ticket = etree.SubElement(xsummary, 'ticket')
            etree.SubElement(ticket, 'id').text = str(tid)
            etree.SubElement(ticket, 'summary').text = summary
            text = format_to_html(self.env, web_context(req),
                                  extract_client_text(description))
            ticket.append(etree.XML('<description>%s</description>' % text))
            etree.SubElement(ticket, 'status').text = status
            etree.SubElement(ticket, 'milestone').text = milestone
            # For convenience, put the date here too (keeps the XSLTs simpler)
            etree.SubElement(ticket, 'due').text = myformat_date(due)
            if estimatedhours:
                etree.SubElement(ticket, 'estimatedhours').text = \
                    myformat_hours(estimatedhours)

            if totalhours:
                etree.SubElement(ticket, 'totalhours').text = \
                    myformat_hours(totalhours, 'None')

        # Put the total hours into the milestone info
        for milestone in milestones:
            etree.SubElement(milestones[milestone]['xml'], 'estimatedhours'). \
                text = myformat_hours(milestones[milestone]['hours'])

        if self.debug:
            with open('/tmp/send-client-email.xml', 'w') as file_:
                file_.write(etree.tostring(xml, pretty_print=True))
            self.log.debug(" Wrote XML to /tmp/send-client-email.xml")

        if not have_data:
            return None

        return xml
예제 #42
0
 def expand_macro(self, formatter, name, content):
     return '<fieldset class="client"><legend>' \
            'Comments to Client</legend>%s</fieldset>' \
            % format_to_html(self.env, web_context(formatter.req), content)
예제 #43
0
파일: api.py 프로젝트: tutybukuny/trac
 def render(self, context, mimetype, content, filename=None, url=None):
     from trac.wiki.formatter import format_to_html
     return format_to_html(self.env, context,
                           content_to_unicode(self.env, content, mimetype))
예제 #44
0
 def render_property(self, name, mode, context, props):
     if name in self.wiki_properties:
         return format_to_html(self.env, context, props[name])
     else:
         return format_to_oneliner(self.env, context, props[name])