示例#1
0
 def process_request(self, req):
     # !!!: Wow, this is hackish. <NPK>
     add_stylesheet(req, 'common/css/wiki.css')
     wiki_hdf = HDFWrapper()
     wiki_hdf.readString(req.__CACHED_PAGE)
     req.hdf.copy('wiki', wiki_hdf.hdf)
     return 'wiki.cs', None
示例#2
0
    def test_icon_links(self):
        env = EnvironmentStub()
        req = Mock(hdf=HDFWrapper(), cgi_location='/trac.cgi', path_info='')

        # No icon set in config, so no icon links
        env.config.set('project', 'icon', '')
        Chrome(env).populate_hdf(req, None)
        assert 'chrome.links.icon' not in req.hdf
        assert 'chrome.links.shortcut icon' not in req.hdf

        # Relative URL for icon config option
        env.config.set('project', 'icon', 'trac.ico')
        Chrome(env).populate_hdf(req, None)
        self.assertEqual('/trac.cgi/chrome/common/trac.ico',
                         req.hdf['chrome.links.icon.0.href'])
        self.assertEqual('/trac.cgi/chrome/common/trac.ico',
                         req.hdf['chrome.links.shortcut icon.0.href'])

        # URL relative to the server root for icon config option
        req.hdf = HDFWrapper()
        env.config.set('project', 'icon', '/favicon.ico')
        Chrome(env).populate_hdf(req, None)
        self.assertEqual('/favicon.ico', req.hdf['chrome.links.icon.0.href'])
        self.assertEqual('/favicon.ico',
                         req.hdf['chrome.links.shortcut icon.0.href'])

        # Absolute URL for icon config option
        req.hdf = HDFWrapper()
        env.config.set('project', 'icon', 'http://example.com/favicon.ico')
        Chrome(env).populate_hdf(req, None)
        self.assertEqual('http://example.com/favicon.ico',
                         req.hdf['chrome.links.icon.0.href'])
        self.assertEqual('http://example.com/favicon.ico',
                         req.hdf['chrome.links.shortcut icon.0.href'])
示例#3
0
    def test_logo(self):
        env = EnvironmentStub()
        req = Mock(hdf=HDFWrapper(), cgi_location='/trac.cgi', path_info='')

        # Verify that no logo data is put in the HDF if no logo is configured
        env.config.set('header_logo', 'src', '')
        Chrome(env).populate_hdf(req, None)
        assert 'chrome.logo.src' not in req.hdf

        # Test with a relative path to the logo image
        req.hdf = HDFWrapper()
        env.config.set('header_logo', 'src', 'foo.png')
        Chrome(env).populate_hdf(req, None)
        self.assertEqual('/trac.cgi/chrome/common/foo.png',
                         req.hdf['chrome.logo.src'])

        # Test with a server-relative path to the logo image
        req.hdf = HDFWrapper()
        env.config.set('header_logo', 'src', '/img/foo.png')
        Chrome(env).populate_hdf(req, None)
        self.assertEqual('/img/foo.png', req.hdf['chrome.logo.src'])

        # Test with an absolute path to the logo image
        req.hdf = HDFWrapper()
        env.config.set('header_logo', 'src', 'http://www.example.org/foo.png')
        Chrome(env).populate_hdf(req, None)
        self.assertEqual('http://www.example.org/foo.png',
                         req.hdf['chrome.logo.src'])
示例#4
0
 def process_request(self, req):
     # !!!: Wow, this is hackish. <NPK>
     add_stylesheet(req, 'common/css/wiki.css')
     wiki_hdf = HDFWrapper()
     wiki_hdf.readString(req.__CACHED_PAGE)
     req.hdf.copy('wiki', wiki_hdf.hdf)
     return 'wiki.cs', None
示例#5
0
def send_project_index(req, options, env_paths=None):
    from trac.web.clearsilver import HDFWrapper

    if 'TRAC_ENV_INDEX_TEMPLATE' in options:
        tmpl_path, template = os.path.split(options['TRAC_ENV_INDEX_TEMPLATE'])

        from trac.config import default_dir
        req.hdf = HDFWrapper(loadpaths=[default_dir('templates'), tmpl_path])

        tmpl_vars = {}
        if 'TRAC_TEMPLATE_VARS' in options:
            for pair in options['TRAC_TEMPLATE_VARS'].split(','):
                key, val = pair.split('=')
                req.hdf[key] = val
    else:
        req.hdf = HDFWrapper()
        template = req.hdf.parse('''<html>
<head><title>Available Projects</title></head>
<body><h1>Available Projects</h1><ul><?cs
 each:project = projects ?><li><?cs
  if:project.href ?>
   <a href="<?cs var:project.href ?>" title="<?cs var:project.description ?>">
    <?cs var:project.name ?></a><?cs
  else ?>
   <small><?cs var:project.name ?>: <em>Error</em> <br />
   (<?cs var:project.description ?>)</small><?cs
  /if ?>
  </li><?cs
 /each ?></ul></body>
</html>''')

    if not env_paths and 'TRAC_ENV_PARENT_DIR' in options:
        dir = options['TRAC_ENV_PARENT_DIR']
        env_paths = [os.path.join(dir, f) for f in os.listdir(dir)]

    href = Href(req.idx_location)
    try:
        projects = []
        for env_path in env_paths:
            if not os.path.isdir(env_path):
                continue
            env_dir, project = os.path.split(env_path)
            try:
                env = _open_environment(env_path)
                proj = {
                    'name': env.config.get('project', 'name'),
                    'description': env.config.get('project', 'descr'),
                    'href': href(project)
                }
            except Exception, e:
                proj = {'name': project, 'description': str(e)}
            projects.append(proj)
        projects.sort(lambda x, y: cmp(x['name'], y['name']))
        req.hdf['projects'] = projects

        # TODO maybe this should be 404 if index wasn't specifically requested
        req.display(template, response=200)
