Example #1
0
    def _format_link_file(self, formatter, ns, target, label, fullmatch=None):
        """ returns a tag for
            org.example.package.Class.method(Class.java:123) """
        fqcn = fullmatch.group("fqcn")
        classname = fullmatch.group("classname")
        line = fullmatch.group("lineno")
        line = line and '#L%s' % line or ""
        rm = RepositoryManager(self.env)
        self.get_psf()  # force parse
        # search repositories by fully qualified class name
        if fqcn:
            fqcn_filename = fqcn.replace('.', '/') + ".java"
            for reponame in self._srcpathes.keys():
                repo = rm.get_repository(reponame)
                if not repo:
                    continue
                for srcpath in self._srcpathes[reponame]:
                    try:
                        if repo.has_node(srcpath + fqcn_filename, None):
                            return tag.a(
                                label,
                                href=formatter.href.browser(reponame + '/' +
                                                            srcpath +
                                                            fqcn_filename) +
                                line,
                                class_="source")
                    except Exception, e:  # GIT throws exception if MBCS used in fqcn
                        self.env.log.error(e)
                        pass
# implemented but not fit i feel
#             for prefix in self._prefixes.keys():
#                 if fqcn.startswith(prefix):
#                     href = self._prefixes[prefix] + fqcn.replace('.', '/') + '.html'
#                     return tag.a(label, href=href, class_="file")
            return label  # not missing resource
Example #2
0
    def pre_process_request(self, req, handler):
        """
        Pre-process the request by adding 'Zip Archive' link into alternative format links
        The link is constructed from first and latest revision number, taken from the default
        repository.

        :param Request req: Trac request
        :param object handler: existing handler
        :returns: Handler, modified or not
        """
        # Add link only in /browser or /browser/?rev= pages
        if (self.browser_regx.match(req.path_info)
            and 'BROWSER_VIEW' in req.perm and 'FILE_VIEW' in req.perm):
            # Get default repository and its type
            rm = RepositoryManager(self.env)
            repo = rm.get_repository('')
            repo_type = rm.repository_type

            # Construct the export urls for each format and based on revision info
            latest_rev = plaintext(str(req.args.get('rev', repo.get_youngest_rev())))

            # Use Trac's internal implementation
            if repo_type == 'svn':
                return handler

            # For other types, iterate supported formats
            for format, info in self.formats.items():
                add_link(req, 'alternate', req.href('export/archive', rev=latest_rev, format=format), _(info['desc']),
                    info['mime'], info['ext'])

        return handler
Example #3
0
    def _format_link(self, formatter, ns, match, label, fullmatch=None):
        if ns == 'log1':
            groups = fullmatch.groupdict()
            it_log = groups.get('it_log')
            revs = groups.get('log_revs')
            path = groups.get('log_path') or '/'
            target = '%s%s@%s' % (it_log, path, revs)
            # prepending it_log is needed, as the helper expects it there
            intertrac = formatter.shorthand_intertrac_helper(
                'log', target, label, fullmatch)
            if intertrac:
                return intertrac
            path, query, fragment = formatter.split_link(path)
        else:
            assert ns in ('log', 'log2')
            if ns == 'log':
                match, query, fragment = formatter.split_link(match)
            else:
                query = fragment = ''
                match = ''.join(reversed(match.split('/', 1)))
            path = match
            revs = ''
            if self.LOG_LINK_RE.match(match):
                indexes = [sep in match and match.index(sep) for sep in ':@']
                idx = min([i for i in indexes if i is not False])
                path, revs = match[:idx], match[idx+1:]

        rm = RepositoryManager(self.env)
        try:
            reponame, repos, path = rm.get_repository_by_path(path)
            if not reponame:
                reponame = rm.get_default_repository(formatter.context)
                if reponame is not None:
                    repos = rm.get_repository(reponame)

            if repos:
                if 'LOG_VIEW' in formatter.perm(repos.resource):
                    reponame = repos.reponame or None
                    path = path or '/'
                    revranges = RevRanges(repos, revs)
                    if revranges.has_ranges():
                        href = formatter.href.log(reponame, path,
                                                  revs=unicode(revranges))
                    else:
                        # try to resolve if single rev
                        repos.normalize_rev(revs)
                        href = formatter.href.log(reponame, path,
                                                  rev=revs or None)
                    if query and '?' in href:
                        query = '&' + query[1:]
                    return tag.a(label, class_='source',
                                 href=href + query + fragment)
                errmsg = _("No permission to view change log")
            elif reponame:
                errmsg = _("Repository '%(repo)s' not found", repo=reponame)
            else:
                errmsg = _("No default repository defined")
        except TracError as e:
            errmsg = to_unicode(e)
        return tag.a(label, class_='missing source', title=errmsg)
Example #4
0
 def get_navigation_items(self, req):
     rm = RepositoryManager(self.env)
     if any(
             repos.is_viewable(req.perm)
             for repos in rm.get_real_repositories()):
         yield ('mainnav', 'browser',
                tag.a(_('Browse Source'), href=req.href.browser()))
Example #5
0
def do_upgrade(env, version, cursor):
    """Replace list of repositories in [trac] repository_sync_per_request
    with boolean values [repositories] <repos>.sync_per_request.
    """
    repos_sync_per_request = \
        env.config.getlist('trac', 'repository_sync_per_request')
    if not repos_sync_per_request:
        return

    backup_config_file(env, '.db32.bak')
    rm = RepositoryManager(env)
    db_provider = env[DbRepositoryProvider]

    trac_ini_repo_names = []
    for name, _ in rm.get_repositories():
        trac_ini_repo_names.append(name)
    for repos in rm.get_all_repositories().values():
        sync_per_request = (repos['name'] or '(default)') \
                           in repos_sync_per_request
        if sync_per_request:
            if repos['name'] in trac_ini_repo_names:
                env.config.set('repositories',
                               repos['name'] + '.sync_per_request', 'true')
            else:
                changes = {'sync_per_request': sync_per_request}
                db_provider.modify_repository(repos['name'], changes)
    env.log.info(
        "Removed [trac] repository_sync_per_request option and "
        "enabled sync_per_request for the following "
        "repositories: %s", ', '.join(repos_sync_per_request))
    env.config.remove('trac', 'repository_sync_per_request')
    env.config.save()
 def setUp(self):
     super(ChangesetIndexerEventsTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.repository_manager = RepositoryManager(self.env)
     self.inject_dummy_repository()
Example #7
0
    def post_process_request(self, req, template, data, content_type):
        #add_script(req, 'multiproject/js/browser.js')
        repository_name = None
        data_repositories = None
        latest_revisions = []
        if len(req.path_info.split("/")) > 2:
            #Get repository name from path_info
            repository_name = req.path_info.split("/")[2]
        if template == 'browser.html':
            username = urllib.quote(req.authname)
            project = Project.get(self.env)
            schemes = None
            if repository_name:
                scm_type = repository_name + ".type"
                scm_dir = repository_name + ".dir"
                scm = self.env.config.get('repositories', scm_type)
                repository_name = self.env.config.get('repositories', scm_dir).split("/")[-1]
                schemes = self.protocols(project.id, scm)
                rm = RepositoryManager(self.env)
                list_repos = rm.get_real_repositories()
                for r in list_repos:
                    if r.get_base().split("/")[-1] == repository_name:
                        l_rev = r.get_youngest_rev()
                        if l_rev:
                            export_url = '../export/archive/'+repository_name+"?rev="+str(l_rev)+"&format=zip"
                            latest_revisions.append(export_url)

            else:
                scm = self.env.config.get('trac', 'repository_type')
                schemes = self.protocols(project.id, scm)
                data_repo_names = self.get_repositories()
                if len(data_repo_names) > 0:
                    data_repositories = []
                    for repo in data_repo_names:
                        type_scheme = []
                        for data_scheme in self.protocols(project.id, repo[1]):
                            type_scheme.append(self.create_co_command(repo[1], username, data_scheme, repo[0]))
                        data_repositories.append(type_scheme)

            

            names = {'git':'GIT', 'svn':'Subversion', 'hg':'Mercurial'}
            cmd_kinds = {'git':'Clone', 'hg':'Clone', 'svn':'Check out'}

            type = names[scm]
            

            data['kinds'] = cmd_kinds
            data['schemes'] = schemes
            data['name'] = names[scm]
            data['type'] = scm
            data['data_repositories'] = data_repositories
            data['export_urls'] = latest_revisions

            co_commands = {}
            for scheme in schemes:
                co_commands[scheme] = self.create_co_command(scm, username, scheme, repository_name)
            data['co_commands'] = co_commands

        return template, data, content_type
Example #8
0
 def _read_source_from_repos(self, formatter, src_path):
     repos_mgr = RepositoryManager(self.env)
     try:  #0.12+
         repos_name, repos, source_obj = repos_mgr.get_repository_by_path(
             src_path)
     except AttributeError, e:  #0.11
         repos = repos_mgr.get_repository(formatter.req.authname)
Example #9
0
    def _format_sha_link(self, formatter, sha, label):
        # FIXME: this function needs serious rethinking...

        reponame = ''

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

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

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

            sha = repos.normalize_rev(sha) # in case it was abbreviated
            changeset = repos.get_changeset(sha)
            return tag.a(label, class_='changeset',
                         title=shorten_line(changeset.message),
                         href=formatter.href.changeset(sha, repos.reponame))
        except Exception as e:
            return tag.a(label, class_='missing changeset',
                         title=to_unicode(e), rel='nofollow')
Example #10
0
    def process_request(self, req):
        if req.method != 'POST':
            msg = u'Method not allowed (%s)\n' % req.method
            req.send(msg.encode('utf-8'), 'text/plain', 405)

        if req.args.get('token') != self.token:
            msg = u'Invalid token (%s)\n' % req.args.get('token')
            req.send(msg.encode('utf-8'), 'text/plain', 403)

        path = req.args.get('path', '/')
        rm = RepositoryManager(self.env)
        reponame, repos, path = rm.get_repository_by_path(path)

        output = u'Running hook on %s\n' % (reponame or '(default)')

        if self.autofetch:
            git = repos.git.repo
            output += u'* Running git fetch\n'
            output += git.fetch()
            output += u'* Updating references\n'
            remote_refs = git.for_each_ref(
                    "--format=%(refname)", "refs/remotes/origin").split()
            for remote_ref in remote_refs:
                local_ref = remote_ref.replace('remotes/origin', 'heads', 1)
                output += git.update_ref(local_ref, remote_ref)

        data = req.args.get('payload')
        if data:
            revs = [commit['id'] for commit in json.loads(data)['commits']]
            if revs:
                output += u'* Adding changesets %s\n' % u', '.join(revs)
                rm.notify('changeset_added', reponame, revs)

        req.send(output.encode('utf-8'), 'text/plain', 200 if output else 204)
Example #11
0
 def _get_authz_info(self):
     if not self.authz_file:
         self.log.error("The [svn] authz_file configuration option in "
                        "trac.ini is empty or not defined")
         raise ConfigurationError()
     try:
         mtime = os.path.getmtime(self.authz_file)
     except OSError as e:
         self.log.error("Error accessing svn authz permission policy "
                        "file: %s", exception_to_unicode(e))
         raise ConfigurationError()
     if mtime != self._mtime:
         self._mtime = mtime
         rm = RepositoryManager(self.env)
         modules = set(repos.reponame
                       for repos in rm.get_real_repositories())
         if '' in modules and self.authz_module_name:
             modules.add(self.authz_module_name)
         modules.add('')
         self.log.info("Parsing authz file: %s", self.authz_file)
         try:
             self._authz = parse(self.authz_file, modules)
         except ParsingError as e:
             self.log.error("Error parsing svn authz permission policy "
                            "file: %s", exception_to_unicode(e))
             raise ConfigurationError()
         else:
             self._users = {user
                            for paths in self._authz.itervalues()
                            for path in paths.itervalues()
                            for user, result in path.iteritems()
                            if result}
     return self._authz, self._users
Example #12
0
 def _get_authz_info(self):
     try:
         mtime = os.path.getmtime(self.authz_file)
     except OSError as e:
         if self._authz is not None:
             self.log.error('Error accessing authz file: %s',
                            exception_to_unicode(e))
         self._mtime = mtime = 0
         self._authz = None
         self._users = set()
     if mtime != self._mtime:
         self._mtime = mtime
         rm = RepositoryManager(self.env)
         modules = set(repos.reponame
                       for repos in rm.get_real_repositories())
         if '' in modules and self.authz_module_name:
             modules.add(self.authz_module_name)
         modules.add('')
         self.log.info('Parsing authz file: %s', self.authz_file)
         try:
             self._authz = parse(read_file(self.authz_file), modules)
             self._users = set(user for paths in self._authz.itervalues()
                               for path in paths.itervalues()
                               for user, result in path.iteritems()
                               if result)
         except Exception as e:
             self._authz = None
             self._users = set()
             self.log.error('Error parsing authz file: %s',
                            exception_to_unicode(e))
     return self._authz, self._users
    def _get_vcs_folders(self, req, q, dirname, prefix):
        rm = RepositoryManager(self.env)

        reponame, repos, path = rm.get_repository_by_path(dirname)
        repo_entries = {'text': _('Suggestions'),
                        'children': [],
                        }
        if repos:
            try:
                entries = ({'id': '/' + pathjoin(repos.reponame, e.path),
                           'text': '/' + pathjoin(repos.reponame, e.path),
                           'is_favorite': False
                            }
                           for e in repos.get_node(path).get_entries()
                           if e.can_view(req.perm)
                           and e.name.lower().startswith(prefix)
                           and e.isdir
                           )
                repo_entries['children'].extend(entries)

                if q.endswith('/'):
                    repo_entries['children'].append({'id': q,
                                                     'text': q,
                                                     'is_favorite': False
                                                     }
                                                    )
            except NoSuchNode:
                pass
        return repo_entries
class ChangesetIndexerEventsTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ChangesetIndexerEventsTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.repository_manager = RepositoryManager(self.env)
        self.inject_dummy_repository()

    def test_can_index_added_changeset(self):
        rev = self.insert_changeset("Changed document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Changed document 1.", doc["message"])

    def test_can_index_modified_changeset(self):
        rev = self.insert_changeset("Changed document 1.")
        self.modify_changeset(rev, "Added document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Added document 1.", doc["message"])

    def insert_changeset(self, message, author=None, date=None, revision=None):
        rev = self.repository.add_changeset(revision, message, author, date)
        self.repository_manager.notify("changeset_added", 'dummy', [rev])
        return rev

    def modify_changeset(self, rev, message=None, author=None, date=None):
        changeset = self.repository.get_changeset(rev)
        if message is not None:
            changeset.message = message
        if author is not None:
            changeset.author = author
        if date is not None:
            changeset.date = date
        self.repository_manager.notify("changeset_modified", "dummy", [rev])

    def inject_dummy_repository(self):
        # pylint: disable=protected-access,attribute-defined-outside-init
        self.repository = DummyRepositry()
        self.repository_connector = DummyRepositoryConnector(self.env)
        self.repository_connector.repository = self.repository
        self.repository_manager._all_repositories = {
            'dummy': dict(dir='dirname', type='dummy')
        }
        self.repository_manager._connectors = {
            'dummy': (self.repository_connector, 100)
        }
Example #15
0
 def _get_source(self, formatter, source_obj, dest_format):
     repos_mgr = RepositoryManager(self.env)
     try:  #0.12+
         repos_name, repos, source_obj = repos_mgr.get_repository_by_path(
             source_obj)
     except AttributeError, e:  #0.11
         repos = repos_mgr.get_repository(formatter.req.authname)
Example #16
0
    def _format_link(self, formatter, ns, match, label, fullmatch=None):
        if ns == 'log1':
            groups = fullmatch.groupdict()
            it_log = groups.get('it_log')
            revs = groups.get('log_revs')
            path = groups.get('log_path') or '/'
            target = '%s%s@%s' % (it_log, path, revs)
            # prepending it_log is needed, as the helper expects it there
            intertrac = formatter.shorthand_intertrac_helper(
                'log', target, label, fullmatch)
            if intertrac:
                return intertrac
            path, query, fragment = formatter.split_link(path)
        else:
            assert ns in ('log', 'log2')
            if ns == 'log':
                match, query, fragment = formatter.split_link(match)
            else:
                query = fragment = ''
                match = ''.join(reversed(match.split('/', 1)))
            path = match
            revs = ''
            if self.LOG_LINK_RE.match(match):
                indexes = [sep in match and match.index(sep) for sep in ':@']
                idx = min([i for i in indexes if i is not False])
                path, revs = match[:idx], match[idx+1:]

        rm = RepositoryManager(self.env)
        try:
            reponame, repos, path = rm.get_repository_by_path(path)
            if not reponame:
                reponame = rm.get_default_repository(formatter.context)
                if reponame is not None:
                    repos = rm.get_repository(reponame)

            if repos:
                if 'LOG_VIEW' in formatter.perm:
                    reponame = repos.reponame or None
                    path = path or '/'
                    revranges = RevRanges(repos, revs)
                    if revranges.has_ranges():
                        href = formatter.href.log(reponame, path,
                                                  revs=unicode(revranges))
                    else:
                        # try to resolve if single rev
                        repos.normalize_rev(revs)
                        href = formatter.href.log(reponame, path,
                                                  rev=revs or None)
                    if query and '?' in href:
                        query = '&' + query[1:]
                    return tag.a(label, class_='source',
                                 href=href + query + fragment)
                errmsg = _("No permission to view change log")
            elif reponame:
                errmsg = _("Repository '%(repo)s' not found", repo=reponame)
            else:
                errmsg = _("No default repository defined")
        except TracError, e:
            errmsg = to_unicode(e)
Example #17
0
def _get_repository(env, req):
    '''From env and req identify and return (reponame, repository, path), 
    removing reponame from path in the process.
    '''
    path = req.args.get('path')
    repo_mgr = RepositoryManager(env)
    reponame, repos, path = repo_mgr.get_repository_by_path(path)
    return reponame, repos, path
Example #18
0
def _get_repository(env, req):
    '''From env and req identify and return (reponame, repository, path), 
    removing reponame from path in the process.
    '''
    path = req.args.get('path')
    repo_mgr = RepositoryManager(env)
    reponame, repos, path = repo_mgr.get_repository_by_path(path)
    return reponame, repos, path
Example #19
0
class ChangesetIndexerEventsTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ChangesetIndexerEventsTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.repository_manager = RepositoryManager(self.env)
        self.inject_dummy_repository()

    def test_can_index_added_changeset(self):
        rev = self.insert_changeset("Changed document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Changed document 1.", doc["message"])

    def test_can_index_modified_changeset(self):
        rev = self.insert_changeset("Changed document 1.")
        self.modify_changeset(rev, "Added document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Added document 1.", doc["message"])

    def insert_changeset(self, message, author=None, date=None, revision=None):
        rev = self.repository.add_changeset(revision, message, author, date)
        self.repository_manager.notify("changeset_added", 'dummy', [rev])
        return rev

    def modify_changeset(self, rev, message=None, author=None, date=None):
        changeset = self.repository.get_changeset(rev)
        if message is not None:
            changeset.message = message
        if author is not None:
            changeset.author = author
        if date is not None:
            changeset.date = date
        self.repository_manager.notify("changeset_modified", "dummy", [rev])

    def inject_dummy_repository(self):
        # pylint: disable=protected-access,attribute-defined-outside-init
        self.repository = DummyRepositry()
        self.repository_connector = DummyRepositoryConnector(self.env)
        self.repository_connector.repository = self.repository
        self.repository_manager._all_repositories = {
            'dummy': dict(dir='dirname', type='dummy')}
        self.repository_manager._connectors = {
            'dummy': (self.repository_connector, 100)}
Example #20
0
    def _render_repository_index(self, context, all_repositories, order, desc):
        # Color scale for the age column
        timerange = custom_colorizer = None
        if self.color_scale:
            custom_colorizer = self.get_custom_colorizer()

        rm = RepositoryManager(self.env)
        repositories = []
        for reponame, repoinfo in all_repositories.iteritems():
            if not reponame or as_bool(repoinfo.get('hidden')):
                continue
            try:
                repos = rm.get_repository(reponame)
            except TracError as err:
                entry = (reponame, repoinfo, None, None,
                         exception_to_unicode(err), None)
            else:
                if repos:
                    if not repos.is_viewable(context.perm):
                        continue
                    try:
                        youngest = repos.get_changeset(repos.youngest_rev)
                    except NoSuchChangeset:
                        youngest = None
                    if self.color_scale and youngest:
                        if not timerange:
                            timerange = TimeRange(youngest.date)
                        else:
                            timerange.insert(youngest.date)
                    raw_href = self._get_download_href(context.href, repos,
                                                       None, None)
                    entry = (reponame, repoinfo, repos, youngest, None,
                             raw_href)
                else:
                    entry = (reponame, repoinfo, None, None, u"\u2013", None)
            if entry[4] is not None:  # Check permission in case of error
                root = Resource('repository', reponame).child('source', '/')
                if 'BROWSER_VIEW' not in context.perm(root):
                    continue
            repositories.append(entry)

        # Ordering of repositories
        if order == 'date':
            def repo_order((reponame, repoinfo, repos, youngest, err, href)):
                return (youngest.date if youngest else to_datetime(0),
                        embedded_numbers(reponame.lower()))
        elif order == 'author':
            def repo_order((reponame, repoinfo, repos, youngest, err, href)):
                return (youngest.author.lower() if youngest else '',
                        embedded_numbers(reponame.lower()))
        else:
            def repo_order((reponame, repoinfo, repos, youngest, err, href)):
                return embedded_numbers(reponame.lower())

        repositories = sorted(repositories, key=repo_order, reverse=desc)

        return {'repositories' : repositories,
                'timerange': timerange, 'colorize_age': custom_colorizer}
Example #21
0
 def _get_source(self, formatter, source_obj, dest_format, start, end, lineno):
     repos_mgr = RepositoryManager(self.env)
     repos_name, repos, source_obj = \
         repos_mgr.get_repository_by_path(source_obj)
     path, rev = _split_path(source_obj)
     try:
         node = repos.get_node(path, rev)
     except (NoSuchChangeset, NoSuchNode), e:
         return system_message(e), None, None, None
Example #22
0
    def _render_repository_index(self, context, all_repositories, order, desc):
        # Color scale for the age column
        timerange = custom_colorizer = None
        if self.color_scale:
            custom_colorizer = self.get_custom_colorizer()

        rm = RepositoryManager(self.env)
        repositories = []
        for reponame, repoinfo in all_repositories.iteritems():
            if not reponame or as_bool(repoinfo.get("hidden")):
                continue
            try:
                repos = rm.get_repository(reponame)
            except TracError as err:
                entry = (reponame, repoinfo, None, None, exception_to_unicode(err), None)
            else:
                if repos:
                    if not repos.is_viewable(context.perm):
                        continue
                    try:
                        youngest = repos.get_changeset(repos.youngest_rev)
                    except NoSuchChangeset:
                        youngest = None
                    if self.color_scale and youngest:
                        if not timerange:
                            timerange = TimeRange(youngest.date)
                        else:
                            timerange.insert(youngest.date)
                    raw_href = self._get_download_href(context.href, repos, None, None)
                    entry = (reponame, repoinfo, repos, youngest, None, raw_href)
                else:
                    entry = (reponame, repoinfo, None, None, u"\u2013", None)
            if entry[4] is not None:  # Check permission in case of error
                root = Resource("repository", reponame).child(self.realm, "/")
                if "BROWSER_VIEW" not in context.perm(root):
                    continue
            repositories.append(entry)

        # Ordering of repositories
        if order == "date":

            def repo_order((reponame, repoinfo, repos, youngest, err, href)):
                return (youngest.date if youngest else to_datetime(0), embedded_numbers(reponame.lower()))

        elif order == "author":

            def repo_order((reponame, repoinfo, repos, youngest, err, href)):
                return (youngest.author.lower() if youngest else "", embedded_numbers(reponame.lower()))

        else:

            def repo_order((reponame, repoinfo, repos, youngest, err, href)):
                return embedded_numbers(reponame.lower())

        repositories = sorted(repositories, key=repo_order, reverse=desc)

        return {"repositories": repositories, "timerange": timerange, "colorize_age": custom_colorizer}
Example #23
0
    def process_request(self, req):
        req.perm.require('BROWSER_VIEW')

        presel = req.args.get('preselected')
        if presel and (presel + '/').startswith(req.href.browser() + '/'):
            req.redirect(presel)

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

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

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

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

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

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

            context = context(
                repos.resource.child('source', path, version=rev_or_latest))
            display_rev = repos.display_rev
Example #24
0
    def check_permission(self, action, username, resource, perm):
        realm = resource.realm if resource else None
        if (realm, action) in self._handled_perms:
            authz, users = self._get_authz_info()
            if authz is None:
                return False

            if username == 'anonymous':
                usernames = ('$anonymous', '*')
            else:
                usernames = (username, '$authenticated', '*')
            if resource is None:
                return True if users & set(usernames) else None

            rm = RepositoryManager(self.env)
            try:
                repos = rm.get_repository(resource.parent.id)
            except TracError:
                return True  # Allow error to be displayed in the repo index
            if repos is None:
                return True
            modules = [resource.parent.id or self.authz_module_name]
            if modules[0]:
                modules.append('')

            def check_path(path):
                path = '/' + join(repos.scope, path)
                if path != '/':
                    path += '/'

                # Allow access to parent directories of allowed resources
                if any(
                        section.get(user) is True
                        for module in modules for spath, section in authz.get(
                            module, {}).iteritems() if spath.startswith(path)
                        for user in usernames):
                    return True

                # Walk from resource up parent directories
                for spath in parent_iter(path):
                    for module in modules:
                        section = authz.get(module, {}).get(spath)
                        if section:
                            for user in usernames:
                                result = section.get(user)
                                if result is not None:
                                    return result

            if realm == 'source':
                return check_path(resource.id)

            elif realm == 'changeset':
                changes = list(repos.get_changeset(resource.id).get_changes())
                if not changes or any(
                        check_path(change[0]) for change in changes):
                    return True
Example #25
0
File: log.py Project: pkdevbox/trac
    def _format_link(self, formatter, ns, match, label, fullmatch=None):
        if ns == "log1":
            groups = fullmatch.groupdict()
            it_log = groups.get("it_log")
            revs = groups.get("log_revs")
            path = groups.get("log_path") or "/"
            target = "%s%s@%s" % (it_log, path, revs)
            # prepending it_log is needed, as the helper expects it there
            intertrac = formatter.shorthand_intertrac_helper("log", target, label, fullmatch)
            if intertrac:
                return intertrac
            path, query, fragment = formatter.split_link(path)
        else:
            assert ns in ("log", "log2")
            if ns == "log":
                match, query, fragment = formatter.split_link(match)
            else:
                query = fragment = ""
                match = "".join(reversed(match.split("/", 1)))
            path = match
            revs = ""
            if self.LOG_LINK_RE.match(match):
                indexes = [sep in match and match.index(sep) for sep in ":@"]
                idx = min([i for i in indexes if i is not False])
                path, revs = match[:idx], match[idx + 1 :]

        rm = RepositoryManager(self.env)
        try:
            reponame, repos, path = rm.get_repository_by_path(path)
            if not reponame:
                reponame = rm.get_default_repository(formatter.context)
                if reponame is not None:
                    repos = rm.get_repository(reponame)

            if repos:
                if "LOG_VIEW" in formatter.perm:
                    reponame = repos.reponame or None
                    path = path or "/"
                    revranges = RevRanges(repos, revs)
                    if revranges.has_ranges():
                        href = formatter.href.log(reponame, path, revs=unicode(revranges))
                    else:
                        # try to resolve if single rev
                        repos.normalize_rev(revs)
                        href = formatter.href.log(reponame, path, rev=revs or None)
                    if query and "?" in href:
                        query = "&" + query[1:]
                    return tag.a(label, class_="source", href=href + query + fragment)
                errmsg = _("No permission to view change log")
            elif reponame:
                errmsg = _("Repository '%(repo)s' not found", repo=reponame)
            else:
                errmsg = _("No default repository defined")
        except TracError as e:
            errmsg = to_unicode(e)
        return tag.a(label, class_="missing source", title=errmsg)
Example #26
0
    def check_permission(self, action, username, resource, perm):
        realm = resource.realm if resource else None
        if (realm, action) in self._handled_perms:
            authz, users = self._get_authz_info()
            if authz is None:
                return False

            if username == 'anonymous':
                usernames = ('$anonymous', '*')
            else:
                usernames = (username, '$authenticated', '*')
            if resource is None:
                return True if users & set(usernames) else None

            rm = RepositoryManager(self.env)
            try:
                repos = rm.get_repository(resource.parent.id)
            except TracError:
                return True # Allow error to be displayed in the repo index
            if repos is None:
                return True
            modules = [resource.parent.id or self.authz_module_name]
            if modules[0]:
                modules.append('')

            def check_path(path):
                path = '/' + join(repos.scope, path)
                if path != '/':
                    path += '/'

                # Allow access to parent directories of allowed resources
                if any(section.get(user) is True
                       for module in modules
                       for spath, section in authz.get(module, {}).iteritems()
                       if spath.startswith(path)
                       for user in usernames):
                    return True

                # Walk from resource up parent directories
                for spath in parent_iter(path):
                    for module in modules:
                        section = authz.get(module, {}).get(spath)
                        if section:
                            for user in usernames:
                                result = section.get(user)
                                if result is not None:
                                    return result

            if realm == 'source':
                return check_path(resource.id)

            elif realm == 'changeset':
                changes = list(repos.get_changeset(resource.id).get_changes())
                if not changes or any(check_path(change[0])
                                      for change in changes):
                    return True
Example #27
0
    def get_psf(self):
        """ parse attached "team project set" for Eclipse IDE
            returns a-list as [ Eclipse project name -> repository URL ] """
        if self._psf is None:
            self._psf = {}
            psfResource = Resource('wiki', 'TeamProjectSet').child(
                'attachment', 'projectSet.psf')
            if (self.compmgr[AttachmentModule].resource_exists(psfResource)):
                psf = Attachment(self.env, psfResource)

                def startElement(name, attrs):
                    if name == 'project':
                        attr = attrs.get('reference', "").split(',')
                        self._psf[attr[2]] = urlparse(
                            attr[1]).path  # trim leading scheme/port

                reader = expat.ParserCreate()
                reader.StartElementHandler = startElement
                reader.ParseFile(psf.open())
                # specify checkout dir in server subversion directory
                rm = RepositoryManager(self.env)
                repos = rm.get_all_repositories()
                for projectname in self._psf.keys():
                    path = self._psf.get(projectname) + '/.project'
                    for reponame in repos:
                        repo = rm.get_repository(reponame)
                        if not repo:
                            continue
                        for npath in self.iter_lstrip(path):
                            if not repo.has_node(npath, None):
                                continue
                            self._psf[projectname] = npath[:-9]

                            # search .classpath here
                            npath = npath[:-9] + '/.classpath'
                            if not repo.has_node(npath, None):
                                continue
                            node = repo.get_node(npath, None)
                            srcpathes = self.parse_classpath(
                                node.get_content())
                            self._srcpathes[repo.reponame] = map(
                                lambda x: npath[:-10] + x, srcpathes)
            else:  # TeamProjectSet not found
                for repo in self.config.getlist('wiki', 'source_path',
                                                sep=';'):
                    # expected: "svn: trunk/theproject/src/main/java trunk/theproject/src/test/java;"
                    repo = repo.split(':')
                    repo, srcpaths = len(repo) < 2 and (
                        "", repo[0]
                    ) or repo  # no leading reponame, use default repo
                    self._srcpathes[repo] = self._srcpathes.get(repo, [])
                    self._srcpathes[repo].extend([
                        s.rstrip('/') + '/' for s in srcpaths.split(' ') if s
                    ])
        return self._psf  # { project_name: repository_url, ... }
Example #28
0
    def process_request(self, req):
        req.perm.require('BROWSER_VIEW')

        presel = req.args.get('preselected')
        if presel and (presel + '/').startswith(req.href.browser() + '/'):
            req.redirect(presel)

        path = req.args.get('path', '/')
        rev = req.args.get('rev', '')
        if rev in ('', 'HEAD'):
            rev = None
        order = req.args.get('order', 'name').lower()
        desc = req.args.has_key('desc')
        xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest'
        
        rm = RepositoryManager(self.env)
        all_repositories = rm.get_all_repositories()
        reponame, repos, path = rm.get_repository_by_path(path)

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

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

        if reponame and reponame != repos.reponame: # Redirect alias
            qs = req.query_string
            req.redirect(req.href.browser(repos.reponame or None, path)
                         + (qs and '?' + qs or ''))
        reponame = repos and repos.reponame or None
        
        # Find node for the requested path/rev
        context = Context.from_request(req)
        node = None
        display_rev = lambda rev: rev
        if repos:
            try:
                if rev:
                    rev = repos.normalize_rev(rev)
                # If `rev` is `None`, we'll try to reuse `None` consistently,
                # as a special shortcut to the latest revision.
                rev_or_latest = rev or repos.youngest_rev
                node = get_existing_node(req, repos, path, rev_or_latest)
            except NoSuchChangeset, e:
                raise ResourceNotFound(e.message,
                                       _('Invalid changeset number'))

            context = context(repos.resource.child('source', path,
                                                   version=rev_or_latest))
            display_rev = repos.display_rev
Example #29
0
 def get_entries_for_index(self):
     repository_manager = RepositoryManager(self.env)
     for repository in repository_manager.get_real_repositories():
         rev = repository.oldest_rev
         stop = repository.youngest_rev
         while True:
             changeset = repository.get_changeset(rev)
             yield self.build_doc(changeset)
             if rev == stop:
                 break
             rev = repository.next_rev(rev)
 def get_entries_for_index(self):
     repository_manager = RepositoryManager(self.env)
     for repository in repository_manager.get_real_repositories():
         rev = repository.oldest_rev
         stop = repository.youngest_rev
         while True:
             changeset = repository.get_changeset(rev)
             yield ChangesetIndexer(self.env).build_doc(changeset)
             if rev == stop:
                 break
             rev = repository.next_rev(rev)
Example #31
0
    def expand_macro(self, formatter, name, args):
        path = unicode(args)

        rm = RepositoryManager(self.env)

        for repo_name in rm.get_all_repositories():
            repo = rm.get_repository(repo_name)

            if repo.has_node(path):
                return self.get_javadoc(repo, repo_name, path)
        return "No file found for %s" % (path)
Example #32
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content)
        format = kwargs.get('format', 'compact')
        glob = kwargs.get('glob', '*')
        order = kwargs.get('order')
        desc = as_bool(kwargs.get('desc', 0))

        rm = RepositoryManager(self.env)
        all_repos = dict(rdata for rdata in rm.get_all_repositories().items()
                         if fnmatchcase(rdata[0], glob))

        if format == 'table':
            repo = self._render_repository_index(formatter.context, all_repos,
                                                 order, desc)

            add_stylesheet(formatter.req, 'common/css/browser.css')
            wiki_format_messages = self.config['changeset'] \
                                       .getbool('wiki_format_messages')
            data = {'repo': repo, 'order': order, 'desc': 1 if desc else None,
                    'reponame': None, 'path': '/', 'stickyrev': None,
                    'wiki_format_messages': wiki_format_messages}
            from trac.web.chrome import Chrome
            return Chrome(self.env).render_template(
                    formatter.req, 'repository_index.html', data, None,
                    fragment=True)

        def get_repository(reponame):
            try:
                return rm.get_repository(reponame)
            except TracError:
                return

        all_repos = [(reponame, get_repository(reponame))
                     for reponame in all_repos]
        all_repos = sorted(((reponame, repos) for reponame, repos in all_repos
                            if repos
                            and not as_bool(repos.params.get('hidden'))
                            and repos.is_viewable(formatter.perm)),
                           reverse=desc)

        def repolink(reponame, repos):
            label = reponame or _('(default)')
            return Markup(tag.a(label,
                          title=_('View repository %(repo)s', repo=label),
                          href=formatter.href.browser(repos.reponame or None)))

        if format == 'list':
            return tag.dl([
                tag(tag.dt(repolink(reponame, repos)),
                    tag.dd(repos.params.get('description')))
                for reponame, repos in all_repos])
        else: # compact
            return Markup(', ').join([repolink(reponame, repos)
                                      for reponame, repos in all_repos])
Example #33
0
    def process_request(self, req):
        if req.method != 'POST':
            msg = u'Method not allowed (%s)\n' % req.method
            self.log.warning(msg.rstrip('\n'))
            req.send(msg.encode('utf-8'), 'text/plain', 405)

        path = req.args['path']

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

        if path != '/':
            msg = u'No such repository (%s)\n' % path
            self.log.warning(msg.rstrip('\n'))
            req.send(msg.encode('utf-8'), 'text/plain', 400)

        output = u'Running hook on %s\n' % (reponame or '(default)')

        output += u'* Updating clone\n'
        repos.git.repo.remote('update', '--prune')
        output += u'* Synchronizing with clone\n'
        repos.git.sync()

        try:
            payload = json.loads(req.args['payload'])
            revs = [
                commit['id'] for commit in payload['commits']
                if commit['distinct']
            ]
        except (ValueError, KeyError):
            msg = u'Invalid payload\n'
            self.log.warning(msg.rstrip('\n'))
            req.send(msg.encode('utf-8'), 'text/plain', 400)

        branches = self.get_branches(reponame)
        added, skipped, unknown = classify_commits(revs, repos, branches)

        if added:
            output += u'* Adding %s\n' % describe_commits(added)
            # This is where Trac gets notified of the commits in the changeset
            rm.notify('changeset_added', reponame, added)

        if skipped:
            output += u'* Skipping %s\n' % describe_commits(skipped)

        if unknown:
            output += u'* Unknown %s\n' % describe_commits(unknown)
            self.log.error(u'Payload contains unknown %s',
                           describe_commits(unknown))

        for line in output.splitlines():
            self.log.debug(line)

        req.send(output.encode('utf-8'), 'text/plain', 200 if output else 204)
Example #34
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content)
        format = kwargs.get('format', 'compact')
        glob = kwargs.get('glob', '*')
        order = kwargs.get('order')
        desc = as_bool(kwargs.get('desc', 0))

        rm = RepositoryManager(self.env)
        all_repos = dict(rdata for rdata in rm.get_all_repositories().items()
                         if fnmatchcase(rdata[0], glob))

        if format == 'table':
            repo = self._render_repository_index(formatter.context, all_repos,
                                                 order, desc)

            add_stylesheet(formatter.req, 'common/css/browser.css')
            wiki_format_messages = self.config['changeset'] \
                                       .getbool('wiki_format_messages')
            data = {'repo': repo, 'order': order, 'desc': desc and 1 or None,
                    'reponame': None, 'path': '/', 'stickyrev': None,
                    'wiki_format_messages': wiki_format_messages}
            from trac.web.chrome import Chrome
            return Chrome(self.env).render_template(
                    formatter.req, 'repository_index.html', data, None,
                    fragment=True)

        def get_repository(reponame):
            try:
                return rm.get_repository(reponame)
            except TracError:
                return

        all_repos = [(reponame, get_repository(reponame))
                     for reponame in all_repos]
        all_repos = sorted(((reponame, repos) for reponame, repos in all_repos
                            if repos
                            and not as_bool(repos.params.get('hidden'))
                            and repos.can_view(formatter.perm)),
                           reverse=desc)

        def repolink(reponame, repos):
            label = reponame or _('(default)')
            return Markup(tag.a(label, 
                          title=_('View repository %(repo)s', repo=label),
                          href=formatter.href.browser(repos.reponame or None)))

        if format == 'list':
            return tag.dl([
                tag(tag.dt(repolink(reponame, repos)),
                    tag.dd(repos.params.get('description')))
                for reponame, repos in all_repos])
        else: # compact
            return Markup(', ').join([repolink(reponame, repos)
                                      for reponame, repos in all_repos])
