##// END OF EJS Templates
merge with beta
marcink -
r2357:ea079c9b merge codereview
parent child Browse files
Show More
@@ -0,0 +1,85 b''
1 <div>
2 ${h.form(url('admin_settings_my_account_update'),method='put')}
3 <div class="form">
4
5 <div class="field">
6 <div class="gravatar_box">
7 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div>
8 <p>
9 %if c.use_gravatar:
10 <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong>
11 <br/>${_('Using')} ${c.user.email}
12 %else:
13 <br/>${c.user.email}
14 %endif
15 </p>
16 </div>
17 </div>
18 <div class="field">
19 <div class="label">
20 <label>${_('API key')}</label> ${c.user.api_key}
21 </div>
22 </div>
23 <div class="fields">
24 <div class="field">
25 <div class="label">
26 <label for="username">${_('Username')}:</label>
27 </div>
28 <div class="input">
29 ${h.text('username',class_="medium")}
30 </div>
31 </div>
32
33 <div class="field">
34 <div class="label">
35 <label for="new_password">${_('New password')}:</label>
36 </div>
37 <div class="input">
38 ${h.password('new_password',class_="medium",autocomplete="off")}
39 </div>
40 </div>
41
42 <div class="field">
43 <div class="label">
44 <label for="password_confirmation">${_('New password confirmation')}:</label>
45 </div>
46 <div class="input">
47 ${h.password('password_confirmation',class_="medium",autocomplete="off")}
48 </div>
49 </div>
50
51 <div class="field">
52 <div class="label">
53 <label for="name">${_('First Name')}:</label>
54 </div>
55 <div class="input">
56 ${h.text('name',class_="medium")}
57 </div>
58 </div>
59
60 <div class="field">
61 <div class="label">
62 <label for="lastname">${_('Last Name')}:</label>
63 </div>
64 <div class="input">
65 ${h.text('lastname',class_="medium")}
66 </div>
67 </div>
68
69 <div class="field">
70 <div class="label">
71 <label for="email">${_('Email')}:</label>
72 </div>
73 <div class="input">
74 ${h.text('email',class_="medium")}
75 </div>
76 </div>
77
78 <div class="buttons">
79 ${h.submit('save',_('Save'),class_="ui-button")}
80 ${h.reset('reset',_('Reset'),class_="ui-button")}
81 </div>
82 </div>
83 </div>
84 ${h.end_form()}
85 </div> No newline at end of file
@@ -25,7 +25,7 b' Or::'
25 25 pip install rhodecode
26 26
27 27 If you prefer to install RhodeCode manually simply grab latest release from
28 http://pypi.python.org/pypi/rhodecode, decompress the archive and run::
28 http://pypi.python.org/pypi/RhodeCode, decompress the archive and run::
29 29
30 30 python setup.py install
31 31
@@ -338,12 +338,14 b' class SettingsController(BaseController)'
338 338 return redirect(url('users'))
339 339
340 340 defaults = c.user.get_dict()
341 return htmlfill.render(
342 render('admin/users/user_edit_my_account.html'),
341
342 c.form = htmlfill.render(
343 render('admin/users/user_edit_my_account_form.html'),
343 344 defaults=defaults,
344 345 encoding="UTF-8",
345 346 force_defaults=False
346 347 )
348 return render('admin/users/user_edit_my_account.html')
347 349
348 350 def my_account_update(self):
349 351 """PUT /_admin/my_account_update: Update an existing item"""
@@ -373,12 +375,13 b' class SettingsController(BaseController)'
373 375 .all()
374 376 c.user_repos = ScmModel().get_repos(all_repos)
375 377
376 return htmlfill.render(
377 render('admin/users/user_edit_my_account.html'),
378 c.form = htmlfill.render(
379 render('admin/users/user_edit_my_account_form.html'),
378 380 defaults=errors.value,
379 381 errors=errors.error_dict or {},
380 382 prefix_error=False,
381 383 encoding="UTF-8")
384 return render('admin/users/user_edit_my_account.html')
382 385 except Exception:
383 386 log.error(traceback.format_exc())
384 387 h.flash(_('error occurred during update of user %s') \
@@ -27,11 +27,13 b' import os'
27 27 import logging
28 28 import datetime
29 29 import traceback
30 import hashlib
30 31 from collections import defaultdict
31 32
32 33 from sqlalchemy import *
33 34 from sqlalchemy.ext.hybrid import hybrid_property
34 35 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
36 from sqlalchemy.exc import DatabaseError
35 37 from beaker.cache import cache_region, region_invalidate
36 38
37 39 from pylons.i18n.translation import lazy_ugettext as _
@@ -47,8 +49,7 b' from rhodecode.lib.compat import json'
47 49 from rhodecode.lib.caching_query import FromCache
48 50
49 51 from rhodecode.model.meta import Base, Session
50 import hashlib
51 from sqlalchemy.exc import DatabaseError
52
52 53
53 54 URL_SEP = '/'
54 55 log = logging.getLogger(__name__)
@@ -155,6 +156,7 b' class BaseModel(object):'
155 156 return safe_str(self.__unicode__())
156 157 return '<DB:%s>' % (self.__class__.__name__)
157 158
159
158 160 class RhodeCodeSetting(Base, BaseModel):
159 161 __tablename__ = 'rhodecode_settings'
160 162 __table_args__ = (
@@ -761,18 +763,27 b' class Repository(Base, BaseModel):'
761 763 def scm_instance(self):
762 764 return self.__get_instance()
763 765
764 @property
765 def scm_instance_cached(self):
766 def scm_instance_cached(self, cache_map=None):
766 767 @cache_region('long_term')
767 768 def _c(repo_name):
768 769 return self.__get_instance()
769 770 rn = self.repo_name
770 771 log.debug('Getting cached instance of repo')
771 inv = self.invalidate
772 if inv is not None:
772
773 if cache_map:
774 # get using prefilled cache_map
775 invalidate_repo = cache_map[self.repo_name]
776 if invalidate_repo:
777 invalidate_repo = (None if invalidate_repo.cache_active
778 else invalidate_repo)
779 else:
780 # get from invalidate
781 invalidate_repo = self.invalidate
782
783 if invalidate_repo is not None:
773 784 region_invalidate(_c, None, rn)
774 785 # update our cache
775 CacheInvalidation.set_valid(inv.cache_key)
786 CacheInvalidation.set_valid(invalidate_repo.cache_key)
776 787 return _c(rn)
777 788
778 789 def __get_instance(self):
@@ -1140,6 +1151,7 b' class CacheInvalidation(Base, BaseModel)'
1140 1151 __tablename__ = 'cache_invalidation'
1141 1152 __table_args__ = (
1142 1153 UniqueConstraint('cache_key'),
1154 Index('key_idx', 'cache_key'),
1143 1155 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1144 1156 'mysql_charset': 'utf8'},
1145 1157 )
@@ -1156,6 +1168,7 b' class CacheInvalidation(Base, BaseModel)'
1156 1168 def __unicode__(self):
1157 1169 return u"<%s('%s:%s')>" % (self.__class__.__name__,
1158 1170 self.cache_id, self.cache_key)
1171
1159 1172 @classmethod
1160 1173 def clear_cache(cls):
1161 1174 cls.query().delete()
@@ -1242,6 +1255,40 b' class CacheInvalidation(Base, BaseModel)'
1242 1255 Session.add(inv_obj)
1243 1256 Session.commit()
1244 1257
1258 @classmethod
1259 def get_cache_map(cls):
1260
1261 class cachemapdict(dict):
1262
1263 def __init__(self, *args, **kwargs):
1264 fixkey = kwargs.get('fixkey')
1265 if fixkey:
1266 del kwargs['fixkey']
1267 self.fixkey = fixkey
1268 super(cachemapdict, self).__init__(*args, **kwargs)
1269
1270 def __getattr__(self, name):
1271 key = name
1272 if self.fixkey:
1273 key, _prefix, _org_key = cls._get_key(key)
1274 if key in self.__dict__:
1275 return self.__dict__[key]
1276 else:
1277 return self[key]
1278
1279 def __getitem__(self, key):
1280 if self.fixkey:
1281 key, _prefix, _org_key = cls._get_key(key)
1282 try:
1283 return super(cachemapdict, self).__getitem__(key)
1284 except KeyError:
1285 return
1286
1287 cache_map = cachemapdict(fixkey=True)
1288 for obj in cls.query().all():
1289 cache_map[obj.cache_key] = cachemapdict(obj.get_dict())
1290 return cache_map
1291
1245 1292
1246 1293 class ChangesetComment(Base, BaseModel):
1247 1294 __tablename__ = 'changeset_comments'
@@ -28,6 +28,8 b' import traceback'
28 28 import logging
29 29 import cStringIO
30 30
31 from sqlalchemy import func
32
31 33 from rhodecode.lib.vcs import get_backend
32 34 from rhodecode.lib.vcs.exceptions import RepositoryError
33 35 from rhodecode.lib.vcs.utils.lazy import LazyProperty
@@ -77,8 +79,12 b' class CachedRepoList(object):'
77 79 return '<%s (%s)>' % (self.__class__.__name__, self.__len__())
78 80
79 81 def __iter__(self):
82 # pre-propagated cache_map to save executing select statements
83 # for each repo
84 cache_map = CacheInvalidation.get_cache_map()
85
80 86 for dbr in self.db_repo_list:
81 scmr = dbr.scm_instance_cached
87 scmr = dbr.scm_instance_cached(cache_map)
82 88 # check permission at this level
83 89 if not HasRepoPermissionAny(
84 90 'repository.read', 'repository.write', 'repository.admin'
@@ -219,7 +225,7 b' class ScmModel(BaseModel):'
219 225 if all_repos is None:
220 226 all_repos = self.sa.query(Repository)\
221 227 .filter(Repository.group_id == None)\
222 .order_by(Repository.repo_name).all()
228 .order_by(func.lower(Repository.repo_name)).all()
223 229
224 230 repo_iter = CachedRepoList(all_repos, repos_path=self.repos_path,
225 231 order_by=sort_key)
@@ -21,91 +21,7 b''
21 21 ${self.breadcrumbs()}
22 22 </div>
23 23 <!-- end box / title -->
24 <div>
25 ${h.form(url('admin_settings_my_account_update'),method='put')}
26 <div class="form">
27
28 <div class="field">
29 <div class="gravatar_box">
30 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div>
31 <p>
32 %if c.use_gravatar:
33 <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong>
34 <br/>${_('Using')} ${c.user.email}
35 %else:
36 <br/>${c.user.email}
37 %endif
38 </p>
39 </div>
40 </div>
41 <div class="field">
42 <div class="label">
43 <label>${_('API key')}</label> ${c.user.api_key}
44 </div>
45 </div>
46 <div class="fields">
47 <div class="field">
48 <div class="label">
49 <label for="username">${_('Username')}:</label>
50 </div>
51 <div class="input">
52 ${h.text('username',class_="medium")}
53 </div>
54 </div>
55
56 <div class="field">
57 <div class="label">
58 <label for="new_password">${_('New password')}:</label>
59 </div>
60 <div class="input">
61 ${h.password('new_password',class_="medium",autocomplete="off")}
62 </div>
63 </div>
64
65 <div class="field">
66 <div class="label">
67 <label for="password_confirmation">${_('New password confirmation')}:</label>
68 </div>
69 <div class="input">
70 ${h.password('password_confirmation',class_="medium",autocomplete="off")}
71 </div>
72 </div>
73
74 <div class="field">
75 <div class="label">
76 <label for="name">${_('First Name')}:</label>
77 </div>
78 <div class="input">
79 ${h.text('name',class_="medium")}
80 </div>
81 </div>
82
83 <div class="field">
84 <div class="label">
85 <label for="lastname">${_('Last Name')}:</label>
86 </div>
87 <div class="input">
88 ${h.text('lastname',class_="medium")}
89 </div>
90 </div>
91
92 <div class="field">
93 <div class="label">
94 <label for="email">${_('Email')}:</label>
95 </div>
96 <div class="input">
97 ${h.text('email',class_="medium")}
98 </div>
99 </div>
100
101 <div class="buttons">
102 ${h.submit('save',_('Save'),class_="ui-button")}
103 ${h.reset('reset',_('Reset'),class_="ui-button")}
104 </div>
105 </div>
106 </div>
107 ${h.end_form()}
108 </div>
24 ${c.form|n}
109 25 </div>
110 26
111 27 <div class="box box-right">
General Comments 0
You need to be logged in to leave comments. Login now