mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-25 06:48:01 -05:00
Add oauth-only view of api docs.
This commit is contained in:
@@ -260,6 +260,8 @@ def make_map():
|
||||
|
||||
mc('/dev', controller='redirect', action='redirect', dest='/dev/api')
|
||||
mc('/dev/api', controller='apidocs', action='docs')
|
||||
mc('/dev/api/:mode', controller='apidocs', action='docs',
|
||||
requirements=dict(mode="oauth"))
|
||||
|
||||
mc("/button_info", controller="api", action="info", limit=1)
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ from pylons.i18n import _
|
||||
from reddit_base import RedditController
|
||||
from r2.lib.utils import Storage
|
||||
from r2.lib.pages import BoringPage, ApiHelp
|
||||
from r2.controllers.validator import validate, VOneOf
|
||||
|
||||
# API sections displayed in the documentation page.
|
||||
# Each section can have a title and a markdown-formatted description.
|
||||
@@ -96,7 +97,7 @@ def api_doc(section, **kwargs):
|
||||
|
||||
class ApidocsController(RedditController):
|
||||
@staticmethod
|
||||
def docs_from_controller(controller, url_prefix='/api'):
|
||||
def docs_from_controller(controller, url_prefix='/api', oauth_only=False):
|
||||
"""
|
||||
Examines a controller for documentation. A dictionary index of
|
||||
sections containing dictionaries of URLs is returned. For each URL, a
|
||||
@@ -142,12 +143,22 @@ class ApidocsController(RedditController):
|
||||
|
||||
# add every variant to the index -- the templates will filter
|
||||
# out variants in the long-form documentation
|
||||
for variant in chain([uri], docs.get('uri_variants', [])):
|
||||
api_docs[docs['section']][variant][method] = docs
|
||||
if oauth_only:
|
||||
if not docs['oauth_scopes']:
|
||||
continue
|
||||
for scope in docs['oauth_scopes']:
|
||||
for variant in chain([uri],
|
||||
docs.get('uri_variants', [])):
|
||||
api_docs[scope][variant][method] = docs
|
||||
else:
|
||||
for variant in chain([uri], docs.get('uri_variants', [])):
|
||||
api_docs[docs['section']][variant][method] = docs
|
||||
|
||||
return api_docs
|
||||
|
||||
def GET_docs(self):
|
||||
@validate(
|
||||
mode=VOneOf('mode', options=('methods', 'oauth'), default='methods'))
|
||||
def GET_docs(self, mode):
|
||||
# controllers to gather docs from.
|
||||
from r2.controllers.api import ApiController, ApiminimalController
|
||||
from r2.controllers.apiv1 import APIv1Controller
|
||||
@@ -166,14 +177,23 @@ class ApidocsController(RedditController):
|
||||
|
||||
# merge documentation info together.
|
||||
api_docs = defaultdict(dict)
|
||||
oauth_index = defaultdict(set)
|
||||
for controller, url_prefix in api_controllers:
|
||||
for section, contents in self.docs_from_controller(controller, url_prefix).iteritems():
|
||||
controller_docs = self.docs_from_controller(controller, url_prefix,
|
||||
mode == 'oauth')
|
||||
for section, contents in controller_docs.iteritems():
|
||||
api_docs[section].update(contents)
|
||||
for variant, method_dict in contents.iteritems():
|
||||
for method, docs in method_dict.iteritems():
|
||||
for scope in docs['oauth_scopes']:
|
||||
oauth_index[scope].add((section, variant, method))
|
||||
|
||||
return BoringPage(
|
||||
_('api documentation'),
|
||||
content=ApiHelp(
|
||||
api_docs=api_docs
|
||||
api_docs=api_docs,
|
||||
oauth_index=oauth_index,
|
||||
mode=mode,
|
||||
),
|
||||
css_class="api-help",
|
||||
show_sidebar=False,
|
||||
|
||||
@@ -5828,6 +5828,41 @@ tr.gold-accent + tr > td {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.api-help .toc .mode-selector {
|
||||
display: inline-block;
|
||||
font-size: x-small;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #888;
|
||||
margin-top: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.api-help .toc .mode-selector .mode {
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 3px;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
width: 107px;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.api-help .toc .mode-selector .mode:hover {
|
||||
background-color: #ccc;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.api-help .toc .mode-selector .mode-current {
|
||||
color: black;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.api-help .toc .mode-selector .mode-current:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.api-help em.placeholder {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
@@ -5882,6 +5917,13 @@ tr.gold-accent + tr > td {
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.api-help .methods h2 .scope-id {
|
||||
margin-left: 1em;
|
||||
font-size: small;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.api-help .endpoint .info {
|
||||
padding-left: 1em;
|
||||
border-left: 1px solid #ddd;
|
||||
|
||||
@@ -24,11 +24,83 @@
|
||||
import re
|
||||
from r2.lib.filters import safemarkdown
|
||||
from r2.controllers.api_docs import section_info
|
||||
from r2.models.token import OAuth2Scope
|
||||
%>
|
||||
|
||||
<%def name="api_method_id(uri, method)">${method}_${uri.replace('/', '_').strip('_')}</%def>
|
||||
<%def name="api_uri(uri)">${unsafe(re.sub(r'{(\w+)}', r'<em class="placeholder">\1</em>', uri))}</%def>
|
||||
|
||||
<%def name="mode_selector(current_mode)">
|
||||
<span class="mode-selector">
|
||||
<a class="mode ${'mode-current' if current_mode == 'section' else ''}"
|
||||
href="/dev/api">by section</a>
|
||||
<a class="mode ${'mode-current' if current_mode == 'oauth' else ''}"
|
||||
href="/dev/api/oauth">by oauth scope</a>
|
||||
</span>
|
||||
</%def>
|
||||
|
||||
<%def name="api_method_toc(api)">
|
||||
<strong>API methods</strong>
|
||||
${mode_selector('section')}
|
||||
<ul>
|
||||
%for section in sorted(api):
|
||||
<li>
|
||||
<a href="#section_${section}" class="section">${section_info[section]['title']}</a>
|
||||
<ul>
|
||||
%for uri in sorted(api[section]):
|
||||
<%
|
||||
methods = sorted(api[section][uri].keys())
|
||||
has_oauth = any(api[section][uri][method]['oauth_scopes']
|
||||
for method in methods)
|
||||
%>
|
||||
<li class="${'supports-oauth' if has_oauth else ''}">
|
||||
<a href="#${api_method_id(uri, methods[0])}">${api_uri(uri)}</a>
|
||||
</li>
|
||||
%endfor
|
||||
</ul>
|
||||
</li>
|
||||
%endfor
|
||||
</ul>
|
||||
</%def>
|
||||
|
||||
<%def name="oauth_toc(api, oauth_index)">
|
||||
<strong>API methods</strong>
|
||||
${mode_selector('oauth')}
|
||||
<ul>
|
||||
%for scope, keys in sorted(oauth_index.iteritems()):
|
||||
<li>
|
||||
<a href="#scope_${scope}" class="section">${scope}</a>
|
||||
<ul>
|
||||
%for section, uri, method in sorted(keys):
|
||||
<li>
|
||||
<a href="#${api_method_id(uri, method)}">${api_uri(uri)}</a>
|
||||
</li>
|
||||
%endfor
|
||||
</ul>
|
||||
</li>
|
||||
%endfor
|
||||
</ul>
|
||||
</%def>
|
||||
|
||||
<%def name="section_header(section)">
|
||||
<h2 id="section_${section}">${section_info[section]['title']}</h2>
|
||||
%if 'description' in section_info[section]:
|
||||
<div class="description">
|
||||
${unsafe(safemarkdown(section_info[section]['description']))}
|
||||
</div>
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="scope_header(scope)">
|
||||
<h2 id="scope_${scope}">
|
||||
${OAuth2Scope.scope_info[scope]['name']}
|
||||
<span class="scope-id">${scope}</span>
|
||||
</h2>
|
||||
<div class="description">
|
||||
${unsafe(safemarkdown(OAuth2Scope.scope_info[scope]['description']))}
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%
|
||||
api = thing.api_docs
|
||||
%>
|
||||
@@ -38,26 +110,11 @@
|
||||
<div class="toc">
|
||||
<ul>
|
||||
<li>
|
||||
<strong>API methods</strong>
|
||||
<ul>
|
||||
%for section in sorted(api):
|
||||
<li>
|
||||
<a href="#section_${section}" class="section">${section_info[section]['title']}</a>
|
||||
<ul>
|
||||
%for uri in sorted(api[section]):
|
||||
<%
|
||||
methods = sorted(api[section][uri].keys())
|
||||
has_oauth = any(api[section][uri][method]['oauth_scopes']
|
||||
for method in methods)
|
||||
%>
|
||||
<li class="${'supports-oauth' if has_oauth else ''}">
|
||||
<a href="#${api_method_id(uri, methods[0])}">${api_uri(uri)}</a>
|
||||
</li>
|
||||
%endfor
|
||||
</ul>
|
||||
</li>
|
||||
%endfor
|
||||
</ul>
|
||||
%if thing.mode == "oauth":
|
||||
${oauth_toc(thing.api_docs, thing.oauth_index)}
|
||||
%else:
|
||||
${api_method_toc(thing.api_docs)}
|
||||
%endif
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -73,11 +130,10 @@
|
||||
|
||||
<div class="section methods">
|
||||
%for section in sorted(api):
|
||||
<h2 id="section_${section}">${section_info[section]['title']}</h2>
|
||||
%if 'description' in section_info[section]:
|
||||
<div class="description">
|
||||
${unsafe(safemarkdown(section_info[section]['description']))}
|
||||
</div>
|
||||
%if thing.mode == 'oauth':
|
||||
${scope_header(section)}
|
||||
%else:
|
||||
${section_header(section)}
|
||||
%endif
|
||||
%for uri in sorted(api[section]):
|
||||
%for method in sorted(api[section][uri]):
|
||||
|
||||
Reference in New Issue
Block a user