diff --git a/r2/r2/config/routing.py b/r2/r2/config/routing.py index addb6792d..203840932 100644 --- a/r2/r2/config/routing.py +++ b/r2/r2/config/routing.py @@ -204,7 +204,7 @@ def make_map(global_conf={}, app_conf={}): mc('/post/:action', controller='post', requirements=dict(action="options|over18|unlogged_options|optout|optin|login|reg")) - mc('/api', controller='apihelp', action='help') + mc('/api', controller='apidocs', action='docs') mc('/api/distinguish/:how', controller='api', action="distinguish") # wherever this is, google has to agree. mc('/api/gcheckout', controller='ipn', action='gcheckout') diff --git a/r2/r2/controllers/__init__.py b/r2/r2/controllers/__init__.py index 1fa391884..d13531875 100644 --- a/r2/r2/controllers/__init__.py +++ b/r2/r2/controllers/__init__.py @@ -59,7 +59,8 @@ try: except ImportError: from api import ApiController -from api import ApiminimalController, ApihelpController +from api import ApiminimalController +from api_docs import ApidocsController from apiv1 import APIv1Controller as Apiv1Controller from oauth2 import OAuth2FrontendController as Oauth2frontendController from oauth2 import OAuth2AccessController as Oauth2accessController diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py index 83088c737..25990003f 100644 --- a/r2/r2/controllers/api.py +++ b/r2/r2/controllers/api.py @@ -34,7 +34,7 @@ from r2.lib.utils import query_string, timefromnow, randstr from r2.lib.utils import timeago, tup, filter_links from r2.lib.pages import EnemyList, FriendList, ContributorList, ModList, \ BannedList, BoringPage, FormPage, CssError, UploadedImage, ClickGadget, \ - UrlParser, WrappedUser, ApiHelp, BoringPage + UrlParser, WrappedUser, BoringPage from r2.lib.pages import FlairList, FlairCsv, FlairTemplateEditor, \ FlairSelector from r2.lib.utils.trial_utils import indict, end_trial, trial_info @@ -2495,65 +2495,3 @@ class ApiController(RedditController): self.enable_admin_mode(c.user) form.redirect(dest) -class ApihelpController(RedditController): - @staticmethod - def docs_from_controller(controller, url_prefix='/api'): - """ - Examines a controller for documentation. A dictionary of URLs is - returned. For each URL, a dictionary of HTTP methods (GET, POST, etc.) - is contained. For each URL/method pair, a dictionary containing the - following items is available: - - - `__doc__`: Markdown-formatted docstring. - - `oauth2_scopes`: List of OAuth2 scopes - - *more to come...* - """ - - api_methods = defaultdict(dict) - for name, func in controller.__dict__.iteritems(): - i = name.find('_') - if i > 0: - method = name[:i] - action = name[i+1:] - else: - continue - - if func.__doc__ and method in ('GET', 'POST'): - docs = { - '__doc__': re.sub(r'\n +', '\n', func.__doc__).strip(), - } - - if hasattr(func, 'oauth2_perms'): - scopes = func.oauth2_perms.get('allowed_scopes') - if scopes: - docs['oauth2_scopes'] = scopes - - # TODO: in the future, it would be cool to introspect the - # validators in order to generate a list of request - # parameters. Some decorators also give a hint as to response - # type (JSON, etc.) which could be included as well. - - api_methods['/'.join((url_prefix, action))][method] = docs - - return api_methods - - def GET_help(self): - from r2.controllers.apiv1 import APIv1Controller - from r2.controllers.oauth2 import OAuth2FrontendController, OAuth2AccessController, scope_info - - api_methods = defaultdict(dict) - for controller, url_prefix in ((ApiController, '/api'), - (ApiminimalController, '/api'), - (OAuth2FrontendController, '/api/v1'), - (OAuth2AccessController, '/api/v1'), - (APIv1Controller, '/api/v1')): - for url, methods in self.docs_from_controller(controller, url_prefix).iteritems(): - api_methods[url].update(methods) - - return BoringPage( - _('api documentation'), - content=ApiHelp( - api_methods=api_methods, - oauth2_scopes=scope_info, - ) - ).render() diff --git a/r2/r2/controllers/api_docs.py b/r2/r2/controllers/api_docs.py new file mode 100644 index 000000000..77ec8d52f --- /dev/null +++ b/r2/r2/controllers/api_docs.py @@ -0,0 +1,70 @@ +import re +from collections import defaultdict + +from pylons.i18n import _ +from reddit_base import RedditController +from r2.lib.pages import BoringPage, ApiHelp + +class ApidocsController(RedditController): + @staticmethod + def docs_from_controller(controller, url_prefix='/api'): + """ + Examines a controller for documentation. A dictionary of URLs is + returned. For each URL, a dictionary of HTTP methods (GET, POST, etc.) + is contained. For each URL/method pair, a dictionary containing the + following items is available: + + - `__doc__`: Markdown-formatted docstring. + - `oauth2_scopes`: List of OAuth2 scopes + - *more to come...* + """ + + api_methods = defaultdict(dict) + for name, func in controller.__dict__.iteritems(): + i = name.find('_') + if i > 0: + method = name[:i] + action = name[i+1:] + else: + continue + + if func.__doc__ and method in ('GET', 'POST'): + docs = { + '__doc__': re.sub(r'\n +', '\n', func.__doc__).strip(), + } + + if hasattr(func, 'oauth2_perms'): + scopes = func.oauth2_perms.get('allowed_scopes') + if scopes: + docs['oauth2_scopes'] = scopes + + # TODO: in the future, it would be cool to introspect the + # validators in order to generate a list of request + # parameters. Some decorators also give a hint as to response + # type (JSON, etc.) which could be included as well. + + api_methods['/'.join((url_prefix, action))][method] = docs + + return api_methods + + def GET_docs(self): + from r2.controllers.api import ApiController, ApiminimalController + from r2.controllers.apiv1 import APIv1Controller + from r2.controllers.oauth2 import OAuth2FrontendController, OAuth2AccessController, scope_info + + api_methods = defaultdict(dict) + for controller, url_prefix in ((ApiController, '/api'), + (ApiminimalController, '/api'), + (OAuth2FrontendController, '/api/v1'), + (OAuth2AccessController, '/api/v1'), + (APIv1Controller, '/api/v1')): + for url, methods in self.docs_from_controller(controller, url_prefix).iteritems(): + api_methods[url].update(methods) + + return BoringPage( + _('api documentation'), + content=ApiHelp( + api_methods=api_methods, + oauth2_scopes=scope_info, + ) + ).render()