示例#6
0
    def test_nav_contributor_order(self):
        class TestNavigationContributor1(Component):
            implements(INavigationContributor)

            def get_active_navigation_item(self, req):
                return None

            def get_navigation_items(self, req):
                yield 'metanav', 'test1', 'Test 1'

        class TestNavigationContributor2(Component):
            implements(INavigationContributor)

            def get_active_navigation_item(self, req):
                return None

            def get_navigation_items(self, req):
                yield 'metanav', 'test2', 'Test 2'

        env = EnvironmentStub(
            enable=[TestNavigationContributor1, TestNavigationContributor2])
        req = Mock(hdf=HDFWrapper(), path_info='/', cgi_location='/trac.cgi')
        chrome = Chrome(env)

        # Test with both items set in the order option
        env.config.set('trac', 'metanav', 'test2, test1')
        chrome.populate_hdf(req, None)
        node = req.hdf.getObj('chrome.nav.metanav').child()
        self.assertEqual('test2', node.name())
        self.assertEqual('test1', node.next().name())

        # Test with only test1 in the order options
        req.hdf = HDFWrapper()
        env.config.set('trac', 'metanav', 'test1')
        chrome.populate_hdf(req, None)
        node = req.hdf.getObj('chrome.nav.metanav').child()
        self.assertEqual('test1', node.name())
        self.assertEqual('test2', node.next().name())

        # Test with only test2 in the order options
        req.hdf = HDFWrapper()
        env.config.set('trac', 'metanav', 'test2')
        chrome.populate_hdf(req, None)
        node = req.hdf.getObj('chrome.nav.metanav').child()
        self.assertEqual('test2', node.name())
        self.assertEqual('test1', node.next().name())

        # Test with none in the order options (order corresponds to
        # registration order)
        req.hdf = HDFWrapper()
        env.config.set('trac', 'metanav', 'foo, bar')
        chrome.populate_hdf(req, None)
        node = req.hdf.getObj('chrome.nav.metanav').child()
        self.assertEqual('test1', node.name())
        self.assertEqual('test2', node.next().name())
示例#7
0
    def render(self, req, mimetype, content, filename=None, rev=None):
        from trac.web.clearsilver import HDFWrapper

        content = content_to_unicode(self.env, content, mimetype)
        d = self._diff_to_hdf(content.splitlines(),
                              Mimeview(self.env).tab_width)
        if not d:
            raise TracError, u'Contenu diff unifié invalide'
        hdf = HDFWrapper(loadpaths=[self.env.get_templates_dir(),
                                    self.config.get('trac', 'templates_dir')])
        hdf['diff.files'] = d

        add_stylesheet(req, 'common/css/diff.css')
        return hdf.render(hdf.parse(self.diff_cs))
示例#8
0
    def render(self, req, mimetype, content, filename=None, rev=None):
        from trac.web.clearsilver import HDFWrapper

        content = content_to_unicode(self.env, content, mimetype)
        d = self._diff_to_hdf(content.splitlines(),
                              Mimeview(self.env).tab_width)
        if not d:
            raise TracError, 'Invalid unified diff content'
        hdf = HDFWrapper(loadpaths=[self.env.get_templates_dir(),
                                    self.config.get('trac', 'templates_dir')])
        hdf['diff.files'] = d

        add_stylesheet(req, 'common/css/diff.css')
        return hdf.render(hdf.parse(self.diff_cs))
示例#9
0
    def render(self, req, mimetype, content, filename=None, rev=None):
        from trac.web.clearsilver import HDFWrapper

        tabwidth = int(self.config.get('diff', 'tab_width'))
        d = self._diff_to_hdf(content.splitlines(), tabwidth)
        if not d:
            raise TracError, 'Invalid unified diff content'
        hdf = HDFWrapper(loadpaths=[
            self.env.get_templates_dir(),
            self.config.get('trac', 'templates_dir')
        ])
        hdf['diff.files'] = d

        add_stylesheet(req, 'common/css/diff.css')
        return hdf.render(hdf.parse(self.diff_cs))
示例#10
0
    def render_summary(self, req, config, build, step, category):
        assert category == 'lint'
        #assert category in ('lint', 'pylint', 'nblint')

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("""
SELECT MAX(lint_file.value) AS file, MAX(CAST(lint_line.value as INT)) AS line,
       MAX(lint_type.value) AS type, MAX(lint_tag.value) AS tag,
       MAX(lint_msg.value) AS msg, MAX(lint_category.value) as cat
FROM bitten_report AS report
  LEFT OUTER JOIN bitten_report_item AS lint_file
    ON(lint_file.report=report.id AND lint_file.name='file')
  LEFT OUTER JOIN bitten_report_item AS lint_line
    ON(lint_line.report=report.id AND
       lint_line.item=lint_file.item AND lint_line.name='line')
  LEFT OUTER JOIN bitten_report_item AS lint_type
    ON(lint_type.report=report.id AND
       lint_type.item=lint_file.item AND lint_type.name='type')
  LEFT OUTER JOIN bitten_report_item AS lint_tag
    ON(lint_tag.report=report.id AND
       lint_tag.item=lint_file.item AND lint_tag.name='tag')
  LEFT OUTER JOIN bitten_report_item AS lint_msg
    ON(lint_msg.report=report.id AND
       lint_msg.item=lint_file.item AND lint_msg.name='msg')
  LEFT OUTER JOIN bitten_report_item AS lint_category
    ON(lint_category.report=report.id AND
       lint_category.item=lint_file.item AND lint_category.name='category')
WHERE category=%s AND build=%s AND step=%s
GROUP BY lint_file.value, lint_line.value, lint_type.value
ORDER BY file, line, type""", (category, build.id, step.name))

        data = []
        for fname, line, ltype, tag, msg, cat in cursor:
            data.append(
                {
                    'href': self.env.href.browser(config.path, fname),
                    'file': fname,
                    'line': line,
                     'type': ltype,
                     'tag': tag,
                     'msg': msg,
                     'cat': cat
                }
            )
        hdf = HDFWrapper(loadpaths=Chrome(self.env).get_all_templates_dirs())
        hdf['data'] = data
        return hdf.render('nosebitten_pylint_summary.cs')
