def _q_lookup(self, request, revrange): current_user = request.user try: sha1, sha2 = revrange.split('...') except ValueError: raise TraversalError( 'please provide valid start & end revisions: /compare/sha1...sha2' ) # noqa project = self.project commits = project.repo.get_commits(sha2, sha1) if commits is False: raise TraversalError() lasttime = commits and commits[0].author_time.strftime( "%Y-%m-%d %H:%M:%S") or 'UNKNOWN' grouped_commits = groupby(commits, lambda c: c.author_time.date()) n_commits = len(commits) n_authors = len(set(c.author.username for c in commits)) diff = project.repo.get_diff(sha2, from_ref=sha1, rename_detection=True) #diffs = project.git.get_3dot_diff(sha1, sha2) n_files = diff.length if diff else 0 comments = [] for ci in commits: comments.extend(Comment.gets_by_proj_and_ref(project.id, ci.sha)) branches = project.repo.branches tags = project.repo.tags ref = project.default_branch n_comments = len(comments) ref_type = 'branch' if ref in branches else 'tag' \ if ref in tags else 'tree' return st('compare.html', **locals())
def _toggle_whitespace(self, request, project, paths, ignore_space, **kwargs): sha1 = kwargs.get('sha1') context_lines = kwargs.get('context_lines') ref = sha1 if ref is None: ref = project.default_branch linecomments = CommitLineComment.gets_by_target_and_ref( project.id, ref) kw = { 'ref': sha1, 'paths': paths, 'ignore_space': ignore_space, 'rename_detection': True, 'linecomments': linecomments } if context_lines is not None: kw.update({'context_lines': context_lines}) try: commit = project.repo.get_commit(sha1) # get_diff 默认与 parent diff diff = project.repo.get_diff(**kw) if not commit: raise TraversalError("not a valid commit ref") except IOError: raise TraversalError() return diff
def _get_tmpl_raw(tmpl_target, rev, path, project_name, request): project = CodeDoubanProject.get_by_name(project_name) if rev is None: rev = project.default_branch try: blob = project.repo.get_file(rev, path.decode('utf-8')) except IOError: raise TraversalError() if not blob: raise TraversalError("No content found") resp = request.response if is_image(path): if path.endswith('svg'): resp.set_header("Content-Type", "image/svg+xml") else: resp.set_header("Content-Type", "image/jpeg") resp.set_header('Expires', 'Sun, 1 Jan 2006 01:00:00 GMT') resp.set_header('Pragma', 'no-cache') resp.set_header('Cache-Control', 'must-revalidate, no-cache, private') return blob.data if path.endswith('.pdf'): resp.set_header("Content-Type", "application/pdf") return blob.data if is_binary(path): resp.set_header("Content-Type", "application/octet-stream") resp.set_header("Content-Disposition", "attachment;filename=%s" % path.split('/')[-1]) resp.set_header("Content-Transfer-Encoding", "binary") return blob.data resp.set_header("Content-Type", "text/plain;charset=utf-8") return blob.data.encode('utf8')
def new(self, request): user = request.user if not user: raise AccessError from_proj = self.project from_ref = request.get_form_var('head_ref', from_proj.default_branch) parent_proj = from_proj.get_forked_from() to_proj = request.get_form_var('base_repo') if to_proj: to_proj = CodeDoubanProject.get_by_name(to_proj) elif parent_proj: to_proj = parent_proj else: to_proj = from_proj if not to_proj: raise TraversalError("The PR's upstream project is not existed") to_ref = request.get_form_var('base_ref', to_proj.default_branch) if from_proj != to_proj: # Allow to create PR to a different project only if user has push perm # ~~A bit weird, maybe should be separate perms # ~~If from and to projects are the same, we should be in online edit mode if not from_proj.has_push_perm(user.name): raise AccessError( "Need push permission to add a PR on another project") pullreq = PullRequest.open(from_proj, from_ref, to_proj, to_ref) family = from_proj.get_fork_network() from_branches = from_proj.repo.branches to_branches = to_proj.repo.branches from_commit = pullreq.from_commit to_commit = pullreq.to_commit if not pullreq.can_pull: raise TraversalError( "The PR's head_ref or base_ref is not existed") highlighted_projects = filter(None, [from_proj, parent_proj]) commits = pullreq.commits n_commits = len(commits) n_authors = len(set(c.author.username for c in commits)) ticket_title, ticket_desc = self._choose_default_PR_title_and_description( commits) # noqa # get diff diff = pullreq.get_diff(rename_detection=True) n_files = diff.length grouped_commits = groupby(commits, lambda c: c.author_time.date()) prs = PullRequest.get_by_from_and_to(from_proj.id, from_ref, to_proj.id, to_ref) open_pullreqs = [] for pr in prs: t = Ticket.get_by_projectid_and_ticketnumber( to_proj.id, pr.ticket_id) if t and t.closed is None: open_pullreqs.append(pr) guideline_url = get_project_guidelines(to_proj) teams = Team.get_all_team_uids() return st('/pull/new.html', **locals())
def __init__(self, request, proj_name, ticket_id): self.proj_name = proj_name self.ticket_id = ticket_id self.project = CodeDoubanProject.get_by_name(self.proj_name) if not self.project: raise TraversalError() self.ticket = Ticket.get_by_projectid_and_ticketnumber( self.project.id, self.ticket_id) if not self.ticket: raise TraversalError()
def __call__(self, request): try: # TODO: clean this text = self.gist.get_file(self.path, rev=self.rev) except IOError: raise TraversalError() if isinstance(text, bool) and text is False: raise TraversalError() resp = request.response resp.set_header("Content-Type", "text/plain; charset=utf-8") return text.encode('utf-8')
def _q_access(self, request): self.docs = SphinxDocs(self.proj) if not self.docs.enabled: raise TraversalError( "docs not enabled: %s" % self.docs.disabled_reason) self.builder_name, self.explicit_builder = guess_builder_from_path( self.docs.builders, self.proj, request.get_path()) if self.explicit_builder: self.base_path = "/%s/docs/%s/" % (self.proj, self.builder_name) else: self.base_path = "/%s/docs/" % (self.proj) self.builder = self.docs.get_builder(self.builder_name) if not self.builder: raise TraversalError("Unknown builder")
def _q_lookup(self, request, comment_id): comment = PullLineComment.get(comment_id) if not comment: raise TraversalError("Unable to find comment %s" % comment_id) else: self.code_review = comment return self
def _q_traverse(self, path): """(path: [string]) -> object Traverse a path and return the result. """ assert len(path) > 0 component = path[0] path = path[1:] name = self._q_translate(component) if name is not None: obj = getattr(self, name) else: obj = self._q_lookup(component) if obj is None: raise TraversalError(private_msg=('directory %r has no component ' '%r' % (self, component))) if path: if hasattr(obj, '_q_traverse'): return obj._q_traverse(path) else: raise TraversalError elif hasattr(obj, '__call__'): return obj() else: return obj
def _q_lookup(self, request, comment_id): comment = CommitLineComment.get(comment_id) if not comment: raise TraversalError("Unable to find comment %s" % comment_id) else: self.linecomment = comment return self
def source(self, request, sha1, path=None): current_user = request.user # guibog 20120815 some inherited templates need current user as user user = request.user project = self.project if sha1.count('.') == 1: sha, diff_type = sha1.split('.') resp = request.response resp.set_header("Content-Type", "text/plain") if diff_type == 'patch': text = project.repo.get_patch_file(sha) return text.encode('utf-8') elif diff_type == 'diff': text = project.repo.get_diff_file(sha) return text.encode('utf-8') ref = sha1 if ref is None: ref = project.default_branch branches = project.repo.branches tags = project.repo.tags ref_type = ('branch' if ref in branches else 'tag' if ref in tags else 'tree') comments = Comment.gets_by_proj_and_ref(project.id, ref) linecomments = CommitLineComment.gets_by_target_and_ref( project.id, ref) whitespace = request.get_form_var('w', '0') if whitespace.isdigit() and int(whitespace) == 1: ignore_space = True else: ignore_space = False try: commit = project.repo.get_commit(sha1) # get_diff 默认与 parent diff diff = project.repo.get_diff(ref=sha1, ignore_space=ignore_space, rename_detection=True, linecomments=linecomments, paths=[path] if path else None) if not commit: raise TraversalError("not a valid commit ref") except IOError: raise TraversalError() return st('commit.html', **locals())
def decorated(*args, **kwargs): if methods is not None: if request.method in methods: return f(*args, **kwargs) else: raise TraversalError() return f(*args, **kwargs)
def _q_lookup(self, request, comment_id): comment = TicketComment.get(id=comment_id) if not comment: raise TraversalError( "Unable to find pr_comment %s" % comment_id) else: self.pr_comment = comment return self
def _q_lookup(self, request, item): gid = item extend = None if item.count('.') == 1: gid, extend = item.split('.') if not gid.isdigit(): raise TraversalError() gist = Gist.get(gid) if not gist or gist.owner_id != self.name: raise TraversalError() if extend == 'js': return GistEmbedUI(gid) return GistUI(gid)
def __call__(self, request): proj = CodeDoubanProject.get_by_name(self.proj_name) ref = request.get_form_var('rev', 'HEAD') filename = '/'.join(self.filepath_parts) # TODO: check ref ret = proj.repo.get_file(ref, filename.decode('utf-8')) if ret is None: raise TraversalError() return str(ret.data.encode('utf8'))
def _q_index(self, request): errors = '' project_name = self.proj_name user = request.user project = CodeDoubanProject.get_by_name(project_name) if not project: raise TraversalError() data = project.git.get_gitstats_data() return st('graph.html', **locals())
def _q_lookup(self, request, comment_id): if request.method == 'DELETE': # FIXME: 不用验证user? ok = Comment.delete(comment_id) if not ok: raise TraversalError( "Unable to delete comment %s" % comment_id) return '' return "Display comment %s TODO" % comment_id
def __call__(self): if "" in self._q_exports and not quixote.get_request().form: # Fix missing trailing slash. path = quixote.get_path() print("Adding slash to: %r " % path) return quixote.redirect(path + "/", permanent=True) else: raise TraversalError(private_msg=('directory %r is not ' 'callable' % self))
def _q_access(self, request): gist = self.gist user = request.user if not gist: raise TraversalError() if not gist.is_public: if not user or user.username != gist.owner_id: raise AccessError()
def delete(self, request): import json user = request.user comment = self.linecomment if comment.author == user.name: ok = comment.delete() if not ok: raise TraversalError("Unable to delete comment %s" % comment.id) return json.dumps({'r': 1}) return json.dumps({'r': 0})
def _q_lookup(self, request, comment_id): if request.method == 'POST': act = request.get_form_var('act', None) if act and act in ('delete', 'update'): comment = GistComment.get(comment_id) if act == 'delete' and comment: if comment.can_delete(request.user.username): comment.delete() return json.dumps({'r': 1}) raise TraversalError("Unable to delete comment %s" % comment_id) return request.redirect(self.gist.url)
def commits(self, request): if not self.ticket: raise TraversalError() pr = PullRequest.get_by_proj_and_ticket(self.project.id, self.ticket.ticket_number) commits = pr.get_commits_shas() commits = [ TicketCommits.commit_as_dict(self.project, c) for c in commits ] # commits = reduce(lambda x, y: x + y, commits) return commits
def decorated(*args, **kwargs): if methods is not None: for arg in args: if isinstance(arg, HTTPRequest): request = arg break if request.method in methods: return f(*args, **kwargs) else: raise TraversalError() return f(*args, **kwargs)
def _q_lookup(self, request, sha1): user = request.user if sha1 == 'raw': return RawGistUI(self.id) if sha1 is None or not self.gist.repo.is_commit(sha1): return TraversalError() tdt = { 'request': request, 'gist': self.gist, 'ref': sha1, 'user': user } return st('/gist/gist_detail.html', **tdt)
def get_content(self, request, path): tdt = _tmpl_common_data(None, path, self.proj, request) if not self.builder.has_content(): tdt['docsdir'] = self.builder.dir return st('sphinx_docs_start.html', **tdt) if path in self.builder.redirects: return request.redirect("%s%s" % ( self.base_path, self.builder.redirects[path])) if self.builder.file_is_static(path): # Serve static files, cannot use nginx rerouting because # code permdir is not on MFS content = self.builder.file_content(path) if content is False: raise TraversalError( "Static content not found in %s" % path) ct = mimetypes.guess_type(path) request.response.set_content_type( ct[0] if ct else 'application/octet-stream') return content fvars = dict((_, request.get_form_var( _)) for _ in self.builder.needed_form_vars) if self.builder.template: tdt['doc'] = { 'with_comment': self.builder.with_comment(), 'docsdir': self.builder.dir, 'base_path': self.base_path, } tdt['doc'].update(self.builder.template_data(path, fvars)) return st(self.builder.template, **tdt) else: content = self.builder.raw_content(path, fvars) if content is False: raise TraversalError( "Builder %s did not find content file for %s" % ( self.builder_name, path)) return content
def get_content(self, rev, path, request): # TODO use a wrapper instead: # get common vars # merge specials if self.view not in _all_views: raise TraversalError() tmpl_target = _all_views[self.view][0] tmpl_getter = _all_views[self.view][1] # PJAX if request.environ.get('HTTP_X_PJAX', False): request.response.set_header('X-PJAX-VERSION', "v1") tmpl_target = 'pjax_' + tmpl_target return tmpl_getter(tmpl_target, rev, path, self.proj, request)
def _get_tmpl_blame(tmpl_target, rev, path, project_name, request): tdt = _tmpl_common_data(rev, path, project_name, request) project = CodeDoubanProject.get_by_name(project_name) ref = rev if ref is None: ref = project.default_branch blob_path = path.decode('utf-8') try: blame = project.repo.blame_file(ref, blob_path) commit = project.repo.get_commit(ref) except IOError: raise TraversalError() tdt.update({ 'blame': blame, 'commit': commit, }) return st(tmpl_target, **tdt)
def _q_index(self, request): if not self.ticket: raise TraversalError() action = request.data.get('action') if request.method == 'PATCH': if action == 'merge': return self.merge(request) elif action == 'close': return self.close(request) elif action == 'comment': return self.add_comment(request) elif action: raise InvalidFieldError('action') else: raise MissingFieldError('action') else: return self._index(request)
def _q_lookup(self, request, sha): if request.method == 'POST': return self._add_status(request, sha) cs = CommitStatuses(self.project.id, sha) if re.match(r'^\d+$', sha): # using id got one s = cs.get(sha) if s: return json.dumps(s.as_dict()) else: raise TraversalError() else: statuses = cs.all() statuses = [s.as_dict() for s in statuses] return json.dumps(statuses)
def __init__(self, name): self.name = name self.user = User(name) current_user = request.user self.is_self = current_user and current_user.username == self.name ext = request.get_path().split('/')[-1] (self.page, self.start, self.link_prev, self.link_next, self.sort, self.direction) =\ make_page_args(request, self.name, ext=ext) self.n_all = Gist.count_user_all(self.name, self.is_self) self.n_fork = Gist.count_user_fork(self.name) self.n_star = Gist.count_user_star(self.name) if self.sort not in ('created', 'updated') \ or self.direction not in ('desc', 'asc'): raise TraversalError()