Beispiel #1
0
class MergeRequestController(object):
    log_widget = SCMLogWidget(show_paging=False)
    thread_widget = w.Thread(page=None,
                             limit=None,
                             page_size=None,
                             count=None,
                             style='linear')
    mr_dispose_form = SCMMergeRequestDisposeWidget()

    def __init__(self, num):
        self.req = M.MergeRequest.query.get(app_config_id=c.app.config._id,
                                            request_number=int(num))
        if self.req is None: raise exc.HTTPNotFound

    @expose('jinja:allura:templates/repo/merge_request.html')
    def index(self, page=0, limit=250):
        c.thread = self.thread_widget
        c.log_widget = self.log_widget
        c.mr_dispose_form = self.mr_dispose_form
        with self.req.push_downstream_context():
            downstream_app = c.app
        return dict(downstream_app=downstream_app,
                    req=self.req,
                    page=page,
                    limit=limit,
                    count=self.req.discussion_thread.post_count)

    @expose()
    @require_post()
    @validate(mr_dispose_form)
    def save(self, status=None):
        security.require(security.has_access(self.req, 'write'),
                         'Write access required')
        self.req.status = status
        redirect('.')
Beispiel #2
0
    def commits_html(self, **kw):
        if self.req.new_commits is not None:
            with self.req.push_downstream_context():
                downstream_app = c.app
            return SCMLogWidget().display(value=self.req.commits, app=downstream_app)

        task_status = self.req.commits_task_status()
        if task_status is None:
            raise exc.HTTPNotFound
        elif task_status == 'error':
            raise exc.HTTPInternalServerError
        elif task_status in ('busy', 'ready'):
            raise exc.HTTPAccepted
class CommitBrowser(BaseController):
    TreeBrowserClass=None
    revision_widget = SCMRevisionWidget()
    log_widget=SCMLogWidget()

    def __init__(self, revision):
        self._revision = revision
        self._commit = c.app.repo.commit(revision)
        if self._commit is None:
            raise exc.HTTPNotFound
        self.tree = self.TreeBrowserClass(self._commit, tree=self._commit.tree)

    @expose('jinja:allura:templates/repo/commit.html')
    def index(self):
        c.revision_widget = self.revision_widget
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        result['artifacts'] = [(t,f) for t in ('added', 'removed', 'changed', 'copied')
                                     for f in self._commit.diffs[t]]
        return result

    @expose('jinja:allura:templates/repo/commit_basic.html')
    def basic(self):
        c.revision_widget = self.revision_widget
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        return result

    @expose('jinja:allura:templates/repo/log.html')
    @with_trailing_slash
    def log(self, limit=None, page=0, count=0, **kw):
        limit, page, start = g.handle_paging(limit, page)
        revisions = c.app.repo.log(
                branch=self._commit._id,
                offset=start,
                limit=limit)
        c.log_widget = self.log_widget
        count = 0
        return dict(
            username=c.user._id and c.user.username,
            branch=None,
            log=revisions,
            page=page,
            limit=limit,
            count=count,
            **kw)
