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