diff --git a/pkgs/patch-celery-dateutil.diff b/pkgs/patch-celery-dateutil.diff deleted file mode 100644 index 6058872b..00000000 --- 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 index 99d04f55..00000000 --- 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 index ec65047e..cbb5bf02 100644 --- 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 index 30e9a6e7..edf820b9 100644 --- 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"; - buildInputs = with self; []; - doCheck = false; - propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; - src = fetchurl { - url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f"; - md5 = "f26633726fa2cd3a340316ee6a5d218f"; - }; - meta = { - license = [ pkgs.lib.licenses.bsdOriginal ]; - }; - }; Routes = super.buildPythonPackage { - name = "Routes-1.13"; + name = "Routes-2.4.1"; buildInputs = with self; []; doCheck = false; - propagatedBuildInputs = with self; [repoze.lru]; + propagatedBuildInputs = with self; [six repoze.lru]; src = fetchurl { - url = "https://pypi.python.org/packages/88/d3/259c3b3cde8837eb9441ab5f574a660e8a4acea8f54a078441d4d2acac1c/Routes-1.13.tar.gz"; - md5 = "d527b0ab7dd9172b1275a41f97448783"; + url = "https://pypi.python.org/packages/33/38/ea827837e68d9c7dde4cff7ec122a93c319f0effc08ce92a17095576603f/Routes-2.4.1.tar.gz"; + md5 = "c058dff6832941dec47e0d0052548ad8"; }; 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 index 292eaa4c..b25ed572 100644 --- 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 index ba44e97b..ae648be1 100644 --- a/rhodecode/api/tests/conftest.py +++ b/rhodecode/api/tests/conftest.py @@ -27,7 +27,7 @@ from rhodecode.tests import TEST_USER_ADMIN_LOGIN @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 index e9d42f56..72f163e1 100644 --- 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 index 77022907..d386620f 100644 --- 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, registry=None): """ 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 index 6f14b285..43051168 100644 --- 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, **kwargs): 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 index 9ea09597..ea29da38 100644 --- 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 index f1e7d341..ab4a1b11 100644 --- 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 NoResultFound 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 index a7e0868d..22c02541 100644 --- 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 index 419c6928..03a3d1b9 100644 --- a/rhodecode/apps/admin/views/defaults.py +++ b/rhodecode/apps/admin/views/defaults.py @@ -44,7 +44,7 @@ class AdminDefaultSettingsView(BaseAppView): 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(BaseAppView): _ = 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 index ca1229a7..ac10f505 100644 --- a/rhodecode/apps/admin/views/open_source_licenses.py +++ b/rhodecode/apps/admin/views/open_source_licenses.py @@ -35,7 +35,7 @@ class OpenSourceLicensesAdminSettingsView(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/permissions.py b/rhodecode/apps/admin/views/permissions.py index c78a523c..506e2e62 100644 --- a/rhodecode/apps/admin/views/permissions.py +++ b/rhodecode/apps/admin/views/permissions.py @@ -54,7 +54,7 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): 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, DataGridAppView): 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, DataGridAppView): 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, DataGridAppView): 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, DataGridAppView): 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 index 7f835138..a0116122 100644 --- 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 index 367b9add..e0b912d5 100644 --- a/rhodecode/apps/admin/views/repo_groups.py +++ b/rhodecode/apps/admin/views/repo_groups.py @@ -47,7 +47,7 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): 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, DataGridAppView): # 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 index e4d33ba7..df6718f2 100644 --- a/rhodecode/apps/admin/views/repositories.py +++ b/rhodecode/apps/admin/views/repositories.py @@ -49,7 +49,7 @@ class AdminReposView(BaseAppView, DataGridAppView): 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, DataGridAppView): 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 index 3ce78c44..62bfd364 100644 --- a/rhodecode/apps/admin/views/sessions.py +++ b/rhodecode/apps/admin/views/sessions.py @@ -39,7 +39,7 @@ class AdminSessionSettingsView(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/settings.py b/rhodecode/apps/admin/views/settings.py index c30c5d19..82255f01 100644 --- 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 index 8c0d33bc..dd26b1ec 100644 --- 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 index f1a66687..1503d234 100644 --- a/rhodecode/apps/admin/views/user_groups.py +++ b/rhodecode/apps/admin/views/user_groups.py @@ -53,7 +53,7 @@ class AdminUserGroupsView(BaseAppView, DataGridAppView): 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, DataGridAppView): 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 index 5bd874ae..a5c89a0b 100644 --- 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, DataGridAppView): 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, DataGridAppView): 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 index 114eaaae..86b9aa44 100644 --- 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 index 3fc9737a..96ee21f2 100644 --- 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 index 957beecd..4d95d13a 100644 --- 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 index bca1c1a1..1c755d83 100644 --- 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(TestController): ] @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 index d052e12f..355bcf18 100644 --- 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 index d6d0939d..4cfcb2eb 100644 --- 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 index 6ddc5f1d..d695170b 100644 --- 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 Fixture 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 index e0f123e2..93c7930f 100644 --- 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 index d2b6363e..e79185b1 100644 --- 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 index 05114bb7..829c7350 100644 --- 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 CommentsModel 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, DataGridAppView): 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, DataGridAppView): 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, DataGridAppView): 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 index 6f7ec66b..f6c2b708 100644 --- 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(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 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 index bd7d8046..0e30a35a 100644 --- 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, DataGridAppView): 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 index 37b3b1ae..640889f3 100644 --- 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 index 18c056ce..ab32aaca 100644 --- 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 index 62ef8dae..e6b2797d 100644 --- 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 index 4abf82ac..3f424af0 100644 --- 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(RepoGroupAppView): 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 index 5c869fad..a28dd5f8 100644 --- 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(RepoGroupAppView): 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 index 3deb4688..db88db22 100644 --- 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, **kwargs): 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 index 7f6d6027..92538a92 100644 --- 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 index 4c801fc1..5f496ad3 100644 --- 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 index 2f16ff8a..4edd5866 100644 --- 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 index 1c2ce014..8476aeca 100644 --- 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 index 374d2c89..4ff8a017 100644 --- 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 index b312cac7..ea03ac74 100644 --- 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 index 2e83f5e3..f3d69576 100644 --- 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 index 0882bf12..d4f0f934 100644 --- 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 index c87d5617..47f80eb5 100644 --- a/rhodecode/apps/repository/views/repo_forks.py +++ b/rhodecode/apps/repository/views/repo_forks.py @@ -57,7 +57,7 @@ class RepoForksView(RepoAppView, DataGridAppView): 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, DataGridAppView): _ = 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 index ea27703a..ba940b50 100644 --- 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 index 87db1e1e..2a78b63b 100644 --- a/rhodecode/apps/repository/views/repo_permissions.py +++ b/rhodecode/apps/repository/views/repo_permissions.py @@ -40,7 +40,7 @@ class RepoSettingsPermissionsView(RepoAppView): 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(RepoAppView): # 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 index 3a85d091..bfd08d44 100644 --- 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, DataGridAppView): 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, DataGridAppView): 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 index e7730952..0466f284 100644 --- 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 index 671c4d6f..274e12d8 100644 --- 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 index 94b2347a..02278d59 100644 --- 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 index 5c811898..636bc31c 100644 --- 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 index c8b7c0b7..50642aaa 100644 --- 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(RepoAppView): 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(RepoAppView): 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 index c0121be4..ce0158ce 100644 --- 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 index 3e30196f..188a6cf8 100644 --- 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 index a0242736..54fe2fb0 100644 --- 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 index 93985959..62917a00 100644 --- 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 index aa0b3355..1d8cbc72 100644 --- a/rhodecode/apps/search/views.py +++ b/rhodecode/apps/search/views.py @@ -103,7 +103,7 @@ def search(request, tmpl_context, repo_name): 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 index f28f6ef0..119f2dfe 100644 --- 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 index 04e8940b..d4a3e06f 100644 --- 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 index 3177a302..50ac56cb 100644 --- a/rhodecode/authentication/views.py +++ b/rhodecode/authentication/views.py @@ -26,25 +26,24 @@ from pyramid.httpexceptions import HTTPFound 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 index 60516d69..f47023f0 100644 --- 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_config, settings): # 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_config, settings): 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 index 3bc7cfc6..6b74d365 100644 --- 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 index 2306153e..59156333 100644 --- 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, **settings): 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, **settings): 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 + if not getattr(request, 'vcs_call', None): + # handle like regular case with our error_handler + return error_handler(HTTPNotFound(), request) - # Appenlight monitoring. - pylons_app, appenlight_client = wrap_in_appenlight_if_enabled( - pylons_app, settings) + # 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 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) - - # 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 index 9d4cb7c1..2d72f4c3 100644 --- a/rhodecode/config/patches.py +++ b/rhodecode/config/patches.py @@ -32,26 +32,10 @@ Please keep the following principles in mind: """ -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 index 0e61f22d..00000000 --- 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 index 0c928113..30c44076 100644 --- a/rhodecode/integrations/views.py +++ b/rhodecode/integrations/views.py @@ -110,7 +110,7 @@ class IntegrationSettingsViewBase(BaseAppView): 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(IntegrationSettingsViewBase): 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(IntegrationSettingsViewBase): 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(IntegrationSettingsViewBase): 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 index 3147b04e..86471e5c 100644 --- 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 CommitDoesNotExistError 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, parse_cs=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 index a79aa357..00000000 --- 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 index 2b0e69df..80e610ed 100644 --- 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 index 94663038..03f7c121 100644 --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -52,42 +52,9 @@ from rhodecode.model.notification import NotificationModel 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, request, user_id): } # 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, request, user_id): 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 index 34e96a2f..dc2ccbbe 100644 --- 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_int, str2bool 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 index 1fde399b..f7fc2916 100644 --- 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 index 5432453a..16d9bd2c 100644 --- 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 index 835edcb7..5f78f0b2 100644 --- 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 index 49f9b321..e5c91454 100644 --- 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, first_name, last_name, size=30): 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, repository=None): :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 index a7d91bba..d317da2b 100644 --- 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_name, repo_alias, action): 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 index 25f7397f..76fba676 100644 --- 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 index d508f558..00000000 --- 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 index 9ec11919..27c5a289 100644 --- 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 index 847d8de5..47f731f6 100644 --- 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 index 669f925b..67c494c5 100644 --- 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 index 39220997..f1e6f503 100644 --- 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 index 4891ca17..a0c25627 100644 --- 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 index 9874da50..ddff0fa7 100644 --- 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 index a9f3ea30..ef676174 100644 --- 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 index 44c5d00f..4a656d6d 100644 --- 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 index 7cc0a593..95b7ebc4 100644 --- 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 = RhodecodeFormZPTRendererFactory(search_path) 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_languages=[], old_data={}): 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=None, allow_disabled=False): 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=None, allow_disabled=False): # 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=None, available_groups=None, 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=None, available_groups=None, 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)) - - chained_validators = [v.ValidPasswordsMatch()] + email = All(v.Email(not_empty=True), v.UniqSystemEmail(localizer, old_data)) + 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, repo_groups=None, landing_revs=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, repo_groups=None, landing_revs=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.Schema): 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_choices, group_perms_choices, 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, create_on_write_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={}, supported_backends=BACKENDS.keys()): 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 index 4275d317..1258e62e 100644 --- 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 index a4c26087..6117e713 100644 --- 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) + 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 index 8a6d501f..d1425a5b 100644 --- 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=None): 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={}, can_create_in_root=False): 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 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'): + localizer, passwd='new_password', + passwd_confirmation='password_confirmation'): + _ = localizer + 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 +def ValidPath(localizer): + _ = localizer - forbidden_params = [ - 'user', 'repo_type', 'repo_enable_locking', - 'repo_enable_downloads', 'repo_enable_statistics' - ] - - 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 index 7400b343..b4f8a43e 100644 --- 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 index 225843cd..62989660 100644 --- 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 index 7dcbdddd..505266a9 100644 --- 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 index 06da0d4f..02b2c5a8 100644 --- 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 index d28778ed..2fc88bb9 100644 --- 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 index d39f0961..969e46d4 100644 --- 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 index 2b198ef8..82c61597 100644 --- 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 index 9734861a..01c7ea14 100644 --- a/rhodecode/templates/channelstream/plugin_init.mako +++ b/rhodecode/templates/channelstream/plugin_init.mako @@ -1,3 +1,5 @@ +<%page args="config"/> +