gists: migrated gists controller to pyramid view.
This commit is contained in:
parent
979f4b8bec
commit
93b6dfba9a
18 changed files with 394 additions and 232 deletions
|
|
@ -28,7 +28,7 @@ from rhodecode.api.tests.utils import (
|
||||||
|
|
||||||
@pytest.mark.usefixtures("testuser_api", "app")
|
@pytest.mark.usefixtures("testuser_api", "app")
|
||||||
class TestApiGetGist(object):
|
class TestApiGetGist(object):
|
||||||
def test_api_get_gist(self, gist_util, http_host_stub):
|
def test_api_get_gist(self, gist_util, http_host_only_stub):
|
||||||
gist = gist_util.create_gist()
|
gist = gist_util.create_gist()
|
||||||
gist_id = gist.gist_access_id
|
gist_id = gist.gist_access_id
|
||||||
gist_created_on = gist.created_on
|
gist_created_on = gist.created_on
|
||||||
|
|
@ -45,14 +45,14 @@ class TestApiGetGist(object):
|
||||||
'expires': -1.0,
|
'expires': -1.0,
|
||||||
'gist_id': int(gist_id),
|
'gist_id': int(gist_id),
|
||||||
'type': 'public',
|
'type': 'public',
|
||||||
'url': 'http://%s/_admin/gists/%s' % (http_host_stub, gist_id,),
|
'url': 'http://%s/_admin/gists/%s' % (http_host_only_stub, gist_id,),
|
||||||
'acl_level': Gist.ACL_LEVEL_PUBLIC,
|
'acl_level': Gist.ACL_LEVEL_PUBLIC,
|
||||||
'content': None,
|
'content': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_ok(id_, expected, given=response.body)
|
assert_ok(id_, expected, given=response.body)
|
||||||
|
|
||||||
def test_api_get_gist_with_content(self, gist_util, http_host_stub):
|
def test_api_get_gist_with_content(self, gist_util, http_host_only_stub):
|
||||||
mapping = {
|
mapping = {
|
||||||
u'filename1.txt': {'content': u'hello world'},
|
u'filename1.txt': {'content': u'hello world'},
|
||||||
u'filename1ą.txt': {'content': u'hello worldę'}
|
u'filename1ą.txt': {'content': u'hello worldę'}
|
||||||
|
|
@ -73,7 +73,7 @@ class TestApiGetGist(object):
|
||||||
'expires': -1.0,
|
'expires': -1.0,
|
||||||
'gist_id': int(gist_id),
|
'gist_id': int(gist_id),
|
||||||
'type': 'public',
|
'type': 'public',
|
||||||
'url': 'http://%s/_admin/gists/%s' % (http_host_stub, gist_id,),
|
'url': 'http://%s/_admin/gists/%s' % (http_host_only_stub, gist_id,),
|
||||||
'acl_level': Gist.ACL_LEVEL_PUBLIC,
|
'acl_level': Gist.ACL_LEVEL_PUBLIC,
|
||||||
'content': {
|
'content': {
|
||||||
u'filename1.txt': u'hello world',
|
u'filename1.txt': u'hello world',
|
||||||
|
|
|
||||||
62
rhodecode/apps/gist/__init__.py
Normal file
62
rhodecode/apps/gist/__init__.py
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
# -*- 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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# 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/
|
||||||
|
from rhodecode.apps._base import ADMIN_PREFIX
|
||||||
|
|
||||||
|
|
||||||
|
def admin_routes(config):
|
||||||
|
config.add_route(
|
||||||
|
name='gists_show', pattern='/gists')
|
||||||
|
config.add_route(
|
||||||
|
name='gists_new', pattern='/gists/new')
|
||||||
|
config.add_route(
|
||||||
|
name='gists_create', pattern='/gists/create')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_show', pattern='/gists/{gist_id}')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_delete', pattern='/gists/{gist_id}/delete')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_edit', pattern='/gists/{gist_id}/edit')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_edit_check_revision',
|
||||||
|
pattern='/gists/{gist_id}/edit/check_revision')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_update', pattern='/gists/{gist_id}/update')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_show_rev',
|
||||||
|
pattern='/gists/{gist_id}/{revision}')
|
||||||
|
config.add_route(
|
||||||
|
name='gist_show_formatted',
|
||||||
|
pattern='/gists/{gist_id}/{revision}/{format}')
|
||||||
|
|
||||||
|
config.add_route(
|
||||||
|
name='gist_show_formatted_path',
|
||||||
|
pattern='/gists/{gist_id}/{revision}/{format}/{f_path:.*}')
|
||||||
|
|
||||||
|
|
||||||
|
def includeme(config):
|
||||||
|
config.include(admin_routes, route_prefix=ADMIN_PREFIX)
|
||||||
|
# Scan module for configuration decorators.
|
||||||
|
config.scan()
|
||||||
20
rhodecode/apps/gist/tests/__init__.py
Normal file
20
rhodecode/apps/gist/tests/__init__.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- 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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# 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/
|
||||||
|
|
||||||
|
|
@ -27,7 +27,31 @@ from rhodecode.model.gist import GistModel
|
||||||
from rhodecode.model.meta import Session
|
from rhodecode.model.meta import Session
|
||||||
from rhodecode.tests import (
|
from rhodecode.tests import (
|
||||||
TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
|
TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
|
||||||
TestController, assert_session_flash, url)
|
TestController, assert_session_flash)
|
||||||
|
|
||||||
|
|
||||||
|
def route_path(name, params=None, **kwargs):
|
||||||
|
import urllib
|
||||||
|
from rhodecode.apps._base import ADMIN_PREFIX
|
||||||
|
|
||||||
|
base_url = {
|
||||||
|
'gists_show': ADMIN_PREFIX + '/gists',
|
||||||
|
'gists_new': ADMIN_PREFIX + '/gists/new',
|
||||||
|
'gists_create': ADMIN_PREFIX + '/gists/create',
|
||||||
|
'gist_show': ADMIN_PREFIX + '/gists/{gist_id}',
|
||||||
|
'gist_delete': ADMIN_PREFIX + '/gists/{gist_id}/delete',
|
||||||
|
'gist_edit': ADMIN_PREFIX + '/gists/{gist_id}/edit',
|
||||||
|
'gist_edit_check_revision': ADMIN_PREFIX + '/gists/{gist_id}/edit/check_revision',
|
||||||
|
'gist_update': ADMIN_PREFIX + '/gists/{gist_id}/update',
|
||||||
|
'gist_show_rev': ADMIN_PREFIX + '/gists/{gist_id}/{revision}',
|
||||||
|
'gist_show_formatted': ADMIN_PREFIX + '/gists/{gist_id}/{revision}/{format}',
|
||||||
|
'gist_show_formatted_path': ADMIN_PREFIX + '/gists/{gist_id}/{revision}/{format}/{f_path}',
|
||||||
|
|
||||||
|
}[name].format(**kwargs)
|
||||||
|
|
||||||
|
if params:
|
||||||
|
base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
|
||||||
class GistUtility(object):
|
class GistUtility(object):
|
||||||
|
|
@ -70,7 +94,7 @@ class TestGistsController(TestController):
|
||||||
|
|
||||||
def test_index_empty(self, create_gist):
|
def test_index_empty(self, create_gist):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.get(url('gists'))
|
response = self.app.get(route_path('gists_show'))
|
||||||
response.mustcontain('data: [],')
|
response.mustcontain('data: [],')
|
||||||
|
|
||||||
def test_index(self, create_gist):
|
def test_index(self, create_gist):
|
||||||
|
|
@ -79,7 +103,7 @@ class TestGistsController(TestController):
|
||||||
g2 = create_gist('gist2', lifetime=1400)
|
g2 = create_gist('gist2', lifetime=1400)
|
||||||
g3 = create_gist('gist3', description='gist3-desc')
|
g3 = create_gist('gist3', description='gist3-desc')
|
||||||
g4 = create_gist('gist4', gist_type='private').gist_access_id
|
g4 = create_gist('gist4', gist_type='private').gist_access_id
|
||||||
response = self.app.get(url('gists'))
|
response = self.app.get(route_path('gists_show'))
|
||||||
|
|
||||||
response.mustcontain('gist: %s' % g1.gist_access_id)
|
response.mustcontain('gist: %s' % g1.gist_access_id)
|
||||||
response.mustcontain('gist: %s' % g2.gist_access_id)
|
response.mustcontain('gist: %s' % g2.gist_access_id)
|
||||||
|
|
@ -95,7 +119,7 @@ class TestGistsController(TestController):
|
||||||
def test_index_private_gists(self, create_gist):
|
def test_index_private_gists(self, create_gist):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
gist = create_gist('gist5', gist_type='private')
|
gist = create_gist('gist5', gist_type='private')
|
||||||
response = self.app.get(url('gists', private=1))
|
response = self.app.get(route_path('gists_show', params=dict(private=1)))
|
||||||
|
|
||||||
# and privates
|
# and privates
|
||||||
response.mustcontain('gist: %s' % gist.gist_access_id)
|
response.mustcontain('gist: %s' % gist.gist_access_id)
|
||||||
|
|
@ -107,7 +131,7 @@ class TestGistsController(TestController):
|
||||||
create_gist('gist3', description='gist3-desc')
|
create_gist('gist3', description='gist3-desc')
|
||||||
create_gist('gist4', gist_type='private')
|
create_gist('gist4', gist_type='private')
|
||||||
|
|
||||||
response = self.app.get(url('gists', all=1))
|
response = self.app.get(route_path('gists_show', params=dict(all=1)))
|
||||||
|
|
||||||
assert len(GistModel.get_all()) == 4
|
assert len(GistModel.get_all()) == 4
|
||||||
# and privates
|
# and privates
|
||||||
|
|
@ -120,7 +144,7 @@ class TestGistsController(TestController):
|
||||||
create_gist('gist3', gist_type='private')
|
create_gist('gist3', gist_type='private')
|
||||||
create_gist('gist4', gist_type='private')
|
create_gist('gist4', gist_type='private')
|
||||||
|
|
||||||
response = self.app.get(url('gists', all=1))
|
response = self.app.get(route_path('gists_show', params=dict(all=1)))
|
||||||
|
|
||||||
assert len(GistModel.get_all()) == 3
|
assert len(GistModel.get_all()) == 3
|
||||||
# since we don't have access to private in this view, we
|
# since we don't have access to private in this view, we
|
||||||
|
|
@ -131,7 +155,7 @@ class TestGistsController(TestController):
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gists'),
|
route_path('gists_create'),
|
||||||
params={'lifetime': -1,
|
params={'lifetime': -1,
|
||||||
'content': 'gist test',
|
'content': 'gist test',
|
||||||
'filename': 'foo',
|
'filename': 'foo',
|
||||||
|
|
@ -146,7 +170,7 @@ class TestGistsController(TestController):
|
||||||
def test_create_with_path_with_dirs(self):
|
def test_create_with_path_with_dirs(self):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gists'),
|
route_path('gists_create'),
|
||||||
params={'lifetime': -1,
|
params={'lifetime': -1,
|
||||||
'content': 'gist test',
|
'content': 'gist test',
|
||||||
'filename': '/home/foo',
|
'filename': '/home/foo',
|
||||||
|
|
@ -163,12 +187,13 @@ class TestGistsController(TestController):
|
||||||
Session().add(gist)
|
Session().add(gist)
|
||||||
Session().commit()
|
Session().commit()
|
||||||
|
|
||||||
self.app.get(url('gist', gist_id=gist.gist_access_id), status=404)
|
self.app.get(route_path('gist_show', gist_id=gist.gist_access_id),
|
||||||
|
status=404)
|
||||||
|
|
||||||
def test_create_private(self):
|
def test_create_private(self):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gists'),
|
route_path('gists_create'),
|
||||||
params={'lifetime': -1,
|
params={'lifetime': -1,
|
||||||
'content': 'private gist test',
|
'content': 'private gist test',
|
||||||
'filename': 'private-foo',
|
'filename': 'private-foo',
|
||||||
|
|
@ -187,7 +212,7 @@ class TestGistsController(TestController):
|
||||||
def test_create_private_acl_private(self):
|
def test_create_private_acl_private(self):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gists'),
|
route_path('gists_create'),
|
||||||
params={'lifetime': -1,
|
params={'lifetime': -1,
|
||||||
'content': 'private gist test',
|
'content': 'private gist test',
|
||||||
'filename': 'private-foo',
|
'filename': 'private-foo',
|
||||||
|
|
@ -206,7 +231,7 @@ class TestGistsController(TestController):
|
||||||
def test_create_with_description(self):
|
def test_create_with_description(self):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gists'),
|
route_path('gists_create'),
|
||||||
params={'lifetime': -1,
|
params={'lifetime': -1,
|
||||||
'content': 'gist test',
|
'content': 'gist test',
|
||||||
'filename': 'foo-desc',
|
'filename': 'foo-desc',
|
||||||
|
|
@ -231,7 +256,8 @@ class TestGistsController(TestController):
|
||||||
'gist_acl_level': Gist.ACL_LEVEL_PUBLIC,
|
'gist_acl_level': Gist.ACL_LEVEL_PUBLIC,
|
||||||
'csrf_token': self.csrf_token
|
'csrf_token': self.csrf_token
|
||||||
}
|
}
|
||||||
response = self.app.post(url('gists'), params=params, status=302)
|
response = self.app.post(
|
||||||
|
route_path('gists_create'), params=params, status=302)
|
||||||
self.logout_user()
|
self.logout_user()
|
||||||
response = response.follow()
|
response = response.follow()
|
||||||
response.mustcontain('added file: foo-desc')
|
response.mustcontain('added file: foo-desc')
|
||||||
|
|
@ -240,35 +266,36 @@ class TestGistsController(TestController):
|
||||||
|
|
||||||
def test_new(self):
|
def test_new(self):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
self.app.get(url('new_gist'))
|
self.app.get(route_path('gists_new'))
|
||||||
|
|
||||||
def test_delete(self, create_gist):
|
def test_delete(self, create_gist):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
gist = create_gist('delete-me')
|
gist = create_gist('delete-me')
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gist', gist_id=gist.gist_id),
|
route_path('gist_delete', gist_id=gist.gist_id),
|
||||||
params={'_method': 'delete', 'csrf_token': self.csrf_token})
|
params={'csrf_token': self.csrf_token})
|
||||||
assert_session_flash(response, 'Deleted gist %s' % gist.gist_id)
|
assert_session_flash(response, 'Deleted gist %s' % gist.gist_id)
|
||||||
|
|
||||||
def test_delete_normal_user_his_gist(self, create_gist):
|
def test_delete_normal_user_his_gist(self, create_gist):
|
||||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||||
gist = create_gist('delete-me', owner=TEST_USER_REGULAR_LOGIN)
|
gist = create_gist('delete-me', owner=TEST_USER_REGULAR_LOGIN)
|
||||||
|
|
||||||
response = self.app.post(
|
response = self.app.post(
|
||||||
url('gist', gist_id=gist.gist_id),
|
route_path('gist_delete', gist_id=gist.gist_id),
|
||||||
params={'_method': 'delete', 'csrf_token': self.csrf_token})
|
params={'csrf_token': self.csrf_token})
|
||||||
assert_session_flash(response, 'Deleted gist %s' % gist.gist_id)
|
assert_session_flash(response, 'Deleted gist %s' % gist.gist_id)
|
||||||
|
|
||||||
def test_delete_normal_user_not_his_own_gist(self, create_gist):
|
def test_delete_normal_user_not_his_own_gist(self, create_gist):
|
||||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||||
gist = create_gist('delete-me')
|
gist = create_gist('delete-me-2')
|
||||||
|
|
||||||
self.app.post(
|
self.app.post(
|
||||||
url('gist', gist_id=gist.gist_id),
|
route_path('gist_delete', gist_id=gist.gist_id),
|
||||||
params={'_method': 'delete', 'csrf_token': self.csrf_token},
|
params={'csrf_token': self.csrf_token}, status=404)
|
||||||
status=403)
|
|
||||||
|
|
||||||
def test_show(self, create_gist):
|
def test_show(self, create_gist):
|
||||||
gist = create_gist('gist-show-me')
|
gist = create_gist('gist-show-me')
|
||||||
response = self.app.get(url('gist', gist_id=gist.gist_access_id))
|
response = self.app.get(route_path('gist_show', gist_id=gist.gist_access_id))
|
||||||
|
|
||||||
response.mustcontain('added file: gist-show-me<')
|
response.mustcontain('added file: gist-show-me<')
|
||||||
|
|
||||||
|
|
@ -283,16 +310,19 @@ class TestGistsController(TestController):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'rhodecode.lib.vcs.settings.ALIASES', ['git']):
|
'rhodecode.lib.vcs.settings.ALIASES', ['git']):
|
||||||
gist = create_gist('gist-show-me-again')
|
gist = create_gist('gist-show-me-again')
|
||||||
self.app.get(url('gist', gist_id=gist.gist_access_id), status=200)
|
self.app.get(
|
||||||
|
route_path('gist_show', gist_id=gist.gist_access_id), status=200)
|
||||||
|
|
||||||
def test_show_acl_private(self, create_gist):
|
def test_show_acl_private(self, create_gist):
|
||||||
gist = create_gist('gist-show-me-only-when-im-logged-in',
|
gist = create_gist('gist-show-me-only-when-im-logged-in',
|
||||||
acl_level=Gist.ACL_LEVEL_PRIVATE)
|
acl_level=Gist.ACL_LEVEL_PRIVATE)
|
||||||
self.app.get(url('gist', gist_id=gist.gist_access_id), status=404)
|
self.app.get(
|
||||||
|
route_path('gist_show', gist_id=gist.gist_access_id), status=404)
|
||||||
|
|
||||||
# now we log-in we should see thi gist
|
# now we log-in we should see thi gist
|
||||||
self.log_user()
|
self.log_user()
|
||||||
response = self.app.get(url('gist', gist_id=gist.gist_access_id))
|
response = self.app.get(
|
||||||
|
route_path('gist_show', gist_id=gist.gist_access_id))
|
||||||
response.mustcontain('added file: gist-show-me-only-when-im-logged-in')
|
response.mustcontain('added file: gist-show-me-only-when-im-logged-in')
|
||||||
|
|
||||||
assert_response = response.assert_response()
|
assert_response = response.assert_response()
|
||||||
|
|
@ -303,36 +333,42 @@ class TestGistsController(TestController):
|
||||||
|
|
||||||
def test_show_as_raw(self, create_gist):
|
def test_show_as_raw(self, create_gist):
|
||||||
gist = create_gist('gist-show-me', content='GIST CONTENT')
|
gist = create_gist('gist-show-me', content='GIST CONTENT')
|
||||||
response = self.app.get(url('formatted_gist',
|
response = self.app.get(
|
||||||
gist_id=gist.gist_access_id, format='raw'))
|
route_path('gist_show_formatted',
|
||||||
|
gist_id=gist.gist_access_id, revision='tip',
|
||||||
|
format='raw'))
|
||||||
assert response.body == 'GIST CONTENT'
|
assert response.body == 'GIST CONTENT'
|
||||||
|
|
||||||
def test_show_as_raw_individual_file(self, create_gist):
|
def test_show_as_raw_individual_file(self, create_gist):
|
||||||
gist = create_gist('gist-show-me-raw', content='GIST BODY')
|
gist = create_gist('gist-show-me-raw', content='GIST BODY')
|
||||||
response = self.app.get(url('formatted_gist_file',
|
response = self.app.get(
|
||||||
gist_id=gist.gist_access_id, format='raw',
|
route_path('gist_show_formatted_path',
|
||||||
revision='tip', f_path='gist-show-me-raw'))
|
gist_id=gist.gist_access_id, format='raw',
|
||||||
|
revision='tip', f_path='gist-show-me-raw'))
|
||||||
assert response.body == 'GIST BODY'
|
assert response.body == 'GIST BODY'
|
||||||
|
|
||||||
def test_edit_page(self, create_gist):
|
def test_edit_page(self, create_gist):
|
||||||
self.log_user()
|
self.log_user()
|
||||||
gist = create_gist('gist-for-edit', content='GIST EDIT BODY')
|
gist = create_gist('gist-for-edit', content='GIST EDIT BODY')
|
||||||
response = self.app.get(url('edit_gist', gist_id=gist.gist_access_id))
|
response = self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id))
|
||||||
response.mustcontain('GIST EDIT BODY')
|
response.mustcontain('GIST EDIT BODY')
|
||||||
|
|
||||||
def test_edit_page_non_logged_user(self, create_gist):
|
def test_edit_page_non_logged_user(self, create_gist):
|
||||||
gist = create_gist('gist-for-edit', content='GIST EDIT BODY')
|
gist = create_gist('gist-for-edit', content='GIST EDIT BODY')
|
||||||
self.app.get(url('edit_gist', gist_id=gist.gist_access_id), status=302)
|
self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id),
|
||||||
|
status=302)
|
||||||
|
|
||||||
def test_edit_normal_user_his_gist(self, create_gist):
|
def test_edit_normal_user_his_gist(self, create_gist):
|
||||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||||
gist = create_gist('gist-for-edit', owner=TEST_USER_REGULAR_LOGIN)
|
gist = create_gist('gist-for-edit', owner=TEST_USER_REGULAR_LOGIN)
|
||||||
self.app.get(url('edit_gist', gist_id=gist.gist_access_id, status=200))
|
self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id,
|
||||||
|
status=200))
|
||||||
|
|
||||||
def test_edit_normal_user_not_his_own_gist(self, create_gist):
|
def test_edit_normal_user_not_his_own_gist(self, create_gist):
|
||||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||||
gist = create_gist('delete-me')
|
gist = create_gist('delete-me')
|
||||||
self.app.get(url('edit_gist', gist_id=gist.gist_access_id), status=403)
|
self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id),
|
||||||
|
status=404)
|
||||||
|
|
||||||
def test_user_first_name_is_escaped(self, user_util, create_gist):
|
def test_user_first_name_is_escaped(self, user_util, create_gist):
|
||||||
xss_atack_string = '"><script>alert(\'First Name\')</script>'
|
xss_atack_string = '"><script>alert(\'First Name\')</script>'
|
||||||
|
|
@ -341,7 +377,7 @@ class TestGistsController(TestController):
|
||||||
user = user_util.create_user(
|
user = user_util.create_user(
|
||||||
firstname=xss_atack_string, password=password)
|
firstname=xss_atack_string, password=password)
|
||||||
create_gist('gist', gist_type='public', owner=user.username)
|
create_gist('gist', gist_type='public', owner=user.username)
|
||||||
response = self.app.get(url('gists'))
|
response = self.app.get(route_path('gists_show'))
|
||||||
response.mustcontain(xss_escaped_string)
|
response.mustcontain(xss_escaped_string)
|
||||||
|
|
||||||
def test_user_last_name_is_escaped(self, user_util, create_gist):
|
def test_user_last_name_is_escaped(self, user_util, create_gist):
|
||||||
|
|
@ -351,5 +387,5 @@ class TestGistsController(TestController):
|
||||||
user = user_util.create_user(
|
user = user_util.create_user(
|
||||||
lastname=xss_atack_string, password=password)
|
lastname=xss_atack_string, password=password)
|
||||||
create_gist('gist', gist_type='public', owner=user.username)
|
create_gist('gist', gist_type='public', owner=user.username)
|
||||||
response = self.app.get(url('gists'))
|
response = self.app.get(route_path('gists_show'))
|
||||||
response.mustcontain(xss_escaped_string)
|
response.mustcontain(xss_escaped_string)
|
||||||
|
|
@ -18,35 +18,26 @@
|
||||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
gist controller for RhodeCode
|
|
||||||
"""
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import formencode
|
import formencode
|
||||||
import peppercorn
|
import peppercorn
|
||||||
|
|
||||||
from pylons import request, response, tmpl_context as c, url
|
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden, HTTPFound
|
||||||
from pylons.controllers.util import redirect
|
from pyramid.view import view_config
|
||||||
from pylons.i18n.translation import _
|
from pyramid.renderers import render
|
||||||
from webob.exc import HTTPNotFound, HTTPForbidden
|
from pyramid.response import Response
|
||||||
from sqlalchemy.sql.expression import or_
|
|
||||||
|
|
||||||
|
from rhodecode.apps._base import BaseAppView
|
||||||
from rhodecode.model.gist import GistModel
|
|
||||||
from rhodecode.model.meta import Session
|
|
||||||
from rhodecode.model.db import Gist, User
|
|
||||||
from rhodecode.lib import auth
|
|
||||||
from rhodecode.lib import helpers as h
|
from rhodecode.lib import helpers as h
|
||||||
from rhodecode.lib.base import BaseController, render
|
from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
|
||||||
from rhodecode.lib.auth import LoginRequired, NotAnonymous
|
|
||||||
from rhodecode.lib.utils import jsonify
|
|
||||||
from rhodecode.lib.utils2 import time_to_datetime
|
from rhodecode.lib.utils2 import time_to_datetime
|
||||||
from rhodecode.lib.ext_json import json
|
from rhodecode.lib.ext_json import json
|
||||||
from rhodecode.lib.vcs.exceptions import VCSError, NodeNotChangedError
|
from rhodecode.lib.vcs.exceptions import VCSError, NodeNotChangedError
|
||||||
|
from rhodecode.model.gist import GistModel
|
||||||
|
from rhodecode.model.meta import Session
|
||||||
|
from rhodecode.model.db import Gist, User, or_
|
||||||
from rhodecode.model import validation_schema
|
from rhodecode.model import validation_schema
|
||||||
from rhodecode.model.validation_schema.schemas import gist_schema
|
from rhodecode.model.validation_schema.schemas import gist_schema
|
||||||
|
|
||||||
|
|
@ -54,10 +45,13 @@ from rhodecode.model.validation_schema.schemas import gist_schema
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class GistsController(BaseController):
|
class GistView(BaseAppView):
|
||||||
"""REST Controller styled on the Atom Publishing Protocol"""
|
|
||||||
|
def load_default_context(self):
|
||||||
|
_ = self.request.translate
|
||||||
|
c = self._get_local_tmpl_context()
|
||||||
|
c.user = c.auth_user.get_instance()
|
||||||
|
|
||||||
def __load_defaults(self, extra_values=None):
|
|
||||||
c.lifetime_values = [
|
c.lifetime_values = [
|
||||||
(-1, _('forever')),
|
(-1, _('forever')),
|
||||||
(5, _('5 minutes')),
|
(5, _('5 minutes')),
|
||||||
|
|
@ -65,22 +59,27 @@ class GistsController(BaseController):
|
||||||
(60 * 24, _('1 day')),
|
(60 * 24, _('1 day')),
|
||||||
(60 * 24 * 30, _('1 month')),
|
(60 * 24 * 30, _('1 month')),
|
||||||
]
|
]
|
||||||
if extra_values:
|
|
||||||
c.lifetime_values.append(extra_values)
|
|
||||||
c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
|
c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
|
||||||
c.acl_options = [
|
c.acl_options = [
|
||||||
(Gist.ACL_LEVEL_PRIVATE, _("Requires registered account")),
|
(Gist.ACL_LEVEL_PRIVATE, _("Requires registered account")),
|
||||||
(Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
|
(Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
self._register_global_c(c)
|
||||||
|
return c
|
||||||
|
|
||||||
@LoginRequired()
|
@LoginRequired()
|
||||||
def index(self):
|
@view_config(
|
||||||
"""GET /admin/gists: All items in the collection"""
|
route_name='gists_show', request_method='GET',
|
||||||
# url('gists')
|
renderer='rhodecode:templates/admin/gists/index.mako')
|
||||||
not_default_user = c.rhodecode_user.username != User.DEFAULT_USER
|
def gist_show_all(self):
|
||||||
c.show_private = request.GET.get('private') and not_default_user
|
c = self.load_default_context()
|
||||||
c.show_public = request.GET.get('public') and not_default_user
|
|
||||||
c.show_all = request.GET.get('all') and c.rhodecode_user.admin
|
not_default_user = self._rhodecode_user.username != User.DEFAULT_USER
|
||||||
|
c.show_private = self.request.GET.get('private') and not_default_user
|
||||||
|
c.show_public = self.request.GET.get('public') and not_default_user
|
||||||
|
c.show_all = self.request.GET.get('all') and self._rhodecode_user.admin
|
||||||
|
|
||||||
gists = _gists = Gist().query()\
|
gists = _gists = Gist().query()\
|
||||||
.filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\
|
.filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\
|
||||||
|
|
@ -90,18 +89,18 @@ class GistsController(BaseController):
|
||||||
# MY private
|
# MY private
|
||||||
if c.show_private and not c.show_public:
|
if c.show_private and not c.show_public:
|
||||||
gists = _gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\
|
gists = _gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\
|
||||||
.filter(Gist.gist_owner == c.rhodecode_user.user_id)
|
.filter(Gist.gist_owner == self._rhodecode_user.user_id)
|
||||||
c.active = 'my_private'
|
c.active = 'my_private'
|
||||||
# MY public
|
# MY public
|
||||||
elif c.show_public and not c.show_private:
|
elif c.show_public and not c.show_private:
|
||||||
gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\
|
gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\
|
||||||
.filter(Gist.gist_owner == c.rhodecode_user.user_id)
|
.filter(Gist.gist_owner == self._rhodecode_user.user_id)
|
||||||
c.active = 'my_public'
|
c.active = 'my_public'
|
||||||
# MY public+private
|
# MY public+private
|
||||||
elif c.show_private and c.show_public:
|
elif c.show_private and c.show_public:
|
||||||
gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC,
|
gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC,
|
||||||
Gist.gist_type == Gist.GIST_PRIVATE))\
|
Gist.gist_type == Gist.GIST_PRIVATE))\
|
||||||
.filter(Gist.gist_owner == c.rhodecode_user.user_id)
|
.filter(Gist.gist_owner == self._rhodecode_user.user_id)
|
||||||
c.active = 'my_all'
|
c.active = 'my_all'
|
||||||
# Show all by super-admin
|
# Show all by super-admin
|
||||||
elif c.show_all:
|
elif c.show_all:
|
||||||
|
|
@ -130,17 +129,29 @@ class GistsController(BaseController):
|
||||||
'description': _render('gist_description', gist.gist_description)
|
'description': _render('gist_description', gist.gist_description)
|
||||||
})
|
})
|
||||||
c.data = json.dumps(data)
|
c.data = json.dumps(data)
|
||||||
return render('admin/gists/index.mako')
|
|
||||||
|
return self._get_template_context(c)
|
||||||
|
|
||||||
@LoginRequired()
|
@LoginRequired()
|
||||||
@NotAnonymous()
|
@NotAnonymous()
|
||||||
@auth.CSRFRequired()
|
@view_config(
|
||||||
def create(self):
|
route_name='gists_new', request_method='GET',
|
||||||
"""POST /admin/gists: Create a new item"""
|
renderer='rhodecode:templates/admin/gists/new.mako')
|
||||||
# url('gists')
|
def gist_new(self):
|
||||||
self.__load_defaults()
|
c = self.load_default_context()
|
||||||
|
return self._get_template_context(c)
|
||||||
|
|
||||||
data = dict(request.POST)
|
@LoginRequired()
|
||||||
|
@NotAnonymous()
|
||||||
|
@CSRFRequired()
|
||||||
|
@view_config(
|
||||||
|
route_name='gists_create', request_method='POST',
|
||||||
|
renderer='rhodecode:templates/admin/gists/new.mako')
|
||||||
|
def gist_create(self):
|
||||||
|
_ = self.request.translate
|
||||||
|
c = self.load_default_context()
|
||||||
|
|
||||||
|
data = dict(self.request.POST)
|
||||||
data['filename'] = data.get('filename') or Gist.DEFAULT_FILENAME
|
data['filename'] = data.get('filename') or Gist.DEFAULT_FILENAME
|
||||||
data['nodes'] = [{
|
data['nodes'] = [{
|
||||||
'filename': data['filename'],
|
'filename': data['filename'],
|
||||||
|
|
@ -166,7 +177,7 @@ class GistsController(BaseController):
|
||||||
gist = GistModel().create(
|
gist = GistModel().create(
|
||||||
gist_id=schema_data['gistid'], # custom access id not real ID
|
gist_id=schema_data['gistid'], # custom access id not real ID
|
||||||
description=schema_data['description'],
|
description=schema_data['description'],
|
||||||
owner=c.rhodecode_user.user_id,
|
owner=self._rhodecode_user.user_id,
|
||||||
gist_mapping=schema_data['nodes'],
|
gist_mapping=schema_data['nodes'],
|
||||||
gist_type=schema_data['gist_type'],
|
gist_type=schema_data['gist_type'],
|
||||||
lifetime=schema_data['lifetime'],
|
lifetime=schema_data['lifetime'],
|
||||||
|
|
@ -185,75 +196,91 @@ class GistsController(BaseController):
|
||||||
errors['filename'] = errors['nodes.0.filename']
|
errors['filename'] = errors['nodes.0.filename']
|
||||||
del errors['nodes.0.filename']
|
del errors['nodes.0.filename']
|
||||||
|
|
||||||
return formencode.htmlfill.render(
|
data = render('rhodecode:templates/admin/gists/new.mako',
|
||||||
render('admin/gists/new.mako'),
|
self._get_template_context(c), self.request)
|
||||||
|
html = formencode.htmlfill.render(
|
||||||
|
data,
|
||||||
defaults=defaults,
|
defaults=defaults,
|
||||||
errors=errors,
|
errors=errors,
|
||||||
prefix_error=False,
|
prefix_error=False,
|
||||||
encoding="UTF-8",
|
encoding="UTF-8",
|
||||||
force_defaults=False
|
force_defaults=False
|
||||||
)
|
)
|
||||||
|
return Response(html)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception("Exception while trying to create a gist")
|
log.exception("Exception while trying to create a gist")
|
||||||
h.flash(_('Error occurred during gist creation'), category='error')
|
h.flash(_('Error occurred during gist creation'), category='error')
|
||||||
return redirect(url('new_gist'))
|
raise HTTPFound(h.route_url('gists_new'))
|
||||||
return redirect(url('gist', gist_id=new_gist_id))
|
raise HTTPFound(h.route_url('gist_show', gist_id=new_gist_id))
|
||||||
|
|
||||||
@LoginRequired()
|
@LoginRequired()
|
||||||
@NotAnonymous()
|
@NotAnonymous()
|
||||||
def new(self):
|
@CSRFRequired()
|
||||||
"""GET /admin/gists/new: Form to create a new item"""
|
@view_config(
|
||||||
# url('new_gist')
|
route_name='gist_delete', request_method='POST')
|
||||||
self.__load_defaults()
|
def gist_delete(self):
|
||||||
return render('admin/gists/new.mako')
|
_ = self.request.translate
|
||||||
|
gist_id = self.request.matchdict['gist_id']
|
||||||
|
|
||||||
@LoginRequired()
|
c = self.load_default_context()
|
||||||
@NotAnonymous()
|
|
||||||
@auth.CSRFRequired()
|
|
||||||
def delete(self, gist_id):
|
|
||||||
"""DELETE /admin/gists/gist_id: Delete an existing item"""
|
|
||||||
# Forms posted to this method should contain a hidden field:
|
|
||||||
# <input type="hidden" name="_method" value="DELETE" />
|
|
||||||
# Or using helpers:
|
|
||||||
# h.form(url('gist', gist_id=ID),
|
|
||||||
# method='delete')
|
|
||||||
# url('gist', gist_id=ID)
|
|
||||||
c.gist = Gist.get_or_404(gist_id)
|
c.gist = Gist.get_or_404(gist_id)
|
||||||
|
|
||||||
owner = c.gist.gist_owner == c.rhodecode_user.user_id
|
owner = c.gist.gist_owner == self._rhodecode_user.user_id
|
||||||
if not (h.HasPermissionAny('hg.admin')() or owner):
|
if not (h.HasPermissionAny('hg.admin')() or owner):
|
||||||
raise HTTPForbidden()
|
log.warning('Deletion of Gist was forbidden '
|
||||||
|
'by unauthorized user: `%s`', self._rhodecode_user)
|
||||||
|
raise HTTPNotFound()
|
||||||
|
|
||||||
GistModel().delete(c.gist)
|
GistModel().delete(c.gist)
|
||||||
Session().commit()
|
Session().commit()
|
||||||
h.flash(_('Deleted gist %s') % c.gist.gist_access_id, category='success')
|
h.flash(_('Deleted gist %s') % c.gist.gist_access_id, category='success')
|
||||||
|
|
||||||
return redirect(url('gists'))
|
raise HTTPFound(h.route_url('gists_show'))
|
||||||
|
|
||||||
def _add_gist_to_context(self, gist_id):
|
def _get_gist(self, gist_id):
|
||||||
c.gist = Gist.get_or_404(gist_id)
|
|
||||||
|
gist = Gist.get_or_404(gist_id)
|
||||||
|
|
||||||
# Check if this gist is expired
|
# Check if this gist is expired
|
||||||
if c.gist.gist_expires != -1:
|
if gist.gist_expires != -1:
|
||||||
if time.time() > c.gist.gist_expires:
|
if time.time() > gist.gist_expires:
|
||||||
log.error(
|
log.error(
|
||||||
'Gist expired at %s', time_to_datetime(c.gist.gist_expires))
|
'Gist expired at %s', time_to_datetime(gist.gist_expires))
|
||||||
raise HTTPNotFound()
|
raise HTTPNotFound()
|
||||||
|
|
||||||
# check if this gist requires a login
|
# check if this gist requires a login
|
||||||
is_default_user = c.rhodecode_user.username == User.DEFAULT_USER
|
is_default_user = self._rhodecode_user.username == User.DEFAULT_USER
|
||||||
if c.gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user:
|
if gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user:
|
||||||
log.error("Anonymous user %s tried to access protected gist `%s`",
|
log.error("Anonymous user %s tried to access protected gist `%s`",
|
||||||
c.rhodecode_user, gist_id)
|
self._rhodecode_user, gist_id)
|
||||||
raise HTTPNotFound()
|
raise HTTPNotFound()
|
||||||
|
return gist
|
||||||
|
|
||||||
@LoginRequired()
|
@LoginRequired()
|
||||||
def show(self, gist_id, revision='tip', format='html', f_path=None):
|
@view_config(
|
||||||
"""GET /admin/gists/gist_id: Show a specific item"""
|
route_name='gist_show', request_method='GET',
|
||||||
# url('gist', gist_id=ID)
|
renderer='rhodecode:templates/admin/gists/show.mako')
|
||||||
self._add_gist_to_context(gist_id)
|
@view_config(
|
||||||
c.render = not request.GET.get('no-render', False)
|
route_name='gist_show_rev', request_method='GET',
|
||||||
|
renderer='rhodecode:templates/admin/gists/show.mako')
|
||||||
|
@view_config(
|
||||||
|
route_name='gist_show_formatted', request_method='GET',
|
||||||
|
renderer=None)
|
||||||
|
@view_config(
|
||||||
|
route_name='gist_show_formatted_path', request_method='GET',
|
||||||
|
renderer=None)
|
||||||
|
def show(self):
|
||||||
|
gist_id = self.request.matchdict['gist_id']
|
||||||
|
|
||||||
|
# TODO(marcink): expose those via matching dict
|
||||||
|
revision = self.request.matchdict.get('revision', 'tip')
|
||||||
|
f_path = self.request.matchdict.get('f_path', None)
|
||||||
|
return_format = self.request.matchdict.get('format')
|
||||||
|
|
||||||
|
c = self.load_default_context()
|
||||||
|
c.gist = self._get_gist(gist_id)
|
||||||
|
c.render = not self.request.GET.get('no-render', False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
c.file_last_commit, c.files = GistModel().get_gist_files(
|
c.file_last_commit, c.files = GistModel().get_gist_files(
|
||||||
|
|
@ -261,25 +288,66 @@ class GistsController(BaseController):
|
||||||
except VCSError:
|
except VCSError:
|
||||||
log.exception("Exception in gist show")
|
log.exception("Exception in gist show")
|
||||||
raise HTTPNotFound()
|
raise HTTPNotFound()
|
||||||
if format == 'raw':
|
|
||||||
|
if return_format == 'raw':
|
||||||
content = '\n\n'.join([f.content for f in c.files
|
content = '\n\n'.join([f.content for f in c.files
|
||||||
if (f_path is None or f.path == f_path)])
|
if (f_path is None or f.path == f_path)])
|
||||||
|
response = Response(content)
|
||||||
response.content_type = 'text/plain'
|
response.content_type = 'text/plain'
|
||||||
return content
|
return response
|
||||||
return render('admin/gists/show.mako')
|
|
||||||
|
return self._get_template_context(c)
|
||||||
|
|
||||||
@LoginRequired()
|
@LoginRequired()
|
||||||
@NotAnonymous()
|
@NotAnonymous()
|
||||||
@auth.CSRFRequired()
|
@view_config(
|
||||||
def edit(self, gist_id):
|
route_name='gist_edit', request_method='GET',
|
||||||
self.__load_defaults()
|
renderer='rhodecode:templates/admin/gists/edit.mako')
|
||||||
self._add_gist_to_context(gist_id)
|
def gist_edit(self):
|
||||||
|
_ = self.request.translate
|
||||||
|
gist_id = self.request.matchdict['gist_id']
|
||||||
|
c = self.load_default_context()
|
||||||
|
c.gist = self._get_gist(gist_id)
|
||||||
|
|
||||||
owner = c.gist.gist_owner == c.rhodecode_user.user_id
|
owner = c.gist.gist_owner == self._rhodecode_user.user_id
|
||||||
if not (h.HasPermissionAny('hg.admin')() or owner):
|
if not (h.HasPermissionAny('hg.admin')() or owner):
|
||||||
raise HTTPForbidden()
|
raise HTTPNotFound()
|
||||||
|
|
||||||
data = peppercorn.parse(request.POST.items())
|
try:
|
||||||
|
c.file_last_commit, c.files = GistModel().get_gist_files(gist_id)
|
||||||
|
except VCSError:
|
||||||
|
log.exception("Exception in gist edit")
|
||||||
|
raise HTTPNotFound()
|
||||||
|
|
||||||
|
if c.gist.gist_expires == -1:
|
||||||
|
expiry = _('never')
|
||||||
|
else:
|
||||||
|
# this cannot use timeago, since it's used in select2 as a value
|
||||||
|
expiry = h.age(h.time_to_datetime(c.gist.gist_expires))
|
||||||
|
|
||||||
|
c.lifetime_values.append(
|
||||||
|
(0, _('%(expiry)s - current value') % {'expiry': _(expiry)})
|
||||||
|
)
|
||||||
|
|
||||||
|
return self._get_template_context(c)
|
||||||
|
|
||||||
|
@LoginRequired()
|
||||||
|
@NotAnonymous()
|
||||||
|
@CSRFRequired()
|
||||||
|
@view_config(
|
||||||
|
route_name='gist_update', request_method='POST',
|
||||||
|
renderer='rhodecode:templates/admin/gists/edit.mako')
|
||||||
|
def gist_update(self):
|
||||||
|
_ = self.request.translate
|
||||||
|
gist_id = self.request.matchdict['gist_id']
|
||||||
|
c = self.load_default_context()
|
||||||
|
c.gist = self._get_gist(gist_id)
|
||||||
|
|
||||||
|
owner = c.gist.gist_owner == self._rhodecode_user.user_id
|
||||||
|
if not (h.HasPermissionAny('hg.admin')() or owner):
|
||||||
|
raise HTTPNotFound()
|
||||||
|
|
||||||
|
data = peppercorn.parse(self.request.POST.items())
|
||||||
|
|
||||||
schema = gist_schema.GistSchema()
|
schema = gist_schema.GistSchema()
|
||||||
schema = schema.bind(
|
schema = schema.bind(
|
||||||
|
|
@ -318,48 +386,23 @@ class GistsController(BaseController):
|
||||||
h.flash(_('Error occurred during update of gist %s') % gist_id,
|
h.flash(_('Error occurred during update of gist %s') % gist_id,
|
||||||
category='error')
|
category='error')
|
||||||
|
|
||||||
return redirect(url('gist', gist_id=gist_id))
|
raise HTTPFound(h.route_url('gist_show', gist_id=gist_id))
|
||||||
|
|
||||||
@LoginRequired()
|
@LoginRequired()
|
||||||
@NotAnonymous()
|
@NotAnonymous()
|
||||||
def edit_form(self, gist_id):
|
@view_config(
|
||||||
translate = _ = c.pyramid_request.translate
|
route_name='gist_edit_check_revision', request_method='GET',
|
||||||
|
renderer='json_ext')
|
||||||
|
def gist_edit_check_revision(self):
|
||||||
|
_ = self.request.translate
|
||||||
|
gist_id = self.request.matchdict['gist_id']
|
||||||
|
c = self.load_default_context()
|
||||||
|
c.gist = self._get_gist(gist_id)
|
||||||
|
|
||||||
"""GET /admin/gists/gist_id/edit: Form to edit an existing item"""
|
|
||||||
# url('edit_gist', gist_id=ID)
|
|
||||||
self._add_gist_to_context(gist_id)
|
|
||||||
|
|
||||||
owner = c.gist.gist_owner == c.rhodecode_user.user_id
|
|
||||||
if not (h.HasPermissionAny('hg.admin')() or owner):
|
|
||||||
raise HTTPForbidden()
|
|
||||||
|
|
||||||
try:
|
|
||||||
c.file_last_commit, c.files = GistModel().get_gist_files(gist_id)
|
|
||||||
except VCSError:
|
|
||||||
log.exception("Exception in gist edit")
|
|
||||||
raise HTTPNotFound()
|
|
||||||
|
|
||||||
if c.gist.gist_expires == -1:
|
|
||||||
expiry = _('never')
|
|
||||||
else:
|
|
||||||
# this cannot use timeago, since it's used in select2 as a value
|
|
||||||
expiry = h.age(h.time_to_datetime(c.gist.gist_expires))
|
|
||||||
|
|
||||||
expiry = translate(expiry)
|
|
||||||
self.__load_defaults(
|
|
||||||
extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry}))
|
|
||||||
return render('admin/gists/edit.mako')
|
|
||||||
|
|
||||||
@LoginRequired()
|
|
||||||
@NotAnonymous()
|
|
||||||
@jsonify
|
|
||||||
def check_revision(self, gist_id):
|
|
||||||
c.gist = Gist.get_or_404(gist_id)
|
|
||||||
last_rev = c.gist.scm_instance().get_commit()
|
last_rev = c.gist.scm_instance().get_commit()
|
||||||
success = True
|
success = True
|
||||||
revision = request.GET.get('revision')
|
revision = self.request.GET.get('revision')
|
||||||
|
|
||||||
##TODO: maybe move this to model ?
|
|
||||||
if revision != last_rev.raw_id:
|
if revision != last_rev.raw_id:
|
||||||
log.error('Last revision %s is different then submitted %s'
|
log.error('Last revision %s is different then submitted %s'
|
||||||
% (revision, last_rev))
|
% (revision, last_rev))
|
||||||
|
|
@ -303,6 +303,7 @@ def includeme(config):
|
||||||
config.include('rhodecode.apps.user_profile')
|
config.include('rhodecode.apps.user_profile')
|
||||||
config.include('rhodecode.apps.my_account')
|
config.include('rhodecode.apps.my_account')
|
||||||
config.include('rhodecode.apps.svn_support')
|
config.include('rhodecode.apps.svn_support')
|
||||||
|
config.include('rhodecode.apps.gist')
|
||||||
|
|
||||||
config.include('rhodecode.tweens')
|
config.include('rhodecode.tweens')
|
||||||
config.include('rhodecode.api')
|
config.include('rhodecode.api')
|
||||||
|
|
|
||||||
|
|
@ -489,39 +489,6 @@ def make_map(config):
|
||||||
m.connect('notification', '/notifications/{notification_id}',
|
m.connect('notification', '/notifications/{notification_id}',
|
||||||
action='show', conditions={'method': ['GET']})
|
action='show', conditions={'method': ['GET']})
|
||||||
|
|
||||||
# ADMIN GIST
|
|
||||||
with rmap.submapper(path_prefix=ADMIN_PREFIX,
|
|
||||||
controller='admin/gists') as m:
|
|
||||||
m.connect('gists', '/gists',
|
|
||||||
action='create', conditions={'method': ['POST']})
|
|
||||||
m.connect('gists', '/gists', jsroute=True,
|
|
||||||
action='index', conditions={'method': ['GET']})
|
|
||||||
m.connect('new_gist', '/gists/new', jsroute=True,
|
|
||||||
action='new', conditions={'method': ['GET']})
|
|
||||||
|
|
||||||
m.connect('/gists/{gist_id}',
|
|
||||||
action='delete', conditions={'method': ['DELETE']})
|
|
||||||
m.connect('edit_gist', '/gists/{gist_id}/edit',
|
|
||||||
action='edit_form', conditions={'method': ['GET']})
|
|
||||||
m.connect('edit_gist', '/gists/{gist_id}/edit',
|
|
||||||
action='edit', conditions={'method': ['POST']})
|
|
||||||
m.connect(
|
|
||||||
'edit_gist_check_revision', '/gists/{gist_id}/edit/check_revision',
|
|
||||||
action='check_revision', conditions={'method': ['GET']})
|
|
||||||
|
|
||||||
m.connect('gist', '/gists/{gist_id}',
|
|
||||||
action='show', conditions={'method': ['GET']})
|
|
||||||
m.connect('gist_rev', '/gists/{gist_id}/{revision}',
|
|
||||||
revision='tip',
|
|
||||||
action='show', conditions={'method': ['GET']})
|
|
||||||
m.connect('formatted_gist', '/gists/{gist_id}/{revision}/{format}',
|
|
||||||
revision='tip',
|
|
||||||
action='show', conditions={'method': ['GET']})
|
|
||||||
m.connect('formatted_gist_file', '/gists/{gist_id}/{revision}/{format}/{f_path}',
|
|
||||||
revision='tip',
|
|
||||||
action='show', conditions={'method': ['GET']},
|
|
||||||
requirements=URL_NAME_REQUIREMENTS)
|
|
||||||
|
|
||||||
# USER JOURNAL
|
# USER JOURNAL
|
||||||
rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
|
rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
|
||||||
controller='journal', action='index')
|
controller='journal', action='index')
|
||||||
|
|
|
||||||
|
|
@ -67,15 +67,25 @@ class CSRFDetector(object):
|
||||||
'/error/document',
|
'/error/document',
|
||||||
))
|
))
|
||||||
|
|
||||||
|
_SKIP_PATTERN = frozenset((
|
||||||
|
'/_admin/gists/',
|
||||||
|
))
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self._app = app
|
self._app = app
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
if environ['REQUEST_METHOD'].upper() not in ('GET', 'POST'):
|
if environ['REQUEST_METHOD'].upper() not in ('GET', 'POST'):
|
||||||
raise Exception(self._PUT_DELETE_MESSAGE)
|
raise Exception(self._PUT_DELETE_MESSAGE)
|
||||||
|
token_expected = environ['PATH_INFO'] not in self._PATHS_WITHOUT_TOKEN
|
||||||
|
allowed = True
|
||||||
|
for pattern in self._SKIP_PATTERN:
|
||||||
|
if environ['PATH_INFO'].startswith(pattern):
|
||||||
|
allowed = False
|
||||||
|
break
|
||||||
|
|
||||||
if (environ['REQUEST_METHOD'] == 'POST' and
|
if (environ['REQUEST_METHOD'] == 'POST' and
|
||||||
environ['PATH_INFO'] not in self._PATHS_WITHOUT_TOKEN and
|
token_expected and allowed and
|
||||||
routes.middleware.is_form_post(environ)):
|
routes.middleware.is_form_post(environ)):
|
||||||
body = environ['wsgi.input']
|
body = environ['wsgi.input']
|
||||||
if body.seekable():
|
if body.seekable():
|
||||||
|
|
|
||||||
|
|
@ -3788,14 +3788,8 @@ class Gist(Base, BaseModel):
|
||||||
return cls.query().filter(cls.gist_access_id == gist_access_id).scalar()
|
return cls.query().filter(cls.gist_access_id == gist_access_id).scalar()
|
||||||
|
|
||||||
def gist_url(self):
|
def gist_url(self):
|
||||||
import rhodecode
|
from rhodecode.model.gist import GistModel
|
||||||
from pylons import url
|
return GistModel().get_url(self)
|
||||||
|
|
||||||
alias_url = rhodecode.CONFIG.get('gist_alias_url')
|
|
||||||
if alias_url:
|
|
||||||
return alias_url.replace('{gistid}', self.gist_access_id)
|
|
||||||
|
|
||||||
return url('gist', gist_id=self.gist_access_id, qualified=True)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def base_path(cls):
|
def base_path(cls):
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import logging
|
||||||
import traceback
|
import traceback
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
from pyramid.threadlocal import get_current_request
|
||||||
|
|
||||||
from rhodecode.lib.utils2 import (
|
from rhodecode.lib.utils2 import (
|
||||||
safe_unicode, unique_id, safe_int, time_to_datetime, AttributeDict)
|
safe_unicode, unique_id, safe_int, time_to_datetime, AttributeDict)
|
||||||
from rhodecode.lib.ext_json import json
|
from rhodecode.lib.ext_json import json
|
||||||
|
|
@ -233,3 +235,16 @@ class GistModel(BaseModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
return gist
|
return gist
|
||||||
|
|
||||||
|
def get_url(self, gist, request=None):
|
||||||
|
import rhodecode
|
||||||
|
|
||||||
|
if not request:
|
||||||
|
request = get_current_request()
|
||||||
|
|
||||||
|
alias_url = rhodecode.CONFIG.get('gist_alias_url')
|
||||||
|
if alias_url:
|
||||||
|
return alias_url.replace('{gistid}', gist.gist_access_id)
|
||||||
|
|
||||||
|
return request.route_url('gist_show', gist_id=gist.gist_access_id)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,13 @@ function setRCMouseBindings(repoName, repoLandingRev) {
|
||||||
window.location = pyroutes.url('home');
|
window.location = pyroutes.url('home');
|
||||||
});
|
});
|
||||||
Mousetrap.bind(['g g'], function(e) {
|
Mousetrap.bind(['g g'], function(e) {
|
||||||
window.location = pyroutes.url('gists', {'private': 1});
|
window.location = pyroutes.url('gists_show', {'private': 1});
|
||||||
});
|
});
|
||||||
Mousetrap.bind(['g G'], function(e) {
|
Mousetrap.bind(['g G'], function(e) {
|
||||||
window.location = pyroutes.url('gists', {'public': 1});
|
window.location = pyroutes.url('gists_show', {'public': 1});
|
||||||
});
|
});
|
||||||
Mousetrap.bind(['n g'], function(e) {
|
Mousetrap.bind(['n g'], function(e) {
|
||||||
window.location = pyroutes.url('new_gist');
|
window.location = pyroutes.url('gists_new');
|
||||||
});
|
});
|
||||||
Mousetrap.bind(['n r'], function(e) {
|
Mousetrap.bind(['n r'], function(e) {
|
||||||
window.location = pyroutes.url('new_repo');
|
window.location = pyroutes.url('new_repo');
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ function registerRCRoutes() {
|
||||||
pyroutes.register('new_repo', '/_admin/create_repository', []);
|
pyroutes.register('new_repo', '/_admin/create_repository', []);
|
||||||
pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
|
pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
|
||||||
pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
|
pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
|
||||||
pyroutes.register('gists', '/_admin/gists', []);
|
|
||||||
pyroutes.register('new_gist', '/_admin/gists/new', []);
|
|
||||||
pyroutes.register('toggle_following', '/_admin/toggle_following', []);
|
pyroutes.register('toggle_following', '/_admin/toggle_following', []);
|
||||||
pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
|
pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
|
||||||
pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
|
pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
|
||||||
|
|
@ -152,5 +150,16 @@ function registerRCRoutes() {
|
||||||
pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
|
pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
|
||||||
pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
|
pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
|
||||||
pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
|
pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
|
||||||
|
pyroutes.register('gists_show', '/_admin/gists', []);
|
||||||
|
pyroutes.register('gists_new', '/_admin/gists/new', []);
|
||||||
|
pyroutes.register('gists_create', '/_admin/gists/create', []);
|
||||||
|
pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
|
||||||
|
pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
|
||||||
|
pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
|
||||||
|
pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
|
||||||
|
pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
|
||||||
|
pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/%(revision)s', ['gist_id', 'revision']);
|
||||||
|
pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
|
||||||
|
pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
|
||||||
pyroutes.register('apiv2', '/_admin/api', []);
|
pyroutes.register('apiv2', '/_admin/api', []);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
<div class="table">
|
<div class="table">
|
||||||
|
|
||||||
<div id="files_data">
|
<div id="files_data">
|
||||||
${h.secure_form(h.url('edit_gist', gist_id=c.gist.gist_access_id), method='post', id='eform')}
|
${h.secure_form(h.route_path('gist_update', gist_id=c.gist.gist_access_id), id='eform', method='POST')}
|
||||||
<div>
|
<div>
|
||||||
<input type="hidden" value="${c.file_last_commit.raw_id}" name="parent_hash">
|
<input type="hidden" value="${c.file_last_commit.raw_id}" name="parent_hash">
|
||||||
<textarea id="description" name="description"
|
<textarea id="description" name="description"
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
|
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
${h.submit('update',_('Update Gist'),class_="btn btn-success")}
|
${h.submit('update',_('Update Gist'),class_="btn btn-success")}
|
||||||
<a class="btn" href="${h.url('gist', gist_id=c.gist.gist_access_id)}">${_('Cancel')}</a>
|
<a class="btn" href="${h.route_path('gist_show', gist_id=c.gist.gist_access_id)}">${_('Cancel')}</a>
|
||||||
</div>
|
</div>
|
||||||
${h.end_form()}
|
${h.end_form()}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -109,9 +109,12 @@
|
||||||
<script>
|
<script>
|
||||||
$('#update').on('click', function(e){
|
$('#update').on('click', function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
$(this).val('Updating...');
|
||||||
|
$(this).attr('disabled', 'disabled');
|
||||||
// check for newer version.
|
// check for newer version.
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "${h.url('edit_gist_check_revision', gist_id=c.gist.gist_access_id)}",
|
url: "${h.route_path('gist_edit_check_revision', gist_id=c.gist.gist_access_id)}",
|
||||||
data: {
|
data: {
|
||||||
'revision': '${c.file_last_commit.raw_id}'
|
'revision': '${c.file_last_commit.raw_id}'
|
||||||
},
|
},
|
||||||
|
|
@ -120,7 +123,7 @@
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
if(data.success === false){
|
if(data.success === false){
|
||||||
message = '${h.literal(_('Gist was updated since you started editing. Copy your changes and click %(here)s to reload the new version.')
|
message = '${h.literal(_('Gist was updated since you started editing. Copy your changes and click %(here)s to reload the new version.')
|
||||||
% {'here': h.link_to('here',h.url('edit_gist', gist_id=c.gist.gist_access_id))})}'
|
% {'here': h.link_to('here', h.route_path('gist_edit', gist_id=c.gist.gist_access_id))})}'
|
||||||
alertMessage = [{"message": {
|
alertMessage = [{"message": {
|
||||||
"message": message, "force": "true", "level": "warning"}}];
|
"message": message, "force": "true", "level": "warning"}}];
|
||||||
$.Topic('/notifications').publish(alertMessage[0]);
|
$.Topic('/notifications').publish(alertMessage[0]);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
||||||
<ul class="links block-right">
|
<ul class="links block-right">
|
||||||
<li>
|
<li>
|
||||||
<a href="${h.url('new_gist')}" class="btn btn-primary">${_(u'Create New Gist')}</a>
|
<a href="${h.route_path('gists_new')}" class="btn btn-primary">${_(u'Create New Gist')}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
%endif
|
%endif
|
||||||
|
|
@ -53,13 +53,13 @@
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<ul class="nav nav-pills nav-stacked">
|
<ul class="nav nav-pills nav-stacked">
|
||||||
% if h.HasPermissionAll('hg.admin')('access admin gists page'):
|
% if h.HasPermissionAll('hg.admin')('access admin gists page'):
|
||||||
<li class="${'active' if c.active=='all' else ''}"><a href="${h.url('gists', all=1)}">${_('All gists')}</a></li>
|
<li class="${'active' if c.active=='all' else ''}"><a href="${h.route_path('gists_show', _query={'all': 1})}">${_('All gists')}</a></li>
|
||||||
%endif
|
%endif
|
||||||
<li class="${'active' if c.active=='public' else ''}"><a href="${h.url('gists')}">${_('All public')}</a></li>
|
<li class="${'active' if c.active=='public' else ''}"><a href="${h.route_path('gists_show')}">${_('All public')}</a></li>
|
||||||
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
||||||
<li class="${'active' if c.active=='my_all' else ''}"><a href="${h.url('gists', public=1, private=1)}">${_('My gists')}</a></li>
|
<li class="${'active' if c.active=='my_all' else ''}"><a href="${h.route_path('gists_show', _query={'public':1, 'private': 1})}">${_('My gists')}</a></li>
|
||||||
<li class="${'active' if c.active=='my_private' else ''}"><a href="${h.url('gists', private=1)}">${_('My private')}</a></li>
|
<li class="${'active' if c.active=='my_private' else ''}"><a href="${h.route_path('gists_show', _query={'private': 1})}">${_('My private')}</a></li>
|
||||||
<li class="${'active' if c.active=='my_public' else ''}"><a href="${h.url('gists', public=1)}">${_('My public')}</a></li>
|
<li class="${'active' if c.active=='my_public' else ''}"><a href="${h.route_path('gists_show', _query={'public': 1})}">${_('My public')}</a></li>
|
||||||
%endif
|
%endif
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div id="files_data">
|
<div id="files_data">
|
||||||
${h.secure_form(h.url('gists'), method='post',id='eform')}
|
${h.secure_form(h.route_path('gists_create'), id='eform', method='POST')}
|
||||||
<div>
|
<div>
|
||||||
<textarea id="description" name="description" placeholder="${_('Gist description ...')}"></textarea>
|
<textarea id="description" name="description" placeholder="${_('Gist description ...')}"></textarea>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
<%def name="breadcrumbs_links()">
|
<%def name="breadcrumbs_links()">
|
||||||
${_('Gist')} · ${c.gist.gist_access_id}
|
${_('Gist')} · ${c.gist.gist_access_id}
|
||||||
/ ${_('URL')}: ${c.gist.gist_url()}
|
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="menu_bar_nav()">
|
<%def name="menu_bar_nav()">
|
||||||
|
|
@ -33,11 +32,12 @@
|
||||||
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
||||||
<ul class="links">
|
<ul class="links">
|
||||||
<li>
|
<li>
|
||||||
<a href="${h.url('new_gist')}" class="btn btn-primary">${_(u'Create New Gist')}</a>
|
<a href="${h.route_path('gists_new')}" class="btn btn-primary">${_(u'Create New Gist')}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
%endif
|
%endif
|
||||||
</div>
|
</div>
|
||||||
|
<code>${c.gist.gist_url()}</code>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div id="files_data">
|
<div id="files_data">
|
||||||
<div id="codeblock" class="codeblock">
|
<div id="codeblock" class="codeblock">
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
%if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
|
%if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
|
||||||
<div class="remove_gist">
|
<div class="remove_gist">
|
||||||
${h.secure_form(url('gist', gist_id=c.gist.gist_access_id),method='delete')}
|
${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), method='POST')}
|
||||||
${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")}
|
${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")}
|
||||||
${h.end_form()}
|
${h.end_form()}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -53,9 +53,9 @@
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
## only owner should see that
|
## only owner should see that
|
||||||
%if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
|
%if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
|
||||||
${h.link_to(_('Edit'),h.url('edit_gist', gist_id=c.gist.gist_access_id),class_="btn btn-mini")}
|
${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")}
|
||||||
%endif
|
%endif
|
||||||
${h.link_to(_('Show as Raw'),h.url('formatted_gist', gist_id=c.gist.gist_access_id, format='raw'),class_="btn btn-mini")}
|
${h.link_to(_('Show as Raw'), h.route_path('gist_show_formatted', gist_id=c.gist.gist_access_id, revision='tip', format='raw'), class_="btn btn-mini")}
|
||||||
</div>
|
</div>
|
||||||
<div class="left" >
|
<div class="left" >
|
||||||
%if c.gist.gist_type != 'public':
|
%if c.gist.gist_type != 'public':
|
||||||
|
|
@ -78,19 +78,21 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="commit">${h.urlify_commit_message(c.file_last_commit.message,c.repo_name)}</div>
|
<div class="commit">${h.urlify_commit_message(c.file_last_commit.message, None)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## iterate over the files
|
## iterate over the files
|
||||||
% for file in c.files:
|
% for file in c.files:
|
||||||
<% renderer = c.render and h.renderer_from_filename(file.path, exclude=['.txt', '.TXT'])%>
|
<% renderer = c.render and h.renderer_from_filename(file.path, exclude=['.txt', '.TXT'])%>
|
||||||
<!-- <div id="${h.FID('G', file.path)}" class="stats" >
|
<!--
|
||||||
|
<div id="${h.FID('G', file.path)}" class="stats" >
|
||||||
<a href="${c.gist.gist_url()}">¶</a>
|
<a href="${c.gist.gist_url()}">¶</a>
|
||||||
<b >${file.path}</b>
|
<b >${file.path}</b>
|
||||||
<div>
|
<div>
|
||||||
${h.link_to(_('Show as raw'),h.url('formatted_gist_file', gist_id=c.gist.gist_access_id, format='raw', revision=file.commit.raw_id, f_path=file.path),class_="btn btn-mini")}
|
${h.link_to(_('Show as raw'), h.route_path('gist_show_formatted_path', gist_id=c.gist.gist_access_id, revision=file.commit.raw_id, format='raw', f_path=file.path), class_="btn btn-mini")}
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
|
-->
|
||||||
<div class="code-body textarea text-area editor">
|
<div class="code-body textarea text-area editor">
|
||||||
%if renderer:
|
%if renderer:
|
||||||
${h.render(file.content, renderer=renderer)}
|
${h.render(file.content, renderer=renderer)}
|
||||||
|
|
|
||||||
|
|
@ -397,7 +397,7 @@
|
||||||
</li>
|
</li>
|
||||||
%endif
|
%endif
|
||||||
<li class="${is_active('gists')}">
|
<li class="${is_active('gists')}">
|
||||||
<a class="menulink childs" title="${_('Show Gists')}" href="${h.url('gists')}">
|
<a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
|
||||||
<div class="menulabel">${_('Gists')}</div>
|
<div class="menulabel">${_('Gists')}</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@
|
||||||
<%def name="gist_access_id(gist_access_id, full_contact)">
|
<%def name="gist_access_id(gist_access_id, full_contact)">
|
||||||
<div>
|
<div>
|
||||||
<b>
|
<b>
|
||||||
<a href="${h.url('gist',gist_id=gist_access_id)}">gist: ${gist_access_id}</a>
|
<a href="${h.route_path('gist_show', gist_id=gist_access_id)}">gist: ${gist_access_id}</a>
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue