Пример #1
0
def prepare_request(req, environ):

    href = Href(req.href.all())
    anenv = get_allenv(environ, req)
    req.href = href
    req.abs_href = Href(req.abs_href.all())
    chrome = Chrome(anenv)

    update_request(req, chrome)

    # auth must be checked before this method runs, we are not a component yet
    req.perm = PermissionCache(anenv, req.authname)
    req.session = Session(anenv, req)

    loadpaths = chrome.get_all_templates_dirs();
    loadpaths.insert(0, os.path.dirname(__file__) + "/templates/")

    req.hdf = {}
    populate_hdf(req.hdf, anenv, req)

    # after populate, add styles and scripts
    path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
    env_name = path_info.pop(0)
    if len(path_info) == 0 or (len(path_info) == 1 and path_info[0] == ''):
        add_stylesheet(req, "tram/css/project-list.css")
    elif path_info[0] == 'roadmap':
        add_stylesheet(req, 'common/css/roadmap.css')
    elif path_info[0] == 'timeline':
        add_stylesheet(req, 'common/css/timeline.css')
    elif path_info[0] == 'query':
        add_stylesheet(req, 'common/css/report.css')
    elif path_info[0] == 'browser':
        add_stylesheet(req, 'common/css/browser.css')
    elif path_info[0] == 'search':
        add_stylesheet(req, 'common/css/search.css')
        add_stylesheet(req, 'tram/css/whole-search.css')
        add_script(req, 'tram/js/jquery-1.1.2.pack.js')
        add_script(req, 'tram/js/jquery.compat-1.0.js')
        add_script(req, 'tram/js/trac_ws.js')
    
    chrome.populate_hdf(req)

    req.hdf['tram.version'] = "0.3"
    req.hdf["tram_htdocs_location"] = req.hdf["htdocs_location"].replace("common", "tram")

    # We want to display the guide whether we are using an "all" env or not
    # As the elements are already ordered we hijac the about element and reassign it below
    req.hdf['chrome.nav.metanav.about'] = Markup('<a href="' + href.wiki('TracGuide') + '">Help/Guide</a>')
    req.hdf['chrome.nav.metanav.help'] = Markup('<a href="' + href.about() + '">About Trac</a>')

    # Here we are adding some links to plugins as they seem not to be loading now...
    if (anenv.isall):
        req.hdf['chrome.nav.mainnav.wiki'] = Markup('<a href="' + href.wiki() + '">Wiki</a>')

    req.hdf['chrome.nav.mainnav.timeline'] = Markup('<a href="' + href.timeline() + '">' + _('Timeline') + '</a>')
    req.hdf['chrome.nav.mainnav.roadmap'] = Markup('<a href="' + href.roadmap() + '">' + _('Roadmap') + '</a>')
    req.hdf['chrome.nav.mainnav.browser'] = Markup('<a href="' + href.browser('/') + '">' + _('Browse Source') + '</a>')
    req.hdf['chrome.nav.mainnav.tickets'] = Markup('<a href="' + href.query() + '">' + _('View Tickets') + '</a>')
    req.hdf['chrome.nav.mainnav.search'] = Markup('<a href="' + href.search() + '">' + _('Search') + '</a>')
    return chrome
Пример #2
0
 def build(self):
     self._position = self._parent.position()
     x = self._position[0]+(self._w-self._tw)/2
     y = self._position[1]
     r = UNIT/2
     rect = SVG.rect(x,y,self._tw,self._h,
                     self._parent.fillcolor(), 
                     self._parent.strokecolor(), 
                     self._parent.strokewidth())
     rect.attributes['rx'] = r
     rect.attributes['ry'] = r        
     text = SVG.text(self._position[0]++self._w/2, 
                     self._position[1]+self._h/2+UNIT/6,
                     "/%s" % self._title.encode('utf-8'), 
                     self._parent.fontsize(), self._parent.fontname())
     text.attributes['style'] = 'text-anchor: middle'
     name = self._title.encode('utf-8').replace('/','')
     g = SVG.group('grp%s' % name, elements=[rect, text])
     href = Href(self._parent.urlbase())
     self._link = SVG.link(plink(href.browser(self._title)), elements=[g])
Пример #3
0
 def href(self):
     """The application root path"""
     return Href(urlsplit(self.abs_href.base).path)
