Mercurial > kallithea
changeset 8721:67e5b90801aa
lib: move webhelpers2 and friends to webutils
Gives less of the unfortunate use of helpers - especially in low level libs.
line wrap: on
line diff
--- a/kallithea/controllers/admin/auth_settings.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/auth_settings.py Sun Nov 01 04:59:46 2020 +0100 @@ -32,8 +32,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPFound -from kallithea.lib import auth_modules -from kallithea.lib import helpers as h +from kallithea.lib import auth_modules, webutils from kallithea.lib.auth import HasPermissionAnyDecorator, LoginRequired from kallithea.lib.base import BaseController, render from kallithea.lib.webutils import url @@ -132,7 +131,7 @@ log.debug("%s = %s", k, str(v)) setting = db.Setting.create_or_update(k, v) meta.Session().commit() - h.flash(_('Auth settings updated successfully'), + webutils.flash(_('Auth settings updated successfully'), category='success') except formencode.Invalid as errors: log.error(traceback.format_exc()) @@ -143,7 +142,7 @@ ) except Exception: log.error(traceback.format_exc()) - h.flash(_('error occurred during update of auth settings'), + webutils.flash(_('error occurred during update of auth settings'), category='error') raise HTTPFound(location=url('auth_home'))
--- a/kallithea/controllers/admin/defaults.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/defaults.py Sun Nov 01 04:59:46 2020 +0100 @@ -34,7 +34,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPFound -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import HasPermissionAnyDecorator, LoginRequired from kallithea.lib.base import BaseController, render from kallithea.lib.webutils import url @@ -70,7 +70,7 @@ for k, v in form_result.items(): setting = db.Setting.create_or_update(k, v) meta.Session().commit() - h.flash(_('Default settings updated successfully'), + webutils.flash(_('Default settings updated successfully'), category='success') except formencode.Invalid as errors: @@ -85,7 +85,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of defaults'), + webutils.flash(_('Error occurred during update of defaults'), category='error') raise HTTPFound(location=url('defaults'))
--- a/kallithea/controllers/admin/gists.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/gists.py Sun Nov 01 04:59:46 2020 +0100 @@ -35,8 +35,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPForbidden, HTTPFound, HTTPNotFound -from kallithea.lib import auth -from kallithea.lib import helpers as h +from kallithea.lib import auth, webutils from kallithea.lib.auth import LoginRequired from kallithea.lib.base import BaseController, jsonify, render from kallithea.lib.page import Page @@ -144,7 +143,7 @@ except Exception as e: log.error(traceback.format_exc()) - h.flash(_('Error occurred during gist creation'), category='error') + webutils.flash(_('Error occurred during gist creation'), category='error') raise HTTPFound(location=url('new_gist')) raise HTTPFound(location=url('gist', gist_id=new_gist_id)) @@ -160,7 +159,7 @@ if auth.HasPermissionAny('hg.admin')() or owner: GistModel().delete(gist) meta.Session().commit() - h.flash(_('Deleted gist %s') % gist.gist_access_id, category='success') + webutils.flash(_('Deleted gist %s') % gist.gist_access_id, category='success') else: raise HTTPForbidden() @@ -233,15 +232,15 @@ ) meta.Session().commit() - h.flash(_('Successfully updated gist content'), category='success') + webutils.flash(_('Successfully updated gist content'), category='success') except NodeNotChangedError: # raised if nothing was changed in repo itself. We anyway then # store only DB stuff for gist meta.Session().commit() - h.flash(_('Successfully updated gist data'), category='success') + webutils.flash(_('Successfully updated gist data'), category='success') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of gist %s') % gist_id, + webutils.flash(_('Error occurred during update of gist %s') % gist_id, category='error') raise HTTPFound(location=url('gist', gist_id=gist_id))
--- a/kallithea/controllers/admin/my_account.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/my_account.py Sun Nov 01 04:59:46 2020 +0100 @@ -35,8 +35,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPFound -from kallithea.lib import auth_modules -from kallithea.lib import helpers as h +from kallithea.lib import auth_modules, webutils from kallithea.lib.auth import AuthUser, LoginRequired from kallithea.lib.base import BaseController, IfSshEnabled, render from kallithea.lib.utils2 import generate_api_key, safe_int @@ -61,7 +60,7 @@ def __load_data(self): c.user = db.User.get(request.authuser.user_id) if c.user.is_default_user: - h.flash(_("You can't edit this user since it's" + webutils.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') raise HTTPFound(location=url('users')) @@ -110,7 +109,7 @@ UserModel().update(request.authuser.user_id, form_result, skip_attrs=skip_attrs) - h.flash(_('Your account was updated successfully'), + webutils.flash(_('Your account was updated successfully'), category='success') meta.Session().commit() update = True @@ -125,7 +124,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of user %s') + webutils.flash(_('Error occurred during update of user %s') % form_result.get('username'), category='error') if update: raise HTTPFound(location='my_account') @@ -148,7 +147,7 @@ form_result = _form.to_python(request.POST) UserModel().update(request.authuser.user_id, form_result) meta.Session().commit() - h.flash(_("Successfully updated password"), category='success') + webutils.flash(_("Successfully updated password"), category='success') except formencode.Invalid as errors: return htmlfill.render( render('admin/my_account/my_account.html'), @@ -159,7 +158,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of user password'), + webutils.flash(_('Error occurred during update of user password'), category='error') return render('admin/my_account/my_account.html') @@ -200,13 +199,13 @@ try: UserModel().add_extra_email(request.authuser.user_id, email) meta.Session().commit() - h.flash(_("Added email %s to user") % email, category='success') + webutils.flash(_("Added email %s to user") % email, category='success') except formencode.Invalid as error: msg = error.error_dict['email'] - h.flash(msg, category='error') + webutils.flash(msg, category='error') except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during email saving'), + webutils.flash(_('An error occurred during email saving'), category='error') raise HTTPFound(location=url('my_account_emails')) @@ -215,7 +214,7 @@ user_model = UserModel() user_model.delete_extra_email(request.authuser.user_id, email_id) meta.Session().commit() - h.flash(_("Removed email from user"), category='success') + webutils.flash(_("Removed email from user"), category='success') raise HTTPFound(location=url('my_account_emails')) def my_account_api_keys(self): @@ -239,7 +238,7 @@ description = request.POST.get('description') ApiKeyModel().create(request.authuser.user_id, description, lifetime) meta.Session().commit() - h.flash(_("API key successfully created"), category='success') + webutils.flash(_("API key successfully created"), category='success') raise HTTPFound(location=url('my_account_api_keys')) def my_account_api_keys_delete(self): @@ -248,11 +247,11 @@ user = db.User.get(request.authuser.user_id) user.api_key = generate_api_key() meta.Session().commit() - h.flash(_("API key successfully reset"), category='success') + webutils.flash(_("API key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, request.authuser.user_id) meta.Session().commit() - h.flash(_("API key successfully deleted"), category='success') + webutils.flash(_("API key successfully deleted"), category='success') raise HTTPFound(location=url('my_account_api_keys')) @@ -272,9 +271,9 @@ description, public_key) meta.Session().commit() SshKeyModel().write_authorized_keys() - h.flash(_("SSH key %s successfully added") % new_ssh_key.fingerprint, category='success') + webutils.flash(_("SSH key %s successfully added") % new_ssh_key.fingerprint, category='success') except SshKeyModelException as e: - h.flash(e.args[0], category='error') + webutils.flash(e.args[0], category='error') raise HTTPFound(location=url('my_account_ssh_keys')) @IfSshEnabled @@ -284,7 +283,7 @@ SshKeyModel().delete(fingerprint, request.authuser.user_id) meta.Session().commit() SshKeyModel().write_authorized_keys() - h.flash(_("SSH key successfully deleted"), category='success') + webutils.flash(_("SSH key successfully deleted"), category='success') except SshKeyModelException as e: - h.flash(e.args[0], category='error') + webutils.flash(e.args[0], category='error') raise HTTPFound(location=url('my_account_ssh_keys'))
--- a/kallithea/controllers/admin/permissions.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/permissions.py Sun Nov 01 04:59:46 2020 +0100 @@ -36,7 +36,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPFound -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator, LoginRequired from kallithea.lib.base import BaseController, render from kallithea.lib.webutils import url @@ -113,7 +113,7 @@ form_result.update({'perm_user_name': 'default'}) PermissionModel().update(form_result) meta.Session().commit() - h.flash(_('Global permissions updated successfully'), + webutils.flash(_('Global permissions updated successfully'), category='success') except formencode.Invalid as errors: @@ -128,7 +128,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of permissions'), + webutils.flash(_('Error occurred during update of permissions'), category='error') raise HTTPFound(location=url('admin_permissions'))
--- a/kallithea/controllers/admin/repo_groups.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/repo_groups.py Sun Nov 01 04:59:46 2020 +0100 @@ -37,6 +37,7 @@ from webob.exc import HTTPForbidden, HTTPFound, HTTPInternalServerError, HTTPNotFound from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import HasPermissionAny, HasRepoGroupPermissionLevel, HasRepoGroupPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseController, render from kallithea.lib.utils2 import safe_int @@ -118,7 +119,7 @@ repo_groups_data.append({ "raw_name": repo_gr.group_name, "group_name": repo_group_name(repo_gr.group_name, children_groups), - "desc": h.escape(repo_gr.group_description), + "desc": webutils.escape(repo_gr.group_description), "repos": repo_count, "owner": h.person(repo_gr.owner), "action": repo_group_actions(repo_gr.group_id, repo_gr.group_name, @@ -161,14 +162,14 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during creation of repository group %s') + webutils.flash(_('Error occurred during creation of repository group %s') % request.POST.get('group_name'), category='error') if form_result is None: raise parent_group_id = form_result['parent_group_id'] # TODO: maybe we should get back to the main view, not the admin one raise HTTPFound(location=url('repos_groups', parent_group=parent_group_id)) - h.flash(_('Created repository group %s') % gr.group_name, + webutils.flash(_('Created repository group %s') % gr.group_name, category='success') raise HTTPFound(location=url('repos_group_home', group_name=gr.group_name)) @@ -215,7 +216,7 @@ new_gr = RepoGroupModel().update(group_name, form_result) meta.Session().commit() - h.flash(_('Updated repository group %s') + webutils.flash(_('Updated repository group %s') % form_result['group_name'], category='success') # we now have new name ! group_name = new_gr.group_name @@ -231,7 +232,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of repository group %s') + webutils.flash(_('Error occurred during update of repository group %s') % request.POST.get('group_name'), category='error') raise HTTPFound(location=url('edit_repo_group', group_name=group_name)) @@ -241,25 +242,25 @@ gr = c.repo_group = db.RepoGroup.guess_instance(group_name) repos = gr.repositories.all() if repos: - h.flash(_('This group contains %s repositories and cannot be ' + webutils.flash(_('This group contains %s repositories and cannot be ' 'deleted') % len(repos), category='warning') raise HTTPFound(location=url('repos_groups')) children = gr.children.all() if children: - h.flash(_('This group contains %s subgroups and cannot be deleted' + webutils.flash(_('This group contains %s subgroups and cannot be deleted' % (len(children))), category='warning') raise HTTPFound(location=url('repos_groups')) try: RepoGroupModel().delete(group_name) meta.Session().commit() - h.flash(_('Removed repository group %s') % group_name, + webutils.flash(_('Removed repository group %s') % group_name, category='success') # TODO: in future action_logger(, '', '', '') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during deletion of repository group %s') + webutils.flash(_('Error occurred during deletion of repository group %s') % group_name, category='error') if gr.parent_group: @@ -344,7 +345,7 @@ if not request.authuser.is_admin: if self._revoke_perms_on_yourself(form_result): msg = _('Cannot revoke permission for yourself as admin') - h.flash(msg, category='warning') + webutils.flash(msg, category='warning') raise HTTPFound(location=url('edit_repo_group_perms', group_name=group_name)) recursive = form_result['recursive'] # iterate over all members(if in recursive mode) of this groups and @@ -358,7 +359,7 @@ #action_logger(request.authuser, 'admin_changed_repo_permissions', # repo_name, request.ip_addr) meta.Session().commit() - h.flash(_('Repository group permissions updated'), category='success') + webutils.flash(_('Repository group permissions updated'), category='success') raise HTTPFound(location=url('edit_repo_group_perms', group_name=group_name)) @HasRepoGroupPermissionLevelDecorator('admin') @@ -374,7 +375,7 @@ if not request.authuser.is_admin: if obj_type == 'user' and request.authuser.user_id == obj_id: msg = _('Cannot revoke permission for yourself as admin') - h.flash(msg, category='warning') + webutils.flash(msg, category='warning') raise Exception('revoke admin permission on self') recursive = request.POST.get('recursive', 'none') if obj_type == 'user': @@ -390,6 +391,6 @@ meta.Session().commit() except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during revoking of permission'), + webutils.flash(_('An error occurred during revoking of permission'), category='error') raise HTTPInternalServerError()
--- a/kallithea/controllers/admin/repos.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/repos.py Sun Nov 01 04:59:46 2020 +0100 @@ -37,7 +37,6 @@ from webob.exc import HTTPForbidden, HTTPFound, HTTPInternalServerError, HTTPNotFound import kallithea -from kallithea.lib import helpers as h from kallithea.lib import webutils from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired, NotAnonymous from kallithea.lib.base import BaseRepoController, jsonify, render @@ -125,7 +124,7 @@ log.error(traceback.format_exc()) msg = (_('Error creating repository %s') % form_result.get('repo_name')) - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPFound(location=url('home')) raise HTTPFound(location=webutils.url('repo_creating_home', @@ -179,19 +178,19 @@ repo = db.Repository.get_by_repo_name(repo_name) if repo and repo.repo_state == db.Repository.STATE_CREATED: if repo.clone_uri: - h.flash(_('Created repository %s from %s') + webutils.flash(_('Created repository %s from %s') % (repo.repo_name, repo.clone_uri_hidden), category='success') else: - repo_url = h.link_to(repo.repo_name, + repo_url = webutils.link_to(repo.repo_name, webutils.url('summary_home', repo_name=repo.repo_name)) fork = repo.fork if fork is not None: fork_name = fork.repo_name - h.flash(h.HTML(_('Forked repository %s as %s')) + webutils.flash(webutils.HTML(_('Forked repository %s as %s')) % (fork_name, repo_url), category='success') else: - h.flash(h.HTML(_('Created repository %s')) % repo_url, + webutils.flash(webutils.HTML(_('Created repository %s')) % repo_url, category='success') return {'result': True} return {'result': False} @@ -220,7 +219,7 @@ form_result = _form.to_python(dict(request.POST)) repo = repo_model.update(repo_name, **form_result) ScmModel().mark_for_invalidation(repo_name) - h.flash(_('Repository %s updated successfully') % repo_name, + webutils.flash(_('Repository %s updated successfully') % repo_name, category='success') changed_name = repo.repo_name action_logger(request.authuser, 'admin_updated_repo', @@ -240,7 +239,7 @@ except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of repository %s') + webutils.flash(_('Error occurred during update of repository %s') % repo_name, category='error') raise HTTPFound(location=url('edit_repo', repo_name=changed_name)) @@ -257,23 +256,23 @@ do = request.POST['forks'] if do == 'detach_forks': handle_forks = 'detach' - h.flash(_('Detached %s forks') % _forks, category='success') + webutils.flash(_('Detached %s forks') % _forks, category='success') elif do == 'delete_forks': handle_forks = 'delete' - h.flash(_('Deleted %s forks') % _forks, category='success') + webutils.flash(_('Deleted %s forks') % _forks, category='success') repo_model.delete(repo, forks=handle_forks) action_logger(request.authuser, 'admin_deleted_repo', repo_name, request.ip_addr) ScmModel().mark_for_invalidation(repo_name) - h.flash(_('Deleted repository %s') % repo_name, category='success') + webutils.flash(_('Deleted repository %s') % repo_name, category='success') meta.Session().commit() except AttachedForksError: - h.flash(_('Cannot delete repository %s which still has forks') + webutils.flash(_('Cannot delete repository %s which still has forks') % repo_name, category='warning') except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during deletion of %s') % repo_name, + webutils.flash(_('An error occurred during deletion of %s') % repo_name, category='error') if repo.group: @@ -313,7 +312,7 @@ #action_logger(request.authuser, 'admin_changed_repo_permissions', # repo_name, request.ip_addr) meta.Session().commit() - h.flash(_('Repository permissions updated'), category='success') + webutils.flash(_('Repository permissions updated'), category='success') raise HTTPFound(location=url('edit_repo_perms', repo_name=repo_name)) @HasRepoPermissionLevelDecorator('admin') @@ -342,7 +341,7 @@ meta.Session().commit() except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during revoking of permission'), + webutils.flash(_('An error occurred during revoking of permission'), category='error') raise HTTPInternalServerError() return [] @@ -372,10 +371,10 @@ meta.Session().add(new_field) meta.Session().commit() except formencode.Invalid as e: - h.flash(_('Field validation error: %s') % e.msg, category='error') + webutils.flash(_('Field validation error: %s') % e.msg, category='error') except Exception as e: log.error(traceback.format_exc()) - h.flash(_('An error occurred during creation of field: %r') % e, category='error') + webutils.flash(_('An error occurred during creation of field: %r') % e, category='error') raise HTTPFound(location=url('edit_repo_fields', repo_name=repo_name)) @HasRepoPermissionLevelDecorator('admin') @@ -387,7 +386,7 @@ except Exception as e: log.error(traceback.format_exc()) msg = _('An error occurred during removal of field') - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPFound(location=url('edit_repo_fields', repo_name=repo_name)) @HasRepoPermissionLevelDecorator('admin') @@ -432,11 +431,11 @@ repo_id = db.Repository.get_by_repo_name(repo_name).repo_id user_id = kallithea.DEFAULT_USER_ID self.scm_model.toggle_following_repo(repo_id, user_id) - h.flash(_('Updated repository visibility in public journal'), + webutils.flash(_('Updated repository visibility in public journal'), category='success') meta.Session().commit() except Exception: - h.flash(_('An error occurred during setting this' + webutils.flash(_('An error occurred during setting this' ' repository in public journal'), category='error') raise HTTPFound(location=url('edit_repo_advanced', repo_name=repo_name)) @@ -454,14 +453,14 @@ request.authuser.username) fork = repo.fork.repo_name if repo.fork else _('Nothing') meta.Session().commit() - h.flash(_('Marked repository %s as fork of %s') % (repo_name, fork), + webutils.flash(_('Marked repository %s as fork of %s') % (repo_name, fork), category='success') except RepositoryError as e: log.error(traceback.format_exc()) - h.flash(e, category='error') + webutils.flash(e, category='error') except Exception as e: log.error(traceback.format_exc()) - h.flash(_('An error occurred during this operation'), + webutils.flash(_('An error occurred during this operation'), category='error') raise HTTPFound(location=url('edit_repo_advanced', repo_name=repo_name)) @@ -473,10 +472,10 @@ if request.POST: try: ScmModel().pull_changes(repo_name, request.authuser.username, request.ip_addr) - h.flash(_('Pulled from remote location'), category='success') + webutils.flash(_('Pulled from remote location'), category='success') except Exception as e: log.error(traceback.format_exc()) - h.flash(_('An error occurred during pull from remote location'), + webutils.flash(_('An error occurred during pull from remote location'), category='error') raise HTTPFound(location=url('edit_repo_remote', repo_name=c.repo_name)) return render('admin/repos/repo_edit.html') @@ -507,7 +506,7 @@ meta.Session().commit() except Exception as e: log.error(traceback.format_exc()) - h.flash(_('An error occurred during deletion of repository stats'), + webutils.flash(_('An error occurred during deletion of repository stats'), category='error') raise HTTPFound(location=url('edit_repo_statistics', repo_name=c.repo_name))
--- a/kallithea/controllers/admin/settings.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/settings.py Sun Nov 01 04:59:46 2020 +0100 @@ -35,7 +35,6 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPFound -from kallithea.lib import helpers as h from kallithea.lib import webutils from kallithea.lib.auth import HasPermissionAnyDecorator, LoginRequired from kallithea.lib.base import BaseController, render @@ -114,11 +113,11 @@ meta.Session().commit() - h.flash(_('Updated VCS settings'), category='success') + webutils.flash(_('Updated VCS settings'), category='success') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred while updating ' + webutils.flash(_('Error occurred while updating ' 'application settings'), category='error') defaults = db.Setting.get_app_settings() @@ -147,13 +146,13 @@ install_git_hooks=install_git_hooks, user=request.authuser.username, overwrite_git_hooks=overwrite_git_hooks) - added_msg = h.HTML(', ').join( - h.link_to(safe_str(repo_name), webutils.url('summary_home', repo_name=repo_name)) for repo_name in added + added_msg = webutils.HTML(', ').join( + webutils.link_to(safe_str(repo_name), webutils.url('summary_home', repo_name=repo_name)) for repo_name in added ) or '-' - removed_msg = h.HTML(', ').join( + removed_msg = webutils.HTML(', ').join( safe_str(repo_name) for repo_name in removed ) or '-' - h.flash(h.HTML(_('Repositories successfully rescanned. Added: %s. Removed: %s.')) % + webutils.flash(webutils.HTML(_('Repositories successfully rescanned. Added: %s. Removed: %s.')) % (added_msg, removed_msg), category='success') if invalidate_cache: @@ -165,7 +164,7 @@ i += 1 except VCSError as e: log.warning('VCS error invalidating %s: %s', repo.repo_name, e) - h.flash(_('Invalidated %s repositories') % i, category='success') + webutils.flash(_('Invalidated %s repositories') % i, category='success') raise HTTPFound(location=url('admin_settings_mapping')) @@ -206,11 +205,11 @@ meta.Session().commit() set_app_settings(config) - h.flash(_('Updated application settings'), category='success') + webutils.flash(_('Updated application settings'), category='success') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred while updating ' + webutils.flash(_('Error occurred while updating ' 'application settings'), category='error') @@ -260,12 +259,12 @@ meta.Session().commit() set_app_settings(config) - h.flash(_('Updated visualisation settings'), + webutils.flash(_('Updated visualisation settings'), category='success') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during updating ' + webutils.flash(_('Error occurred during updating ' 'visualisation settings'), category='error') @@ -289,7 +288,7 @@ test_body = ('Kallithea Email test, ' 'Kallithea version: %s' % c.kallithea_version) if not test_email: - h.flash(_('Please enter email address'), category='error') + webutils.flash(_('Please enter email address'), category='error') raise HTTPFound(location=url('admin_settings_email')) test_email_txt_body = EmailNotificationModel() \ @@ -304,7 +303,7 @@ tasks.send_email(recipients, test_email_subj, test_email_txt_body, test_email_html_body) - h.flash(_('Send email task created'), category='success') + webutils.flash(_('Send email task created'), category='success') raise HTTPFound(location=url('admin_settings_email')) defaults = db.Setting.get_app_settings() @@ -332,12 +331,12 @@ try: ui_key = ui_key and ui_key.strip() if ui_key in (x.ui_key for x in db.Ui.get_custom_hooks()): - h.flash(_('Hook already exists'), category='error') + webutils.flash(_('Hook already exists'), category='error') elif ui_key in (x.ui_key for x in db.Ui.get_builtin_hooks()): - h.flash(_('Builtin hooks are read-only. Please use another hook name.'), category='error') + webutils.flash(_('Builtin hooks are read-only. Please use another hook name.'), category='error') elif ui_value and ui_key: db.Ui.create_or_update_hook(ui_key, ui_value) - h.flash(_('Added new hook'), category='success') + webutils.flash(_('Added new hook'), category='success') elif hook_id: db.Ui.delete(hook_id) meta.Session().commit() @@ -353,11 +352,11 @@ update = True if update: - h.flash(_('Updated hooks'), category='success') + webutils.flash(_('Updated hooks'), category='success') meta.Session().commit() except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during hook creation'), + webutils.flash(_('Error occurred during hook creation'), category='error') raise HTTPFound(location=url('admin_settings_hooks')) @@ -381,7 +380,7 @@ repo_location = self._get_hg_ui_settings()['paths_root_path'] full_index = request.POST.get('full_index', False) tasks.whoosh_index(repo_location, full_index) - h.flash(_('Whoosh reindex task scheduled'), category='success') + webutils.flash(_('Whoosh reindex task scheduled'), category='success') raise HTTPFound(location=url('admin_settings_search')) defaults = db.Setting.get_app_settings()
--- a/kallithea/controllers/admin/user_groups.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/user_groups.py Sun Nov 01 04:59:46 2020 +0100 @@ -38,6 +38,7 @@ from webob.exc import HTTPFound, HTTPInternalServerError from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import HasPermissionAnyDecorator, HasUserGroupPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseController, render from kallithea.lib.exceptions import RepoGroupAssignmentError, UserGroupsAssignedException @@ -100,7 +101,7 @@ "raw_name": user_gr.users_group_name, "group_name": user_group_name(user_gr.users_group_id, user_gr.users_group_name), - "desc": h.escape(user_gr.user_group_description), + "desc": webutils.escape(user_gr.user_group_description), "members": len(user_gr.members), "active": h.boolicon(user_gr.users_group_active), "owner": h.person(user_gr.owner.username), @@ -129,7 +130,7 @@ action_logger(request.authuser, 'admin_created_users_group:%s' % gr, None, request.ip_addr) - h.flash(h.HTML(_('Created user group %s')) % h.link_to(gr, url('edit_users_group', id=ug.users_group_id)), + webutils.flash(webutils.HTML(_('Created user group %s')) % webutils.link_to(gr, url('edit_users_group', id=ug.users_group_id)), category='success') meta.Session().commit() except formencode.Invalid as errors: @@ -142,7 +143,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during creation of user group %s') + webutils.flash(_('Error occurred during creation of user group %s') % request.POST.get('users_group_name'), category='error') raise HTTPFound(location=url('users_groups')) @@ -170,7 +171,7 @@ action_logger(request.authuser, 'admin_updated_users_group:%s' % gr, None, request.ip_addr) - h.flash(_('Updated user group %s') % gr, category='success') + webutils.flash(_('Updated user group %s') % gr, category='success') meta.Session().commit() except formencode.Invalid as errors: ug_model = UserGroupModel() @@ -192,7 +193,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of user group %s') + webutils.flash(_('Error occurred during update of user group %s') % request.POST.get('users_group_name'), category='error') raise HTTPFound(location=url('edit_users_group', id=id)) @@ -203,12 +204,12 @@ try: UserGroupModel().delete(usr_gr) meta.Session().commit() - h.flash(_('Successfully deleted user group'), category='success') + webutils.flash(_('Successfully deleted user group'), category='success') except UserGroupsAssignedException as e: - h.flash(e, category='error') + webutils.flash(e, category='error') except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during deletion of user group'), + webutils.flash(_('An error occurred during deletion of user group'), category='error') raise HTTPFound(location=url('users_groups')) @@ -264,13 +265,13 @@ UserGroupModel()._update_permissions(user_group, form['perms_new'], form['perms_updates']) except RepoGroupAssignmentError: - h.flash(_('Target group cannot be the same'), category='error') + webutils.flash(_('Target group cannot be the same'), category='error') raise HTTPFound(location=url('edit_user_group_perms', id=id)) # TODO: implement this #action_logger(request.authuser, 'admin_changed_repo_permissions', # repo_name, request.ip_addr) meta.Session().commit() - h.flash(_('User group permissions updated'), category='success') + webutils.flash(_('User group permissions updated'), category='success') raise HTTPFound(location=url('edit_user_group_perms', id=id)) @HasUserGroupPermissionLevelDecorator('admin') @@ -286,7 +287,7 @@ if not request.authuser.is_admin: if obj_type == 'user' and request.authuser.user_id == obj_id: msg = _('Cannot revoke permission for yourself as admin') - h.flash(msg, category='warning') + webutils.flash(msg, category='warning') raise Exception('revoke admin permission on self') if obj_type == 'user': UserGroupModel().revoke_user_permission(user_group=id, @@ -297,7 +298,7 @@ meta.Session().commit() except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during revoking of permission'), + webutils.flash(_('An error occurred during revoking of permission'), category='error') raise HTTPInternalServerError() @@ -379,11 +380,11 @@ else: usergroup_model.grant_perm(id, 'hg.fork.none') - h.flash(_("Updated permissions"), category='success') + webutils.flash(_("Updated permissions"), category='success') meta.Session().commit() except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during permissions saving'), + webutils.flash(_('An error occurred during permissions saving'), category='error') raise HTTPFound(location=url('edit_user_group_default_perms', id=id))
--- a/kallithea/controllers/admin/users.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/admin/users.py Sun Nov 01 04:59:46 2020 +0100 @@ -39,6 +39,7 @@ import kallithea from kallithea.lib import auth_modules from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator, LoginRequired from kallithea.lib.base import BaseController, IfSshEnabled, render from kallithea.lib.exceptions import DefaultUserException, UserCreationError, UserOwnsReposException @@ -87,8 +88,8 @@ "gravatar": grav_tmpl % h.gravatar(user.email, size=20), "raw_name": user.username, "username": username(user.user_id, user.username), - "firstname": h.escape(user.name), - "lastname": h.escape(user.lastname), + "firstname": webutils.escape(user.name), + "lastname": webutils.escape(user.lastname), "last_login": h.fmt_date(user.last_login), "last_login_raw": datetime_to_time(user.last_login), "active": h.boolicon(user.active), @@ -116,7 +117,7 @@ user = user_model.create(form_result) action_logger(request.authuser, 'admin_created_user:%s' % user.username, None, request.ip_addr) - h.flash(_('Created user %s') % user.username, + webutils.flash(_('Created user %s') % user.username, category='success') meta.Session().commit() except formencode.Invalid as errors: @@ -128,10 +129,10 @@ encoding="UTF-8", force_defaults=False) except UserCreationError as e: - h.flash(e, 'error') + webutils.flash(e, 'error') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during creation of user %s') + webutils.flash(_('Error occurred during creation of user %s') % request.POST.get('username'), category='error') raise HTTPFound(location=url('edit_user', id=user.user_id)) @@ -155,7 +156,7 @@ usr = form_result['username'] action_logger(request.authuser, 'admin_updated_user:%s' % usr, None, request.ip_addr) - h.flash(_('User updated successfully'), category='success') + webutils.flash(_('User updated successfully'), category='success') meta.Session().commit() except formencode.Invalid as errors: defaults = errors.value @@ -174,7 +175,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during update of user %s') + webutils.flash(_('Error occurred during update of user %s') % form_result.get('username'), category='error') raise HTTPFound(location=url('edit_user', id=id)) @@ -184,12 +185,12 @@ try: UserModel().delete(usr) meta.Session().commit() - h.flash(_('Successfully deleted user'), category='success') + webutils.flash(_('Successfully deleted user'), category='success') except (UserOwnsReposException, DefaultUserException) as e: - h.flash(e, category='warning') + webutils.flash(e, category='warning') except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during deletion of user'), + webutils.flash(_('An error occurred during deletion of user'), category='error') else: if has_ssh_keys: @@ -200,7 +201,7 @@ try: return db.User.get_or_404(id, allow_default=False) except DefaultUserException: - h.flash(_("The default user cannot be edited"), category='warning') + webutils.flash(_("The default user cannot be edited"), category='warning') raise HTTPNotFound def _render_edit_profile(self, user): @@ -268,7 +269,7 @@ description = request.POST.get('description') ApiKeyModel().create(c.user.user_id, description, lifetime) meta.Session().commit() - h.flash(_("API key successfully created"), category='success') + webutils.flash(_("API key successfully created"), category='success') raise HTTPFound(location=url('edit_user_api_keys', id=c.user.user_id)) def delete_api_key(self, id): @@ -278,11 +279,11 @@ if request.POST.get('del_api_key_builtin'): c.user.api_key = generate_api_key() meta.Session().commit() - h.flash(_("API key successfully reset"), category='success') + webutils.flash(_("API key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, c.user.user_id) meta.Session().commit() - h.flash(_("API key successfully deleted"), category='success') + webutils.flash(_("API key successfully deleted"), category='success') raise HTTPFound(location=url('edit_user_api_keys', id=c.user.user_id)) @@ -335,11 +336,11 @@ user_model.grant_perm(id, 'hg.fork.repository') else: user_model.grant_perm(id, 'hg.fork.none') - h.flash(_("Updated permissions"), category='success') + webutils.flash(_("Updated permissions"), category='success') meta.Session().commit() except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during permissions saving'), + webutils.flash(_('An error occurred during permissions saving'), category='error') raise HTTPFound(location=url('edit_user_perms', id=id)) @@ -364,13 +365,13 @@ try: user_model.add_extra_email(id, email) meta.Session().commit() - h.flash(_("Added email %s to user") % email, category='success') + webutils.flash(_("Added email %s to user") % email, category='success') except formencode.Invalid as error: msg = error.error_dict['email'] - h.flash(msg, category='error') + webutils.flash(msg, category='error') except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during email saving'), + webutils.flash(_('An error occurred during email saving'), category='error') raise HTTPFound(location=url('edit_user_emails', id=id)) @@ -380,7 +381,7 @@ user_model = UserModel() user_model.delete_extra_email(id, email_id) meta.Session().commit() - h.flash(_("Removed email from user"), category='success') + webutils.flash(_("Removed email from user"), category='success') raise HTTPFound(location=url('edit_user_emails', id=id)) def edit_ips(self, id): @@ -406,13 +407,13 @@ try: user_model.add_extra_ip(id, ip) meta.Session().commit() - h.flash(_("Added IP address %s to user whitelist") % ip, category='success') + webutils.flash(_("Added IP address %s to user whitelist") % ip, category='success') except formencode.Invalid as error: msg = error.error_dict['ip'] - h.flash(msg, category='error') + webutils.flash(msg, category='error') except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred while adding IP address'), + webutils.flash(_('An error occurred while adding IP address'), category='error') if 'default_user' in request.POST: @@ -424,7 +425,7 @@ user_model = UserModel() user_model.delete_extra_ip(id, ip_id) meta.Session().commit() - h.flash(_("Removed IP address from user whitelist"), category='success') + webutils.flash(_("Removed IP address from user whitelist"), category='success') if 'default_user' in request.POST: raise HTTPFound(location=url('admin_permissions_ips')) @@ -453,9 +454,9 @@ description, public_key) meta.Session().commit() SshKeyModel().write_authorized_keys() - h.flash(_("SSH key %s successfully added") % new_ssh_key.fingerprint, category='success') + webutils.flash(_("SSH key %s successfully added") % new_ssh_key.fingerprint, category='success') except SshKeyModelException as e: - h.flash(e.args[0], category='error') + webutils.flash(e.args[0], category='error') raise HTTPFound(location=url('edit_user_ssh_keys', id=c.user.user_id)) @IfSshEnabled @@ -467,7 +468,7 @@ SshKeyModel().delete(fingerprint, c.user.user_id) meta.Session().commit() SshKeyModel().write_authorized_keys() - h.flash(_("SSH key successfully deleted"), category='success') + webutils.flash(_("SSH key successfully deleted"), category='success') except SshKeyModelException as e: - h.flash(e.args[0], category='error') + webutils.flash(e.args[0], category='error') raise HTTPFound(location=url('edit_user_ssh_keys', id=c.user.user_id))
--- a/kallithea/controllers/changelog.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/changelog.py Sun Nov 01 04:59:46 2020 +0100 @@ -33,7 +33,6 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPBadRequest, HTTPFound, HTTPNotFound -import kallithea.lib.helpers as h from kallithea.lib import webutils from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, render @@ -65,10 +64,10 @@ try: return c.db_repo_scm_instance.get_changeset(rev) except EmptyRepositoryError as e: - h.flash(_('There are no changesets yet'), category='error') + webutils.flash(_('There are no changesets yet'), category='error') except RepositoryError as e: log.error(traceback.format_exc()) - h.flash(e, category='error') + webutils.flash(e, category='error') raise HTTPBadRequest() @LoginRequired(allow_default_user=True) @@ -112,7 +111,7 @@ cs = self.__get_cs(revision, repo_name) collection = cs.get_file_history(f_path) except RepositoryError as e: - h.flash(e, category='warning') + webutils.flash(e, category='warning') raise HTTPFound(location=webutils.url('changelog_home', repo_name=repo_name)) else: collection = c.db_repo_scm_instance.get_changesets(start=0, end=revision, @@ -126,11 +125,11 @@ c.cs_comments = c.db_repo.get_comments(page_revisions) c.cs_statuses = c.db_repo.statuses(page_revisions) except EmptyRepositoryError as e: - h.flash(e, category='warning') + webutils.flash(e, category='warning') raise HTTPFound(location=url('summary_home', repo_name=c.repo_name)) except (RepositoryError, ChangesetDoesNotExistError, Exception) as e: log.error(traceback.format_exc()) - h.flash(e, category='error') + webutils.flash(e, category='error') raise HTTPFound(location=url('changelog_home', repo_name=c.repo_name)) c.branch_name = branch_name
--- a/kallithea/controllers/changeset.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/changeset.py Sun Nov 01 04:59:46 2020 +0100 @@ -86,7 +86,7 @@ if not allowed_to_change_status: if status or close_pr: - h.flash(_('No permission to change status'), 'error') + webutils.flash(_('No permission to change status'), 'error') raise HTTPForbidden() if pull_request and delete == "delete": @@ -97,7 +97,7 @@ ) and not pull_request.is_closed(): PullRequestModel().delete(pull_request) meta.Session().commit() - h.flash(_('Successfully deleted pull request %s') % pull_request_id, + webutils.flash(_('Successfully deleted pull request %s') % pull_request_id, category='success') return { 'location': webutils.url('my_pullrequests'), # or repo pr list? @@ -143,7 +143,7 @@ meta.Session().commit() data = { - 'target_id': h.safeid(request.POST.get('f_path')), + 'target_id': webutils.safeid(request.POST.get('f_path')), } if comment is not None: c.comment = comment @@ -199,7 +199,7 @@ except (ChangesetDoesNotExistError, EmptyRepositoryError): log.debug(traceback.format_exc()) msg = _('Such revision does not exist for this repository') - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPNotFound() c.changes = OrderedDict()
--- a/kallithea/controllers/compare.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/compare.py Sun Nov 01 04:59:46 2020 +0100 @@ -63,13 +63,13 @@ c.cs_repo = db.Repository.get_by_repo_name(other_repo) if c.cs_repo is None: msg = _('Could not find other repository %s') % other_repo - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPFound(location=url('compare_home', repo_name=c.a_repo.repo_name)) # Verify that it's even possible to compare these two repositories. if c.a_repo.scm_instance.alias != c.cs_repo.scm_instance.alias: msg = _('Cannot compare repositories of different types') - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPFound(location=url('compare_home', repo_name=c.a_repo.repo_name)) @LoginRequired(allow_default_user=True) @@ -146,7 +146,7 @@ else: msg = _('Multiple merge ancestors found for merge compare') if rev1 is None: - h.flash(msg, category='error') + webutils.flash(msg, category='error') log.error(msg) raise HTTPNotFound @@ -160,7 +160,7 @@ if org_repo != other_repo: # TODO: we could do this by using hg unionrepo log.error('cannot compare across repos %s and %s', org_repo, other_repo) - h.flash(_('Cannot compare repositories without using common ancestor'), category='error') + webutils.flash(_('Cannot compare repositories without using common ancestor'), category='error') raise HTTPBadRequest rev1 = c.a_rev
--- a/kallithea/controllers/files.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/files.py Sun Nov 01 04:59:46 2020 +0100 @@ -83,15 +83,15 @@ url_ = url('files_add_home', repo_name=c.repo_name, revision=0, f_path='', anchor='edit') - add_new = h.link_to(_('Click here to add new file'), url_, class_="alert-link") - h.flash(_('There are no files yet.') + ' ' + add_new, category='warning') + add_new = webutils.link_to(_('Click here to add new file'), url_, class_="alert-link") + webutils.flash(_('There are no files yet.') + ' ' + add_new, category='warning') raise HTTPNotFound() except (ChangesetDoesNotExistError, LookupError): msg = _('Such revision does not exist for this repository') - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPNotFound() except RepositoryError as e: - h.flash(e, category='error') + webutils.flash(e, category='error') raise HTTPNotFound() def __get_filenode(self, cs, path): @@ -108,10 +108,10 @@ raise RepositoryError('given path is a directory') except ChangesetDoesNotExistError: msg = _('Such revision does not exist for this repository') - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPNotFound() except RepositoryError as e: - h.flash(e, category='error') + webutils.flash(e, category='error') raise HTTPNotFound() return file_node @@ -176,7 +176,7 @@ else: c.authors = c.file_history = [] except RepositoryError as e: - h.flash(e, category='error') + webutils.flash(e, category='error') raise HTTPNotFound() if request.environ.get('HTTP_X_PARTIAL_XHR'): @@ -293,7 +293,7 @@ _branches = repo.scm_instance.branches # check if revision is a branch name or branch hash if revision not in _branches and revision not in _branches.values(): - h.flash(_('You can only delete files with revision ' + webutils.flash(_('You can only delete files with revision ' 'being a valid branch'), category='warning') raise HTTPFound(location=webutils.url('files_home', repo_name=repo_name, revision='tip', @@ -328,11 +328,11 @@ author=author, ) - h.flash(_('Successfully deleted file %s') % f_path, + webutils.flash(_('Successfully deleted file %s') % f_path, category='success') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during commit'), category='error') + webutils.flash(_('Error occurred during commit'), category='error') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) @@ -347,7 +347,7 @@ _branches = repo.scm_instance.branches # check if revision is a branch name or branch hash if revision not in _branches and revision not in _branches.values(): - h.flash(_('You can only edit files with revision ' + webutils.flash(_('You can only edit files with revision ' 'being a valid branch'), category='warning') raise HTTPFound(location=webutils.url('files_home', repo_name=repo_name, revision='tip', @@ -376,7 +376,7 @@ author = request.authuser.full_contact if content == old_content: - h.flash(_('No changes'), category='warning') + webutils.flash(_('No changes'), category='warning') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) try: @@ -386,11 +386,11 @@ ip_addr=request.ip_addr, author=author, message=message, content=content, f_path=f_path) - h.flash(_('Successfully committed to %s') % f_path, + webutils.flash(_('Successfully committed to %s') % f_path, category='success') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during commit'), category='error') + webutils.flash(_('Error occurred during commit'), category='error') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) @@ -426,11 +426,11 @@ content = content.file if not content: - h.flash(_('No content'), category='warning') + webutils.flash(_('No content'), category='warning') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) if not filename: - h.flash(_('No filename'), category='warning') + webutils.flash(_('No filename'), category='warning') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) # strip all crap out of file, just leave the basename @@ -454,18 +454,18 @@ author=author, ) - h.flash(_('Successfully committed to %s') % node_path, + webutils.flash(_('Successfully committed to %s') % node_path, category='success') except NonRelativePathError as e: - h.flash(_('Location must be relative path and must not ' + webutils.flash(_('Location must be relative path and must not ' 'contain .. in path'), category='warning') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) except (NodeError, NodeAlreadyExistsError) as e: - h.flash(_(e), category='error') + webutils.flash(_(e), category='error') except Exception: log.error(traceback.format_exc()) - h.flash(_('Error occurred during commit'), category='error') + webutils.flash(_('Error occurred during commit'), category='error') raise HTTPFound(location=url('changeset_home', repo_name=c.repo_name, revision='tip')) @@ -687,7 +687,7 @@ node2 = FileNode(f_path, '', changeset=c.changeset_2) except ChangesetDoesNotExistError as e: msg = _('Such revision does not exist for this repository') - h.flash(msg, category='error') + webutils.flash(msg, category='error') raise HTTPNotFound() c.node1 = node1 c.node2 = node2
--- a/kallithea/controllers/forks.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/forks.py Sun Nov 01 04:59:46 2020 +0100 @@ -36,7 +36,6 @@ from webob.exc import HTTPFound, HTTPNotFound import kallithea -import kallithea.lib.helpers as h from kallithea.lib import webutils from kallithea.lib.auth import HasPermissionAnyDecorator, HasRepoPermissionLevel, HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, render @@ -166,7 +165,7 @@ force_defaults=False) except Exception: log.error(traceback.format_exc()) - h.flash(_('An error occurred during repository forking %s') % + webutils.flash(_('An error occurred during repository forking %s') % repo_name, category='error') raise HTTPFound(location=webutils.url('repo_creating_home',
--- a/kallithea/controllers/login.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/login.py Sun Nov 01 04:59:46 2020 +0100 @@ -36,7 +36,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPBadRequest, HTTPFound -import kallithea.lib.helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator from kallithea.lib.base import BaseController, log_in_user, render from kallithea.lib.exceptions import UserCreationError @@ -99,13 +99,13 @@ # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself - h.flash(e, 'error') + webutils.flash(e, 'error') else: # login_form already validated the password - now set the session cookie accordingly auth_user = log_in_user(user, c.form_result['remember'], is_external_auth=False, ip_addr=request.ip_addr) if auth_user: raise HTTPFound(location=c.came_from) - h.flash(_('Authentication failed.'), 'error') + webutils.flash(_('Authentication failed.'), 'error') else: # redirect if already logged in if not request.authuser.is_anonymous: @@ -144,7 +144,7 @@ error_dict=error_dict) UserModel().create_registration(form_result) - h.flash(_('You have successfully registered with %s') % (c.site_name or 'Kallithea'), + webutils.flash(_('You have successfully registered with %s') % (c.site_name or 'Kallithea'), category='success') meta.Session().commit() raise HTTPFound(location=url('login_home')) @@ -162,7 +162,7 @@ # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself - h.flash(e, 'error') + webutils.flash(e, 'error') return render('/register.html') @@ -188,7 +188,7 @@ raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) redirect_link = UserModel().send_reset_password_email(form_result) - h.flash(_('A password reset confirmation code has been sent'), + webutils.flash(_('A password reset confirmation code has been sent'), category='success') raise HTTPFound(location=redirect_link) @@ -240,7 +240,7 @@ encoding='UTF-8') UserModel().reset_password(form_result['email'], form_result['password']) - h.flash(_('Successfully updated password'), category='success') + webutils.flash(_('Successfully updated password'), category='success') raise HTTPFound(location=url('login_home')) def logout(self): @@ -254,4 +254,4 @@ Only intended for testing but might also be useful for other kinds of automation. """ - return h.session_csrf_secret_token() + return webutils.session_csrf_secret_token()
--- a/kallithea/controllers/pullrequests.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/pullrequests.py Sun Nov 01 04:59:46 2020 +0100 @@ -35,9 +35,9 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPFound, HTTPNotFound +import kallithea.lib.helpers as h from kallithea.controllers.changeset import create_cs_pr_comment, delete_cs_pr_comment -from kallithea.lib import auth, diffs -from kallithea.lib import helpers as h +from kallithea.lib import auth, diffs, webutils from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, jsonify, render from kallithea.lib.graphmod import graph_data @@ -63,7 +63,7 @@ user = None if user is None or user.is_default_user: - h.flash(_('Invalid reviewer "%s" specified') % user_id, category='error') + webutils.flash(_('Invalid reviewer "%s" specified') % user_id, category='error') raise HTTPBadRequest() return user @@ -245,7 +245,7 @@ try: org_scm_instance.get_changeset() except EmptyRepositoryError as e: - h.flash(_('There are no changesets yet'), + webutils.flash(_('There are no changesets yet'), category='warning') raise HTTPFound(location=url('summary_home', repo_name=org_repo.repo_name)) @@ -314,7 +314,7 @@ log.error(traceback.format_exc()) log.error(str(errors)) msg = _('Error creating pull request: %s') % errors.msg - h.flash(msg, 'error') + webutils.flash(msg, 'error') raise HTTPBadRequest # heads up: org and other might seem backward here ... @@ -333,19 +333,19 @@ try: cmd = CreatePullRequestAction(org_repo, other_repo, org_ref, other_ref, title, description, owner, reviewers) except CreatePullRequestAction.ValidationError as e: - h.flash(e, category='error', logf=log.error) + webutils.flash(e, category='error', logf=log.error) raise HTTPNotFound try: pull_request = cmd.execute() meta.Session().commit() except Exception: - h.flash(_('Error occurred while creating pull request'), + webutils.flash(_('Error occurred while creating pull request'), category='error') log.error(traceback.format_exc()) raise HTTPFound(location=url('pullrequest_home', repo_name=repo_name)) - h.flash(_('Successfully opened new pull request'), + webutils.flash(_('Successfully opened new pull request'), category='success') raise HTTPFound(location=pull_request.url()) @@ -356,19 +356,19 @@ try: cmd = CreatePullRequestIterationAction(old_pull_request, new_org_rev, new_other_rev, title, description, owner, reviewers) except CreatePullRequestAction.ValidationError as e: - h.flash(e, category='error', logf=log.error) + webutils.flash(e, category='error', logf=log.error) raise HTTPNotFound try: pull_request = cmd.execute() meta.Session().commit() except Exception: - h.flash(_('Error occurred while creating pull request'), + webutils.flash(_('Error occurred while creating pull request'), category='error') log.error(traceback.format_exc()) raise HTTPFound(location=old_pull_request.url()) - h.flash(_('New pull request iteration created'), + webutils.flash(_('New pull request iteration created'), category='success') raise HTTPFound(location=pull_request.url()) @@ -396,11 +396,11 @@ other_removed = old_reviewers - cur_reviewers if other_added: - h.flash(_('Meanwhile, the following reviewers have been added: %s') % + webutils.flash(_('Meanwhile, the following reviewers have been added: %s') % (', '.join(u.username for u in other_added)), category='warning') if other_removed: - h.flash(_('Meanwhile, the following reviewers have been removed: %s') % + webutils.flash(_('Meanwhile, the following reviewers have been removed: %s') % (', '.join(u.username for u in other_removed)), category='warning') @@ -425,7 +425,7 @@ PullRequestModel().remove_reviewers(user, pull_request, removed_reviewers) meta.Session().commit() - h.flash(_('Pull request updated'), category='success') + webutils.flash(_('Pull request updated'), category='success') raise HTTPFound(location=pull_request.url()) @@ -438,7 +438,7 @@ if pull_request.owner_id == request.authuser.user_id: PullRequestModel().delete(pull_request) meta.Session().commit() - h.flash(_('Successfully deleted pull request'), + webutils.flash(_('Successfully deleted pull request'), category='success') raise HTTPFound(location=url('my_pullrequests')) raise HTTPForbidden() @@ -474,7 +474,7 @@ c.cs_ranges.append(org_scm_instance.get_changeset(x)) except ChangesetDoesNotExistError: c.cs_ranges = [] - h.flash(_('Revision %s not found in %s') % (x, c.cs_repo.repo_name), + webutils.flash(_('Revision %s not found in %s') % (x, c.cs_repo.repo_name), 'error') break c.cs_ranges_org = None # not stored and not important and moving target - could be calculated ...
--- a/kallithea/controllers/summary.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/controllers/summary.py Sun Nov 01 04:59:46 2020 +0100 @@ -38,8 +38,7 @@ from tg.i18n import ugettext as _ from webob.exc import HTTPBadRequest -import kallithea.lib.helpers as h -from kallithea.lib import ext_json +from kallithea.lib import ext_json, webutils from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, jsonify, render from kallithea.lib.celerylib.tasks import get_commits_stats @@ -108,7 +107,7 @@ try: collection = c.db_repo_scm_instance.get_changesets(reverse=True) except EmptyRepositoryError as e: - h.flash(e, category='warning') + webutils.flash(e, category='warning') collection = [] c.cs_pagination = Page(collection, page=p, items_per_page=size) page_revisions = [x.raw_id for x in list(c.cs_pagination)]
--- a/kallithea/lib/auth.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/auth.py Sun Nov 01 04:59:46 2020 +0100 @@ -40,6 +40,7 @@ from webob.exc import HTTPForbidden, HTTPFound import kallithea +from kallithea.lib import webutils from kallithea.lib.utils import get_repo_group_slug, get_repo_slug, get_user_group_slug from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_bytes from kallithea.lib.vcs.utils.lazy import LazyProperty @@ -544,9 +545,8 @@ """Return an exception that must be raised. It will redirect to the login page which will redirect back to the current URL after authentication. The optional message will be shown in a flash message.""" - from kallithea.lib import helpers as h if message: - h.flash(message, category='warning') + webutils.flash(message, category='warning') p = request.path_qs log.debug('Redirecting to login page, origin: %s', p) return HTTPFound(location=url('login_home', came_from=p))
--- a/kallithea/lib/base.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/base.py Sun Nov 01 04:59:46 2020 +0100 @@ -44,7 +44,7 @@ from tg.i18n import ugettext as _ import kallithea -from kallithea.lib import auth_modules, ext_json +from kallithea.lib import auth_modules, ext_json, webutils from kallithea.lib.auth import AuthUser, HasPermissionAnyMiddleware from kallithea.lib.exceptions import UserCreationError from kallithea.lib.utils import get_repo_slug, is_valid_repo @@ -361,9 +361,8 @@ # guaranteed to be side effect free. In practice, the only situation # where we allow side effects without ambient authority is when the # authority comes from an API key; and that is handled above. - from kallithea.lib import helpers as h - token = request.POST.get(h.session_csrf_secret_name) - if not token or token != h.session_csrf_secret_token(): + token = request.POST.get(webutils.session_csrf_secret_name) + if not token or token != webutils.session_csrf_secret_token(): log.error('CSRF check failed') raise webob.exc.HTTPForbidden() @@ -444,8 +443,7 @@ try: user_info = auth_modules.authenticate('', '', request.environ) except UserCreationError as e: - from kallithea.lib import helpers as h - h.flash(e, 'error', logf=log.error) + webutils.flash(e, 'error', logf=log.error) else: if user_info is not None: username = user_info['username'] @@ -474,12 +472,11 @@ raise webob.exc.HTTPMethodNotAllowed() # Make sure CSRF token never appears in the URL. If so, invalidate it. - from kallithea.lib import helpers as h - if h.session_csrf_secret_name in request.GET: + if webutils.session_csrf_secret_name in request.GET: log.error('CSRF key leak detected') - session.pop(h.session_csrf_secret_name, None) + session.pop(webutils.session_csrf_secret_name, None) session.save() - h.flash(_('CSRF token leak has been detected - all form tokens have been expired'), + webutils.flash(_('CSRF token leak has been detected - all form tokens have been expired'), category='error') # WebOb already ignores request payload parameters for anything other @@ -575,8 +572,7 @@ if c.db_repo_scm_instance is None: log.error('%s this repository is present in database but it ' 'cannot be created as an scm instance', c.repo_name) - from kallithea.lib import helpers as h - h.flash(_('Repository not found in the filesystem'), + webutils.flash(_('Repository not found in the filesystem'), category='error') raise webob.exc.HTTPNotFound() @@ -592,22 +588,21 @@ """ Safe way to get changeset. If error occurs show error. """ - from kallithea.lib import helpers as h try: return repo.scm_instance.get_ref_revision(ref_type, ref_name) except EmptyRepositoryError as e: if returnempty: return repo.scm_instance.EMPTY_CHANGESET - h.flash(_('There are no changesets yet'), category='error') + webutils.flash(_('There are no changesets yet'), category='error') raise webob.exc.HTTPNotFound() except ChangesetDoesNotExistError as e: - h.flash(_('Changeset for %s %s not found in %s') % + webutils.flash(_('Changeset for %s %s not found in %s') % (ref_type, ref_name, repo.repo_name), category='error') raise webob.exc.HTTPNotFound() except RepositoryError as e: log.error(traceback.format_exc()) - h.flash(e, category='error') + webutils.flash(e, category='error') raise webob.exc.HTTPBadRequest() @@ -642,7 +637,6 @@ If SSH access is disabled in the configuration file, HTTPNotFound is raised. """ if not c.ssh_enabled: - from kallithea.lib import helpers as h - h.flash(_("SSH access is disabled."), category='warning') + webutils.flash(_("SSH access is disabled."), category='warning') raise webob.exc.HTTPNotFound() return func(*args, **kwargs)
--- a/kallithea/lib/diffs.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/diffs.py Sun Nov 01 04:59:46 2020 +0100 @@ -31,7 +31,7 @@ from tg.i18n import ugettext as _ -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.utils2 import safe_str from kallithea.lib.vcs.backends.base import EmptyChangeset from kallithea.lib.vcs.exceptions import VCSError @@ -207,7 +207,7 @@ if not html_diff: submodules = [o for o in [filenode_new, filenode_old] if isinstance(o, SubModuleNode)] if submodules: - html_diff = wrap_to_table(h.escape('Submodule %r' % submodules[0])) + html_diff = wrap_to_table(webutils.escape('Submodule %r' % submodules[0])) else: html_diff = wrap_to_table(_('No changes detected')) @@ -249,7 +249,7 @@ return scm_instance.get_diff(rev1, rev2, path=path, ignore_whitespace=ignore_whitespace, context=context) except MemoryError: - h.flash('MemoryError: Diff is too big', category='error') + webutils.flash('MemoryError: Diff is too big', category='error') return b''
--- a/kallithea/lib/helpers.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/helpers.py Sun Nov 01 04:59:46 2020 +0100 @@ -20,7 +20,6 @@ import hashlib import json import logging -import random import re import textwrap import urllib.parse @@ -28,16 +27,7 @@ from beaker.cache import cache_region from pygments import highlight as code_highlight from pygments.formatters.html import HtmlFormatter -from tg import session from tg.i18n import ugettext as _ -from webhelpers2.html import HTML, escape, literal -from webhelpers2.html.tags import NotGiven, Option, Options, _input, _make_safe_id_component, checkbox, end_form -from webhelpers2.html.tags import form as insecure_form -from webhelpers2.html.tags import hidden, link_to, password, radio -from webhelpers2.html.tags import select as webhelpers2_select -from webhelpers2.html.tags import submit, text, textarea -from webhelpers2.number import format_byte_size -from webhelpers2.text import chop_at, truncate, wrap_paragraphs import kallithea from kallithea.lib.annotate import annotate_highlight @@ -55,47 +45,49 @@ # SCM FILTERS available via h. #============================================================================== from kallithea.lib.vcs.utils import author_email, author_name -from kallithea.lib.webutils import canonical_url, url +from kallithea.lib.webutils import (HTML, Option, canonical_url, checkbox, chop_at, end_form, escape, form, format_byte_size, hidden, html_escape, link_to, + literal, password, pop_flash_messages, radio, reset, safeid, select, session_csrf_secret_name, session_csrf_secret_token, + submit, text, textarea, truncate, url, wrap_paragraphs) from kallithea.model import db from kallithea.model.changeset_status import ChangesetStatusModel # mute pyflakes "imported but unused" +# from webutils assert Option +assert canonical_url assert checkbox +assert chop_at assert end_form +assert form +assert format_byte_size +assert hidden assert password +assert pop_flash_messages assert radio +assert reset +assert safeid +assert select +assert session_csrf_secret_name +assert session_csrf_secret_token assert submit assert text assert textarea -assert format_byte_size -assert chop_at assert wrap_paragraphs +# from kallithea.lib.auth assert HasPermissionAny assert HasRepoGroupPermissionLevel assert HasRepoPermissionLevel +# from utils2 assert age assert time_to_datetime +# from vcs assert EmptyChangeset -assert canonical_url log = logging.getLogger(__name__) -def html_escape(s): - """Return string with all html escaped. - This is also safe for javascript in html but not necessarily correct. - """ - return (s - .replace('&', '&') - .replace(">", ">") - .replace("<", "<") - .replace('"', """) - .replace("'", "'") # Note: this is HTML5 not HTML4 and might not work in mails - ) - def js(value): """Convert Python value to the corresponding JavaScript representation. @@ -152,44 +144,6 @@ return s -def reset(name, value, id=NotGiven, **attrs): - """Create a reset button, similar to webhelpers2.html.tags.submit .""" - return _input("reset", name, value, id, attrs) - - -def select(name, selected_values, options, id=NotGiven, **attrs): - """Convenient wrapper of webhelpers2 to let it accept options as a tuple list""" - if isinstance(options, list): - option_list = options - # Handle old value,label lists ... where value also can be value,label lists - options = Options() - for x in option_list: - if isinstance(x, tuple) and len(x) == 2: - value, label = x - elif isinstance(x, str): - value = label = x - else: - log.error('invalid select option %r', x) - raise - if isinstance(value, list): - og = options.add_optgroup(label) - for x in value: - if isinstance(x, tuple) and len(x) == 2: - group_value, group_label = x - elif isinstance(x, str): - group_value = group_label = x - else: - log.error('invalid select option %r', x) - raise - og.add_option(group_label, group_value) - else: - options.add_option(label, value) - return webhelpers2_select(name, selected_values, options, id=id, **attrs) - - -safeid = _make_safe_id_component - - def FID(raw_id, path): """ Creates a unique ID for filenode based on it's hash of path and revision @@ -448,76 +402,6 @@ return literal(markup_whitespace(annotate_highlight(filenode, url_func, **kwargs))) -class _Message(object): - """A message returned by ``pop_flash_messages()``. - - Converting the message to a string returns the message text. Instances - also have the following attributes: - - * ``category``: the category specified when the message was created. - * ``message``: the html-safe message text. - """ - - def __init__(self, category, message): - self.category = category - self.message = message - - -def _session_flash_messages(append=None, clear=False): - """Manage a message queue in tg.session: return the current message queue - after appending the given message, and possibly clearing the queue.""" - key = 'flash' - if key in session: - flash_messages = session[key] - else: - if append is None: # common fast path - also used for clearing empty queue - return [] # don't bother saving - flash_messages = [] - session[key] = flash_messages - if append is not None and append not in flash_messages: - flash_messages.append(append) - if clear: - session.pop(key, None) - session.save() - return flash_messages - - -def flash(message, category, logf=None): - """ - Show a message to the user _and_ log it through the specified function - - category: notice (default), warning, error, success - logf: a custom log function - such as log.debug - - logf defaults to log.info, unless category equals 'success', in which - case logf defaults to log.debug. - """ - assert category in ('error', 'success', 'warning'), category - if hasattr(message, '__html__'): - # render to HTML for storing in cookie - safe_message = str(message) - else: - # Apply str - the message might be an exception with __str__ - # Escape, so we can trust the result without further escaping, without any risk of injection - safe_message = html_escape(str(message)) - if logf is None: - logf = log.info - if category == 'success': - logf = log.debug - - logf('Flash %s: %s', category, safe_message) - - _session_flash_messages(append=(category, safe_message)) - - -def pop_flash_messages(): - """Return all accumulated messages and delete them from the session. - - The return value is a list of ``Message`` objects. - """ - return [_Message(category, message) for category, message in _session_flash_messages(clear=True)] - - def capitalize(x): return x.capitalize() @@ -1317,23 +1201,3 @@ def ip_range(ip_addr): s, e = db.UserIpMap._get_ip_range(ip_addr) return '%s - %s' % (s, e) - - -session_csrf_secret_name = "_session_csrf_secret_token" - -def session_csrf_secret_token(): - """Return (and create) the current session's CSRF protection token.""" - if not session_csrf_secret_name in session: - session[session_csrf_secret_name] = str(random.getrandbits(128)) - session.save() - return session[session_csrf_secret_name] - -def form(url, method="post", **attrs): - """Like webhelpers.html.tags.form , but automatically adding - session_csrf_secret_token for POST. The secret is thus never leaked in GET - URLs. - """ - form = insecure_form(url, method, **attrs) - if method.lower() == 'get': - return form - return form + HTML.div(hidden(session_csrf_secret_name, session_csrf_secret_token()), style="display: none;")
--- a/kallithea/lib/hooks.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/hooks.py Sun Nov 01 04:59:46 2020 +0100 @@ -32,7 +32,7 @@ import mercurial.scmutil import kallithea -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.exceptions import UserCreationError from kallithea.lib.utils import action_logger, make_ui from kallithea.lib.utils2 import HookEnvironmentError, ascii_str, get_hook_environment, safe_bytes, safe_str @@ -59,9 +59,9 @@ except OSError: pass - size_scm_f = h.format_byte_size(size_scm) - size_root_f = h.format_byte_size(size_root) - size_total_f = h.format_byte_size(size_root + size_scm) + size_scm_f = webutils.format_byte_size(size_scm) + size_root_f = webutils.format_byte_size(size_root) + size_total_f = webutils.format_byte_size(size_root + size_scm) return size_scm_f, size_root_f, size_total_f
--- a/kallithea/lib/page.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/page.py Sun Nov 01 04:59:46 2020 +0100 @@ -19,9 +19,8 @@ import paginate import paginate_sqlalchemy import sqlalchemy.orm -from webhelpers2.html import literal -from kallithea.lib.webutils import url +from kallithea.lib import webutils log = logging.getLogger(__name__) @@ -35,10 +34,10 @@ if isinstance(collection, sqlalchemy.orm.query.Query): collection = paginate_sqlalchemy.SqlalchemyOrmWrapper(collection) paginate.Page.__init__(self, collection, page=page, items_per_page=items_per_page, item_count=item_count, - url_maker=lambda page: url.current(page=page, **kwargs)) + url_maker=lambda page: webutils.url.current(page=page, **kwargs)) def pager(self): - return literal( + return webutils.literal( paginate.Page.pager(self, format='<ul class="pagination">$link_previous\n~4~$link_next</ul>', link_attr={'class': 'pager_link'},
--- a/kallithea/lib/webutils.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/lib/webutils.py Sun Nov 01 04:59:46 2020 +0100 @@ -20,11 +20,46 @@ imported anywhere - just like the global variables can be used everywhere. """ -from tg import request +import logging +import random + +from tg import request, session +from webhelpers2.html import HTML, escape, literal +from webhelpers2.html.tags import NotGiven, Option, Options, _input +from webhelpers2.html.tags import _make_safe_id_component as safeid +from webhelpers2.html.tags import checkbox, end_form +from webhelpers2.html.tags import form as insecure_form +from webhelpers2.html.tags import hidden, link_to, password, radio +from webhelpers2.html.tags import select as webhelpers2_select +from webhelpers2.html.tags import submit, text, textarea +from webhelpers2.number import format_byte_size +from webhelpers2.text import chop_at, truncate, wrap_paragraphs import kallithea +log = logging.getLogger(__name__) + + +# mute pyflakes "imported but unused" +assert Option +assert checkbox +assert chop_at +assert end_form +assert escape +assert format_byte_size +assert link_to +assert literal +assert password +assert radio +assert safeid +assert submit +assert text +assert textarea +assert truncate +assert wrap_paragraphs + + # # General Kallithea URL handling # @@ -75,3 +110,149 @@ except IndexError: parts = url('home', qualified=True).split('://', 1) return parts[1].split('/', 1)[0] + + +# +# Custom Webhelpers2 stuff +# + +def html_escape(s): + """Return string with all html escaped. + This is also safe for javascript in html but not necessarily correct. + """ + return (s + .replace('&', '&') + .replace(">", ">") + .replace("<", "<") + .replace('"', """) + .replace("'", "'") # Note: this is HTML5 not HTML4 and might not work in mails + ) + + +def reset(name, value, id=NotGiven, **attrs): + """Create a reset button, similar to webhelpers2.html.tags.submit .""" + return _input("reset", name, value, id, attrs) + + +def select(name, selected_values, options, id=NotGiven, **attrs): + """Convenient wrapper of webhelpers2 to let it accept options as a tuple list""" + if isinstance(options, list): + option_list = options + # Handle old value,label lists ... where value also can be value,label lists + options = Options() + for x in option_list: + if isinstance(x, tuple) and len(x) == 2: + value, label = x + elif isinstance(x, str): + value = label = x + else: + log.error('invalid select option %r', x) + raise + if isinstance(value, list): + og = options.add_optgroup(label) + for x in value: + if isinstance(x, tuple) and len(x) == 2: + group_value, group_label = x + elif isinstance(x, str): + group_value = group_label = x + else: + log.error('invalid select option %r', x) + raise + og.add_option(group_label, group_value) + else: + options.add_option(label, value) + return webhelpers2_select(name, selected_values, options, id=id, **attrs) + + +session_csrf_secret_name = "_session_csrf_secret_token" + +def session_csrf_secret_token(): + """Return (and create) the current session's CSRF protection token.""" + if not session_csrf_secret_name in session: + session[session_csrf_secret_name] = str(random.getrandbits(128)) + session.save() + return session[session_csrf_secret_name] + +def form(url, method="post", **attrs): + """Like webhelpers.html.tags.form , but automatically adding + session_csrf_secret_token for POST. The secret is thus never leaked in GET + URLs. + """ + form = insecure_form(url, method, **attrs) + if method.lower() == 'get': + return form + return form + HTML.div(hidden(session_csrf_secret_name, session_csrf_secret_token()), style="display: none;") + + +# +# Flash messages, stored in cookie +# + +class _Message(object): + """A message returned by ``pop_flash_messages()``. + + Converting the message to a string returns the message text. Instances + also have the following attributes: + + * ``category``: the category specified when the message was created. + * ``message``: the html-safe message text. + """ + + def __init__(self, category, message): + self.category = category + self.message = message + + +def _session_flash_messages(append=None, clear=False): + """Manage a message queue in tg.session: return the current message queue + after appending the given message, and possibly clearing the queue.""" + key = 'flash' + if key in session: + flash_messages = session[key] + else: + if append is None: # common fast path - also used for clearing empty queue + return [] # don't bother saving + flash_messages = [] + session[key] = flash_messages + if append is not None and append not in flash_messages: + flash_messages.append(append) + if clear: + session.pop(key, None) + session.save() + return flash_messages + + +def flash(message, category, logf=None): + """ + Show a message to the user _and_ log it through the specified function + + category: notice (default), warning, error, success + logf: a custom log function - such as log.debug + + logf defaults to log.info, unless category equals 'success', in which + case logf defaults to log.debug. + """ + assert category in ('error', 'success', 'warning'), category + if hasattr(message, '__html__'): + # render to HTML for storing in cookie + safe_message = str(message) + else: + # Apply str - the message might be an exception with __str__ + # Escape, so we can trust the result without further escaping, without any risk of injection + safe_message = html_escape(str(message)) + if logf is None: + logf = log.info + if category == 'success': + logf = log.debug + + logf('Flash %s: %s', category, safe_message) + + _session_flash_messages(append=(category, safe_message)) + + +def pop_flash_messages(): + """Return all accumulated messages and delete them from the session. + + The return value is a list of ``Message`` objects. + """ + return [_Message(category, message) for category, message in _session_flash_messages(clear=True)]
--- a/kallithea/model/comment.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/model/comment.py Sun Nov 01 04:59:46 2020 +0100 @@ -81,7 +81,7 @@ repo_name=repo.repo_name, revision=revision, anchor='comment-%s' % comment.comment_id) - subj = h.link_to( + subj = webutils.link_to( 'Re changeset: %(desc)s %(line)s' % {'desc': desc, 'line': line}, comment_url) @@ -127,7 +127,7 @@ webutils.canonical_hostname())) comment_url = pull_request.url(canonical=True, anchor='comment-%s' % comment.comment_id) - subj = h.link_to( + subj = webutils.link_to( 'Re pull request %(pr_nice_id)s: %(desc)s %(line)s' % {'desc': desc, 'pr_nice_id': comment.pull_request.nice_id(),
--- a/kallithea/model/db.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/model/db.py Sun Nov 01 04:59:46 2020 +0100 @@ -1306,9 +1306,8 @@ return grouped def _repo_size(self): - from kallithea.lib import helpers as h log.debug('calculating repository size...') - return h.format_byte_size(self.scm_instance.size) + return webutils.format_byte_size(self.scm_instance.size) #========================================================================== # SCM CACHE INSTANCE @@ -1397,10 +1396,9 @@ @classmethod def _generate_choice(cls, repo_group): """Return tuple with group_id and name as html literal""" - from webhelpers2.html import literal if repo_group is None: return (-1, '-- %s --' % _('top level')) - return repo_group.group_id, literal(cls.SEP.join(repo_group.full_path_splitted)) + return repo_group.group_id, webutils.literal(cls.SEP.join(repo_group.full_path_splitted)) @classmethod def groups_choices(cls, groups):
--- a/kallithea/model/pull_request.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/model/pull_request.py Sun Nov 01 04:59:46 2020 +0100 @@ -82,7 +82,7 @@ threading = ['%s-pr-%s@%s' % (pr.other_repo.repo_name, pr.pull_request_id, webutils.canonical_hostname())] - subject = h.link_to( + subject = webutils.link_to( _('%(user)s wants you to review pull request %(pr_nice_id)s: %(pr_title)s') % {'user': user.username, 'pr_title': pr.title,
--- a/kallithea/model/user.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/model/user.py Sun Nov 01 04:59:46 2020 +0100 @@ -314,7 +314,6 @@ allowing users to copy-paste or manually enter the token from the email. """ - import kallithea.lib.helpers as h from kallithea.lib.celerylib import tasks from kallithea.model.notification import EmailNotificationModel @@ -326,7 +325,7 @@ log.debug('password reset user %s found', user) token = self.get_reset_password_token(user, timestamp, - h.session_csrf_secret_token()) + webutils.session_csrf_secret_token()) # URL must be fully qualified; but since the token is locked to # the current browser session, we must provide a URL with the # current scheme and hostname, rather than the canonical_url. @@ -359,7 +358,6 @@ timestamp=timestamp) def verify_reset_password_token(self, email, timestamp, token): - import kallithea.lib.helpers as h user = db.User.get_by_email(email) if user is None: log.debug("user with email %s not found", email) @@ -377,7 +375,7 @@ expected_token = self.get_reset_password_token(user, timestamp, - h.session_csrf_secret_token()) + webutils.session_csrf_secret_token()) log.debug('computed password reset token: %s', expected_token) log.debug('received password reset token: %s', token) return expected_token == token
--- a/kallithea/tests/functional/test_admin_users.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/tests/functional/test_admin_users.py Sun Nov 01 04:59:46 2020 +0100 @@ -19,7 +19,7 @@ import kallithea from kallithea.controllers.admin.users import UsersController -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import check_password from kallithea.model import db, meta, validators from kallithea.model.user import UserModel @@ -112,7 +112,7 @@ with test_context(self.app): msg = validators.ValidUsername(False, {})._messages['system_invalid_username'] - msg = h.html_escape(msg % {'username': 'new_user'}) + msg = webutils.html_escape(msg % {'username': 'new_user'}) response.mustcontain("""<span class="error-message">%s</span>""" % msg) response.mustcontain("""<span class="error-message">Please enter a value</span>""") response.mustcontain("""<span class="error-message">An email address must contain a single @</span>""") @@ -569,7 +569,7 @@ # flash complains about an non-existing session def flash_mock(*args, **kwargs): pass - monkeypatch.setattr(h, 'flash', flash_mock) + monkeypatch.setattr(webutils, 'flash', flash_mock) u = UsersController() # a regular user should work correctly
--- a/kallithea/tests/functional/test_login.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/tests/functional/test_login.py Sun Nov 01 04:59:46 2020 +0100 @@ -7,7 +7,7 @@ from tg.util.webtest import test_context import kallithea.lib.celerylib.tasks -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.lib.auth import check_password from kallithea.lib.utils2 import generate_api_key from kallithea.model import db, meta, validators @@ -238,7 +238,7 @@ with test_context(self.app): msg = validators.ValidUsername()._messages['username_exists'] - msg = h.html_escape(msg % {'username': uname}) + msg = webutils.html_escape(msg % {'username': uname}) response.mustcontain(msg) def test_register_err_same_email(self): @@ -311,7 +311,7 @@ response.mustcontain('An email address must contain a single @') with test_context(self.app): msg = validators.ValidUsername()._messages['username_exists'] - msg = h.html_escape(msg % {'username': usr}) + msg = webutils.html_escape(msg % {'username': usr}) response.mustcontain(msg) def test_register_special_chars(self):
--- a/kallithea/tests/functional/test_my_account.py Thu Oct 29 14:32:42 2020 +0100 +++ b/kallithea/tests/functional/test_my_account.py Sun Nov 01 04:59:46 2020 +0100 @@ -2,7 +2,7 @@ from tg.util.webtest import test_context -from kallithea.lib import helpers as h +from kallithea.lib import webutils from kallithea.model import db, meta from kallithea.model.user import UserModel from kallithea.tests import base @@ -186,7 +186,7 @@ with test_context(self.app): msg = validators.ValidUsername(edit=False, old_data={}) \ ._messages['username_exists'] - msg = h.html_escape(msg % {'username': base.TEST_USER_ADMIN_LOGIN}) + msg = webutils.html_escape(msg % {'username': base.TEST_USER_ADMIN_LOGIN}) response.mustcontain(msg) def test_my_account_api_keys(self):