Beispiel #4
0
class CommitBrowser(BaseController):
    TreeBrowserClass = None
    revision_widget = SCMRevisionWidget()
    log_widget = SCMLogWidget()
    page_list = ffw.PageList()
    DEFAULT_PAGE_LIMIT = 25

    def __init__(self, revision):
        self._revision = revision
        self._commit = c.app.repo.commit(revision)
        c.revision = revision
        if self._commit is None:
            raise exc.HTTPNotFound
        self.tree = self.TreeBrowserClass(self._commit, tree=self._commit.tree)

    @expose('jinja:allura:templates/repo/commit.html')
    @validate(dict(page=validators.Int(if_empty=0, if_invalid=0),
                   limit=validators.Int(if_empty=DEFAULT_PAGE_LIMIT, if_invalid=DEFAULT_PAGE_LIMIT)))
    def index(self, page=0, limit=DEFAULT_PAGE_LIMIT, **kw):
        c.revision_widget = self.revision_widget
        c.page_list = self.page_list
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        tree = self._commit.tree
        limit, page, start = g.handle_paging(limit, page,
                                             default=self.DEFAULT_PAGE_LIMIT)
        diffs = self._commit.paged_diffs(start=start, end=start + limit)
        result['artifacts'] = []
        for t in ('added', 'removed', 'changed', 'copied', 'renamed'):
            for f in diffs[t]:
                if t in ('copied', 'renamed'):
                    filepath = f['new']
                else:
                    filepath = f
                is_text = filepath and tree.get_blob_by_path(filepath) and tree.get_blob_by_path(filepath).has_html_view
                result['artifacts'].append(
                    (t, f, 'blob' if tree.get_blob_by_path(f) else 'tree', is_text)
                )
        count = diffs['total']
        result.update(dict(page=page, limit=limit, count=count))
        return result

    @expose('jinja:allura:templates/repo/commit_basic.html')
    def basic(self, **kw):
        c.revision_widget = self.revision_widget
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        return result

    @expose('jinja:allura:templates/repo/tarball.html')
    def tarball(self, **kw):
        path = request.params.get('path')
        if not asbool(tg.config.get('scm.repos.tarball.enable', False)):
            raise exc.HTTPNotFound()
        rev = self._commit.url().split('/')[-2]
        status = c.app.repo.get_tarball_status(rev, path)
        if not status and request.method == 'POST':
            allura.tasks.repo_tasks.tarball.post(rev, path)
            redirect('tarball' + '?path={0}'.format(path) if path else '')
        return dict(commit=self._commit, revision=rev, status=status)

    @expose('json:')
    def tarball_status(self, path=None, **kw):
        if not asbool(tg.config.get('scm.repos.tarball.enable', False)):
            raise exc.HTTPNotFound()
        rev = self._commit.url().split('/')[-2]
        return dict(status=c.app.repo.get_tarball_status(rev, path))

    @expose('jinja:allura:templates/repo/log.html')
    @with_trailing_slash
    @validate(dict(page=validators.Int(if_empty=0, if_invalid=0),
                   limit=validators.Int(if_empty=25, if_invalid=25)))
    def log(self, limit=25, path=None, **kw):
        is_file = False
        if path:
            is_file = c.app.repo.is_file(path, self._commit._id)
        limit, _ = h.paging_sanitizer(limit, 0)
        commits = list(islice(c.app.repo.log(
            revs=self._commit._id,
            path=path,
            id_only=False,
            page_size=limit + 1), limit + 1))
        next_commit = None
        if len(commits) > limit:
            next_commit = commits.pop()
        c.log_widget = self.log_widget
        return dict(
            username=c.user._id and c.user.username,
            branch=None,
            log=commits,
            next_commit=next_commit,
            limit=limit,
            path=path,
            is_file=is_file,
            **kw)