Example #35
0
 def _get_link_info(self, path, rev, href, perm):
     rm = RepositoryManager(self.env)
     node = raw_href = title = None
     try:
         reponame, repos, npath = rm.get_repository_by_path(path)
         node = get_allowed_node(repos, npath, rev, perm)
         if node is not None:
             raw_href = self._get_download_href(href, repos, node, rev)
             title = _("Download") if node.isfile else _("Download as Zip archive")
     except TracError:
         pass
     return (node, raw_href, title)
Example #36
0
 def _get_source(self, formatter, source_obj, dest_format):
     repos_mgr = RepositoryManager(self.env)
     try:  # 0.12+
         repos_name, repos, source_obj = \
             repos_mgr.get_repository_by_path(source_obj)
     except AttributeError:  # 0.11
         repos = repos_mgr.get_repository(formatter.req.authname)
     path, rev = _split_path(source_obj)
     try:
         node = repos.get_node(path, rev)
     except (NoSuchChangeset, NoSuchNode), e:
         return system_message(e), None, None
Example #37
0
    def process_request(self, req):
        rev = req.args.get("rev")
        path = req.args.get("path")

        rm = RepositoryManager(self.env)
        reponame, repos, path = rm.get_repository_by_path(path)
        gh_repo = self.get_gh_repo(reponame)

        try:
            rev = repos.normalize_rev(rev)
        except NoSuchChangeset, e:
            raise ResourceNotFound(e.message, _("Invalid Changeset Number"))
Example #38
0
    def process_request(self, req):
        if req.method != 'POST':
            msg = u'Method not allowed (%s)\n' % req.method
            self.log.warning(msg.rstrip('\n'))
            req.send(msg.encode('utf-8'), 'text/plain', 405)

        path = req.args['path']

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

        if path != '/':
            msg = u'No such repository (%s)\n' % path
            self.log.warning(msg.rstrip('\n'))
            req.send(msg.encode('utf-8'), 'text/plain', 400)

        output = u'Running hook on %s\n' % (reponame or '(default)')

        output += u'* Updating clone\n'
        repos.git.repo.remote('update', '--prune')
        output += u'* Synchronizing with clone\n'
        repos.git.sync()

        try:
            payload = json.loads(req.args['payload'])
            revs = [commit['id']
                    for commit in payload['commits'] if commit['distinct']]
        except (ValueError, KeyError):
            msg = u'Invalid payload\n'
            self.log.warning(msg.rstrip('\n'))
            req.send(msg.encode('utf-8'), 'text/plain', 400)

        branches = self.get_branches(reponame)
        added, skipped, unknown = classify_commits(revs, repos, branches)

        if added:
            output += u'* Adding %s\n' % describe_commits(added)
            # This is where Trac gets notified of the commits in the changeset
            rm.notify('changeset_added', reponame, added)

        if skipped:
            output += u'* Skipping %s\n' % describe_commits(skipped)

        if unknown:
            output += u'* Unknown %s\n' % describe_commits(unknown)
            self.log.error(u'Payload contains unknown %s',
                    describe_commits(unknown))

        for line in output.splitlines():
            self.log.debug(line)

        req.send(output.encode('utf-8'), 'text/plain', 200 if output else 204)
Example #39
0
    def _suggest_source(self, req, term):
        def suggest_revs(repos, node, search_rev):
            if search_rev:
                for category, names, path, rev in repos.get_quickjump_entries(
                        None):
                    if path and path != '/':
                        # skip jumps to other paths
                        # (like SVN's 'trunk', 'branches/...', 'tags/...' folders)
                        continue
                    # Multiple Mercurial tags on same revision are comma-separated:
                    for name in names.split(', '):
                        if ' ' in name:
                            # use first token, e.g. '1.0' from '1.0 (tip)'
                            name = name.split(' ', 1)[0]
                        if name.startswith(search_rev):
                            yield name
            for r in node.get_history(10):
                rev = repos.short_rev(r[1])
                if str(rev).startswith(search_rev):
                    yield rev

        rm = RepositoryManager(self.env)
        if term.find('/') == -1 and term.find('@') == -1:
            lower_term = term.lower()
            completions = sorted(
                reponame + '/' for reponame in rm.get_all_repositories()
                if reponame.lower().startswith(lower_term)
                and 'BROWSER_VIEW' in req.perm('repository', reponame))
        else:
            pos = term.find('/')
            if pos == -1:
                pos = term.find('@')
            reponame, path = term[:pos], term[pos:]
            repos = rm.get_repository(reponame)
            completions = []
            if repos is not None:
                if path.find('@') != -1:
                    path, search_rev = path.rsplit('@', 1)
                    node = repos.get_node(path, repos.youngest_rev)
                    if node.can_view(req.perm):
                        completions.extend(
                            '%s%s@%s' % (reponame, path, rev)
                            for rev in suggest_revs(repos, node, search_rev))
                else:
                    dir, filename = path.rsplit('/', 1)
                    node = repos.get_node(dir or '/', repos.youngest_rev)
                    completions = sorted(
                        '%s/%s%s' %
                        (reponame, n.path.lstrip('/'), '/' if n.isdir else '')
                        for n in node.get_entries() if
                        n.name.startswith(filename) and n.can_view(req.perm))
        return completions
