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('.')
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)
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)
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()}
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)
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)