Beispiel #5
0
class MergeRequestController(object):
    log_widget = SCMLogWidget(show_paging=False)
    thread_widget = w.Thread(
        page=None, limit=None, page_size=None, count=None,
        style='linear')
    mr_dispose_form = SCMMergeRequestDisposeWidget()

    def __init__(self, num):
        self.tmpl = g.jinja2_env.get_template('allura:templates/repo/merge_request_changed.html')
        self.req = M.MergeRequest.query.get(
            app_config_id=c.app.config._id,
            request_number=int(num))
        if self.req is None:
            raise exc.HTTPNotFound

    @with_trailing_slash
    @expose('jinja:allura:templates/repo/merge_request.html')
    def index(self, page=0, limit=250, **kw):
        c.thread = self.thread_widget
        c.log_widget = self.log_widget
        c.mr_dispose_form = self.mr_dispose_form
        limit, page = h.paging_sanitizer(limit, page)
        with self.req.push_downstream_context():
            downstream_app = c.app
        result = dict(
            downstream_app=downstream_app,
            req=self.req,
            can_merge=self.req.can_merge(),
            can_merge_status=self.req.can_merge_task_status(),
            merge_status=self.req.merge_task_status(),
            page=page,
            limit=limit,
            count=self.req.discussion_thread.post_count)
        try:
            result['commits'] = self.req.commits
        except Exception:
            log.info(
                "Can't get commits for merge request %s",
                self.req.url(),
                exc_info=True)
            result['commits'] = []
            result['error'] = True
        return result

    @property
    def mr_widget_edit(self):
        target_branches = [
            b.name
            for b in c.app.repo.get_branches() + c.app.repo.get_tags()]
        with self.req.push_downstream_context():
            source_branches = [
                b.name
                for b in c.app.repo.get_branches() + c.app.repo.get_tags()]
        return SCMMergeRequestWidget(
            source_branches=source_branches,
            target_branches=target_branches)

    @expose('jinja:allura:templates/repo/merge_request_edit.html')
    def edit(self, **kw):
        require_access(self.req, 'write')
        c.form = self.mr_widget_edit
        if self.req['source_branch'] in c.form.source_branches:
            source_branch = self.req['source_branch']
        else:
            source_branch = c.app.default_branch_name
        if self.req['target_branch'] in c.form.target_branches:
            target_branch = self.req['target_branch']
        else:
            target_branch = c.app.default_branch_name
        return {
            'source_branch': source_branch,
            'target_branch': target_branch,
            'description': self.req['description'],
            'summary': self.req['summary']
        }

    @expose()
    @require_post()
    def do_request_merge_edit(self, **kw):
        require_access(self.req, 'write')
        kw = self.mr_widget_edit.to_python(kw)
        changes = OrderedDict()
        if self.req.summary != kw['summary']:
            changes['Summary'] = [self.req.summary, kw['summary']]
            self.req.summary = kw['summary']

        if self.req.target_branch != kw['target_branch']:
            changes['Target branch'] = [self.req.target_branch, kw['target_branch']]
            self.req.target_branch = kw['target_branch']

        if self.req.source_branch != kw['source_branch']:
            changes['Source branch'] = [self.req.source_branch, kw['source_branch']]
            self.req.source_branch = kw['source_branch']

        if self.req.description != kw['description']:
            changes['Description'] = h.unidiff(self.req.description, kw['description'])
            self.req.description = kw['description']
        with self.req.push_downstream_context():
            self.req.downstream['commit_id'] = c.app.repo.commit(kw['source_branch'])._id

        message = self.tmpl.render(changes=changes)
        self.req.discussion_thread.add_post(text=message, is_meta=True)
        redirect(self.req.url())

    @expose()
    @require_post()
    @validate(mr_dispose_form)
    def save(self, status=None, **kw):
        require_access(self.req, 'write')
        if self.req.status != status:
            message = self.tmpl.render(changes={'Status': [self.req.status, status]})
            self.req.discussion_thread.add_post(text=message, is_meta=True)
            self.req.status = status
        redirect('.')

    @expose()
    @require_post()
    def merge(self):
        if not self.req.merge_allowed(c.user) or not self.req.can_merge():
            raise exc.HTTPNotFound
        self.req.merge()
        redirect(self.req.url())

    @expose('json:')
    def merge_task_status(self, **kw):
        return {'status': self.req.merge_task_status()}

    @expose('json:')
    def can_merge_task_status(self, **kw):
        return {'status': self.req.can_merge_task_status()}

    @expose('json:')
    def can_merge_result(self, **kw):
        """Return result from the cache. Used by js, after task was completed."""
        return {'can_merge': self.req.can_merge()}
