##// END OF EJS Templates
merged + fixed pull request #62: Implemented metatags and visualisation options....
marcink -
r2674:a221706d beta
parent child Browse files
Show More
@@ -144,20 +144,21 b' class ReposController(BaseController):'
144 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
144 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
145
145
146 quick_menu = lambda repo_name: (template.get_def("quick_menu")
146 quick_menu = lambda repo_name: (template.get_def("quick_menu")
147 .render(repo_name, _=_, h=h))
147 .render(repo_name, _=_, h=h, c=c))
148 repo_lnk = lambda name, rtype, private, fork_of: (
148 repo_lnk = lambda name, rtype, private, fork_of: (
149 template.get_def("repo_name")
149 template.get_def("repo_name")
150 .render(name, rtype, private, fork_of, short_name=False,
150 .render(name, rtype, private, fork_of, short_name=False,
151 admin=True, _=_, h=h))
151 admin=True, _=_, h=h, c=c))
152
152
153 repo_actions = lambda repo_name: (template.get_def("repo_actions")
153 repo_actions = lambda repo_name: (template.get_def("repo_actions")
154 .render(repo_name, _=_, h=h))
154 .render(repo_name, _=_, h=h, c=c))
155
155
156 for repo in c.repos_list:
156 for repo in c.repos_list:
157 repos_data.append({
157 repos_data.append({
158 "menu": quick_menu(repo.repo_name),
158 "menu": quick_menu(repo.repo_name),
159 "raw_name": repo.repo_name,
159 "raw_name": repo.repo_name,
160 "name": repo_lnk(repo.repo_name, repo.repo_type, repo.private, repo.fork),
160 "name": repo_lnk(repo.repo_name, repo.repo_type,
161 repo.private, repo.fork),
161 "desc": repo.description,
162 "desc": repo.description,
162 "owner": repo.user.username,
163 "owner": repo.user.username,
163 "action": repo_actions(repo.repo_name),
164 "action": repo_actions(repo.repo_name),
@@ -45,7 +45,7 b' from rhodecode.lib.utils import repo2db_'
45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
46 RhodeCodeSetting, PullRequest, PullRequestReviewers
46 RhodeCodeSetting, PullRequest, PullRequestReviewers
47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
48 ApplicationUiSettingsForm
48 ApplicationUiSettingsForm, ApplicationVisualisationForm
49 from rhodecode.model.scm import ScmModel
49 from rhodecode.model.scm import ScmModel
50 from rhodecode.model.user import UserModel
50 from rhodecode.model.user import UserModel
51 from rhodecode.model.db import User
51 from rhodecode.model.db import User
@@ -143,15 +143,15 b' class SettingsController(BaseController)'
143 )
143 )
144
144
145 try:
145 try:
146 sett1 = RhodeCodeSetting.get_by_name('title')
146 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
147 sett1.app_settings_value = form_result['rhodecode_title']
147 sett1.app_settings_value = form_result['rhodecode_title']
148 Session().add(sett1)
148 Session().add(sett1)
149
149
150 sett2 = RhodeCodeSetting.get_by_name('realm')
150 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
151 sett2.app_settings_value = form_result['rhodecode_realm']
151 sett2.app_settings_value = form_result['rhodecode_realm']
152 Session().add(sett2)
152 Session().add(sett2)
153
153
154 sett3 = RhodeCodeSetting.get_by_name('ga_code')
154 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
155 sett3.app_settings_value = form_result['rhodecode_ga_code']
155 sett3.app_settings_value = form_result['rhodecode_ga_code']
156 Session().add(sett3)
156 Session().add(sett3)
157
157
@@ -165,6 +165,47 b' class SettingsController(BaseController)'
165 'application settings'),
165 'application settings'),
166 category='error')
166 category='error')
167
167
168 if setting_id == 'visual':
169
170 application_form = ApplicationVisualisationForm()()
171 try:
172 form_result = application_form.to_python(dict(request.POST))
173 except formencode.Invalid, errors:
174 return htmlfill.render(
175 render('admin/settings/settings.html'),
176 defaults=errors.value,
177 errors=errors.error_dict or {},
178 prefix_error=False,
179 encoding="UTF-8"
180 )
181
182 try:
183 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
184 sett1.app_settings_value = \
185 form_result['rhodecode_show_public_icon']
186
187 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
188 sett2.app_settings_value = \
189 form_result['rhodecode_show_private_icon']
190
191 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
192 sett3.app_settings_value = \
193 form_result['rhodecode_stylify_metatags']
194
195 Session().add(sett1)
196 Session().add(sett2)
197 Session().add(sett3)
198 Session().commit()
199 set_rhodecode_config(config)
200 h.flash(_('Updated visualisation settings'),
201 category='success')
202
203 except Exception:
204 log.error(traceback.format_exc())
205 h.flash(_('error occurred during updating '
206 'visualisation settings'),
207 category='error')
208
168 if setting_id == 'vcs':
209 if setting_id == 'vcs':
169 application_form = ApplicationUiSettingsForm()()
210 application_form = ApplicationUiSettingsForm()()
170 try:
211 try:
@@ -78,15 +78,15 b' class UsersController(BaseController):'
78
78
79 grav_tmpl = lambda user_email, size: (
79 grav_tmpl = lambda user_email, size: (
80 template.get_def("user_gravatar")
80 template.get_def("user_gravatar")
81 .render(user_email, size, _=_, h=h))
81 .render(user_email, size, _=_, h=h, c=c))
82
82
83 user_lnk = lambda user_id, username: (
83 user_lnk = lambda user_id, username: (
84 template.get_def("user_name")
84 template.get_def("user_name")
85 .render(user_id, username, _=_, h=h))
85 .render(user_id, username, _=_, h=h, c=c))
86
86
87 user_actions = lambda user_id, username: (
87 user_actions = lambda user_id, username: (
88 template.get_def("user_actions")
88 template.get_def("user_actions")
89 .render(user_id, username, _=_, h=h))
89 .render(user_id, username, _=_, h=h, c=c))
90
90
91 for user in c.users_list:
91 for user in c.users_list:
92 users_data.append({
92 users_data.append({
@@ -17,7 +17,7 b' from pylons.templating import render_mak'
17
17
18 from rhodecode import __version__, BACKENDS
18 from rhodecode import __version__, BACKENDS
19
19
20 from rhodecode.lib.utils2 import str2bool, safe_unicode
20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
21 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
21 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
22 HasPermissionAnyMiddleware, CookieStoreWrapper
22 HasPermissionAnyMiddleware, CookieStoreWrapper
23 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
23 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
@@ -158,7 +158,7 b' class BaseVCSController(object):'
158 log.debug('proto is %s and SSL is required BAD REQUEST !'
158 log.debug('proto is %s and SSL is required BAD REQUEST !'
159 % org_proto)
159 % org_proto)
160 return False
160 return False
161 return True
161 return True
162
162
163 def __call__(self, environ, start_response):
163 def __call__(self, environ, start_response):
164 start = time.time()
164 start = time.time()
@@ -178,6 +178,12 b' class BaseController(WSGIController):'
178 c.rhodecode_name = config.get('rhodecode_title')
178 c.rhodecode_name = config.get('rhodecode_title')
179 c.use_gravatar = str2bool(config.get('use_gravatar'))
179 c.use_gravatar = str2bool(config.get('use_gravatar'))
180 c.ga_code = config.get('rhodecode_ga_code')
180 c.ga_code = config.get('rhodecode_ga_code')
181 # Visual options
182 c.visual = AttributeDict({})
183 c.visual.show_public_icon = str2bool(config.get('rhodecode_show_public_icon'))
184 c.visual.show_private_icon = str2bool(config.get('rhodecode_show_private_icon'))
185 c.visual.stylify_metatags = str2bool(config.get('rhodecode_stylify_metatags'))
186
181 c.repo_name = get_repo_slug(request)
187 c.repo_name = get_repo_slug(request)
182 c.backends = BACKENDS.keys()
188 c.backends = BACKENDS.keys()
183 c.unread_notifications = NotificationModel()\
189 c.unread_notifications = NotificationModel()\
@@ -9,6 +9,7 b' import StringIO'
9 import urllib
9 import urllib
10 import math
10 import math
11 import logging
11 import logging
12 import re
12
13
13 from datetime import datetime
14 from datetime import datetime
14 from pygments.formatters.html import HtmlFormatter
15 from pygments.formatters.html import HtmlFormatter
@@ -430,6 +431,26 b' def person(author):'
430 return _author
431 return _author
431
432
432
433
434 def desc_stylize(value):
435 """
436 converts tags from value into html equivalent
437
438 :param value:
439 """
440 value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
441 '<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
442 value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
443 '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
444 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z\-\/]*)\]',
445 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
446 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/]*)\]',
447 '<div class="metatag" tag="lang">\\2</div>', value)
448 value = re.sub(r'\[([a-z]+)\]',
449 '<div class="metatag" tag="\\1">\\1</div>', value)
450
451 return value
452
453
433 def bool2icon(value):
454 def bool2icon(value):
434 """Returns True/False values represented as small html image of true/false
455 """Returns True/False values represented as small html image of true/false
435 icons
456 icons
@@ -443,3 +443,9 b' def extract_mentioned_users(s):'
443 usrs.add(username)
443 usrs.add(username)
444
444
445 return sorted(list(usrs), key=lambda k: k.lower())
445 return sorted(list(usrs), key=lambda k: k.lower())
446
447 class AttributeDict(dict):
448 def __getattr__(self, attr):
449 return self.get(attr, None)
450 __setattr__ = dict.__setitem__
451 __delattr__ = dict.__delitem__
@@ -182,9 +182,16 b' class RhodeCodeSetting(Base, BaseModel):'
182 )
182 )
183
183
184 @classmethod
184 @classmethod
185 def get_by_name(cls, ldap_key):
185 def get_by_name(cls, key):
186 return cls.query()\
186 return cls.query()\
187 .filter(cls.app_settings_name == ldap_key).scalar()
187 .filter(cls.app_settings_name == key).scalar()
188
189 @classmethod
190 def get_by_name_or_create(cls, key):
191 res = cls.get_by_name(key)
192 if not res:
193 res = cls(key)
194 return res
188
195
189 @classmethod
196 @classmethod
190 def get_app_settings(cls, cache=False):
197 def get_app_settings(cls, cache=False):
@@ -589,8 +596,8 b' class Repository(Base, BaseModel):'
589 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
596 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
590 stats = relationship('Statistics', cascade='all', uselist=False)
597 stats = relationship('Statistics', cascade='all', uselist=False)
591
598
592 followers = relationship('UserFollowing',
599 followers = relationship('UserFollowing',
593 primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id',
600 primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id',
594 cascade='all')
601 cascade='all')
595
602
596 logs = relationship('UserLog')
603 logs = relationship('UserLog')
@@ -1547,7 +1554,7 b' class PullRequest(Base, BaseModel):'
1547 self._revisions = ':'.join(val)
1554 self._revisions = ':'.join(val)
1548
1555
1549 author = relationship('User', lazy='joined')
1556 author = relationship('User', lazy='joined')
1550 reviewers = relationship('PullRequestReviewers',
1557 reviewers = relationship('PullRequestReviewers',
1551 cascade="all, delete, delete-orphan")
1558 cascade="all, delete, delete-orphan")
1552 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1559 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1553 other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
1560 other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
@@ -242,23 +242,30 b' def ApplicationSettingsForm():'
242 return _ApplicationSettingsForm
242 return _ApplicationSettingsForm
243
243
244
244
245 def ApplicationVisualisationForm():
246 class _ApplicationVisualisationForm(formencode.Schema):
247 allow_extra_fields = True
248 filter_extra_fields = False
249 rhodecode_show_public_icon = v.StringBoolean(if_missing=False)
250 rhodecode_show_private_icon = v.StringBoolean(if_missing=False)
251 rhodecode_stylify_metatags = v.StringBoolean(if_missing=False)
252
253 return _ApplicationVisualisationForm
254
255
245 def ApplicationUiSettingsForm():
256 def ApplicationUiSettingsForm():
246 class _ApplicationUiSettingsForm(formencode.Schema):
257 class _ApplicationUiSettingsForm(formencode.Schema):
247 allow_extra_fields = True
258 allow_extra_fields = True
248 filter_extra_fields = False
259 filter_extra_fields = False
249 web_push_ssl = v.OneOf(['true', 'false'], if_missing='false')
260 web_push_ssl = v.StringBoolean(if_missing=False)
250 paths_root_path = All(
261 paths_root_path = All(
251 v.ValidPath(),
262 v.ValidPath(),
252 v.UnicodeString(strip=True, min=1, not_empty=True)
263 v.UnicodeString(strip=True, min=1, not_empty=True)
253 )
264 )
254 hooks_changegroup_update = v.OneOf(['True', 'False'],
265 hooks_changegroup_update = v.StringBoolean(if_missing=False)
255 if_missing=False)
266 hooks_changegroup_repo_size = v.StringBoolean(if_missing=False)
256 hooks_changegroup_repo_size = v.OneOf(['True', 'False'],
267 hooks_changegroup_push_logger = v.StringBoolean(if_missing=False)
257 if_missing=False)
268 hooks_preoutgoing_pull_logger = v.StringBoolean(if_missing=False)
258 hooks_changegroup_push_logger = v.OneOf(['True', 'False'],
259 if_missing=False)
260 hooks_preoutgoing_pull_logger = v.OneOf(['True', 'False'],
261 if_missing=False)
262
269
263 return _ApplicationUiSettingsForm
270 return _ApplicationUiSettingsForm
264
271
@@ -268,7 +275,7 b' def DefaultPermissionsForm(perms_choices'
268 allow_extra_fields = True
275 allow_extra_fields = True
269 filter_extra_fields = True
276 filter_extra_fields = True
270 overwrite_default = v.StringBoolean(if_missing=False)
277 overwrite_default = v.StringBoolean(if_missing=False)
271 anonymous = v.OneOf(['True', 'False'], if_missing=False)
278 anonymous = v.StringBoolean(if_missing=False)
272 default_perm = v.OneOf(perms_choices)
279 default_perm = v.OneOf(perms_choices)
273 default_register = v.OneOf(register_choices)
280 default_register = v.OneOf(register_choices)
274 default_create = v.OneOf(create_choices)
281 default_create = v.OneOf(create_choices)
@@ -1827,6 +1827,81 b' div.form div.fields div.field div.button'
1827
1827
1828 }
1828 }
1829
1829
1830 #summary .metatag {
1831 display: inline-block;
1832 padding: 3px 5px;
1833 margin-bottom: 3px;
1834 margin-right: 1px;
1835 border-radius: 5px;
1836 }
1837
1838 #content div.box #summary p {
1839 margin-bottom: -5px;
1840 width: 600px;
1841 white-space: pre-wrap;
1842 }
1843
1844 #content div.box #summary p:last-child {
1845 margin-bottom: 9px;
1846 }
1847
1848 #content div.box #summary p:first-of-type {
1849 margin-top: 9px;
1850 }
1851
1852 .metatag {
1853 display: inline-block;
1854 margin-right: 1px;
1855 -webkit-border-radius: 4px 4px 4px 4px;
1856 -khtml-border-radius: 4px 4px 4px 4px;
1857 -moz-border-radius: 4px 4px 4px 4px;
1858 border-radius: 4px 4px 4px 4px;
1859
1860 border: solid 1px #9CF;
1861 padding: 2px 3px 2px 3px !important;
1862 background-color: #DEF;
1863 }
1864
1865 .metatag[tag="dead"] {
1866 background-color: #E44;
1867 }
1868
1869 .metatag[tag="stale"] {
1870 background-color: #EA4;
1871 }
1872
1873 .metatag[tag="featured"] {
1874 background-color: #AEA;
1875 }
1876
1877 .metatag[tag="requires"] {
1878 background-color: #9CF;
1879 }
1880
1881 .metatag[tag="recommends"] {
1882 background-color: #BDF;
1883 }
1884
1885 .metatag[tag="lang"] {
1886 background-color: #FAF474;
1887 }
1888
1889 .metatag[tag="license"] {
1890 border: solid 1px #9CF;
1891 background-color: #DEF;
1892 target-new: tab !important;
1893 }
1894 .metatag[tag="see"] {
1895 border: solid 1px #CBD;
1896 background-color: #EDF;
1897 }
1898
1899 a.metatag[tag="license"]:hover {
1900 background-color: #003367;
1901 color: #FFF;
1902 text-decoration: none;
1903 }
1904
1830 #summary .desc {
1905 #summary .desc {
1831 white-space: pre;
1906 white-space: pre;
1832 width: 100%;
1907 width: 100%;
@@ -116,6 +116,63 b''
116 </div>
116 </div>
117 ${h.end_form()}
117 ${h.end_form()}
118
118
119 <h3>${_('Visualisation settings')}</h3>
120 ${h.form(url('admin_setting', setting_id='visual'),method='put')}
121 <div class="form">
122 <!-- fields -->
123
124 <div class="fields">
125
126 <div class="field">
127 <div class="label label-checkbox">
128 <label>${_('Icons')}:</label>
129 </div>
130 <div class="checkboxes">
131 <div class="checkbox">
132 ${h.checkbox('rhodecode_show_public_icon','True')}
133 <label for="rhodecode_show_public_icon">${_('Show public repo icon on repositories')}</label>
134 </div>
135 <div class="checkbox">
136 ${h.checkbox('rhodecode_show_private_icon','True')}
137 <label for="rhodecode_show_private_icon">${_('Show private repo icon on repositories')}</label>
138 </div>
139 </div>
140 </div>
141
142 <div class="field">
143 <div class="label label-checkbox">
144 <label>${_('Meta-Tagging')}:</label>
145 </div>
146 <div class="checkboxes">
147 <div class="checkbox">
148 ${h.checkbox('rhodecode_stylify_metatags','True')}
149 <label for="rhodecode_stylify_metatags">${_('Stylify recognised metatags:')}</label>
150 </div>
151 <div style="padding-left: 20px;">
152 <ul> <!-- Fix style here -->
153 <li>[featured] <span class="metatag" tag="featured">featured</span></li>
154 <li>[stale] <span class="metatag" tag="stale">stale</span></li>
155 <li>[dead] <span class="metatag" tag="dead">dead</span></li>
156 <li>[lang =&gt; lang] <span class="metatag" tag="lang" >lang</span></li>
157 <li>[license =&gt; License] <span class="metatag" tag="license"><a href="http://www.opensource.org/licenses/License" >License</a></span></li>
158 <li>[requires =&gt; Repo] <span class="metatag" tag="requires" >requires =&gt; <a href="#" >Repo</a></span></li>
159 <li>[recommends =&gt; Repo] <span class="metatag" tag="recommends" >recommends =&gt; <a href="#" >Repo</a></span></li>
160 <li>[see =&gt; URI] <span class="metatag" tag="see">see =&gt; <a href="#">URI</a> </span></li>
161 </ul>
162 </div>
163 </div>
164 </div>
165
166 <div class="buttons">
167 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
168 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
169 </div>
170
171 </div>
172 </div>
173 ${h.end_form()}
174
175
119 <h3>${_('VCS settings')}</h3>
176 <h3>${_('VCS settings')}</h3>
120 ${h.form(url('admin_setting', setting_id='vcs'),method='put')}
177 ${h.form(url('admin_setting', setting_id='vcs'),method='put')}
121 <div class="form">
178 <div class="form">
@@ -63,10 +63,10 b''
63 %endif
63 %endif
64
64
65 ##PRIVATE/PUBLIC
65 ##PRIVATE/PUBLIC
66 %if private:
66 %if private and c.visual.show_private_icon:
67 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
67 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
68 %else:
68 %elif not private and c.visual.show_public_icon:
69 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
69 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
70 %endif
70 %endif
71
71
72 ##NAME
72 ##NAME
@@ -108,4 +108,3 b''
108 <%def name="user_name(user_id, username)">
108 <%def name="user_name(user_id, username)">
109 ${h.link_to(username,h.url('edit_user', id=user_id))}
109 ${h.link_to(username,h.url('edit_user', id=user_id))}
110 </%def>
110 </%def>
111
@@ -41,7 +41,11 b''
41 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
41 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
42 </div>
42 </div>
43 </td>
43 </td>
44 <td>${gr.group_description}</td>
44 %if c.visual.stylify_metatags:
45 <td>${h.desc_stylize(gr.group_description)}</td>
46 %else:
47 <td>${gr.group_description}</td>
48 %endif
45 ## this is commented out since for multi nested repos can be HEAVY!
49 ## this is commented out since for multi nested repos can be HEAVY!
46 ## in number of executed queries during traversing uncomment at will
50 ## in number of executed queries during traversing uncomment at will
47 ##<td><b>${gr.repositories_recursive_count}</b></td>
51 ##<td><b>${gr.repositories_recursive_count}</b></td>
@@ -85,7 +89,11 b''
85 </td>
89 </td>
86 ##DESCRIPTION
90 ##DESCRIPTION
87 <td><span class="tooltip" title="${h.tooltip(repo['description'])}">
91 <td><span class="tooltip" title="${h.tooltip(repo['description'])}">
92 %if c.visual.stylify_metatags:
93 ${h.urlify_text(h.desc_stylize(h.truncate(repo['description'],60)))}</span>
94 %else:
88 ${h.truncate(repo['description'],60)}</span>
95 ${h.truncate(repo['description'],60)}</span>
96 %endif
89 </td>
97 </td>
90 ##LAST CHANGE DATE
98 ##LAST CHANGE DATE
91 <td>
99 <td>
@@ -128,9 +128,9 b''
128 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
128 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
129 %endif
129 %endif
130
130
131 %if entry.follows_repository.private:
131 %if entry.follows_repository.private and c.visual.show_private_icon:
132 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
132 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
133 %else:
133 %elif not entry.follows_repository.private and c.visual.show_public_icon:
134 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
134 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
135 %endif
135 %endif
136 <span class="watched_repo">
136 <span class="watched_repo">
@@ -6,12 +6,12 b''
6
6
7 %for repo in c.repos_list:
7 %for repo in c.repos_list:
8
8
9 %if repo['dbrepo']['private']:
9 %if repo['dbrepo']['private'] and c.visual.show_private_icon:
10 <li>
10 <li>
11 <img src="${h.url('/images/icons/lock.png')}" alt="${_('Private repository')}" class="repo_switcher_type"/>
11 <img src="${h.url('/images/icons/lock.png')}" alt="${_('Private repository')}" class="repo_switcher_type"/>
12 ${h.link_to(repo['name'],h.url('summary_home',repo_name=repo['name']),class_="repo_name %s" % repo['dbrepo']['repo_type'])}
12 ${h.link_to(repo['name'],h.url('summary_home',repo_name=repo['name']),class_="repo_name %s" % repo['dbrepo']['repo_type'])}
13 </li>
13 </li>
14 %else:
14 %elif not repo['dbrepo']['private'] and c.visual.show_public_icon:
15 <li>
15 <li>
16 <img src="${h.url('/images/icons/lock_open.png')}" alt="${_('Public repository')}" class="repo_switcher_type" />
16 <img src="${h.url('/images/icons/lock_open.png')}" alt="${_('Public repository')}" class="repo_switcher_type" />
17 ${h.link_to(repo['name'],h.url('summary_home',repo_name=repo['name']),class_="repo_name %s" % repo['dbrepo']['repo_type'])}
17 ${h.link_to(repo['name'],h.url('summary_home',repo_name=repo['name']),class_="repo_name %s" % repo['dbrepo']['repo_type'])}
@@ -104,7 +104,11 b''
104 <div class="label-summary">
104 <div class="label-summary">
105 <label>${_('Description')}:</label>
105 <label>${_('Description')}:</label>
106 </div>
106 </div>
107 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
107 %if c.visual.stylify_metatags:
108 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(h.desc_stylize(c.dbrepo.description))}</div>
109 %else:
110 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
111 %endif
108 </div>
112 </div>
109
113
110 <div class="field">
114 <div class="field">
@@ -131,3 +131,19 b' class TestLibs(unittest.TestCase):'
131 self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[n.month-1] + 2))),
131 self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[n.month-1] + 2))),
132 u'1 month and 2 days ago')
132 u'1 month and 2 days ago')
133 self.assertEqual(age(n - delt(hours=24 * 400)), u'1 year and 1 month ago')
133 self.assertEqual(age(n - delt(hours=24 * 400)), u'1 year and 1 month ago')
134
135 def test_tag_exctrator(self):
136 sample = (
137 "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]"
138 "[requires] [stale] [see<>=>] [see => http://url.com]"
139 "[requires => url] [lang => python] [just a tag]"
140 "[,d] [ => ULR ] [obsolete] [desc]]"
141 )
142 from rhodecode.lib.helpers import desc_stylize
143 res = desc_stylize(sample)
144 self.assertTrue('<div class="metatag" tag="tag">tag</div>' in res)
145 self.assertTrue('<div class="metatag" tag="obsolete">obsolete</div>' in res)
146 self.assertTrue('<div class="metatag" tag="stale">stale</div>' in res)
147 self.assertTrue('<div class="metatag" tag="lang">python</div>' in res)
148 self.assertTrue('<div class="metatag" tag="requires">requires =&gt; <a href="/url">url</a></div>' in res)
149 self.assertTrue('<div class="metatag" tag="tag">tag</div>' in res)
General Comments 0
You need to be logged in to leave comments. Login now