Example #40
0
    def test_pre_process_request_sync_skipped_for_invalid_connector(self):
        """Repository synchronization is skipped for an invalid connector."""
        self.env.config.set('repositories', 'repos.dir', '/some/path')
        self.env.config.set('repositories', 'repos.type', 'invalid')
        self.env.config.set('repositories', 'repos.sync_per_request', True)
        req = MockRequest(self.env)
        handler = Mock()
        repos_manager = RepositoryManager(self.env)

        repos_manager.pre_process_request(req, handler)

        self.assertNotIn('invalid', repos_manager.get_supported_types())
        self.assertEqual([], req.chrome['warnings'])
Example #41
0
    def process_request(self, req):
        if not self.gh_repo:
            return super(GitHubBrowser, self).process_request(req)

        rev = req.args.get('rev')
        path = req.args.get('path')
        rm = RepositoryManager(self.env)
        reponame, repos, path = rm.get_repository_by_path(path)

        try:
            rev = repos.normalize_rev(rev)
        except NoSuchChangeset, e:
            raise ResourceNotFound(e.message, _('Invalid Changeset Number'))
Example #42
0
 def _get_link_info(self, path, rev, href, perm):
     rm = RepositoryManager(self.env)
     node = raw_href = title = None
     try:
         reponame, repos, npath = rm.get_repository_by_path(path)
         node = get_allowed_node(repos, npath, rev, perm)
         if node is not None:
             raw_href = self._get_download_href(href, repos, node, rev)
             title = _("Download") if node.isfile \
                     else _("Download as Zip archive")
     except TracError:
         pass
     return node, raw_href, title
Example #43
0
 def __init__(self, env, context):
     self.env = env
     self.context = context
     rm = RepositoryManager(self.env)
     self.repos = rm.get_repository(context.resource.parent.id)
     self.path = context.resource.id
     self.rev = context.resource.version
     # maintain state
     self.prev_chgset = None
     self.chgset_data = {}
     add_script(context.req, 'common/js/blame.js')
     add_stylesheet(context.req, 'common/css/changeset.css')
     add_stylesheet(context.req, 'common/css/diff.css')
     self.reset()
Example #44
0
    def get_revtree(self, repos, req):
        rm = RepositoryManager(self.env)
        reps = rm.get_all_repositories()
        for repo in reps:
            rtype = reps[repo].get('type', None) or rm.default_repository_type
            if rtype == 'svn':
                break
        else:
            raise TracError("Revtree only supports Subversion repositories")

        self.env.log.debug("Enhancers: %s" % self.enhancers)

        return SvgRevtree(self.env, repos, req.href(),
                          self.enhancers, self.optimizer)
Example #45
0
    def register_repository(self, repository, name=None):
        """Register a repository with trac"""

        project = repository.project
        tracname = name if name is not None else repository.name

        if repository.name in project.data.get('plugins',
                                               {}).get('trac', {}).get(
                                                   repository.type, {}):
            logger.error(
                "Repository %s:%s is already registered in project %s",
                repository.type, repository.name, project.name)
            return False

        if repository.type not in self.typemap:
            logger.error("Repository type %s is not supported in Trac",
                         repository.type)
            return False

        if not self.has_env(project):
            logger.warning(
                "Tried to add repository %s:%s to Trac of project %s, but there is no environment",
                repository.type, repository.name, project.name)
            return False

        try:
            env = Environment(self.get_env_path(project))

            DbRepositoryProvider(env).add_repository(
                tracname, repository.path, self.typemap[repository.type])

            # save mapping in project
            project.data.setdefault('plugins',
                                    {}).setdefault('trac', {}).setdefault(
                                        repository.type,
                                        {})[repository.name] = tracname
            project.save()

            # Synchronise repository
            rm = RepositoryManager(env)
            repos = rm.get_repository(tracname)
            repos.sync(lambda rev: logger.debug("Synced revision: %s", rev),
                       clean=True)

            return True
        except Exception as e:
            logger.exception(
                "Exception occured while addingrepository %s:%s to Trac of project %s",
                repository.type, repository.name, project.name)
            return False
Example #46
0
 def __init__(self, env, context):
     self.env = env
     self.context = context
     rm = RepositoryManager(self.env)
     self.repos = rm.get_repository(context.resource.parent.id)
     self.path = context.resource.id
     self.rev = context.resource.version
     # maintain state
     self.prev_chgset = None
     self.chgset_data = {}
     add_script(context.req, 'common/js/blame.js')
     add_stylesheet(context.req, 'common/css/changeset.css')
     add_stylesheet(context.req, 'common/css/diff.css')
     self.reset()
Example #47
0
    def process_request(self, req):
        if req.method != "POST":
            msg = u"Method not allowed (%s)\n" % req.method
            self.log.warning(msg.rstrip("\n"))
            req.send(msg.encode("utf-8"), "text/plain", 405)

        path = req.args["path"]

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

        if path != "/":
            msg = u"No such repository (%s)\n" % path
            self.log.warning(msg.rstrip("\n"))
            req.send(msg.encode("utf-8"), "text/plain", 400)

        output = u"Running hook on %s\n" % (reponame or "(default)")

        output += u"* Updating clone\n"
        output += repos.git.repo.remote("update", "--prune")

        try:
            payload = json.loads(req.args["payload"])
            revs = [commit["id"] for commit in payload["commits"] if commit["distinct"]]
        except (ValueError, KeyError):
            msg = u"Invalid payload\n"
            self.log.warning(msg.rstrip("\n"))
            req.send(msg.encode("utf-8"), "text/plain", 400)

        branches = self.get_branches(reponame)
        added_revs, skipped_revs = [], []
        for rev in revs:
            if rev_in_branches(repos.get_changeset(rev), branches):
                added_revs.append(rev)
            else:
                skipped_revs.append(rev)

        if added_revs:
            output += u"* Adding %s\n" % describe_commits(added_revs)
            # This is where Trac gets notified of the commits in the changeset
            rm.notify("changeset_added", reponame, added_revs)

        if skipped_revs:
            output += u"* Skipping %s\n" % describe_commits(skipped_revs)

        for line in output.splitlines():
            self.log.debug(line)

        req.send(output.encode("utf-8"), "text/plain", 200 if output else 204)
Example #48
0
 def _format_revision_link(self, formatter, ns, reponame, rev, label,
                           fullmatch=None):
     rev, params, fragment = formatter.split_link(rev)
     try:
         repos = RepositoryManager(self.env).get_repository(reponame)
         if repos:
             changeset = repos.get_changeset(rev)
             return tag.a(label, class_="changeset",
                          title=shorten_line(changeset.message),
                          href=(formatter.href.changeset(rev) +
                                params + fragment))
     except NoSuchChangeset:
         pass
     return tag.a(label, class_="missing changeset", rel="nofollow",
                  href=formatter.href.changeset(rev))
Example #49
0
 def _format_revision_link(self, formatter, ns, reponame, rev, label,
                           fullmatch=None):
     rev, params, fragment = formatter.split_link(rev)
     try:
         repos = RepositoryManager(self.env).get_repository(reponame)
         if repos:
             changeset = repos.get_changeset(rev)
             return tag.a(label, class_="changeset",
                          title=shorten_line(changeset.message),
                          href=(formatter.href.changeset(rev) +
                                params + fragment))
     except NoSuchChangeset:
         pass
     return tag.a(label, class_="missing changeset", rel="nofollow",
                  href=formatter.href.changeset(rev))