Beispiel #6
0
class CommitBrowser(BaseController):
    TreeBrowserClass = None
    revision_widget = SCMRevisionWidget()
    log_widget = SCMLogWidget()
    page_list = ffw.PageList()
    DEFAULT_PAGE_LIMIT = 25

    def __init__(self, revision):
        self._revision = revision
        self._commit = c.app.repo.commit(revision)
        if self._commit is None:
            raise exc.HTTPNotFound
        self.tree = self.TreeBrowserClass(self._commit, tree=self._commit.tree)

    @expose('jinja:allura:templates/repo/commit.html')
    @validate(
        dict(page=validators.Int(if_empty=0),
             limit=validators.Int(if_empty=DEFAULT_PAGE_LIMIT)))
    def index(self, page=0, limit=DEFAULT_PAGE_LIMIT):
        c.revision_widget = self.revision_widget
        c.page_list = self.page_list
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        tree = self._commit.tree
        limit, page, start = g.handle_paging(limit,
                                             page,
                                             default=self.DEFAULT_PAGE_LIMIT)
        diffs = self._commit.paged_diffs(start=start, end=start + limit)
        result['artifacts'] = [(t, f) for t in ('added', 'removed', 'changed',
                                                'copied') for f in diffs[t]
                               if t == 'removed' or tree.get_blob_by_path(f)]
        count = diffs['total']
        result.update(dict(page=page, limit=limit, count=count))
        return result

    @expose('jinja:allura:templates/repo/commit_basic.html')
    def basic(self):
        c.revision_widget = self.revision_widget
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        return result

    @expose('jinja:allura:templates/repo/tarball.html')
    def tarball(self, **kw):
        path = kw.pop('path', None)
        if not asbool(tg.config.get('scm.repos.tarball.enable', False)):
            raise exc.HTTPNotFound()
        rev = self._commit.url().split('/')[-2]
        status = c.app.repo.get_tarball_status(rev, path)
        if status is None:
            allura.tasks.repo_tasks.tarball.post(revision=rev, path=path)
        return dict(commit=self._commit, revision=rev, status=status)

    @expose('json:')
    def tarball_status(self, path=None, **kw):
        if not asbool(tg.config.get('scm.repos.tarball.enable', False)):
            raise exc.HTTPNotFound()
        rev = self._commit.url().split('/')[-2]
        return dict(status=c.app.repo.get_tarball_status(rev, path))

    @expose('jinja:allura:templates/repo/log.html')
    @with_trailing_slash
    @validate(
        dict(page=validators.Int(if_empty=0),
             limit=validators.Int(if_empty=25)))
    def log(self, limit=25, path=None, **kw):
        is_file = False
        if path:
            path = path.lstrip('/')
            is_file = self.tree._tree.get_blob_by_path(path) is not None
        params = dict(path=path, rev=self._commit._id)
        commits = list(c.app.repo.commits(limit=limit + 1, **params))
        next_commit = None
        if len(commits) > limit:
            next_commit = M.repo.Commit.query.get(_id=commits.pop())
            next_commit.set_context(c.app.repo)
        revisions = list(M.repo.Commit.query.find({'_id': {'$in': commits}}))
        for commit in revisions:
            commit.set_context(c.app.repo)
        revisions = sorted(revisions, key=lambda c: commits.index(c._id))
        c.log_widget = self.log_widget
        return dict(username=c.user._id and c.user.username,
                    branch=None,
                    log=revisions,
                    next_commit=next_commit,
                    limit=limit,
                    path=path,
                    is_file=is_file,
                    **kw)
Beispiel #7
0
class MergeRequestController(object):
    log_widget = SCMLogWidget(show_paging=False)
    thread_widget = w.Thread(page=None,
                             limit=None,
                             page_size=None,
                             count=None,
                             style='linear')
    mr_dispose_form = SCMMergeRequestDisposeWidget()
    subscribe_form = SubscribeForm(thing='merge request')

    def __init__(self, num):
        self.req = M.MergeRequest.query.get(app_config_id=c.app.config._id,
                                            request_number=int(num))
        if self.req is None:
            raise exc.HTTPNotFound

    @with_trailing_slash
    @expose('jinja:allura:templates/repo/merge_request.html')
    def index(self, page=0, limit=250, **kw):
        c.thread = self.thread_widget
        c.log_widget = self.log_widget
        c.mr_dispose_form = self.mr_dispose_form
        c.subscribe_form = self.subscribe_form

        limit, page = h.paging_sanitizer(limit, page)
        with self.req.push_downstream_context():
            downstream_app = c.app

        tool_subscribed = M.Mailbox.subscribed()
        if tool_subscribed:
            subscribed = False
        else:
            subscribed = M.Mailbox.subscribed(artifact=self.req)

        result = dict(
            downstream_app=downstream_app,
            req=self.req,
            can_merge=self.req.can_merge(),
            can_merge_status=self.req.can_merge_task_status(),
            merge_status=self.req.merge_task_status(),
            page=page,
            limit=limit,
            count=self.req.discussion_thread.post_count,
            subscribed=subscribed,
            commits_task_started=False,
        )
        if self.req.new_commits is not None:
            try:
                result['commits'] = self.req.commits
            except Exception:
                log.info("Can't get commits for merge request %s",
                         self.req.url(),
                         exc_info=True)
                result['commits'] = []
                result['error'] = True
        else:
            if self.req.commits_task_status() not in ('busy', 'ready'):
                allura.tasks.repo_tasks.determine_mr_commits.post(self.req._id)
            result['commits'] = []
            result['commits_task_started'] = True
        return result

    @property
    def mr_widget_edit(self):
        target_branches = [
            b.name for b in c.app.repo.get_branches() + c.app.repo.get_tags()
        ]
        with self.req.push_downstream_context():
            source_branches = [
                b.name
                for b in c.app.repo.get_branches() + c.app.repo.get_tags()
            ]
        return SCMMergeRequestWidget(source_branches=source_branches,
                                     target_branches=target_branches)

    @expose('jinja:allura:templates/repo/merge_request_edit.html')
    def edit(self, **kw):
        require_access(self.req, 'write')
        c.form = self.mr_widget_edit
        if self.req['source_branch'] in c.form.source_branches:
            source_branch = self.req['source_branch']
        else:
            source_branch = c.app.default_branch_name
        if self.req['target_branch'] in c.form.target_branches:
            target_branch = self.req['target_branch']
        else:
            target_branch = c.app.default_branch_name
        return {
            'source_branch': source_branch,
            'target_branch': target_branch,
            'description': self.req['description'],
            'summary': self.req['summary']
        }

    @expose()
    @require_post()
    def do_request_merge_edit(self, **kw):
        require_access(self.req, 'write')
        kw = self.mr_widget_edit.to_python(kw)
        changes = OrderedDict()
        if self.req.summary != kw['summary']:
            changes['Summary'] = [self.req.summary, kw['summary']]
            self.req.summary = kw['summary']

        if self.req.target_branch != kw['target_branch']:
            changes['Target branch'] = [
                self.req.target_branch, kw['target_branch']
            ]
            self.req.target_branch = kw['target_branch']

        if self.req.source_branch != kw['source_branch']:
            changes['Source branch'] = [
                self.req.source_branch, kw['source_branch']
            ]
            self.req.source_branch = kw['source_branch']

        if self.req.description != kw['description']:
            changes['Description'] = h.unidiff(self.req.description,
                                               kw['description'])
            self.req.description = kw['description']

        if changes:
            self.req.add_meta_post(changes=changes)
            g.director.create_activity(c.user,
                                       'updated',
                                       self.req,
                                       related_nodes=[c.project],
                                       tags=['merge-request'])
        self.refresh()

    @expose()
    @require_post()
    @validate(mr_dispose_form)
    def save(self, status=None, **kw):
        if status and self.req.status != status and \
           (has_access(self.req, 'write') or (self.req.creator == c.user and status == 'rejected')):
            self.req.add_meta_post(
                changes={'Status': [self.req.status, status]})
            g.director.create_activity(c.user,
                                       'updated',
                                       self.req,
                                       related_nodes=[c.project],
                                       tags=['merge-request'])
            self.req.status = status
        redirect('.')

    @expose()
    @require_post()
    def refresh(self, **kw):
        require_access(self.req, 'read')
        with self.req.push_downstream_context():
            self.req.new_commits = None  # invalidate this cache
            self.req.downstream['commit_id'] = c.app.repo.commit(
                self.req.source_branch)._id
        redirect(self.req.url())

    @expose()
    @require_post()
    def merge(self):
        if not self.req.merge_allowed(c.user) or not self.req.can_merge():
            raise exc.HTTPNotFound
        self.req.merge()
        redirect(self.req.url())

    @expose('json:')
    def merge_task_status(self, **kw):
        return {'status': self.req.merge_task_status()}

    @expose('json:')
    def can_merge_task_status(self, **kw):
        return {'status': self.req.can_merge_task_status()}

    @expose('json:')
    def can_merge_result(self, **kw):
        """Return result from the cache. Used by js, after task was completed."""
        return {'can_merge': self.req.can_merge()}

    @expose()
    def commits_html(self, **kw):
        if self.req.new_commits is not None:
            with self.req.push_downstream_context():
                downstream_app = c.app
            return SCMLogWidget().display(value=self.req.commits,
                                          app=downstream_app)

        task_status = self.req.commits_task_status()
        if task_status is None:
            raise exc.HTTPNotFound
        elif task_status == 'error':
            raise exc.HTTPInternalServerError
        elif task_status in ('busy', 'ready'):
            raise exc.HTTPAccepted

    @expose('json:')
    @require_post()
    @validate(subscribe_form)
    def subscribe(self, subscribe=None, unsubscribe=None, **kw):
        if subscribe:
            self.req.subscribe()
        elif unsubscribe:
            self.req.unsubscribe()
        return {
            'status': 'ok',
            'subscribed': M.Mailbox.subscribed(artifact=self.req),
            'subscribed_to_tool': M.Mailbox.subscribed(),
            'subscribed_to_entire_name': 'code repository',
        }