Пример #4
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')]
    if req.environ.get('trac.env_index_template'):
        env_index_template = req.environ['trac.env_index_template']
        tmpl_path, template = os.path.split(env_index_template)
        loadpaths.insert(0, tmpl_path)
    else:
        template = 'index.html'

    data = {
        'trac': {
            'version': TRAC_VERSION,
            'time': user_time(req, 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
    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 as 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

        loader = TemplateLoader(loadpaths,
                                variable_lookup='lenient',
                                default_encoding='utf-8')
        tmpl = loader.load(template)
        stream = tmpl.generate(**data)
        if template.endswith('.xml'):
            output = stream.render('xml')
            req.send(output, 'text/xml')
        else:
            output = stream.render('xhtml',
                                   doctype=DocType.XHTML_STRICT,
                                   encoding='utf-8')
            req.send(output, 'text/html')

    except RequestDone:
        pass
Пример #5
0
 def setUp(self):
     self.env = EnvironmentStub()
     self.req = Mock(href=Href('/'), abs_href=Href('http://example.org/'),
                     authname='anonymous', tz=utc, locale=locale_en,
                     lc_time=locale_en, chrome={}, perm=MockPerm(),
                     session={})
Пример #6
0
    def process_request(self, req):
        req.perm.assert_permission('ROADMAP_VIEW')

        #If the page was posted, a filter was applied. Build and redirect using query strnig
        if req.args.has_key('update'):
            req.redirect(self._get_href(req))

        req.hdf['title'] = 'Project List'

        #Process filtering arguments
        self.status = req.args.has_key('status') and req.args['status'] or None

        #Process sorting arguments
        self.desc = req.args.has_key(
            'desc') and req.args['desc'] == '1' or None
        self.order = req.args.has_key(
            'order') and req.args['order'] or DEFAULT_SORT_FIELD

        #Get search path and base_url
        search_path, this_project = os.path.split(self.env.path)
        base_url, _ = posixpath.split(req.abs_href())
        href = Href(base_url)

        #Start with an empty project list
        projects = []
        for project in os.listdir(search_path):

            #Open the project environment
            project_path = os.path.join(search_path, project)
            env = open_environment(project_path)

            #Check if DB needs upgrading
            check_upgrade(env)

            #Trim project description if too long
            if len(env.project_description) <= 60:
                description = env.project_description
            else:
                description = "%s..." % env.project_description[:60]

            #Get last_login timestamp, and convert to human readable
            last_login = int(get_property(env, 'last_login', 0))
            if last_login == 0:
                last_login = ''
            else:
                last_login = datetime.fromtimestamp(last_login).strftime(
                    TIME_FORMAT)

            #Filter by status
            project_status = get_property(env, 'status', 'unknown')
            if self.status and project_status != self.status:
                continue

            projects.append({
                'name':
                env.project_name,
                'description':
                description,
                'company':
                get_property(env, 'company'),
                'created':
                get_property(env, 'date_created'),
                'started':
                get_property(env, 'date_started'),
                'scheduled':
                get_property(env, 'date_scheduled'),
                'finished':
                get_property(env, 'date_finished'),
                'percent_finished':
                get_property(env, 'percent', '0'),
                'percent_remaining':
                100 - int(get_property(env, 'percent', '0')),
                'status':
                STATUS[project_status],
                'client':
                get_property(env, 'client'),
                'manager':
                get_property(env, 'manager'),
                'last_login':
                last_login,
                'href':
                href(project)
            })

        #Status selection
        sorted_keys = STATUS.keys()
        sorted_keys.sort()
        statuses = [dict(name='', label='*', selected=self.status == None)]
        statuses += [
            dict(name=x, label=STATUS[x], selected=self.status == x)
            for x in sorted_keys
        ]

        ####################################
        ## Functions for project sorting, depending on the field
        def cmp_datetime(x, y):
            try:
                return datetime.strptime(x, TIME_FORMAT) < datetime.strptime(
                    y, TIME_FORMAT) and -1 or 1
            except:
                return x.lower() < y.lower() and -1 or 1

        def cmp_date(x, y):
            try:
                return datetime.strptime(x, DATE_FORMAT) < datetime.strptime(
                    y, DATE_FORMAT) and -1 or 1
            except:
                return x.lower() < y.lower() and -1 or 1

        def cmp_int(x, y):
            try:
                return int(x) < int(y) and -1 or 1
            except:
                return x < y and -1 or 1

        def cmp_str_nocase(x, y):
            try:
                return x.lower() < y.lower() and -1 or 1
            except:
                return x < y and -1 or 1

        #################################

        #For some fields, use a special comparison function
        if self.order in ('created', 'last_login'):
            cmp = lambda x, y: cmp_datetime(x[self.order], y[self.order])
        if self.order in ('started', 'scheduled', 'finished'):
            cmp = lambda x, y: cmp_date(x[self.order], y[self.order])
        if self.order in ('percent_finished'):
            cmp = lambda x, y: cmp_int(x[self.order], y[self.order])
        else:
            cmp = lambda x, y: cmp_str_nocase(x[self.order], y[self.order])

        projects.sort(cmp=cmp, reverse=self.desc and True or False)

        #Set template HDF
        req.hdf['projects'] = projects
        req.hdf['statuses'] = statuses
        req.hdf['status'] = self.status
        req.hdf['order'] = self.order
        req.hdf['desc'] = self.desc

        add_stylesheet(req, 'tracprojectmanager/css/projectlist.css')

        return 'projectlist.cs', None
Пример #7
0
 def test_add_link_simple(self):
     req = Request(href=Href('/trac.cgi'))
     add_link(req, 'start', '/trac/wiki')
     self.assertEqual('/trac/wiki', req.chrome['links']['start'][0]['href'])
Пример #8
0
    def test_process_build_step_failure_continue(self):
        recipe = """<build>
  <step id="foo" onerror="continue">
  </step>
</build>"""
        BuildConfig(self.env,
                    'test',
                    path='somepath',
                    active=True,
                    recipe=recipe).insert()
        build = Build(self.env,
                      'test',
                      '123',
                      1,
                      slave='hal',
                      rev_time=42,
                      started=42,
                      status=Build.IN_PROGRESS)
        build.slave_info[Build.TOKEN] = '123'

        build.insert()

        inbody = StringIO("""<result step="foo" status="failure"
                                     time="2007-04-01T15:30:00.0000"
                                     duration="3.45">
</result>""")
        outheaders = {}
        outbody = StringIO()
        req = Mock(method='POST',
                   base_path='',
                   path_info='/builds/%d/steps/' % build.id,
                   href=Href('/trac'),
                   abs_href=Href('http://example.org/trac'),
                   remote_addr='127.0.0.1',
                   args={},
                   perm=PermissionCache(self.env, 'hal'),
                   read=inbody.read,
                   send_response=lambda x: outheaders.setdefault('Status', x),
                   send_header=lambda x, y: outheaders.setdefault(x, y),
                   write=outbody.write,
                   incookie=Cookie('trac_auth=123'))
        module = BuildMaster(self.env)

        module._start_new_step(build, 'foo').insert()

        assert module.match_request(req)

        self.assertRaises(RequestDone, module.process_request, req)

        self.assertEqual(201, outheaders['Status'])
        self.assertEqual('20', outheaders['Content-Length'])
        self.assertEqual('text/plain', outheaders['Content-Type'])
        self.assertEqual('Build step processed', outbody.getvalue())

        build = Build.fetch(self.env, build.id)
        self.assertEqual(Build.FAILURE, build.status)
        assert build.stopped
        assert build.stopped > build.started

        steps = list(BuildStep.select(self.env, build.id))
        self.assertEqual(1, len(steps))
        self.assertEqual('foo', steps[0].name)
        self.assertEqual(BuildStep.FAILURE, steps[0].status)
Пример #9
0
    def test_process_build_step_success_with_report(self):
        recipe = """<build>
  <step id="foo">
  </step>
</build>"""
        BuildConfig(self.env,
                    'test',
                    path='somepath',
                    active=True,
                    recipe=recipe).insert()
        build = Build(self.env,
                      'test',
                      '123',
                      1,
                      slave='hal',
                      rev_time=42,
                      started=42,
                      status=Build.IN_PROGRESS)
        build.slave_info[Build.TOKEN] = '123'
        build.insert()

        inbody = StringIO("""<result step="foo" status="success"
                                     time="2007-04-01T15:30:00.0000"
                                     duration="3.45">
    <report category="test"
            generator="http://bitten.edgewall.org/tools/python#unittest">
        <test fixture="my.Fixture" file="my/test/file.py">
            <stdout>Doing my thing</stdout>
        </test>
    </report>
</result>""")
        outheaders = {}
        outbody = StringIO()
        req = Mock(method='POST',
                   base_path='',
                   path_info='/builds/%d/steps/' % build.id,
                   href=Href('/trac'),
                   abs_href=Href('http://example.org/trac'),
                   remote_addr='127.0.0.1',
                   args={},
                   perm=PermissionCache(self.env, 'hal'),
                   read=inbody.read,
                   send_response=lambda x: outheaders.setdefault('Status', x),
                   send_header=lambda x, y: outheaders.setdefault(x, y),
                   write=outbody.write,
                   incookie=Cookie('trac_auth=123'))
        module = BuildMaster(self.env)

        module._start_new_step(build, 'foo').insert()

        assert module.match_request(req)

        self.assertRaises(RequestDone, module.process_request, req)

        self.assertEqual(201, outheaders['Status'])
        self.assertEqual('20', outheaders['Content-Length'])
        self.assertEqual('text/plain', outheaders['Content-Type'])
        self.assertEqual('Build step processed', outbody.getvalue())

        build = Build.fetch(self.env, build.id)
        self.assertEqual(Build.SUCCESS, build.status)
        assert build.stopped
        assert build.stopped > build.started

        steps = list(BuildStep.select(self.env, build.id))
        self.assertEqual(1, len(steps))
        self.assertEqual('foo', steps[0].name)
        self.assertEqual(BuildStep.SUCCESS, steps[0].status)

        reports = list(Report.select(self.env, build=build.id, step='foo'))
        self.assertEqual(1, len(reports))
        self.assertEqual('test', reports[0].category)
        self.assertEqual('http://bitten.edgewall.org/tools/python#unittest',
                         reports[0].generator)
        self.assertEqual(1, len(reports[0].items))
        self.assertEqual(
            {
                'fixture': 'my.Fixture',
                'file': 'my/test/file.py',
                'stdout': 'Doing my thing',
                'type': 'test',
            }, reports[0].items[0])
Пример #10
0
    def open_environment(self, environ, start_response):
        env_path = environ.get('trac.env_path')
        if not env_path:
            env_parent_dir = environ.get('trac.env_parent_dir')
            env_paths = environ.get('trac.env_paths')
            if env_parent_dir or env_paths:
                # The first component of the path is the base name of the
                # environment
                path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
                env_name = path_info.pop(0)

                if not env_name:
                    # No specific environment requested, so render an environment
                    # index page
                    send_project_index(environ, start_response, env_parent_dir,
                                       env_paths)
                    raise RequestDone

                errmsg = None

                # To make the matching patterns of request handlers work, we append
                # the environment name to the `SCRIPT_NAME` variable, and keep only
                # the remaining path in the `PATH_INFO` variable.
                script_name = environ.get('SCRIPT_NAME', '')
                try:
                    script_name = unicode(script_name, 'utf-8')
                    # (as Href expects unicode parameters)
                    environ['SCRIPT_NAME'] = Href(script_name)(env_name)
                    environ['PATH_INFO'] = '/' + '/'.join(path_info)

                    if env_parent_dir:
                        env_path = os.path.join(env_parent_dir, env_name)
                    else:
                        env_path = get_environments(environ).get(env_name)

                    if not env_path or not os.path.isdir(env_path):
                        errmsg = 'Environment not found'
                except UnicodeDecodeError:
                    errmsg = 'Invalid URL encoding (was %r)' % script_name

                if errmsg:
                    write = start_response('404 Not Found',
                                   [('Content-Type', 'text/plain'),
                                    ('Content-Length', str(len(errmsg)))])
                    write(errmsg)
                    raise RequestDone

        if not env_path:
            raise EnvironmentError('The environment options "TRAC_ENV" or '
                                   '"TRAC_ENV_PARENT_DIR" or the mod_python '
                                   'options "TracEnv" or "TracEnvParentDir" are '
                                   'missing. Trac requires one of these options '
                                   'to locate the Trac environment(s).')
        run_once = environ['wsgi.run_once']

        env = None
        self.global_env = global_env = None
        try:
            self.global_env = global_env = open_environment(env_path, use_cache=not run_once)
            factory = environment_factory(global_env)
            factory_env = factory().open_environment(environ, env_path, global_env, use_cache=not run_once) if factory \
                            else None
            env = factory_env if factory_env else global_env
        except Exception:
            raise
        return env
Пример #11
0
    def post_process_request(self, req, template, data, content_type):
        msg = req.session.get('watchlist_message', [])
        if msg:
            add_notice(req, msg)
            del req.session['watchlist_message']
        msg = req.session.get('watchlist_notify_message', [])
        if msg:
            add_notice(req, msg)
            del req.session['watchlist_notify_message']

        # Extract realm and resid from path:
        parts = req.path_info[1:].split('/', 1)

        # Handle special case for '/' and '/wiki'
        if len(parts) == 0 or not parts[0]:
            parts = ["wiki", "WikiStart"]
        elif len(parts) == 1:
            parts.append("WikiStart")

        realm, resid = parts[:2]

        if realm not in ('wiki','ticket') \
          or realm.upper() + '_VIEW' not in req.perm:
            return (template, data, content_type)

        href = Href(req.base_path)
        user = req.authname
        if user and user != "anonymous":
            if self.is_watching(realm, resid, user):
                add_ctxtnav(req,
                            "Unwatch",
                            href=href('watchlist',
                                      action='unwatch',
                                      resid=resid,
                                      realm=realm),
                            title="Remove %s from watchlist" % realm)
            else:
                add_ctxtnav(req,
                            "Watch",
                            href=href('watchlist',
                                      action='watch',
                                      resid=resid,
                                      realm=realm),
                            title="Add %s to watchlist" % realm)
            if self.gnotify and self.notifyctxtnav:
                if self.is_notify(req.session.sid, True, realm, resid):
                    add_ctxtnav(req,
                                "Do not Notify me",
                                href=href('watchlist',
                                          action='notifyoff',
                                          resid=resid,
                                          realm=realm),
                                title="No not notify me if %s changes" % realm)
                else:
                    add_ctxtnav(req,
                                "Notify me",
                                href=href('watchlist',
                                          action='notifyon',
                                          resid=resid,
                                          realm=realm),
                                title="Notify me if %s changes" % realm)

        return (template, data, content_type)
Пример #12
0
def dispatch_request(environ, start_response):
    """Main entry point for the Trac web interface.
    
    @param environ: the WSGI environment dict
    @param start_response: the WSGI callback for starting the response
    """
    if 'mod_python.options' in environ:
        options = environ['mod_python.options']
        environ.setdefault('trac.env_path', options.get('TracEnv'))
        environ.setdefault('trac.env_parent_dir',
                           options.get('TracEnvParentDir'))
        environ.setdefault('trac.env_index_template',
                           options.get('TracEnvIndexTemplate'))
        environ.setdefault('trac.template_vars',
                           options.get('TracTemplateVars'))
        environ.setdefault('trac.locale', options.get('TracLocale'))

        if 'TracUriRoot' in options:
            # Special handling of SCRIPT_NAME/PATH_INFO for mod_python, which
            # tends to get confused for whatever reason
            root_uri = options['TracUriRoot'].rstrip('/')
            request_uri = environ['REQUEST_URI'].split('?', 1)[0]
            if not request_uri.startswith(root_uri):
                raise ValueError(u'TracUriRoot défini pour %s mais la requète '
                                 u'pointe sur %s' % (root_uri, request_uri))
            environ['SCRIPT_NAME'] = root_uri
            environ['PATH_INFO'] = urllib.unquote(request_uri[len(root_uri):])

    else:
        environ.setdefault('trac.env_path', os.getenv('TRAC_ENV'))
        environ.setdefault('trac.env_parent_dir',
                           os.getenv('TRAC_ENV_PARENT_DIR'))
        environ.setdefault('trac.env_index_template',
                           os.getenv('TRAC_ENV_INDEX_TEMPLATE'))
        environ.setdefault('trac.template_vars',
                           os.getenv('TRAC_TEMPLATE_VARS'))
        environ.setdefault('trac.locale', 
                           os.getenv('TRAC_LOCALE'))

    if environ['trac.locale']:
        locale.setlocale(locale.LC_ALL, environ['trac.locale'])
    else:
        if os.name == 'posix':
            locale.setlocale(locale.LC_ALL, 'fr_FR')
        elif os.name == 'nt':
    	    locale.setlocale(locale.LC_ALL, 'French_France')
        else:
            locale.setlocale(locale.LC_ALL, '')

    # Allow specifying the python eggs cache directory using SetEnv
    if 'mod_python.subprocess_env' in environ:
        egg_cache = environ['mod_python.subprocess_env'].get('PYTHON_EGG_CACHE')
        if egg_cache:
            os.environ['PYTHON_EGG_CACHE'] = egg_cache

    # Determine the environment
    env_path = environ.get('trac.env_path')
    if not env_path:
        env_parent_dir = environ.get('trac.env_parent_dir')
        env_paths = environ.get('trac.env_paths')
        if env_parent_dir or env_paths:
            # The first component of the path is the base name of the
            # environment
            path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
            env_name = path_info.pop(0)

            if not env_name:
                # No specific environment requested, so render an environment
                # index page
                send_project_index(environ, start_response, env_parent_dir,
                                   env_paths)
                return []

            # To make the matching patterns of request handlers work, we append
            # the environment name to the `SCRIPT_NAME` variable, and keep only
            # the remaining path in the `PATH_INFO` variable.
            environ['SCRIPT_NAME'] = Href(environ['SCRIPT_NAME'])(env_name)
            environ['PATH_INFO'] = '/'.join([''] + path_info)

            if env_parent_dir:
                env_path = os.path.join(env_parent_dir, env_name)
            else:
                env_path = get_environments(environ).get(env_name)

            if not env_path or not os.path.isdir(env_path):
                start_response(u'404 Non trouvé', [])
                return [u'Environment non trouvé']

    if not env_path:
        raise EnvironmentError(u'Les options d\'environment "TRAC_ENV" ou '
                               u'"TRAC_ENV_PARENT_DIR", ou bien les options '
                               u'mod_python "TracEnv" ou "TracEnvParentDir" ne '
                               u'sont pas définies. Trac a besoin d\'une de ces '
                               u'options pour localiser le ou les environnments '
                               u'Trac.')
    run_once = environ['wsgi.run_once']
    env = _open_environment(env_path, run_once=run_once)

    if env.base_url:
        environ['trac.base_url'] = env.base_url

    req = Request(environ, start_response)
    try:
        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:
        env.log.warn(e)
        if req.hdf:
            req.hdf['title'] = e.reason or u'Erreur'
            req.hdf['error'] = {
                'title': e.reason or u'Erreur',
                'type': 'TracError',
                'message': e.message
            }
        try:
            req.send_error(sys.exc_info(), status=e.code)
        except RequestDone:
            return []
Пример #13
0
 def test_empty_content(self):
     context = Mock(env=self.env, href=Href('/'), req=self.req)
     formatter = Mock(context=context, req=self.req)
     self.assertTrue('No resources found' in str(
         self.tag_twm.expand_macro(formatter, 'ListTagged', '')))
Пример #14
0
class TracTicket(object):
    """A Trac ticket implementation
    see http://trac.edgewall.org/
    """
    def __init__(self, env, parameters):
        self.env = env
        self.db = None

    def searchTickets(self, nbsec):
        """search tickets updated since nbsec, if nbsec is -1, it checks all jobs
        else check is performed since now - nbsec.
        """
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        tickets = {}
        if nbsec == -1:
            sql = 'SELECT id, changetime, owner, summary, status FROM ticket'
        else:
            sql = 'SELECT id, changetime, owner, summary, status FROM ticket WHERE strftime(\'%s\',  \'now\') - changetime < ' + str(
                nbsec)
        cursor.execute(sql)
        while True:
            row = cursor.fetchone()
            if row == None:
                break
            r = {
                'Date': row[1],
                'Status': row[4],
                'Description': row[3],
                'User': row[2],
                'From': u'trac'
            }
            tickets[row[0]] = r

        return tickets

    def searchFixes(self, id, jobs):
        """try to retrieve comment input string into ticket's changes stored
        in sqlite db.
        """
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        begin_ticket_re = re.compile(r'see changelist')
        ticket_re = re.compile(r'\d+')

        tickets = {}
        sql = 'SELECT newvalue FROM ticket_change where field="comment" and ticket=%d' % (
            id)
        cursor.execute(sql)
        while True:
            row = cursor.fetchone()
            if row == None:
                break
            row = str(row)
            if begin_ticket_re.search(row):
                trac = set([])
                for x in ticket_re.findall(row):
                    trac.add(int(x))
                jobs.difference_update(trac)

        return jobs

    def updateTicket(self, id, ticket, notification):
        """
        """
        try:
            tkt = Ticket(self.env, id, self.db)
        except TracError, detail:
            print "Cannot create Trac ticket : %s" % (detail)
            return

        tkt['status'] = settings['p4_to_trac'][ticket['Status']]
        if tkt['status'] == u'closed':
            tkt['resolution'] = u'fixed'
        else:
            tkt['resolution'] = u''
        tkt['owner'] = ticket['User']
        tkt['summary'] = ticket['Description']

        jobs = set([])
        comment = ''
        if 'Fixes' in ticket:
            for f in ticket['Fixes']:
                jobs.add(int(f))
            jobs = self.searchFixes(id, jobs)
            if len(jobs) > 0:
                comment = 'see changelist :'
                for j in jobs:
                    comment += ' [%d]' % j
        if settings.get('debug', 0) > 1:
            print "Trac ticket comment %s" % (comment)

        when = datetime.fromtimestamp(ticket['Date'], utc)

        if settings.get('debug', 0):
            print "update Trac %d  %s" % (id, ticket)
        if settings.get('dry_run', 0) == 0:
            saved = tkt.save_changes(ticket['User'], comment, when)
            try:
                if saved:
                    self.env._abs_href = Href(
                        self.env.config.get('project', 'url'))
                    #self.env._href = Href(self.env.config.get('project', 'url'))
                    tn = TicketNotifyEmail(self.env)
                    tn.notify(tkt, False, when)
            except Exception, e:
                print 'TD: Failure sending notification on creation of ticket #%s: %s' % (
                    id, e)
Пример #15
0
    def test_testcase_errors_and_failures(self):
        config = Mock(name='trunk',
                      path='/somewhere',
                      min_rev_time=lambda env: 0,
                      max_rev_time=lambda env: 1000)
        step = Mock(name='foo')

        build = Build(self.env,
                      config=config.name,
                      platform=1,
                      rev=123,
                      rev_time=42)
        build.insert()
        report = Report(self.env,
                        build=build.id,
                        step=step.name,
                        category='test')
        report.items += [{
            'fixture': 'test_foo',
            'name': 'foo',
            'file': 'foo.c',
            'type': 'test',
            'status': 'success'
        }, {
            'fixture': 'test_bar',
            'name': 'bar',
            'file': 'bar.c',
            'type': 'test',
            'status': 'error',
            'traceback': 'Error traceback'
        }, {
            'fixture': 'test_baz',
            'name': 'baz',
            'file': 'baz.c',
            'type': 'test',
            'status': 'failure',
            'traceback': 'Failure reason'
        }]
        report.insert()

        req = Mock(href=Href('trac'))
        generator = TestResultsSummarizer(self.env)
        template, data = generator.render_summary(req, config, build, step,
                                                  'test')
        self.assertEquals('bitten_summary_tests.html', template)
        self.assertEquals(data['totals'], {
            'ignore': 0,
            'failure': 1,
            'success': 1,
            'error': 1
        })
        for fixture in data['fixtures']:
            if fixture.has_key('failures'):
                if fixture['failures'][0]['status'] == 'error':
                    self.assertEquals('test_bar', fixture['name'])
                    self.assertEquals('Error traceback',
                                      fixture['failures'][0]['traceback'])
                if fixture['failures'][0]['status'] == 'failure':
                    self.assertEquals('test_baz', fixture['name'])
                    self.assertEquals('Failure reason',
                                      fixture['failures'][0]['traceback'])
Пример #16
0
    def populate_hdf(self, req, handler):
        """Add chrome-related data to the HDF."""

        # Provided for template customization
        req.hdf['HTTP.PathInfo'] = req.path_info

        href = Href(req.base_path)
        req.hdf['chrome.href'] = href.chrome()
        htdocs_location = self.htdocs_location or href.chrome('common')
        req.hdf['htdocs_location'] = htdocs_location.rstrip('/') + '/'

        # HTML <head> links
        add_link(req, 'start', req.href.wiki())
        add_link(req, 'search', req.href.search())
        add_link(req, 'help', req.href.wiki('TracGuide'))
        add_stylesheet(req, 'common/css/trac.css')
        add_script(req, 'common/js/trac.js')

        icon = self.env.project_icon
        if icon:
            if not icon.startswith('/') and icon.find('://') == -1:
                if '/' in icon:
                    icon = href.chrome(icon)
                else:
                    icon = href.chrome('common', icon)
            mimetype = mimeview.get_mimetype(icon)
            add_link(req, 'icon', icon, mimetype=mimetype)
            add_link(req, 'shortcut icon', icon, mimetype=mimetype)

        # Logo image
        logo_src = self.logo_src
        if logo_src:
            logo_src_abs = logo_src.startswith('http://') or \
                           logo_src.startswith('https://')
            if not logo_src.startswith('/') and not logo_src_abs:
                if '/' in logo_src:
                    logo_src = href.chrome(logo_src)
                else:
                    logo_src = href.chrome('common', logo_src)
            width = self.logo_width > -1 and self.logo_width
            height = self.logo_height > -1 and self.logo_height
            req.hdf['chrome.logo'] = {
                'link': self.logo_link, 'src': logo_src,
                'src_abs': logo_src_abs, 'alt': self.logo_alt,
                'width': width, 'height': height
            }
        else:
            req.hdf['chrome.logo.link'] = self.logo_link

        # Navigation links
        navigation = {}
        active = None
        for contributor in self.navigation_contributors:
            for category, name, text in contributor.get_navigation_items(req):
                navigation.setdefault(category, {})[name] = text
            if contributor is handler:
                active = contributor.get_active_navigation_item(req)

        for category, items in [(k, v.items()) for k, v in navigation.items()]:
            category_order = category + '_order'
            if hasattr(self, category_order):
                order = getattr(self, category_order)
                def navcmp(x, y):
                    if x[0] not in order:
                        return int(y[0] in order)
                    if y[0] not in order:
                        return -int(x[0] in order)
                    return cmp(order.index(x[0]), order.index(y[0]))
                items.sort(navcmp)

            for name, text in items:
                req.hdf['chrome.nav.%s.%s' % (category, name)] = text
                if name == active:
                    req.hdf['chrome.nav.%s.%s.active' % (category, name)] = 1
Пример #17
0
    def expand_macro(self, formatter, name, content, args=None):
        content = content.replace('\n', ',')
        args, kwargs = parse_args(content,
                                  multi=['markers', 'path', 'visible'])

        # HTML arguments used in Google Maps URL
        hargs = {
            'center': "50.805935,10.349121",
            #'zoom'   : "6",
            'key': self.key,
            'size': self.size,
            'hl': self.hl,
            'sensor': 'false',
        }

        # Set API version
        api = kwargs.get('api', self.api)
        if api not in self.google_url:
            api = self.api

        # Delete default zoom if user provides 'span' argument:
        if 'span' in kwargs:
            del hargs['zoom']

        # Copy given macro arguments to the HTML arguments
        for k, v in kwargs.iteritems():
            if k in self.allowed_args and v:
                hargs[k] = v

        # Check if API key exists
        if not 'key' in hargs and api == '1':  # TODO: check if old API still needs the key
            raise TracError("No Google Maps API key given!\n")

        # Get height and width
        try:
            if 'x' not in hargs['size']:
                hargs['size'] = hargs['size'] + 'x' + hargs['size']
            (width, height) = hargs['size'].split('x')
            if int(height) < 1:
                height = "1"
            elif int(height) > 640:
                height = "640"
            if int(width) < 1:
                width = "1"
            elif int(width) > 640:
                width = "640"
            hargs['size'] = "%sx%s" % (width, height)
        except:
            raise TracError(
                "Invalid `size` argument. Should be `<width>x<height>`.")

        if api == '1':
            # Correct separator for 'center' argument because comma isn't allowed in
            # macro arguments
            hargs['center'] = hargs['center'].replace(':', ',')
            if 'markers' in hargs:
                hargs['markers'] = [
                    marker.replace(':', ',') for marker in hargs['markers']
                ]

        # Build URL
        src = Href(self.google_url.get(api, ''))(**hargs)

        title = alt = "Google Static Map at %s" % hargs['center']
        # TODO: provide sane alternative text and image title

        if 'title' in kwargs:
            title = kwargs['title']

        return tag.img(
            class_="googlestaticmap",
            src=src,
            title=title,
            alt=alt,
            height=height,
            width=width,
        )
Пример #18
0
    def post_process_request(self, req, template, data, content_type):
        user = to_unicode(req.authname)
        settings = self.get_settings(
            user)  # FIXME: suboptimal to reload settings here
        # TODO: Move to request handler?

        msg = req.session.get('watchlist_message', [])
        if msg:
            add_notice(req, msg)
            del req.session['watchlist_message']
        msg = req.session.get('watchlist_notify_message', [])
        if msg:
            add_notice(req, msg)
            del req.session['watchlist_notify_message']

        # Extract realm and resid from path:
        parts = req.path_info[1:].split('/', 1)

        # Handle special case for '/' and '/wiki'
        if len(parts) == 0 or not parts[0]:
            parts = ["wiki", "WikiStart"]
        elif len(parts) == 1:
            parts.append("WikiStart")

        realm, resid = parts[:2]

        if realm not in self.realms or not \
                self.realm_handler[realm].has_perm(realm, req.perm):
            return (template, data, content_type)

        href = Href(req.base_path)
        user = req.authname
        if user and user != "anonymous":
            if self.is_watching(realm, resid, user):
                add_ctxtnav(req,
                            _("Unwatch"),
                            href=req.href('watchlist',
                                          action='unwatch',
                                          resid=resid,
                                          realm=realm),
                            title=_("Remove %s from watchlist") % realm)
            else:
                add_ctxtnav(req,
                            _("Watch"),
                            href=req.href('watchlist',
                                          action='watch',
                                          resid=resid,
                                          realm=realm),
                            title=_("Add %s to watchlist") % realm)
            if settings['notifications'] and settings[
                    'display_notify_navitems']:
                if self.is_notify(req, realm, resid):
                    add_ctxtnav(req,
                                _("Do not Notify me"),
                                href=req.href('watchlist',
                                              action='notifyoff',
                                              resid=resid,
                                              realm=realm),
                                title=_("Do not notify me if %s changes") %
                                realm)
                else:
                    add_ctxtnav(req,
                                _("Notify me"),
                                href=req.href('watchlist',
                                              action='notifyon',
                                              resid=resid,
                                              realm=realm),
                                title=_("Notify me if %s changes") % realm)

        return (template, data, content_type)
Пример #19
0
    def test_process_build_step_invalidated_build(self):
        recipe = """<build>
  <step id="foo">
  </step>
  <step id="foo2">
  </step>
</build>"""
        BuildConfig(self.env,
                    'test',
                    path='somepath',
                    active=True,
                    recipe=recipe).insert()
        build = Build(self.env,
                      'test',
                      '123',
                      1,
                      slave='hal',
                      rev_time=42,
                      started=42,
                      status=Build.IN_PROGRESS)
        build.slave_info[Build.TOKEN] = '123'
        build.insert()

        inbody = StringIO("""<result step="foo" status="success"
                                     time="2007-04-01T15:30:00.0000"
                                     duration="3.45">
    <log generator="http://bitten.edgewall.org/tools/python#unittest">
        <message level="info">Doing stuff</message>
        <message level="error">Ouch that hurt</message>
    </log>
</result>""")
        outheaders = {}
        outbody = StringIO()
        req = Mock(method='POST',
                   base_path='',
                   path_info='/builds/%d/steps/' % build.id,
                   href=Href('/trac'),
                   abs_href=Href('http://example.org/trac'),
                   remote_addr='127.0.0.1',
                   args={},
                   perm=PermissionCache(self.env, 'hal'),
                   read=inbody.read,
                   send_response=lambda x: outheaders.setdefault('Status', x),
                   send_header=lambda x, y: outheaders.setdefault(x, y),
                   write=outbody.write,
                   incookie=Cookie('trac_auth=123'))
        module = BuildMaster(self.env)

        module._start_new_step(build, 'foo').insert()

        assert module.match_request(req)

        self.assertRaises(RequestDone, module.process_request, req)

        build = Build.fetch(self.env, build.id)
        self.assertEqual(Build.IN_PROGRESS, build.status)
        assert not build.stopped

        steps = list(BuildStep.select(self.env, build.id))
        self.assertEqual(2, len(steps))

        # invalidate the build.

        build = Build.fetch(self.env, build.id)
        build.slave = None
        build.status = Build.PENDING
        build.slave_info = {}
        for step in list(BuildStep.select(self.env, build=build.id)):
            step.delete()
        build.update()

        # have this slave submit more data.
        inbody = StringIO("""<result step="foo2" status="success"
                                     time="2007-04-01T15:45:00.0000"
                                     duration="4">
    <log generator="http://bitten.edgewall.org/tools/python#unittest">
        <message level="info">This is a step after invalidation</message>
    </log>
</result>""")
        outheaders = {}
        outbody = StringIO()
        req = Mock(method='POST',
                   base_path='',
                   path_info='/builds/%d/steps/' % build.id,
                   href=Href('/trac'),
                   abs_href=Href('http://example.org/trac'),
                   remote_addr='127.0.0.1',
                   args={},
                   perm=PermissionCache(self.env, 'hal'),
                   read=inbody.read,
                   send_response=lambda x: outheaders.setdefault('Status', x),
                   send_header=lambda x, y: outheaders.setdefault(x, y),
                   write=outbody.write,
                   incookie=Cookie('trac_auth=123'))
        module = BuildMaster(self.env)

        module._start_new_step(build, 'foo').insert()

        assert module.match_request(req)

        self.assertRaises(RequestDone, module.process_request, req)

        self.assertEquals(409, outheaders['Status'])
        self.assertEquals('Token mismatch (wrong slave): slave=123, build=',
                          outbody.getvalue())

        build = Build.fetch(self.env, build.id)
        self.assertEqual(Build.PENDING, build.status)
Пример #20
0
 def test_login_no_username(self):
     req = Mock(incookie=Cookie(), href=Href('/trac.cgi'),
                remote_addr='127.0.0.1', remote_user=None,
                base_path='/trac.cgi')
     self.assertRaises(TracError, self.module._do_login, req)
Пример #21
0
class LinkAdmin(Component):
    implements(IAdminPageProvider, ITemplateProvider)

    # IAdminPageProvider methods

    # required permission to access this page
    _perm = 'TRAC_ADMIN'

    def get_admin_pages(self, req):
        # FIXME: more suitable permission should be used
        if req.perm.has_permission(self._perm):
            # (category, category_label, page, page_label)
            yield ('general', 'General', 'link', 'Links')

    def _set_message(self, req, cls, text):
        req.session['message_text'] = text
        req.session['message_class'] = cls

    def _get_message(self, req):
        return req.session.get('message_text', ''), \
               req.session.get('message_class', 'none')

    def _clear_message(self, req):
        dic = req.session
        if dic.has_key('message_text'):
            dic.pop('message_text')
        if dic.has_key('message_class'):
            dic.pop('message_class')

    def _notify(self, req, text):
        self._set_message(req, 'notify', text)

    def _error(self, req, text):
        self._set_message(req, 'error', 'ERROR: ' + text)

    def process_admin_request(self, req, category, page, name):
        req.perm.assert_permission(self._perm)

        # this page may called like
        # /proj/admin/general
        # /proj/admin/general/link
        # /proj/admin/general/link/name
        base_href = self.env.href.admin('general', 'link')

        # post back actions:
        #   add ... add and redirect to top
        #   modify ... modify and redirect self or renamed self
        #   remove ... redirect to top

        prov = GeneralLinkSyntaxProvider(self.env)
        prov.load()
        try:
            if name:
                link = prov.get_link(name)
                if not link:
                    raise TracError('No such link name: ' + name)

                # prepare to modify
                req.hdf['admin.link'] = link.get_hash()
                req.hdf['admin.link.mode'] = 'modify'
                if req.method == 'POST':
                    # change value
                    if req.args.get('save'):
                        # set values
                        prov.modify(name,
                                    req.args.get('expose') != None,
                                    req.args.get('disp'), req.args.get('url'))
                        self._notify(req, "link '%s' is modified'" % name)
                    # redirect to base
                    req.redirect(base_href)
            else:
                if req.method == 'POST':
                    if req.args.get('add'):
                        # add new entry
                        name = req.args.get('name')
                        expose = req.args.get('expose') != None
                        url = req.args.get('url')
                        disp = req.args.get('disp')
                        req.hdf['admin.link'] = {
                            'mode': 'add',
                            'name': name,
                            'exposed': expose,
                            'disp': disp,
                            'url': url
                        }
                        prov.add(name, expose, disp, url)
                        self._notify(req, "link '%s' is added'" % name)
                    elif req.args.get('remove') and req.args.get('sel'):
                        # Remove components
                        sel = req.args.get('sel')
                        sel = isinstance(sel, list) and sel or [sel]
                        if not sel:
                            raise TracError, 'No item selected'
                        for name in sel:
                            prov.delete(name)
                        self._notify(req, 'deleted %d liks' % len(sel))
                    req.redirect(base_href)

        except Exception, e:
            self._error(req, str(e))

        # render current links
        links = []
        href = Href(base_href)
        for link in prov.get_links():
            h = link.get_hash()
            h['href'] = href(link.get_name())
            links.append(h)
        req.hdf['admin.links'] = links
        # prepare notify message
        message_text, message_class = self._get_message(req)
        req.hdf['admin.message.text'] = message_text
        req.hdf['admin.message.class'] = message_class
        self._clear_message(req)
        add_stylesheet(req, 'admin/css/admin_link.css')
        return 'admin_link.cs', None
Пример #22
0
 def test_logout_not_logged_in(self):
     req = Mock(cgi_location='/trac', href=Href('/trac.cgi'),
                incookie=Cookie(), outcookie=Cookie(),
                remote_addr='127.0.0.1', remote_user=None,
                authname='anonymous', method='POST', base_path='/trac.cgi')
     self.module._do_logout(req) # this shouldn't raise an error
Пример #23
0
 def test_add_stylesheet_media(self):
     req = Request(base_path='/trac.cgi', href=Href('/trac.cgi'))
     add_stylesheet(req, 'foo.css', media='print')
     links = req.chrome['links']['stylesheet']
     self.assertEqual(1, len(links))
     self.assertEqual('print', links[0]['media'])
Пример #24
0
 def test_anonymous_access(self):
     req = Mock(incookie=Cookie(), href=Href('/trac.cgi'),
                remote_addr='127.0.0.1', remote_user=None,
                base_path='/trac.cgi')
     self.assertIsNone(self.module.authenticate(req))
Пример #25
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True)
     self.req = Mock(perm=MockPerm(), href=Href('/trac.cgi'))
     self.context = web_context(self.req)
Пример #26
0
 def setUp(self):
     self.ghref = Href('/gbase')
     self.phref = ProductizedHref(self.ghref, '/gbase/product')
Пример #27
0
def dispatch_request(environ, start_response):
    """Main entry point for the Trac web interface.

    :param environ: the WSGI environment dict
    :param start_response: the WSGI callback for starting the response
    """

    # SCRIPT_URL is an Apache var containing the URL before URL rewriting
    # has been applied, so we can use it to reconstruct logical SCRIPT_NAME
    script_url = environ.get('SCRIPT_URL')
    if script_url is not None:
        path_info = environ.get('PATH_INFO')
        if not path_info:
            environ['SCRIPT_NAME'] = script_url
        else:
            # mod_wsgi squashes slashes in PATH_INFO (!)
            script_url = _slashes_re.sub('/', script_url)
            path_info = _slashes_re.sub('/', path_info)
            if script_url.endswith(path_info):
                environ['SCRIPT_NAME'] = script_url[:-len(path_info)]

    # If the expected configuration keys aren't found in the WSGI environment,
    # try looking them up in the process environment variables
    environ.setdefault('trac.env_path', os.getenv('TRAC_ENV'))
    environ.setdefault('trac.env_parent_dir', os.getenv('TRAC_ENV_PARENT_DIR'))
    environ.setdefault('trac.env_index_template',
                       os.getenv('TRAC_ENV_INDEX_TEMPLATE'))
    environ.setdefault('trac.template_vars', os.getenv('TRAC_TEMPLATE_VARS'))
    environ.setdefault('trac.locale', '')
    environ.setdefault('trac.base_url', os.getenv('TRAC_BASE_URL'))

    locale.setlocale(locale.LC_ALL, environ['trac.locale'])

    # Determine the environment
    env_path = environ.get('trac.env_path')
    if not env_path:
        env_parent_dir = environ.get('trac.env_parent_dir')
        env_paths = environ.get('trac.env_paths')
        if env_parent_dir or env_paths:
            # The first component of the path is the base name of the
            # environment
            path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
            env_name = path_info.pop(0)

            if not env_name:
                # No specific environment requested, so render an environment
                # index page
                send_project_index(environ, start_response, env_parent_dir,
                                   env_paths)
                return []

            errmsg = None

            # To make the matching patterns of request handlers work, we append
            # the environment name to the `SCRIPT_NAME` variable, and keep only
            # the remaining path in the `PATH_INFO` variable.
            script_name = environ.get('SCRIPT_NAME', '')
            try:
                script_name = unicode(script_name, 'utf-8')
                # (as Href expects unicode parameters)
                environ['SCRIPT_NAME'] = Href(script_name)(env_name)
                environ['PATH_INFO'] = '/' + '/'.join(path_info)

                if env_parent_dir:
                    env_path = os.path.join(env_parent_dir, env_name)
                else:
                    env_path = get_environments(environ).get(env_name)

                if not env_path or not os.path.isdir(env_path):
                    errmsg = 'Environment not found'
            except UnicodeDecodeError:
                errmsg = 'Invalid URL encoding (was %r)' % script_name

            if errmsg:
                start_response('404 Not Found',
                               [('Content-Type', 'text/plain'),
                                ('Content-Length', str(len(errmsg)))])
                return [errmsg]

    if not env_path:
        raise EnvironmentError('The environment options "TRAC_ENV" or '
                               '"TRAC_ENV_PARENT_DIR" or the mod_python '
                               'options "TracEnv" or "TracEnvParentDir" are '
                               'missing. Trac requires one of these options '
                               'to locate the Trac environment(s).')
    run_once = environ['wsgi.run_once']

    env = env_error = None
    try:
        env = open_environment(env_path, use_cache=not run_once)
        if env.base_url_for_redirect:
            environ['trac.base_url'] = env.base_url

        # Web front-end type and version information
        if not hasattr(env, 'webfrontend'):
            mod_wsgi_version = environ.get('mod_wsgi.version')
            if mod_wsgi_version:
                mod_wsgi_version = (
                    "%s (WSGIProcessGroup %s WSGIApplicationGroup %s)" %
                    ('.'.join([str(x) for x in mod_wsgi_version
                               ]), environ.get('mod_wsgi.process_group'),
                     environ.get('mod_wsgi.application_group') or '%{GLOBAL}'))
                environ.update({
                    'trac.web.frontend': 'mod_wsgi',
                    'trac.web.version': mod_wsgi_version
                })
            env.webfrontend = environ.get('trac.web.frontend')
            if env.webfrontend:
                env.webfrontend_version = environ['trac.web.version']
    except Exception as e:
        env_error = e

    req = RequestWithSession(environ, start_response)
    translation.make_activable(lambda: req.locale, env.path if env else None)
    try:
        return _dispatch_request(req, env, env_error)
    finally:
        translation.deactivate()
        if env and not run_once:
            env.shutdown(threading._get_ident())
            # Now it's a good time to do some clean-ups
            #
            # Note: enable the '##' lines as soon as there's a suspicion
            #       of memory leak due to uncollectable objects (typically
            #       objects with a __del__ method caught in a cycle)
            #
            ##gc.set_debug(gc.DEBUG_UNCOLLECTABLE)
            unreachable = gc.collect()
Пример #28
0
    def __init__(self,
                 default_data=False,
                 enable=None,
                 disable=None,
                 path=None,
                 destroying=False):
        """Construct a new Environment stub object.

        :param default_data: If True, populate the database with some
                             defaults.
        :param enable: A list of component classes or name globs to
                       activate in the stub environment.
        """
        ComponentManager.__init__(self)
        Component.__init__(self)

        self.systeminfo = []

        import trac
        self.path = path
        if self.path is None:
            self.path = os.path.dirname(trac.__file__)
            if not os.path.isabs(self.path):
                self.path = os.path.join(os.getcwd(), self.path)

        # -- configuration
        self.config = Configuration(None)
        # We have to have a ticket-workflow config for ''lots'' of things to
        # work.  So insert the basic-workflow config here.  There may be a
        # better solution than this.
        load_workflow_config_snippet(self.config, 'basic-workflow.ini')
        self.config.set('logging', 'log_level', 'DEBUG')
        self.config.set('logging', 'log_type', 'stderr')
        if enable is not None:
            self.config.set('components', 'trac.*', 'disabled')
        else:
            self.config.set('components', 'tracopt.versioncontrol.svn.*',
                            'enabled')
        for name_or_class in enable or ():
            config_key = self._component_name(name_or_class)
            self.config.set('components', config_key, 'enabled')
        for name_or_class in disable or ():
            config_key = self._component_name(name_or_class)
            self.config.set('components', config_key, 'disabled')

        # -- logging
        from trac.log import logger_handler_factory
        self.log, self._log_handler = logger_handler_factory('test')

        # -- database
        self.config.set('components', 'trac.db.*', 'enabled')
        self.dburi = get_dburi()

        init_global = False
        if self.global_databasemanager:
            self.components[DatabaseManager] = self.global_databasemanager
        else:
            self.config.set('trac', 'database', self.dburi)
            self.global_databasemanager = DatabaseManager(self)
            self.config.set('trac', 'debug_sql', True)
            self.config.set('logging', 'log_type', 'stderr')
            self.config.set('logging', 'log_level', 'DEBUG')
            init_global = not destroying

        if default_data or init_global:
            self.reset_db(default_data)

        from trac.web.href import Href
        self.href = Href('/trac.cgi')
        self.abs_href = Href('http://example.org/trac.cgi')

        self.known_users = []
        translation.activate(locale_en)
Пример #29
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True)
     self.req = Mock(base_path='', chrome={}, args={}, session={},
                     abs_href=Href('/'), href=Href('/'), locale='',
                     perm=MockPerm(), authname=None, tz=None)
     self.report_module = ReportModule(self.env)
Пример #30
0
 def _get_jquery_ui_script_data(self, lc_time):
     req = Request(href=Href('/trac.cgi'), tz=utc, lc_time=lc_time)
     Chrome(self.env).add_jquery_ui(req)
     return req.chrome['script_data']['jquery_ui']
Пример #31
0
 def abs_href(self):
     """The application URL"""
     if not self.base_url:
         self.log.warning("base_url option not set in configuration, "
                          "generated links may be incorrect")
     return Href(self.base_url)
Пример #32
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True)
     self.query_module = QueryModule(self.env)
     req = Mock(perm=MockPerm(), args={}, href=Href('/'))
     self.formatter = LinkFormatter(self.env, web_context(req))