示例#11
0
 def test_add_link_advanced(self):
     req = Mock(hdf=HDFWrapper())
     add_link(req, 'start', '/trac/wiki', 'Start page', 'text/html', 'home')
     self.assertEqual('/trac/wiki', req.hdf['chrome.links.start.0.href'])
     self.assertEqual('Start page', req.hdf['chrome.links.start.0.title'])
     self.assertEqual('text/html', req.hdf['chrome.links.start.0.type'])
     self.assertEqual('home', req.hdf['chrome.links.start.0.class'])
示例#12
0
 def __init__(self, env):
     self.env = env
     self.config = env.config
     self.db = env.get_db_cnx()
     self.hdf = HDFWrapper(loadpaths=[env.get_templates_dir(),
                                      self.config.get('trac', 'templates_dir')])
     populate_hdf(self.hdf, env)
示例#13
0
def send_project_index(environ,
                       start_response,
                       parent_dir=None,
                       env_paths=None):
    req = Request(environ, start_response)

    loadpaths = [pkg_resources.resource_filename('trac', 'templates')]
    use_clearsilver = False
    if req.environ.get('trac.env_index_template'):
        tmpl_path, template = os.path.split(
            req.environ['trac.env_index_template'])
        loadpaths.insert(0, tmpl_path)
        use_clearsilver = template.endswith('.cs')  # assume Clearsilver
        if use_clearsilver:
            req.hdf = HDFWrapper(
                loadpaths)  # keep that for custom .cs templates
    else:
        template = 'index.html'

    data = {
        'trac': {
            'version': TRAC_VERSION,
            'time': format_datetime()
        },
        'req': req
    }
    if req.environ.get('trac.template_vars'):
        for pair in req.environ['trac.template_vars'].split(','):
            key, val = pair.split('=')
            data[key] = val
            if use_clearsilver:
                req.hdf[key] = val
    try:
        href = Href(req.base_path)
        projects = []
        for env_name, env_path in get_environments(environ).items():
            try:
                env = open_environment(env_path,
                                       use_cache=not environ['wsgi.run_once'])
                proj = {
                    'env': env,
                    'name': env.project_name,
                    'description': env.project_description,
                    'href': href(env_name)
                }
            except Exception, e:
                proj = {'name': env_name, 'description': to_unicode(e)}
            projects.append(proj)
        projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))

        data['projects'] = projects
        if use_clearsilver:
            req.hdf['projects'] = projects
            req.display(template)

        loader = TemplateLoader(loadpaths, variable_lookup='lenient')
        tmpl = loader.load(template)
        stream = tmpl.generate(**data)
        output = stream.render('xhtml', doctype=DocType.XHTML_STRICT)
        req.send(output, 'text/html')
示例#14
0
    def __init__(self, env):
        self.env = env
        self.config = env.config
        self.db = env.get_db_cnx()

        loadpaths = Chrome(self.env).get_all_templates_dirs()
        self.hdf = HDFWrapper(loadpaths)
        populate_hdf(self.hdf, env)
示例#15
0
 def setUp(self):
     self.env = EnvironmentStub()
     self.ticket_module = TicketModule(self.env)
     self.mimeview = Mimeview(self.env)
     self.req = Mock(hdf=HDFWrapper(['./templates']),
                     base_path='/trac.cgi',
                     path_info='',
                     href=Href('/trac.cgi'))
示例#16
0
def send_pretty_error(e, env, req=None):
    """Send a "pretty" HTML error page to the client."""
    import traceback
    import StringIO
    tb = StringIO.StringIO()
    traceback.print_exc(file=tb)
    if not req:
        from trac.web.cgi_frontend import CGIRequest
        from trac.web.clearsilver import HDFWrapper
        req = CGIRequest()
        req.authname = ''
        req.hdf = HDFWrapper()
    try:
        if not env:
            from trac.env import open_environment
            env = open_environment()
            env.href = Href(req.cgi_location)
        if env and env.log:
            env.log.exception(e)
        populate_hdf(req.hdf, env, req)

        if isinstance(e, TracError):
            req.hdf['title'] = e.title or 'Error'
            req.hdf['error.title'] = e.title or 'Error'
            req.hdf['error.type'] = 'TracError'
            req.hdf['error.message'] = e.message
            if e.show_traceback:
                req.hdf['error.traceback'] = escape(tb.getvalue())
            req.display('error.cs', response=500)

        elif isinstance(e, PermissionError):
            req.hdf['title'] = 'Permission Denied'
            req.hdf['error.type'] = 'permission'
            req.hdf['error.action'] = e.action
            req.hdf['error.message'] = e
            req.display('error.cs', response=403)

        else:
            req.hdf['title'] = 'Oops'
            req.hdf['error.type'] = 'internal'
            req.hdf['error.message'] = escape(str(e))
            req.hdf['error.traceback'] = escape(tb.getvalue())
            req.display('error.cs', response=500)

    except RequestDone:
        pass
    except Exception, e2:
        if env and env.log:
            env.log.error('Failed to render pretty error page: %s', e2,
                          exc_info=True)
        req.send_response(500)
        req.send_header('Content-Type', 'text/plain')
        req.end_headers()
        req.write('Oops...\n\nTrac detected an internal error:\n\n')
        req.write(str(e))
        req.write('\n')
        req.write(tb.getvalue())
示例#17
0
 def test_default_links(self):
     env = EnvironmentStub()
     req = Mock(hdf=HDFWrapper(), cgi_location='/trac.cgi', path_info='')
     Chrome(env).populate_hdf(req, None)
     self.assertEqual('/trac.cgi/wiki',
                      req.hdf['chrome.links.start.0.href'])
     self.assertEqual('/trac.cgi/search',
                      req.hdf['chrome.links.search.0.href'])
     self.assertEqual('/trac.cgi/wiki/TracGuide',
                      req.hdf['chrome.links.help.0.href'])
     self.assertEqual('/trac.cgi/chrome/common/css/trac.css',
                      req.hdf['chrome.links.stylesheet.0.href'])
