Mercurial > kallithea
changeset 2357:ea079c9b62b5 codereview
merge with beta
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 28 May 2012 23:35:30 +0200 |
parents | 29a8096820dc (current diff) 2da7b5984ae5 (diff) |
children | 948c16bb9476 |
files | rhodecode/model/db.py |
diffstat | 6 files changed, 157 insertions(+), 100 deletions(-) [+] |
line wrap: on
line diff
--- a/docs/installation.rst Mon May 28 23:21:43 2012 +0200 +++ b/docs/installation.rst Mon May 28 23:35:30 2012 +0200 @@ -25,7 +25,7 @@ pip install rhodecode If you prefer to install RhodeCode manually simply grab latest release from -http://pypi.python.org/pypi/rhodecode, decompress the archive and run:: +http://pypi.python.org/pypi/RhodeCode, decompress the archive and run:: python setup.py install
--- a/rhodecode/controllers/admin/settings.py Mon May 28 23:21:43 2012 +0200 +++ b/rhodecode/controllers/admin/settings.py Mon May 28 23:35:30 2012 +0200 @@ -338,12 +338,14 @@ return redirect(url('users')) defaults = c.user.get_dict() - return htmlfill.render( - render('admin/users/user_edit_my_account.html'), + + 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""" @@ -373,12 +375,13 @@ .all() c.user_repos = ScmModel().get_repos(all_repos) - return htmlfill.render( - render('admin/users/user_edit_my_account.html'), + 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') except Exception: log.error(traceback.format_exc()) h.flash(_('error occurred during update of user %s') \
--- a/rhodecode/model/db.py Mon May 28 23:21:43 2012 +0200 +++ b/rhodecode/model/db.py Mon May 28 23:35:30 2012 +0200 @@ -27,11 +27,13 @@ import logging import datetime import traceback +import hashlib from collections import defaultdict from sqlalchemy import * from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import relationship, joinedload, class_mapper, validates +from sqlalchemy.exc import DatabaseError from beaker.cache import cache_region, region_invalidate from pylons.i18n.translation import lazy_ugettext as _ @@ -47,8 +49,7 @@ from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -import hashlib -from sqlalchemy.exc import DatabaseError + URL_SEP = '/' log = logging.getLogger(__name__) @@ -155,6 +156,7 @@ return safe_str(self.__unicode__()) return '<DB:%s>' % (self.__class__.__name__) + class RhodeCodeSetting(Base, BaseModel): __tablename__ = 'rhodecode_settings' __table_args__ = ( @@ -225,7 +227,7 @@ .filter(cls.app_settings_name.startswith('ldap_')).all() fd = {} for row in ret: - fd.update({row.app_settings_name:row.app_settings_value}) + fd.update({row.app_settings_name: row.app_settings_value}) return fd @@ -761,18 +763,27 @@ def scm_instance(self): return self.__get_instance() - @property - def scm_instance_cached(self): + def scm_instance_cached(self, cache_map=None): @cache_region('long_term') def _c(repo_name): return self.__get_instance() rn = self.repo_name log.debug('Getting cached instance of repo') - inv = self.invalidate - if inv is not None: + + if cache_map: + # get using prefilled cache_map + invalidate_repo = cache_map[self.repo_name] + if invalidate_repo: + invalidate_repo = (None if invalidate_repo.cache_active + else invalidate_repo) + else: + # get from invalidate + invalidate_repo = self.invalidate + + if invalidate_repo is not None: region_invalidate(_c, None, rn) # update our cache - CacheInvalidation.set_valid(inv.cache_key) + CacheInvalidation.set_valid(invalidate_repo.cache_key) return _c(rn) def __get_instance(self): @@ -1140,6 +1151,7 @@ __tablename__ = 'cache_invalidation' __table_args__ = ( UniqueConstraint('cache_key'), + Index('key_idx', 'cache_key'), {'extend_existing': True, 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}, ) @@ -1156,6 +1168,7 @@ def __unicode__(self): return u"<%s('%s:%s')>" % (self.__class__.__name__, self.cache_id, self.cache_key) + @classmethod def clear_cache(cls): cls.query().delete() @@ -1242,6 +1255,40 @@ Session.add(inv_obj) Session.commit() + @classmethod + def get_cache_map(cls): + + class cachemapdict(dict): + + def __init__(self, *args, **kwargs): + fixkey = kwargs.get('fixkey') + if fixkey: + del kwargs['fixkey'] + self.fixkey = fixkey + super(cachemapdict, self).__init__(*args, **kwargs) + + def __getattr__(self, name): + key = name + if self.fixkey: + key, _prefix, _org_key = cls._get_key(key) + if key in self.__dict__: + return self.__dict__[key] + else: + return self[key] + + def __getitem__(self, key): + if self.fixkey: + key, _prefix, _org_key = cls._get_key(key) + try: + return super(cachemapdict, self).__getitem__(key) + except KeyError: + return + + cache_map = cachemapdict(fixkey=True) + for obj in cls.query().all(): + cache_map[obj.cache_key] = cachemapdict(obj.get_dict()) + return cache_map + class ChangesetComment(Base, BaseModel): __tablename__ = 'changeset_comments'
--- a/rhodecode/model/scm.py Mon May 28 23:21:43 2012 +0200 +++ b/rhodecode/model/scm.py Mon May 28 23:35:30 2012 +0200 @@ -28,6 +28,8 @@ import logging import cStringIO +from sqlalchemy import func + from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.exceptions import RepositoryError from rhodecode.lib.vcs.utils.lazy import LazyProperty @@ -77,8 +79,12 @@ return '<%s (%s)>' % (self.__class__.__name__, self.__len__()) def __iter__(self): + # pre-propagated cache_map to save executing select statements + # for each repo + cache_map = CacheInvalidation.get_cache_map() + for dbr in self.db_repo_list: - scmr = dbr.scm_instance_cached + scmr = dbr.scm_instance_cached(cache_map) # check permission at this level if not HasRepoPermissionAny( 'repository.read', 'repository.write', 'repository.admin' @@ -219,7 +225,7 @@ if all_repos is None: all_repos = self.sa.query(Repository)\ .filter(Repository.group_id == None)\ - .order_by(Repository.repo_name).all() + .order_by(func.lower(Repository.repo_name)).all() repo_iter = CachedRepoList(all_repos, repos_path=self.repos_path, order_by=sort_key)
--- a/rhodecode/templates/admin/users/user_edit_my_account.html Mon May 28 23:21:43 2012 +0200 +++ b/rhodecode/templates/admin/users/user_edit_my_account.html Mon May 28 23:35:30 2012 +0200 @@ -21,91 +21,7 @@ ${self.breadcrumbs()} </div> <!-- end box / title --> - <div> - ${h.form(url('admin_settings_my_account_update'),method='put')} - <div class="form"> - - <div class="field"> - <div class="gravatar_box"> - <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div> - <p> - %if c.use_gravatar: - <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong> - <br/>${_('Using')} ${c.user.email} - %else: - <br/>${c.user.email} - %endif - </p> - </div> - </div> - <div class="field"> - <div class="label"> - <label>${_('API key')}</label> ${c.user.api_key} - </div> - </div> - <div class="fields"> - <div class="field"> - <div class="label"> - <label for="username">${_('Username')}:</label> - </div> - <div class="input"> - ${h.text('username',class_="medium")} - </div> - </div> - - <div class="field"> - <div class="label"> - <label for="new_password">${_('New password')}:</label> - </div> - <div class="input"> - ${h.password('new_password',class_="medium",autocomplete="off")} - </div> - </div> - - <div class="field"> - <div class="label"> - <label for="password_confirmation">${_('New password confirmation')}:</label> - </div> - <div class="input"> - ${h.password('password_confirmation',class_="medium",autocomplete="off")} - </div> - </div> - - <div class="field"> - <div class="label"> - <label for="name">${_('First Name')}:</label> - </div> - <div class="input"> - ${h.text('name',class_="medium")} - </div> - </div> - - <div class="field"> - <div class="label"> - <label for="lastname">${_('Last Name')}:</label> - </div> - <div class="input"> - ${h.text('lastname',class_="medium")} - </div> - </div> - - <div class="field"> - <div class="label"> - <label for="email">${_('Email')}:</label> - </div> - <div class="input"> - ${h.text('email',class_="medium")} - </div> - </div> - - <div class="buttons"> - ${h.submit('save',_('Save'),class_="ui-button")} - ${h.reset('reset',_('Reset'),class_="ui-button")} - </div> - </div> - </div> - ${h.end_form()} - </div> + ${c.form|n} </div> <div class="box box-right">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/templates/admin/users/user_edit_my_account_form.html Mon May 28 23:35:30 2012 +0200 @@ -0,0 +1,85 @@ +<div> + ${h.form(url('admin_settings_my_account_update'),method='put')} + <div class="form"> + + <div class="field"> + <div class="gravatar_box"> + <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div> + <p> + %if c.use_gravatar: + <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong> + <br/>${_('Using')} ${c.user.email} + %else: + <br/>${c.user.email} + %endif + </p> + </div> + </div> + <div class="field"> + <div class="label"> + <label>${_('API key')}</label> ${c.user.api_key} + </div> + </div> + <div class="fields"> + <div class="field"> + <div class="label"> + <label for="username">${_('Username')}:</label> + </div> + <div class="input"> + ${h.text('username',class_="medium")} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="new_password">${_('New password')}:</label> + </div> + <div class="input"> + ${h.password('new_password',class_="medium",autocomplete="off")} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="password_confirmation">${_('New password confirmation')}:</label> + </div> + <div class="input"> + ${h.password('password_confirmation',class_="medium",autocomplete="off")} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="name">${_('First Name')}:</label> + </div> + <div class="input"> + ${h.text('name',class_="medium")} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="lastname">${_('Last Name')}:</label> + </div> + <div class="input"> + ${h.text('lastname',class_="medium")} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="email">${_('Email')}:</label> + </div> + <div class="input"> + ${h.text('email',class_="medium")} + </div> + </div> + + <div class="buttons"> + ${h.submit('save',_('Save'),class_="ui-button")} + ${h.reset('reset',_('Reset'),class_="ui-button")} + </div> + </div> + </div> + ${h.end_form()} + </div> \ No newline at end of file