class CommitBrowser(BaseController):
    TreeBrowserClass=None
    revision_widget = SCMRevisionWidget()
    log_widget=SCMLogWidget()
    page_list=ffw.PageList()
    DEFAULT_PAGE_LIMIT = 25

    def __init__(self, revision):
        self._revision = revision
        self._commit = c.app.repo.commit(revision)
        if self._commit is None:
            raise exc.HTTPNotFound
        self.tree = self.TreeBrowserClass(self._commit, tree=self._commit.tree)

    @expose('jinja:allura:templates/repo/commit.html')
    @validate(dict(page=validators.Int(if_empty=0),
                   limit=validators.Int(if_empty=DEFAULT_PAGE_LIMIT)))
    def index(self, page=0, limit=DEFAULT_PAGE_LIMIT):
        c.revision_widget = self.revision_widget
        c.page_list = self.page_list
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        tree = self._commit.tree
        limit, page, start = g.handle_paging(limit, page,
                                             default=self.DEFAULT_PAGE_LIMIT)
        result['artifacts'] = [
                (t,f) for t in ('added', 'removed', 'changed', 'copied')
                    for f in self._commit.diffs[t]
                        if t == 'removed' or tree.get_blob_by_path(f)]
        count = len(result['artifacts'])
        result['artifacts'] = result['artifacts'][start:start+limit]
        result.update(dict(page=page, limit=limit, count=count))
        return result

    @expose('jinja:allura:templates/repo/commit_basic.html')
    def basic(self):
        c.revision_widget = self.revision_widget
        result = dict(commit=self._commit)
        if self._commit:
            result.update(self._commit.context())
        return result

    @expose('jinja:allura:templates/repo/log.html')
    @with_trailing_slash
    @validate(dict(page=validators.Int(if_empty=0),
                   limit=validators.Int(if_empty=25)))
    def log(self, limit=25, page=0, **kw):
        limit, page, start = g.handle_paging(limit, page, default=25)
        revisions = c.app.repo.log(
                branch=self._commit._id,
                offset=start,
                limit=limit)
        count = c.app.repo.count(branch=self._commit._id)
        c.log_widget = self.log_widget
        return dict(
            username=c.user._id and c.user.username,
            branch=None,
            log=revisions,
            page=page,
            limit=limit,
            count=count,
            **kw)