def my_account(self): """ GET /_admin/my_account Displays info about my account """ # url('admin_settings_my_account') c.user = User.get(self.rhodecode_user.user_id) c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, ip_addr=self.ip_addr) c.ldap_dn = c.user.ldap_dn if c.user.username == 'default': h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users')) #json used to render the grid c.data = self._load_my_repos_data() defaults = c.user.get_dict() c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=defaults, encoding="UTF-8", force_defaults=False ) return render('admin/users/user_edit_my_account.html')
def my_account_update(self): """PUT /_admin/my_account_update: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('admin_settings_my_account_update'), # method='put') # url('admin_settings_my_account_update', id=ID) uid = self.rhodecode_user.user_id email = self.rhodecode_user.email _form = UserForm(edit=True, old_data={'user_id': uid, 'email': email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) UserModel().update_my_account(uid, form_result) h.flash(_('Your account was updated successfully'), category='success') Session().commit() except formencode.Invalid, errors: c.user = User.get(self.rhodecode_user.user_id) c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8") return render('admin/users/user_edit_my_account.html')
def index(self): # Return a rendered template p = int(request.params.get('page', 1)) c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() c.user_repos = ScmModel().get_repos(all_repos) c.following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ .all() journal = self._get_journal_data(c.following) c.journal_pager = Page(journal, page=p, items_per_page=20) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render('journal/journal_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.journal_data return render('journal/journal.html')
def my_account(self): """ GET /_admin/my_account Displays info about my account """ # url('admin_settings_my_account') c.user = User.get(self.rhodecode_user.user_id) all_repos = Session().query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() c.user_repos = ScmModel().get_repos(all_repos) if c.user.username == 'default': h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users')) defaults = c.user.get_dict() c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=defaults, encoding="UTF-8", force_defaults=False ) return render('admin/users/user_edit_my_account.html')
def index(self): users_log = UserLog.query()\ .options(joinedload(UserLog.user))\ .options(joinedload(UserLog.repository)) #FILTERING c.search_term = request.GET.get('filter') try: users_log = _journal_filter(users_log, c.search_term) except: # we want this to crash for now raise users_log = users_log.order_by(UserLog.action_date.desc()) p = safe_int(request.params.get('page', 1), 1) def url_generator(**kw): return url.current(filter=c.search_term, **kw) c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator) c.log_data = render('admin/admin_log.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.log_data return render('admin/admin.html')
def followers(self, repo_name): p = int(request.params.get("page", 1)) repo_id = c.rhodecode_db_repo.repo_id d = UserFollowing.get_repo_followers(repo_id).order_by(UserFollowing.follows_from) c.followers_pager = Page(d, page=p, items_per_page=20) c.followers_data = render("/followers/followers_data.html") if request.environ.get("HTTP_X_PARTIAL_XHR"): return c.followers_data return render("/followers/followers.html")
def forks(self, repo_name): p = int(request.params.get('page', 1)) repo_id = c.rhodecode_db_repo.repo_id d = Repository.get_repo_forks(repo_id) c.forks_pager = Page(d, page=p, items_per_page=20) c.forks_data = render('/forks/forks_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.forks_data return render('/forks/forks.html')
def show_all(self, repo_name): c.pull_requests = PullRequestModel().get_all(repo_name) c.repo_name = repo_name p = safe_int(request.GET.get('page', 1), 1) c.pullrequests_pager = Page(c.pull_requests, page=p, items_per_page=10) c.pullrequest_data = render('/pullrequests/pullrequest_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.pullrequest_data return render('/pullrequests/pullrequest_show_all.html')
def followers(self, repo_name): p = safe_int(request.GET.get('page', 1), 1) repo_id = c.rhodecode_db_repo.repo_id d = UserFollowing.get_repo_followers(repo_id)\ .order_by(UserFollowing.follows_from) c.followers_pager = Page(d, page=p, items_per_page=20) c.followers_data = render('/followers/followers_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.followers_data return render('/followers/followers.html')
def index(self): users_log = self.sa.query(UserLog)\ .options(joinedload(UserLog.user))\ .options(joinedload(UserLog.repository))\ .order_by(UserLog.action_date.desc()) p = int(request.params.get('page', 1)) c.users_log = Page(users_log, page=p, items_per_page=10) c.log_data = render('admin/admin_log.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.log_data return render('admin/admin.html')
def index(self, repo_name): p = int(request.params.get('page', 1)) size = int(request.params.get('size', 20)) def url_generator(**kw): return url('shortlog_home', repo_name=repo_name, size=size, **kw) c.repo_changesets = RepoPage(c.rhodecode_repo, page=p, items_per_page=size, url=url_generator) c.shortlog_data = render('shortlog/shortlog_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.shortlog_data r = render('shortlog/shortlog.html') return r
def register(self): user_model = UserModel() c.auto_active = False for perm in user_model.get_by_username('default', cache=False).user_perms: if perm.permission.permission_name == 'hg.register.auto_activate': c.auto_active = True break if request.POST: register_form = RegisterForm()() try: form_result = register_form.to_python(dict(request.POST)) form_result['active'] = c.auto_active user_model.create_registration(form_result) h.flash(_('You have successfully registered into rhodecode'), category='success') return redirect(url('login_home')) except formencode.Invalid, errors: return htmlfill.render( render('/register.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def update(self, id): """PUT /defaults/id: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('default', id=ID), # method='put') # url('default', id=ID) _form = DefaultsForm()() try: form_result = _form.to_python(dict(request.POST)) for k, v in form_result.iteritems(): setting = RhodeCodeSetting.get_by_name_or_create(k) setting.app_settings_value = v Session().add(setting) Session().commit() h.flash(_('Default settings updated successfully'), category='success') except formencode.Invalid, errors: defaults = errors.value return htmlfill.render( render('admin/defaults/defaults.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def edit(self, id, format='html'): """GET /permissions/id/edit: Form to edit an existing item""" #url('edit_permission', id=ID) c.perms_choices = self.perms_choices c.register_choices = self.register_choices c.create_choices = self.create_choices if id == 'default': default_user = UserModel().get_by_username('default') defaults = {'_method': 'put', 'anonymous': default_user.active} for p in default_user.user_perms: if p.permission.permission_name.startswith('repository.'): defaults['default_perm'] = p.permission.permission_name if p.permission.permission_name.startswith('hg.register.'): defaults['default_register'] = p.permission.permission_name if p.permission.permission_name.startswith('hg.create.'): defaults['default_create'] = p.permission.permission_name return htmlfill.render( render('admin/permissions/permissions.html'), defaults=defaults, encoding="UTF-8", force_defaults=True,) else: return redirect(url('admin_home'))
def update(self, id): """PUT /permissions/id: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('permission', id=ID), # method='put') # url('permission', id=ID) permission_model = PermissionModel() _form = DefaultPermissionsForm([x[0] for x in self.perms_choices], [x[0] for x in self.register_choices], [x[0] for x in self.create_choices])() try: form_result = _form.to_python(dict(request.POST)) form_result.update({'perm_user_name': id}) permission_model.update(form_result) h.flash(_('Default permissions updated successfully'), category='success') except formencode.Invalid, errors: c.perms_choices = self.perms_choices c.register_choices = self.register_choices c.create_choices = self.create_choices defaults = errors.value return htmlfill.render( render('admin/permissions/permissions.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() form_result = {} try: form_result = _form.to_python(dict(request.POST)) # create fork is done sometimes async on celery, db transaction # management is handled there. RepoModel().create_fork(form_result, self.rhodecode_user.user_id) h.flash(_('forked %s repository as %s') \ % (repo_name, form_result['repo_name']), category='success') except formencode.Invalid, errors: c.new_repo = errors.value['repo_name'] return htmlfill.render( render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def create_repository(self): """GET /_admin/create_repository: Form to create a new item""" new_repo = request.GET.get('repo', '') parent_group = request.GET.get('parent_group') if not HasPermissionAny('hg.admin', 'hg.create.repository')(): #you're not super admin nor have global create permissions, #but maybe you have at least write permission to a parent group ? _gr = RepoGroup.get(parent_group) gr_name = _gr.group_name if _gr else None if not HasReposGroupPermissionAny('group.admin', 'group.write')(group_name=gr_name): raise HTTPForbidden acl_groups = GroupList(RepoGroup.query().all(), perm_set=['group.write', 'group.admin']) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.new_repo = repo_name_slug(new_repo) ## apply the defaults from defaults page defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True) if parent_group: defaults.update({'repo_group': parent_group}) return htmlfill.render( render('admin/repos/repo_add.html'), defaults=defaults, errors={}, prefix_error=False, encoding="UTF-8" )
def comment(self, repo_name, revision): status = request.POST.get('changeset_status') change_status = request.POST.get('change_changeset_status') text = request.POST.get('text') if status and change_status: text = text or (_('Status change -> %s') % ChangesetStatus.get_status_lbl(status)) c.co = comm = ChangesetCommentsModel().create( text=text, repo=c.rhodecode_db_repo.repo_id, user=c.rhodecode_user.user_id, revision=revision, f_path=request.POST.get('f_path'), line_no=request.POST.get('line'), status_change=(ChangesetStatus.get_status_lbl(status) if status and change_status else None) ) # get status if set ! if status and change_status: # if latest status was from pull request and it's closed # disallow changing status ! # dont_allow_on_closed_pull_request = True ! try: ChangesetStatusModel().set_status( c.rhodecode_db_repo.repo_id, status, c.rhodecode_user.user_id, comm, revision=revision, dont_allow_on_closed_pull_request=True ) except StatusChangeOnClosedPullRequestError: log.error(traceback.format_exc()) msg = _('Changing status on a changeset associated with ' 'a closed pull request is not allowed') h.flash(msg, category='warning') return redirect(h.url('changeset_home', repo_name=repo_name, revision=revision)) action_logger(self.rhodecode_user, 'user_commented_revision:%s' % revision, c.rhodecode_db_repo, self.ip_addr, self.sa) Session().commit() if not request.environ.get('HTTP_X_PARTIAL_XHR'): return redirect(h.url('changeset_home', repo_name=repo_name, revision=revision)) #only ajax below data = { 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))), } if comm: data.update(comm.get_dict()) data.update({'rendered_text': render('changeset/changeset_comment_block.html')}) return data
def update(self, id): """PUT /users/id: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('update_user', id=ID), # method='put') # url('user', id=ID) user_model = UserModel() c.user = user_model.get(id) _form = UserForm(edit=True, old_data={'user_id': id, 'email': c.user.email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) user_model.update(id, form_result) h.flash(_('User updated successfully'), category='success') Session.commit() except formencode.Invalid, errors: e = errors.error_dict or {} perm = Permission.get_by_key('hg.create.repository') e.update({'create_repo_perm': user_model.has_perm(id, perm)}) return htmlfill.render( render('admin/users/user_edit.html'), defaults=errors.value, errors=e, prefix_error=False, encoding="UTF-8")
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() form_result = {} try: form_result = _form.to_python(dict(request.POST)) # an approximation that is better than nothing if not RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE).ui_active: form_result['update_after_clone'] = False # create fork is done sometimes async on celery, db transaction # management is handled there. RepoModel().create_fork(form_result, self.rhodecode_user.user_id) fork_url = h.link_to(form_result['repo_name_full'], h.url('summary_home', repo_name=form_result['repo_name_full'])) h.flash(h.literal(_('Forked repository %s as %s') \ % (repo_name, fork_url)), category='success') except formencode.Invalid, errors: c.new_repo = errors.value['repo_name'] return htmlfill.render( render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def create(self): """POST /repos_groups: Create a new item""" # url('repos_groups') self.__load_defaults() # permissions for can create group based on parent_id are checked # here in the Form repos_group_form = ReposGroupForm(available_groups= map(lambda k: unicode(k[0]), c.repo_groups))() try: form_result = repos_group_form.to_python(dict(request.POST)) ReposGroupModel().create( group_name=form_result['group_name'], group_description=form_result['group_description'], parent=form_result['group_parent_id'], owner=self.rhodecode_user.user_id ) Session().commit() h.flash(_('Created repository group %s') \ % form_result['group_name'], category='success') #TODO: in futureaction_logger(, '', '', '', self.sa) except formencode.Invalid, errors: return htmlfill.render( render('admin/repos_groups/repos_groups_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def show(self, group_name, format='html'): """GET /repos_groups/group_name: Show a specific item""" # url('repos_group', group_name=GROUP_NAME) c.group = c.repos_group = ReposGroupModel()._get_repo_group(group_name) c.group_repos = c.group.repositories.all() #overwrite our cached list with current filter gr_filter = c.group_repos c.repo_cnt = 0 groups = RepoGroup.query().order_by(RepoGroup.group_name)\ .filter(RepoGroup.group_parent_id == c.group.group_id).all() c.groups = self.scm_model.get_repos_groups(groups) c.repos_list = Repository.query()\ .filter(Repository.group_id == c.group.group_id)\ .order_by(func.lower(Repository.repo_name))\ .all() repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list, admin=False) #json used to render the grid c.data = json.dumps(repos_data) return render('admin/repos_groups/repos_groups.html')
def edit(self, id, format='html'): """GET /users/id/edit: Form to edit an existing item""" # url('edit_user', id=ID) c.user = User.get_or_404(id) if c.user.username == 'default': h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr) c.user.permissions = {} c.granted_permissions = UserModel().fill_perms(c.user)\ .permissions['global'] c.user_email_map = UserEmailMap.query()\ .filter(UserEmailMap.user == c.user).all() c.user_ip_map = UserIpMap.query()\ .filter(UserIpMap.user == c.user).all() user_model = UserModel() c.ldap_dn = c.user.ldap_dn defaults = c.user.get_dict() defaults.update({ 'create_repo_perm': user_model.has_perm(id, 'hg.create.repository'), 'fork_repo_perm': user_model.has_perm(id, 'hg.fork.repository'), }) return htmlfill.render( render('admin/users/user_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def update(self, repo_name): """ PUT /repos/repo_name: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('repo', repo_name=ID), # method='put') # url('repo', repo_name=ID) self.__load_defaults() repo_model = RepoModel() changed_name = repo_name _form = RepoForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices)() try: form_result = _form.to_python(dict(request.POST)) repo = repo_model.update(repo_name, form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully' % repo_name), category='success') changed_name = repo.repo_name action_logger(self.rhodecode_user, 'admin_updated_repo', changed_name, '', self.sa) Session.commit() except formencode.Invalid, errors: defaults = self.__load_data(repo_name) defaults.update(errors.value) return htmlfill.render( render('admin/repos/repo_edit.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def update(self, repo_name): self.__load_defaults() repo_model = RepoModel() changed_name = repo_name #override the choices with extracted revisions ! choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name) c.landing_revs_choices = choices _form = RepoSettingsForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() try: form_result = _form.to_python(dict(request.POST)) repo_model.update(repo_name, **form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully') % repo_name, category='success') changed_name = form_result['repo_name_full'] action_logger(self.rhodecode_user, 'user_updated_repo', changed_name, self.ip_addr, self.sa) Session().commit() except formencode.Invalid, errors: defaults = self.__load_data(repo_name) defaults.update(errors.value) return htmlfill.render( render('settings/repo_settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def ldap_settings(self): """POST ldap create and store ldap settings""" _form = LdapSettingsForm([x[0] for x in self.tls_reqcert_choices], [x[0] for x in self.search_scope_choices], [x[0] for x in self.tls_kind_choices])() try: form_result = _form.to_python(dict(request.POST)) try: for k, v in form_result.items(): if k.startswith('ldap_'): setting = RhodeCodeSettings.get_by_name(k) setting.app_settings_value = v self.sa.add(setting) self.sa.commit() h.flash(_('Ldap settings updated successfully'), category='success') except (DatabaseError,): raise except LdapImportError: h.flash(_('Unable to activate ldap. The "python-ldap" library ' 'is missing.'), category='warning') except formencode.Invalid, errors: e = errors.error_dict or {} return htmlfill.render( render('admin/ldap/ldap.html'), defaults=errors.value, errors=e, prefix_error=False, encoding="UTF-8")
def index(self): users_log = ( UserLog.query() .options(joinedload(UserLog.user)) .options(joinedload(UserLog.repository)) .order_by(UserLog.action_date.desc()) ) p = safe_int(request.params.get("page", 1), 1) c.users_log = Page(users_log, page=p, items_per_page=10) c.log_data = render("admin/admin_log.html") if request.environ.get("HTTP_X_PARTIAL_XHR"): return c.log_data return render("admin/admin.html")
def annotate(self, repo_name, revision, f_path): c.cs = self.__get_cs_or_redirect(revision, repo_name) c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path) c.file_history = self._get_node_history(c.cs, f_path) c.f_path = f_path return render('files/files_annotate.html')
def edit(self, id, format='html'): """GET /users_groups/id/edit: Form to edit an existing item""" # url('edit_users_group', id=ID) c.users_group = UsersGroup.get_or_404(id) c.users_group.permissions = {} c.group_members_obj = [x.user for x in c.users_group.members] c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] c.available_members = [(x.user_id, x.username) for x in User.query().all()] ug_model = UsersGroupModel() defaults = c.users_group.get_dict() defaults.update({ 'create_repo_perm': ug_model.has_perm(c.users_group, 'hg.create.repository'), 'fork_repo_perm': ug_model.has_perm(c.users_group, 'hg.fork.repository'), }) return htmlfill.render( render('admin/users_groups/users_group_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def edit(self, group_name, format='html'): """GET /repos_groups/group_name/edit: Form to edit an existing item""" # url('edit_repos_group', group_name=GROUP_NAME) c.repos_group = ReposGroupModel()._get_repo_group(group_name) #we can only allow moving empty group if it's already a top-level #group, ie has no parents, or we're admin if HasPermissionAll('hg.admin')('group edit'): #we're global admin, we're ok and we can create TOP level groups allow_empty_group = True elif not c.repos_group.parent_group: allow_empty_group = True else: allow_empty_group = False self.__load_defaults(allow_empty_group=allow_empty_group, exclude_group_ids=[c.repos_group.group_id]) defaults = self.__load_data(c.repos_group.group_id) return htmlfill.render( render('admin/repos_groups/repos_groups_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def index(self, format='html'): """GET /_admin/notifications: All items in the collection""" # url('notifications') c.user = self.rhodecode_user notif = NotificationModel().get_for_user(self.rhodecode_user.user_id, filter_=request.GET.getall('type')) p = safe_int(request.GET.get('page', 1), 1) c.notifications = Page(notif, page=p, items_per_page=10) c.pull_request_type = Notification.TYPE_PULL_REQUEST c.comment_type = [Notification.TYPE_CHANGESET_COMMENT, Notification.TYPE_PULL_REQUEST_COMMENT] _current_filter = request.GET.getall('type') c.current_filter = 'all' if _current_filter == [c.pull_request_type]: c.current_filter = 'pull_request' elif _current_filter == c.comment_type: c.current_filter = 'comment' return render('admin/notifications/notifications.html')
def permission_application_update(self): c.active = 'application' self.__load_data() _form = ApplicationPermissionsForm( [x[0] for x in c.register_choices], [x[0] for x in c.extern_activate_choices])() try: form_result = _form.to_python(dict(request.POST)) form_result.update({'perm_user_name': User.DEFAULT_USER}) PermissionModel().update_application_permissions(form_result) settings = [ ('register_message', 'default_register_message'), ] for setting, form_key in settings: sett = SettingsModel().create_or_update_setting( setting, form_result[form_key]) Session().add(sett) Session().commit() h.flash(_('Application permissions updated successfully'), category='success') except formencode.Invalid as errors: defaults = errors.value return htmlfill.render( render('admin/permissions/permissions.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.exception("Exception during update of permissions") h.flash(_('Error occurred during update of permissions'), category='error') return redirect(url('admin_permissions_application'))
def edit_perms(self, user_group_id): user_group_id = safe_int(user_group_id) c.user_group = UserGroup.get_or_404(user_group_id) c.active = 'perms' defaults = {} # fill user group users for p in c.user_group.user_user_group_to_perm: defaults.update( {'u_perm_%s' % p.user.user_id: p.permission.permission_name}) for p in c.user_group.user_group_user_group_to_perm: defaults.update({ 'g_perm_%s' % p.user_group.users_group_id: p.permission.permission_name }) return htmlfill.render( render('admin/user_groups/user_group_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def create(self): """POST /users_groups: Create a new item""" # url('users_groups') users_group_form = UserGroupForm()() try: form_result = users_group_form.to_python(dict(request.POST)) UserGroupModel().create(name=form_result['users_group_name'], active=form_result['users_group_active']) gr = form_result['users_group_name'] action_logger(self.rhodecode_user, 'admin_created_users_group:%s' % gr, None, self.ip_addr, self.sa) h.flash(_('Created user group %s') % gr, category='success') Session().commit() except formencode.Invalid, errors: return htmlfill.render( render('admin/users_groups/users_group_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def edit(self, group_name): """GET /repo_groups/group_name/edit: Form to edit an existing item""" # url('edit_repo_group', group_name=GROUP_NAME) c.active = 'settings' c.repo_group = RepoGroupModel()._get_repo_group(group_name) # we can only allow moving empty group if it's already a top-level # group, ie has no parents, or we're admin can_create_in_root = self._can_create_repo_group() show_root_location = can_create_in_root if not c.repo_group.parent_group: # this group don't have a parrent so we should show empty value show_root_location = True self.__load_defaults(allow_empty_group=show_root_location, repo_group=c.repo_group) defaults = self.__load_data(c.repo_group.group_id) return htmlfill.render( render('admin/repo_groups/repo_group_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def create(self): """ POST /repos: Create a new item""" # url('repos') self.__load_defaults() form_result = {} task_id = None try: # CanWriteToGroup validators checks permissions of this POST form_result = RepoForm(repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)()\ .to_python(dict(request.POST)) # create is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create(form_result, c.rhodecode_user.user_id) from celery.result import BaseAsyncResult if isinstance(task, BaseAsyncResult): task_id = task.task_id except formencode.Invalid as errors: c.personal_repo_group = RepoGroup.get_by_group_name( c.rhodecode_user.username) return htmlfill.render(render('admin/repos/repo_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception as e: msg = self._log_creation_exception(e, form_result.get('repo_name')) h.flash(msg, category='error') return redirect(url('home')) return redirect( h.url('repo_creating_home', repo_name=form_result['repo_name_full'], task_id=task_id))
def settings_global_update(self): """POST /admin/settings/global: All items in the collection""" # url('admin_settings_global') c.active = 'global' application_form = ApplicationSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render(render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: settings = [ ('title', 'rhodecode_title'), ('realm', 'rhodecode_realm'), ('pre_code', 'rhodecode_pre_code'), ('post_code', 'rhodecode_post_code'), ('captcha_public_key', 'rhodecode_captcha_public_key'), ('captcha_private_key', 'rhodecode_captcha_private_key'), ] for setting, form_key in settings: sett = SettingsModel().create_or_update_setting( setting, form_result[form_key]) Session().add(sett) Session().commit() SettingsModel().invalidate_settings_cache() h.flash(_('Updated application settings'), category='success') except Exception: log.exception("Exception while updating application settings") h.flash(_('Error occurred during updating application settings'), category='error') return redirect(url('admin_settings_global'))
def index(self, format='html'): """GET /admin/gists: All items in the collection""" # url('gists') c.show_private = request.GET.get( 'private') and c.rhodecode_user.username != 'default' c.show_public = request.GET.get( 'public') and c.rhodecode_user.username != 'default' gists = Gist().query()\ .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\ .order_by(Gist.created_on.desc()) if c.show_private: c.gists = gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\ .filter(Gist.gist_owner == c.rhodecode_user.user_id) elif c.show_public: c.gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\ .filter(Gist.gist_owner == c.rhodecode_user.user_id) else: c.gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) p = safe_int(request.GET.get('page', 1), 1) c.gists_pager = Page(c.gists, page=p, items_per_page=10) return render('admin/gists/index.html')
def show(self, id, format='html'): """GET /repos_groups/id: Show a specific item""" # url('repos_group', id=ID) c.group = RepoGroup.get(id) if c.group: c.group_repos = c.group.repositories.all() else: return redirect(url('home')) #overwrite our cached list with current filter gr_filter = c.group_repos c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter) c.repos_list = c.cached_repo_list c.repo_cnt = 0 c.groups = self.sa.query(RepoGroup).order_by(RepoGroup.group_name)\ .filter(RepoGroup.group_parent_id == id).all() return render('admin/repos_groups/repos_groups.html')
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() form_result = {} task_id = None try: form_result = _form.to_python(dict(request.POST)) # create fork is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create_fork( form_result, c.rhodecode_user.user_id) from celery.result import BaseAsyncResult if isinstance(task, BaseAsyncResult): task_id = task.task_id except formencode.Invalid as errors: c.new_repo = errors.value['repo_name'] return htmlfill.render( render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.exception( u'Exception while trying to fork the repository %s', repo_name) msg = ( _('An error occurred during repository forking %s') % (repo_name, )) h.flash(msg, category='error') return redirect(h.url('repo_creating_home', repo_name=form_result['repo_name_full'], task_id=task_id))
def show(self, notification_id, format='html'): """GET /_admin/notifications/id: Show a specific item""" # url('notification', notification_id=ID) c.user = self.rhodecode_user no = Notification.get(notification_id) owner = lambda: (no.notifications_to_users.user.user_id == c.user. user_id) if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner): unotification = NotificationModel()\ .get_user_notification(c.user.user_id, no) # if this association to user is not valid, we don't want to show # this message if unotification: if unotification.read is False: unotification.mark_as_read() Session.commit() c.notification = no return render('admin/notifications/show_notification.html') return redirect(url('notifications'))
def edit_home(self, repo_name, revision, f_path): commit_id = revision repo = c.rhodecode_db_repo if repo.enable_locking and repo.locked[0]: h.flash( _('This repository has been locked by %s on %s') % (h.person_by_id(repo.locked[0]), h.format_date(h.time_to_datetime(repo.locked[1]))), 'warning') return redirect( h.url('files_home', repo_name=repo_name, revision='tip')) if not self._is_valid_head(commit_id, repo.scm_instance()): h.flash(_('You can only edit files with revision ' 'being a valid branch '), category='warning') return redirect( h.url('files_home', repo_name=repo_name, revision='tip', f_path=f_path)) c.commit = self.__get_commit_or_redirect(commit_id, repo_name) c.file = self.__get_filenode_or_redirect(repo_name, c.commit, f_path) if c.file.is_binary: return redirect( url('files_home', repo_name=c.repo_name, revision=c.commit.raw_id, f_path=f_path)) c.default_message = _('Edited file %s via RhodeCode Enterprise') % ( f_path) c.f_path = f_path return render('files/files_edit.html')
def show_all(self, repo_name): # filter types c.active = 'open' c.source = str2bool(request.GET.get('source')) c.closed = str2bool(request.GET.get('closed')) c.my = str2bool(request.GET.get('my')) c.awaiting_review = str2bool(request.GET.get('awaiting_review')) c.awaiting_my_review = str2bool(request.GET.get('awaiting_my_review')) c.repo_name = repo_name opened_by = None if c.my: c.active = 'my' opened_by = [c.rhodecode_user.user_id] statuses = [PullRequest.STATUS_NEW, PullRequest.STATUS_OPEN] if c.closed: c.active = 'closed' statuses = [PullRequest.STATUS_CLOSED] if c.awaiting_review and not c.source: c.active = 'awaiting' if c.source and not c.awaiting_review: c.active = 'source' if c.awaiting_my_review: c.active = 'awaiting_my' data = self._get_pull_requests_list(repo_name=repo_name, opened_by=opened_by, statuses=statuses) if not request.is_xhr: c.data = json.dumps(data['data']) c.records_total = data['recordsTotal'] return render('/pullrequests/pullrequests.html') else: return json.dumps(data)
def my_account_update(self): """PUT /_admin/my_account_update: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('admin_settings_my_account_update'), # method='put') # url('admin_settings_my_account_update', id=ID) user_model = UserModel() uid = self.rhodecode_user.user_id _form = UserForm(edit=True, old_data={ 'user_id': uid, 'email': self.rhodecode_user.email })() form_result = {} try: form_result = _form.to_python(dict(request.POST)) user_model.update_my_account(uid, form_result) h.flash(_('Your account was updated successfully'), category='success') Session.commit() except formencode.Invalid, errors: c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name))\ .all() c.user_repos = ScmModel().get_repos(all_repos) return htmlfill.render( render('admin/users/user_edit_my_account.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def my_account(self): """ GET /_admin/my_account Displays info about my account """ # url('admin_settings_my_account') c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() c.user_repos = ScmModel().get_repos(all_repos) if c.user.username == 'default': h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users')) defaults = c.user.get_dict() return htmlfill.render(render('admin/users/user_edit_my_account.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def show(self, gist_id, format='html', revision='tip', f_path=None): """GET /admin/gists/gist_id: Show a specific item""" # url('gist', gist_id=ID) c.gist = Gist.get_or_404(gist_id) #check if this gist is not expired if c.gist.gist_expires != -1: if time.time() > c.gist.gist_expires: log.error('Gist expired at %s' % (time_to_datetime(c.gist.gist_expires))) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files(gist_id) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() if format == 'raw': content = '\n\n'.join([ f.content for f in c.files if (f_path is None or f.path == f_path) ]) response.content_type = 'text/plain' return content return render('admin/gists/show.html')
def create(self): """POST /repos_groups: Create a new item""" # url('repos_groups') self.__load_defaults() repos_group_form = ReposGroupForm( available_groups=c.repo_groups_choices)() try: form_result = repos_group_form.to_python(dict(request.POST)) ReposGroupModel().create( group_name=form_result['group_name'], group_description=form_result['group_description'], parent=form_result['group_parent_id']) Session.commit() h.flash(_('created repos group %s') \ % form_result['group_name'], category='success') #TODO: in futureaction_logger(, '', '', '', self.sa) except formencode.Invalid, errors: return htmlfill.render( render('admin/repos_groups/repos_groups_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def edit_statistics_form(self, repo_name): """GET /repo_name/settings: Form to edit an existing item""" # url('edit_repo', repo_name=ID) c.repo_info = self._load_repo(repo_name) repo = c.repo_info.scm_instance() if c.repo_info.stats: # this is on what revision we ended up so we add +1 for count last_rev = c.repo_info.stats.stat_on_revision + 1 else: last_rev = 0 c.stats_revision = last_rev c.repo_last_rev = repo.count() if last_rev == 0 or c.repo_last_rev == 0: c.stats_percentage = 0 else: c.stats_percentage = '%.2f' % ((float( (last_rev)) / c.repo_last_rev) * 100) c.active = 'statistics' return render('admin/repos/repo_edit.html')
def edit(self, group_name, format='html'): """GET /repos_groups/group_name/edit: Form to edit an existing item""" # url('edit_repos_group', group_name=GROUP_NAME) c.repos_group = ReposGroupModel()._get_repo_group(group_name) #we can only allow moving empty group if it's already a top-level #group, ie has no parents, or we're admin if HasPermissionAll('hg.admin')('group edit'): #we're global admin, we're ok and we can create TOP level groups allow_empty_group = True elif not c.repos_group.parent_group: allow_empty_group = True else: allow_empty_group = False self.__load_defaults(allow_empty_group=allow_empty_group, exclude_group_ids=[c.repos_group.group_id]) defaults = self.__load_data(c.repos_group.group_id) return htmlfill.render( render('admin/repos_groups/repos_groups_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def permission_global_update(self): c.active = 'global' self.__load_data() _form = UserPermissionsForm( [x[0] for x in c.repo_create_choices], [x[0] for x in c.repo_create_on_write_choices], [x[0] for x in c.repo_group_create_choices], [x[0] for x in c.user_group_create_choices], [x[0] for x in c.fork_choices], [x[0] for x in c.inherit_default_permission_choices])() try: form_result = _form.to_python(dict(request.POST)) form_result.update({'perm_user_name': User.DEFAULT_USER}) PermissionModel().update_user_permissions(form_result) Session().commit() h.flash(_('Global permissions updated successfully'), category='success') except formencode.Invalid as errors: defaults = errors.value return htmlfill.render( render('admin/permissions/permissions.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.exception("Exception during update of permissions") h.flash(_('Error occurred during update of permissions'), category='error') return redirect(url('admin_permissions_global'))
def permission_application(self): c.active = 'application' self.__load_data() c.user = User.get_default_user() # TODO: johbo: The default user might be based on outdated state which # has been loaded from the cache. A call to refresh() ensures that the # latest state from the database is used. Session().refresh(c.user) app_settings = SettingsModel().get_all_settings() defaults = { 'anonymous': c.user.active, 'default_register_message': app_settings.get('rhodecode_register_message') } defaults.update(c.user.get_default_perms()) return htmlfill.render(render('admin/permissions/permissions.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def edit(self, repo_name, revision, f_path): repo = c.rhodecode_db_repo if repo.enable_locking and repo.locked[0]: h.flash(_('This repository is has been locked by %s on %s') % (h.person_by_id(repo.locked[0]), h.fmt_date(h.time_to_datetime(repo.locked[1]))), 'warning') return redirect(h.url('files_home', repo_name=repo_name, revision='tip')) # check if revision is a branch identifier- basically we cannot # create multiple heads via file editing _branches = repo.scm_instance.branches # check if revision is a branch name or branch hash if revision not in _branches.keys() + _branches.values(): h.flash(_('You can only edit files with revision ' 'being a valid branch '), category='warning') return redirect(h.url('files_home', repo_name=repo_name, revision='tip', f_path=f_path)) r_post = request.POST c.cs = self.__get_cs_or_redirect(revision, repo_name) c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path) if c.file.is_binary: return redirect(url('files_home', repo_name=c.repo_name, revision=c.cs.raw_id, f_path=f_path)) c.default_message = _('Edited file %s via RhodeCode') % (f_path) c.f_path = f_path if r_post: old_content = c.file.content sl = old_content.splitlines(1) first_line = sl[0] if sl else '' # modes: 0 - Unix, 1 - Mac, 2 - DOS mode = detect_mode(first_line, 0) content = convert_line_endings(r_post.get('content'), mode) message = r_post.get('message') or c.default_message author = self.rhodecode_user.full_contact if content == old_content: h.flash(_('No changes'), category='warning') return redirect(url('changeset_home', repo_name=c.repo_name, revision='tip')) try: self.scm_model.commit_change(repo=c.rhodecode_repo, repo_name=repo_name, cs=c.cs, user=self.rhodecode_user.user_id, author=author, message=message, content=content, f_path=f_path) h.flash(_('Successfully committed to %s') % f_path, category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during commit'), category='error') return redirect(url('changeset_home', repo_name=c.repo_name, revision='tip')) return render('files/files_edit.html')
_hist = [] c.file_history = [] if c.load_full_history: c.file_history, _hist = self._get_node_history(c.changeset, f_path) c.authors = [] for a in set([x.author for x in _hist]): c.authors.append((h.email(a), h.person(a))) else: c.authors = c.file_history = [] except RepositoryError, e: h.flash(str(e), category='error') raise HTTPNotFound() if request.environ.get('HTTP_X_PARTIAL_XHR'): return render('files/files_ypjax.html') return render('files/files.html') @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin') def history(self, repo_name, revision, f_path, annotate=False): if request.environ.get('HTTP_X_PARTIAL_XHR'): c.changeset = self.__get_cs_or_redirect(revision, repo_name) c.f_path = f_path c.annotate = annotate c.file = c.changeset.get_node(f_path) if c.file.is_file(): file_last_cs = c.file.last_changeset c.file_changeset = (c.changeset
class ChangesetController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin') def __before__(self): super(ChangesetController, self).__before__() c.affected_files_cut_off = 60 def index(self, revision): c.anchor_url = anchor_url c.ignorews_url = _ignorews_url c.context_url = _context_url limit_off = request.GET.get('fulldiff') #get ranges of revisions if preset rev_range = revision.split('...')[:2] enable_comments = True try: if len(rev_range) == 2: enable_comments = False rev_start = rev_range[0] rev_end = rev_range[1] rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start, end=rev_end) else: rev_ranges = [c.rhodecode_repo.get_changeset(revision)] c.cs_ranges = list(rev_ranges) if not c.cs_ranges: raise RepositoryError('Changeset range returned empty result') except (RepositoryError, ChangesetDoesNotExistError, Exception), e: log.error(traceback.format_exc()) h.flash(str(e), category='warning') return redirect(url('home')) c.changes = OrderedDict() c.lines_added = 0 # count of lines added c.lines_deleted = 0 # count of lines removes cumulative_diff = 0 c.cut_off = False # defines if cut off limit is reached c.comments = [] c.inline_comments = [] c.inline_cnt = 0 # Iterate over ranges (default changeset view is always one changeset) for changeset in c.cs_ranges: c.comments.extend(ChangesetCommentsModel()\ .get_comments(c.rhodecode_db_repo.repo_id, changeset.raw_id)) inlines = ChangesetCommentsModel()\ .get_inline_comments(c.rhodecode_db_repo.repo_id, changeset.raw_id) c.inline_comments.extend(inlines) c.changes[changeset.raw_id] = [] try: changeset_parent = changeset.parents[0] except IndexError: changeset_parent = None #================================================================== # ADDED FILES #================================================================== for node in changeset.added: fid = h.FID(revision, node.path) line_context_lcl = get_line_ctx(fid, request.GET) ign_whitespace_lcl = get_ignore_ws(fid, request.GET) lim = self.cut_off_limit if cumulative_diff > self.cut_off_limit: lim = -1 if limit_off is None else None size, cs1, cs2, diff, st = wrapped_diff( filenode_old=None, filenode_new=node, cut_off_limit=lim, ignore_whitespace=ign_whitespace_lcl, line_context=line_context_lcl, enable_comments=enable_comments) cumulative_diff += size c.lines_added += st[0] c.lines_deleted += st[1] c.changes[changeset.raw_id].append( ('added', node, diff, cs1, cs2, st)) #================================================================== # CHANGED FILES #================================================================== for node in changeset.changed: try: filenode_old = changeset_parent.get_node(node.path) except ChangesetError: log.warning('Unable to fetch parent node for diff') filenode_old = FileNode(node.path, '', EmptyChangeset()) fid = h.FID(revision, node.path) line_context_lcl = get_line_ctx(fid, request.GET) ign_whitespace_lcl = get_ignore_ws(fid, request.GET) lim = self.cut_off_limit if cumulative_diff > self.cut_off_limit: lim = -1 if limit_off is None else None size, cs1, cs2, diff, st = wrapped_diff( filenode_old=filenode_old, filenode_new=node, cut_off_limit=lim, ignore_whitespace=ign_whitespace_lcl, line_context=line_context_lcl, enable_comments=enable_comments) cumulative_diff += size c.lines_added += st[0] c.lines_deleted += st[1] c.changes[changeset.raw_id].append( ('changed', node, diff, cs1, cs2, st)) #================================================================== # REMOVED FILES #================================================================== for node in changeset.removed: c.changes[changeset.raw_id].append( ('removed', node, None, None, None, (0, 0))) # count inline comments for path, lines in c.inline_comments: for comments in lines.values(): c.inline_cnt += len(comments) if len(c.cs_ranges) == 1: c.changeset = c.cs_ranges[0] c.changes = c.changes[c.changeset.raw_id] return render('changeset/changeset.html') else: return render('changeset/changeset_range.html')
# get the history for the file ! tip_cs = c.rhodecode_repo.get_changeset() try: collection = tip_cs.get_file_history(f_path) except (NodeDoesNotExistError, ChangesetError): #this node is not present at tip ! try: cs = self.__get_cs_or_redirect(revision, repo_name) collection = cs.get_file_history(f_path) except RepositoryError, e: h.flash(str(e), category='warning') redirect(h.url('shortlog_home', repo_name=repo_name)) collection = list(reversed(collection)) c.repo_changesets = RepoPage(collection, page=p, items_per_page=size, url=url_generator) page_revisions = [x.raw_id for x in list(c.repo_changesets)] c.statuses = c.rhodecode_db_repo.statuses(page_revisions) if not c.repo_changesets: h.flash(_('There are no changesets yet'), category='warning') return redirect(url('summary_home', repo_name=repo_name)) c.shortlog_data = render('shortlog/shortlog_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.shortlog_data r = render('shortlog/shortlog.html') return r
class ChangesetController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin') def __before__(self): super(ChangesetController, self).__before__() c.affected_files_cut_off = 60 repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() def index(self, revision, method='show'): c.anchor_url = anchor_url c.ignorews_url = _ignorews_url c.context_url = _context_url c.fulldiff = fulldiff = request.GET.get('fulldiff') #get ranges of revisions if preset rev_range = revision.split('...')[:2] enable_comments = True try: if len(rev_range) == 2: enable_comments = False rev_start = rev_range[0] rev_end = rev_range[1] rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start, end=rev_end) else: rev_ranges = [c.rhodecode_repo.get_changeset(revision)] c.cs_ranges = list(rev_ranges) if not c.cs_ranges: raise RepositoryError('Changeset range returned empty result') except (RepositoryError, ChangesetDoesNotExistError, Exception), e: log.error(traceback.format_exc()) h.flash(str(e), category='error') raise HTTPNotFound() c.changes = OrderedDict() c.lines_added = 0 # count of lines added c.lines_deleted = 0 # count of lines removes c.changeset_statuses = ChangesetStatus.STATUSES c.comments = [] c.statuses = [] c.inline_comments = [] c.inline_cnt = 0 # Iterate over ranges (default changeset view is always one changeset) for changeset in c.cs_ranges: inlines = [] if method == 'show': c.statuses.extend([ChangesetStatusModel().get_status( c.rhodecode_db_repo.repo_id, changeset.raw_id)]) c.comments.extend(ChangesetCommentsModel()\ .get_comments(c.rhodecode_db_repo.repo_id, revision=changeset.raw_id)) #comments from PR st = ChangesetStatusModel().get_statuses( c.rhodecode_db_repo.repo_id, changeset.raw_id, with_revisions=True) # from associated statuses, check the pull requests, and # show comments from them prs = set([x.pull_request for x in filter(lambda x: x.pull_request != None, st)]) for pr in prs: c.comments.extend(pr.comments) inlines = ChangesetCommentsModel()\ .get_inline_comments(c.rhodecode_db_repo.repo_id, revision=changeset.raw_id) c.inline_comments.extend(inlines) c.changes[changeset.raw_id] = [] cs2 = changeset.raw_id cs1 = changeset.parents[0].raw_id if changeset.parents else EmptyChangeset() context_lcl = get_line_ctx('', request.GET) ign_whitespace_lcl = ign_whitespace_lcl = get_ignore_ws('', request.GET) _diff = c.rhodecode_repo.get_diff(cs1, cs2, ignore_whitespace=ign_whitespace_lcl, context=context_lcl) diff_limit = self.cut_off_limit if not fulldiff else None diff_processor = diffs.DiffProcessor(_diff, vcs=c.rhodecode_repo.alias, format='gitdiff', diff_limit=diff_limit) cs_changes = OrderedDict() if method == 'show': _parsed = diff_processor.prepare() c.limited_diff = False if isinstance(_parsed, LimitedDiffContainer): c.limited_diff = True for f in _parsed: st = f['stats'] if st[0] != 'b': c.lines_added += st[0] c.lines_deleted += st[1] fid = h.FID(changeset.raw_id, f['filename']) diff = diff_processor.as_html(enable_comments=enable_comments, parsed_lines=[f]) cs_changes[fid] = [cs1, cs2, f['operation'], f['filename'], diff, st] else: # downloads/raw we only need RAW diff nothing else diff = diff_processor.as_raw() cs_changes[''] = [None, None, None, None, diff, None] c.changes[changeset.raw_id] = cs_changes #sort comments by how they were generated c.comments = sorted(c.comments, key=lambda x: x.comment_id) # count inline comments for __, lines in c.inline_comments: for comments in lines.values(): c.inline_cnt += len(comments) if len(c.cs_ranges) == 1: c.changeset = c.cs_ranges[0] c.parent_tmpl = ''.join(['# Parent %s\n' % x.raw_id for x in c.changeset.parents]) if method == 'download': response.content_type = 'text/plain' response.content_disposition = 'attachment; filename=%s.diff' \ % revision[:12] return diff elif method == 'patch': response.content_type = 'text/plain' c.diff = safe_unicode(diff) return render('changeset/patch_changeset.html') elif method == 'raw': response.content_type = 'text/plain' return diff elif method == 'show': if len(c.cs_ranges) == 1: return render('changeset/changeset.html') else: return render('changeset/changeset_range.html')
def diff(self, repo_name, f_path): ignore_whitespace = request.GET.get('ignorews') == '1' line_context = request.GET.get('context', 3) diff1 = request.GET.get('diff1', '') diff2 = request.GET.get('diff2', '') c.action = request.GET.get('diff') c.no_changes = diff1 == diff2 c.f_path = f_path c.big_diff = False c.anchor_url = anchor_url c.ignorews_url = _ignorews_url c.context_url = _context_url c.changes = OrderedDict() c.changes[diff2] = [] #special case if we want a show rev only, it's impl here #to reduce JS and callbacks if request.GET.get('show_rev'): if str2bool(request.GET.get('annotate', 'False')): _url = url('files_annotate_home', repo_name=c.repo_name, revision=diff1, f_path=c.f_path) else: _url = url('files_home', repo_name=c.repo_name, revision=diff1, f_path=c.f_path) return redirect(_url) try: if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) try: node1 = c.changeset_1.get_node(f_path) if node1.is_dir(): raise NodeError('%s path is a %s not a file' % (node1, type(node1))) except NodeDoesNotExistError: c.changeset_1 = EmptyChangeset(cs=diff1, revision=c.changeset_1.revision, repo=c.rhodecode_repo) node1 = FileNode(f_path, '', changeset=c.changeset_1) else: c.changeset_1 = EmptyChangeset(repo=c.rhodecode_repo) node1 = FileNode(f_path, '', changeset=c.changeset_1) if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) try: node2 = c.changeset_2.get_node(f_path) if node2.is_dir(): raise NodeError('%s path is a %s not a file' % (node2, type(node2))) except NodeDoesNotExistError: c.changeset_2 = EmptyChangeset(cs=diff2, revision=c.changeset_2.revision, repo=c.rhodecode_repo) node2 = FileNode(f_path, '', changeset=c.changeset_2) else: c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo) node2 = FileNode(f_path, '', changeset=c.changeset_2) except (RepositoryError, NodeError): log.error(traceback.format_exc()) return redirect(url('files_home', repo_name=c.repo_name, f_path=f_path)) if c.action == 'download': _diff = diffs.get_gitdiff(node1, node2, ignore_whitespace=ignore_whitespace, context=line_context) diff = diffs.DiffProcessor(_diff, format='gitdiff') diff_name = '%s_vs_%s.diff' % (diff1, diff2) response.content_type = 'text/plain' response.content_disposition = ( 'attachment; filename=%s' % diff_name ) return diff.as_raw() elif c.action == 'raw': _diff = diffs.get_gitdiff(node1, node2, ignore_whitespace=ignore_whitespace, context=line_context) diff = diffs.DiffProcessor(_diff, format='gitdiff') response.content_type = 'text/plain' return diff.as_raw() else: fid = h.FID(diff2, node2.path) line_context_lcl = get_line_ctx(fid, request.GET) ign_whitespace_lcl = get_ignore_ws(fid, request.GET) lim = request.GET.get('fulldiff') or self.cut_off_limit _, cs1, cs2, diff, st = diffs.wrapped_diff(filenode_old=node1, filenode_new=node2, cut_off_limit=lim, ignore_whitespace=ign_whitespace_lcl, line_context=line_context_lcl, enable_comments=False) op = '' filename = node1.path cs_changes = { 'fid': [cs1, cs2, op, filename, diff, st] } c.changes = cs_changes return render('files/file_diff.html')
def compare(self, repo_name, source_ref_type, source_ref, target_ref_type, target_ref): # source_ref will be evaluated in source_repo source_repo_name = c.rhodecode_db_repo.repo_name source_path, source_id = parse_path_ref(source_ref) # target_ref will be evaluated in target_repo target_repo_name = request.GET.get('target_repo', source_repo_name) target_path, target_id = parse_path_ref(target_ref) c.commit_statuses = ChangesetStatus.STATUSES # if merge is True # Show what changes since the shared ancestor commit of target/source # the source would get if it was merged with target. Only commits # which are in target but not in source will be shown. merge = str2bool(request.GET.get('merge')) # if merge is False # Show a raw diff of source/target refs even if no ancestor exists # c.fulldiff disables cut_off_limit c.fulldiff = str2bool(request.GET.get('fulldiff')) # if partial, returns just compare_commits.html (commits log) partial = request.is_xhr # swap url for compare_diff page c.swap_url = h.url('compare_url', repo_name=target_repo_name, source_ref_type=target_ref_type, source_ref=target_ref, target_repo=source_repo_name, target_ref_type=source_ref_type, target_ref=source_ref, merge=merge and '1' or '') source_repo = Repository.get_by_repo_name(source_repo_name) target_repo = Repository.get_by_repo_name(target_repo_name) if source_repo is None: msg = _('Could not find the original repo: %(repo)s') % { 'repo': source_repo } log.error(msg) h.flash(msg, category='error') return redirect(url('compare_home', repo_name=c.repo_name)) if target_repo is None: msg = _('Could not find the other repo: %(repo)s') % { 'repo': target_repo_name } log.error(msg) h.flash(msg, category='error') return redirect(url('compare_home', repo_name=c.repo_name)) source_alias = source_repo.scm_instance().alias target_alias = target_repo.scm_instance().alias if source_alias != target_alias: msg = _('The comparison of two different kinds of remote repos ' 'is not available') log.error(msg) h.flash(msg, category='error') return redirect(url('compare_home', repo_name=c.repo_name)) source_commit = self._get_commit_or_redirect(ref=source_id, ref_type=source_ref_type, repo=source_repo, partial=partial) target_commit = self._get_commit_or_redirect(ref=target_id, ref_type=target_ref_type, repo=target_repo, partial=partial) c.compare_home = False c.source_repo = source_repo c.target_repo = target_repo c.source_ref = source_ref c.target_ref = target_ref c.source_ref_type = source_ref_type c.target_ref_type = target_ref_type source_scm = source_repo.scm_instance() target_scm = target_repo.scm_instance() pre_load = ["author", "branch", "date", "message"] c.ancestor = None try: c.commit_ranges = source_scm.compare(source_commit.raw_id, target_commit.raw_id, target_scm, merge, pre_load=pre_load) if merge: c.ancestor = source_scm.get_common_ancestor( source_commit.raw_id, target_commit.raw_id, target_scm) except RepositoryRequirementError: msg = _('Could not compare repos with different ' 'large file settings') log.error(msg) if partial: return msg h.flash(msg, category='error') return redirect(url('compare_home', repo_name=c.repo_name)) c.statuses = c.rhodecode_db_repo.statuses( [x.raw_id for x in c.commit_ranges]) if partial: # for PR ajax commits loader if not c.ancestor: return '' # cannot merge if there is no ancestor return render('compare/compare_commits.html') if c.ancestor: # case we want a simple diff without incoming commits, # previewing what will be merged. # Make the diff on target repo (which is known to have target_ref) log.debug('Using ancestor %s as source_ref instead of %s' % (c.ancestor, source_ref)) source_repo = target_repo source_commit = target_repo.get_commit(commit_id=c.ancestor) # diff_limit will cut off the whole diff if the limit is applied # otherwise it will just hide the big files from the front-end diff_limit = self.cut_off_limit_diff file_limit = self.cut_off_limit_file log.debug( 'calculating diff between ' 'source_ref:%s and target_ref:%s for repo `%s`', source_commit, target_commit, safe_unicode(source_repo.scm_instance().path)) if source_commit.repository != target_commit.repository: msg = _( "Repositories unrelated. " "Cannot compare commit %(commit1)s from repository %(repo1)s " "with commit %(commit2)s from repository %(repo2)s.") % { 'commit1': h.show_id(source_commit), 'repo1': source_repo.repo_name, 'commit2': h.show_id(target_commit), 'repo2': target_repo.repo_name, } h.flash(msg, category='error') raise HTTPBadRequest() txtdiff = source_repo.scm_instance().get_diff(commit1=source_commit, commit2=target_commit, path1=source_path, path=target_path) diff_processor = diffs.DiffProcessor(txtdiff, format='gitdiff', diff_limit=diff_limit, file_limit=file_limit, show_full_diff=c.fulldiff) _parsed = diff_processor.prepare() c.limited_diff = False if isinstance(_parsed, diffs.LimitedDiffContainer): c.limited_diff = True c.files = [] c.changes = {} c.lines_added = 0 c.lines_deleted = 0 for f in _parsed: st = f['stats'] if not st['binary']: c.lines_added += st['added'] c.lines_deleted += st['deleted'] fid = h.FID('', f['filename']) c.files.append([fid, f['operation'], f['filename'], f['stats'], f]) htmldiff = diff_processor.as_html(enable_comments=False, parsed_lines=[f]) c.changes[fid] = [f['operation'], f['filename'], htmldiff, f] c.preview_mode = merge return render('compare/compare_diff.html')
def raw_changeset(self, revision): method = request.GET.get('diff', 'show') ignore_whitespace = request.GET.get('ignorews') == '1' line_context = request.GET.get('context', 3) try: c.scm_type = c.rhodecode_repo.alias c.changeset = c.rhodecode_repo.get_changeset(revision) except RepositoryError: log.error(traceback.format_exc()) return redirect(url('home')) else: try: c.changeset_parent = c.changeset.parents[0] except IndexError: c.changeset_parent = None c.changes = [] for node in c.changeset.added: filenode_old = FileNode(node.path, '') if filenode_old.is_binary or node.is_binary: diff = _('binary file') + '\n' else: f_gitdiff = diffs.get_gitdiff( filenode_old, node, ignore_whitespace=ignore_whitespace, context=line_context) diff = diffs.DiffProcessor(f_gitdiff, format='gitdiff').raw_diff() cs1 = None cs2 = node.changeset.raw_id c.changes.append(('added', node, diff, cs1, cs2)) for node in c.changeset.changed: filenode_old = c.changeset_parent.get_node(node.path) if filenode_old.is_binary or node.is_binary: diff = _('binary file') else: f_gitdiff = diffs.get_gitdiff( filenode_old, node, ignore_whitespace=ignore_whitespace, context=line_context) diff = diffs.DiffProcessor(f_gitdiff, format='gitdiff').raw_diff() cs1 = filenode_old.changeset.raw_id cs2 = node.changeset.raw_id c.changes.append(('changed', node, diff, cs1, cs2)) response.content_type = 'text/plain' if method == 'download': response.content_disposition = 'attachment; filename=%s.patch' \ % revision c.parent_tmpl = ''.join( ['# Parent %s\n' % x.raw_id for x in c.changeset.parents]) c.diffs = '' for x in c.changes: c.diffs += x[2] return render('changeset/raw_changeset.html')
def index(self, format='html'): """GET /users_groups: All items in the collection""" # url('users_groups') c.users_groups_list = UserGroup().query().all() return render('admin/users_groups/users_groups.html')