class Blob(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member, version, path): watcher = get_repo_watcher(g.current_user.id, repo.id) jagare = get_jagare(repo.id, repo.parent) tname = team.name if team else None content, content_type, content_length = format_content(jagare, repo, path, version=version) return self.render_template( member=member, repo=repo, \ organization=organization, \ watcher=watcher, file_path=path, \ branches=get_branches(repo, jagare), \ content=content, \ content_length=content_length, \ content_type=content_type, \ admin=admin, team=team, team_member=team_member, \ version=version, \ path=render_path( path, version, organization.git, tname, repo.name ) )
class View(MethodView): decorators = [ gist_require(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist, version='master'): jagare = get_jagare(gist.id, gist.parent) error, tree = jagare.ls_tree(gist.get_real_path(), version=version) if not error: tree, meta = tree['content'], tree['meta'] tree = render_tree(jagare, tree, gist, organization, version=version) watcher = get_gist_watcher(g.current_user.id, gist.id) return self.render_template( organization=organization, \ member=member, \ error=error, \ tree=tree, \ gist=gist, \ watcher=watcher, \ )
class Forks(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): forks = get_repo_forks(repo.id) return self.render_template( organization=organization, \ member=member, \ repo=repo, \ forks=self.render_forks(organization, forks, team) ) def render_forks(self, organization, forks, team): for fork in forks: view_url = get_url(organization, fork, view='repos.view', team=team) setattr(fork, 'view', view_url) setattr(fork, 'user', get_user(fork.uid)) yield fork
class Activities(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): page = request.args.get('p', 1) try: page = int(page) except ValueError: raise abort(403) data, list_page = render_activities_page(page, t='repo', repo=repo) return self.render_template( data=self.render_activities(data, organization, repo, team), \ list_page=list_page, \ member=member, repo=repo, \ organization=organization, \ admin=admin, team=team, team_member=team_member, \ ) def render_activities(self, data, organization, repo, team): for action, original, timestamp in data: if action['type'] == 'push': yield render_push_action(action, organization, repo=repo, team=team) else: #TODO for merge data continue
class ViewTeam(MethodView): decorators = [ team_member_required(need=False), \ member_required(admin=False), \ login_required('account.login') ] def get(self, organization, member, team, team_member): members = get_team_members(team.id) users = (get_user(member.uid) for member in members) page = request.args.get('p', 1) try: page = int(page) except ValueError: raise abort(403) data, list_page = render_activities_page(page, t='team', organization=organization, team=team) return self.render_template( organization=organization, \ team_member=team_member, \ team=team, member=member, \ users=users, \ data=self.render_activities(data, organization, team), \ list_page=list_page, \ ) def render_activities(self, data, organization, team): for action, original, _ in data: if action['type'] == 'push': yield render_push_action(action, organization, team=team) else: #TODO for other data continue
class DeleteFile(MethodView): decorators = [ repo_required(need_write=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member, version=None, path=None): if not check_obj_type(repo, path, version, 'blob'): raise abort(403) error = update_file( organization, \ g.current_user, \ repo, {path: ''}, \ version, \ '%s %s' % (code.REPOS_DELETE_FILE, path) ) if not error: path = path.rsplit('/', 1)[0] if '/' in path else None return redirect(repo.meta.get_view(version=version, path=path))
class Commit(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member, version): jagare = get_jagare(repo.id, repo.parent) error, commits = jagare.get_log( repo.get_real_path(), \ size=1, start=version, \ ) if not commits: raise abort(404) commit = commits[0] render_commit(commit, organization, repo) commit['diffs'] = split_diff(commit['diff']) return self.render_template( member=member, repo=repo, \ organization=organization, \ admin=admin, team=team, team_member=team_member, \ commit=commit, \ )
class Create(MethodView): decorators = [ member_required(admin=False), login_required('account.login') ] def get(self, organization, member): return self.render_template( organization=organization, \ member=member, \ teams=self.get_joined_teams(organization) ) def post(self, organization, member): repopath = request.form.get('path', '') name = request.form.get('name', '') summary = request.form.get('summary', '') teamname = repopath.strip('/').split('/', 1)[0] if not check_reponame(name): return self.render_template( organization=organization, \ member=member, \ teams=self.get_joined_teams(organization), \ error = code.REPOS_NAME_INVALID, \ ) team = get_team_by_name(organization.id, teamname) if teamname else None if teamname and (not team or not get_team_member(team.id, g.current_user.id)): return self.render_template( organization=organization, \ member=member, \ teams=self.get_joined_teams(organization), \ error = code.REPOS_PATH_INVALID, \ ) path = os.path.join(teamname, '%s.git' % name) repo, error = create_repo(name, path, g.current_user, organization, team=team, summary=summary) if error: return self.render_template( organization=organization, \ member=member, \ teams=self.get_joined_teams(organization), \ error = error, \ ) return redirect(get_url(organization, repo)) def get_joined_teams(self, organization): for team in get_teams_by_ogranization(organization.id): if not get_team_member(team.id, g.current_user.id): continue yield team
class CreateTeam(MethodView): decorators = [ member_required(admin=False), login_required('account.login'), ] def get(self, organization, member): if not self.check_permits(organization, member): raise abort(403) return self.render_template( organization=organization, \ member=member, \ ) def post(self, organization, member): if not self.check_permits(organization, member): raise abort(403) name = request.form.get('name', None) display = request.form.get('display', None) private = 1 if 'private' in request.form else 0 status = check_git(name) if not status: return self.render_template( organization=organization, \ member=member, \ error=code.ORGANIZATION_GITNAME_INVALID, \ ) status = check_team_name(display) if not status: return self.render_template( organization=organization, \ member=member, \ error=code.ORGANIZATION_NAME_INVALID, \ ) team, error = create_team(name, display, g.current_user, organization, private=private, members=1) if error: return self.render_template( organization=organization, \ member=member, \ error=error, \ ) return redirect( url_for('organization.viewteam', git=organization.git, tname=team.name)) def check_permits(self, organization, member): if organization.allow: return True if member.admin: return True return False
class Delete(MethodView): decorators = [ repo_required(admin=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): delete_repo(organization, repo, team) return redirect(url_for('organization.view', git=organization.git))
class Delete(MethodView): decorators = [ gist_require(owner=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist): delete_gist(g.current_user, gist, organization) return redirect(url_for('organization.view', git=organization.git))
class Create(MethodView): decorators = [ member_required(admin=False), login_required('account.login') ] def get(self, organization, member): return self.render_template( organization=organization, \ member=member, \ ) def post(self, organization, member): summary = request.form.get('summary') filenames = request.form.getlist('filename') codes = request.form.getlist('code') private = create_token(20) if request.form.get('private') else None data = {} if len(filenames) != len(codes): raise abort(400) for filename, content in zip(filenames, codes): if not filename and not content: continue if not filename or not content: return self.render_template( organization=organization, \ member=member, \ error=code.GIST_WITHOUT_FILENAME if not filename else code.GIST_WITHOUT_CONTENT, \ filenames=filenames, \ codes=codes, \ ) if data.get(filename): return self.render_template( organization=organization, \ member=member, \ error=code.GIST_FILENAME_EXISTS, \ filenames=filenames, \ codes=codes, \ ) data[filename] = content gist, err = create_gist(organization, g.current_user, summary, data=data, private=private, watchers=1) if err: return self.render_template( organization=organization, \ member=member, \ error=code.GIST_CREATE_FAILED, \ filenames=filenames, \ codes=codes, \ ) return redirect(get_url(organization, gist))
class Watch(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): watcher = get_repo_watcher(g.current_user.id, repo.id) if not watcher: create_watcher(g.current_user, repo, organization, team=team) return redirect(repo.meta.view)
class Unwatch(MethodView): decorators = [ gist_require(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist): watcher = get_gist_watcher(g.current_user.id, gist.id) if watcher: delete_watcher(g.current_user, watcher, gist, organization) return redirect(gist.meta.view)
class QuitTeam(MethodView): decorators = [ team_member_required(), \ member_required(admin=False), \ login_required('account.login') ] def post(self, organization, member, team, team_member): quit_team(organization, team, team_member, g.current_user) return redirect( url_for('organization.viewteam', git=organization.git, tname=team.name))
class RemoveCommiter(MethodView): decorators = [ repo_required(admin=True), member_required(admin=False), login_required('account.login') ] def post(self, organization, member, repo, admin, team, team_member): name = request.form.get('name') user = get_user(name) if not user or user.id == repo.uid: return redirect(repo.meta.commiter) commiter = get_repo_commiter(user.id, repo.id) if user and commiter: delete_commiter(user, commiter, repo, organization, team) return redirect(repo.meta.commiter)
class Revisions(MethodView): decorators = [gist_require(owner=True), member_required(admin=False), login_required('account.login')] def get(self, organization, member, gist): page = request.args.get('p', 1) try: page = int(page) except ValueError: raise abort(403) jagare = get_jagare(gist.id, gist.parent) error, revisions = jagare.get_log(gist.get_real_path(), page=page, size=config.REVISIONS_PER_PAGE) if not revisions: raise abort(404) list_page = render_revisions_page(gist, page) revisions = self.render_revisions(organization, gist, revisions, list_page) return self.render_template( organization=organization, \ member=member, \ error=error, \ revisions=revisions, \ gist=gist, \ list_page=list_page, \ ) def render_revisions(self, organization, gist, revisions, list_page): for rev in revisions[:-1]: self.render_rev(rev, organization, gist) rev['type'] = 'update' yield rev rev = revisions[-1] self.render_rev(rev, organization, gist) rev['type'] = 'create' if not list_page.has_next else 'update' yield rev def render_rev(self, rev, organization, gist): rev['view'] = get_url(organization, gist, version=rev['sha']) rev['committer_time'] = format_time(rev['committer_time']) author = reqcache.get(rev['author_email']) if not author: author = get_user_from_alias(rev['author_email']) reqcache.set(rev['author_email'], author) if not author: author = Obj() author.email = rev['author_email'] author.name = None rev['author'] = author rev['diff'] = render_diff(rev['diff'])
class Commiters(MethodView): decorators = [ repo_required(admin=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): return self.render_template( member=member, repo=repo, organization=organization, \ commiters=self.get_commiters(repo), \ admin=admin, team=team, team_member=team_member, \ ) def post(self, organization, member, repo, admin, team, team_member): name = request.form.get('name') user = get_user(name) if not user: return self.render_template( member=member, repo=repo, organization=organization, \ commiters = self.get_commiters(repo), \ error=code.ACCOUNT_NO_SUCH_USER, \ admin=admin, team=team, team_member=team_member, \ ) if user.id == repo.uid: return self.render_template( member=member, repo=repo, organization=organization, \ commiters = self.get_commiters(repo), \ error=code.REPOS_COMMITER_EXISTS, \ admin=admin, team=team, team_member=team_member, \ ) is_member = get_organization_member(organization.id, user.id) if not is_member: return self.render_template( member=member, repo=repo, organization=organization, \ commiters = self.get_commiters(repo), \ error=code.ORGANIZATION_MEMBER_NOT_EXISTS, \ admin=admin, team=team, team_member=team_member, \ ) create_commiter(user, repo, organization, team) return redirect(repo.meta.commiter) def get_commiters(self, repo): commiters = get_repo_commiters(repo.id) commiters = (get_user(commiter.uid) for commiter in commiters) return commiters
class Fork(MethodView): decorators = [ gist_require(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist): private = create_token(20) if gist.private else None fork_gist, err = create_gist(organization, g.current_user, gist.summary, parent=gist, private=private, watchers=1) if err: return redirect(gist.meta.view) return redirect(get_url(organization, fork_gist))
class Raw(MethodView): decorators = [ gist_require(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist, path): jagare = get_jagare(gist.id, gist.parent) error, res = jagare.cat_file(gist.get_real_path(), path) if error: raise abort(error) resp = Response(stream_with_context(res)) resp.headers['X-Accel-Buffering'] = 'no' resp.headers['Cache-Control'] = 'no-cache' resp.headers['Content-Type'] = res.headers.get( 'content-type', 'application/octet-stream') return resp
class Transport(MethodView): decorators = [ repo_required(admin=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): return self.render_template( member=member, repo=repo, organization=organization, \ admin=admin, team=team, team_member=team_member, \ ) def post(self, organization, member, repo, admin, team, team_member): name = request.form.get('name') user = get_user(name) if not user: return self.render_template( member=member, repo=repo, organization=organization, \ error=code.ACCOUNT_NO_SUCH_USER, \ admin=admin, team=team, team_member=team_member, \ ) if user.id == repo.uid: return self.render_template( member=member, repo=repo, organization=organization, \ error=code.REPOS_CANT_TRANSPORT_SELF, \ admin=admin, team=team, team_member=team_member, \ ) is_member = get_organization_member(organization.id, user.id) if not is_member: return self.render_template( member=member, repo=repo, organization=organization, \ error=code.ORGANIZATION_MEMBER_NOT_EXISTS, \ admin=admin, team=team, team_member=team_member, \ ) error = transport_repo(organization, user, repo, team) if error: return self.render_template( member=member, repo=repo, organization=organization, \ error=error, \ admin=admin, team=team, team_member=team_member, \ ) return redirect(repo.meta.transport)
class Watchers(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): watchers = get_repo_watchers(repo.id) return self.render_template( member=member, repo=repo, organization=organization, \ watchers=self.render_watchers(watchers), \ admin=admin, team=team, team_member=team_member, \ ) def render_watchers(self, watchers): for watcher in watchers: setattr(watcher, 'user', get_user(watcher.uid)) yield watcher
class Fork(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): return self.render_template( organization=organization, \ member=member, \ repo=repo, \ ) def post(self, organization, member, repo, admin, team, team_member): name = request.form.get('name', '') summary = request.form.get('summary', '') teamname = '' if not team else team.name if not check_reponame(name): return self.render_template( organization=organization, \ member=member, \ repo=repo, \ error = code.REPOS_NAME_INVALID, \ ) path = os.path.join(teamname, '%s.git' % name) fork_repo, error = create_repo( name, path, g.current_user, organization, \ team=team, summary=summary, parent=repo, \ default=repo.default ) if error: return self.render_template( organization=organization, \ member=member, \ repo=repo, \ error = error, \ ) return redirect(get_url(organization, fork_repo))
class Watchers(MethodView): decorators = [ gist_require(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist): watchers = get_gist_watchers(gist.id) return self.render_template( organization=organization, \ member=member, \ gist=gist, \ watchers=self.render_watchers(watchers) ) def render_watchers(self, watchers): for watcher in watchers: setattr(watcher, 'user', get_user(watcher.uid)) yield watcher
class Forks(MethodView): decorators = [ gist_require(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, gist): forks = get_gist_forks(gist.id) return self.render_template( organization=organization, \ member=member, \ gist=gist, \ forks=self.render_forks(organization, forks) ) def render_forks(self, organization, forks): for fork in forks: view_url = get_url(organization, fork, 'gists.view') setattr(fork, 'view', view_url) setattr(fork, 'user', get_user(fork.uid)) yield fork
class AddMember(MethodView): decorators = [ team_member_required(admin=True), \ member_required(admin=False), \ login_required('account.login') ] def get(self, organization, member, team, team_member): return self.render_template( organization=organization, \ team_member=team_member, \ team=team, member=member, \ ) def post(self, organization, member, team, team_member): name = request.form.get('name', None) admin = 1 if 'admin' in request.form else 0 user = get_user(name) if not user: return self.render_template( organization=organization, \ team_member=team_member, \ team=team, member=member, \ error=code.ACCOUNT_NO_SUCH_USER, \ ) is_member = get_organization_member(organization.id, user.id) if not is_member: return self.render_template( organization=organization, \ team_member=team_member, \ team=team, member=member, \ error=code.ORGANIZATION_MEMBER_NOT_EXISTS, \ ) create_team_members(organization, team, user, admin=admin) return redirect( url_for('organization.viewteam', git=organization.git, tname=team.name))
class Explore(MethodView): decorators = [ member_required(admin=False), login_required('account.login') ] def get(self, organization, member): f = request.args.get('f', None) if f not in ['w', 'm']: f = None else: f = 0 if f == 'w' else 1 return self.render_template( organization = organization, \ member = member, \ gists = self.get_gists(organization, f), \ ) def filter_gists(self, organization, f): if f is None: ret = get_organization_gists(organization.id) elif f == 0: ret = get_user_watch_gists(g.current_user.id, organization.id) elif f == 1: ret = get_user_organization_gists(organization.id, g.current_user.id) else: ret = [] return ret def get_gists(self, organization, f=None): ret = self.filter_gists(organization, f) for r in ret: setattr(r, 'user', get_user(r.uid)) setattr(r, 'view', get_url(organization, r)) yield r
class Setting(MethodView): decorators = [ repo_required(admin=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member): jagare = get_jagare(repo.id, repo.parent) branches = jagare.get_branches_names(repo.get_real_path()) return self.render_template( branches_switch=branches, \ member=member, repo=repo, \ organization=organization, \ admin=admin, team=team, team_member=team_member, \ ) def post(self, organization, member, repo, admin, team, team_member): name = request.form.get('name') default = request.form.get('default') params = {} if name != repo.name: params['name'] = name if default != repo.default: params['default'] = default if params: params['team'] = team error = update_repo(organization, repo, params) if error: return self.render_template( member=member, repo=repo, organization=organization, \ error = error, \ admin=admin, team=team, team_member=team_member, \ ) return redirect(get_url(organization, repo, 'repos.setting', team=team))
class View(MethodView): decorators = [ repo_required(), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member, version=None, path=None): version = version or repo.default file_path = path watcher = get_repo_watcher(g.current_user.id, repo.id) jagare = get_jagare(repo.id, repo.parent) tname = team.name if team else None if not check_obj_type(repo, path, version, 'tree'): raise abort(403) error, tree = jagare.ls_tree(repo.get_real_path(), path=path, version=version) readme = None commit = None if not error: tree, meta = tree['content'], tree['meta'] readme, tree = self.render_tree( jagare, \ repo, organization, \ tree, version, team, \ ) path = render_path( path, version, organization.git, \ tname, repo.name ) commit = self.get_commit_user(meta) return self.render_template( member=member, repo=repo, \ organization=organization, \ watcher=watcher, file_path=file_path, \ branches=get_branches(repo, jagare), \ tree=tree, error=error, \ readme=readme, \ version=version, \ admin=admin, team=team, team_member=team_member, \ path=path, commit=commit, \ ) def get_commit_user(self, meta): user = Obj() commit = Obj() user.name = meta['committer']['name'] user.email = meta['committer']['email'] user.avatar = None commit.message = meta['message'] commit.user = user commit.sha = meta['sha'] commit.date = meta['committer']['date'] alias = get_alias_by_email(user.email) if alias: user = get_user(alias.uid) commit.user.name = user.name commit.user.avatar = user.avatar(18) return commit def render_tree(self, jagare, repo, organization, tree, version, team): ret = [] readme = None for d in tree: data = Obj() if d['type'] == 'tree': data.url = get_url(organization, repo, view='repos.view', team=team, version=version, path=d['path']) elif d['type'] == 'blob': data.url = get_url(organization, repo, view='repos.blob', team=team, version=version, path=d['path']) if d['name'].startswith('README.'): readme, content_type, _ = format_content(jagare, repo, d['path'], version=version) if content_type != 'file': readme = None elif d['type'] == 'submodule': data.url = get_submodule_url(d['submodule'], d['sha']) d['name'] = '%s@%s' % (d['name'], d['sha'][:10]) data.name = d['name'] data.sha = d['sha'] data.type = d['type'] data.ago = format_time(d['commit']['committer']['ts']) data.message = d['commit']['message'][:150] data.commit = d['commit']['sha'] data.path = d['path'] ret.append(data) return readme, ret
class NewFile(MethodView): decorators = [ repo_required(need_write=True), member_required(admin=False), login_required('account.login') ] def get(self, organization, member, repo, admin, team, team_member, version=None, path=None): if not check_obj_type(repo, path, version, 'tree'): raise abort(403) return self.add(organization, repo, team, version, path) def post(self, organization, member, repo, admin, team, team_member, version=None, path=None): if not check_obj_type(repo, path, version, 'tree'): raise abort(403) filename = request.form.get('filename') content = request.form.get('content') if not filename or not content: return self.add( organization, repo, team, version, path, \ filename=filename, content=content, \ error_message=code.REPOS_EDIT_WITHOUT_INFO ) new_path = os.path.join(path if path else '', filename) data = {new_path: content} error = update_file( organization, \ g.current_user, \ repo, data, \ version, \ '%s %s' % (code.REPOS_NEW_FILE, new_path) ) if error: return self.add( organization, repo, team, version, path, \ filename=filename, content=content, \ error_message=code.REPOS_EDIT_FAILED ) return redirect(repo.meta.get_blob(version=version, path=new_path)) def add(self, organization, repo, team, version=None, path=None, error_message=None, content='', filename=''): watcher = get_repo_watcher(g.current_user.id, repo.id) tname = team.name if team else None return self.render_template( repo=repo, \ organization=organization, \ file_path=path, \ watcher=watcher, \ content=content, \ branches=get_branches(repo), \ version=version, \ filename=filename, \ path = render_path( path, version, organization.git, \ tname, repo.name ), \ error_message=error_message, \ )