# HG changeset patch # User Thomas De Schampheleire # Date 2017-01-14 21:22:51 # Node ID 0122959e1f1d53a733a2758ddb54438b1cdb5343 # Parent 7250e5b1ab46e1562674276ef1e4503464d6381c lib: move jsonify from utils to base Suggested by Mads Kiilerich. The jsonify method is the only thing in utils that directly uses pylons. Move it to base where it fits better and we can use existing global imports. diff --git a/kallithea/controllers/admin/gists.py b/kallithea/controllers/admin/gists.py --- a/kallithea/controllers/admin/gists.py +++ b/kallithea/controllers/admin/gists.py @@ -40,9 +40,8 @@ from kallithea.model.gist import GistMod from kallithea.model.meta import Session from kallithea.model.db import Gist, User from kallithea.lib import helpers as h -from kallithea.lib.base import BaseController, render +from kallithea.lib.base import BaseController, render, jsonify from kallithea.lib.auth import LoginRequired, NotAnonymous -from kallithea.lib.utils import jsonify from kallithea.lib.utils2 import safe_int, safe_unicode, time_to_datetime from kallithea.lib.page import Page from sqlalchemy.sql.expression import or_ diff --git a/kallithea/controllers/admin/repos.py b/kallithea/controllers/admin/repos.py --- a/kallithea/controllers/admin/repos.py +++ b/kallithea/controllers/admin/repos.py @@ -38,8 +38,8 @@ from kallithea.config.routing import url from kallithea.lib import helpers as h from kallithea.lib.auth import LoginRequired, \ HasRepoPermissionAnyDecorator, NotAnonymous, HasPermissionAny -from kallithea.lib.base import BaseRepoController, render -from kallithea.lib.utils import action_logger, jsonify +from kallithea.lib.base import BaseRepoController, render, jsonify +from kallithea.lib.utils import action_logger from kallithea.lib.vcs import RepositoryError from kallithea.model.meta import Session from kallithea.model.db import User, Repository, UserFollowing, RepoGroup, \ diff --git a/kallithea/controllers/changeset.py b/kallithea/controllers/changeset.py --- a/kallithea/controllers/changeset.py +++ b/kallithea/controllers/changeset.py @@ -33,7 +33,6 @@ from pylons import tmpl_context as c, re from pylons.i18n.translation import _ from webob.exc import HTTPFound, HTTPForbidden, HTTPBadRequest, HTTPNotFound -from kallithea.lib.utils import jsonify from kallithea.lib.vcs.exceptions import RepositoryError, \ ChangesetDoesNotExistError, EmptyRepositoryError @@ -41,7 +40,7 @@ from kallithea.lib.compat import json import kallithea.lib.helpers as h from kallithea.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \ NotAnonymous -from kallithea.lib.base import BaseRepoController, render +from kallithea.lib.base import BaseRepoController, render, jsonify from kallithea.lib.utils import action_logger from kallithea.lib.compat import OrderedDict from kallithea.lib import diffs diff --git a/kallithea/controllers/files.py b/kallithea/controllers/files.py --- a/kallithea/controllers/files.py +++ b/kallithea/controllers/files.py @@ -37,7 +37,7 @@ from pylons.i18n.translation import _ from webob.exc import HTTPFound from kallithea.config.routing import url -from kallithea.lib.utils import jsonify, action_logger +from kallithea.lib.utils import action_logger from kallithea.lib import diffs from kallithea.lib import helpers as h @@ -45,7 +45,7 @@ from kallithea.lib.compat import Ordered from kallithea.lib.utils2 import convert_line_endings, detect_mode, safe_str, \ str2bool, safe_int from kallithea.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from kallithea.lib.base import BaseRepoController, render +from kallithea.lib.base import BaseRepoController, render, jsonify from kallithea.lib.vcs.backends.base import EmptyChangeset from kallithea.lib.vcs.conf import settings from kallithea.lib.vcs.exceptions import RepositoryError, \ diff --git a/kallithea/controllers/home.py b/kallithea/controllers/home.py --- a/kallithea/controllers/home.py +++ b/kallithea/controllers/home.py @@ -33,10 +33,10 @@ from pylons.i18n.translation import _ from webob.exc import HTTPBadRequest from sqlalchemy.sql.expression import func -from kallithea.lib.utils import jsonify, conditional_cache +from kallithea.lib.utils import conditional_cache from kallithea.lib.compat import json from kallithea.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from kallithea.lib.base import BaseController, render +from kallithea.lib.base import BaseController, render, jsonify from kallithea.model.db import Repository, RepoGroup from kallithea.model.repo import RepoModel diff --git a/kallithea/controllers/pullrequests.py b/kallithea/controllers/pullrequests.py --- a/kallithea/controllers/pullrequests.py +++ b/kallithea/controllers/pullrequests.py @@ -39,12 +39,12 @@ from kallithea.lib import helpers as h from kallithea.lib import diffs from kallithea.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \ NotAnonymous -from kallithea.lib.base import BaseRepoController, render +from kallithea.lib.base import BaseRepoController, render, jsonify from kallithea.lib.compat import json, OrderedDict from kallithea.lib.diffs import LimitedDiffContainer from kallithea.lib.exceptions import UserInvalidException from kallithea.lib.page import Page -from kallithea.lib.utils import action_logger, jsonify +from kallithea.lib.utils import action_logger from kallithea.lib.vcs.exceptions import EmptyRepositoryError, ChangesetDoesNotExistError from kallithea.lib.vcs.utils import safe_str from kallithea.lib.vcs.utils.hgcompat import unionrepo diff --git a/kallithea/controllers/summary.py b/kallithea/controllers/summary.py --- a/kallithea/controllers/summary.py +++ b/kallithea/controllers/summary.py @@ -42,11 +42,10 @@ from kallithea.lib.vcs.exceptions import NodeDoesNotExistError from kallithea.config.conf import ALL_READMES, ALL_EXTS, LANGUAGES_EXTENSIONS_MAP from kallithea.model.db import Statistics, CacheInvalidation, User -from kallithea.lib.utils import jsonify from kallithea.lib.utils2 import safe_str from kallithea.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \ NotAnonymous -from kallithea.lib.base import BaseRepoController, render +from kallithea.lib.base import BaseRepoController, render, jsonify from kallithea.lib.vcs.backends.base import EmptyChangeset from kallithea.lib.markup_renderer import MarkupRenderer from kallithea.lib.celerylib.tasks import get_commits_stats diff --git a/kallithea/lib/base.py b/kallithea/lib/base.py --- a/kallithea/lib/base.py +++ b/kallithea/lib/base.py @@ -29,9 +29,11 @@ Original author and date, and relevant c """ import datetime +import decorator import logging import time import traceback +import warnings import webob.exc import paste.httpexceptions @@ -39,7 +41,7 @@ import paste.auth.basic import paste.httpheaders from webhelpers.pylonslib import secure_form -from pylons import config, tmpl_context as c, request, session +from pylons import config, tmpl_context as c, request, response, session from pylons.controllers import WSGIController from pylons.templating import render_mako as render # don't remove this import from pylons.i18n.translation import _ @@ -51,6 +53,7 @@ from kallithea.lib.utils2 import str2boo safe_str, safe_int from kallithea.lib import auth_modules from kallithea.lib.auth import AuthUser, HasPermissionAnyMiddleware +from kallithea.lib.compat import json from kallithea.lib.utils import get_repo_slug from kallithea.lib.exceptions import UserCreationError from kallithea.lib.vcs.exceptions import RepositoryError, EmptyRepositoryError, ChangesetDoesNotExistError @@ -581,3 +584,28 @@ class WSGIResultCloseCallback(object): if hasattr(self._result, 'close'): self._result.close() self._close() + + +@decorator.decorator +def jsonify(func, *args, **kwargs): + """Action decorator that formats output for JSON + + Given a function that will return content, this decorator will turn + the result into JSON, with a content-type of 'application/json' and + output it. + """ + response.headers['Content-Type'] = 'application/json; charset=utf-8' + data = func(*args, **kwargs) + if isinstance(data, (list, tuple)): + # A JSON list response is syntactically valid JavaScript and can be + # loaded and executed as JavaScript by a malicious third-party site + # using