diff --git a/rhodecode/controllers/admin/repos.py b/rhodecode/controllers/admin/repos.py --- a/rhodecode/controllers/admin/repos.py +++ b/rhodecode/controllers/admin/repos.py @@ -144,20 +144,21 @@ class ReposController(BaseController): template = _tmpl_lookup.get_template('data_table/_dt_elements.html') quick_menu = lambda repo_name: (template.get_def("quick_menu") - .render(repo_name, _=_, h=h)) + .render(repo_name, _=_, h=h, c=c)) repo_lnk = lambda name, rtype, private, fork_of: ( template.get_def("repo_name") - .render(name, rtype, private, fork_of, short_name=False, - admin=True, _=_, h=h)) + .render(name, rtype, private, fork_of, short_name=False, + admin=True, _=_, h=h, c=c)) repo_actions = lambda repo_name: (template.get_def("repo_actions") - .render(repo_name, _=_, h=h)) + .render(repo_name, _=_, h=h, c=c)) for repo in c.repos_list: repos_data.append({ "menu": quick_menu(repo.repo_name), "raw_name": repo.repo_name, - "name": repo_lnk(repo.repo_name, repo.repo_type, repo.private, repo.fork), + "name": repo_lnk(repo.repo_name, repo.repo_type, + repo.private, repo.fork), "desc": repo.description, "owner": repo.user.username, "action": repo_actions(repo.repo_name), diff --git a/rhodecode/controllers/admin/settings.py b/rhodecode/controllers/admin/settings.py --- a/rhodecode/controllers/admin/settings.py +++ b/rhodecode/controllers/admin/settings.py @@ -45,7 +45,7 @@ from rhodecode.lib.utils import repo2db_ from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \ RhodeCodeSetting, PullRequest, PullRequestReviewers from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \ - ApplicationUiSettingsForm + ApplicationUiSettingsForm, ApplicationVisualisationForm from rhodecode.model.scm import ScmModel from rhodecode.model.user import UserModel from rhodecode.model.db import User @@ -143,15 +143,15 @@ class SettingsController(BaseController) ) try: - sett1 = RhodeCodeSetting.get_by_name('title') + sett1 = RhodeCodeSetting.get_by_name_or_create('title') sett1.app_settings_value = form_result['rhodecode_title'] Session().add(sett1) - sett2 = RhodeCodeSetting.get_by_name('realm') + sett2 = RhodeCodeSetting.get_by_name_or_create('realm') sett2.app_settings_value = form_result['rhodecode_realm'] Session().add(sett2) - sett3 = RhodeCodeSetting.get_by_name('ga_code') + sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code') sett3.app_settings_value = form_result['rhodecode_ga_code'] Session().add(sett3) @@ -165,6 +165,47 @@ class SettingsController(BaseController) 'application settings'), category='error') + if setting_id == 'visual': + + application_form = ApplicationVisualisationForm()() + try: + form_result = application_form.to_python(dict(request.POST)) + except formencode.Invalid, errors: + return htmlfill.render( + render('admin/settings/settings.html'), + defaults=errors.value, + errors=errors.error_dict or {}, + prefix_error=False, + encoding="UTF-8" + ) + + try: + sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon') + sett1.app_settings_value = \ + form_result['rhodecode_show_public_icon'] + + sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon') + sett2.app_settings_value = \ + form_result['rhodecode_show_private_icon'] + + sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags') + sett3.app_settings_value = \ + form_result['rhodecode_stylify_metatags'] + + Session().add(sett1) + Session().add(sett2) + Session().add(sett3) + Session().commit() + set_rhodecode_config(config) + h.flash(_('Updated visualisation settings'), + category='success') + + except Exception: + log.error(traceback.format_exc()) + h.flash(_('error occurred during updating ' + 'visualisation settings'), + category='error') + if setting_id == 'vcs': application_form = ApplicationUiSettingsForm()() try: diff --git a/rhodecode/controllers/admin/users.py b/rhodecode/controllers/admin/users.py --- a/rhodecode/controllers/admin/users.py +++ b/rhodecode/controllers/admin/users.py @@ -78,15 +78,15 @@ class UsersController(BaseController): grav_tmpl = lambda user_email, size: ( template.get_def("user_gravatar") - .render(user_email, size, _=_, h=h)) + .render(user_email, size, _=_, h=h, c=c)) user_lnk = lambda user_id, username: ( template.get_def("user_name") - .render(user_id, username, _=_, h=h)) + .render(user_id, username, _=_, h=h, c=c)) user_actions = lambda user_id, username: ( template.get_def("user_actions") - .render(user_id, username, _=_, h=h)) + .render(user_id, username, _=_, h=h, c=c)) for user in c.users_list: users_data.append({ diff --git a/rhodecode/lib/base.py b/rhodecode/lib/base.py --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -17,7 +17,7 @@ from pylons.templating import render_mak from rhodecode import __version__, BACKENDS -from rhodecode.lib.utils2 import str2bool, safe_unicode +from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\ HasPermissionAnyMiddleware, CookieStoreWrapper from rhodecode.lib.utils import get_repo_slug, invalidate_cache @@ -158,7 +158,7 @@ class BaseVCSController(object): log.debug('proto is %s and SSL is required BAD REQUEST !' % org_proto) return False - return True + return True def __call__(self, environ, start_response): start = time.time() @@ -178,6 +178,12 @@ class BaseController(WSGIController): c.rhodecode_name = config.get('rhodecode_title') c.use_gravatar = str2bool(config.get('use_gravatar')) c.ga_code = config.get('rhodecode_ga_code') + # Visual options + c.visual = AttributeDict({}) + c.visual.show_public_icon = str2bool(config.get('rhodecode_show_public_icon')) + c.visual.show_private_icon = str2bool(config.get('rhodecode_show_private_icon')) + c.visual.stylify_metatags = str2bool(config.get('rhodecode_stylify_metatags')) + c.repo_name = get_repo_slug(request) c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel()\ diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -9,6 +9,7 @@ import StringIO import urllib import math import logging +import re from datetime import datetime from pygments.formatters.html import HtmlFormatter @@ -430,6 +431,26 @@ def person(author): return _author +def desc_stylize(value): + """ + converts tags from value into html equivalent + + :param value: + """ + value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]', + '
', value) + value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]', + ' ', value) + value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z\-\/]*)\]', + ' ', value) + value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/]*)\]', + ' ', value) + value = re.sub(r'\[([a-z]+)\]', + ' ', value) + + return value + + def bool2icon(value): """Returns True/False values represented as small html image of true/false icons diff --git a/rhodecode/lib/utils2.py b/rhodecode/lib/utils2.py --- a/rhodecode/lib/utils2.py +++ b/rhodecode/lib/utils2.py @@ -443,3 +443,9 @@ def extract_mentioned_users(s): usrs.add(username) return sorted(list(usrs), key=lambda k: k.lower()) + +class AttributeDict(dict): + def __getattr__(self, attr): + return self.get(attr, None) + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -182,9 +182,16 @@ class RhodeCodeSetting(Base, BaseModel): ) @classmethod - def get_by_name(cls, ldap_key): + def get_by_name(cls, key): return cls.query()\ - .filter(cls.app_settings_name == ldap_key).scalar() + .filter(cls.app_settings_name == key).scalar() + + @classmethod + def get_by_name_or_create(cls, key): + res = cls.get_by_name(key) + if not res: + res = cls(key) + return res @classmethod def get_app_settings(cls, cache=False): @@ -589,8 +596,8 @@ class Repository(Base, BaseModel): users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all') stats = relationship('Statistics', cascade='all', uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', + followers = relationship('UserFollowing', + primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') logs = relationship('UserLog') @@ -1547,7 +1554,7 @@ class PullRequest(Base, BaseModel): self._revisions = ':'.join(val) author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', + reviewers = relationship('PullRequestReviewers', cascade="all, delete, delete-orphan") org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -242,23 +242,30 @@ def ApplicationSettingsForm(): return _ApplicationSettingsForm +def ApplicationVisualisationForm(): + class _ApplicationVisualisationForm(formencode.Schema): + allow_extra_fields = True + filter_extra_fields = False + rhodecode_show_public_icon = v.StringBoolean(if_missing=False) + rhodecode_show_private_icon = v.StringBoolean(if_missing=False) + rhodecode_stylify_metatags = v.StringBoolean(if_missing=False) + + return _ApplicationVisualisationForm + + def ApplicationUiSettingsForm(): class _ApplicationUiSettingsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False - web_push_ssl = v.OneOf(['true', 'false'], if_missing='false') + web_push_ssl = v.StringBoolean(if_missing=False) paths_root_path = All( v.ValidPath(), v.UnicodeString(strip=True, min=1, not_empty=True) ) - hooks_changegroup_update = v.OneOf(['True', 'False'], - if_missing=False) - hooks_changegroup_repo_size = v.OneOf(['True', 'False'], - if_missing=False) - hooks_changegroup_push_logger = v.OneOf(['True', 'False'], - if_missing=False) - hooks_preoutgoing_pull_logger = v.OneOf(['True', 'False'], - if_missing=False) + hooks_changegroup_update = v.StringBoolean(if_missing=False) + hooks_changegroup_repo_size = v.StringBoolean(if_missing=False) + hooks_changegroup_push_logger = v.StringBoolean(if_missing=False) + hooks_preoutgoing_pull_logger = v.StringBoolean(if_missing=False) return _ApplicationUiSettingsForm @@ -268,7 +275,7 @@ def DefaultPermissionsForm(perms_choices allow_extra_fields = True filter_extra_fields = True overwrite_default = v.StringBoolean(if_missing=False) - anonymous = v.OneOf(['True', 'False'], if_missing=False) + anonymous = v.StringBoolean(if_missing=False) default_perm = v.OneOf(perms_choices) default_register = v.OneOf(register_choices) default_create = v.OneOf(create_choices) diff --git a/rhodecode/public/css/style.css b/rhodecode/public/css/style.css --- a/rhodecode/public/css/style.css +++ b/rhodecode/public/css/style.css @@ -1827,6 +1827,81 @@ div.form div.fields div.field div.button } +#summary .metatag { + display: inline-block; + padding: 3px 5px; + margin-bottom: 3px; + margin-right: 1px; + border-radius: 5px; +} + +#content div.box #summary p { + margin-bottom: -5px; + width: 600px; + white-space: pre-wrap; +} + +#content div.box #summary p:last-child { + margin-bottom: 9px; +} + +#content div.box #summary p:first-of-type { + margin-top: 9px; +} + + .metatag { + display: inline-block; + margin-right: 1px; + -webkit-border-radius: 4px 4px 4px 4px; + -khtml-border-radius: 4px 4px 4px 4px; + -moz-border-radius: 4px 4px 4px 4px; + border-radius: 4px 4px 4px 4px; + + border: solid 1px #9CF; + padding: 2px 3px 2px 3px !important; + background-color: #DEF; +} + +.metatag[tag="dead"] { + background-color: #E44; +} + +.metatag[tag="stale"] { + background-color: #EA4; +} + +.metatag[tag="featured"] { + background-color: #AEA; +} + +.metatag[tag="requires"] { + background-color: #9CF; +} + +.metatag[tag="recommends"] { + background-color: #BDF; +} + +.metatag[tag="lang"] { + background-color: #FAF474; +} + +.metatag[tag="license"] { + border: solid 1px #9CF; + background-color: #DEF; + target-new: tab !important; +} +.metatag[tag="see"] { + border: solid 1px #CBD; + background-color: #EDF; +} + +a.metatag[tag="license"]:hover { + background-color: #003367; + color: #FFF; + text-decoration: none; +} + #summary .desc { white-space: pre; width: 100%; diff --git a/rhodecode/templates/admin/settings/settings.html b/rhodecode/templates/admin/settings/settings.html --- a/rhodecode/templates/admin/settings/settings.html +++ b/rhodecode/templates/admin/settings/settings.html @@ -116,6 +116,63 @@ ${h.end_form()} +