示例#18
0
    def test_nav_contributor_active(self):
        class TestNavigationContributor(Component):
            implements(INavigationContributor)

            def get_active_navigation_item(self, req):
                return 'test'

            def get_navigation_items(self, req):
                yield 'metanav', 'test', 'Test'

        env = EnvironmentStub(enable=[TestNavigationContributor])
        req = Mock(hdf=HDFWrapper(), path_info='/', cgi_location='/trac.cgi')
        chrome = Chrome(env)
        chrome.populate_hdf(req, TestNavigationContributor(env))
        self.assertEqual('Test', req.hdf['chrome.nav.metanav.test'])
        self.assertEqual('1', req.hdf['chrome.nav.metanav.test.active'])
示例#19
0
 def _test_import(self, env, filename, sheet=1):
     req = Request(
         {
             'SERVER_PORT': 0,
             'SERVER_NAME': 'any',
             'wsgi.url_scheme': 'any',
             'wsgi.input': 'any',
             'REQUEST_METHOD': 'GET'
         }, lambda x, y: _printme)
     try:
         from trac.test import MockPerm
         req.perm = MockPerm()
     except ImportError:
         pass
     req.authname = 'testuser'
     req.hdf = HDFWrapper(
         []
     )  # replace by this if you want to generate HTML: req.hdf = HDFWrapper(loadpaths=chrome.get_all_templates_dirs())
     db = env.get_db_cnx()
     cursor = db.cursor()
     _exec(cursor, "select * from enum")
     enums_before = cursor.fetchall()
     _exec(cursor, "select * from component")
     components_before = cursor.fetchall()
     #print enums_before
     # when testing, always use the same time so that the results are comparable
     #print "importing " + filename + " with tickettime " + str(ImporterTestCase.TICKET_TIME)
     template, content_type = ImportModule(env)._do_import(
         filename, sheet, req, filename, ImporterTestCase.TICKET_TIME)
     #sys.stdout = tempstdout
     #req.display(template, content_type or 'text/html')
     #open('/tmp/out.html', 'w').write(req.hdf.render(template, None))
     _exec(cursor, "select * from ticket")
     tickets = cursor.fetchall()
     _exec(cursor, "select * from ticket_custom")
     tickets_custom = cursor.fetchall()
     _exec(cursor, "select * from ticket_change")
     tickets_change = cursor.fetchall()
     _exec(cursor, "select * from enum")
     enums = [f for f in set(cursor.fetchall()) - set(enums_before)]
     _exec(cursor, "select * from component")
     components = [
         f for f in set(cursor.fetchall()) - set(components_before)
     ]
     pp = pprint.PrettyPrinter(indent=4)
     return pp.pformat(
         [tickets, tickets_custom, tickets_change, enums, components])
示例#20
0
def send_project_index(environ,
                       start_response,
                       parent_dir=None,
                       env_paths=None):
    from trac.config import default_dir

    req = Request(environ, start_response)

    loadpaths = [default_dir('templates')]
    if req.environ.get('trac.env_index_template'):
        tmpl_path, template = os.path.split(
            req.environ['trac.env_index_template'])
        loadpaths.insert(0, tmpl_path)
    else:
        template = 'index.cs'
    req.hdf = HDFWrapper(loadpaths)

    tmpl_vars = {}
    if req.environ.get('trac.template_vars'):
        for pair in req.environ['trac.template_vars'].split(','):
            key, val = pair.split('=')
            req.hdf[key] = val

    if parent_dir and not env_paths:
        env_paths = dict([(filename, os.path.join(parent_dir, filename))
                          for filename in os.listdir(parent_dir)])

    try:
        href = Href(req.base_path)
        projects = []
        for env_name, env_path in get_environments(environ).items():
            try:
                env = _open_environment(env_path,
                                        run_once=environ['wsgi.run_once'])
                proj = {
                    'name': env.project_name,
                    'description': env.project_description,
                    'href': href(env_name)
                }
            except Exception, e:
                proj = {'name': env_name, 'description': to_unicode(e)}
            projects.append(proj)
        projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))

        req.hdf['projects'] = projects
        req.display(template)
示例#21
0
    def dispatch(self, req):
        """Find a registered handler that matches the request and let it process
        it.
        
        In addition, this method initializes the HDF data set and adds the web
        site chrome.
        """
        req.authname = self.authenticate(req)
        req.perm = PermissionCache(self.env, req.authname)

        chrome = Chrome(self.env)
        req.hdf = HDFWrapper(loadpaths=chrome.get_all_templates_dirs())
        populate_hdf(req.hdf, self.env, req)

        newsession = req.args.has_key('newsession')
        req.session = Session(self.env, req, newsession)

        # Select the component that should handle the request
        chosen_handler = None
        default_handler = None
        if not req.path_info or req.path_info == '/':
            default_handler = self.config.get('trac', 'default_handler')
        for handler in self.handlers:
            if handler.match_request(req) or \
               handler.__class__.__name__ == default_handler:
                chosen_handler = handler
                break

        chrome.populate_hdf(req, chosen_handler)

        if not chosen_handler:
            # FIXME: Should return '404 Not Found' to the client
            raise TracError, 'No handler matched request to %s' % req.path_info

        try:
            resp = chosen_handler.process_request(req)
            if resp:
                template, content_type = resp
                if not content_type:
                    content_type = 'text/html'

                req.display(template, content_type or 'text/html')
        finally:
            # Give the session a chance to persist changes
            req.session.save()
示例#22
0
 def _test_preview(self, env, filename):
     req = Request(
         {
             'SERVER_PORT': 0,
             'SERVER_NAME': 'any',
             'wsgi.url_scheme': 'any',
             'wsgi.input': 'any',
             'REQUEST_METHOD': 'GET'
         }, lambda x, y: _printme)
     try:
         from trac.test import MockPerm
         req.perm = MockPerm()
     except ImportError:
         pass
     req.authname = 'testuser'
     req.hdf = HDFWrapper(
         []
     )  # replace by this if you want to generate HTML: req.hdf = HDFWrapper(loadpaths=chrome.get_all_templates_dirs())
     template, content_type = ImportModule(env)._do_preview(
         filename, 1, req)
     #sys.stdout = tempstdout
     #req.display(template, content_type or 'text/html')
     #open('/tmp/out.html', 'w').write(req.hdf.render(template, None))
     return str(req.hdf) + "\n"
示例#23
0
 def _get_hdf(self, req):
     hdf = HDFWrapper(loadpaths=Chrome(self.env).get_all_templates_dirs())
     populate_hdf(hdf, self.env, req)
     return hdf
示例#24
0
class CodeReviewNotifyEmail(NotifyEmail):
    template_name = "code_review_notify_email.cs"
    from_email = "codereview@localhost"
    ticket_pattern = re.compile('#([0-9]+)')

    def __init__(self, env):
        NotifyEmail.__init__(self, env)
        self.hdf = HDFWrapper(loadpaths=self.get_templates_dirs())
        populate_hdf(self.hdf, env)

    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]

    def notify(self, cr_dict):
        self.cr_dict = cr_dict
        cr = CodeReview(self.env, cr_dict['cr_id'])
        
        cursor = self.env.get_db_cnx().cursor()
        cursor.execute("SELECT author, message FROM revision WHERE rev='%s'" % cr_dict['cr_id'])

        recordset = cursor.fetchall()

        if not recordset:
            return
        cs_author = recordset[0][0]
        cs_message = recordset[0][1]

        if cs_author == "anonymous" and cr_dict['cr_author'] == "anonymous":
            return

        subject = "[TracNotify] ChangeSet r%s by %s reviewed by %s" % \
                  (cr_dict['cr_id'], cs_author, ','.join(cr.get_reviewers()))
        if cr_dict['priority'] == 'critical':
            subject = '[Critical]' + subject

        ticket_info = self.get_ticket_info(cs_message, cr_dict['cr_message'])

        self.hdf['trac_name'] = self.env.config.get('project', 'name')
        absurl = self.env.config.get('codereview', 'absurl')
        self.hdf['absurl'] = absurl
        self.hdf['r_content'] = wiki_to_html(cr_dict['cr_message'], self.env, cr_dict['req'], absurls = absurl)
        self.hdf['ticket_len'] = len(ticket_info)
        self.hdf['t_info'] = ticket_info
        self.hdf['cs_id'] = cr_dict['cr_id']
        self.hdf['cs_author'] = cs_author
        self.hdf['cs_message'] = wiki_to_html(cs_message, self.env, cr_dict['req'], absurls = absurl, escape_newlines=True)
        self.hdf['r_author'] = ', '.join(cr.get_reviewers())
        self.hdf['r_priority'] = cr_dict['priority']

        self.subject = subject

        self.smtp_server = self.config['notification'].get('smtp_server')
        self.smtp_port = self.config['notification'].getint('smtp_port')
        self.from_email = self.config['notification'].get('smtp_from')
        self.replyto_email = self.config['notification'].get('smtp_replyto')
        self.from_email = self.from_email or self.replyto_email
        if not self.from_email and not self.replyto_email:
            raise TracError(Markup('Unable to send email due to identity '
                                   'crisis.<p>Neither <b>notification.from</b> '
                                   'nor <b>notification.reply_to</b> are '
                                   'specified in the configuration.</p>'),
                            'SMTP Notification Error')

        # Authentication info (optional)
        self.user_name = self.config['notification'].get('smtp_user')
        self.password = self.config['notification'].get('smtp_password')

        Notify.notify(self, cr_dict['cr_id'])

    def get_reviewer_team(self):
        reviewer_team = self.env.config.get("codereview", "team_list", "")
        if reviewer_team:
            return [reviewer.strip() for reviewer in reviewer_team.split(',')]
        else:
            return []

    def get_recipients(self, cr_id):
        cr = CodeReview(self.env, cr_id)
        reviewers = list(set(self.get_reviewer_team() + cr.get_reviewers()))

	cs_author = self.hdf.get('cs_author', None)
	if cs_author is None:
            cursor = self.env.get_db_cnx().cursor()
            cursor.execute("SELECT author FROM revision WHERE rev='%s'" % cr_id)
            cs_author = cursor.fetchone()
            if cs_author:
                cs_author = cs_author[0]
            else:
	        cs_author = ''

        if cs_author in reviewers:
            reviewers.remove(cs_author)
        return ([cs_author,], reviewers)

    def get_ticket_info(self, cs_message, cr_message):
        cursor = self.env.get_db_cnx().cursor()
        ticket_ids = set(self.ticket_pattern.findall(cs_message or '') + self.ticket_pattern.findall(cr_message or ''))
        ticket_info = []
        if(ticket_ids):
            cursor.execute('SELECT id, summary FROM ticket WHERE id in (%s) ORDER BY id' % ','.join(ticket_ids))
            for id, summary in cursor.fetchall():
                ticket_info.append({'id': id, 'summary': summary})
        return ticket_info

    def send(self, torcpts, ccrcpts):
        from email.MIMEText import MIMEText
        from email.Utils import formatdate, formataddr
        body = self.hdf.render(self.template_name)
        projname = self.config.get('project', 'name')
        headers = {}
        headers['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__
        headers['X-Trac-Version'] =  __version__
        headers['X-Trac-Project'] =  projname
        headers['X-URL'] = self.config.get('project', 'url')
        headers['Subject'] = self.subject
        headers['From'] = (projname, self.from_email)
        headers['Sender'] = self.from_email
        headers['Reply-To'] = self.replyto_email

        def build_addresses(rcpts):
            """Format and remove invalid addresses"""
            return filter(lambda x: x, \
                          [self.get_smtp_address(addr) for addr in rcpts])
        def remove_dup(rcpts, all):
            """Remove duplicates"""
            tmp = []
            for rcpt in rcpts:
                if not rcpt in all:
                    tmp.append(rcpt)
                    all.append(rcpt)
            return (tmp, all)

        toaddrs = build_addresses(torcpts)
        ccaddrs = build_addresses(ccrcpts)

        recipients = []
        (toaddrs, recipients) = remove_dup(toaddrs, recipients)
        (ccaddrs, recipients) = remove_dup(ccaddrs, recipients)
        
        if len(recipients) < 1:
            self.env.log.info('no recipient for a ticket notification')
            return

        headers['To'] = ', '.join(toaddrs)
        headers['Cc'] = ', '.join(ccaddrs)
        headers['Date'] = formatdate()
        if not self._charset.body_encoding:
            try:
                dummy = body.encode('ascii')
            except UnicodeDecodeError:
                raise TracError, "CodeReview contains non-Ascii chars. " \
                                 "Please change encoding setting"
        msg = MIMEText(body)
        msg.set_type("text/html")

        del msg['Content-Transfer-Encoding']
        msg.set_charset(self._charset)
        self.add_headers(msg, headers)
        self.env.log.debug("Sending SMTP notification to %s on port %d to %s"
                           % (self.smtp_server, self.smtp_port, recipients))
        msgtext = msg.as_string()
        # Ensure the message complies with RFC2822: use CRLF line endings
        recrlf = re.compile("\r?\n")
        msgtext = "\r\n".join(recrlf.split(msgtext))
        self.server.sendmail(msg['From'], recipients, msgtext)
示例#25
0
 def __init__(self, env):
     NotifyEmail.__init__(self, env)
     self.hdf = HDFWrapper(loadpaths=self.get_templates_dirs())
     populate_hdf(self.hdf, env)
示例#26
0
    def dispatch(self, req):
        """Find a registered handler that matches the request and let it process
        it.
        
        In addition, this method initializes the HDF data set and adds the web
        site chrome.
        """
        # FIXME: For backwards compatibility, should be removed in 0.11
        self.env.href = req.href
        # FIXME in 0.11: self.env.abs_href = Href(self.env.base_url)
        self.env.abs_href = req.abs_href

        # Select the component that should handle the request
        chosen_handler = None
        early_error = None
        req.authname = 'anonymous'
        req.perm = NoPermissionCache()
        try:
            if not req.path_info or req.path_info == '/':
                chosen_handler = self.default_handler
            else:
                for handler in self.handlers:
                    if handler.match_request(req):
                        chosen_handler = handler
                        break

            # Attach user information to the request early, so that
            # the IRequestFilter can see it while preprocessing
            if not getattr(chosen_handler, 'anonymous_request', False):
                try:
                    req.authname = self.authenticate(req)
                    req.perm = PermissionCache(self.env, req.authname)
                    req.session = Session(self.env, req)
                    req.form_token = self._get_form_token(req)
                except:
                    req.authname = 'anonymous'
                    req.perm = NoPermissionCache()
                    early_error = sys.exc_info()

            chosen_handler = self._pre_process_request(req, chosen_handler)
        except:
            early_error = sys.exc_info()

        if not chosen_handler and not early_error:
            early_error = (HTTPNotFound('No handler matched request to %s',
                                        req.path_info), None, None)

        # Prepare HDF for the clearsilver template
        try:
            use_template = getattr(chosen_handler, 'use_template', True)
            req.hdf = None
            if use_template:
                chrome = Chrome(self.env)
                req.hdf = HDFWrapper(loadpaths=chrome.get_all_templates_dirs())
                populate_hdf(req.hdf, self.env, req)
                chrome.populate_hdf(req, chosen_handler)
        except:
            req.hdf = None  # revert to sending plaintext error
            if not early_error:
                raise

        if early_error:
            try:
                self._post_process_request(req)
            except Exception, e:
                self.log.exception(e)
            raise early_error[0], early_error[1], early_error[2]
示例#27
0
                               'to locate the Trac environment(s).')
    run_once = environ['wsgi.run_once']

    env = env_error = None
    try:
        env = _open_environment(env_path, run_once=run_once)
        if env.base_url:
            environ['trac.base_url'] = env.base_url
    except TracError, e:
        env_error = e

    req = Request(environ, start_response)
    try:
        if not env and env_error:
            from trac.config import default_dir
            req.hdf = HDFWrapper([default_dir('templates')])
            raise HTTPInternalError(env_error.message)
        try:
            try:
                dispatcher = RequestDispatcher(env)
                dispatcher.dispatch(req)
            except RequestDone:
                pass
            return req._response or []
        finally:
            if not run_once:
                env.shutdown(threading._get_ident())

    except HTTPException, e:
        if env:
            env.log.warn(e)
示例#28
0
    def render_summary(self, req, config, build, step, category):
        assert category == 'pylint'

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("""
SELECT MAX(lint_file.value) AS file, MAX(CAST(lint_line.value as INT)) AS line,
       MAX(lint_type.value) AS type, MAX(lint_tag.value) AS tag,
       MAX(lint_msg.value) AS msg, MAX(lint_category.value) as cat
FROM bitten_report AS report
  LEFT OUTER JOIN bitten_report_item AS lint_file
    ON(lint_file.report=report.id AND lint_file.name='file')
  LEFT OUTER JOIN bitten_report_item AS lint_line
    ON(lint_line.report=report.id AND
       lint_line.item=lint_file.item AND lint_line.name='line')
  LEFT OUTER JOIN bitten_report_item AS lint_type
    ON(lint_type.report=report.id AND
       lint_type.item=lint_file.item AND lint_type.name='type')
  LEFT OUTER JOIN bitten_report_item AS lint_tag
    ON(lint_tag.report=report.id AND
       lint_tag.item=lint_file.item AND lint_tag.name='tag')
  LEFT OUTER JOIN bitten_report_item AS lint_msg
    ON(lint_msg.report=report.id AND
       lint_msg.item=lint_file.item AND lint_msg.name='msg')
  LEFT OUTER JOIN bitten_report_item AS lint_category
    ON(lint_category.report=report.id AND
       lint_category.item=lint_file.item AND lint_category.name='category')
WHERE category=%s AND build=%s AND step=%s
GROUP BY lint_file.value, lint_line.value, lint_type.value
ORDER BY file, line, type""", (category, build.id, step.name))

        data = []
        totals = {
            'error': 0,
            'warning': 0,
            'refactor': 0,
            'fatal': 0,
            'convention': 0,
            'ignored': 0

        }
        for fname, line, ltype, tag, msg, cat in cursor:
            #self.log.debug("%s, %s, %s, %s, %s, %s", fname, line, ltype, tag, msg, cat)
            #self.log.debug("CAT: %r", cat)
            if cat in ('error', 'warning', 'refactor', 'fatal', 'convention', 'ignored'):
                data.append(
                    {
                        'href': self.env.href.browser(config.path, fname),
                        'file': fname,
                        'line': line,
                        'type': ltype,
                        'tag': tag,
                        'msg': msg,
                        'cat': cat
                    }
                )
                totals[cat] += 1
        hdf = HDFWrapper(loadpaths=Chrome(self.env).get_all_templates_dirs())
        hdf['data'] = data
        hdf['totals'] = totals
        return hdf.render('bittentrac_pylint.cs')