Пример #33
0
    def test_process_build_step_success_with_log(self):
        recipe = """<build>
  <step id="foo">
  </step>
</build>"""
        BuildConfig(self.env,
                    'test',
                    path='somepath',
                    active=True,
                    recipe=recipe).insert()
        build = Build(self.env,
                      'test',
                      '123',
                      1,
                      slave='hal',
                      rev_time=42,
                      started=42,
                      status=Build.IN_PROGRESS)
        build.slave_info[Build.TOKEN] = '123'
        build.insert()

        inbody = StringIO("""<result step="foo" status="success"
                                     time="2007-04-01T15:30:00.0000"
                                     duration="3.45">
    <log generator="http://bitten.edgewall.org/tools/python#unittest">
        <message level="info">Doing stuff</message>
        <message level="error">Ouch that hurt</message>
    </log>
</result>""")
        outheaders = {}
        outbody = StringIO()
        req = Mock(method='POST',
                   base_path='',
                   path_info='/builds/%d/steps/' % build.id,
                   href=Href('/trac'),
                   abs_href=Href('http://example.org/trac'),
                   remote_addr='127.0.0.1',
                   args={},
                   perm=PermissionCache(self.env, 'hal'),
                   read=inbody.read,
                   send_response=lambda x: outheaders.setdefault('Status', x),
                   send_header=lambda x, y: outheaders.setdefault(x, y),
                   write=outbody.write,
                   incookie=Cookie('trac_auth=123'))
        module = BuildMaster(self.env)

        module._start_new_step(build, 'foo').insert()

        assert module.match_request(req)

        self.assertRaises(RequestDone, module.process_request, req)

        self.assertEqual(201, outheaders['Status'])
        self.assertEqual('20', outheaders['Content-Length'])
        self.assertEqual('text/plain', outheaders['Content-Type'])
        self.assertEqual('Build step processed', outbody.getvalue())

        build = Build.fetch(self.env, build.id)
        self.assertEqual(Build.SUCCESS, build.status)
        assert build.stopped
        assert build.stopped > build.started

        steps = list(BuildStep.select(self.env, build.id))
        self.assertEqual(1, len(steps))
        self.assertEqual('foo', steps[0].name)
        self.assertEqual(BuildStep.SUCCESS, steps[0].status)

        logs = list(BuildLog.select(self.env, build=build.id, step='foo'))
        self.assertEqual(1, len(logs))
        self.assertEqual('http://bitten.edgewall.org/tools/python#unittest',
                         logs[0].generator)
        self.assertEqual(2, len(logs[0].messages))
        self.assertEqual((u'info', u'Doing stuff'), logs[0].messages[0])
        self.assertEqual((u'error', u'Ouch that hurt'), logs[0].messages[1])
Пример #34
0
 def get_href(self, href, *args, **kwargs):
     href = Href(href.tracforge())
     return super(MultiQuery, self).get_href(href, *args, **kwargs)