##// 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 pip install rhodecode
25 pip install rhodecode
26
26
27 If you prefer to install RhodeCode manually simply grab latest release from
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 python setup.py install
30 python setup.py install
31
31
@@ -338,12 +338,14 b' class SettingsController(BaseController)'
338 return redirect(url('users'))
338 return redirect(url('users'))
339
339
340 defaults = c.user.get_dict()
340 defaults = c.user.get_dict()
341 return htmlfill.render(
341
342 render('admin/users/user_edit_my_account.html'),
342 c.form = htmlfill.render(
343 render('admin/users/user_edit_my_account_form.html'),
343 defaults=defaults,
344 defaults=defaults,
344 encoding="UTF-8",
345 encoding="UTF-8",
345 force_defaults=False
346 force_defaults=False
346 )
347 )
348 return render('admin/users/user_edit_my_account.html')
347
349
348 def my_account_update(self):
350 def my_account_update(self):
349 """PUT /_admin/my_account_update: Update an existing item"""
351 """PUT /_admin/my_account_update: Update an existing item"""
@@ -373,12 +375,13 b' class SettingsController(BaseController)'
373 .all()
375 .all()
374 c.user_repos = ScmModel().get_repos(all_repos)
376 c.user_repos = ScmModel().get_repos(all_repos)
375
377
376 return htmlfill.render(
378 c.form = htmlfill.render(
377 render('admin/users/user_edit_my_account.html'),
379 render('admin/users/user_edit_my_account_form.html'),
378 defaults=errors.value,
380 defaults=errors.value,
379 errors=errors.error_dict or {},
381 errors=errors.error_dict or {},
380 prefix_error=False,
382 prefix_error=False,
381 encoding="UTF-8")
383 encoding="UTF-8")
384 return render('admin/users/user_edit_my_account.html')
382 except Exception:
385 except Exception:
383 log.error(traceback.format_exc())
386 log.error(traceback.format_exc())
384 h.flash(_('error occurred during update of user %s') \
387 h.flash(_('error occurred during update of user %s') \
@@ -27,11 +27,13 b' import os'
27 import logging
27 import logging
28 import datetime
28 import datetime
29 import traceback
29 import traceback
30 import hashlib
30 from collections import defaultdict
31 from collections import defaultdict
31
32
32 from sqlalchemy import *
33 from sqlalchemy import *
33 from sqlalchemy.ext.hybrid import hybrid_property
34 from sqlalchemy.ext.hybrid import hybrid_property
34 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
35 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
36 from sqlalchemy.exc import DatabaseError
35 from beaker.cache import cache_region, region_invalidate
37 from beaker.cache import cache_region, region_invalidate
36
38
37 from pylons.i18n.translation import lazy_ugettext as _
39 from pylons.i18n.translation import lazy_ugettext as _
@@ -47,8 +49,7 b' from rhodecode.lib.compat import json'
47 from rhodecode.lib.caching_query import FromCache
49 from rhodecode.lib.caching_query import FromCache
48
50
49 from rhodecode.model.meta import Base, Session
51 from rhodecode.model.meta import Base, Session
50 import hashlib
52
51 from sqlalchemy.exc import DatabaseError
52
53
53 URL_SEP = '/'
54 URL_SEP = '/'
54 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
@@ -155,6 +156,7 b' class BaseModel(object):'
155 return safe_str(self.__unicode__())
156 return safe_str(self.__unicode__())
156 return '<DB:%s>' % (self.__class__.__name__)
157 return '<DB:%s>' % (self.__class__.__name__)
157
158
159
158 class RhodeCodeSetting(Base, BaseModel):
160 class RhodeCodeSetting(Base, BaseModel):
159 __tablename__ = 'rhodecode_settings'
161 __tablename__ = 'rhodecode_settings'
160 __table_args__ = (
162 __table_args__ = (
@@ -761,18 +763,27 b' class Repository(Base, BaseModel):'
761 def scm_instance(self):
763 def scm_instance(self):
762 return self.__get_instance()
764 return self.__get_instance()
763
765
764 @property
766 def scm_instance_cached(self, cache_map=None):
765 def scm_instance_cached(self):
766 @cache_region('long_term')
767 @cache_region('long_term')
767 def _c(repo_name):
768 def _c(repo_name):
768 return self.__get_instance()
769 return self.__get_instance()
769 rn = self.repo_name
770 rn = self.repo_name
770 log.debug('Getting cached instance of repo')
771 log.debug('Getting cached instance of repo')
771 inv = self.invalidate
772
772 if inv is not None:
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 region_invalidate(_c, None, rn)
784 region_invalidate(_c, None, rn)
774 # update our cache
785 # update our cache
775 CacheInvalidation.set_valid(inv.cache_key)
786 CacheInvalidation.set_valid(invalidate_repo.cache_key)
776 return _c(rn)
787 return _c(rn)
777
788
778 def __get_instance(self):
789 def __get_instance(self):
@@ -1140,6 +1151,7 b' class CacheInvalidation(Base, BaseModel)'
1140 __tablename__ = 'cache_invalidation'
1151 __tablename__ = 'cache_invalidation'
1141 __table_args__ = (
1152 __table_args__ = (
1142 UniqueConstraint('cache_key'),
1153 UniqueConstraint('cache_key'),
1154 Index('key_idx', 'cache_key'),
1143 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1155 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1144 'mysql_charset': 'utf8'},
1156 'mysql_charset': 'utf8'},
1145 )
1157 )
@@ -1156,6 +1168,7 b' class CacheInvalidation(Base, BaseModel)'
1156 def __unicode__(self):
1168 def __unicode__(self):
1157 return u"<%s('%s:%s')>" % (self.__class__.__name__,
1169 return u"<%s('%s:%s')>" % (self.__class__.__name__,
1158 self.cache_id, self.cache_key)
1170 self.cache_id, self.cache_key)
1171
1159 @classmethod
1172 @classmethod
1160 def clear_cache(cls):
1173 def clear_cache(cls):
1161 cls.query().delete()
1174 cls.query().delete()
@@ -1242,6 +1255,40 b' class CacheInvalidation(Base, BaseModel)'
1242 Session.add(inv_obj)
1255 Session.add(inv_obj)
1243 Session.commit()
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 class ChangesetComment(Base, BaseModel):
1293 class ChangesetComment(Base, BaseModel):
1247 __tablename__ = 'changeset_comments'
1294 __tablename__ = 'changeset_comments'
@@ -28,6 +28,8 b' import traceback'
28 import logging
28 import logging
29 import cStringIO
29 import cStringIO
30
30
31 from sqlalchemy import func
32
31 from rhodecode.lib.vcs import get_backend
33 from rhodecode.lib.vcs import get_backend
32 from rhodecode.lib.vcs.exceptions import RepositoryError
34 from rhodecode.lib.vcs.exceptions import RepositoryError
33 from rhodecode.lib.vcs.utils.lazy import LazyProperty
35 from rhodecode.lib.vcs.utils.lazy import LazyProperty
@@ -77,8 +79,12 b' class CachedRepoList(object):'
77 return '<%s (%s)>' % (self.__class__.__name__, self.__len__())
79 return '<%s (%s)>' % (self.__class__.__name__, self.__len__())
78
80
79 def __iter__(self):
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 for dbr in self.db_repo_list:
86 for dbr in self.db_repo_list:
81 scmr = dbr.scm_instance_cached
87 scmr = dbr.scm_instance_cached(cache_map)
82 # check permission at this level
88 # check permission at this level
83 if not HasRepoPermissionAny(
89 if not HasRepoPermissionAny(
84 'repository.read', 'repository.write', 'repository.admin'
90 'repository.read', 'repository.write', 'repository.admin'
@@ -219,7 +225,7 b' class ScmModel(BaseModel):'
219 if all_repos is None:
225 if all_repos is None:
220 all_repos = self.sa.query(Repository)\
226 all_repos = self.sa.query(Repository)\
221 .filter(Repository.group_id == None)\
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 repo_iter = CachedRepoList(all_repos, repos_path=self.repos_path,
230 repo_iter = CachedRepoList(all_repos, repos_path=self.repos_path,
225 order_by=sort_key)
231 order_by=sort_key)
@@ -21,91 +21,7 b''
21 ${self.breadcrumbs()}
21 ${self.breadcrumbs()}
22 </div>
22 </div>
23 <!-- end box / title -->
23 <!-- end box / title -->
24 <div>
24 ${c.form|n}
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>
109 </div>
25 </div>
110
26
111 <div class="box box-right">
27 <div class="box box-right">
General Comments 0
You need to be logged in to leave comments. Login now