示例#29
0
 def test_htdocs_location(self):
     env = EnvironmentStub()
     req = Mock(hdf=HDFWrapper(), cgi_location='/trac.cgi', path_info='')
     Chrome(env).populate_hdf(req, None)
     self.assertEqual('/trac.cgi/chrome/common/',
                      req.hdf['htdocs_location'])
示例#30
0
 def test_add_stylesheet(self):
     req = Mock(cgi_location='/trac.cgi', hdf=HDFWrapper())
     add_stylesheet(req, 'common/css/trac.css')
     self.assertEqual('text/css', req.hdf['chrome.links.stylesheet.0.type'])
     self.assertEqual('/trac.cgi/chrome/common/css/trac.css',
                      req.hdf['chrome.links.stylesheet.0.href'])
示例#31
0
    def render_summary(self, req, config, build, step, category):
        self.log.debug('Category: %s', category)
        assert category == 'coverage'

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("""
SELECT item_name.value AS unit, item_file.value AS file,
       MAX(item_lines.value) AS loc, MAX(exec_lines.value) AS exec,
       MAX(item_percentage.value) AS cov, MAX(miss_lines.value) AS miss
FROM bitten_report AS report
 LEFT OUTER JOIN bitten_report_item AS item_name
  ON (item_name.report=report.id AND item_name.name='name')
 LEFT OUTER JOIN bitten_report_item AS item_file
  ON (item_file.report=report.id AND item_file.item=item_name.item AND
      item_file.name='file')
 LEFT OUTER JOIN bitten_report_item AS item_lines
  ON (item_lines.report=report.id AND item_lines.item=item_name.item AND
      item_lines.name='lines')
 LEFT OUTER JOIN bitten_report_item AS exec_lines
  ON (exec_lines.report=report.id AND
      exec_lines.item=item_name.item AND
      exec_lines.name='executed')
 LEFT OUTER JOIN bitten_report_item AS item_percentage
  ON (item_percentage.report=report.id AND
      item_percentage.item=item_name.item AND
      item_percentage.name='percentage')
 LEFT OUTER JOIN bitten_report_item AS miss_lines
  ON (miss_lines.report=report.id AND
      miss_lines.item=item_name.item AND
      miss_lines.name='miss')
WHERE category='coverage' AND build=%s AND step=%s
GROUP BY file, unit ORDER BY unit""", (build.id, step.name))

        data = []
        total_loc, total_cov, total_exe = 0, 0, 0
        for unit, file, loc, exe, cov, miss in cursor:
            loc, cov, exe = int(loc), float(cov), int(exe)
            if loc:
                d = {'name': unit, 'loc': loc, 'cov': int(cov), 'exe': exe} #, 'miss': miss}
                if file:
                    d['href'] = self.env.href.browser(config.path, file)
                if miss and file:
                    missed = []
                    for lines in miss.split():
                        m = {'lines': lines}
                        m['href'] = self.env.href.browser(config.path, file) + '#L%s' % \
                                lines.split('-')[0]
                        missed.append(m)
                    d['miss'] = missed
                else:
                    d['miss'] = {'lines': miss}

                self.log.debug('DATA ROW:', d)

                data.append(d)
                total_loc += loc
                total_exe += exe
                total_cov += loc * cov

        hdf = HDFWrapper(loadpaths=Chrome(self.env).get_all_templates_dirs())
        hdf['data'] = data
        hdf['totals'] = {'loc': total_loc, 'cov': int(total_cov / total_loc), 'exe': total_exe}

        return hdf.render('bittentrac_nosecoverage.cs')
示例#32
0
 def __init__(self, env):
     NotifyEmail.__init__(self, env)
     self.hdf = HDFWrapper(loadpaths=self.get_templates_dirs())
     populate_hdf(self.hdf, env)
示例#33
0
 def test_add_link_simple(self):
     req = Mock(hdf=HDFWrapper())
     add_link(req, 'start', '/trac/wiki')
     self.assertEqual('/trac/wiki', req.hdf['chrome.links.start.0.href'])
