Adding the last few endpoints. Now just need to write out descriptions and params for all of them and we're done.

This commit is contained in:
Samuel Clay 2011-04-23 23:15:44 -04:00
parent 1d9168bd0e
commit d1fd28b702
5 changed files with 150 additions and 549 deletions

View file

@ -15,14 +15,15 @@ def about(request):
context_instance=RequestContext(request))
def faq(request):
return render_to_response('static/api.xhtml', {},
return render_to_response('static/faq.xhtml', {},
context_instance=RequestContext(request))
def api(request):
filename = settings.TEMPLATE_DIRS[0] + '/static/api.yml'
filename = settings.TEMPLATE_DIRS[0] + '/static/api.yml'
api_yml_file = open(filename).read()
data = yaml.load(api_yml_file)
return render_to_response('static/api_yaml.xhtml', {
data = yaml.load(api_yml_file)
return render_to_response('static/api.xhtml', {
'data': data
}, context_instance=RequestContext(request))

View file

@ -5223,6 +5223,9 @@ background: transparent;
.NB-static-api h3 {
/* margin-top: 64px;*/
}
.NB-static-api h4 {
margin-top: 12px;
}
.NB-static-api .NB-api-endpoint {
/* margin-left: 12px;*/
/* padding-left: 18px;*/
@ -5250,21 +5253,23 @@ background: transparent;
margin: 12px 0;
}
.NB-static-api table {
width: 620px;
width: 600px;
border-spacing: 0 0;
margin: 24px 0;
/* border: 1px solid #B0B0B0;*/
margin: 24px 0 12px 20px;
background: transparent url('../img/reader/static_bullet_white.png') no-repeat 0 0;
border-bottom: 1px solid #F6F6F6;
}
.NB-static-api table th,
.NB-static-api table td {
text-align: left;
vertical-align: top;
padding: 7px 20px 7px 10px;
padding: 7px 8px 7px 8px;
margin: 0;
}
.NB-static-api table td {
border-right: 1px solid #F6F6f6;
white-space: nowrap;
/* border-bottom: 1px solid #F6F6f6;*/
}
.NB-static-api table td:last-child {
@ -5276,7 +5281,7 @@ background: transparent;
background: -moz-linear-gradient(center bottom, #FCFCFC 0%, #E0E0E0 100%);
border-right: 1px solid #BBB;
border-bottom: 1px solid #BBB;
padding: 2px 20px 2px 10px;
padding: 2px 8px;
color: #222;
font-size: 10px;
text-transform: uppercase;
@ -5316,4 +5321,8 @@ background: transparent;
font-size: 12px;
line-height: 16px;
margin-bottom: 12px;
}
.NB-static-api .NB-api-endpoint-param-desc {
width: 100%;
white-space: normal;
}

View file

@ -24,7 +24,7 @@
<a href="http://github.com/samuelclay/NewsBlur/tree/master/apps/reader/views.py">/reader/ views</a>,
<a href="http://github.com/samuelclay/NewsBlur/tree/master/apps/rss_feeds/views.py">/rss_feeds/ views</a>,
as well as
<a href="http://github.com/samuelclay/NewsBlur/tree/master/templates/static/api.yml">this page itself</a>.</p>
<a href="http://github.com/samuelclay/NewsBlur/tree/master/templates/static/api.yml">the API definitions in YML</a>.</p>
</div>
</div>
@ -37,397 +37,87 @@
<div class="NB-module-content">
<div class="NB-api-endpoint">
<div class="NB-api-toc-header">Feeds</div>
<ul class="NB-api-toc">
<li>
<div class="NB-api-link-desc">User's feeds, with unread counts, meta data, and optional favicons.</div>
<a href="#feeds">GET <code>/reader/feeds</code></a>
</li>
<li>
<div class="NB-api-link-desc">Favicons for each of a user's feeds.</div>
<a href="#favicons">GET <code>/reader/favicons</code></a>
</li>
<li>
<div class="NB-api-link-desc">Original page from a single feed.</div>
<a href="#feed_page">GET <code>/reader/page/:id</code></a>
</li>
<li>
<div class="NB-api-link-desc">Get latest unread counts for active feeds.</div>
<a href="#refresh_feeds">GET <code>/reader/refresh_feeds</code></a>
</li>
<li>
<div class="NB-api-link-desc">Get statistics and history for a feed.</div>
<a href="#statistics">GET <code>/rss_feeds/statistics</code></a>
</li>
<li>
<div class="NB-api-link-desc">Get a list of feeds that contain a phrase.</div>
<a href="#feed_autocomplete">POST <code>/rss_feeds/feed_autocomplete</code></a>
</li>
</ul>
<div class="NB-api-toc-header">Stories</div>
<ul class="NB-api-toc">
<li>
<div class="NB-api-link-desc">Stories from a single feed.</div>
<a href="#feed"><code>/reader/feed/:id</code></a>
</li>
<li>
<div class="NB-api-link-desc">User's starred stories.</div>
<a href="#starred_stories"><code>/reader/starred_stories</code></a>
</li>
<li>
<div class="NB-api-link-desc">Stories from multiple feeds (River of News).</div>
<a href="#river_stories"><code>/reader/river_stories</code></a>
</li>
<li>
<div class="NB-api-link-desc">Mark a story as read.</div>
<a href="#mark_story_as_read"><code>/reader/mark_story_as_read</code></a>
</li>
<li>
<div class="NB-api-link-desc">Mark a story as starred (saved).</div>
<a href="#mark_story_as_starred"><code>/reader/mark_story_as_starred</code></a>
</li>
<li>
<div class="NB-api-link-desc">Mark all stories in a feed as read.</div>
<a href="#mark_feed_as_read"><code>/reader/mark_feed_as_read</code></a>
</li>
<li>
<div class="NB-api-link-desc">Mark all stories from all feeds as read.</div>
<a href="#mark_all_as_read"><code>/reader/mark_all_as_read</code></a>
</li>
</ul>
<div class="NB-api-toc-header">Feed Management</div>
<ul class="NB-api-toc">
<li>
<div class="NB-api-link-desc">Add a feed by its URL (RSS feed or website).</div>
<a href="#add_url"><code>/reader/add_url</code></a>
</li>
<li>
<div class="NB-api-link-desc">Add a folder.</div>
<a href="#add_folder"><code>/reader/add_folder</code></a>
</li>
<li>
<div class="NB-api-link-desc">Rename a feed title.</div>
<a href="#rename_feed"><code>/reader/rename_feed</code></a>
</li>
<li>
<div class="NB-api-link-desc">Unsubscribe from a feed.</div>
<a href="#delete_feed"><code>/reader/delete_feed</code></a>
</li>
<li>
<div class="NB-api-link-desc">Rename a folder.</div>
<a href="#rename_folder"><code>/reader/rename_folder</code></a>
</li>
<li>
<div class="NB-api-link-desc">Delete a folder and unsubscribe from all feeds inside.</div>
<a href="#delete_folder"><code>/reader/delete_folder</code></a>
</li>
<li>
<div class="NB-api-link-desc">Original page from a single feed.</div>
<a href="#mark_feed_as_read"><code>/reader/mark_feed_as_read</code></a>
</li>
<li>
<div class="NB-api-link-desc">Reorder feeds and move them around between folders.</div>
<a href="#save_feed_order"><code>/reader/save_feed_order</code></a>
</li>
</ul>
<div class="NB-api-toc-header">Import/Export</div>
<ul class="NB-api-toc">
<li>
<div class="NB-api-link-desc">Upload OPML file.</div>
<a href="#opml_upload"><code>/import/opml_upload</code></a>
</li>
<li>
<div class="NB-api-link-desc">Download backup of feeds as an OPML file.</div>
<a href="#opml_export"><code>/import/opml_export</code></a>
</li>
</ul>
{% for group in data %}{% for group_name, endpoints in group.items %}
<div class="NB-api-toc-header">{{ group_name }}</div>
<ul class="NB-api-toc">
{% for endpoint in endpoints %}
<li>
<div class="NB-api-link-desc">{{ endpoint.short_desc }}</div>
<a href="#{{ endpoint.url }}">{{ endpoint.method }} <code>{{ endpoint.url }}</code></a>
</li>
{% endfor %}
</ul>
{% endfor %}{% endfor %}
</div>
</div>
</div>
<div class="NB-module">
<h5 class="NB-module-title">Feeds</h5>
<div class="NB-module-content">
{% for group in data %}{% for group_name, endpoints in group.items %}
<div class="NB-module">
<h5 class="NB-module-title">{{ group_name }}</h5>
<div class="NB-module-content">
<div class="NB-api-endpoint">
<h3><tt>GET /reader/feeds</tt></h3>
<a class="NB-anchor" name="feeds"></a>
{% for endpoint in endpoints %}
<div class="NB-api-endpoint">
<h3><tt>{{ endpoint.method }} {{ endpoint.url }}</tt></h3>
<a class="NB-anchor" name="{{ endpoint.url }}"></a>
<ul>
<li>Retrieve a user's list of feeds. Includes the 3 unread counts (positive, neutral,
negative), as well as optional favicons.</li>
</ul>
{% if endpoint.long_desc %}
<ul>
{% for desc in endpoint.long_desc %}
<li>{{ desc|safe }}</li>
{% endfor %}
</ul>
{% endif %}
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
<tr>
<td>include_favicons</td>
<td><span class="optional">Optional</span> Include
favicons inline. Since they can be time consuming to download, you can optionally
turn them off. Use <tt>/api/v1/feeds/favicons/</tt> to retrieve the favicons in a
separate request.</td>
<td><code>true</code></td>
<td><code>true/false</code></td>
</tr>
<tr>
<td>flat</td>
<td><span class="optional">Optional</span> Returns a flat folder structure instead of nested folders. Useful when displaying all folders in a single depth without recursive descent.</td>
<td><code>false</code></td>
<td><code>true/false</code></td>
</tr>
</table>
<h4>Example Response</h4>
<pre><code>
{
'feeds': []
}
</code></pre>
<h4>Tips</h4>
<ul>
<li>Use <code>/reader/refresh_feeds</code> to get updated unread counts.</li>
<li>Turn off <code>include_favicons</code> if you can either cache favicons or can
wait to fetch them.</li>
</ul>
{% if endpoint.params %}
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
{% for param in endpoint.params %}
<tr>
<td>{{ param.key }}</td>
<td class="NB-api-endpoint-param-desc">
{% if param.optional %}
<span class="optional">Optional</span>
{% else %}{% if param.required %}
<span class="required">Required</span>
{% endif %}{% endif %}
{{ param.desc|safe }}
</td>
<td>{% if param.default %}<code>{{ param.default }}</code>{% endif %}</td>
<td><code>{{ param.example }}</code></td>
</tr>
{% endfor %}
</table>
{% endif %}
{# <h4>Example Response</h4> #}
{# <pre><code> #}
{# { #}
{# 'feeds': [] #}
{# } #}
{# </code></pre> #}
{% if endpoint.tips %}
<h4>Tips</h4>
<ul>
{% for tip in endpoint.tips %}
<li>{{ tip|safe }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
</div>
<div class="NB-api-endpoint">
<h3><tt>GET /reader/favicons</tt></h3>
<a class="NB-anchor" name="favicons"> </a>
<ul>
<li>Retrieve a list of favicons for a list of feeds. Used when combined with
<tt>/reader/feeds</tt> and <tt>include_favicons=false</tt>, so the
feeds request contains far less data. Useful for mobile devices, but requires a
second request.</li>
</ul>
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
<tr>
<td>feeds</td>
<td><span class="optional">OPTIONAL</span> Array of feed ids. Leave empty to retrieve all active (enabled) feeds.</td>
<td></td>
<td><code>[1, 2, 3]</code></td>
</tr>
</table>
<h4>Example Response</h4>
<pre><code>
{
'feeds': []
}
</code></pre>
<h4>Tips</h4>
<ul>
<li>To use inline data images, you can use this syntax:
<pre><code>
&lt;img src="data:image/png;base64,[IMAGE_DATA_STRING]" /&gt;
</code></pre>
</li>
</ul>
</div>
<div class="NB-api-endpoint">
<h3><tt>GET /reader/page/:id</tt></h3>
<a class="NB-anchor" name="feed_page"> </a>
<ul>
<li>Retrieve the original page from a single feed.</li>
</ul>
<h4>Example Response</h4>
<pre><code>
{# <html> #}
{# <head> #}
{# <base href="http://www.newsblur.com" /> #}
{# <title>Proxied Page</title> #}
{# </head> #}
{# <body> #}
{# <p>This is a proxied page. This is straight HTML.</p> #}
{# </body> #}
{# </html> #}
</code></pre>
</div>
<div class="NB-api-endpoint">
<h3><tt>GET /reader/refresh_feeds</tt></h3>
<a class="NB-anchor" name="refresh_feeds"> </a>
<ul>
<li>Up-to-the-second unread counts for each active feed.</li>
<li>Poll for these counts no more than once a minute.</li>
</ul>
<h4>Example Response</h4>
<pre><code>
{
'feeds': []
}
</code></pre>
</div>
</div>
</div>
{# =========== #}
{# = Stories = #}
{# =========== #}
<div class="NB-module">
<h5 class="NB-module-title">Stories</h5>
<div class="NB-module-content">
<div class="NB-api-endpoint">
<h3><tt>GET /reader/feed/:id</tt></h3>
<a class="NB-anchor" name="feed"> </a>
<ul>
<li>Retrieve stories from a single feed.</li>
</ul>
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
<tr>
<td>page</td>
<td><span class="optional">optional</span> Page of stories, starting from 1.</td>
<td><code>1</code></td>
<td><code>2</code></td>
</tr>
</table>
<h4>Example Response</h4>
<pre><code>
{
'feeds': []
}
</code></pre>
</div>
<div class="NB-api-endpoint">
<h3><tt>GET /reader/starred_stories</tt></h3>
<a class="NB-anchor" name="starred_stories"></a>
<ul>
<li>Retrieve a user's starred stories.</li>
</ul>
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
<tr>
<td>page</td>
<td><span class="optional">optional</span> Page of starred stories, starting from 1.</td>
<td><code>1</code></td>
<td><code>2</code></td>
</tr>
</table>
<h4>Example Response</h4>
<pre><code>
{
'feeds': []
}
</code></pre>
</div>
<div class="NB-api-endpoint">
<h3><tt>GET /reader/river_stories</tt></h3>
<a class="NB-anchor" name="river_stories"> </a>
<ul>
<li>Retrieve stories from a collection of feeds. This is known as the River of News.</li>
<li>Stories are ordered in reverse chronological order.</li>
</ul>
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
<tr>
<td>feeds</td>
<td><span class="required">required</span> List of feed ids.</td>
<td></td>
<td><code>[12, 24, 36]</code></td>
</tr>
<tr>
<td>page</td>
<td><span class="optional">optional</span> Page of stories, starting from 1.</td>
<td><code>1</code></td>
<td><code>2</code></td>
</tr>
</table>
<h4>Example Response</h4>
<pre><code>
{
'feeds': []
}
</code></pre>
</div>
</div>
</div>
{# ================ #}
{# = Intelligence = #}
{# ================ #}
<div class="NB-module">
<h5 class="NB-module-title">Intelligence</h5>
<div class="NB-module-content">
<div class="NB-api-endpoint">
</div>
</div>
</div>
{% endfor %}{% endfor %}
{# ===================== #}
{# = Terms of Services = #}

View file

@ -94,14 +94,21 @@
method: 'GET'
short_desc: "Stories from multiple feeds (River of News)."
long_desc:
- ""
tips:
- ''
- "Retrieve stories from a collection of feeds. This is known as the River of News."
- "Stories are ordered in reverse chronological order."
params:
- key: 'feeds'
desc: "Feed ids to use in the river. Usually every feed in a folder with unread stories."
required: true
example: "[12, 24, 36]"
- key: 'page'
desc: "Page of stories, starting from 1."
optional: true
example: "2"
- key: 'read_stories_count'
desc: "An optimization used to skip a set number of stories that are guaranteed to be read. Pass in the number of stories that have been read from this series. If your page >= 2, you should probably have some read stories from the first page."
optional: true
example: "12"
- url: '/reader/mark_story_as_read'
method: 'POST'
@ -261,12 +268,13 @@
example: "[1, 2, 3]"
- "import/export":
- url: '/import/opml_upload'
method: 'POST'
short_desc: "Upload OPML file."
- "intelligence classifiers":
- url: '/get/publisher'
method: 'GET'
short_desc: "Get the intelligence classifiers for a user's site."
long_desc:
- ""
- "Get the intelligence classifiers for a user's site."
- "Includes both popular classifiers and the user's own classifiers."
tips:
- ''
params:
@ -275,9 +283,50 @@
optional: true
example: "[1, 2, 3]"
- url: '/save/publisher'
method: 'POST'
short_desc: "Save intelligence classifiers for a feed."
long_desc:
- "Save intelligence classifiers (tags, titles, authors, and the feed) for a feed."
tips:
- ''
params:
- key: ''
desc: ""
optional: true
example: "[1, 2, 3]"
- url: '/save/story'
method: 'POST'
short_desc: "Save intelligence classifiers from a specific story."
long_desc:
- "Save intelligence classifiers (tags, titles, authors, and the feed) from a specific story."
tips:
- ''
params:
- key: ''
desc: ""
optional: true
example: "[1, 2, 3]"
- "import/export":
- url: '/import/opml_export'
method: 'GET'
short_desc: "Download backup of feeds as an OPML file."
long_desc:
- ""
tips:
- ''
params:
- key: ''
desc: ""
optional: true
example: "[1, 2, 3]"
- url: '/import/opml_upload'
method: 'POST'
short_desc: "Upload OPML file."
long_desc:
- ""
tips:

View file

@ -1,148 +0,0 @@
{% extends 'base.html' %}
{% block bodyclass %}NB-static NB-static-api{% endblock %}
{% block title %}The NewsBlur API{% endblock %}
{% block content %}
<div class="NB-static-title">
The NewsBlur API
</div>
<div class="NB-module">
<h5 class="NB-module-title">Introduction to the API</h5>
<div class="NB-module-content">
<p><a href="/">NewsBlur</a> is an RSS feed reader with intelligence.</p>
<p>NewsBlur's API allows users to retrieve their feeds, feed counts, feed icons, feed
statistics, and individual feed stories. No API key is required, but you are required
to authenticate before using any of the API endpoints. Please be considerate, and don't
hammer our servers.</p>
<p>It is a very nice thing to note that this entire API is open-source, including
the implementation of the endpoints. You can find the source of the
<a href="http://github.com/samuelclay/NewsBlur/tree/master/apps/reader/views.py">/reader/ views</a>,
<a href="http://github.com/samuelclay/NewsBlur/tree/master/apps/rss_feeds/views.py">/rss_feeds/ views</a>,
as well as
<a href="http://github.com/samuelclay/NewsBlur/tree/master/templates/static/api.yml">the API definitions in YML</a>.</p>
</div>
</div>
{# ========= #}
{# = Feeds = #}
{# ========= #}
<div class="NB-module">
<h5 class="NB-module-title">API Table of Contents</h5>
<div class="NB-module-content">
<div class="NB-api-endpoint">
{% for group in data %}{% for group_name, endpoints in group.items %}
<div class="NB-api-toc-header">{{ group_name }}</div>
<ul class="NB-api-toc">
{% for endpoint in endpoints %}
<li>
<div class="NB-api-link-desc">{{ endpoint.short_desc }}</div>
<a href="#{{ endpoint.url }}">{{ endpoint.method }} <code>{{ endpoint.url }}</code></a>
</li>
{% endfor %}
</ul>
{% endfor %}{% endfor %}
</div>
</div>
</div>
{% for group in data %}{% for group_name, endpoints in group.items %}
<div class="NB-module">
<h5 class="NB-module-title">{{ group_name }}</h5>
<div class="NB-module-content">
{% for endpoint in endpoints %}
<div class="NB-api-endpoint">
<h3><tt>{{ endpoint.method }} {{ endpoint.url }}</tt></h3>
<a class="NB-anchor" name="{{ endpoint.url }}"></a>
{% if endpoint.long_desc %}
<ul>
{% for desc in endpoint.long_desc %}
<li>{{ desc|safe }}</li>
{% endfor %}
</ul>
{% endif %}
{% if endpoint.params %}
<table>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Default</th>
<th>Example</th>
</tr>
{% for param in endpoint.params %}
<tr>
<td>{{ param.key }}</td>
<td>
{% if param.optional %}
<span class="optional">Optional</span>
{% else %}{% if param.required %}
<span class="required">Required</span>
{% endif %}{% endif %}
{{ param.desc|safe }}
</td>
<td>{% if param.default %}<code>{{ param.default }}</code>{% endif %}</td>
<td><code>{{ param.example }}</code></td>
</tr>
{% endfor %}
</table>
{% endif %}
{# <h4>Example Response</h4> #}
{# <pre><code> #}
{# { #}
{# 'feeds': [] #}
{# } #}
{# </code></pre> #}
{% if endpoint.tips %}
<h4>Tips</h4>
<ul>
{% for tip in endpoint.tips %}
<li>{{ tip|safe }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endfor %}{% endfor %}
{# ===================== #}
{# = Terms of Services = #}
{# ===================== #}
<div class="NB-module">
<h5 class="NB-module-title">API Guidelines and Terms of Service</h5>
<div class="NB-module-content">
<p>NewsBlur's API allows users to retrieve their feeds, feed counts, feed icons, feed
statistics, and individual feed stories. No API key is required, but you are required
to authenticate before using any of the API endpoints. Please be considerate, and don't
hammer our servers.</p>
<p>If your project or application allows users to interact with data from NewsBlur,
you must cite NewsBlur as the source of your data.</p>
<p>You may use the API commercially, by which we mean you may charge people money to
use your project which itself uses the API. You may not, however, sell advertising
against any data retrieved from NewsBlur's API. Essentially, you can charge money for
your application or service, but not wrap NewsBlur in advertisements.</p>
<p><i>We reserve the right to revise these guidelines. If you violate the spirit of
these terms, expect to be blocked without advance warning.</i></p>
</div>
</div>
{% endblock content %}