Example #50
0
def do_upgrade(env, version, cursor):
    """Replace list of repositories in [trac] repository_sync_per_request
    with boolean values [repositories] <repos>.sync_per_request and a list
    of repositories in [gitweb-repositories] sync_per_request. Move and
    rename the Gitweb configuration options from the [git] section to
    the [gitweb-repositories] section.
    """
    backup_config_file(env, '.db32.bak')
    repos_sync_per_request = \
        env.config.getlist('trac', 'repository_sync_per_request', '(default)')

    for suffix in ('base', 'list', 'url'):
        option_name = 'projects_' + suffix
        env.config.set('gitweb-repositories', option_name,
                       env.config.get('git', option_name))
        env.config.remove('git', option_name)
        env.log.info("Moved [git] %s -> [gitweb-repositories] %s", option_name,
                     option_name)

    rm = RepositoryManager(env)
    if repos_sync_per_request:
        for name, _ in rm.get_repositories():
            sync_per_request = (name or '(default)') in repos_sync_per_request
            if sync_per_request:
                env.config.set('repositories', name + '.sync_per_request',
                               'true')
                env.log.info("Enabled sync_per_request for %s", name)

        gwrp = GitwebProjectsRepositoryProvider(env)
        gitweb_repo_names = [name for name, _ in gwrp.get_repositories()]
        sync_per_request = \
            ', '.join(set(gitweb_repo_names) & set(repos_sync_per_request))
        env.config.set('gitweb-repositories', 'sync_per_request',
                       sync_per_request)
        env.log.info("Enabled sync_per_request for %s", sync_per_request)

        db_provider = DbRepositoryProvider(env)
        for name, _ in db_provider.get_repositories():
            sync_per_request = (name or '(default)') in repos_sync_per_request
            changes = {'sync_per_request': sync_per_request}
            db_provider.modify_repository(name, changes)
            if sync_per_request:
                env.log.info("Enabled sync_per_request for %s", name)

    env.config.remove('trac', 'repository_sync_per_request')
    env.log.info("Removed [trac] repository_sync_per_request option")
    env.config.save()
    rm.reload_repositories()
Example #51
0
 def setUp(self):
     super(ChangesetIndexerEventsTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.repository_manager = RepositoryManager(self.env)
     self.inject_dummy_repository()
Example #52
0
File: env.py Project: hanotch/trac
 def shutdown(self, tid=None):
     """Close the environment."""
     from trac.versioncontrol.api import RepositoryManager
     RepositoryManager(self).shutdown(tid)
     DatabaseManager(self).shutdown(tid)
     if tid is None:
         log.shutdown(self.log)
Example #53
0
    def process_request(self, req):
        if not self.repository:                             # pragma: no cover
            return super(GitHubBrowser, self).process_request(req)

        rev = req.args.get('rev')
        path = req.args.get('path')

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

        key = 'repository' if is_default(reponame) else '%s.repository' % reponame
        gh_repo = self.config.get('github', key)

        try:
            rev = repos.normalize_rev(rev)
        except NoSuchChangeset, e:
            raise ResourceNotFound(e.message, _('Invalid Changeset Number'))
Example #54
0
 def get_timeline_events(self, req, start, stop, filters):
     rm = RepositoryManager(self.env)
     events = super(GitHubBrowser, self).get_timeline_events(req, start, stop, filters)
     for event in events:
         if event[0] != 'changeset':
             yield event
             continue
         allow = True
         for changeset in event[3][0]:
             reponame = changeset[2][0]
             repos = rm.get_repository(reponame)
             key = 'branches' if is_default(reponame) else '%s.branches' % reponame
             branches = self.config.getlist('github', key, sep=' ')
             if branches:
                 allow = allow and allow_revision(changeset[0].rev, repos, branches)
         if allow:
             yield event
Example #55
0
    def process_request(self, req):
        rev = req.args.get('rev')
        path = req.args.get('path')

        rm = RepositoryManager(self.env)
        reponame, repos, path = rm.get_repository_by_path(path)
        gh_repo = self.get_gh_repo(reponame)

        rev = repos.normalize_rev(rev)

        if path and path != '/':
            path = path.lstrip('/')
            # GitHub will s/blob/tree/ if the path is a directory
            url = 'https://github.com/%s/blob/%s/%s' % (gh_repo, rev, path)
        else:
            url = 'https://github.com/%s/commit/%s' % (gh_repo, rev)
        req.redirect(url)
Example #56
0
    def help(self, req):

        rm = RepositoryManager(self.env)
        all_repositories = rm.get_all_repositories()
        page = _('= Repositories =') + '\n'

        for reponame, repoinfo in all_repositories.iteritems():
          path = '%s/dav/%s' % (req.base_path, reponame)
          url = '%s://%s@%s:%s%s' % (req.scheme, req.remote_user, req.server_name, req.server_port, path)
          url = urlparse.urlparse(url)
          self.log.info('repo %r', repoinfo)
          page += ' == %s == \r\n {{{\n %s %s \n}}}\n\n' % (reponame, self.helper_vcs(repoinfo['type']), url.geturl())

        data = {
            'proxydav_title': _('Repo access'), 
            'proxydav_page': self.format_to_html(req, page)
        }
        return 'proxydav.html', data, None
Example #57
0
    def _format_sha_link(self, formatter, sha, label):
        # FIXME: this function needs serious rethinking...

        reponame = ''

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

        repos = RepositoryManager(self.env).get_all_repositories()

        for r in repos:
            try:
                testrepo = RepositoryManager(self.env).get_repository(r)
                testrepo.get_changeset(testrepo.normalize_rev(sha))
                reponame = testrepo.reponame
            except Exception, e:
                self.log.debug("%s not found in repo: %s" % (sha, r))
Example #58
0
    def register_repository(self, repository, name=None):
        """Register a repository with trac"""

        project = repository.project
        tracname = name if name is not None else repository.name

        if repository.name in project.data.get('plugins', {}).get('trac', {}).get(repository.type, {}):
            logger.error("Repository %s:%s is already registered in project %s",
                        repository.type, repository.name, project.name)
            return False

        if repository.type not in self.typemap:
            logger.error("Repository type %s is not supported in Trac", repository.type)
            return False

        if not self.has_env(project):
            logger.warning("Tried to add repository %s:%s to Trac of project %s, but there is no environment",
                        repository.type, repository.name, project.name)
            return False

        try:
            env = Environment(self.get_env_path(project))

            DbRepositoryProvider(env).add_repository(tracname, repository.path, self.typemap[repository.type])

            # save mapping in project
            project.data.setdefault('plugins', {}).setdefault('trac', {}).setdefault(repository.type, {})[repository.name] = tracname
            project.save()

            # Synchronise repository
            rm = RepositoryManager(env)
            repos = rm.get_repository(tracname)
            repos.sync(lambda rev: logger.debug("Synced revision: %s", rev), clean=True)

            return True
        except Exception as e:
            logger.exception("Exception occured while addingrepository %s:%s to Trac of project %s",
                        repository.type, repository.name, project.name)
            return False
Example #59
0
    def _render_repository_index(self, context, all_repositories, order, desc):
        # Color scale for the age column
        timerange = custom_colorizer = None
        if self.color_scale:
            custom_colorizer = self.get_custom_colorizer()

        rm = RepositoryManager(self.env)
        repositories = []
        for reponame, repoinfo in all_repositories.iteritems():
            if not reponame or as_bool(repoinfo.get('hidden')):
                continue
            try:
                repos = rm.get_repository(reponame)
                if repos:
                    if not repos.can_view(context.perm):
                        continue
                    try:
                        youngest = repos.get_changeset(repos.youngest_rev)
                    except NoSuchChangeset:
                        youngest = None
                    if self.color_scale and youngest:
                        if not timerange:
                            timerange = TimeRange(youngest.date)
                        else:
                            timerange.insert(youngest.date)
                    entry = (reponame, repoinfo, repos, youngest, None)
                else:
                    entry = (reponame, repoinfo, None, None, u"\u2013")
            except TracError, err:
                entry = (reponame, repoinfo, None, None,
                         exception_to_unicode(err))
            if entry[-1] is not None:   # Check permission in case of error
                root = Resource('repository', reponame).child('source', '/')
                if 'BROWSER_VIEW' not in context.perm(root):
                    continue
            repositories.append(entry)