@@ -11,48 +11,49 @@ Changelog
:branch: beta
news
++++
fixes
+++++
1.5.1 (**2012-12-13**)
----------------------
- implements #677: Don't allow to close pull requests when they are
under-review status
- implemented #670 Implementation of Roles in Pull Request
- default permissions can get duplicated after migration
- fixed changeset status labels, they now select radio buttons
- #682 translation difficult for multi-line text
- #683 fixed difference between messages about not mapped repositories
1.5.0 (**2012-12-12**)
- new rewritten from scratch diff engine. 10x faster in edge cases. Handling
of file renames, copies, change flags and binary files
- added lightweight dashboard option. ref #500. New version of dashboard
page that doesn't use any VCS data and is super fast to render. Recommended
for large amount of repositories.
- implements #648 write Script for updating last modification time for
lightweight dashboard
- implemented compare engine for git repositories.
- LDAP failover, option to specify multiple servers
- added Errormator and Sentry support for monitoring RhodeCode
- implemented #628: Pass server URL to rc-extensions hooks
- new tooltip implementation - added lazy loading of changesets from journal
pages. This can significantly improve speed of rendering the page
- implements #632,added branch/tag/bookmarks info into feeds
added changeset link to body of message
- implemented #638 permissions overview to groups
- implements #636, lazy loading of history and authors to speed up source
@@ -68,54 +68,49 @@ class ReposController(BaseController):
super(ReposController, self).__before__()
def __load_defaults(self):
c.repo_groups = RepoGroup.groups_choices(check_perms=True)
c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
repo_model = RepoModel()
c.users_array = repo_model.get_users_js()
c.users_groups_array = repo_model.get_users_groups_js()
choices, c.landing_revs = ScmModel().get_repo_landing_revs()
c.landing_revs_choices = choices
def __load_data(self, repo_name=None):
"""
Load defaults settings for edit, and update
:param repo_name:
self.__load_defaults()
c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
repo = db_repo.scm_instance
if c.repo_info is None:
h.flash(_('%s repository is not mapped to db perhaps'
' it was created or renamed from the filesystem'
' please run the application again'
' in order to rescan repositories') % repo_name,
category='error')
h.not_mapped_error(repo_name)
return redirect(url('repos'))
##override defaults for exact repo info here git/hg etc
choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info)
c.default_user_id = User.get_by_username('default').user_id
c.in_public_journal = UserFollowing.query()\
.filter(UserFollowing.user_id == c.default_user_id)\
.filter(UserFollowing.follows_repository == c.repo_info).scalar()
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 repo.revisions else 0
if last_rev == 0 or c.repo_last_rev == 0:
c.stats_percentage = 0
c.stats_percentage = '%.2f' % ((float((last_rev)) /
@@ -289,54 +284,49 @@ class ReposController(BaseController):
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8")
except Exception:
log.error(traceback.format_exc())
h.flash(_('error occurred during update of repository %s') \
% repo_name, category='error')
return redirect(url('edit_repo', repo_name=changed_name))
@HasPermissionAllDecorator('hg.admin')
def delete(self, repo_name):
DELETE /repos/repo_name: Delete an existing item"""
# Forms posted to this method should contain a hidden field:
# <input type="hidden" name="_method" value="DELETE" />
# Or using helpers:
# h.form(url('repo', repo_name=ID),
# method='delete')
# url('repo', repo_name=ID)
repo = repo_model.get_by_repo_name(repo_name)
if not repo:
' it was moved or renamed from the filesystem'
try:
action_logger(self.rhodecode_user, 'admin_deleted_repo',
repo_name, self.ip_addr, self.sa)
repo_model.delete(repo)
invalidate_cache('get_repo_cached_%s' % repo_name)
h.flash(_('deleted repository %s') % repo_name, category='success')
Session().commit()
except IntegrityError, e:
if e.message.find('repositories_fork_id_fkey') != -1:
h.flash(_('Cannot delete %s it still contains attached '
'forks') % repo_name,
category='warning')
h.flash(_('An error occurred during '
'deletion of %s') % repo_name,
except Exception, e:
h.flash(_('An error occurred during deletion of %s') % repo_name,
@@ -50,54 +50,49 @@ log = logging.getLogger(__name__)
class ForksController(BaseRepoController):
@LoginRequired()
def __before__(self):
super(ForksController, self).__before__()
last_rev = c.repo_info.stats.stat_on_revision+1
c.repo_last_rev) * 100)
defaults = RepoModel()._get_defaults(repo_name)
# add suffix to fork
defaults['repo_name'] = '%s-fork' % defaults['repo_name']
@@ -110,54 +105,49 @@ class ForksController(BaseRepoController
repo_id = c.rhodecode_db_repo.repo_id
d = []
for r in Repository.get_repo_forks(repo_id):
if not HasRepoPermissionAny(
'repository.read', 'repository.write', 'repository.admin'
)(r.repo_name, 'get forks check'):
continue
d.append(r)
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')
@NotAnonymous()
@HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def fork(self, repo_name):
c.repo_info = Repository.get_by_repo_name(repo_name)
if not c.repo_info:
' it was created or renamed from the file system'
return redirect(url('home'))
defaults = self.__load_data(repo_name)
return htmlfill.render(
render('forks/fork.html'),
defaults=defaults,
encoding="UTF-8",
force_defaults=False
)
def fork_create(self, 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 = {}
form_result = _form.to_python(dict(request.POST))
@@ -56,54 +56,49 @@ class SettingsController(BaseRepoControl
super(SettingsController, self).__before__()
return defaults
@HasRepoPermissionAllDecorator('repository.admin')
def index(self, repo_name):
render('settings/repo_settings.html'),
def update(self, repo_name):
@@ -136,54 +131,49 @@ class SettingsController(BaseRepoControl
return redirect(url('repo_settings_home', repo_name=changed_name))
"""DELETE /repos/repo_name: Delete an existing item"""
# h.form(url('repo_settings_delete', repo_name=ID),
# url('repo_settings_delete', repo_name=ID)
action_logger(self.rhodecode_user, 'user_deleted_repo',
return redirect(url('admin_settings_my_account', anchor='my'))
@HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
def toggle_locking(self, repo_name):
Toggle locking of repository by simple GET call to url
@@ -1136,24 +1136,31 @@ def changeset_status_lbl(changeset_statu
def get_permission_name(key):
return dict(Permission.PERMS).get(key)
def journal_filter_help():
return _(textwrap.dedent('''
Example filter terms:
repository:vcs
username:marcin
action:*push*
ip:127.0.0.1
date:20120101
date:[20120101100000 TO 20120102]
Generate wildcards using '*' character:
"repositroy:vcs*" - search everything starting with 'vcs'
"repository:*vcs*" - search for repository containing 'vcs'
Optional AND / OR operators in queries
"repository:vcs OR repository:test"
"username:test AND repository:test*"
'''))
def not_mapped_error(repo_name):
flash(_('%s repository is not mapped to db perhaps'
' in order to rescan repositories') % repo_name, category='error')
Status change: