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")
|
||||
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_id = gist.gist_access_id
|
||||
gist_created_on = gist.created_on
|
||||
|
|
@ -45,14 +45,14 @@ class TestApiGetGist(object):
|
|||
'expires': -1.0,
|
||||
'gist_id': int(gist_id),
|
||||
'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,
|
||||
'content': None,
|
||||
}
|
||||
|
||||
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 = {
|
||||
u'filename1.txt': {'content': u'hello world'},
|
||||
u'filename1ą.txt': {'content': u'hello worldę'}
|
||||
|
|
@ -73,7 +73,7 @@ class TestApiGetGist(object):
|
|||
'expires': -1.0,
|
||||
'gist_id': int(gist_id),
|
||||
'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,
|
||||
'content': {
|
||||
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.tests import (
|
||||
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):
|
||||
|
|
@ -70,7 +94,7 @@ class TestGistsController(TestController):
|
|||
|
||||
def test_index_empty(self, create_gist):
|
||||
self.log_user()
|
||||
response = self.app.get(url('gists'))
|
||||
response = self.app.get(route_path('gists_show'))
|
||||
response.mustcontain('data: [],')
|
||||
|
||||
def test_index(self, create_gist):
|
||||
|
|
@ -79,7 +103,7 @@ class TestGistsController(TestController):
|
|||
g2 = create_gist('gist2', lifetime=1400)
|
||||
g3 = create_gist('gist3', description='gist3-desc')
|
||||
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' % g2.gist_access_id)
|
||||
|
|
@ -95,7 +119,7 @@ class TestGistsController(TestController):
|
|||
def test_index_private_gists(self, create_gist):
|
||||
self.log_user()
|
||||
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
|
||||
response.mustcontain('gist: %s' % gist.gist_access_id)
|
||||
|
|
@ -107,7 +131,7 @@ class TestGistsController(TestController):
|
|||
create_gist('gist3', description='gist3-desc')
|
||||
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
|
||||
# and privates
|
||||
|
|
@ -120,7 +144,7 @@ class TestGistsController(TestController):
|
|||
create_gist('gist3', 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
|
||||
# since we don't have access to private in this view, we
|
||||
|
|
@ -131,7 +155,7 @@ class TestGistsController(TestController):
|
|||
def test_create(self):
|
||||
self.log_user()
|
||||
response = self.app.post(
|
||||
url('gists'),
|
||||
route_path('gists_create'),
|
||||
params={'lifetime': -1,
|
||||
'content': 'gist test',
|
||||
'filename': 'foo',
|
||||
|
|
@ -146,7 +170,7 @@ class TestGistsController(TestController):
|
|||
def test_create_with_path_with_dirs(self):
|
||||
self.log_user()
|
||||
response = self.app.post(
|
||||
url('gists'),
|
||||
route_path('gists_create'),
|
||||
params={'lifetime': -1,
|
||||
'content': 'gist test',
|
||||
'filename': '/home/foo',
|
||||
|
|
@ -163,12 +187,13 @@ class TestGistsController(TestController):
|
|||
Session().add(gist)
|
||||
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):
|
||||
self.log_user()
|
||||
response = self.app.post(
|
||||
url('gists'),
|
||||
route_path('gists_create'),
|
||||
params={'lifetime': -1,
|
||||
'content': 'private gist test',
|
||||
'filename': 'private-foo',
|
||||
|
|
@ -187,7 +212,7 @@ class TestGistsController(TestController):
|
|||
def test_create_private_acl_private(self):
|
||||
self.log_user()
|
||||
response = self.app.post(
|
||||
url('gists'),
|
||||
route_path('gists_create'),
|
||||
params={'lifetime': -1,
|
||||
'content': 'private gist test',
|
||||
'filename': 'private-foo',
|
||||
|
|
@ -206,7 +231,7 @@ class TestGistsController(TestController):
|
|||
def test_create_with_description(self):
|
||||
self.log_user()
|
||||
response = self.app.post(
|
||||
url('gists'),
|
||||
route_path('gists_create'),
|
||||
params={'lifetime': -1,
|
||||
'content': 'gist test',
|
||||
'filename': 'foo-desc',
|
||||
|
|
@ -231,7 +256,8 @@ class TestGistsController(TestController):
|
|||
'gist_acl_level': Gist.ACL_LEVEL_PUBLIC,
|
||||
'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()
|
||||
response = response.follow()
|
||||
response.mustcontain('added file: foo-desc')
|
||||
|
|
@ -240,35 +266,36 @@ class TestGistsController(TestController):
|
|||
|
||||
def test_new(self):
|
||||
self.log_user()
|
||||
self.app.get(url('new_gist'))
|
||||
self.app.get(route_path('gists_new'))
|
||||
|
||||
def test_delete(self, create_gist):
|
||||
self.log_user()
|
||||
gist = create_gist('delete-me')
|
||||
response = self.app.post(
|
||||
url('gist', gist_id=gist.gist_id),
|
||||
params={'_method': 'delete', 'csrf_token': self.csrf_token})
|
||||
route_path('gist_delete', gist_id=gist.gist_id),
|
||||
params={'csrf_token': self.csrf_token})
|
||||
assert_session_flash(response, 'Deleted gist %s' % gist.gist_id)
|
||||
|
||||
def test_delete_normal_user_his_gist(self, create_gist):
|
||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||
gist = create_gist('delete-me', owner=TEST_USER_REGULAR_LOGIN)
|
||||
|
||||
response = self.app.post(
|
||||
url('gist', gist_id=gist.gist_id),
|
||||
params={'_method': 'delete', 'csrf_token': self.csrf_token})
|
||||
route_path('gist_delete', gist_id=gist.gist_id),
|
||||
params={'csrf_token': self.csrf_token})
|
||||
assert_session_flash(response, 'Deleted gist %s' % gist.gist_id)
|
||||
|
||||
def test_delete_normal_user_not_his_own_gist(self, create_gist):
|
||||
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(
|
||||
url('gist', gist_id=gist.gist_id),
|
||||
params={'_method': 'delete', 'csrf_token': self.csrf_token},
|
||||
status=403)
|
||||
route_path('gist_delete', gist_id=gist.gist_id),
|
||||
params={'csrf_token': self.csrf_token}, status=404)
|
||||
|
||||
def test_show(self, create_gist):
|
||||
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<')
|
||||
|
||||
|
|
@ -283,16 +310,19 @@ class TestGistsController(TestController):
|
|||
with mock.patch(
|
||||
'rhodecode.lib.vcs.settings.ALIASES', ['git']):
|
||||
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):
|
||||
gist = create_gist('gist-show-me-only-when-im-logged-in',
|
||||
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
|
||||
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')
|
||||
|
||||
assert_response = response.assert_response()
|
||||
|
|
@ -303,36 +333,42 @@ class TestGistsController(TestController):
|
|||
|
||||
def test_show_as_raw(self, create_gist):
|
||||
gist = create_gist('gist-show-me', content='GIST CONTENT')
|
||||
response = self.app.get(url('formatted_gist',
|
||||
gist_id=gist.gist_access_id, format='raw'))
|
||||
response = self.app.get(
|
||||
route_path('gist_show_formatted',
|
||||
gist_id=gist.gist_access_id, revision='tip',
|
||||
format='raw'))
|
||||
assert response.body == 'GIST CONTENT'
|
||||
|
||||
def test_show_as_raw_individual_file(self, create_gist):
|
||||
gist = create_gist('gist-show-me-raw', content='GIST BODY')
|
||||
response = self.app.get(url('formatted_gist_file',
|
||||
gist_id=gist.gist_access_id, format='raw',
|
||||
revision='tip', f_path='gist-show-me-raw'))
|
||||
response = self.app.get(
|
||||
route_path('gist_show_formatted_path',
|
||||
gist_id=gist.gist_access_id, format='raw',
|
||||
revision='tip', f_path='gist-show-me-raw'))
|
||||
assert response.body == 'GIST BODY'
|
||||
|
||||
def test_edit_page(self, create_gist):
|
||||
self.log_user()
|
||||
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')
|
||||
|
||||
def test_edit_page_non_logged_user(self, create_gist):
|
||||
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):
|
||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||
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):
|
||||
self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
|
||||
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):
|
||||
xss_atack_string = '"><script>alert(\'First Name\')</script>'
|
||||
|
|
@ -341,7 +377,7 @@ class TestGistsController(TestController):
|
|||
user = user_util.create_user(
|
||||
firstname=xss_atack_string, password=password)
|
||||
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)
|
||||
|
||||
def test_user_last_name_is_escaped(self, user_util, create_gist):
|
||||
|
|
@ -351,5 +387,5 @@ class TestGistsController(TestController):
|
|||
user = user_util.create_user(
|
||||
lastname=xss_atack_string, password=password)
|
||||
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)
|
||||
|
|
@ -18,35 +18,26 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
|
||||
"""
|
||||
gist controller for RhodeCode
|
||||
"""
|
||||
|
||||
import time
|
||||
import logging
|
||||
|
||||
import formencode
|
||||
import peppercorn
|
||||
|
||||
from pylons import request, response, tmpl_context as c, url
|
||||
from pylons.controllers.util import redirect
|
||||
from pylons.i18n.translation import _
|
||||
from webob.exc import HTTPNotFound, HTTPForbidden
|
||||
from sqlalchemy.sql.expression import or_
|
||||
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden, HTTPFound
|
||||
from pyramid.view import view_config
|
||||
from pyramid.renderers import render
|
||||
from pyramid.response import Response
|
||||
|
||||
|
||||
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.apps._base import BaseAppView
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.lib.base import BaseController, render
|
||||
from rhodecode.lib.auth import LoginRequired, NotAnonymous
|
||||
from rhodecode.lib.utils import jsonify
|
||||
from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
|
||||
from rhodecode.lib.utils2 import time_to_datetime
|
||||
from rhodecode.lib.ext_json import json
|
||||
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.validation_schema.schemas import gist_schema
|
||||
|
||||
|
|
@ -54,10 +45,13 @@ from rhodecode.model.validation_schema.schemas import gist_schema
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GistsController(BaseController):
|
||||
"""REST Controller styled on the Atom Publishing Protocol"""
|
||||
class GistView(BaseAppView):
|
||||
|
||||
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 = [
|
||||
(-1, _('forever')),
|
||||
(5, _('5 minutes')),
|
||||
|
|
@ -65,22 +59,27 @@ class GistsController(BaseController):
|
|||
(60 * 24, _('1 day')),
|
||||
(60 * 24 * 30, _('1 month')),
|
||||
]
|
||||
if extra_values:
|
||||
c.lifetime_values.append(extra_values)
|
||||
|
||||
c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
|
||||
c.acl_options = [
|
||||
(Gist.ACL_LEVEL_PRIVATE, _("Requires registered account")),
|
||||
(Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
|
||||
]
|
||||
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
def index(self):
|
||||
"""GET /admin/gists: All items in the collection"""
|
||||
# url('gists')
|
||||
not_default_user = c.rhodecode_user.username != User.DEFAULT_USER
|
||||
c.show_private = request.GET.get('private') and not_default_user
|
||||
c.show_public = request.GET.get('public') and not_default_user
|
||||
c.show_all = request.GET.get('all') and c.rhodecode_user.admin
|
||||
@view_config(
|
||||
route_name='gists_show', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/gists/index.mako')
|
||||
def gist_show_all(self):
|
||||
c = self.load_default_context()
|
||||
|
||||
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()\
|
||||
.filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\
|
||||
|
|
@ -90,18 +89,18 @@ class GistsController(BaseController):
|
|||
# MY private
|
||||
if c.show_private and not c.show_public:
|
||||
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'
|
||||
# MY public
|
||||
elif c.show_public and not c.show_private:
|
||||
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'
|
||||
# MY public+private
|
||||
elif c.show_private and c.show_public:
|
||||
gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC,
|
||||
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'
|
||||
# Show all by super-admin
|
||||
elif c.show_all:
|
||||
|
|
@ -130,17 +129,29 @@ class GistsController(BaseController):
|
|||
'description': _render('gist_description', gist.gist_description)
|
||||
})
|
||||
c.data = json.dumps(data)
|
||||
return render('admin/gists/index.mako')
|
||||
|
||||
return self._get_template_context(c)
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@auth.CSRFRequired()
|
||||
def create(self):
|
||||
"""POST /admin/gists: Create a new item"""
|
||||
# url('gists')
|
||||
self.__load_defaults()
|
||||
@view_config(
|
||||
route_name='gists_new', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/gists/new.mako')
|
||||
def gist_new(self):
|
||||
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['nodes'] = [{
|
||||
'filename': data['filename'],
|
||||
|
|
@ -166,7 +177,7 @@ class GistsController(BaseController):
|
|||
gist = GistModel().create(
|
||||
gist_id=schema_data['gistid'], # custom access id not real ID
|
||||
description=schema_data['description'],
|
||||
owner=c.rhodecode_user.user_id,
|
||||
owner=self._rhodecode_user.user_id,
|
||||
gist_mapping=schema_data['nodes'],
|
||||
gist_type=schema_data['gist_type'],
|
||||
lifetime=schema_data['lifetime'],
|
||||
|
|
@ -185,75 +196,91 @@ class GistsController(BaseController):
|
|||
errors['filename'] = errors['nodes.0.filename']
|
||||
del errors['nodes.0.filename']
|
||||
|
||||
return formencode.htmlfill.render(
|
||||
render('admin/gists/new.mako'),
|
||||
data = render('rhodecode:templates/admin/gists/new.mako',
|
||||
self._get_template_context(c), self.request)
|
||||
html = formencode.htmlfill.render(
|
||||
data,
|
||||
defaults=defaults,
|
||||
errors=errors,
|
||||
prefix_error=False,
|
||||
encoding="UTF-8",
|
||||
force_defaults=False
|
||||
)
|
||||
return Response(html)
|
||||
|
||||
except Exception:
|
||||
log.exception("Exception while trying to create a gist")
|
||||
h.flash(_('Error occurred during gist creation'), category='error')
|
||||
return redirect(url('new_gist'))
|
||||
return redirect(url('gist', gist_id=new_gist_id))
|
||||
raise HTTPFound(h.route_url('gists_new'))
|
||||
raise HTTPFound(h.route_url('gist_show', gist_id=new_gist_id))
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
def new(self):
|
||||
"""GET /admin/gists/new: Form to create a new item"""
|
||||
# url('new_gist')
|
||||
self.__load_defaults()
|
||||
return render('admin/gists/new.mako')
|
||||
@CSRFRequired()
|
||||
@view_config(
|
||||
route_name='gist_delete', request_method='POST')
|
||||
def gist_delete(self):
|
||||
_ = self.request.translate
|
||||
gist_id = self.request.matchdict['gist_id']
|
||||
|
||||
@LoginRequired()
|
||||
@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 = self.load_default_context()
|
||||
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):
|
||||
raise HTTPForbidden()
|
||||
log.warning('Deletion of Gist was forbidden '
|
||||
'by unauthorized user: `%s`', self._rhodecode_user)
|
||||
raise HTTPNotFound()
|
||||
|
||||
GistModel().delete(c.gist)
|
||||
Session().commit()
|
||||
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):
|
||||
c.gist = Gist.get_or_404(gist_id)
|
||||
def _get_gist(self, gist_id):
|
||||
|
||||
gist = Gist.get_or_404(gist_id)
|
||||
|
||||
# Check if this gist is expired
|
||||
if c.gist.gist_expires != -1:
|
||||
if time.time() > c.gist.gist_expires:
|
||||
if gist.gist_expires != -1:
|
||||
if time.time() > gist.gist_expires:
|
||||
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()
|
||||
|
||||
# check if this gist requires a login
|
||||
is_default_user = c.rhodecode_user.username == User.DEFAULT_USER
|
||||
if c.gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user:
|
||||
is_default_user = self._rhodecode_user.username == User.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`",
|
||||
c.rhodecode_user, gist_id)
|
||||
self._rhodecode_user, gist_id)
|
||||
raise HTTPNotFound()
|
||||
return gist
|
||||
|
||||
@LoginRequired()
|
||||
def show(self, gist_id, revision='tip', format='html', f_path=None):
|
||||
"""GET /admin/gists/gist_id: Show a specific item"""
|
||||
# url('gist', gist_id=ID)
|
||||
self._add_gist_to_context(gist_id)
|
||||
c.render = not request.GET.get('no-render', False)
|
||||
@view_config(
|
||||
route_name='gist_show', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/gists/show.mako')
|
||||
@view_config(
|
||||
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:
|
||||
c.file_last_commit, c.files = GistModel().get_gist_files(
|
||||
|
|
@ -261,25 +288,66 @@ class GistsController(BaseController):
|
|||
except VCSError:
|
||||
log.exception("Exception in gist show")
|
||||
raise HTTPNotFound()
|
||||
if format == 'raw':
|
||||
|
||||
if return_format == 'raw':
|
||||
content = '\n\n'.join([f.content for f in c.files
|
||||
if (f_path is None or f.path == f_path)])
|
||||
response = Response(content)
|
||||
response.content_type = 'text/plain'
|
||||
return content
|
||||
return render('admin/gists/show.mako')
|
||||
return response
|
||||
|
||||
return self._get_template_context(c)
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@auth.CSRFRequired()
|
||||
def edit(self, gist_id):
|
||||
self.__load_defaults()
|
||||
self._add_gist_to_context(gist_id)
|
||||
@view_config(
|
||||
route_name='gist_edit', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/gists/edit.mako')
|
||||
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):
|
||||
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 = schema.bind(
|
||||
|
|
@ -318,48 +386,23 @@ class GistsController(BaseController):
|
|||
h.flash(_('Error occurred during update of gist %s') % gist_id,
|
||||
category='error')
|
||||
|
||||
return redirect(url('gist', gist_id=gist_id))
|
||||
raise HTTPFound(h.route_url('gist_show', gist_id=gist_id))
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
def edit_form(self, gist_id):
|
||||
translate = _ = c.pyramid_request.translate
|
||||
@view_config(
|
||||
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()
|
||||
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:
|
||||
log.error('Last revision %s is different then submitted %s'
|
||||
% (revision, last_rev))
|
||||
|
|
@ -303,6 +303,7 @@ def includeme(config):
|
|||
config.include('rhodecode.apps.user_profile')
|
||||
config.include('rhodecode.apps.my_account')
|
||||
config.include('rhodecode.apps.svn_support')
|
||||
config.include('rhodecode.apps.gist')
|
||||
|
||||
config.include('rhodecode.tweens')
|
||||
config.include('rhodecode.api')
|
||||
|
|
|
|||
|
|
@ -489,39 +489,6 @@ def make_map(config):
|
|||
m.connect('notification', '/notifications/{notification_id}',
|
||||
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
|
||||
rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
|
||||
controller='journal', action='index')
|
||||
|
|
|
|||
|
|
@ -67,15 +67,25 @@ class CSRFDetector(object):
|
|||
'/error/document',
|
||||
))
|
||||
|
||||
_SKIP_PATTERN = frozenset((
|
||||
'/_admin/gists/',
|
||||
))
|
||||
|
||||
def __init__(self, app):
|
||||
self._app = app
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
if environ['REQUEST_METHOD'].upper() not in ('GET', 'POST'):
|
||||
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
|
||||
environ['PATH_INFO'] not in self._PATHS_WITHOUT_TOKEN and
|
||||
token_expected and allowed and
|
||||
routes.middleware.is_form_post(environ)):
|
||||
body = environ['wsgi.input']
|
||||
if body.seekable():
|
||||
|
|
|
|||
|
|
@ -3788,14 +3788,8 @@ class Gist(Base, BaseModel):
|
|||
return cls.query().filter(cls.gist_access_id == gist_access_id).scalar()
|
||||
|
||||
def gist_url(self):
|
||||
import rhodecode
|
||||
from pylons import url
|
||||
|
||||
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)
|
||||
from rhodecode.model.gist import GistModel
|
||||
return GistModel().get_url(self)
|
||||
|
||||
@classmethod
|
||||
def base_path(cls):
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import logging
|
|||
import traceback
|
||||
import shutil
|
||||
|
||||
from pyramid.threadlocal import get_current_request
|
||||
|
||||
from rhodecode.lib.utils2 import (
|
||||
safe_unicode, unique_id, safe_int, time_to_datetime, AttributeDict)
|
||||
from rhodecode.lib.ext_json import json
|
||||
|
|
@ -233,3 +235,16 @@ class GistModel(BaseModel):
|
|||
)
|
||||
|
||||
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');
|
||||
});
|
||||
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) {
|
||||
window.location = pyroutes.url('gists', {'public': 1});
|
||||
window.location = pyroutes.url('gists_show', {'public': 1});
|
||||
});
|
||||
Mousetrap.bind(['n g'], function(e) {
|
||||
window.location = pyroutes.url('new_gist');
|
||||
window.location = pyroutes.url('gists_new');
|
||||
});
|
||||
Mousetrap.bind(['n r'], function(e) {
|
||||
window.location = pyroutes.url('new_repo');
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ function registerRCRoutes() {
|
|||
pyroutes.register('new_repo', '/_admin/create_repository', []);
|
||||
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('gists', '/_admin/gists', []);
|
||||
pyroutes.register('new_gist', '/_admin/gists/new', []);
|
||||
pyroutes.register('toggle_following', '/_admin/toggle_following', []);
|
||||
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']);
|
||||
|
|
@ -152,5 +150,16 @@ function registerRCRoutes() {
|
|||
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_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', []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<div class="table">
|
||||
|
||||
<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>
|
||||
<input type="hidden" value="${c.file_last_commit.raw_id}" name="parent_hash">
|
||||
<textarea id="description" name="description"
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
|
||||
<div class="pull-right">
|
||||
${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>
|
||||
${h.end_form()}
|
||||
</div>
|
||||
|
|
@ -109,9 +109,12 @@
|
|||
<script>
|
||||
$('#update').on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
$(this).val('Updating...');
|
||||
$(this).attr('disabled', 'disabled');
|
||||
// check for newer version.
|
||||
$.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: {
|
||||
'revision': '${c.file_last_commit.raw_id}'
|
||||
},
|
||||
|
|
@ -120,7 +123,7 @@
|
|||
success: function(data) {
|
||||
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.')
|
||||
% {'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": {
|
||||
"message": message, "force": "true", "level": "warning"}}];
|
||||
$.Topic('/notifications').publish(alertMessage[0]);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
||||
<ul class="links block-right">
|
||||
<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>
|
||||
</ul>
|
||||
%endif
|
||||
|
|
@ -53,13 +53,13 @@
|
|||
<div class="sidebar">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
% 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
|
||||
<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:
|
||||
<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_private' else ''}"><a href="${h.url('gists', 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_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.route_path('gists_show', _query={'private': 1})}">${_('My private')}</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
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<div class="table">
|
||||
<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>
|
||||
<textarea id="description" name="description" placeholder="${_('Gist description ...')}"></textarea>
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
<%def name="breadcrumbs_links()">
|
||||
${_('Gist')} · ${c.gist.gist_access_id}
|
||||
/ ${_('URL')}: ${c.gist.gist_url()}
|
||||
</%def>
|
||||
|
||||
<%def name="menu_bar_nav()">
|
||||
|
|
@ -33,11 +32,12 @@
|
|||
%if c.rhodecode_user.username != h.DEFAULT_USER:
|
||||
<ul class="links">
|
||||
<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>
|
||||
</ul>
|
||||
%endif
|
||||
</div>
|
||||
<code>${c.gist.gist_url()}</code>
|
||||
<div class="table">
|
||||
<div id="files_data">
|
||||
<div id="codeblock" class="codeblock">
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
<div class="stats">
|
||||
%if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
|
||||
<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.end_form()}
|
||||
</div>
|
||||
|
|
@ -53,9 +53,9 @@
|
|||
<div class="buttons">
|
||||
## only owner should see that
|
||||
%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
|
||||
${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 class="left" >
|
||||
%if c.gist.gist_type != 'public':
|
||||
|
|
@ -78,19 +78,21 @@
|
|||
</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>
|
||||
|
||||
## iterate over the files
|
||||
% for file in c.files:
|
||||
<% 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>
|
||||
<b >${file.path}</b>
|
||||
<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 class="code-body textarea text-area editor">
|
||||
%if renderer:
|
||||
${h.render(file.content, renderer=renderer)}
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@
|
|||
</li>
|
||||
%endif
|
||||
<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>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@
|
|||
<%def name="gist_access_id(gist_access_id, full_contact)">
|
||||
<div>
|
||||
<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>
|
||||
</div>
|
||||
</%def>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue