# HG changeset patch # User Marcin Kuzminski # Date 2017-11-15 12:42:54 # Node ID 5927212158170867eacdca71b04cfeae5a87321d # Parent a907f1dd9ade64a5f59a2b12be599ab6114ccab7 pylons: remove pylons as dependency - dependencies: bumped: -setuptools-scm==1.15.6 -celery==4.1.0 -kombu==4.1.0 -pytz==2017.3 -Routes==2.4.1 Removed all pylons components. Refactored the code to use only pyramid parts diff --git a/pkgs/patch-celery-dateutil.diff b/pkgs/patch-celery-dateutil.diff deleted file mode 100644 --- a/pkgs/patch-celery-dateutil.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -rup celery-2.2.10-orig/setup.py celery-2.2.10/setup.py ---- celery-2.2.10-orig/setup.py 2017-02-25 15:30:34.000000000 +0100 -+++ celery-2.2.10/setup.py 2017-02-25 15:30:34.000000000 +0100 -@@ -48,7 +48,7 @@ try: - except ImportError: - install_requires.append("importlib") - install_requires.extend([ -- "python-dateutil>=1.5.0,<2.0.0", -+ "python-dateutil>=1.5.0,<2.2.0", - "anyjson>=0.3.1", - "kombu>=1.1.2,<2.0.0", - "pyparsing>=1.5.0,<2.0.0", diff --git a/pkgs/patch-kombu-py-2-7-11.diff b/pkgs/patch-kombu-py-2-7-11.diff deleted file mode 100644 --- a/pkgs/patch-kombu-py-2-7-11.diff +++ /dev/null @@ -1,15 +0,0 @@ -diff -rup kombu-1.5.1-orig/kombu/utils/__init__.py kombu-1.5.1/kombu/utils/__init__.py ---- kombu-1.5.1-orig/kombu/utils/__init__.py 2016-03-09 15:11:34.000000000 +0100 -+++ kombu-1.5.1/kombu/utils/__init__.py 2016-03-09 15:15:52.000000000 +0100 -@@ -11,7 +11,10 @@ Internal utilities. - import sys - - from time import sleep --from uuid import UUID, uuid4 as _uuid4, _uuid_generate_random -+from uuid import UUID, uuid4 as _uuid4 -+ -+# Fix for Python 2.7.11 -+_uuid_generate_random = None - - from kombu.utils.encoding import safe_repr as _safe_repr - diff --git a/pkgs/python-packages-overrides.nix b/pkgs/python-packages-overrides.nix --- a/pkgs/python-packages-overrides.nix +++ b/pkgs/python-packages-overrides.nix @@ -61,23 +61,6 @@ self: super: { ]; }); - celery = super.celery.override (attrs: { - # The current version of kombu needs some patching to work with the - # other libs. Should be removed once we update celery and kombu. - patches = [ - ./patch-celery-dateutil.diff - ]; - }); - - kombu = super.kombu.override (attrs: { - # The current version of kombu needs some patching to work with the - # other libs. Should be removed once we update celery and kombu. - patches = [ - ./patch-kombu-py-2-7-11.diff - ./patch-kombu-msgpack.diff - ]; - }); - lxml = super.lxml.override (attrs: { # johbo: On 16.09 we need this to compile on darwin, otherwise compilation # fails on Darwin. @@ -133,10 +116,6 @@ self: super: { }; }); - Pylons = super.Pylons.override (attrs: { - name = "Pylons-1.0.2.rhodecode-patch1"; - }); - pyramid = super.pyramid.override (attrs: { postFixup = '' wrapPythonPrograms diff --git a/pkgs/python-packages.nix b/pkgs/python-packages.nix --- a/pkgs/python-packages.nix +++ b/pkgs/python-packages.nix @@ -184,30 +184,17 @@ license = [ pkgs.lib.licenses.bsdOriginal ]; }; }; - Pylons = super.buildPythonPackage { - name = "Pylons-1.0.2.dev20171106"; + Routes = super.buildPythonPackage { + name = "Routes-2.4.1"; buildInputs = with self; []; doCheck = false; - propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; + propagatedBuildInputs = with self; [six repoze.lru]; src = fetchurl { - url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f"; - md5 = "f26633726fa2cd3a340316ee6a5d218f"; + url = "https://pypi.python.org/packages/33/38/ea827837e68d9c7dde4cff7ec122a93c319f0effc08ce92a17095576603f/Routes-2.4.1.tar.gz"; + md5 = "c058dff6832941dec47e0d0052548ad8"; }; meta = { - license = [ pkgs.lib.licenses.bsdOriginal ]; - }; - }; - Routes = super.buildPythonPackage { - name = "Routes-1.13"; - buildInputs = with self; []; - doCheck = false; - propagatedBuildInputs = with self; [repoze.lru]; - src = fetchurl { - url = "https://pypi.python.org/packages/88/d3/259c3b3cde8837eb9441ab5f574a660e8a4acea8f54a078441d4d2acac1c/Routes-1.13.tar.gz"; - md5 = "d527b0ab7dd9172b1275a41f97448783"; - }; - meta = { - license = [ pkgs.lib.licenses.bsdOriginal ]; + license = [ pkgs.lib.licenses.mit ]; }; }; SQLAlchemy = super.buildPythonPackage { @@ -340,6 +327,19 @@ license = [ pkgs.lib.licenses.mit ]; }; }; + amqp = super.buildPythonPackage { + name = "amqp-2.2.2"; + buildInputs = with self; []; + doCheck = false; + propagatedBuildInputs = with self; [vine]; + src = fetchurl { + url = "https://pypi.python.org/packages/e0/70/9ab9ccd8247fb7d2adb717e9f6a0ed358c9e1ab2c349048b0352f9e80ee2/amqp-2.2.2.tar.gz"; + md5 = "0971a3fd2d635ded45c349cfc17106bd"; + }; + meta = { + license = [ pkgs.lib.licenses.bsdOriginal ]; + }; + }; amqplib = super.buildPythonPackage { name = "amqplib-1.0.2"; buildInputs = with self; []; @@ -353,19 +353,6 @@ license = [ { fullName = "LGPL"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ]; }; }; - anyjson = super.buildPythonPackage { - name = "anyjson-0.3.3"; - buildInputs = with self; []; - doCheck = false; - propagatedBuildInputs = with self; []; - src = fetchurl { - url = "https://pypi.python.org/packages/c3/4d/d4089e1a3dd25b46bebdb55a992b0797cff657b4477bc32ce28038fdecbc/anyjson-0.3.3.tar.gz"; - md5 = "2ea28d6ec311aeeebaf993cb3008b27c"; - }; - meta = { - license = [ pkgs.lib.licenses.bsdOriginal ]; - }; - }; appenlight-client = super.buildPythonPackage { name = "appenlight-client-0.6.22"; buildInputs = with self; []; @@ -418,6 +405,19 @@ license = [ pkgs.lib.licenses.mit ]; }; }; + billiard = super.buildPythonPackage { + name = "billiard-3.5.0.3"; + buildInputs = with self; []; + doCheck = false; + propagatedBuildInputs = with self; []; + src = fetchurl { + url = "https://pypi.python.org/packages/39/ac/f5571210cca2e4f4532e38aaff242f26c8654c5e2436bee966c230647ccc/billiard-3.5.0.3.tar.gz"; + md5 = "113ba481e48400adbf6fbbf59a2f8554"; + }; + meta = { + license = [ pkgs.lib.licenses.bsdOriginal ]; + }; + }; bleach = super.buildPythonPackage { name = "bleach-1.5.0"; buildInputs = with self; []; @@ -458,13 +458,13 @@ }; }; celery = super.buildPythonPackage { - name = "celery-2.2.10"; + name = "celery-4.1.0"; buildInputs = with self; []; doCheck = false; - propagatedBuildInputs = with self; [python-dateutil anyjson kombu pyparsing]; + propagatedBuildInputs = with self; [pytz billiard kombu]; src = fetchurl { - url = "https://pypi.python.org/packages/b1/64/860fd50e45844c83442e7953effcddeff66b2851d90b2d784f7201c111b8/celery-2.2.10.tar.gz"; - md5 = "898bc87e54f278055b561316ba73e222"; + url = "https://pypi.python.org/packages/07/65/88a2a45fc80f487872c93121a701a53bbbc3d3d832016876fac84fc8d46a/celery-4.1.0.tar.gz"; + md5 = "db91e1d26936381127f01e150fe3054a"; }; meta = { license = [ pkgs.lib.licenses.bsdOriginal ]; @@ -1004,13 +1004,13 @@ }; }; kombu = super.buildPythonPackage { - name = "kombu-1.5.1"; + name = "kombu-4.1.0"; buildInputs = with self; []; doCheck = false; - propagatedBuildInputs = with self; [anyjson amqplib]; + propagatedBuildInputs = with self; [amqp]; src = fetchurl { - url = "https://pypi.python.org/packages/19/53/74bf2a624644b45f0850a638752514fc10a8e1cbd738f10804951a6df3f5/kombu-1.5.1.tar.gz"; - md5 = "50662f3c7e9395b3d0721fb75d100b63"; + url = "https://pypi.python.org/packages/03/5e/1a47d1e543d4943d65330af4e4406049f443878818fb65bfdc651bb93a96/kombu-4.1.0.tar.gz"; + md5 = "2fb2be9fec0e6514231bba23a3779439"; }; meta = { license = [ pkgs.lib.licenses.bsdOriginal ]; @@ -1094,19 +1094,6 @@ license = [ pkgs.lib.licenses.bsdOriginal ]; }; }; - nose = super.buildPythonPackage { - name = "nose-1.3.6"; - buildInputs = with self; []; - doCheck = false; - propagatedBuildInputs = with self; []; - src = fetchurl { - url = "https://pypi.python.org/packages/70/c7/469e68148d17a0d3db5ed49150242fd70a74a8147b8f3f8b87776e028d99/nose-1.3.6.tar.gz"; - md5 = "0ca546d81ca8309080fc80cb389e7a16"; - }; - meta = { - license = [ { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "GNU LGPL"; } ]; - }; - }; objgraph = super.buildPythonPackage { name = "objgraph-3.1.1"; buildInputs = with self; []; @@ -1173,13 +1160,13 @@ }; }; pexpect = super.buildPythonPackage { - name = "pexpect-4.2.1"; + name = "pexpect-4.3.0"; buildInputs = with self; []; doCheck = false; propagatedBuildInputs = with self; [ptyprocess]; src = fetchurl { - url = "https://pypi.python.org/packages/e8/13/d0b0599099d6cd23663043a2a0bb7c61e58c6ba359b2656e6fb000ef5b98/pexpect-4.2.1.tar.gz"; - md5 = "3694410001a99dff83f0b500a1ca1c95"; + url = "https://pypi.python.org/packages/f8/44/5466c30e49762bb92e442bbdf4472d6904608d211258eb3198a11f0309a4/pexpect-4.3.0.tar.gz"; + md5 = "047a486dcd26134b74f2e67046bb61a0"; }; meta = { license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ]; @@ -1550,16 +1537,16 @@ }; }; python-dateutil = super.buildPythonPackage { - name = "python-dateutil-2.1"; + name = "python-dateutil-2.6.1"; buildInputs = with self; []; doCheck = false; propagatedBuildInputs = with self; [six]; src = fetchurl { - url = "https://pypi.python.org/packages/65/52/9c18dac21f174ad31b65e22d24297864a954e6fe65876eba3f5773d2da43/python-dateutil-2.1.tar.gz"; - md5 = "1534bb15cf311f07afaa3aacba1c028b"; + url = "https://pypi.python.org/packages/54/bb/f1db86504f7a49e1d9b9301531181b00a1c7325dc85a29160ee3eaa73a54/python-dateutil-2.6.1.tar.gz"; + md5 = "db38f6b4511cefd76014745bb0cc45a4"; }; meta = { - license = [ { fullName = "Simplified BSD"; } ]; + license = [ pkgs.lib.licenses.bsdOriginal { fullName = "Simplified BSD"; } ]; }; }; python-editor = super.buildPythonPackage { @@ -1615,13 +1602,13 @@ }; }; pytz = super.buildPythonPackage { - name = "pytz-2015.4"; + name = "pytz-2017.3"; buildInputs = with self; []; doCheck = false; propagatedBuildInputs = with self; []; src = fetchurl { - url = "https://pypi.python.org/packages/7e/1a/f43b5c92df7b156822030fed151327ea096bcf417e45acc23bd1df43472f/pytz-2015.4.zip"; - md5 = "233f2a2b370d03f9b5911700cc9ebf3c"; + url = "https://pypi.python.org/packages/60/88/d3152c234da4b2a1f7a989f89609ea488225eaea015bc16fbde2b3fdfefa/pytz-2017.3.zip"; + md5 = "7006b56c0d68a162d9fe57d4249c3171"; }; meta = { license = [ pkgs.lib.licenses.mit ]; @@ -1696,7 +1683,7 @@ name = "rhodecode-enterprise-ce-4.11.0"; buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj]; doCheck = true; - propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic cssselect celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu lxml msgpack-python nbconvert packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client redis repoze.lru requests simplejson sshpubkeys subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt]; + propagatedBuildInputs = with self; [setuptools-scm amqplib amqp authomatic Babel Beaker celery Chameleon channelstream click colander configobj cssselect decorator deform docutils dogpile.cache dogpile.core ecdsa FormEncode future futures gnureadline infrae.cache iso8601 itsdangerous Jinja2 billiard kombu lxml Mako Markdown MarkupSafe msgpack-python MySQL-python objgraph packaging Paste PasteDeploy PasteScript pathlib2 peppercorn psutil psycopg2 py-bcrypt pycrypto pycurl pyflakes pygments-markdown-lexer Pygments pyparsing pyramid-beaker pyramid-debugtoolbar pyramid-jinja2 pyramid-mako pyramid pysqlite python-dateutil python-ldap python-memcached python-pam pytz pyzmq py-gfm recaptcha-client redis repoze.lru requests Routes setproctitle simplejson six SQLAlchemy sshpubkeys subprocess32 Tempita translationstring trollius urllib3 URLObject venusian WebError WebHelpers2 WebHelpers WebOb Whoosh wsgiref zope.cachedescriptors zope.deprecation zope.event zope.interface nbconvert bleach nbformat jupyter-client alembic invoke bumpversion transifex-client gevent greenlet gunicorn waitress uWSGI ipdb ipython CProfileV bottle rhodecode-tools appenlight-client pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage]; src = ./.; meta = { license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ]; @@ -1755,13 +1742,13 @@ }; }; setuptools-scm = super.buildPythonPackage { - name = "setuptools-scm-1.15.0"; + name = "setuptools-scm-1.15.6"; buildInputs = with self; []; doCheck = false; propagatedBuildInputs = with self; []; src = fetchurl { - url = "https://pypi.python.org/packages/80/b7/31b6ae5fcb188e37f7e31abe75f9be90490a5456a72860fa6e643f8a3cbc/setuptools_scm-1.15.0.tar.gz"; - md5 = "b6916c78ed6253d6602444fad4279c5b"; + url = "https://pypi.python.org/packages/03/6d/aafdd01edd227ee879b691455bf19895091872af7e48192bea1758c82032/setuptools_scm-1.15.6.tar.gz"; + md5 = "f17493d53f0d842bb0152f214775640b"; }; meta = { license = [ pkgs.lib.licenses.mit ]; @@ -1949,6 +1936,19 @@ license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; }; }; + vine = super.buildPythonPackage { + name = "vine-1.1.4"; + buildInputs = with self; []; + doCheck = false; + propagatedBuildInputs = with self; []; + src = fetchurl { + url = "https://pypi.python.org/packages/32/23/36284986e011f3c130d802c3c66abd8f1aef371eae110ddf80c5ae22e1ff/vine-1.1.4.tar.gz"; + md5 = "9fdb971e7fd15b181b84f3bfcf20d11c"; + }; + meta = { + license = [ pkgs.lib.licenses.bsdOriginal ]; + }; + }; waitress = super.buildPythonPackage { name = "waitress-1.1.0"; buildInputs = with self; []; diff --git a/requirements.txt b/requirements.txt --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,13 @@ ## core setuptools==30.1.0 -setuptools-scm==1.15.0 +setuptools-scm==1.15.6 amqplib==1.0.2 -anyjson==0.3.3 +amqp==2.2.2 authomatic==0.1.0.post1 Babel==1.3 Beaker==1.9.0 -celery==2.2.10 +celery==4.1.0 Chameleon==2.24 channelstream==0.5.2 click==6.6 @@ -28,7 +28,8 @@ infrae.cache==1.0.1 iso8601==0.1.12 itsdangerous==0.24 Jinja2==2.9.6 -kombu==1.5.1 +billiard==3.5.0.3 +kombu==4.1.0 lxml==3.7.3 Mako==1.0.7 Markdown==2.6.9 @@ -57,18 +58,18 @@ pyramid-jinja2==2.7 pyramid-mako==1.0.2 pyramid==1.9.1 pysqlite==2.8.3 -python-dateutil==2.1 +python-dateutil python-ldap==2.4.45 python-memcached==1.58 python-pam==1.8.2 -pytz==2015.4 +pytz==2017.3 pyzmq==14.6.0 py-gfm==0.1.3 recaptcha-client==1.0.6 redis==2.10.6 repoze.lru==0.7 requests==2.9.1 -Routes==1.13 +Routes==2.4.1 setproctitle==1.1.10 simplejson==3.11.1 six==1.11.0 @@ -92,10 +93,6 @@ zope.deprecation==4.1.2 zope.event==4.0.3 zope.interface==4.1.3 -## customized/patched libs -# our patched version of Pylons==1.0.2 -https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1 - # IPYTHON RENDERING # entrypoints backport, pypi version doesn't support egg installs diff --git a/rhodecode/api/tests/conftest.py b/rhodecode/api/tests/conftest.py --- a/rhodecode/api/tests/conftest.py +++ b/rhodecode/api/tests/conftest.py @@ -27,7 +27,7 @@ from rhodecode.tests import TEST_USER_AD @pytest.fixture(scope="class") -def testuser_api(request, pylonsapp): +def testuser_api(request, baseapp): cls = request.cls # ADMIN USER diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py --- a/rhodecode/apps/_base/__init__.py +++ b/rhodecode/apps/_base/__init__.py @@ -159,32 +159,14 @@ class BaseAppView(object): return c - def _register_global_c(self, tmpl_args): - """ - Registers attributes to pylons global `c` - """ - - # TODO(marcink): remove once pyramid migration is finished - from pylons import tmpl_context as c - try: - for k, v in tmpl_args.items(): - setattr(c, k, v) - except TypeError: - log.exception('Failed to register pylons C') - pass - - def _get_template_context(self, tmpl_args): - self._register_global_c(tmpl_args) + def _get_template_context(self, tmpl_args, **kwargs): local_tmpl_args = { 'defaults': {}, 'errors': {}, - # register a fake 'c' to be used in templates instead of global - # pylons c, after migration to pyramid we should rename it to 'c' - # make sure we replace usage of _c in templates too - '_c': tmpl_args + 'c': tmpl_args } - local_tmpl_args.update(tmpl_args) + local_tmpl_args.update(kwargs) return local_tmpl_args def load_default_context(self): @@ -194,7 +176,7 @@ class BaseAppView(object): def load_default_context(self): c = self._get_local_tmpl_context() c.custom_var = 'foobar' - self._register_global_c(c) + return c """ raise NotImplementedError('Needs implementation in view class') @@ -213,7 +195,7 @@ class RepoAppView(BaseAppView): 'Requirements are missing for repository %s: %s', self.db_repo_name, error.message) - def _get_local_tmpl_context(self, include_app_defaults=False): + def _get_local_tmpl_context(self, include_app_defaults=True): _ = self.request.translate c = super(RepoAppView, self)._get_local_tmpl_context( include_app_defaults=include_app_defaults) @@ -336,7 +318,7 @@ class BaseReferencesView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c def load_refs_context(self, ref_items, partials_template): diff --git a/rhodecode/apps/admin/navigation.py b/rhodecode/apps/admin/navigation.py --- a/rhodecode/apps/admin/navigation.py +++ b/rhodecode/apps/admin/navigation.py @@ -25,7 +25,6 @@ import collections from zope.interface import implementer from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry -from rhodecode.lib.utils import get_registry from rhodecode.lib.utils2 import str2bool from rhodecode.translation import _ @@ -116,7 +115,7 @@ def navigation_registry(request, registr """ Helper that returns the admin navigation registry. """ - pyramid_registry = registry or get_registry(request) + pyramid_registry = registry or request.registry nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry) return nav_registry diff --git a/rhodecode/apps/admin/tests/test_admin_audit_logs.py b/rhodecode/apps/admin/tests/test_admin_audit_logs.py --- a/rhodecode/apps/admin/tests/test_admin_audit_logs.py +++ b/rhodecode/apps/admin/tests/test_admin_audit_logs.py @@ -46,10 +46,11 @@ def route_path(name, params=None, **kwar return base_url -class TestAdminController(TestController): +@pytest.mark.usefixtures('app') +class TestAdminController(object): @pytest.fixture(scope='class', autouse=True) - def prepare(self, request, pylonsapp): + def prepare(self, request, baseapp): UserLog.query().delete() Session().commit() @@ -84,104 +85,87 @@ class TestAdminController(TestController UserLog.query().delete() Session().commit() - def test_index(self): - self.log_user() + def test_index(self, autologin_user): response = self.app.get(route_path('admin_audit_logs')) response.mustcontain('Admin audit logs') - def test_filter_all_entries(self): - self.log_user() + def test_filter_all_entries(self, autologin_user): response = self.app.get(route_path('admin_audit_logs')) all_count = UserLog.query().count() response.mustcontain('%s entries' % all_count) - def test_filter_journal_filter_exact_match_on_repository(self): - self.log_user() + def test_filter_journal_filter_exact_match_on_repository(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:rhodecode'))) response.mustcontain('3 entries') - def test_filter_journal_filter_exact_match_on_repository_CamelCase(self): - self.log_user() + def test_filter_journal_filter_exact_match_on_repository_CamelCase(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:RhodeCode'))) response.mustcontain('3 entries') - def test_filter_journal_filter_wildcard_on_repository(self): - self.log_user() + def test_filter_journal_filter_wildcard_on_repository(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:*test*'))) response.mustcontain('862 entries') - def test_filter_journal_filter_prefix_on_repository(self): - self.log_user() + def test_filter_journal_filter_prefix_on_repository(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:test*'))) response.mustcontain('257 entries') - def test_filter_journal_filter_prefix_on_repository_CamelCase(self): - self.log_user() + def test_filter_journal_filter_prefix_on_repository_CamelCase(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:Test*'))) response.mustcontain('257 entries') - def test_filter_journal_filter_prefix_on_repository_and_user(self): - self.log_user() + def test_filter_journal_filter_prefix_on_repository_and_user(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:test* AND username:demo'))) response.mustcontain('130 entries') - def test_filter_journal_filter_prefix_on_repository_or_target_repo(self): - self.log_user() + def test_filter_journal_filter_prefix_on_repository_or_target_repo(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='repository:test* OR repository:rhodecode'))) response.mustcontain('260 entries') # 257 + 3 - def test_filter_journal_filter_exact_match_on_username(self): - self.log_user() + def test_filter_journal_filter_exact_match_on_username(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='username:demo'))) response.mustcontain('1087 entries') - def test_filter_journal_filter_exact_match_on_username_camelCase(self): - self.log_user() + def test_filter_journal_filter_exact_match_on_username_camelCase(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='username:DemO'))) response.mustcontain('1087 entries') - def test_filter_journal_filter_wildcard_on_username(self): - self.log_user() + def test_filter_journal_filter_wildcard_on_username(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='username:*test*'))) entries_count = UserLog.query().filter(UserLog.username.ilike('%test%')).count() response.mustcontain('{} entries'.format(entries_count)) - def test_filter_journal_filter_prefix_on_username(self): - self.log_user() + def test_filter_journal_filter_prefix_on_username(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='username:demo*'))) response.mustcontain('1101 entries') - def test_filter_journal_filter_prefix_on_user_or_other_user(self): - self.log_user() + def test_filter_journal_filter_prefix_on_user_or_other_user(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='username:demo OR username:volcan'))) response.mustcontain('1095 entries') # 1087 + 8 - def test_filter_journal_filter_wildcard_on_action(self): - self.log_user() + def test_filter_journal_filter_wildcard_on_action(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='action:*pull_request*'))) response.mustcontain('187 entries') - def test_filter_journal_filter_on_date(self): - self.log_user() + def test_filter_journal_filter_on_date(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='date:20121010'))) response.mustcontain('47 entries') - def test_filter_journal_filter_on_date_2(self): - self.log_user() + def test_filter_journal_filter_on_date_2(self, autologin_user): response = self.app.get(route_path('admin_audit_logs', params=dict(filter='date:20121020'))) response.mustcontain('17 entries') diff --git a/rhodecode/apps/admin/tests/test_admin_settings.py b/rhodecode/apps/admin/tests/test_admin_settings.py --- a/rhodecode/apps/admin/tests/test_admin_settings.py +++ b/rhodecode/apps/admin/tests/test_admin_settings.py @@ -429,7 +429,7 @@ class TestAdminSettingsVcs(object): # TODO: johbo: What we really want is to checkpoint before a test run and # reset the session afterwards. @pytest.fixture(scope='class', autouse=True) - def cleanup_settings(self, request, pylonsapp): + def cleanup_settings(self, request, baseapp): ui_id = RhodeCodeUi.ui_id original_ids = list( r.ui_id for r in RhodeCodeUi.query().values(ui_id)) diff --git a/rhodecode/apps/admin/tests/test_admin_users.py b/rhodecode/apps/admin/tests/test_admin_users.py --- a/rhodecode/apps/admin/tests/test_admin_users.py +++ b/rhodecode/apps/admin/tests/test_admin_users.py @@ -23,7 +23,6 @@ from sqlalchemy.orm.exc import NoResultF from rhodecode.lib import auth from rhodecode.lib import helpers as h -from rhodecode.model import validators from rhodecode.model.db import User, UserApiKeys, UserEmailMap, Repository from rhodecode.model.meta import Session from rhodecode.model.user import UserModel @@ -386,8 +385,7 @@ class TestAdminUsersView(TestController) 'csrf_token': self.csrf_token, }) - msg = validators.ValidUsername( - False, {})._messages['system_invalid_username'] + msg = '???' msg = h.html_escape(msg % {'username': 'new_user'}) response.mustcontain('%s' % msg) response.mustcontain( diff --git a/rhodecode/apps/admin/views/audit_logs.py b/rhodecode/apps/admin/views/audit_logs.py --- a/rhodecode/apps/admin/views/audit_logs.py +++ b/rhodecode/apps/admin/views/audit_logs.py @@ -36,7 +36,6 @@ log = logging.getLogger(__name__) class AdminAuditLogsView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) return c @LoginRequired() diff --git a/rhodecode/apps/admin/views/defaults.py b/rhodecode/apps/admin/views/defaults.py --- a/rhodecode/apps/admin/views/defaults.py +++ b/rhodecode/apps/admin/views/defaults.py @@ -44,7 +44,7 @@ class AdminDefaultSettingsView(BaseAppVi def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() @@ -79,7 +79,7 @@ class AdminDefaultSettingsView(BaseAppVi _ = self.request.translate c = self.load_default_context() c.active = 'repositories' - form = DefaultsForm()() + form = DefaultsForm(self.request.translate)() try: form_result = form.to_python(dict(self.request.POST)) diff --git a/rhodecode/apps/admin/views/open_source_licenses.py b/rhodecode/apps/admin/views/open_source_licenses.py --- a/rhodecode/apps/admin/views/open_source_licenses.py +++ b/rhodecode/apps/admin/views/open_source_licenses.py @@ -35,7 +35,7 @@ class OpenSourceLicensesAdminSettingsVie def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/admin/views/permissions.py b/rhodecode/apps/admin/views/permissions.py --- a/rhodecode/apps/admin/views/permissions.py +++ b/rhodecode/apps/admin/views/permissions.py @@ -54,7 +54,7 @@ class AdminPermissionsView(BaseAppView, def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + PermissionModel().set_global_permission_choices( c, gettext_translator=self.request.translate) return c @@ -100,6 +100,7 @@ class AdminPermissionsView(BaseAppView, c.active = 'application' _form = ApplicationPermissionsForm( + self.request.translate, [x[0] for x in c.register_choices], [x[0] for x in c.password_reset_choices], [x[0] for x in c.extern_activate_choices])() @@ -180,6 +181,7 @@ class AdminPermissionsView(BaseAppView, c.active = 'objects' _form = ObjectPermissionsForm( + self.request.translate, [x[0] for x in c.repo_perms_choices], [x[0] for x in c.group_perms_choices], [x[0] for x in c.user_group_perms_choices])() @@ -251,6 +253,7 @@ class AdminPermissionsView(BaseAppView, c.active = 'global' _form = UserPermissionsForm( + self.request.translate, [x[0] for x in c.repo_create_choices], [x[0] for x in c.repo_create_on_write_choices], [x[0] for x in c.repo_group_create_choices], @@ -395,6 +398,7 @@ class AdminPermissionsView(BaseAppView, renderer='json_ext', xhr=True) def ssh_keys_data(self): _ = self.request.translate + self.load_default_context() column_map = { 'fingerprint': 'ssh_key_fingerprint', 'username': User.username diff --git a/rhodecode/apps/admin/views/process_management.py b/rhodecode/apps/admin/views/process_management.py --- a/rhodecode/apps/admin/views/process_management.py +++ b/rhodecode/apps/admin/views/process_management.py @@ -35,7 +35,7 @@ log = logging.getLogger(__name__) class AdminProcessManagementView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/admin/views/repo_groups.py b/rhodecode/apps/admin/views/repo_groups.py --- a/rhodecode/apps/admin/views/repo_groups.py +++ b/rhodecode/apps/admin/views/repo_groups.py @@ -47,7 +47,7 @@ class AdminRepoGroupsView(BaseAppView, D def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c def _load_form_data(self, c): @@ -150,8 +150,9 @@ class AdminRepoGroupsView(BaseAppView, D # permissions for can create group based on parent_id are checked # here in the Form available_groups = map(lambda k: safe_unicode(k[0]), c.repo_groups) - repo_group_form = RepoGroupForm(available_groups=available_groups, - can_create_in_root=can_create)() + repo_group_form = RepoGroupForm( + self.request.translate, available_groups=available_groups, + can_create_in_root=can_create)() repo_group_name = self.request.POST.get('group_name') try: diff --git a/rhodecode/apps/admin/views/repositories.py b/rhodecode/apps/admin/views/repositories.py --- a/rhodecode/apps/admin/views/repositories.py +++ b/rhodecode/apps/admin/views/repositories.py @@ -49,7 +49,7 @@ class AdminReposView(BaseAppView, DataGr def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c def _load_form_data(self, c): @@ -148,9 +148,10 @@ class AdminReposView(BaseAppView, DataGr try: # CanWriteToGroup validators checks permissions of this POST - form_result = RepoForm(repo_groups=c.repo_groups_choices, - landing_revs=c.landing_revs_choices)()\ - .to_python(dict(self.request.POST)) + form = RepoForm( + self.request.translate, repo_groups=c.repo_groups_choices, + landing_revs=c.landing_revs_choices)() + form_results = form.to_python(dict(self.request.POST)) # create is done sometimes async on celery, db transaction # management is handled there. diff --git a/rhodecode/apps/admin/views/sessions.py b/rhodecode/apps/admin/views/sessions.py --- a/rhodecode/apps/admin/views/sessions.py +++ b/rhodecode/apps/admin/views/sessions.py @@ -39,7 +39,7 @@ class AdminSessionSettingsView(BaseAppVi def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/admin/views/settings.py b/rhodecode/apps/admin/views/settings.py --- a/rhodecode/apps/admin/views/settings.py +++ b/rhodecode/apps/admin/views/settings.py @@ -67,7 +67,7 @@ class AdminSettingsView(BaseAppView): c.labs_active = str2bool( rhodecode.CONFIG.get('labs_settings_active', 'true')) c.navlist = navigation_list(self.request) - self._register_global_c(c) + return c @classmethod @@ -153,7 +153,7 @@ class AdminSettingsView(BaseAppView): settings = self.request.registry.settings c.svn_proxy_generate_config = settings[generate_config] - application_form = ApplicationUiSettingsForm()() + application_form = ApplicationUiSettingsForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) @@ -310,7 +310,7 @@ class AdminSettingsView(BaseAppView): c.active = 'global' c.personal_repo_group_default_pattern = RepoGroupModel()\ .get_personal_group_name_pattern() - application_form = ApplicationSettingsForm()() + application_form = ApplicationSettingsForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: @@ -382,7 +382,7 @@ class AdminSettingsView(BaseAppView): _ = self.request.translate c = self.load_default_context() c.active = 'visual' - application_form = ApplicationVisualisationForm()() + application_form = ApplicationVisualisationForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: @@ -482,7 +482,7 @@ class AdminSettingsView(BaseAppView): settings_model = IssueTrackerSettingsModel() try: - form = IssueTrackerPatternsForm()().to_python(self.request.POST) + form = IssueTrackerPatternsForm(self.request.translate)().to_python(self.request.POST) except formencode.Invalid as errors: log.exception('Failed to add new pattern') error = errors @@ -698,7 +698,7 @@ class AdminSettingsView(BaseAppView): c = self.load_default_context() c.active = 'labs' - application_form = LabsSettingsForm()() + application_form = LabsSettingsForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: diff --git a/rhodecode/apps/admin/views/system_info.py b/rhodecode/apps/admin/views/system_info.py --- a/rhodecode/apps/admin/views/system_info.py +++ b/rhodecode/apps/admin/views/system_info.py @@ -40,7 +40,7 @@ log = logging.getLogger(__name__) class AdminSystemInfoSettingsView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @staticmethod diff --git a/rhodecode/apps/admin/views/user_groups.py b/rhodecode/apps/admin/views/user_groups.py --- a/rhodecode/apps/admin/views/user_groups.py +++ b/rhodecode/apps/admin/views/user_groups.py @@ -53,7 +53,7 @@ class AdminUserGroupsView(BaseAppView, D PermissionModel().set_global_permission_choices( c, gettext_translator=self.request.translate) - self._register_global_c(c) + return c # permission check in data loading of @@ -196,7 +196,7 @@ class AdminUserGroupsView(BaseAppView, D def user_groups_create(self): _ = self.request.translate c = self.load_default_context() - users_group_form = UserGroupForm()() + users_group_form = UserGroupForm(self.request.translate)() user_group_name = self.request.POST.get('users_group_name') try: diff --git a/rhodecode/apps/admin/views/users.py b/rhodecode/apps/admin/views/users.py --- a/rhodecode/apps/admin/views/users.py +++ b/rhodecode/apps/admin/views/users.py @@ -44,7 +44,8 @@ from rhodecode.lib import helpers as h from rhodecode.lib.utils2 import safe_int, safe_unicode, AttributeDict from rhodecode.model.auth_token import AuthTokenModel from rhodecode.model.forms import ( - UserForm, UserIndividualPermissionsForm, UserPermissionsForm) + UserForm, UserIndividualPermissionsForm, UserPermissionsForm, + UserExtraEmailForm, UserExtraIpForm) from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.ssh_key import SshKeyModel @@ -62,7 +63,6 @@ class AdminUsersView(BaseAppView, DataGr def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) return c @LoginRequired() @@ -191,7 +191,7 @@ class AdminUsersView(BaseAppView, DataGr c = self.load_default_context() c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name user_model = UserModel() - user_form = UserForm()() + user_form = UserForm(self.request.translate)() try: form_result = user_form.to_python(dict(self.request.POST)) user = user_model.create(form_result) @@ -259,7 +259,7 @@ class UsersView(UserAppView): PermissionModel().set_global_permission_choices( c, gettext_translator=req.translate) - self._register_global_c(c) + return c @LoginRequired() @@ -280,7 +280,8 @@ class UsersView(UserAppView): c.extern_name = c.user.extern_name c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) available_languages = [x[0] for x in c.allowed_languages] - _form = UserForm(edit=True, available_languages=available_languages, + _form = UserForm(self.request.translate, edit=True, + available_languages=available_languages, old_data={'user_id': user_id, 'email': c.user.email})() form_result = {} @@ -538,7 +539,7 @@ class UsersView(UserAppView): c.active = 'global_perms' try: # first stage that verifies the checkbox - _form = UserIndividualPermissionsForm() + _form = UserIndividualPermissionsForm(self.request.translate) form_result = _form.to_python(dict(self.request.POST)) inherit_perms = form_result['inherit_default_permissions'] c.user.inherit_default_permissions = inherit_perms @@ -547,6 +548,7 @@ class UsersView(UserAppView): if not inherit_perms: # only update the individual ones if we un check the flag _form = UserPermissionsForm( + self.request.translate, [x[0] for x in c.repo_create_choices], [x[0] for x in c.repo_create_on_write_choices], [x[0] for x in c.repo_group_create_choices], @@ -914,6 +916,11 @@ class UsersView(UserAppView): email = self.request.POST.get('new_email') user_data = c.user.get_api_data() try: + + form = UserExtraEmailForm(self.request.translate)() + data = form.to_python({'email': email}) + email = data['email'] + UserModel().add_extra_email(c.user.user_id, email) audit_logger.store_web( 'user.edit.email.add', @@ -1009,6 +1016,10 @@ class UsersView(UserAppView): user_data = c.user.get_api_data() for ip in ip_list: try: + form = UserExtraIpForm(self.request.translate)() + data = form.to_python({'ip': ip}) + ip = data['ip'] + user_model.add_extra_ip(c.user.user_id, ip, desc) audit_logger.store_web( 'user.edit.ip.add', diff --git a/rhodecode/apps/channelstream/views.py b/rhodecode/apps/channelstream/views.py --- a/rhodecode/apps/channelstream/views.py +++ b/rhodecode/apps/channelstream/views.py @@ -24,6 +24,7 @@ import uuid from pyramid.view import view_config from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway +from rhodecode.apps._base import BaseAppView from rhodecode.lib.channelstream import ( channelstream_request, ChannelstreamConnectionException, @@ -34,28 +35,28 @@ from rhodecode.lib.channelstream import parse_channels_info, update_history_from_logs, STATE_PUBLIC_KEYS) + from rhodecode.lib.auth import NotAnonymous log = logging.getLogger(__name__) -class ChannelstreamView(object): - def __init__(self, context, request): - self.context = context - self.request = request +class ChannelstreamView(BaseAppView): - # Some of the decorators rely on this attribute to be present - # on the class of the decorated method. - self._rhodecode_user = request.user - registry = request.registry - self.channelstream_config = registry.rhodecode_plugins['channelstream'] + def load_default_context(self): + c = self._get_local_tmpl_context() + self.channelstream_config = \ + self.request.registry.rhodecode_plugins['channelstream'] if not self.channelstream_config.get('enabled'): log.error('Channelstream plugin is disabled') raise HTTPBadRequest() + return c + @NotAnonymous() - @view_config(route_name='channelstream_connect', renderer='json') + @view_config(route_name='channelstream_connect', renderer='json_ext') def connect(self): + self.load_default_context() """ handle authorization of users trying to connect """ try: json_body = self.request.json_body @@ -122,9 +123,10 @@ class ChannelstreamView(object): return connect_result @NotAnonymous() - @view_config(route_name='channelstream_subscribe', renderer='json') + @view_config(route_name='channelstream_subscribe', renderer='json_ext') def subscribe(self): """ can be used to subscribe specific connection to other channels """ + self.load_default_context() try: json_body = self.request.json_body except Exception: diff --git a/rhodecode/apps/debug_style/views.py b/rhodecode/apps/debug_style/views.py --- a/rhodecode/apps/debug_style/views.py +++ b/rhodecode/apps/debug_style/views.py @@ -31,7 +31,7 @@ log = logging.getLogger(__name__) class DebugStyleView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @view_config( diff --git a/rhodecode/apps/gist/views.py b/rhodecode/apps/gist/views.py --- a/rhodecode/apps/gist/views.py +++ b/rhodecode/apps/gist/views.py @@ -67,7 +67,7 @@ class GistView(BaseAppView): (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users")) ] - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/home/tests/test_get_goto_switched_data.py b/rhodecode/apps/home/tests/test_get_goto_switched_data.py --- a/rhodecode/apps/home/tests/test_get_goto_switched_data.py +++ b/rhodecode/apps/home/tests/test_get_goto_switched_data.py @@ -66,7 +66,7 @@ class TestGotoSwitcherData(TestControlle ] @pytest.fixture(autouse=True, scope='class') - def prepare(self, request, pylonsapp): + def prepare(self, request, baseapp): for repo_and_group in self.required_repos_with_groups: # create structure of groups and return the last group diff --git a/rhodecode/apps/home/views.py b/rhodecode/apps/home/views.py --- a/rhodecode/apps/home/views.py +++ b/rhodecode/apps/home/views.py @@ -46,7 +46,7 @@ class HomeView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() c.user = c.auth_user.get_instance() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/journal/views.py b/rhodecode/apps/journal/views.py --- a/rhodecode/apps/journal/views.py +++ b/rhodecode/apps/journal/views.py @@ -47,7 +47,7 @@ class JournalView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context(include_app_defaults=True) - self._register_global_c(c) + self._load_defaults(c.rhodecode_name) # TODO(marcink): what is this, why we need a global register ? @@ -146,7 +146,8 @@ class JournalView(BaseAppView): user = AttributeDict({'short_contact': entry.username, 'email': '', 'full_contact': ''}) - action, action_extra, ico = h.action_parser(entry, feed=True) + action, action_extra, ico = h.action_parser( + self.request, entry, feed=True) title = "%s - %s %s" % (user.short_contact, action(), entry.repository.repo_name) desc = action_extra() @@ -191,7 +192,8 @@ class JournalView(BaseAppView): user = AttributeDict({'short_contact': entry.username, 'email': '', 'full_contact': ''}) - action, action_extra, ico = h.action_parser(entry, feed=True) + action, action_extra, ico = h.action_parser( + self.request, entry, feed=True) title = "%s - %s %s" % (user.short_contact, action(), entry.repository.repo_name) desc = action_extra() diff --git a/rhodecode/apps/login/tests/test_login.py b/rhodecode/apps/login/tests/test_login.py --- a/rhodecode/apps/login/tests/test_login.py +++ b/rhodecode/apps/login/tests/test_login.py @@ -30,7 +30,6 @@ from rhodecode.tests.fixture import Fixt from rhodecode.lib.auth import check_password from rhodecode.lib import helpers as h from rhodecode.model.auth_token import AuthTokenModel -from rhodecode.model import validators from rhodecode.model.db import User, Notification, UserApiKeys from rhodecode.model.meta import Session @@ -234,7 +233,7 @@ class TestLoginController(object): ) assertr = response.assert_response() - msg = validators.ValidUsername()._messages['username_exists'] + msg = '???' msg = msg % {'username': uname} assertr.element_contains('#username+.error-message', msg) @@ -252,7 +251,7 @@ class TestLoginController(object): ) assertr = response.assert_response() - msg = validators.UniqSystemEmail()()._messages['email_taken'] + msg = '???' assertr.element_contains('#email+.error-message', msg) def test_register_err_same_email_case_sensitive(self): @@ -268,7 +267,7 @@ class TestLoginController(object): } ) assertr = response.assert_response() - msg = validators.UniqSystemEmail()()._messages['email_taken'] + msg = '???' assertr.element_contains('#email+.error-message', msg) def test_register_err_wrong_data(self): @@ -322,7 +321,7 @@ class TestLoginController(object): ) assertr = response.assert_response() - msg = validators.ValidUsername()._messages['username_exists'] + msg = '???' msg = msg % {'username': usr} assertr.element_contains('#username+.error-message', msg) @@ -339,7 +338,7 @@ class TestLoginController(object): } ) - msg = validators.ValidPassword()._messages['invalid_password'] + msg = '???' response.mustcontain(msg) def test_register_password_mismatch(self): @@ -354,7 +353,7 @@ class TestLoginController(object): 'lastname': 'test' } ) - msg = validators.ValidPasswordsMatch()._messages['password_mismatch'] + msg = '???' response.mustcontain(msg) def test_register_ok(self): diff --git a/rhodecode/apps/login/views.py b/rhodecode/apps/login/views.py --- a/rhodecode/apps/login/views.py +++ b/rhodecode/apps/login/views.py @@ -113,7 +113,7 @@ class LoginView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() c.came_from = get_came_from(self.request) - self._register_global_c(c) + return c def _get_captcha_data(self): @@ -157,7 +157,7 @@ class LoginView(BaseAppView): def login_post(self): c = self.load_default_context() - login_form = LoginForm()() + login_form = LoginForm(self.request.translate)() try: self.session.invalidate() @@ -182,11 +182,10 @@ class LoginView(BaseAppView): defaults = errors.value # remove password from filling in form again defaults.pop('password', None) - render_ctx = self._get_template_context(c) - render_ctx.update({ + render_ctx = { 'errors': errors.error_dict, 'defaults': defaults, - }) + } audit_user = audit_logger.UserWrap( username=self.request.POST.get('username'), @@ -195,7 +194,7 @@ class LoginView(BaseAppView): audit_logger.store_web( 'user.login.failure', action_data=action_data, user=audit_user, commit=True) - return render_ctx + return self._get_template_context(c, **render_ctx) except UserCreationError as e: # headers auth or other auth functions that create users on @@ -255,7 +254,7 @@ class LoginView(BaseAppView): auto_active = 'hg.register.auto_activate' in User.get_default_user()\ .AuthUser().permissions['global'] - register_form = RegisterForm()() + register_form = RegisterForm(self.request.translate)() try: form_result = register_form.to_python(self.request.POST) @@ -324,7 +323,7 @@ class LoginView(BaseAppView): queue='error') return HTTPFound(self.request.route_path('reset_password')) - password_reset_form = PasswordResetForm()() + password_reset_form = PasswordResetForm(self.request.translate)() try: form_result = password_reset_form.to_python( self.request.POST) diff --git a/rhodecode/apps/my_account/tests/test_my_account_edit.py b/rhodecode/apps/my_account/tests/test_my_account_edit.py --- a/rhodecode/apps/my_account/tests/test_my_account_edit.py +++ b/rhodecode/apps/my_account/tests/test_my_account_edit.py @@ -198,8 +198,6 @@ class TestMyAccountEdit(TestController): params=params) response.mustcontain('An email address must contain a single @') - from rhodecode.model import validators - msg = validators.ValidUsername( - edit=False, old_data={})._messages['username_exists'] + msg = '???' msg = h.html_escape(msg % {'username': 'test_admin'}) response.mustcontain(u"%s" % msg) diff --git a/rhodecode/apps/my_account/views/my_account.py b/rhodecode/apps/my_account/views/my_account.py --- a/rhodecode/apps/my_account/views/my_account.py +++ b/rhodecode/apps/my_account/views/my_account.py @@ -42,7 +42,7 @@ from rhodecode.model.comment import Comm from rhodecode.model.db import ( Repository, UserEmailMap, UserApiKeys, UserFollowing, joinedload, PullRequest) -from rhodecode.model.forms import UserForm +from rhodecode.model.forms import UserForm, UserExtraEmailForm from rhodecode.model.meta import Session from rhodecode.model.pull_request import PullRequestModel from rhodecode.model.scm import RepoList @@ -64,7 +64,7 @@ class MyAccountView(BaseAppView, DataGri c = self._get_local_tmpl_context() c.user = c.auth_user.get_instance() c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS - self._register_global_c(c) + return c @LoginRequired() @@ -245,6 +245,10 @@ class MyAccountView(BaseAppView, DataGri email = self.request.POST.get('new_email') try: + form = UserExtraEmailForm(self.request.translate)() + data = form.to_python({'email': email}) + email = data['email'] + UserModel().add_extra_email(c.user.user_id, email) audit_logger.store_web( 'user.edit.email.add', action_data={ @@ -442,7 +446,7 @@ class MyAccountView(BaseAppView, DataGri c.extern_type = c.user.extern_type c.extern_name = c.user.extern_name - _form = UserForm(edit=True, + _form = UserForm(self.request.translate, edit=True, old_data={'user_id': self._rhodecode_user.user_id, 'email': self._rhodecode_user.email})() form_result = {} diff --git a/rhodecode/apps/my_account/views/my_account_notifications.py b/rhodecode/apps/my_account/views/my_account_notifications.py --- a/rhodecode/apps/my_account/views/my_account_notifications.py +++ b/rhodecode/apps/my_account/views/my_account_notifications.py @@ -43,7 +43,7 @@ class MyAccountNotificationsView(BaseApp def load_default_context(self): c = self._get_local_tmpl_context() c.user = c.auth_user.get_instance() - self._register_global_c(c) + return c def _has_permissions(self, notification): diff --git a/rhodecode/apps/my_account/views/my_account_ssh_keys.py b/rhodecode/apps/my_account/views/my_account_ssh_keys.py --- a/rhodecode/apps/my_account/views/my_account_ssh_keys.py +++ b/rhodecode/apps/my_account/views/my_account_ssh_keys.py @@ -44,7 +44,7 @@ class MyAccountSshKeysView(BaseAppView, c.ssh_enabled = self.request.registry.settings.get( 'ssh.generate_authorized_keyfile') - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/ops/__init__.py b/rhodecode/apps/ops/__init__.py --- a/rhodecode/apps/ops/__init__.py +++ b/rhodecode/apps/ops/__init__.py @@ -36,7 +36,7 @@ def admin_routes(config): def includeme(config): config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops') - # make OLD entries from pylons work + # make OLD entries from <4.10.0 work config.add_route( name='ops_ping_legacy', pattern=ADMIN_PREFIX + '/ping') config.add_route( diff --git a/rhodecode/apps/ops/views.py b/rhodecode/apps/ops/views.py --- a/rhodecode/apps/ops/views.py +++ b/rhodecode/apps/ops/views.py @@ -35,7 +35,7 @@ class OpsView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() c.user = c.auth_user.get_instance() - self._register_global_c(c) + return c @view_config( diff --git a/rhodecode/apps/repo_group/views/repo_group_advanced.py b/rhodecode/apps/repo_group/views/repo_group_advanced.py --- a/rhodecode/apps/repo_group/views/repo_group_advanced.py +++ b/rhodecode/apps/repo_group/views/repo_group_advanced.py @@ -37,7 +37,7 @@ log = logging.getLogger(__name__) class RepoGroupSettingsView(RepoGroupAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repo_group/views/repo_group_permissions.py b/rhodecode/apps/repo_group/views/repo_group_permissions.py --- a/rhodecode/apps/repo_group/views/repo_group_permissions.py +++ b/rhodecode/apps/repo_group/views/repo_group_permissions.py @@ -38,7 +38,7 @@ log = logging.getLogger(__name__) class RepoGroupPermissionsView(RepoGroupAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() @@ -65,7 +65,7 @@ class RepoGroupPermissionsView(RepoGroup c.repo_group = self.db_repo_group valid_recursive_choices = ['none', 'repos', 'groups', 'all'] - form = RepoGroupPermsForm(valid_recursive_choices)()\ + form = RepoGroupPermsForm(self.request.translate, valid_recursive_choices)()\ .to_python(self.request.POST) if not c.rhodecode_user.is_admin: diff --git a/rhodecode/apps/repo_group/views/repo_group_settings.py b/rhodecode/apps/repo_group/views/repo_group_settings.py --- a/rhodecode/apps/repo_group/views/repo_group_settings.py +++ b/rhodecode/apps/repo_group/views/repo_group_settings.py @@ -73,7 +73,7 @@ class RepoGroupSettingsView(RepoGroupApp c.repo_groups_choices.append(parent_group.group_id) c.repo_groups.append(RepoGroup._generate_choice(parent_group)) - self._register_global_c(c) + return c def _can_create_repo_group(self, parent_group_id=None): diff --git a/rhodecode/apps/repository/tests/test_repo_commit_comments.py b/rhodecode/apps/repository/tests/test_repo_commit_comments.py --- a/rhodecode/apps/repository/tests/test_repo_commit_comments.py +++ b/rhodecode/apps/repository/tests/test_repo_commit_comments.py @@ -47,7 +47,7 @@ def route_path(name, params=None, **kwar class TestRepoCommitCommentsView(TestController): @pytest.fixture(autouse=True) - def prepare(self, request, pylonsapp): + def prepare(self, request, baseapp): for x in ChangesetComment.query().all(): Session().delete(x) Session().commit() diff --git a/rhodecode/apps/repository/views/repo_audit_logs.py b/rhodecode/apps/repository/views/repo_audit_logs.py --- a/rhodecode/apps/repository/views/repo_audit_logs.py +++ b/rhodecode/apps/repository/views/repo_audit_logs.py @@ -34,7 +34,7 @@ class AuditLogsView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repository/views/repo_caches.py b/rhodecode/apps/repository/views/repo_caches.py --- a/rhodecode/apps/repository/views/repo_caches.py +++ b/rhodecode/apps/repository/views/repo_caches.py @@ -37,7 +37,7 @@ class RepoCachesView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repository/views/repo_changelog.py b/rhodecode/apps/repository/views/repo_changelog.py --- a/rhodecode/apps/repository/views/repo_changelog.py +++ b/rhodecode/apps/repository/views/repo_changelog.py @@ -159,7 +159,7 @@ class RepoChangelogView(RepoAppView): c = self._get_local_tmpl_context(include_app_defaults=True) c.rhodecode_repo = self.rhodecode_vcs_repo - self._register_global_c(c) + return c def _get_preload_attrs(self): diff --git a/rhodecode/apps/repository/views/repo_checks.py b/rhodecode/apps/repository/views/repo_checks.py --- a/rhodecode/apps/repository/views/repo_checks.py +++ b/rhodecode/apps/repository/views/repo_checks.py @@ -34,7 +34,7 @@ log = logging.getLogger(__name__) class RepoChecksView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @NotAnonymous() diff --git a/rhodecode/apps/repository/views/repo_commits.py b/rhodecode/apps/repository/views/repo_commits.py --- a/rhodecode/apps/repository/views/repo_commits.py +++ b/rhodecode/apps/repository/views/repo_commits.py @@ -150,7 +150,6 @@ class RepoCommitsView(RepoAppView): c = self._get_local_tmpl_context(include_app_defaults=True) c.rhodecode_repo = self.rhodecode_vcs_repo - self._register_global_c(c) return c def _commit(self, commit_id_range, method): diff --git a/rhodecode/apps/repository/views/repo_compare.py b/rhodecode/apps/repository/views/repo_compare.py --- a/rhodecode/apps/repository/views/repo_compare.py +++ b/rhodecode/apps/repository/views/repo_compare.py @@ -47,7 +47,7 @@ class RepoCompareView(RepoAppView): c.rhodecode_repo = self.rhodecode_vcs_repo - self._register_global_c(c) + return c def _get_commit_or_redirect( diff --git a/rhodecode/apps/repository/views/repo_feed.py b/rhodecode/apps/repository/views/repo_feed.py --- a/rhodecode/apps/repository/views/repo_feed.py +++ b/rhodecode/apps/repository/views/repo_feed.py @@ -42,7 +42,7 @@ class RepoFeedView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + self._load_defaults() return c diff --git a/rhodecode/apps/repository/views/repo_files.py b/rhodecode/apps/repository/views/repo_files.py --- a/rhodecode/apps/repository/views/repo_files.py +++ b/rhodecode/apps/repository/views/repo_files.py @@ -83,7 +83,7 @@ class RepoFilesView(RepoAppView): c.rhodecode_repo = self.rhodecode_vcs_repo - self._register_global_c(c) + return c def _ensure_not_locked(self): diff --git a/rhodecode/apps/repository/views/repo_forks.py b/rhodecode/apps/repository/views/repo_forks.py --- a/rhodecode/apps/repository/views/repo_forks.py +++ b/rhodecode/apps/repository/views/repo_forks.py @@ -57,7 +57,7 @@ class RepoForksView(RepoAppView, DataGri c.landing_revs_choices = choices c.personal_repo_group = c.rhodecode_user.personal_repo_group - self._register_global_c(c) + return c @LoginRequired() @@ -209,7 +209,7 @@ class RepoForksView(RepoAppView, DataGri _ = self.request.translate c = self.load_default_context() - _form = RepoForkForm(old_data={'repo_type': self.db_repo.repo_type}, + _form = RepoForkForm(self.request.translate, old_data={'repo_type': self.db_repo.repo_type}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() post_data = dict(self.request.POST) diff --git a/rhodecode/apps/repository/views/repo_maintainance.py b/rhodecode/apps/repository/views/repo_maintainance.py --- a/rhodecode/apps/repository/views/repo_maintainance.py +++ b/rhodecode/apps/repository/views/repo_maintainance.py @@ -33,7 +33,7 @@ class RepoMaintenanceView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repository/views/repo_permissions.py b/rhodecode/apps/repository/views/repo_permissions.py --- a/rhodecode/apps/repository/views/repo_permissions.py +++ b/rhodecode/apps/repository/views/repo_permissions.py @@ -40,7 +40,7 @@ class RepoSettingsPermissionsView(RepoAp def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() @@ -68,7 +68,7 @@ class RepoSettingsPermissionsView(RepoAp # default user permissions, prevents submission of FAKE post data # into the form for private repos data['repo_private'] = self.db_repo.private - form = RepoPermsForm()().to_python(data) + form = RepoPermsForm(self.request.translate)().to_python(data) changes = RepoModel().update_permissions( self.db_repo_name, form['perm_additions'], form['perm_updates'], form['perm_deletions']) diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py --- a/rhodecode/apps/repository/views/repo_pull_requests.py +++ b/rhodecode/apps/repository/views/repo_pull_requests.py @@ -60,7 +60,7 @@ class RepoPullRequestsView(RepoAppView, c = self._get_local_tmpl_context(include_app_defaults=True) c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED - self._register_global_c(c) + return c def _get_pull_requests_list( @@ -749,7 +749,9 @@ class RepoPullRequestsView(RepoAppView, controls = peppercorn.parse(self.request.POST.items()) try: - _form = PullRequestForm(self.db_repo.repo_id)().to_python(controls) + form = PullRequestForm( + self.request.translate, self.db_repo.repo_id)() + _form = form.to_python(controls) except formencode.Invalid as errors: if errors.error_dict.get('revisions'): msg = 'Revisions: %s' % errors.error_dict['revisions'] diff --git a/rhodecode/apps/repository/views/repo_review_rules.py b/rhodecode/apps/repository/views/repo_review_rules.py --- a/rhodecode/apps/repository/views/repo_review_rules.py +++ b/rhodecode/apps/repository/views/repo_review_rules.py @@ -32,8 +32,6 @@ log = logging.getLogger(__name__) class RepoReviewRulesView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - - self._register_global_c(c) return c @LoginRequired() @@ -54,6 +52,7 @@ class RepoReviewRulesView(RepoAppView): route_name='repo_default_reviewers_data', request_method='GET', renderer='json_ext') def repo_default_reviewers_data(self): + self.load_default_context() review_data = get_default_reviewers_data( self.db_repo.user, None, None, None, None) return review_data diff --git a/rhodecode/apps/repository/views/repo_settings.py b/rhodecode/apps/repository/views/repo_settings.py --- a/rhodecode/apps/repository/views/repo_settings.py +++ b/rhodecode/apps/repository/views/repo_settings.py @@ -71,7 +71,7 @@ class RepoSettingsView(RepoAppView): c.repo_fields = RepositoryField.query()\ .filter(RepositoryField.repository == self.db_repo).all() - self._register_global_c(c) + return c def _get_schema(self, c, old_values=None): diff --git a/rhodecode/apps/repository/views/repo_settings_advanced.py b/rhodecode/apps/repository/views/repo_settings_advanced.py --- a/rhodecode/apps/repository/views/repo_settings_advanced.py +++ b/rhodecode/apps/repository/views/repo_settings_advanced.py @@ -44,7 +44,7 @@ class RepoSettingsView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repository/views/repo_settings_fields.py b/rhodecode/apps/repository/views/repo_settings_fields.py --- a/rhodecode/apps/repository/views/repo_settings_fields.py +++ b/rhodecode/apps/repository/views/repo_settings_fields.py @@ -43,7 +43,7 @@ class RepoSettingsFieldsView(RepoAppView def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() @@ -70,7 +70,8 @@ class RepoSettingsFieldsView(RepoAppView _ = self.request.translate try: - form_result = RepoFieldForm()().to_python(dict(self.request.POST)) + form = RepoFieldForm(self.request.translate)() + form_result = form.to_python(dict(self.request.POST)) RepoModel().add_repo_field( self.db_repo_name, form_result['new_field_key'], diff --git a/rhodecode/apps/repository/views/repo_settings_issue_trackers.py b/rhodecode/apps/repository/views/repo_settings_issue_trackers.py --- a/rhodecode/apps/repository/views/repo_settings_issue_trackers.py +++ b/rhodecode/apps/repository/views/repo_settings_issue_trackers.py @@ -40,7 +40,7 @@ class RepoSettingsIssueTrackersView(Repo def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() @@ -118,7 +118,7 @@ class RepoSettingsIssueTrackersView(Repo Session().commit() try: - form = IssueTrackerPatternsForm()().to_python(self.request.POST) + form = IssueTrackerPatternsForm(self.request.translate)().to_python(self.request.POST) except formencode.Invalid as errors: log.exception('Failed to add new pattern') error = errors diff --git a/rhodecode/apps/repository/views/repo_settings_remote.py b/rhodecode/apps/repository/views/repo_settings_remote.py --- a/rhodecode/apps/repository/views/repo_settings_remote.py +++ b/rhodecode/apps/repository/views/repo_settings_remote.py @@ -36,7 +36,7 @@ class RepoSettingsRemoteView(RepoAppView def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repository/views/repo_settings_vcs.py b/rhodecode/apps/repository/views/repo_settings_vcs.py --- a/rhodecode/apps/repository/views/repo_settings_vcs.py +++ b/rhodecode/apps/repository/views/repo_settings_vcs.py @@ -43,7 +43,7 @@ class RepoSettingsVcsView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c def _vcs_form_defaults(self, repo_name): @@ -117,7 +117,7 @@ class RepoSettingsVcsView(RepoAppView): defaults = self._vcs_form_defaults(self.db_repo_name) c.inherit_global_settings = defaults['inherit_global_settings'] - application_form = RepoVcsSettingsForm(self.db_repo_name)() + application_form = RepoVcsSettingsForm(self.request.translate, self.db_repo_name)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: diff --git a/rhodecode/apps/repository/views/repo_strip.py b/rhodecode/apps/repository/views/repo_strip.py --- a/rhodecode/apps/repository/views/repo_strip.py +++ b/rhodecode/apps/repository/views/repo_strip.py @@ -35,7 +35,7 @@ class StripView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/repository/views/repo_summary.py b/rhodecode/apps/repository/views/repo_summary.py --- a/rhodecode/apps/repository/views/repo_summary.py +++ b/rhodecode/apps/repository/views/repo_summary.py @@ -53,7 +53,7 @@ class RepoSummaryView(RepoAppView): if not c.repository_requirements_missing: c.rhodecode_repo = self.rhodecode_vcs_repo - self._register_global_c(c) + return c def _get_readme_data(self, db_repo, default_renderer): diff --git a/rhodecode/apps/search/views.py b/rhodecode/apps/search/views.py --- a/rhodecode/apps/search/views.py +++ b/rhodecode/apps/search/views.py @@ -103,7 +103,7 @@ def search(request, tmpl_context, repo_n class SearchView(BaseAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() @@ -119,7 +119,7 @@ class SearchView(BaseAppView): class SearchRepoView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/apps/user_group/views/__init__.py b/rhodecode/apps/user_group/views/__init__.py --- a/rhodecode/apps/user_group/views/__init__.py +++ b/rhodecode/apps/user_group/views/__init__.py @@ -56,7 +56,7 @@ class UserGroupsView(UserGroupAppView): PermissionModel().set_global_permission_choices( c, gettext_translator=self.request.translate) - self._register_global_c(c) + return c def _get_perms_summary(self, user_group_id): @@ -94,6 +94,7 @@ class UserGroupsView(UserGroupAppView): """ Return members of given user group """ + self.load_default_context() user_group = self.db_user_group group_members_obj = sorted((x.user for x in user_group.members), key=lambda u: u.username.lower()) @@ -173,7 +174,8 @@ class UserGroupsView(UserGroupAppView): c.active = 'settings' users_group_form = UserGroupForm( - edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)() + self.request.translate, edit=True, + old_data=c.user_group.get_dict(), allow_disabled=True)() old_values = c.user_group.get_api_data() user_group_name = self.request.POST.get('users_group_name') @@ -346,7 +348,7 @@ class UserGroupsView(UserGroupAppView): user_group_id = user_group.users_group_id c = self.load_default_context() c.user_group = user_group - form = UserGroupPermsForm()().to_python(self.request.POST) + form = UserGroupPermsForm(self.request.translate)().to_python(self.request.POST) if not self._rhodecode_user.is_admin: if self._revoke_perms_on_yourself(form): @@ -435,6 +437,7 @@ class UserGroupsView(UserGroupAppView): if not inherit_perms: # only update the individual ones if we un check the flag _form = UserPermissionsForm( + self.request.translate, [x[0] for x in c.repo_create_choices], [x[0] for x in c.repo_create_on_write_choices], [x[0] for x in c.repo_group_create_choices], diff --git a/rhodecode/authentication/base.py b/rhodecode/authentication/base.py --- a/rhodecode/authentication/base.py +++ b/rhodecode/authentication/base.py @@ -252,29 +252,6 @@ class RhodeCodeAuthPluginBase(object): del settings_copy[k] return settings_copy - @property - def validators(self): - """ - Exposes RhodeCode validators modules - """ - # this is a hack to overcome issues with pylons threadlocals and - # translator object _() not being registered properly. - class LazyCaller(object): - def __init__(self, name): - self.validator_name = name - - def __call__(self, *args, **kwargs): - from rhodecode.model import validators as v - obj = getattr(v, self.validator_name) - # log.debug('Initializing lazy formencode object: %s', obj) - return LazyFormencode(obj, *args, **kwargs) - - class ProxyGet(object): - def __getattribute__(self, name): - return LazyCaller(name) - - return ProxyGet() - @hybrid_property def name(self): """ diff --git a/rhodecode/authentication/views.py b/rhodecode/authentication/views.py --- a/rhodecode/authentication/views.py +++ b/rhodecode/authentication/views.py @@ -26,25 +26,24 @@ from pyramid.httpexceptions import HTTPF from pyramid.renderers import render from pyramid.response import Response +from rhodecode.apps._base import BaseAppView from rhodecode.authentication.base import ( get_auth_cache_manager, get_perms_cache_manager, get_authn_registry) -from rhodecode.lib import auth -from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator +from rhodecode.lib.auth import ( + LoginRequired, HasPermissionAllDecorator, CSRFRequired) from rhodecode.model.forms import AuthSettingsForm from rhodecode.model.meta import Session from rhodecode.model.settings import SettingsModel -from rhodecode.translation import _ log = logging.getLogger(__name__) -class AuthnPluginViewBase(object): +class AuthnPluginViewBase(BaseAppView): - def __init__(self, context, request): - self.request = request - self.context = context - self.plugin = context.plugin - self._rhodecode_user = request.user + def load_default_context(self): + c = self._get_local_tmpl_context() + self.plugin = self.context.plugin + return c @LoginRequired() @HasPermissionAllDecorator('hg.admin') @@ -52,6 +51,7 @@ class AuthnPluginViewBase(object): """ View that displays the plugin settings as a form. """ + c = self.load_default_context() defaults = defaults or {} errors = errors or {} schema = self.plugin.get_settings_schema() @@ -70,15 +70,17 @@ class AuthnPluginViewBase(object): 'resource': self.context, } - return template_context + return self._get_template_context(c, **template_context) @LoginRequired() @HasPermissionAllDecorator('hg.admin') - @auth.CSRFRequired() + @CSRFRequired() def settings_post(self): """ View that validates and stores the plugin settings. """ + _ = self.request.translate + self.load_default_context() schema = self.plugin.get_settings_schema() data = self.request.params @@ -107,23 +109,16 @@ class AuthnPluginViewBase(object): return HTTPFound(redirect_to) -# TODO: Ongoing migration in these views. -# - Maybe we should also use a colander schema for these views. -class AuthSettingsView(object): - def __init__(self, context, request): - self.context = context - self.request = request - - # TODO: Move this into a utility function. It is needed in all view - # classes during migration. Maybe a mixin? - - # Some of the decorators rely on this attribute to be present on the - # class of the decorated method. - self._rhodecode_user = request.user +class AuthSettingsView(BaseAppView): + def load_default_context(self): + c = self._get_local_tmpl_context() + return c @LoginRequired() @HasPermissionAllDecorator('hg.admin') def index(self, defaults=None, errors=None, prefix_error=False): + c = self.load_default_context() + defaults = defaults or {} authn_registry = get_authn_registry(self.request.registry) enabled_plugins = SettingsModel().get_auth_plugins() @@ -135,8 +130,8 @@ class AuthSettingsView(object): 'enabled_plugins': enabled_plugins, } html = render('rhodecode:templates/admin/auth/auth_settings.mako', - template_context, - request=self.request) + self._get_template_context(c, **template_context), + self.request) # Create form default values and fill the form. form_defaults = { @@ -155,11 +150,12 @@ class AuthSettingsView(object): @LoginRequired() @HasPermissionAllDecorator('hg.admin') - @auth.CSRFRequired() + @CSRFRequired() def auth_settings(self): + _ = self.request.translate try: - form = AuthSettingsForm()() - form_result = form.to_python(self.request.params) + form = AuthSettingsForm(self.request.translate)() + form_result = form.to_python(self.request.POST) plugins = ','.join(form_result['auth_plugins']) setting = SettingsModel().create_or_update_setting( 'auth_plugins', plugins) diff --git a/rhodecode/config/environment.py b/rhodecode/config/environment.py --- a/rhodecode/config/environment.py +++ b/rhodecode/config/environment.py @@ -18,127 +18,49 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -""" -Pylons environment configuration -""" import os import logging import rhodecode -from mako.lookup import TemplateLookup -from pyramid.settings import asbool - # ------------------------------------------------------------------------------ # CELERY magic until refactor - issue #4163 - import order matters here: -from rhodecode.lib import celerypylons # this must be first, celerypylons +#from rhodecode.lib import celerypylons # this must be first, celerypylons # sets config settings upon import import rhodecode.integrations # any modules using celery task # decorators should be added afterwards: # ------------------------------------------------------------------------------ -from rhodecode.lib import app_globals from rhodecode.config import utils -from rhodecode.config.routing import make_map -from rhodecode.lib import helpers -from rhodecode.lib.utils import ( - make_db_config, set_rhodecode_config, load_rcextensions) -from rhodecode.lib.utils2 import str2bool, aslist +from rhodecode.lib.utils import load_rcextensions +from rhodecode.lib.utils2 import str2bool from rhodecode.lib.vcs import connect_vcs, start_vcs_server log = logging.getLogger(__name__) -def load_environment(global_conf, app_conf, initial=False, - test_env=None, test_index=None): - """ - Configure the Pylons environment via the ``pylons.config`` - object - """ - from pylons.configuration import PylonsConfig - from pylons.error import handle_mako_error - - config = PylonsConfig() - - - # Pylons paths - root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - paths = { - 'root': root, - 'controllers': os.path.join(root, 'controllers'), - 'static_files': os.path.join(root, 'public'), - 'templates': [os.path.join(root, 'templates')], - } - - # Initialize config with the basic options - config.init_app(global_conf, app_conf, package='rhodecode', paths=paths) - - # store some globals into rhodecode - rhodecode.CELERY_ENABLED = str2bool(config['app_conf'].get('use_celery')) - rhodecode.CELERY_EAGER = str2bool( - config['app_conf'].get('celery.always.eager')) - - config['routes.map'] = make_map(config) - - config['pylons.app_globals'] = app_globals.Globals(config) - config['pylons.h'] = helpers - rhodecode.CONFIG = config - - load_rcextensions(root_path=config['here']) - - # Setup cache object as early as possible - import pylons - pylons.cache._push_object(config['pylons.app_globals'].cache) - - # Create the Mako TemplateLookup, with the default auto-escaping - config['pylons.app_globals'].mako_lookup = TemplateLookup( - directories=paths['templates'], - error_handler=handle_mako_error, - module_directory=os.path.join(app_conf['cache_dir'], 'templates'), - input_encoding='utf-8', default_filters=['escape'], - imports=['from webhelpers.html import escape']) - - # sets the c attribute access when don't existing attribute are accessed - config['pylons.strict_tmpl_context'] = True - - # configure channelstream - config['channelstream_config'] = { - 'enabled': asbool(config.get('channelstream.enabled', False)), - 'server': config.get('channelstream.server'), - 'secret': config.get('channelstream.secret') - } - - db_cfg = make_db_config(clear_session=True) - - repos_path = list(db_cfg.items('paths'))[0][1] - config['base_path'] = repos_path - - # store db config also in main global CONFIG - set_rhodecode_config(config) - - # configure instance id - utils.set_instance_id(config) - - # CONFIGURATION OPTIONS HERE (note: all config options will override - # any Pylons config options) - - # store config reference into our module to skip import magic of pylons - rhodecode.CONFIG.update(config) - - return config - - def load_pyramid_environment(global_config, settings): # Some parts of the code expect a merge of global and app settings. settings_merged = global_config.copy() settings_merged.update(settings) - # Store the settings to make them available to other modules. - rhodecode.PYRAMID_SETTINGS = settings_merged - # NOTE(marcink): needs to be enabled after full port to pyramid - # rhodecode.CONFIG = config + # TODO(marcink): probably not required anymore + # configure channelstream, + settings_merged['channelstream_config'] = { + 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)), + 'server': settings_merged.get('channelstream.server'), + 'secret': settings_merged.get('channelstream.secret') + } + + + # TODO(marcink): celery + # # store some globals into rhodecode + # rhodecode.CELERY_ENABLED = str2bool(config['app_conf'].get('use_celery')) + # rhodecode.CELERY_EAGER = str2bool( + # config['app_conf'].get('celery.always.eager')) + # If this is a test run we prepare the test environment like # creating a test database, test search index and test repositories. @@ -152,6 +74,11 @@ def load_pyramid_environment(global_conf # Initialize the database connection. utils.initialize_database(settings_merged) + # TODO(marcink): base_path handling ? + # repos_path = list(db_cfg.items('paths'))[0][1] + + load_rcextensions(root_path=settings_merged['here']) + # Limit backends to `vcs.backends` from configuration for alias in rhodecode.BACKENDS.keys(): if alias not in settings['vcs.backends']: @@ -173,5 +100,10 @@ def load_pyramid_environment(global_conf utils.configure_vcs(settings) + # Store the settings to make them available to other modules. + + rhodecode.PYRAMID_SETTINGS = settings_merged + rhodecode.CONFIG = settings_merged + if vcs_server_enabled: connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings)) diff --git a/rhodecode/config/licenses.json b/rhodecode/config/licenses.json --- a/rhodecode/config/licenses.json +++ b/rhodecode/config/licenses.json @@ -43,10 +43,7 @@ }, "python2.7-Pygments-2.2.0": { "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" - }, - "python2.7-Pylons-1.0.2.rhodecode-patch1": { - "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" - }, + }, "python2.7-Routes-1.13": { "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" }, @@ -80,10 +77,7 @@ }, "python2.7-amqplib-1.0.2": { "GNU Lesser General Public License v3.0 only": "http://spdx.org/licenses/LGPL-3.0" - }, - "python2.7-anyjson-0.3.3": { - "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" - }, + }, "python2.7-appenlight-client-0.6.14": { "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" }, @@ -327,7 +321,7 @@ "Python Software Foundation License version 2": "http://spdx.org/licenses/Python-2.0", "Zope Public License 2.0": "http://spdx.org/licenses/ZPL-2.0" }, - "python2.7-setuptools-scm-1.15.0": { + "python2.7-setuptools-scm-1.15.6": { "MIT License": "http://spdx.org/licenses/MIT" }, "python2.7-simplegeneric-0.8.1": { diff --git a/rhodecode/config/middleware.py b/rhodecode/config/middleware.py --- a/rhodecode/config/middleware.py +++ b/rhodecode/config/middleware.py @@ -22,33 +22,26 @@ import logging import traceback import collections -from paste.registry import RegistryManager from paste.gzipper import make_gzip_middleware +from pyramid.wsgi import wsgiapp from pyramid.authorization import ACLAuthorizationPolicy from pyramid.config import Configurator from pyramid.settings import asbool, aslist -from pyramid.wsgi import wsgiapp from pyramid.httpexceptions import ( - HTTPException, HTTPError, HTTPInternalServerError, HTTPFound) + HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound) from pyramid.events import ApplicationCreated from pyramid.renderers import render_to_response -from routes.middleware import RoutesMiddleware -import rhodecode from rhodecode.model import meta from rhodecode.config import patches from rhodecode.config import utils as config_utils -from rhodecode.config.routing import STATIC_FILE_PREFIX -from rhodecode.config.environment import ( - load_environment, load_pyramid_environment) +from rhodecode.config.environment import load_pyramid_environment +from rhodecode.lib.middleware.vcs import VCSMiddleware from rhodecode.lib.vcs import VCSCommunicationError from rhodecode.lib.exceptions import VCSServerUnavailable from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled -from rhodecode.lib.middleware.error_handling import ( - PylonsErrorHandlingMiddleware) from rhodecode.lib.middleware.https_fixup import HttpsFixup -from rhodecode.lib.middleware.vcs import VCSMiddleware from rhodecode.lib.plugins.utils import register_rhodecode_plugin from rhodecode.lib.utils2 import aslist as rhodecode_aslist, AttributeDict from rhodecode.subscribers import ( @@ -59,76 +52,17 @@ from rhodecode.subscribers import ( log = logging.getLogger(__name__) -# this is used to avoid avoid the route lookup overhead in routesmiddleware -# for certain routes which won't go to pylons to - eg. static files, debugger -# it is only needed for the pylons migration and can be removed once complete -class SkippableRoutesMiddleware(RoutesMiddleware): - """ Routes middleware that allows you to skip prefixes """ - - def __init__(self, *args, **kw): - self.skip_prefixes = kw.pop('skip_prefixes', []) - super(SkippableRoutesMiddleware, self).__init__(*args, **kw) - - def __call__(self, environ, start_response): - for prefix in self.skip_prefixes: - if environ['PATH_INFO'].startswith(prefix): - # added to avoid the case when a missing /_static route falls - # through to pylons and causes an exception as pylons is - # expecting wsgiorg.routingargs to be set in the environ - # by RoutesMiddleware. - if 'wsgiorg.routing_args' not in environ: - environ['wsgiorg.routing_args'] = (None, {}) - return self.app(environ, start_response) - - return super(SkippableRoutesMiddleware, self).__call__( - environ, start_response) - - -def make_app(global_conf, static_files=True, **app_conf): - """Create a Pylons WSGI application and return it - - ``global_conf`` - The inherited configuration for this application. Normally from - the [DEFAULT] section of the Paste ini file. - - ``app_conf`` - The application's local configuration. Normally specified in - the [app:] section of the Paste ini file (where - defaults to main). - - """ - from pylons.wsgiapp import PylonsApp - - # Apply compatibility patches - patches.kombu_1_5_1_python_2_7_11() - patches.inspect_getargspec() - - # Configure the Pylons environment - config = load_environment(global_conf, app_conf) - - # The Pylons WSGI app - app = PylonsApp(config=config) - - # Establish the Registry for this application - app = RegistryManager(app) - - app.config = config - - return app +def is_http_error(response): + # error which should have traceback + return response.status_code > 499 def make_pyramid_app(global_config, **settings): """ - Constructs the WSGI application based on Pyramid and wraps the Pylons based - application. + Constructs the WSGI application based on Pyramid. Specials: - * We migrate from Pylons to Pyramid. While doing this, we keep both - frameworks functional. This involves moving some WSGI middlewares around - and providing access to some data internals, so that the old code is - still functional. - * The application can also be integrated like a plugin via the call to `includeme`. This is accompanied with the other utility functions which are called. Changing this should be done with great care to not break @@ -138,9 +72,11 @@ def make_pyramid_app(global_config, **se sanitize_settings_and_apply_defaults(settings) config = Configurator(settings=settings) - load_pyramid_environment(global_config, settings) - add_pylons_compat_data(config.registry, global_config, settings.copy()) + # Apply compatibility patches + patches.inspect_getargspec() + + load_pyramid_environment(global_config, settings) # Static file view comes first includeme_first(config) @@ -157,54 +93,24 @@ def make_pyramid_app(global_config, **se return pyramid_app -def make_not_found_view(config): +def not_found_view(request): """ This creates the view which should be registered as not-found-view to - pyramid. Basically it contains of the old pylons app, converted to a view. - Additionally it is wrapped by some other middlewares. + pyramid. """ - settings = config.registry.settings - vcs_server_enabled = settings['vcs.server.enable'] - # Make pylons app from unprepared settings. - pylons_app = make_app( - config.registry._pylons_compat_global_config, - **config.registry._pylons_compat_settings) - config.registry._pylons_compat_config = pylons_app.config - - # Appenlight monitoring. - pylons_app, appenlight_client = wrap_in_appenlight_if_enabled( - pylons_app, settings) + if not getattr(request, 'vcs_call', None): + # handle like regular case with our error_handler + return error_handler(HTTPNotFound(), request) - # The pylons app is executed inside of the pyramid 404 exception handler. - # Exceptions which are raised inside of it are not handled by pyramid - # again. Therefore we add a middleware that invokes the error handler in - # case of an exception or error response. This way we return proper error - # HTML pages in case of an error. - reraise = (settings.get('debugtoolbar.enabled', False) or - rhodecode.disable_error_handler) - pylons_app = PylonsErrorHandlingMiddleware( - pylons_app, error_handler, reraise) + # handle not found view as a vcs call + settings = request.registry.settings + ae_client = getattr(request, 'ae_client', None) + vcs_app = VCSMiddleware( + HTTPNotFound(), request.registry, settings, + appenlight_client=ae_client) - # The VCSMiddleware shall operate like a fallback if pyramid doesn't find a - # view to handle the request. Therefore it is wrapped around the pylons - # app. It has to be outside of the error handling otherwise error responses - # from the vcsserver are converted to HTML error pages. This confuses the - # command line tools and the user won't get a meaningful error message. - if vcs_server_enabled: - pylons_app = VCSMiddleware( - pylons_app, settings, appenlight_client, registry=config.registry) - - # Convert WSGI app to pyramid view and return it. - return wsgiapp(pylons_app) - - -def add_pylons_compat_data(registry, global_config, settings): - """ - Attach data to the registry to support the Pylons integration. - """ - registry._pylons_compat_global_config = global_config - registry._pylons_compat_settings = settings + return wsgiapp(vcs_app)(None, request) def error_handler(exception, request): @@ -220,10 +126,6 @@ def error_handler(exception, request): elif isinstance(exception, VCSCommunicationError): base_response = VCSServerUnavailable() - def is_http_error(response): - # error which should have traceback - return response.status_code > 499 - if is_http_error(base_response): log.exception( 'error occurred handling this request for path: %s', request.path) @@ -366,43 +268,29 @@ def includeme(config): for inc in includes: config.include(inc) - # This is the glue which allows us to migrate in chunks. By registering the - # pylons based application as the "Not Found" view in Pyramid, we will - # fallback to the old application each time the new one does not yet know - # how to handle a request. - config.add_notfound_view(make_not_found_view(config)) - + # custom not found view, if our pyramid app doesn't know how to handle + # the request pass it to potential VCS handling ap + config.add_notfound_view(not_found_view) if not settings.get('debugtoolbar.enabled', False): # disabled debugtoolbar handle all exceptions via the error_handlers config.add_view(error_handler, context=Exception) + # all errors including 403/404/50X config.add_view(error_handler, context=HTTPError) def wrap_app_in_wsgi_middlewares(pyramid_app, config): """ Apply outer WSGI middlewares around the application. - - Part of this has been moved up from the Pylons layer, so that the - data is also available if old Pylons code is hit through an already ported - view. """ settings = config.registry.settings # enable https redirects based on HTTP_X_URL_SCHEME set by proxy pyramid_app = HttpsFixup(pyramid_app, settings) - # Add RoutesMiddleware to support the pylons compatibility tween during - # migration to pyramid. - - # TODO(marcink): remove after migration to pyramid - if hasattr(config.registry, '_pylons_compat_config'): - routes_map = config.registry._pylons_compat_config['routes.map'] - pyramid_app = SkippableRoutesMiddleware( - pyramid_app, routes_map, - skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar')) - - pyramid_app, _ = wrap_in_appenlight_if_enabled(pyramid_app, settings) + pyramid_app, _ae_client = wrap_in_appenlight_if_enabled( + pyramid_app, settings) + config.registry.ae_client = _ae_client if settings['gzip_responses']: pyramid_app = make_gzip_middleware( @@ -518,10 +406,10 @@ def _int_setting(settings, name, default def _bool_setting(settings, name, default): - input = settings.get(name, default) - if isinstance(input, unicode): - input = input.encode('utf8') - settings[name] = asbool(input) + input_val = settings.get(name, default) + if isinstance(input_val, unicode): + input_val = input_val.encode('utf8') + settings[name] = asbool(input_val) def _list_setting(settings, name, default): diff --git a/rhodecode/config/patches.py b/rhodecode/config/patches.py --- a/rhodecode/config/patches.py +++ b/rhodecode/config/patches.py @@ -32,26 +32,10 @@ Please keep the following principles in """ -def kombu_1_5_1_python_2_7_11(): - """ - Kombu 1.5.1 relies on a private method which got removed in Python 2.7.11. - - This patch adds the symbol to the module :mod:`uuid` and assigns the value - ``None`` to it. This causes kombu to fall back to the public API of - :mod:`uuid`. - - This patch can most probably be removed once celery and kombu are updated - to more recent versions. - """ - import uuid - - if not hasattr(uuid, '_uuid_generate_random'): - uuid._uuid_generate_random = None - def inspect_getargspec(): """ - Pyramid and Pylons rely on inspect.getargspec to lookup the signature of + Pyramid rely on inspect.getargspec to lookup the signature of view functions. This is not compatible with cython, therefore we replace getargspec with a custom version. Code is inspired by the inspect module from Python-3.4 diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py deleted file mode 100644 --- a/rhodecode/config/routing.py +++ /dev/null @@ -1,184 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (C) 2010-2017 RhodeCode GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3 -# (only), as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# This program is dual-licensed. If you wish to learn more about the -# RhodeCode Enterprise Edition, including its added features, Support services, -# and proprietary license terms, please see https://rhodecode.com/licenses/ - -""" -Routes configuration - -The more specific and detailed routes should be defined first so they -may take precedent over the more generic routes. For more information -refer to the routes manual at http://routes.groovie.org/docs/ - -IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py -and _route_name variable which uses some of stored naming here to do redirects. -""" -import os -import re -from routes import Mapper - -# prefix for non repository related links needs to be prefixed with `/` -ADMIN_PREFIX = '/_admin' -STATIC_FILE_PREFIX = '/_static' - -# Default requirements for URL parts -URL_NAME_REQUIREMENTS = { - # group name can have a slash in them, but they must not end with a slash - 'group_name': r'.*?[^/]', - 'repo_group_name': r'.*?[^/]', - # repo names can have a slash in them, but they must not end with a slash - 'repo_name': r'.*?[^/]', - # file path eats up everything at the end - 'f_path': r'.*', - # reference types - 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)', - 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)', -} - - -class JSRoutesMapper(Mapper): - """ - Wrapper for routes.Mapper to make pyroutes compatible url definitions - """ - _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$') - _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)') - def __init__(self, *args, **kw): - super(JSRoutesMapper, self).__init__(*args, **kw) - self._jsroutes = [] - - def connect(self, *args, **kw): - """ - Wrapper for connect to take an extra argument jsroute=True - - :param jsroute: boolean, if True will add the route to the pyroutes list - """ - if kw.pop('jsroute', False): - if not self._named_route_regex.match(args[0]): - raise Exception('only named routes can be added to pyroutes') - self._jsroutes.append(args[0]) - - super(JSRoutesMapper, self).connect(*args, **kw) - - def _extract_route_information(self, route): - """ - Convert a route into tuple(name, path, args), eg: - ('show_user', '/profile/%(username)s', ['username']) - """ - routepath = route.routepath - def replace(matchobj): - if matchobj.group(1): - return "%%(%s)s" % matchobj.group(1).split(':')[0] - else: - return "%%(%s)s" % matchobj.group(2) - - routepath = self._argument_prog.sub(replace, routepath) - return ( - route.name, - routepath, - [(arg[0].split(':')[0] if arg[0] != '' else arg[1]) - for arg in self._argument_prog.findall(route.routepath)] - ) - - def jsroutes(self): - """ - Return a list of pyroutes.js compatible routes - """ - for route_name in self._jsroutes: - yield self._extract_route_information(self._routenames[route_name]) - - -def make_map(config): - """Create, configure and return the routes Mapper""" - rmap = JSRoutesMapper( - directory=config['pylons.paths']['controllers'], - always_scan=config['debug']) - rmap.minimization = False - rmap.explicit = False - - from rhodecode.lib.utils2 import str2bool - from rhodecode.model import repo, repo_group - - def check_repo(environ, match_dict): - """ - check for valid repository for proper 404 handling - - :param environ: - :param match_dict: - """ - repo_name = match_dict.get('repo_name') - - if match_dict.get('f_path'): - # fix for multiple initial slashes that causes errors - match_dict['f_path'] = match_dict['f_path'].lstrip('/') - repo_model = repo.RepoModel() - by_name_match = repo_model.get_by_repo_name(repo_name) - # if we match quickly from database, short circuit the operation, - # and validate repo based on the type. - if by_name_match: - return True - - by_id_match = repo_model.get_repo_by_id(repo_name) - if by_id_match: - repo_name = by_id_match.repo_name - match_dict['repo_name'] = repo_name - return True - - return False - - def check_group(environ, match_dict): - """ - check for valid repository group path for proper 404 handling - - :param environ: - :param match_dict: - """ - repo_group_name = match_dict.get('group_name') - repo_group_model = repo_group.RepoGroupModel() - by_name_match = repo_group_model.get_by_group_name(repo_group_name) - if by_name_match: - return True - - return False - - def check_user_group(environ, match_dict): - """ - check for valid user group for proper 404 handling - - :param environ: - :param match_dict: - """ - return True - - def check_int(environ, match_dict): - return match_dict.get('id').isdigit() - - - #========================================================================== - # CUSTOM ROUTES HERE - #========================================================================== - - # ADMIN MY ACCOUNT - with rmap.submapper(path_prefix=ADMIN_PREFIX, - controller='admin/my_account') as m: - - # NOTE(marcink): this needs to be kept for password force flag to be - # handled in pylons controllers, remove after full migration to pyramid - m.connect('my_account_password', '/my_account/password', - action='my_account_password', conditions={'method': ['GET']}) - - return rmap diff --git a/rhodecode/integrations/views.py b/rhodecode/integrations/views.py --- a/rhodecode/integrations/views.py +++ b/rhodecode/integrations/views.py @@ -110,7 +110,7 @@ class IntegrationSettingsViewBase(BaseAp return False - def _get_local_tmpl_context(self, include_app_defaults=False): + def _get_local_tmpl_context(self, include_app_defaults=True): _ = self.request.translate c = super(IntegrationSettingsViewBase, self)._get_local_tmpl_context( include_app_defaults=include_app_defaults) @@ -366,7 +366,7 @@ class GlobalIntegrationsView(Integration c.repo = self.repo c.repo_group = self.repo_group c.navlist = navigation_list(self.request) - self._register_global_c(c) + return c @LoginRequired() @@ -403,7 +403,7 @@ class RepoIntegrationsView(IntegrationSe c.repo_name = self.db_repo.repo_name c.repository_pull_requests = ScmModel().get_pull_requests(self.repo) - self._register_global_c(c) + return c @LoginRequired() @@ -434,7 +434,7 @@ class RepoGroupIntegrationsView(Integrat c.repo = self.repo c.repo_group = self.repo_group c.navlist = navigation_list(self.request) - self._register_global_c(c) + return c @LoginRequired() diff --git a/rhodecode/lib/action_parser.py b/rhodecode/lib/action_parser.py --- a/rhodecode/lib/action_parser.py +++ b/rhodecode/lib/action_parser.py @@ -20,7 +20,6 @@ import logging -from pylons.i18n.translation import _ from webhelpers.html.builder import literal from webhelpers.html.tags import link_to @@ -32,7 +31,7 @@ from rhodecode.lib.vcs.exceptions import log = logging.getLogger(__name__) -def action_parser(user_log, feed=False, parse_cs=False): +def action_parser(request, user_log, feed=False, parse_cs=False): """ This helper will action_map the specified string action into translated fancy names with icons and links @@ -42,11 +41,11 @@ def action_parser(user_log, feed=False, :param parse_cs: parse Changesets into VCS instances """ if user_log.version == 'v2': - ap = AuditLogParser(user_log) + ap = AuditLogParser(request, user_log) return ap.callbacks() else: # old style - ap = ActionParser(user_log, feed=False, parse_commits=False) + ap = ActionParser(request, user_log, feed=False, parse_commits=False) return ap.callbacks() @@ -55,10 +54,11 @@ class ActionParser(object): commits_limit = 3 # display this amount always commits_top_limit = 50 # show up to this amount of commits hidden - def __init__(self, user_log, feed=False, parse_commits=False): + def __init__(self, request, user_log, feed=False, parse_commits=False): self.user_log = user_log self.feed = feed self.parse_commits = parse_commits + self.request = request self.action = user_log.action self.action_params = ' ' @@ -86,7 +86,7 @@ class ActionParser(object): @property def action_map(self): - + _ = self.request.translate # action : translated str, callback(extractor), icon action_map = { 'user_deleted_repo': ( @@ -166,6 +166,7 @@ class ActionParser(object): def get_fork_name(self): from rhodecode.lib import helpers as h + _ = self.request.translate repo_name = self.action_params _url = h.route_path('repo_summary', repo_name=repo_name) return _('fork name %s') % link_to(self.action_params, _url) @@ -180,6 +181,7 @@ class ActionParser(object): def get_pull_request(self): from rhodecode.lib import helpers as h + _ = self.request.translate pull_request_id = self.action_params if self.is_deleted(): repo_name = self.user_log.repository_name @@ -201,6 +203,7 @@ class ActionParser(object): def get_cs_links(self): from rhodecode.lib import helpers as h + _ = self.request.translate if self.is_deleted(): return self.action_params @@ -277,7 +280,9 @@ class ActionParser(object): def lnk(self, commit_or_id, repo_name): from rhodecode.lib.helpers import tooltip from rhodecode.lib import helpers as h - + _ = self.request.translate + title = '' + lazy_cs = True if isinstance(commit_or_id, (BaseCommit, AttributeDict)): lazy_cs = True if (getattr(commit_or_id, 'op', None) and @@ -312,8 +317,9 @@ class ActionParser(object): class AuditLogParser(object): - def __init__(self, audit_log_entry): + def __init__(self, request, audit_log_entry): self.audit_log_entry = audit_log_entry + self.request = request def get_icon(self, action): return 'icon-rhodecode' diff --git a/rhodecode/lib/app_globals.py b/rhodecode/lib/app_globals.py deleted file mode 100644 --- a/rhodecode/lib/app_globals.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (C) 2010-2017 RhodeCode GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3 -# (only), as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# This program is dual-licensed. If you wish to learn more about the -# RhodeCode Enterprise Edition, including its added features, Support services, -# and proprietary license terms, please see https://rhodecode.com/licenses/ - -""" -The application's Globals object -""" - -from beaker.cache import CacheManager -from beaker.util import parse_cache_config_options - - -class Globals(object): - """ - Globals acts as a container for objects available throughout the - life of the application - """ - - def __init__(self, config): - """One instance of Globals is created during application - initialization and is available during requests via the - 'app_globals' variable - - """ - self.cache = CacheManager(**parse_cache_config_options(config)) - self.available_permissions = None # propagated after init_model diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py --- a/rhodecode/lib/auth.py +++ b/rhodecode/lib/auth.py @@ -34,7 +34,7 @@ import traceback from functools import wraps import ipaddress -from beaker.cache import cache_region + from pyramid.httpexceptions import HTTPForbidden, HTTPFound, HTTPNotFound from sqlalchemy.orm.exc import ObjectDeletedError from sqlalchemy.orm import joinedload diff --git a/rhodecode/lib/base.py b/rhodecode/lib/base.py --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -52,42 +52,9 @@ from rhodecode.model.notification import from rhodecode.model.scm import ScmModel from rhodecode.model.settings import VcsSettingsModel, SettingsModel -# NOTE(marcink): remove after base controller is no longer required -from pylons.controllers import WSGIController -from pylons.i18n import translation - log = logging.getLogger(__name__) -# hack to make the migration to pyramid easier -def render(template_name, extra_vars=None, cache_key=None, - cache_type=None, cache_expire=None): - """Render a template with Mako - - Accepts the cache options ``cache_key``, ``cache_type``, and - ``cache_expire``. - - """ - from pylons.templating import literal - from pylons.templating import cached_template, pylons_globals - - # Create a render callable for the cache function - def render_template(): - # Pull in extra vars if needed - globs = extra_vars or {} - - # Second, get the globals - globs.update(pylons_globals()) - - globs['_ungettext'] = globs['ungettext'] - # Grab a template reference - template = globs['app_globals'].mako_lookup.get_template(template_name) - - return literal(template.render_unicode(**globs)) - - return cached_template(template_name, render_template, cache_key=cache_key, - cache_type=cache_type, cache_expire=cache_expire) - def _filter_proxy(ip): """ Passed in IP addresses in HEADERS can be in a special format of multiple @@ -310,14 +277,10 @@ def get_current_lang(request): def attach_context_attributes(context, request, user_id): """ - Attach variables into template context called `c`, please note that - request could be pylons or pyramid request in here. + Attach variables into template context called `c`. """ - # NOTE(marcink): remove check after pyramid migration - if hasattr(request, 'registry'): - config = request.registry.settings - else: - from pylons import config + config = request.registry.settings + rc_config = SettingsModel().get_all_settings(cache=True) @@ -418,10 +381,6 @@ def attach_context_attributes(context, r } # END CONFIG VARS - # TODO: This dosn't work when called from pylons compatibility tween. - # Fix this and remove it from base controller. - # context.repo_name = get_repo_slug(request) # can be empty - diffmode = 'sideside' if request.GET.get('diffmode'): if request.GET['diffmode'] == 'unified': @@ -439,20 +398,15 @@ def attach_context_attributes(context, r context.backends.sort() context.unread_notifications = NotificationModel().get_unread_cnt_for_user(user_id) - # NOTE(marcink): when migrated to pyramid we don't need to set this anymore, - # given request will ALWAYS be pyramid one - pyramid_request = pyramid.threadlocal.get_current_request() - context.pyramid_request = pyramid_request - # web case - if hasattr(pyramid_request, 'user'): - context.auth_user = pyramid_request.user - context.rhodecode_user = pyramid_request.user + if hasattr(request, 'user'): + context.auth_user = request.user + context.rhodecode_user = request.user # api case - if hasattr(pyramid_request, 'rpc_user'): - context.auth_user = pyramid_request.rpc_user - context.rhodecode_user = pyramid_request.rpc_user + if hasattr(request, 'rpc_user'): + context.auth_user = request.rpc_user + context.rhodecode_user = request.rpc_user # attach the whole call context to the request request.call_context = context @@ -500,82 +454,6 @@ def get_auth_user(request): return auth_user -class BaseController(WSGIController): - - def __before__(self): - """ - __before__ is called before controller methods and after __call__ - """ - # on each call propagate settings calls into global settings. - from pylons import config - from pylons import tmpl_context as c, request, url - set_rhodecode_config(config) - attach_context_attributes(c, request, self._rhodecode_user.user_id) - - # TODO: Remove this when fixed in attach_context_attributes() - c.repo_name = get_repo_slug(request) # can be empty - - self.cut_off_limit_diff = safe_int(config.get('cut_off_limit_diff')) - self.cut_off_limit_file = safe_int(config.get('cut_off_limit_file')) - self.sa = meta.Session - self.scm_model = ScmModel(self.sa) - - # set user language - user_lang = getattr(c.pyramid_request, '_LOCALE_', None) - if user_lang: - translation.set_lang(user_lang) - log.debug('set language to %s for user %s', - user_lang, self._rhodecode_user) - - def _dispatch_redirect(self, with_url, environ, start_response): - from webob.exc import HTTPFound - resp = HTTPFound(with_url) - environ['SCRIPT_NAME'] = '' # handle prefix middleware - environ['PATH_INFO'] = with_url - return resp(environ, start_response) - - def __call__(self, environ, start_response): - """Invoke the Controller""" - # WSGIController.__call__ dispatches to the Controller method - # the request is routed to. This routing information is - # available in environ['pylons.routes_dict'] - from rhodecode.lib import helpers as h - from pylons import tmpl_context as c, request, url - - # Provide the Pylons context to Pyramid's debugtoolbar if it asks - if environ.get('debugtoolbar.wants_pylons_context', False): - environ['debugtoolbar.pylons_context'] = c._current_obj() - - _route_name = '.'.join([environ['pylons.routes_dict']['controller'], - environ['pylons.routes_dict']['action']]) - - self.rc_config = SettingsModel().get_all_settings(cache=True) - self.ip_addr = get_ip_addr(environ) - - # The rhodecode auth user is looked up and passed through the - # environ by the pylons compatibility tween in pyramid. - # So we can just grab it from there. - auth_user = environ['rc_auth_user'] - - # set globals for auth user - request.user = auth_user - self._rhodecode_user = auth_user - - log.info('IP: %s User: %s accessed %s [%s]' % ( - self.ip_addr, auth_user, safe_unicode(get_access_path(environ)), - _route_name) - ) - - user_obj = auth_user.get_instance() - if user_obj and user_obj.user_data.get('force_password_change'): - h.flash('You are required to change your password', 'warning', - ignore_duplicate=True) - return self._dispatch_redirect( - url('my_account_password'), environ, start_response) - - return WSGIController.__call__(self, environ, start_response) - - def h_filter(s): """ Custom filter for Mako templates. Mako by standard uses `markupsafe.escape` @@ -623,6 +501,7 @@ def bootstrap_config(request): # allow pyramid lookup in testing config.include('pyramid_mako') + config.include('pyramid_beaker') add_events_routes(config) diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -28,7 +28,6 @@ import os import logging from celery.task import task -from pylons import config import rhodecode from rhodecode.lib import audit_logger @@ -42,9 +41,6 @@ from rhodecode.lib.utils2 import safe_in from rhodecode.model.db import Repository, User -add_cache(config) # pragma: no cover - - def get_logger(cls): if rhodecode.CELERY_ENABLED: try: diff --git a/rhodecode/lib/celerypylons/loader.py b/rhodecode/lib/celerypylons/loader.py --- a/rhodecode/lib/celerypylons/loader.py +++ b/rhodecode/lib/celerypylons/loader.py @@ -36,7 +36,7 @@ class PylonsSettingsProxy(object): """ def __getattr__(self, key): pylons_key = to_pylons(key) - proxy_config = rhodecode.PYRAMID_SETTINGS or pylons.config + proxy_config = rhodecode.PYRAMID_SETTINGS try: value = proxy_config[pylons_key] if key in LIST_PARAMS: @@ -59,7 +59,7 @@ class PylonsSettingsProxy(object): def __setattr__(self, key, value): pylons_key = to_pylons(key) - proxy_config = rhodecode.PYRAMID_SETTINGS or pylons.config + proxy_config = rhodecode.PYRAMID_SETTINGS proxy_config[pylons_key] = value def __setitem__(self, key, value): diff --git a/rhodecode/lib/diffs.py b/rhodecode/lib/diffs.py --- a/rhodecode/lib/diffs.py +++ b/rhodecode/lib/diffs.py @@ -30,7 +30,7 @@ import logging from itertools import tee, imap -from pylons.i18n.translation import _ +from rhodecode.translation import temp_translation_factory as _ from rhodecode.lib.vcs.exceptions import VCSError from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode diff --git a/rhodecode/lib/ext_json.py b/rhodecode/lib/ext_json.py --- a/rhodecode/lib/ext_json.py +++ b/rhodecode/lib/ext_json.py @@ -7,9 +7,9 @@ import simplejson as json from rhodecode.lib.datelib import is_aware try: - import pylons + import rhodecode.translation except ImportError: - pylons = None + rhodecode = None __all__ = ['json'] @@ -51,7 +51,7 @@ def _obj_dump(obj): return str(obj) elif isinstance(obj, complex): return [obj.real, obj.imag] - elif pylons and isinstance(obj, pylons.i18n.translation.LazyString): + elif rhodecode and isinstance(obj, rhodecode.translation.LazyString): return obj.eval() else: raise TypeError(repr(obj) + " is not JSON serializable") diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -91,11 +91,6 @@ DEFAULT_USER = User.DEFAULT_USER DEFAULT_USER_EMAIL = User.DEFAULT_USER_EMAIL -def url(*args, **kw): - from pylons import url as pylons_url - return pylons_url(*args, **kw) - - def asset(path, ver=None, **kwargs): """ Helper to generate a static asset file path for rhodecode assets @@ -1287,15 +1282,8 @@ def initials_gravatar(email_address, fir def gravatar_url(email_address, size=30, request=None): request = get_current_request() - if request and hasattr(request, 'call_context'): - _use_gravatar = request.call_context.visual.use_gravatar - _gravatar_url = request.call_context.visual.gravatar_url - else: - # doh, we need to re-import those to mock it later - from pylons import tmpl_context as c - - _use_gravatar = c.visual.use_gravatar - _gravatar_url = c.visual.gravatar_url + _use_gravatar = request.call_context.visual.use_gravatar + _gravatar_url = request.call_context.visual.gravatar_url _gravatar_url = _gravatar_url or User.DEFAULT_GRAVATAR_URL @@ -1745,8 +1733,6 @@ def urlify_commit_message(commit_text, r :param commit_text: :param repository: """ - from pylons import url # doh, we need to re-import url to mock it later - def escaper(string): return string.replace('<', '<').replace('>', '>') @@ -2006,8 +1992,6 @@ def get_last_path_part(file_node): def route_url(*args, **kwargs): """ Wrapper around pyramids `route_url` (fully qualified url) function. - It is used to generate URLs from within pylons views or templates. - This will be removed when pyramid migration if finished. """ req = get_current_request() return req.route_url(*args, **kwargs) @@ -2015,9 +1999,7 @@ def route_url(*args, **kwargs): def route_path(*args, **kwargs): """ - Wrapper around pyramids `route_path` function. It is used to generate - URLs from within pylons views or templates. This will be removed when - pyramid migration if finished. + Wrapper around pyramids `route_path` function. """ req = get_current_request() return req.route_path(*args, **kwargs) @@ -2036,26 +2018,6 @@ def current_route_path(request, **kw): return request.current_route_path(_query=new_args) -def static_url(*args, **kwds): - """ - Wrapper around pyramids `route_path` function. It is used to generate - URLs from within pylons views or templates. This will be removed when - pyramid migration if finished. - """ - req = get_current_request() - return req.static_url(*args, **kwds) - - -def resource_path(*args, **kwds): - """ - Wrapper around pyramids `route_path` function. It is used to generate - URLs from within pylons views or templates. This will be removed when - pyramid migration if finished. - """ - req = get_current_request() - return req.resource_path(*args, **kwds) - - def api_call_example(method, args): """ Generates an API call example via CURL diff --git a/rhodecode/lib/hooks_utils.py b/rhodecode/lib/hooks_utils.py --- a/rhodecode/lib/hooks_utils.py +++ b/rhodecode/lib/hooks_utils.py @@ -18,8 +18,8 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -import pylons import webob +from pyramid.threadlocal import get_current_request from rhodecode import events from rhodecode.lib import hooks_base @@ -31,12 +31,15 @@ def _get_rc_scm_extras(username, repo_na from rhodecode.lib.base import vcs_operation_context check_locking = action in ('pull', 'push') + request = get_current_request() + + # default + dummy_environ = webob.Request.blank('').environ try: - environ = pylons.request.environ + environ = request.environ or dummy_environ except TypeError: - # we might use this outside of request context, let's fake the - # environ data - environ = webob.Request.blank('').environ + # we might use this outside of request context + environ = dummy_environ extras = vcs_operation_context( environ, repo_name, username, action, repo_alias, check_locking) diff --git a/rhodecode/lib/index/whoosh.py b/rhodecode/lib/index/whoosh.py --- a/rhodecode/lib/index/whoosh.py +++ b/rhodecode/lib/index/whoosh.py @@ -27,7 +27,7 @@ import logging import os import re -from pylons.i18n.translation import _ +from rhodecode.translation import temp_translation_factory as _ from whoosh import query as query_lib, sorting from whoosh.highlight import HtmlFormatter, ContextFragmenter diff --git a/rhodecode/lib/middleware/error_handling.py b/rhodecode/lib/middleware/error_handling.py deleted file mode 100644 --- a/rhodecode/lib/middleware/error_handling.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (C) 2016-2017 RhodeCode GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3 -# (only), as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# This program is dual-licensed. If you wish to learn more about the -# RhodeCode Enterprise Edition, including its added features, Support services, -# and proprietary license terms, please see https://rhodecode.com/licenses/ - - -import logging -from pyramid import httpexceptions -from pyramid.httpexceptions import ( - HTTPRedirection, HTTPError, HTTPInternalServerError) -from pyramid.threadlocal import get_current_request - -from rhodecode.lib.exceptions import VCSServerUnavailable -from rhodecode.lib.vcs.exceptions import VCSCommunicationError - - -log = logging.getLogger(__name__) - - -class PylonsErrorHandlingMiddleware(object): - """ - This middleware is wrapped around the old pylons application to catch - errors and invoke our error handling view to return a proper error page. - """ - def __init__(self, app, error_view, reraise=False): - self.app = app - self.error_view = error_view - self._reraise = reraise - - def __call__(self, environ, start_response): - # We need to use the pyramid request here instead of creating a custom - # instance from the environ because this request maybe passed to the - # error handler view which is a pyramid view and expects a pyramid - # request which has been processed by the pyramid router. - request = get_current_request() - - response = self.handle_request(request) - return response(environ, start_response) - - def is_http_error(self, response): - # webob type error responses - return 400 <= response.status_int <= 599 - - def reraise(self): - return self._reraise - - def handle_request(self, request): - """ - Calls the underlying WSGI app (typically the old RhodeCode pylons app) - and returns the response if no error happened. In case of an error it - invokes the error handling view to return a proper error page as - response. - - - old webob type exceptions get converted to pyramid exceptions - - pyramid exceptions are passed to the error handler view - """ - try: - response = request.get_response(self.app) - if self.is_http_error(response): - response = webob_to_pyramid_http_response(response) - return self.error_view(response, request) - except HTTPRedirection as e: - # pyramid type redirection, with status codes in the 300s - log.debug('Handling pyramid HTTPRedirection: %s', e) - return e - except HTTPError as e: - # pyramid type exceptions, with status codes in the 400s and 500s - log.debug('Handling pyramid HTTPError: %s', e) - return self.error_view(e, request) - except Exception as e: - log.debug('Handling general error: %s', e) - - if self.reraise(): - raise - - if isinstance(e, VCSCommunicationError): - return self.error_view(VCSServerUnavailable(), request) - - return self.error_view(HTTPInternalServerError(), request) - - return response - - -def webob_to_pyramid_http_response(webob_response): - log.debug('response is webob http error[%s], handling now...', - webob_response.status_int) - ResponseClass = httpexceptions.status_map[webob_response.status_int] - pyramid_response = ResponseClass(webob_response.status) - pyramid_response.status = webob_response.status - pyramid_response.headers.update(webob_response.headers) - if pyramid_response.headers['content-type'] == 'text/html': - pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8' - return pyramid_response diff --git a/rhodecode/lib/middleware/request_wrapper.py b/rhodecode/lib/middleware/request_wrapper.py --- a/rhodecode/lib/middleware/request_wrapper.py +++ b/rhodecode/lib/middleware/request_wrapper.py @@ -23,7 +23,7 @@ import time import logging -from rhodecode.lib.base import get_ip_addr, get_access_path +from rhodecode.lib.base import get_ip_addr, get_access_path, get_user_agent from rhodecode.lib.utils2 import safe_str @@ -43,10 +43,11 @@ class RequestWrapperTween(object): response = self.handler(request) finally: end = time.time() - - log.info('IP: %s Request to %s time: %.3fs' % ( + total = end - start + log.info('IP: %s Request to %s time: %.3fs [%s]' % ( get_ip_addr(request.environ), - safe_str(get_access_path(request.environ)), end - start) + safe_str(get_access_path(request.environ)), total, + get_user_agent(request. environ),) ) return response diff --git a/rhodecode/lib/middleware/simplesvn.py b/rhodecode/lib/middleware/simplesvn.py --- a/rhodecode/lib/middleware/simplesvn.py +++ b/rhodecode/lib/middleware/simplesvn.py @@ -134,11 +134,11 @@ class SimpleSvn(simplevcs.SimpleVCS): # SVN includes the whole path in it's requests, including # subdirectories inside the repo. Therefore we have to search for # the repo root directory. - if not is_valid_repo(repo_name, self.basepath, self.SCM): + if not is_valid_repo(repo_name, self.base_path, self.SCM): current_path = '' for component in repo_name.split('/'): current_path += component - if is_valid_repo(current_path, self.basepath, self.SCM): + if is_valid_repo(current_path, self.base_path, self.SCM): return current_path current_path += '/' diff --git a/rhodecode/lib/middleware/simplevcs.py b/rhodecode/lib/middleware/simplevcs.py --- a/rhodecode/lib/middleware/simplevcs.py +++ b/rhodecode/lib/middleware/simplevcs.py @@ -31,7 +31,8 @@ from functools import wraps import time from paste.httpheaders import REMOTE_USER, AUTH_TYPE -from webob.exc import ( +# TODO(marcink): check if we should use webob.exc here ? +from pyramid.httpexceptions import ( HTTPNotFound, HTTPForbidden, HTTPNotAcceptable, HTTPInternalServerError) import rhodecode @@ -55,7 +56,7 @@ from rhodecode.model import meta from rhodecode.model.db import User, Repository, PullRequest from rhodecode.model.scm import ScmModel from rhodecode.model.pull_request import PullRequestModel -from rhodecode.model.settings import SettingsModel +from rhodecode.model.settings import SettingsModel, VcsSettingsModel log = logging.getLogger(__name__) @@ -103,14 +104,13 @@ class SimpleVCS(object): 'repository$' # shadow repo .format(slug_pat=SLUG_RE.pattern)) - def __init__(self, application, config, registry): + def __init__(self, config, registry): self.registry = registry - self.application = application self.config = config # re-populated by specialized middleware self.repo_vcs_config = base.Config() self.rhodecode_settings = SettingsModel().get_all_settings(cache=True) - self.basepath = rhodecode.CONFIG['base_path'] + registry.rhodecode_settings = self.rhodecode_settings # authenticate this VCS request using authfunc auth_ret_code_detection = \ @@ -120,6 +120,10 @@ class SimpleVCS(object): auth_ret_code_detection) self.ip_addr = '0.0.0.0' + @property + def base_path(self): + return self.repo_vcs_config.get(*VcsSettingsModel.PATH_SETTING) + def set_repo_names(self, environ): """ This will populate the attributes acl_repo_name, url_repo_name, @@ -381,6 +385,8 @@ class SimpleVCS(object): # Check if the shadow repo actually exists, in case someone refers # to it, and it has been deleted because of successful merge. if self.is_shadow_repo and not self.is_shadow_repo_dir: + log.debug('Shadow repo detected, and shadow repo dir `%s` is missing', + self.is_shadow_repo_dir) return HTTPNotFound()(environ, start_response) # ====================================================================== @@ -493,7 +499,7 @@ class SimpleVCS(object): # REQUEST HANDLING # ====================================================================== repo_path = os.path.join( - safe_str(self.basepath), safe_str(self.vcs_repo_name)) + safe_str(self.base_path), safe_str(self.vcs_repo_name)) log.debug('Repository path is %s', repo_path) fix_PATH() diff --git a/rhodecode/lib/middleware/vcs.py b/rhodecode/lib/middleware/vcs.py --- a/rhodecode/lib/middleware/vcs.py +++ b/rhodecode/lib/middleware/vcs.py @@ -168,11 +168,11 @@ def detect_vcs_request(environ, backends class VCSMiddleware(object): - def __init__(self, app, config, appenlight_client, registry): + def __init__(self, app, registry, config, appenlight_client): self.application = app + self.registry = registry self.config = config self.appenlight_client = appenlight_client - self.registry = registry self.use_gzip = True # order in which we check the middlewares, based on vcs.backends config self.check_middlewares = config['vcs.backends'] @@ -193,7 +193,7 @@ class VCSMiddleware(object): log.debug('VCSMiddleware: detecting vcs type.') handler = detect_vcs_request(environ, self.check_middlewares) if handler: - app = handler(self.application, self.config, self.registry) + app = handler(self.config, self.registry) return app @@ -212,7 +212,7 @@ class VCSMiddleware(object): # check for type, presence in database and on filesystem if not vcs_handler.is_valid_and_existing_repo( vcs_handler.acl_repo_name, - vcs_handler.basepath, + vcs_handler.base_path, vcs_handler.SCM): return HTTPNotFound()(environ, start_response) diff --git a/rhodecode/lib/system_info.py b/rhodecode/lib/system_info.py --- a/rhodecode/lib/system_info.py +++ b/rhodecode/lib/system_info.py @@ -578,9 +578,6 @@ def rhodecode_config(): blacklist = [ 'rhodecode_license_key', 'routes.map', - 'pylons.h', - 'pylons.app_globals', - 'pylons.environ_config', 'sqlalchemy.db1.url', 'channelstream.secret', 'beaker.session.secret', diff --git a/rhodecode/lib/utils.py b/rhodecode/lib/utils.py --- a/rhodecode/lib/utils.py +++ b/rhodecode/lib/utils.py @@ -97,18 +97,14 @@ def repo_name_slug(value): #============================================================================== def get_repo_slug(request): _repo = '' - if isinstance(request, Request): - if hasattr(request, 'db_repo'): - # if our requests has set db reference use it for name, this - # translates the example.com/_ into proper repo names - _repo = request.db_repo.repo_name - elif getattr(request, 'matchdict', None): - # pyramid - _repo = request.matchdict.get('repo_name') - # TODO(marcink): remove after pylons migration... - if not _repo: - _repo = request.environ['pylons.routes_dict'].get('repo_name') + if hasattr(request, 'db_repo'): + # if our requests has set db reference use it for name, this + # translates the example.com/_ into proper repo names + _repo = request.db_repo.repo_name + elif getattr(request, 'matchdict', None): + # pyramid + _repo = request.matchdict.get('repo_name') if _repo: _repo = _repo.rstrip('/') @@ -117,18 +113,14 @@ def get_repo_slug(request): def get_repo_group_slug(request): _group = '' - if isinstance(request, Request): - if hasattr(request, 'db_repo_group'): - # if our requests has set db reference use it for name, this - # translates the example.com/_ into proper repo group names - _group = request.db_repo_group.group_name - elif getattr(request, 'matchdict', None): - # pyramid - _group = request.matchdict.get('repo_group_name') + if hasattr(request, 'db_repo_group'): + # if our requests has set db reference use it for name, this + # translates the example.com/_ into proper repo group names + _group = request.db_repo_group.group_name + elif getattr(request, 'matchdict', None): + # pyramid + _group = request.matchdict.get('repo_group_name') - # TODO(marcink): remove after pylons migration... - if not _group: - _group = request.environ['pylons.routes_dict'].get('group_name') if _group: _group = _group.rstrip('/') @@ -137,26 +129,21 @@ def get_repo_group_slug(request): def get_user_group_slug(request): _user_group = '' - if isinstance(request, Request): - if hasattr(request, 'db_user_group'): - _user_group = request.db_user_group.users_group_name - elif getattr(request, 'matchdict', None): - # pyramid - _user_group = request.matchdict.get('user_group_id') + if hasattr(request, 'db_user_group'): + _user_group = request.db_user_group.users_group_name + elif getattr(request, 'matchdict', None): + # pyramid + _user_group = request.matchdict.get('user_group_id') - try: - _user_group = UserGroup.get(_user_group) - if _user_group: - _user_group = _user_group.users_group_name - except Exception: - log.exception('Failed to get user group by id') - # catch all failures here - return None - - # TODO(marcink): remove after pylons migration... - if not _user_group: - _user_group = request.environ['pylons.routes_dict'].get('user_group_id') + try: + _user_group = UserGroup.get(_user_group) + if _user_group: + _user_group = _user_group.users_group_name + except Exception: + log.exception('Failed to get user group by id') + # catch all failures here + return None return _user_group @@ -438,7 +425,7 @@ def get_enabled_hook_classes(ui_settings def set_rhodecode_config(config): """ - Updates pylons config with new settings from database + Updates pyramid config with new settings from database :param config: """ @@ -881,19 +868,6 @@ def read_opensource_licenses(): return _license_cache -def get_registry(request): - """ - Utility to get the pyramid registry from a request. During migration to - pyramid we sometimes want to use the pyramid registry from pylons context. - Therefore this utility returns `request.registry` for pyramid requests and - uses `get_current_registry()` for pylons requests. - """ - try: - return request.registry - except AttributeError: - return get_current_registry() - - def generate_platform_uuid(): """ Generates platform UUID based on it's name diff --git a/rhodecode/model/__init__.py b/rhodecode/model/__init__.py --- a/rhodecode/model/__init__.py +++ b/rhodecode/model/__init__.py @@ -18,27 +18,6 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -""" -The application's model objects - -:example: - - .. code-block:: python - - from paste.deploy import appconfig - from pylons import config - from sqlalchemy import engine_from_config - from rhodecode.config.environment import load_environment - - conf = appconfig('config:development.ini', relative_to = './../../') - load_environment(conf.global_conf, conf.local_conf) - - engine = engine_from_config(config, 'sqlalchemy.') - init_model(engine) - # RUN YOUR CODE HERE - -""" - import logging diff --git a/rhodecode/model/comment.py b/rhodecode/model/comment.py --- a/rhodecode/model/comment.py +++ b/rhodecode/model/comment.py @@ -26,7 +26,6 @@ import logging import traceback import collections -from pylons.i18n.translation import _ from pyramid.threadlocal import get_current_registry, get_current_request from sqlalchemy.sql.expression import null from sqlalchemy.sql.functions import coalesce @@ -68,8 +67,8 @@ class CommentsModel(BaseModel): user_objects.append(user_obj) return user_objects - def _get_renderer(self, global_renderer='rst'): - request = get_current_request() + def _get_renderer(self, global_renderer='rst', request=None): + request = request or get_current_request() try: global_renderer = request.call_context.visual.default_renderer @@ -194,9 +193,11 @@ class CommentsModel(BaseModel): if not text: log.warning('Missing text for comment, skipping...') return + request = get_current_request() + _ = request.translate if not renderer: - renderer = self._get_renderer() + renderer = self._get_renderer(request=request) repo = self._get_repo(repo) user = self._get_user(user) @@ -268,7 +269,7 @@ class CommentsModel(BaseModel): cs_author = repo.user recipients += [cs_author] - commit_comment_url = self.get_url(comment) + commit_comment_url = self.get_url(comment, request=request) target_repo_url = h.link_to( repo.repo_name, diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -48,7 +48,7 @@ import formencode from pkg_resources import resource_filename from formencode import All, Pipe -from pylons.i18n.translation import _ +from rhodecode.translation import temp_translation_factory as _ from pyramid.threadlocal import get_current_request from rhodecode import BACKENDS @@ -75,7 +75,9 @@ form_renderer = RhodecodeFormZPTRenderer deform.Form.set_default_renderer(form_renderer) -def LoginForm(): +def LoginForm(localizer): + _ = localizer + class _LoginForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -101,33 +103,37 @@ def LoginForm(): remember = v.StringBoolean(if_missing=False) - chained_validators = [v.ValidAuth()] + chained_validators = [v.ValidAuth(localizer)] return _LoginForm -def UserForm(edit=False, available_languages=[], old_data={}): +def UserForm(localizer, edit=False, available_languages=None, old_data=None): + old_data = old_data or {} + available_languages = available_languages or [] + _ = localizer + class _UserForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True username = All(v.UnicodeString(strip=True, min=1, not_empty=True), - v.ValidUsername(edit, old_data)) + v.ValidUsername(localizer, edit, old_data)) if edit: new_password = All( - v.ValidPassword(), + v.ValidPassword(localizer), v.UnicodeString(strip=False, min=6, max=72, not_empty=False) ) password_confirmation = All( - v.ValidPassword(), + v.ValidPassword(localizer), v.UnicodeString(strip=False, min=6, max=72, not_empty=False), ) admin = v.StringBoolean(if_missing=False) else: password = All( - v.ValidPassword(), + v.ValidPassword(localizer), v.UnicodeString(strip=False, min=6, max=72, not_empty=True) ) password_confirmation = All( - v.ValidPassword(), + v.ValidPassword(localizer), v.UnicodeString(strip=False, min=6, max=72, not_empty=False) ) @@ -137,17 +143,18 @@ def UserForm(edit=False, available_langu active = v.StringBoolean(if_missing=False) firstname = v.UnicodeString(strip=True, min=1, not_empty=False) lastname = v.UnicodeString(strip=True, min=1, not_empty=False) - email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data)) + email = All(v.Email(not_empty=True), v.UniqSystemEmail(localizer, old_data)) extern_name = v.UnicodeString(strip=True) extern_type = v.UnicodeString(strip=True) language = v.OneOf(available_languages, hideList=False, testValueList=True, if_missing=None) - chained_validators = [v.ValidPasswordsMatch()] + chained_validators = [v.ValidPasswordsMatch(localizer)] return _UserForm -def UserGroupForm(edit=False, old_data=None, allow_disabled=False): +def UserGroupForm(localizer, edit=False, old_data=None, allow_disabled=False): old_data = old_data or {} + _ = localizer class _UserGroupForm(formencode.Schema): allow_extra_fields = True @@ -155,7 +162,7 @@ def UserGroupForm(edit=False, old_data=N users_group_name = All( v.UnicodeString(strip=True, min=1, not_empty=True), - v.ValidUserGroup(edit, old_data) + v.ValidUserGroup(localizer, edit, old_data) ) user_group_description = v.UnicodeString(strip=True, min=1, not_empty=False) @@ -166,12 +173,13 @@ def UserGroupForm(edit=False, old_data=N # this is user group owner user = All( v.UnicodeString(not_empty=True), - v.ValidRepoUser(allow_disabled)) + v.ValidRepoUser(localizer, allow_disabled)) return _UserGroupForm -def RepoGroupForm(edit=False, old_data=None, available_groups=None, - can_create_in_root=False, allow_disabled=False): +def RepoGroupForm(localizer, edit=False, old_data=None, available_groups=None, + can_create_in_root=False, allow_disabled=False): + _ = localizer old_data = old_data or {} available_groups = available_groups or [] @@ -180,7 +188,7 @@ def RepoGroupForm(edit=False, old_data=N filter_extra_fields = False group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), - v.SlugifyName(),) + v.SlugifyName(localizer),) group_description = v.UnicodeString(strip=True, min=1, not_empty=False) group_copy_permissions = v.StringBoolean(if_missing=False) @@ -189,53 +197,57 @@ def RepoGroupForm(edit=False, old_data=N testValueList=True, not_empty=True) enable_locking = v.StringBoolean(if_missing=False) chained_validators = [ - v.ValidRepoGroup(edit, old_data, can_create_in_root)] + v.ValidRepoGroup(localizer, edit, old_data, can_create_in_root)] if edit: # this is repo group owner user = All( v.UnicodeString(not_empty=True), - v.ValidRepoUser(allow_disabled)) - + v.ValidRepoUser(localizer, allow_disabled)) return _RepoGroupForm -def RegisterForm(edit=False, old_data={}): +def RegisterForm(localizer, edit=False, old_data=None): + _ = localizer + old_data = old_data or {} + class _RegisterForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True username = All( - v.ValidUsername(edit, old_data), + v.ValidUsername(localizer, edit, old_data), v.UnicodeString(strip=True, min=1, not_empty=True) ) password = All( - v.ValidPassword(), + v.ValidPassword(localizer), v.UnicodeString(strip=False, min=6, max=72, not_empty=True) ) password_confirmation = All( - v.ValidPassword(), + v.ValidPassword(localizer), v.UnicodeString(strip=False, min=6, max=72, not_empty=True) ) active = v.StringBoolean(if_missing=False) firstname = v.UnicodeString(strip=True, min=1, not_empty=False) lastname = v.UnicodeString(strip=True, min=1, not_empty=False) - email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data)) + email = All(v.Email(not_empty=True), v.UniqSystemEmail(localizer, old_data)) - chained_validators = [v.ValidPasswordsMatch()] - + chained_validators = [v.ValidPasswordsMatch(localizer)] return _RegisterForm -def PasswordResetForm(): +def PasswordResetForm(localizer): + _ = localizer + class _PasswordResetForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True - email = All(v.ValidSystemEmail(), v.Email(not_empty=True)) + email = All(v.ValidSystemEmail(localizer), v.Email(not_empty=True)) return _PasswordResetForm -def RepoForm(edit=False, old_data=None, repo_groups=None, landing_revs=None, - allow_disabled=False): +def RepoForm(localizer, edit=False, old_data=None, repo_groups=None, + landing_revs=None, allow_disabled=False): + _ = localizer old_data = old_data or {} repo_groups = repo_groups or [] landing_revs = landing_revs or [] @@ -245,8 +257,8 @@ def RepoForm(edit=False, old_data=None, allow_extra_fields = True filter_extra_fields = False repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), - v.SlugifyName(), v.CannotHaveGitSuffix()) - repo_group = All(v.CanWriteGroup(old_data), + v.SlugifyName(localizer), v.CannotHaveGitSuffix(localizer)) + repo_group = All(v.CanWriteGroup(localizer, old_data), v.OneOf(repo_groups, hideList=True)) repo_type = v.OneOf(supported_backends, required=False, if_missing=old_data.get('repo_type')) @@ -264,77 +276,91 @@ def RepoForm(edit=False, old_data=None, # this is repo owner user = All( v.UnicodeString(not_empty=True), - v.ValidRepoUser(allow_disabled)) + v.ValidRepoUser(localizer, allow_disabled)) clone_uri_change = v.UnicodeString( not_empty=False, if_missing=v.Missing) - chained_validators = [v.ValidCloneUri(), - v.ValidRepoName(edit, old_data)] + chained_validators = [v.ValidCloneUri(localizer), + v.ValidRepoName(localizer, edit, old_data)] return _RepoForm -def RepoPermsForm(): +def RepoPermsForm(localizer): + _ = localizer + class _RepoPermsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False - chained_validators = [v.ValidPerms(type_='repo')] + chained_validators = [v.ValidPerms(localizer, type_='repo')] return _RepoPermsForm -def RepoGroupPermsForm(valid_recursive_choices): +def RepoGroupPermsForm(localizer, valid_recursive_choices): + _ = localizer + class _RepoGroupPermsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False recursive = v.OneOf(valid_recursive_choices) - chained_validators = [v.ValidPerms(type_='repo_group')] + chained_validators = [v.ValidPerms(localizer, type_='repo_group')] return _RepoGroupPermsForm -def UserGroupPermsForm(): +def UserGroupPermsForm(localizer): + _ = localizer + class _UserPermsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False - chained_validators = [v.ValidPerms(type_='user_group')] + chained_validators = [v.ValidPerms(localizer, type_='user_group')] return _UserPermsForm -def RepoFieldForm(): +def RepoFieldForm(localizer): + _ = localizer + class _RepoFieldForm(formencode.Schema): filter_extra_fields = True allow_extra_fields = True - new_field_key = All(v.FieldKey(), + new_field_key = All(v.FieldKey(localizer), v.UnicodeString(strip=True, min=3, not_empty=True)) new_field_value = v.UnicodeString(not_empty=False, if_missing=u'') new_field_type = v.OneOf(['str', 'unicode', 'list', 'tuple'], if_missing='str') new_field_label = v.UnicodeString(not_empty=False) new_field_desc = v.UnicodeString(not_empty=False) - return _RepoFieldForm -def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(), - repo_groups=[], landing_revs=[]): +def RepoForkForm(localizer, edit=False, old_data=None, + supported_backends=BACKENDS.keys(), repo_groups=None, + landing_revs=None): + _ = localizer + old_data = old_data or {} + repo_groups = repo_groups or [] + landing_revs = landing_revs or [] + class _RepoForkForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), - v.SlugifyName()) - repo_group = All(v.CanWriteGroup(), + v.SlugifyName(localizer)) + repo_group = All(v.CanWriteGroup(localizer, ), v.OneOf(repo_groups, hideList=True)) - repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends)) + repo_type = All(v.ValidForkType(localizer, old_data), v.OneOf(supported_backends)) description = v.UnicodeString(strip=True, min=1, not_empty=True) private = v.StringBoolean(if_missing=False) copy_permissions = v.StringBoolean(if_missing=False) fork_parent_id = v.UnicodeString() - chained_validators = [v.ValidForkName(edit, old_data)] + chained_validators = [v.ValidForkName(localizer, edit, old_data)] landing_rev = v.OneOf(landing_revs, hideList=True) - return _RepoForkForm -def ApplicationSettingsForm(): +def ApplicationSettingsForm(localizer): + _ = localizer + class _ApplicationSettingsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False @@ -346,11 +372,12 @@ def ApplicationSettingsForm(): rhodecode_captcha_private_key = v.UnicodeString(strip=True, min=1, not_empty=False) rhodecode_create_personal_repo_group = v.StringBoolean(if_missing=False) rhodecode_personal_repo_group_pattern = v.UnicodeString(strip=True, min=1, not_empty=False) - return _ApplicationSettingsForm -def ApplicationVisualisationForm(): +def ApplicationVisualisationForm(localizer): + _ = localizer + class _ApplicationVisualisationForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False @@ -370,11 +397,11 @@ def ApplicationVisualisationForm(): rhodecode_support_url = v.UnicodeString() rhodecode_show_revision_number = v.StringBoolean(if_missing=False) rhodecode_show_sha_length = v.Int(min=4, not_empty=True) - return _ApplicationVisualisationForm class _BaseVcsSettingsForm(formencode.Schema): + allow_extra_fields = True filter_extra_fields = False hooks_changegroup_repo_size = v.StringBoolean(if_missing=False) @@ -403,48 +430,54 @@ class _BaseVcsSettingsForm(formencode.Sc vcs_svn_proxy_http_server_url = v.UnicodeString(strip=True, if_missing=None) -def ApplicationUiSettingsForm(): +def ApplicationUiSettingsForm(localizer): + _ = localizer + class _ApplicationUiSettingsForm(_BaseVcsSettingsForm): web_push_ssl = v.StringBoolean(if_missing=False) paths_root_path = All( - v.ValidPath(), + v.ValidPath(localizer), v.UnicodeString(strip=True, min=1, not_empty=True) ) largefiles_usercache = All( - v.ValidPath(), + v.ValidPath(localizer), v.UnicodeString(strip=True, min=2, not_empty=True)) vcs_git_lfs_store_location = All( - v.ValidPath(), + v.ValidPath(localizer), v.UnicodeString(strip=True, min=2, not_empty=True)) extensions_hgsubversion = v.StringBoolean(if_missing=False) extensions_hggit = v.StringBoolean(if_missing=False) - new_svn_branch = v.ValidSvnPattern(section='vcs_svn_branch') - new_svn_tag = v.ValidSvnPattern(section='vcs_svn_tag') - + new_svn_branch = v.ValidSvnPattern(localizer, section='vcs_svn_branch') + new_svn_tag = v.ValidSvnPattern(localizer, section='vcs_svn_tag') return _ApplicationUiSettingsForm -def RepoVcsSettingsForm(repo_name): +def RepoVcsSettingsForm(localizer, repo_name): + _ = localizer + class _RepoVcsSettingsForm(_BaseVcsSettingsForm): inherit_global_settings = v.StringBoolean(if_missing=False) - new_svn_branch = v.ValidSvnPattern( + new_svn_branch = v.ValidSvnPattern(localizer, section='vcs_svn_branch', repo_name=repo_name) - new_svn_tag = v.ValidSvnPattern( + new_svn_tag = v.ValidSvnPattern(localizer, section='vcs_svn_tag', repo_name=repo_name) - return _RepoVcsSettingsForm -def LabsSettingsForm(): +def LabsSettingsForm(localizer): + _ = localizer + class _LabSettingsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False - return _LabSettingsForm def ApplicationPermissionsForm( - register_choices, password_reset_choices, extern_activate_choices): + localizer, register_choices, password_reset_choices, + extern_activate_choices): + _ = localizer + class _DefaultPermissionsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -454,12 +487,13 @@ def ApplicationPermissionsForm( default_register_message = v.UnicodeString() default_password_reset = v.OneOf(password_reset_choices) default_extern_activate = v.OneOf(extern_activate_choices) - return _DefaultPermissionsForm -def ObjectPermissionsForm(repo_perms_choices, group_perms_choices, +def ObjectPermissionsForm(localizer, repo_perms_choices, group_perms_choices, user_group_perms_choices): + _ = localizer + class _ObjectPermissionsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -469,13 +503,14 @@ def ObjectPermissionsForm(repo_perms_cho default_repo_perm = v.OneOf(repo_perms_choices) default_group_perm = v.OneOf(group_perms_choices) default_user_group_perm = v.OneOf(user_group_perms_choices) - return _ObjectPermissionsForm -def UserPermissionsForm(create_choices, create_on_write_choices, +def UserPermissionsForm(localizer, create_choices, create_on_write_choices, repo_group_create_choices, user_group_create_choices, fork_choices, inherit_default_permissions_choices): + _ = localizer + class _DefaultPermissionsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -488,21 +523,24 @@ def UserPermissionsForm(create_choices, default_repo_group_create = v.OneOf(repo_group_create_choices) default_fork_create = v.OneOf(fork_choices) default_inherit_default_permissions = v.OneOf(inherit_default_permissions_choices) - return _DefaultPermissionsForm -def UserIndividualPermissionsForm(): +def UserIndividualPermissionsForm(localizer): + _ = localizer + class _DefaultPermissionsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True inherit_default_permissions = v.StringBoolean(if_missing=False) - return _DefaultPermissionsForm -def DefaultsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()): +def DefaultsForm(localizer, edit=False, old_data=None, supported_backends=BACKENDS.keys()): + _ = localizer + old_data = old_data or {} + class _DefaultsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -511,34 +549,39 @@ def DefaultsForm(edit=False, old_data={} default_repo_enable_statistics = v.StringBoolean(if_missing=False) default_repo_enable_downloads = v.StringBoolean(if_missing=False) default_repo_enable_locking = v.StringBoolean(if_missing=False) - return _DefaultsForm -def AuthSettingsForm(): +def AuthSettingsForm(localizer): + _ = localizer + class _AuthSettingsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True - auth_plugins = All(v.ValidAuthPlugins(), - v.UniqueListFromString()(not_empty=True)) - + auth_plugins = All(v.ValidAuthPlugins(localizer), + v.UniqueListFromString(localizer)(not_empty=True)) return _AuthSettingsForm -def UserExtraEmailForm(): +def UserExtraEmailForm(localizer): + _ = localizer + class _UserExtraEmailForm(formencode.Schema): - email = All(v.UniqSystemEmail(), v.Email(not_empty=True)) + email = All(v.UniqSystemEmail(localizer), v.Email(not_empty=True)) return _UserExtraEmailForm -def UserExtraIpForm(): +def UserExtraIpForm(localizer): + _ = localizer + class _UserExtraIpForm(formencode.Schema): - ip = v.ValidIp()(not_empty=True) + ip = v.ValidIp(localizer)(not_empty=True) return _UserExtraIpForm +def PullRequestForm(localizer, repo_id): + _ = localizer -def PullRequestForm(repo_id): class ReviewerForm(formencode.Schema): user_id = v.Int(not_empty=True) reasons = All() @@ -553,8 +596,8 @@ def PullRequestForm(repo_id): source_ref = v.UnicodeString(strip=True, required=True) target_repo = v.UnicodeString(strip=True, required=True) target_ref = v.UnicodeString(strip=True, required=True) - revisions = All(#v.NotReviewedRevisions(repo_id)(), - v.UniqueList()(not_empty=True)) + revisions = All(#v.NotReviewedRevisions(localizer, repo_id)(), + v.UniqueList(localizer)(not_empty=True)) review_members = formencode.ForEach(ReviewerForm()) pullrequest_title = v.UnicodeString(strip=True, required=True) pullrequest_desc = v.UnicodeString(strip=True, required=False) @@ -562,9 +605,11 @@ def PullRequestForm(repo_id): return _PullRequestForm -def IssueTrackerPatternsForm(): +def IssueTrackerPatternsForm(localizer): + _ = localizer + class _IssueTrackerPatternsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = False - chained_validators = [v.ValidPattern()] + chained_validators = [v.ValidPattern(localizer)] return _IssueTrackerPatternsForm diff --git a/rhodecode/model/scm.py b/rhodecode/model/scm.py --- a/rhodecode/model/scm.py +++ b/rhodecode/model/scm.py @@ -30,7 +30,7 @@ import logging import cStringIO import pkg_resources -from pylons.i18n.translation import _ +from rhodecode.translation import temp_translation_factory as _ from sqlalchemy import func from zope.cachedescriptors.property import Lazy as LazyProperty diff --git a/rhodecode/model/user.py b/rhodecode/model/user.py --- a/rhodecode/model/user.py +++ b/rhodecode/model/user.py @@ -26,7 +26,7 @@ import logging import traceback import datetime -from pylons.i18n.translation import _ +from rhodecode.translation import temp_translation_factory as _ import ipaddress from sqlalchemy.exc import DatabaseError @@ -754,14 +754,12 @@ class UserModel(BaseModel): :param user: :param email: """ - from rhodecode.model import forms - form = forms.UserExtraEmailForm()() - data = form.to_python({'email': email}) + user = self._get_user(user) obj = UserEmailMap() obj.user = user - obj.email = data['email'] + obj.email = email self.sa.add(obj) return obj @@ -811,14 +809,11 @@ class UserModel(BaseModel): :param user: :param ip: """ - from rhodecode.model import forms - form = forms.UserExtraIpForm()() - data = form.to_python({'ip': ip}) + user = self._get_user(user) - obj = UserIpMap() obj.user = user - obj.ip_addr = data['ip'] + obj.ip_addr = ip obj.description = description self.sa.add(obj) return obj diff --git a/rhodecode/model/validators.py b/rhodecode/model/validators.py --- a/rhodecode/model/validators.py +++ b/rhodecode/model/validators.py @@ -22,10 +22,11 @@ Set of generic validators """ -import logging + import os import re -from collections import defaultdict +import logging +import collections import formencode import ipaddress @@ -33,7 +34,7 @@ from formencode.validators import ( UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, NotEmpty, IPAddress, CIDR, String, FancyValidator ) -from pylons.i18n.translation import _ + from sqlalchemy.sql.expression import true from sqlalchemy.util import OrderedSet from webhelpers.pylonslib.secure_form import authentication_token @@ -62,17 +63,11 @@ log = logging.getLogger(__name__) class _Missing(object): pass + Missing = _Missing() -class StateObj(object): - """ - this is needed to translate the messages using _() in validators - """ - _ = staticmethod(_) - - -def M(self, key, state=None, **kwargs): +def M(self, key, state, **kwargs): """ returns string from self.message based on given key, passed kw params are used to substitute %(named)s params inside @@ -81,16 +76,16 @@ def M(self, key, state=None, **kwargs): :param msg: :param state: """ - if state is None: - state = StateObj() - else: - state._ = staticmethod(_) + + #state._ = staticmethod(_) # inject validator into state object return self.message(key, state, **kwargs) -def UniqueList(convert=None): - class _UniqueList(formencode.FancyValidator): +def UniqueList(localizer, convert=None): + _ = localizer + + class _validator(formencode.FancyValidator): """ Unique List ! """ @@ -123,20 +118,23 @@ def UniqueList(convert=None): def empty_value(self, value): return [] - - return _UniqueList + return _validator -def UniqueListFromString(): - class _UniqueListFromString(UniqueList()): +def UniqueListFromString(localizer): + _ = localizer + + class _validator(UniqueList(localizer)): def _to_python(self, value, state): if isinstance(value, basestring): value = aslist(value, ',') - return super(_UniqueListFromString, self)._to_python(value, state) - return _UniqueListFromString + return super(_validator, self)._to_python(value, state) + return _validator -def ValidSvnPattern(section, repo_name=None): +def ValidSvnPattern(localizer, section, repo_name=None): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'pattern_exists': _(u'Pattern already exists'), @@ -154,7 +152,10 @@ def ValidSvnPattern(section, repo_name=N return _validator -def ValidUsername(edit=False, old_data={}): +def ValidUsername(localizer, edit=False, old_data=None): + _ = localizer + old_data = old_data or {} + class _validator(formencode.validators.FancyValidator): messages = { 'username_exists': _(u'Username "%(username)s" already exists'), @@ -187,13 +188,9 @@ def ValidUsername(edit=False, old_data={ return _validator -def ValidRegex(msg=None): - class _validator(formencode.validators.Regex): - messages = {'invalid': msg or _(u'The input is not valid')} - return _validator +def ValidRepoUser(localizer, allow_disabled=False): + _ = localizer - -def ValidRepoUser(allow_disabled=False): class _validator(formencode.validators.FancyValidator): messages = { 'invalid_username': _(u'Username %(username)s is not valid'), @@ -213,11 +210,13 @@ def ValidRepoUser(allow_disabled=False): raise formencode.Invalid( msg, value, state, error_dict={'username': msg} ) - return _validator -def ValidUserGroup(edit=False, old_data={}): +def ValidUserGroup(localizer, edit=False, old_data=None): + _ = localizer + old_data = old_data or {} + class _validator(formencode.validators.FancyValidator): messages = { 'invalid_group': _(u'Invalid user group name'), @@ -254,11 +253,13 @@ def ValidUserGroup(edit=False, old_data= raise formencode.Invalid( msg, value, state, error_dict={'users_group_name': msg} ) - return _validator -def ValidRepoGroup(edit=False, old_data={}, can_create_in_root=False): +def ValidRepoGroup(localizer, edit=False, old_data=None, can_create_in_root=False): + _ = localizer + old_data = old_data or {} + class _validator(formencode.validators.FancyValidator): messages = { 'group_parent_id': _(u'Cannot assign this group as parent'), @@ -375,11 +376,12 @@ def ValidRepoGroup(edit=False, old_data= msg = M(self, 'repo_exists', state, group_name=group_name) raise formencode.Invalid( msg, value, state, error_dict={'group_name': msg}) - return _validator -def ValidPassword(): +def ValidPassword(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'invalid_password': @@ -395,24 +397,11 @@ def ValidPassword(): return _validator -def ValidOldPassword(username): - class _validator(formencode.validators.FancyValidator): - messages = { - 'invalid_password': _(u'Invalid old password') - } +def ValidPasswordsMatch( + localizer, passwd='new_password', + passwd_confirmation='password_confirmation'): + _ = localizer - def validate_python(self, value, state): - from rhodecode.authentication.base import authenticate, HTTP_TYPE - if not authenticate(username, value, '', HTTP_TYPE): - msg = M(self, 'invalid_password', state) - raise formencode.Invalid( - msg, value, state, error_dict={'current_password': msg} - ) - return _validator - - -def ValidPasswordsMatch( - passwd='new_password', passwd_confirmation='password_confirmation'): class _validator(formencode.validators.FancyValidator): messages = { 'password_mismatch': _(u'Passwords do not match'), @@ -430,7 +419,9 @@ def ValidPasswordsMatch( return _validator -def ValidAuth(): +def ValidAuth(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'invalid_password': _(u'invalid password'), @@ -464,7 +455,9 @@ def ValidAuth(): return _validator -def ValidAuthToken(): +def ValidAuthToken(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'invalid_token': _(u'Token mismatch') @@ -477,7 +470,10 @@ def ValidAuthToken(): return _validator -def ValidRepoName(edit=False, old_data={}): +def ValidRepoName(localizer, edit=False, old_data=None): + old_data = old_data or {} + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'invalid_repo_name': @@ -558,11 +554,15 @@ def ValidRepoName(edit=False, old_data={ return _validator -def ValidForkName(*args, **kwargs): - return ValidRepoName(*args, **kwargs) +def ValidForkName(localizer, *args, **kwargs): + _ = localizer + + return ValidRepoName(localizer, *args, **kwargs) -def SlugifyName(): +def SlugifyName(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): def _to_python(self, value, state): @@ -570,11 +570,12 @@ def SlugifyName(): def validate_python(self, value, state): pass - return _validator -def CannotHaveGitSuffix(): +def CannotHaveGitSuffix(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'has_git_suffix': @@ -590,11 +591,12 @@ def CannotHaveGitSuffix(): self, 'has_git_suffix', state) raise formencode.Invalid( msg, value, state, error_dict={'repo_name': msg}) - return _validator -def ValidCloneUri(): +def ValidCloneUri(localizer): + _ = localizer + class InvalidCloneUrl(Exception): allowed_prefixes = () @@ -652,19 +654,22 @@ def ValidCloneUri(): url_handler(repo_type, url) except InvalidCloneUrl as e: log.warning(e) - msg = M(self, 'invalid_clone_uri', rtype=repo_type, + msg = M(self, 'invalid_clone_uri', state, rtype=repo_type, allowed_prefixes=','.join(e.allowed_prefixes)) raise formencode.Invalid(msg, value, state, error_dict={'clone_uri': msg}) except Exception: log.exception('Url validation failed') - msg = M(self, 'clone_uri', rtype=repo_type) + msg = M(self, 'clone_uri', state, rtype=repo_type) raise formencode.Invalid(msg, value, state, error_dict={'clone_uri': msg}) return _validator -def ValidForkType(old_data={}): +def ValidForkType(localizer, old_data=None): + _ = localizer + old_data = old_data or {} + class _validator(formencode.validators.FancyValidator): messages = { 'invalid_fork_type': _(u'Fork have to be the same type as parent') @@ -679,7 +684,9 @@ def ValidForkType(old_data={}): return _validator -def CanWriteGroup(old_data=None): +def CanWriteGroup(localizer, old_data=None): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'permission_denied': _( @@ -730,11 +737,11 @@ def CanWriteGroup(old_data=None): raise formencode.Invalid( msg, value, state, error_dict={'repo_type': msg} ) - return _validator -def ValidPerms(type_='repo'): +def ValidPerms(localizer, type_='repo'): + _ = localizer if type_ == 'repo_group': EMPTY_PERM = 'group.none' elif type_ == 'repo': @@ -756,8 +763,8 @@ def ValidPerms(type_='repo'): # Read the perm_new_member/perm_del_member attributes and group # them by they IDs - new_perms_group = defaultdict(dict) - del_perms_group = defaultdict(dict) + new_perms_group = collections.defaultdict(dict) + del_perms_group = collections.defaultdict(dict) for k, v in value.copy().iteritems(): if k.startswith('perm_del_member'): # delete from org storage so we don't process that later @@ -851,29 +858,9 @@ def ValidPerms(type_='repo'): return _validator -def ValidSettings(): - class _validator(formencode.validators.FancyValidator): - def _to_python(self, value, state): - # settings form for users that are not admin - # can't edit certain parameters, it's extra backup if they mangle - # with forms - - forbidden_params = [ - 'user', 'repo_type', 'repo_enable_locking', - 'repo_enable_downloads', 'repo_enable_statistics' - ] +def ValidPath(localizer): + _ = localizer - for param in forbidden_params: - if param in value: - del value[param] - return value - - def validate_python(self, value, state): - pass - return _validator - - -def ValidPath(): class _validator(formencode.validators.FancyValidator): messages = { 'invalid_path': _(u'This is not a valid path') @@ -888,7 +875,10 @@ def ValidPath(): return _validator -def UniqSystemEmail(old_data={}): +def UniqSystemEmail(localizer, old_data=None): + _ = localizer + old_data = old_data or {} + class _validator(formencode.validators.FancyValidator): messages = { 'email_taken': _(u'This e-mail address is already taken') @@ -908,7 +898,9 @@ def UniqSystemEmail(old_data={}): return _validator -def ValidSystemEmail(): +def ValidSystemEmail(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'non_existing_email': _(u'e-mail "%(email)s" does not exist.') @@ -924,11 +916,11 @@ def ValidSystemEmail(): raise formencode.Invalid( msg, value, state, error_dict={'email': msg} ) - return _validator -def NotReviewedRevisions(repo_id): +def NotReviewedRevisions(localizer, repo_id): + _ = localizer class _validator(formencode.validators.FancyValidator): messages = { 'rev_already_reviewed': @@ -960,7 +952,9 @@ def NotReviewedRevisions(repo_id): return _validator -def ValidIp(): +def ValidIp(localizer): + _ = localizer + class _validator(CIDR): messages = { 'badFormat': _(u'Please enter a valid IPv4 or IpV6 address'), @@ -984,11 +978,12 @@ def ValidIp(): except ValueError: raise formencode.Invalid(self.message('badFormat', state), value, state) - return _validator -def FieldKey(): +def FieldKey(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'badFormat': _( @@ -1003,7 +998,9 @@ def FieldKey(): return _validator -def ValidAuthPlugins(): +def ValidAuthPlugins(localizer): + _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { 'import_duplicate': _( @@ -1033,11 +1030,11 @@ def ValidAuthPlugins(): log.exception( 'Exception during import of auth legacy plugin "{}"' .format(plugin_id)) - msg = M(self, 'import_error', plugin_id=plugin_id) + msg = M(self, 'import_error', state, plugin_id=plugin_id) raise formencode.Invalid(msg, value, state) if not hasattr(plugin, 'includeme'): - msg = M(self, 'missing_includeme', plugin_id=plugin_id) + msg = M(self, 'missing_includeme', state, plugin_id=plugin_id) raise formencode.Invalid(msg, value, state) return plugin @@ -1051,7 +1048,7 @@ def ValidAuthPlugins(): plugin = loadplugin(plugin_id) if plugin is None: - msg = M(self, 'no_plugin', plugin_id=plugin_id) + msg = M(self, 'no_plugin', state, plugin_id=plugin_id) raise formencode.Invalid(msg, value, state) return plugin @@ -1074,13 +1071,13 @@ def ValidAuthPlugins(): next_to_load=plugin) raise formencode.Invalid(msg, value, state) unique_names[plugin.name] = plugin - return _validator -def ValidPattern(): +def ValidPattern(localizer): + _ = localizer - class _Validator(formencode.validators.FancyValidator): + class _validator(formencode.validators.FancyValidator): messages = { 'bad_format': _(u'Url must start with http or /'), } @@ -1129,4 +1126,4 @@ def ValidPattern(): delete_patterns = [delete_patterns] value['delete_patterns'] = delete_patterns return value - return _Validator + return _validator diff --git a/rhodecode/subscribers.py b/rhodecode/subscribers.py --- a/rhodecode/subscribers.py +++ b/rhodecode/subscribers.py @@ -21,7 +21,6 @@ import io import re import datetime import logging -import pylons import Queue import subprocess32 import os @@ -36,14 +35,11 @@ from threading import Thread from rhodecode.translation import _ as tsf from rhodecode.config.jsroutes import generate_jsroutes_content from rhodecode.lib import auth +from rhodecode.lib.base import get_auth_user + import rhodecode -from pylons.i18n.translation import _get_translator -from pylons.util import ContextObj -from routes.util import URLGenerator - -from rhodecode.lib.base import attach_context_attributes, get_auth_user log = logging.getLogger(__name__) @@ -51,11 +47,6 @@ log = logging.getLogger(__name__) def add_renderer_globals(event): from rhodecode.lib import helpers - # NOTE(marcink): - # Put pylons stuff into the context. This will be removed as soon as - # migration to pyramid is finished. - event['c'] = pylons.tmpl_context - # TODO: When executed in pyramid view context the request is not available # in the event. Find a better solution to get the request. request = event['request'] or get_current_request() @@ -68,12 +59,11 @@ def add_renderer_globals(event): def add_localizer(event): request = event.request - localizer = get_localizer(request) + localizer = request.localizer def auto_translate(*args, **kwargs): return localizer.translate(tsf(*args, **kwargs)) - request.localizer = localizer request.translate = auto_translate request.plularize = localizer.pluralize @@ -108,39 +98,6 @@ def add_request_user_context(event): request.environ['rc_auth_user'] = auth_user -def add_pylons_context(event): - request = event.request - - config = rhodecode.CONFIG - environ = request.environ - session = request.session - - if hasattr(request, 'vcs_call'): - # skip vcs calls - return - - # Setup pylons globals. - pylons.config._push_object(config) - pylons.request._push_object(request) - pylons.session._push_object(session) - pylons.translator._push_object(_get_translator(config.get('lang'))) - - pylons.url._push_object(URLGenerator(config['routes.map'], environ)) - session_key = ( - config['pylons.environ_config'].get('session', 'beaker.session')) - environ[session_key] = session - - if hasattr(request, 'rpc_method'): - # skip api calls - return - - # Setup the pylons context object ('c') - context = ContextObj() - context.rhodecode_user = request.user - attach_context_attributes(context, request, request.user.user_id) - pylons.tmpl_context._push_object(context) - - def inject_app_settings(event): settings = event.app.registry.settings # inject info about available permissions diff --git a/rhodecode/templates/admin/admin_audit_log_entry.mako b/rhodecode/templates/admin/admin_audit_log_entry.mako --- a/rhodecode/templates/admin/admin_audit_log_entry.mako +++ b/rhodecode/templates/admin/admin_audit_log_entry.mako @@ -61,14 +61,14 @@ % if c.audit_log_entry.version == c.audit_log_entry.VERSION_1: - ${h.action_parser(l)[0]()} + ${h.action_parser(request, l)[0]()} % else: ${h.literal(c.audit_log_entry.action)} % endif
% if c.audit_log_entry.version == c.audit_log_entry.VERSION_1: - ${h.literal(h.action_parser(l)[1]())} + ${h.literal(h.action_parser(request, l)[1]())} % endif
diff --git a/rhodecode/templates/admin/admin_audit_logs.mako b/rhodecode/templates/admin/admin_audit_logs.mako --- a/rhodecode/templates/admin/admin_audit_logs.mako +++ b/rhodecode/templates/admin/admin_audit_logs.mako @@ -14,7 +14,7 @@ ${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)} ${h.end_form()} -

${_('Example Queries')}

+

${_('Example Queries')}

<%def name="menu_bar_nav()"> diff --git a/rhodecode/templates/admin/admin_log_base.mako b/rhodecode/templates/admin/admin_log_base.mako --- a/rhodecode/templates/admin/admin_log_base.mako +++ b/rhodecode/templates/admin/admin_log_base.mako @@ -26,14 +26,14 @@ % if l.version == l.VERSION_1: - ${h.action_parser(l)[0]()} + ${h.action_parser(request, l)[0]()} % else: ${h.literal(l.action)} % endif
% if l.version == l.VERSION_1: - ${h.literal(h.action_parser(l)[1]())} + ${h.literal(h.action_parser(request, l)[1]())} % endif
diff --git a/rhodecode/templates/admin/repos/repo_edit_audit.mako b/rhodecode/templates/admin/repos/repo_edit_audit.mako --- a/rhodecode/templates/admin/repos/repo_edit_audit.mako +++ b/rhodecode/templates/admin/repos/repo_edit_audit.mako @@ -14,7 +14,7 @@ ${h.end_form()} -

${_('Example Queries')}

+

${_('Example Queries')}

<%include file="/admin/admin_log_base.mako" /> diff --git a/rhodecode/templates/admin/users/user_edit_audit.mako b/rhodecode/templates/admin/users/user_edit_audit.mako --- a/rhodecode/templates/admin/users/user_edit_audit.mako +++ b/rhodecode/templates/admin/users/user_edit_audit.mako @@ -14,7 +14,7 @@ ${h.end_form()} -

${_('Example Queries')}

+

${_('Example Queries')}

<%include file="/admin/admin_log_base.mako" /> diff --git a/rhodecode/templates/base/plugins_base.mako b/rhodecode/templates/base/plugins_base.mako --- a/rhodecode/templates/base/plugins_base.mako +++ b/rhodecode/templates/base/plugins_base.mako @@ -1,11 +1,8 @@ -<% -from pyramid.renderers import render as pyramid_render -from pyramid.threadlocal import get_current_registry, get_current_request -pyramid_registry = get_current_registry() -%> -% for plugin, config in getattr(pyramid_registry, 'rhodecode_plugins', {}).items(): -% if config['template_hooks'].get('plugin_init_template'): -${pyramid_render(config['template_hooks'].get('plugin_init_template'), -{'config':config}, request=get_current_request(), package='rc_ae')|n} -% endif + +% for plugin, config in getattr(request.registry, 'rhodecode_plugins', {}).items(): + <% tmpl = config['template_hooks'].get('plugin_init_template') %> + + % if tmpl: + <%include file="${tmpl}" args="config=config"/> + % endif % endfor diff --git a/rhodecode/templates/channelstream/plugin_init.mako b/rhodecode/templates/channelstream/plugin_init.mako --- a/rhodecode/templates/channelstream/plugin_init.mako +++ b/rhodecode/templates/channelstream/plugin_init.mako @@ -1,3 +1,5 @@ +<%page args="config"/> +