示例#34
0
class CodeReviewNotifyEmail(NotifyEmail):
    template_name = "code_review_notify_email.cs"
    from_email = "codereview@localhost"
    ticket_pattern = re.compile('#([0-9]+)')

    def __init__(self, env):
        NotifyEmail.__init__(self, env)
        self.hdf = HDFWrapper(loadpaths=self.get_templates_dirs())
        populate_hdf(self.hdf, env)

    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]

    def notify(self, cr_dict):
        self.cr_dict = cr_dict
        cr = CodeReview(self.env, cr_dict['cr_id'])

        cursor = self.env.get_db_cnx().cursor()
        cursor.execute("SELECT author, message FROM revision WHERE rev='%s'" %
                       cr_dict['cr_id'])

        recordset = cursor.fetchall()

        if not recordset:
            return
        cs_author = recordset[0][0]
        cs_message = recordset[0][1]

        if cs_author == "anonymous" and cr_dict['cr_author'] == "anonymous":
            return

        subject = "[TracNotify] ChangeSet r%s by %s reviewed by %s" % \
                  (cr_dict['cr_id'], cs_author, ','.join(cr.get_reviewers()))
        if cr_dict['priority'] == 'critical':
            subject = '[Critical]' + subject

        ticket_info = self.get_ticket_info(cs_message, cr_dict['cr_message'])

        self.hdf['trac_name'] = self.env.config.get('project', 'name')
        absurl = self.env.config.get('codereview', 'absurl')
        self.hdf['absurl'] = absurl
        self.hdf['r_content'] = wiki_to_html(cr_dict['cr_message'],
                                             self.env,
                                             cr_dict['req'],
                                             absurls=absurl)
        self.hdf['ticket_len'] = len(ticket_info)
        self.hdf['t_info'] = ticket_info
        self.hdf['cs_id'] = cr_dict['cr_id']
        self.hdf['cs_author'] = cs_author
        self.hdf['cs_message'] = wiki_to_html(cs_message,
                                              self.env,
                                              cr_dict['req'],
                                              absurls=absurl,
                                              escape_newlines=True)
        self.hdf['r_author'] = ', '.join(cr.get_reviewers())
        self.hdf['r_priority'] = cr_dict['priority']

        self.subject = subject

        self.smtp_server = self.config['notification'].get('smtp_server')
        self.smtp_port = self.config['notification'].getint('smtp_port')
        self.from_email = self.config['notification'].get('smtp_from')
        self.replyto_email = self.config['notification'].get('smtp_replyto')
        self.from_email = self.from_email or self.replyto_email
        if not self.from_email and not self.replyto_email:
            raise TracError(
                Markup('Unable to send email due to identity '
                       'crisis.<p>Neither <b>notification.from</b> '
                       'nor <b>notification.reply_to</b> are '
                       'specified in the configuration.</p>'),
                'SMTP Notification Error')

        # Authentication info (optional)
        self.user_name = self.config['notification'].get('smtp_user')
        self.password = self.config['notification'].get('smtp_password')

        Notify.notify(self, cr_dict['cr_id'])

    def get_reviewer_team(self):
        reviewer_team = self.env.config.get("codereview", "team_list", "")
        if reviewer_team:
            return [reviewer.strip() for reviewer in reviewer_team.split(',')]
        else:
            return []

    def get_recipients(self, cr_id):
        cr = CodeReview(self.env, cr_id)
        reviewers = list(set(self.get_reviewer_team() + cr.get_reviewers()))

        cs_author = self.hdf.get('cs_author', None)
        if cs_author is None:
            cursor = self.env.get_db_cnx().cursor()
            cursor.execute("SELECT author FROM revision WHERE rev='%s'" %
                           cr_id)
            cs_author = cursor.fetchone()
            if cs_author:
                cs_author = cs_author[0]
            else:
                cs_author = ''

        if cs_author in reviewers:
            reviewers.remove(cs_author)
        return ([
            cs_author,
        ], reviewers)

    def get_ticket_info(self, cs_message, cr_message):
        cursor = self.env.get_db_cnx().cursor()
        ticket_ids = set(
            self.ticket_pattern.findall(cs_message or '') +
            self.ticket_pattern.findall(cr_message or ''))
        ticket_info = []
        if (ticket_ids):
            cursor.execute(
                'SELECT id, summary FROM ticket WHERE id in (%s) ORDER BY id' %
                ','.join(ticket_ids))
            for id, summary in cursor.fetchall():
                ticket_info.append({'id': id, 'summary': summary})
        return ticket_info

    def send(self, torcpts, ccrcpts):
        from email.MIMEText import MIMEText
        from email.Utils import formatdate, formataddr
        body = self.hdf.render(self.template_name)
        projname = self.config.get('project', 'name')
        headers = {}
        headers['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__
        headers['X-Trac-Version'] = __version__
        headers['X-Trac-Project'] = projname
        headers['X-URL'] = self.config.get('project', 'url')
        headers['Subject'] = self.subject
        headers['From'] = (projname, self.from_email)
        headers['Sender'] = self.from_email
        headers['Reply-To'] = self.replyto_email

        def build_addresses(rcpts):
            """Format and remove invalid addresses"""
            return filter(lambda x: x, \
                          [self.get_smtp_address(addr) for addr in rcpts])

        def remove_dup(rcpts, all):
            """Remove duplicates"""
            tmp = []
            for rcpt in rcpts:
                if not rcpt in all:
                    tmp.append(rcpt)
                    all.append(rcpt)
            return (tmp, all)

        toaddrs = build_addresses(torcpts)
        ccaddrs = build_addresses(ccrcpts)

        recipients = []
        (toaddrs, recipients) = remove_dup(toaddrs, recipients)
        (ccaddrs, recipients) = remove_dup(ccaddrs, recipients)

        if len(recipients) < 1:
            self.env.log.info('no recipient for a ticket notification')
            return

        headers['To'] = ', '.join(toaddrs)
        headers['Cc'] = ', '.join(ccaddrs)
        headers['Date'] = formatdate()
        if not self._charset.body_encoding:
            try:
                dummy = body.encode('ascii')
            except UnicodeDecodeError:
                raise TracError, "CodeReview contains non-Ascii chars. " \
                                 "Please change encoding setting"
        msg = MIMEText(body)
        msg.set_type("text/html")

        del msg['Content-Transfer-Encoding']
        msg.set_charset(self._charset)
        self.add_headers(msg, headers)
        self.env.log.debug("Sending SMTP notification to %s on port %d to %s" %
                           (self.smtp_server, self.smtp_port, recipients))
        msgtext = msg.as_string()
        # Ensure the message complies with RFC2822: use CRLF line endings
        recrlf = re.compile("\r?\n")
        msgtext = "\r\n".join(recrlf.split(msgtext))
        self.server.sendmail(msg['From'], recipients, msgtext)