mirror of
https://github.com/TracksApp/tracks.git
synced 2025-09-22 05:50:47 +02:00
Added documentation for REST API.
git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@674 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
413fcb4db7
commit
ac5590f923
5 changed files with 254 additions and 7 deletions
|
@ -4,6 +4,10 @@ class IntegrationsController < ApplicationController
|
|||
@page_title = 'TRACKS::Integrations'
|
||||
end
|
||||
|
||||
def rest_api
|
||||
@page_title = 'TRACKS::REST API Documentation'
|
||||
end
|
||||
|
||||
def get_quicksilver_applescript
|
||||
context = current_user.contexts.find params[:context_id]
|
||||
render :partial => 'quicksilver_applescript', :locals => { :context => context }
|
||||
|
|
|
@ -116,6 +116,7 @@ class TodosController < ApplicationController
|
|||
end
|
||||
render
|
||||
end
|
||||
format.xml { render :xml => @todo.to_xml( :except => :user_id ) }
|
||||
format.html do
|
||||
if @saved
|
||||
# TODO: I think this will work, but can't figure out how to test it
|
||||
|
@ -132,6 +133,10 @@ class TodosController < ApplicationController
|
|||
def toggle_star
|
||||
@todo.toggle_star!
|
||||
@saved = @todo.save!
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.xml { render :xml => @todo.to_xml( :except => :user_id ) }
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
|
@ -189,6 +194,7 @@ class TodosController < ApplicationController
|
|||
determine_down_count
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.xml { render :xml => @todo.to_xml( :except => :user_id ) }
|
||||
format.m do
|
||||
if @saved
|
||||
redirect_to formatted_todos_path(:m)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<h1>Integrations</h1>
|
||||
<p>Tracks can be integrated with a number of other tools... whatever it takes to help you get things done! This page has information on setting up some of these. Not all of these are applicable to all platforms, and some require more technical knowledge than others.</p>
|
||||
<p>Tracks can be integrated with a number of other tools... whatever it takes to help you get things done! This page has information on setting up some of these. Not all of these are applicable to all platforms, and some require more technical knowledge than others. See also <%= link_to "developer documentation for Tracks' REST API", url_for(:action => 'rest_api') %>.</p>
|
||||
<p>Contents:
|
||||
<ol>
|
||||
<li><a href="#applescript1-section">Add an Action with Applescript</a></li>
|
||||
<li><a href="#applescript2-section">Add an Action with Applescript based on the currently selected Email in Mail.app</a></li>
|
||||
<li><a href="#quicksilver-applescript-section">Add Actions with Quicksilver and Applescript</a></li>
|
||||
<li><a href="#email-cron-section">Automatically Email Yourself Upcoming Actions</a></li>
|
||||
<ol>
|
||||
<li><a href="#applescript1-section">Add an Action with Applescript</a></li>
|
||||
<li><a href="#applescript2-section">Add an Action with Applescript based on the currently selected Email in Mail.app</a></li>
|
||||
<li><a href="#quicksilver-applescript-section">Add Actions with Quicksilver and Applescript</a></li>
|
||||
<li><a href="#email-cron-section">Automatically Email Yourself Upcoming Actions</a></li>
|
||||
</ol><br />
|
||||
</p>
|
||||
<p>Do you have one of your own to add? <a href="http://www.rousette.org.uk/projects/forums/viewforum/10/" title="Tracks | Tips and Tricks">Tell us about it in our Tips and Tricks forum
|
||||
|
@ -16,7 +16,7 @@
|
|||
<p>This is a simple script that pops up a dialog box asking for a description, and then sends that to Tracks with a hard-coded context.</p>
|
||||
|
||||
<ol>
|
||||
<li>Choose the context you want to add actions to: <select name="applescript1-contexts" id="applescript1-contexts"><%= options_from_collection_for_select(current_user.contexts, "id", "name", current_user.contexts.first.id) %></select>
|
||||
<li>Choose the context you want to add actions to: <select name="applescript1-contexts" id="applescript1-contexts"><%= options_from_collection_for_select(current_user.contexts, "id", "name", current_user.contexts.first.id) %></select>
|
||||
<%= observe_field "applescript1-contexts", :update => "applescript1",
|
||||
:with => 'context_id',
|
||||
:url => { :controller => "integrations", :action => "get_applescript1" },
|
||||
|
|
218
tracks/app/views/integrations/rest_api.rhtml
Normal file
218
tracks/app/views/integrations/rest_api.rhtml
Normal file
|
@ -0,0 +1,218 @@
|
|||
<h1>REST API Documentation for Developers</h1>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>Tracks is designed to be integrated with scripts, web services, and third-party applications. This page serves as the documentation of our REST API.</p>
|
||||
|
||||
<h2>Tracks REST API</h2>
|
||||
|
||||
<p>The Tracks REST API allows developers to integrate Tracks into their applications. It allows applications to access and modify Tracks data, and is implemented as Vanilla XML over HTTP.</p>
|
||||
|
||||
<p>The API is a <a href="http://en.wikipedia.org/wiki/REST">RESTful</a> service. All data is available through the API as a resource to which can be referred using a unique identifier. It responds to a number of the HTTP methods, specifically GET, PUT, POST and UPDATE, and all responses from the API are in a simple XML format encoded as UTF-8.</p>
|
||||
|
||||
<h2>Authentication</h2>
|
||||
|
||||
<p>Authentication is handled using <a href="http://en.wikipedia.org/wiki/Basic_authentication">Basic HTTP authentication</a>. Your Tracks username and password is used as the authentication credentials for the API. Note that in Basic HTTP authentication, your password is sent in clear text. If you need a more secure authentication solution, you should configure your web server to run Tracks under HTTPS.</p>
|
||||
|
||||
<h2>Retrieving data from the API</h2>
|
||||
|
||||
<p>To retrieve data you only need to do an HTTP GET on a resource identifier. For example, if you want to get all the contexts with <a href="http://en.wikipedia.org/wiki/CURL">cURL</a>:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd \
|
||||
<%= home_url %>contexts.xml
|
||||
>> <?xml version="1.0" encoding="UTF-8"?>
|
||||
<contexts>...</contexts>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>Getting a single context:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd \
|
||||
<%= home_url %>contexts/51.xml
|
||||
>> <?xml version="1.0" encoding="UTF-8"?>
|
||||
<context>...</context>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>Getting the todos within a context:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd \
|
||||
<%= home_url %>contexts/51/todos.xml
|
||||
>> <?xml version="1.0" encoding="UTF-8"?>
|
||||
<todos type="array">...</todos>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>You also can apply the pattern shown above with projects instead of contexts.</p>
|
||||
|
||||
<p>All data is available according to the following resource paths:</p>
|
||||
|
||||
<ul>
|
||||
<li>/todos.xml</li>
|
||||
<li>/todos/<code>ID</code>.xml</li>
|
||||
<li>/contexts.xml</li>
|
||||
<li>/contexts/<code>ID</code>.xml</li>
|
||||
<li>/contexts/<code>ID</code>/todos.xml</li>
|
||||
<li>/projects.xml</li>
|
||||
<li>/projects/<code>ID</code>.xml</li>
|
||||
<li>/projects/<code>ID</code>/todos.xml</li>
|
||||
</ul>
|
||||
|
||||
<h2>Writing to the API</h2>
|
||||
|
||||
<p>The API provides mechanisms for adding, updating and deleting resources using the HTTP methods <code>PUT</code>, <code>POST</code> and <code>DELETE</code> in combination with the content.</p>
|
||||
|
||||
<p>Creating a new project, using curl:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd \
|
||||
-d "project[name]=Build a treehouse for the kids" \
|
||||
<%= home_url %>projects.xml -i
|
||||
>> HTTP/1.1 201 Created
|
||||
Location: <%= home_url %>projects/65.xml
|
||||
...
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>The response is an <code>HTTP/1.1 201 Created</code> with <code>Location</code> header indicating where the new project resource can be found. Now we can add a todo to this project, using curl:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd \
|
||||
-d "todo[description]=Model treehouse in SketchUp&todo[context_id]=2&todo[project_id]=65" \
|
||||
<%= home_url %>todos.xml -i
|
||||
>> HTTP/1.1 201 Created
|
||||
Location: <%= home_url %>todos/452.xml
|
||||
...
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>The response is a again an <code>HTTP/1.1 201 Created</code> with <code>Location</code> header indicating where the new todo resource can be found. Changing the todo notes, again using curl:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd -X PUT \
|
||||
-d "todo[notes]=use maple texture" \
|
||||
<%= home_url %>todos/452.xml -i
|
||||
>> HTTP/1.1 200 OK
|
||||
...
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<todo>
|
||||
...
|
||||
<description>Model treehouse in SketchUp</description>
|
||||
|
||||
<notes>use maple texture</notes>
|
||||
...
|
||||
</todo>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>The response is an <code>HTTP/1.1 200 OK</code> with in the body the XML representation of the updated todo. We provide a shorcut method to toggle a todo done or undone without having to perform the update with the right field values:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd -X PUT \
|
||||
<%= home_url %>todos/452/toggle_check.xml -i
|
||||
>> HTTP/1.1 200 OK
|
||||
...
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<todo>
|
||||
...
|
||||
<completed-at type=\"datetime\">2007-12-05T06:43:25Z</completed-at>
|
||||
|
||||
<state>completed</state>
|
||||
...
|
||||
</todo>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
|
||||
<p>If we want to delete that todo we can call its unique resource identifier (the URL) with the HTTP method <code>DELETE</code>, again with curl:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd -X DELETE \
|
||||
<%= home_url %>todos/452.xml -i
|
||||
>> HTTP/1.1 200 OK
|
||||
...
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>The API returns an <code>HTTP/1.1 200 OK</code> and the todo is now deleted.</p>
|
||||
|
||||
|
||||
<h2>Dealing with the response and response status</h2>
|
||||
|
||||
|
||||
<p>All successful operations respond with a status code of <code>200 OK</code> or <code>201 Created</code> depending on the operation. Sometimes a list, say <code>GET /contexts/2/todos.xml</code> will not have any items, it will return an empty list.</p>
|
||||
|
||||
<p>The XML for empty list responses look like this, again with curl:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd \
|
||||
<%= home_url %>contexts/2/todos.xml
|
||||
>> <?xml version="1.0" encoding="UTF-8"?>
|
||||
<nil-classes type="array"/>
|
||||
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h2>Consuming the API with ActiveResource</h2>
|
||||
|
||||
<p><a href="http://weblog.rubyonrails.org/2007/9/30/rails-2-0-0-preview-release">ActiveResource</a> is a thin but powerful wrapper around RESTful services exposed by <a href="http://www.rubyonrails.org">Ruby on Rails</a>. It will be part of Rails 2.0 but until then you can get it with <code>gem install activeresource --source http://gems.rubyonrails.org --include-dependencies</code>.</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ script/console
|
||||
Loading development environment (Rails 1.2.4)
|
||||
>> class Context < ActiveResource::Base; end
|
||||
=> nil
|
||||
>> Context.site = "<%= home_url %>"
|
||||
=> "<%= home_url %>"
|
||||
>> Context.site.user = "username"
|
||||
=> "username"
|
||||
|
||||
>> Context.site.password = CGI.escape "p4ssw0rd"
|
||||
=> "p4ssw0rd"
|
||||
>> Context.find :first
|
||||
=> #<Context:0x262396c @prefix_options={}, @attributes={...}>
|
||||
>> >> Context.find :all
|
||||
=> [#<Context:0x274cfc8 @prefix_options={}, @attributes={...}, ...]
|
||||
</code>
|
||||
|
||||
</pre>
|
||||
|
||||
<p>Inspired by <a href="http://www.37signals.com">37 Signals</a> ’s Highrise wrapper, we’ve put together a small ruby wrapper (find it in the doc/ directory) for the API which sets up the ActiveResource models for you to play with in an IRB session:</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
$ SITE="http://username:p4ssw0rd@<%= @request.host_with_port %>" irb \
|
||||
-r tracks_api_wrapper.rb
|
||||
|
||||
irb(main):001:0> inbox = Tracks::Context.find :first
|
||||
irb(main):002:0> inbox.name
|
||||
=> "@inbox"
|
||||
irb(main):003:0>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h3>Notes about the documentation</h3>
|
||||
|
||||
<p>A few conventions have been applied in the documentation, these are:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>ID</code>’s in a resource <span class="caps">URL</span> indicate that the resource’s unique ID needs to be inserted there</li>
|
||||
<li><code>...</code> indicates that unimportant bits of response data have been removed to eliminate noise from the documentation</li>
|
||||
</ul>
|
||||
|
||||
<p>All examples make use of <a href="http://en.wikipedia.org/wiki/CURL">cURL</a> .</p></div>
|
|
@ -12,6 +12,25 @@ require 'activeresource'
|
|||
# => "my pc"
|
||||
# >> my_pc.todos
|
||||
# => [#<Tracks::Todo:0x1e16b84 @prefix_options={}, @attributes={"context_id"=>8, "completed_at"=>Tue Apr 10 12:57:24 UTC 2007, "project_id"=>nil, "show_from"=>nil, "id"=>1432, "notes"=>nil, "description"=>"check rhino mocks bug", "due"=>Mon, 09 Apr 2007, "created_at"=>Sun Apr 08 04:56:35 UTC 2007, "state"=>"completed"}, #<Tracks::Todo:0x1e16b70 @prefix_options={}, @attributes={"context_id"=>8, "completed_at"=>Mon Oct 10 13:10:21 UTC 2005, "project_id"=>10, "show_from"=>nil, "id"=>17, "notes"=>"fusion problem", "description"=>"Fix Client Installer", "due"=>nil, "created_at"=>Sat Oct 08 00:19:33 UTC 2005, "state"=>"completed"}]
|
||||
#
|
||||
# >> t = Tracks::Todo.new
|
||||
# => #<Tracks::Todo:0x1ee9fc0 @prefix_options={}, @attributes={}>
|
||||
# >> t.description = "do it now"
|
||||
# => "do it now"
|
||||
# >> t.context_id = 8
|
||||
# => 8
|
||||
# >> t.save
|
||||
# => true
|
||||
# >> t.reload
|
||||
# => #<Tracks::Todo:0x1ee9fc0 @prefix_options={}, @attributes={"completed_at"=>nil, "context_id"=>8, "project_id"=>nil, "show_from"=>nil, "notes"=>nil, "id"=>1791, "description"=>"do it now", "due"=>nil, "created_at"=>Mon Dec 03 19:15:46 UTC 2007, "state"=>"active"}
|
||||
# >> t.put(:toggle_check)
|
||||
# => #<Net::HTTPOK 200 OK readbody=true>
|
||||
# >> t.reload
|
||||
# => #<Tracks::Todo:0x1ee9fc0 @prefix_options={}, @attributes={"completed_at"=>Mon Dec 03 19:17:46 UTC 2007, "context_id"=>8, "project_id"=>nil, "show_from"=>nil, "notes"=>nil, "id"=>1791, "description"=>"do it now", "due"=>nil, "created_at"=>Mon Dec 03 19:15:46 UTC 2007, "state"=>"completed"}
|
||||
|
||||
# If you want to see the HTTP requests and responses that are being passed back and
|
||||
# forth, you can tweak your active_resource like as described in:
|
||||
# http://blog.pepperdust.org/2007/2/13/enabling-wire-level-debug-output-for-activeresource
|
||||
|
||||
module Tracks
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue