[Rt-commit] [svn] r844 - in RTx-Atom: . html/Atom/0.3 html/Atom/0.3/NoAuth lib/RTx

autrijus at pallas.eruditorum.org autrijus at pallas.eruditorum.org
Thu May 6 07:39:06 EDT 2004


Author: autrijus
Date: Thu May  6 07:39:05 2004
New Revision: 844

Added:
   RTx-Atom/html/Atom/0.3/NoAuth/pod.css
Removed:
   RTx-Atom/html/Atom/0.3/NoAuth/valid-atom.png
Modified:
   RTx-Atom/   (props changed)
   RTx-Atom/html/Atom/0.3/NoAuth/feed.css
   RTx-Atom/html/Atom/0.3/NoAuth/spec.html
   RTx-Atom/html/Atom/0.3/index
   RTx-Atom/lib/RTx/Atom.pm
Log:
 ----------------------------------------------------------------------
 r4521 at not:  autrijus | 2004-05-06T11:38:52.079021Z
 
 * reworked the spec display.
 ----------------------------------------------------------------------


Modified: RTx-Atom/html/Atom/0.3/NoAuth/feed.css
==============================================================================
--- RTx-Atom/html/Atom/0.3/NoAuth/feed.css	(original)
+++ RTx-Atom/html/Atom/0.3/NoAuth/feed.css	Thu May  6 07:39:05 2004
@@ -119,3 +119,10 @@
 name {
   font-weight: bold;
 }
+
+a.poweredby {
+  font-weight: bold;
+  text-decoration: underline;
+  border: 2px ridge #9999ff;
+  background:#aaaaff;
+}

Added: RTx-Atom/html/Atom/0.3/NoAuth/pod.css
==============================================================================
--- (empty file)
+++ RTx-Atom/html/Atom/0.3/NoAuth/pod.css	Thu May  6 07:39:05 2004
@@ -0,0 +1,365 @@
+BODY, .logo { background: white; }
+
+BODY {
+  color: black;
+  font-family: arial,sans-serif;
+  margin: 0;
+  padding: 1ex;
+}
+
+TABLE {
+  border-collapse: collapse;
+  border-spacing: 0;
+  border-width: 0;
+  color: inherit;
+}
+
+IMG { border: 0; }
+FORM { margin: 0; }
+input { margin: 2px; }
+
+.logo {
+  float: left;
+  width: 264px;
+  height: 77px;
+}
+
+.front .logo  {
+  float: none;
+  display:block;
+}
+
+.front .searchbox  {
+  margin: 2ex auto;
+  text-align: center;
+}
+
+.front .menubar {
+  text-align: center;
+}
+
+.menubar {
+  background: #006699;
+  margin: 1ex 0;
+  padding: 1px;
+} 
+
+.menubar A {
+  padding: 0.8ex;
+  font: bold 10pt Arial,Helvetica,sans-serif;
+}
+
+.menubar A:link, .menubar A:visited {
+  color: white;
+  text-decoration: none;
+}
+
+.menubar A:hover {
+  color: #ff6600;
+  text-decoration: underline;
+}
+
+A:link, A:visited {
+  background: transparent;
+  color: #006699;
+}
+
+A[href="#POD_ERRORS"] {
+  background: transparent;
+  color: #FF0000;
+}
+
+TD {
+  margin: 0;
+  padding: 0;
+}
+
+DIV {
+  border-width: 0;
+}
+
+DT {
+  margin-top: 1em;
+}
+
+.credits TD {
+  padding: 0.5ex 2ex;
+}
+
+.huge {
+  font-size: 32pt;
+}
+
+.s {
+  background: #dddddd;
+  color: inherit;
+}
+
+.s TD, .r TD {
+  padding: 0.2ex 1ex;
+  vertical-align: baseline;
+}
+
+TH {
+  background: #bbbbbb;
+  color: inherit;
+  padding: 0.4ex 1ex;
+  text-align: left;
+}
+
+TH A:link, TH A:visited {
+  background: transparent;
+  color: black;
+}
+
+.box {
+  border: 1px solid #006699;
+  margin: 1ex 0;
+  padding: 0;
+}
+
+.distfiles TD {
+  padding: 0 2ex 0 0;
+  vertical-align: baseline;
+}
+
+.manifest TD {
+  padding: 0 1ex;
+  vertical-align: top;
+}
+
+.l1 {
+  font-weight: bold;
+}
+
+.l2 {
+  font-weight: normal;
+}
+
+.t1, .t2, .t3, .t4  {
+  background: #006699;
+  color: white;
+}
+.t4 {
+  padding: 0.2ex 0.4ex;
+}
+.t1, .t2, .t3  {
+  padding: 0.5ex 1ex;
+}
+
+/* IE does not support  .box>.t1  Grrr */
+.box .t1, .box .t2, .box .t3 {
+  margin: 0;
+}
+
+.t1 {
+  font-size: 1.4em;
+  font-weight: bold;
+  text-align: center;
+}
+
+.t2 {
+  font-size: 1.0em;
+  font-weight: bold;
+  text-align: left;
+}
+
+.t3 {
+  font-size: 1.0em;
+  font-weight: normal;
+  text-align: left;
+}
+
+/* width: 100%; border: 0.1px solid #FFFFFF; */ /* NN4 hack */
+
+.datecell {
+  text-align: center;
+  width: 17em;
+}
+
+.cell {
+  padding: 0.2ex 1ex;
+  text-align: left;
+}
+
+.label {
+  background: #aaaaaa;
+  color: black;
+  font-weight: bold;
+  padding: 0.2ex 1ex;
+  text-align: right;
+  white-space: nowrap;
+  vertical-align: baseline;
+}
+
+.categories {
+  border-bottom: 3px double #006699;
+  margin-bottom: 1ex;
+  padding-bottom: 1ex;
+}
+
+.categories TABLE {
+  margin: auto;
+}
+
+.categories TD {
+  padding: 0.5ex 1ex;
+  vertical-align: baseline;
+}
+
+.path A {
+  background: transparent;
+  color: #006699;
+  font-weight: bold;
+}
+
+.pages {
+  background: #dddddd;
+  color: #006699;
+  padding: 0.2ex 0.4ex;
+}
+
+.path {
+  background: #dddddd;
+  border-bottom: 1px solid #006699;
+  color: #006699;
+ /*  font-size: 1.4em;*/
+  margin: 1ex 0;
+  padding: 0.5ex 1ex;
+}
+
+.menubar TD {
+  background: #006699;
+  color: white;
+}
+
+.menubar {
+  background: #006699;
+  color: white;
+  margin: 1ex 0;
+  padding: 1px;
+}
+
+.menubar .links     {
+  background: transparent;
+  color: white;
+  padding: 0.2ex;
+  text-align: left;
+}
+
+.menubar .searchbar {
+  background: black;
+  color: black;
+  margin: 0px;
+  padding: 2px;
+  text-align: right;
+}
+
+A.m:link, A.m:visited {
+  background: #006699;
+  color: white;
+  font: bold 10pt Arial,Helvetica,sans-serif;
+  text-decoration: none;
+}
+
+A.o:link, A.o:visited {
+  background: #006699;
+  color: #ccffcc;
+  font: bold 10pt Arial,Helvetica,sans-serif;
+  text-decoration: none;
+}
+
+A.o:hover {
+  background: transparent;
+  color: #ff6600;
+  text-decoration: underline;
+}
+
+A.m:hover {
+  background: transparent;
+  color: #ff6600;
+  text-decoration: underline;
+}
+
+table.dlsip     {
+  background: #dddddd;
+  border: 0.4ex solid #dddddd;
+}
+
+PRE     {
+  background: #eeeeee;
+  border: 1px solid #888888;
+  color: black;
+  padding: 1em;
+  white-space: pre;
+}
+
+H1      {
+  background: transparent;
+  color: #006699;
+  font-size: large;
+}
+
+H2      {
+  background: transparent;
+  color: #006699;
+  font-size: medium;
+}
+
+IMG     {
+  vertical-align: top;
+}
+
+.toc A  {
+  text-decoration: none;
+}
+
+.toc LI {
+  line-height: 1.2em;
+  list-style-type: none;
+}
+
+.faq DT {
+  font-size: 1.4em;
+  font-weight: bold;
+}
+
+.chmenu {
+  background: black;
+  color: red;
+  font: bold 1.1em Arial,Helvetica,sans-serif;
+  margin: 1ex auto;
+  padding: 0.5ex;
+}
+
+.chmenu TD {
+  padding: 0.2ex 1ex;
+}
+
+.chmenu A:link, .chmenu A:visited  {
+  background: transparent;
+  color: white;
+  text-decoration: none;
+}
+
+.chmenu A:hover {
+  background: transparent;
+  color: #ff6600;
+  text-decoration: underline;
+}
+
+.column {
+  padding: 0.5ex 1ex;
+  vertical-align: top;
+}
+
+.datebar {
+  margin: auto;
+  width: 14em;
+}
+
+.date {
+  background: transparent;
+  color: #008000;
+}
+

Modified: RTx-Atom/html/Atom/0.3/NoAuth/spec.html
==============================================================================
--- RTx-Atom/html/Atom/0.3/NoAuth/spec.html	(original)
+++ RTx-Atom/html/Atom/0.3/NoAuth/spec.html	Thu May  6 07:39:05 2004
@@ -10,6 +10,7 @@
     "--infile=$INC{'RTx/Atom.pm'}",
     "--outfile=$filename",
     "--cachedir=" . File::Spec->tmpdir,
+    "--css=pod.css",
 );
 
 seek $fh, 0, 0;

Modified: RTx-Atom/html/Atom/0.3/index
==============================================================================
--- RTx-Atom/html/Atom/0.3/index	(original)
+++ RTx-Atom/html/Atom/0.3/index	Thu May  6 07:39:05 2004
@@ -16,7 +16,7 @@
   <entry>
     <title><% loc($type) %></title>
     <& $ShowLink, Relation => "service.feed", URI => "$BaseURI/$class?", Title => $type, IsChild => 1 &>
-    <& $ShowLink, Relation => 'service.post', URI => "$BaseURI/$class!add", Title => $type &>
+    <& $ShowLink, Relation => 'service.post', URI => "$BaseURI/$class!add", Id => "$type!add", Title => $type &>
     <& $ShowLink, Type => "text/html", URI => $BaseURI, Title => $type &>
     <id><% $RT::SystemUser->UserObj->URI %>/<% $class %></id>
     <issued><% $RT::SystemUser->UserObj->CreatedObj->W3CDTF %></issued>
@@ -24,7 +24,7 @@
   </entry>
 % }
   <info></info>
-  <html:a href="<% $BaseURI %>/NoAuth/spec.html" title="The RT-Atom Specification"><html:img type="image/png" src="<% $BaseURI %>/NoAuth/valid-atom.png" alt="Valid Atom"></html:img></html:a>
+  <html:a class="poweredby" href="<% $BaseURI %>/NoAuth/spec.html" title="The RT-Atom Specification"><&|/l&>Powered by RT-Atom</&></html:a>
 </feed>
 <%ARGS>
 $Path

Modified: RTx-Atom/lib/RTx/Atom.pm
==============================================================================
--- RTx-Atom/lib/RTx/Atom.pm	(original)
+++ RTx-Atom/lib/RTx/Atom.pm	Thu May  6 07:39:05 2004
@@ -1,3 +1,4 @@
+# vim: expandtab shiftwidth=4
 package RTx::Atom;
 
 $RTx::Atom::VERSION = '0.01';
@@ -6,64 +7,41 @@
 
 =head1 NAME
 
-RTx::Atom - Atom API for RT
+RTx::Atom - The RT-Atom API
 
 =head1 DESCRIPTION
 
-This RT extension implements a XML-based web service interface, based on
-the B<Atom draft specification>, version 0.3.
+This RT extension implements a REST-style web service interface, based
+on the B<Atom draft specification>, version 0.3.
 
-If you have never heard of Atom,
-L<http://www.atomenabled.org/developers/tutorials/api-quick-guide.php>
-offers a concise introduction.
-
-Please see
-L<http://www.atomenabled.org/developers/api/atom-api-spec.php>
-for definitions of I<FeedURI>, I<EditURI> and I<PostURI> as used in this
-documentation.
-
-The I<AtomFeed> and I<AtomEntry> formats are defined in
-L<http://www.atomenabled.org/developers/syndication/atom-format-spec.php>.
-
-The authentication algorithm is describe in
-L<http://www.xml.com/pub/a/2003/12/17/dive.html>
-with one important exception -- that article assumes the shared
-password between client and server is in plaintext, but RT-Atom
-uses this instead:
-
-    md5_hex(join(':', $username, $realm, md5_hex($password)));
-
-Request methods and response status codes are specified in
-L<http://www.w3.org/Protocols/rfc2616/rfc2616.html>.
-
-=head1 EXAMPLES
+For more information on Atom and REST, please consult the references
+in the L</SEE ALSO> section.
 
 =head2 The RT-Atom URI space
 
-XXX - Describe the principle of odd/even depth, verbs and adverbs here.
-
 Some example canonical URIs are:
 
-    /Atom/0.3					# FeedURI
-    /Atom/0.3/RT-Tickets			# FeedURI
-    /Atom/0.3/RT-Tickets!add			# PostURI (Container)
-    /Atom/0.3/RT-Tickets/15			# EditURI (Object)
-    /Atom/0.3/RT-Tickets/15.Subject		# EditURI (Property)
-    /Atom/0.3/RT-Tickets/15!update		# PostURI (Object)
-    /Atom/0.3/RT-Tickets/15!comment		# PostURI (Object)
-    /Atom/0.3/RT-Tickets/15!correspond		# PostURI (Object)
-    /Atom/0.3/RT-Tickets/15,16,17!update	# PostURI (ResultSet)
-    /Atom/0.3/RT-Tickets/15/Transactions	# FeedURI
-
-RT-Atom also supplies alias URIs.  Whenever an user request the URI,
-it is redirected to the canonical URL with a I<301 Moved Permanently>
-status code.  Here are some example aliases:
-
-    /Atom			# /Atom/0.3
-    /Atom/0.3/tickets		# /Atom/0.3/RT-Tickets
-    /Atom/0.3/Tickets		# /Atom/0.3/RT-Tickets
-    /Atom/0.3/Ticket/15		# /Atom/0.3/RT-Tickets/15
-    /Atom/0.3/Users/somename	# /Atom/0.3/Users/1234
+    /Atom/0.3                                   # FeedURI
+    /Atom/0.3/RT-Tickets                        # FeedURI
+    /Atom/0.3/RT-Tickets!add                    # PostURI (Container)
+    /Atom/0.3/RT-Tickets/15                     # EditURI (Object)
+    /Atom/0.3/RT-Tickets/15.Subject             # EditURI (Property)
+    /Atom/0.3/RT-Tickets/15!update              # PostURI (Object)
+    /Atom/0.3/RT-Tickets/15!comment             # PostURI (Object)
+    /Atom/0.3/RT-Tickets/15!correspond          # PostURI (Object)
+    /Atom/0.3/RT-Tickets/15,16,17!update        # PostURI (ResultSet)
+    /Atom/0.3/RT-Tickets/15/Transactions        # FeedURI
+
+A RT-Atom server may also supplies alias URIs.  Whenever an user request the
+URI, it is redirected to the canonical URL with a I<301 Moved Permanently>.
+
+Here are some example aliases:
+
+    /Atom                       # /Atom/0.3
+    /Atom/0.3/tickets           # /Atom/0.3/RT-Tickets
+    /Atom/0.3/Tickets           # /Atom/0.3/RT-Tickets
+    /Atom/0.3/Ticket/15         # /Atom/0.3/RT-Tickets/15
+    /Atom/0.3/Users/somename    # /Atom/0.3/Users/1234
 
 =head2 Sample exchange
 
@@ -75,12 +53,12 @@
     my $rt = RT::Client->new('http://guest:guest@localhost/');
 
     my $user = $rt->Users->add(
-	Name => 'autrijus',
-	EmailAddress => 'autrijus at example.com',
+        Name => 'autrijus',
+        EmailAddress => 'autrijus at example.com',
     );
 
     $rt->Groups->search("HasMember='root'")->update(
-	Members => { add => $user },
+        Members => { add => $user },
     );
 
 And now the actual requests and responses.  Note that C<GET> may
@@ -89,72 +67,110 @@
     HEAD /Atom/0.3
     Accept: application/x.atom+xml,*/*
 
-	401 Authorization Required
-	WWW-Authenticate: WSSE realm="localhost", profile="UsernameToken"
+        401 Authorization Required
+        WWW-Authenticate: WSSE realm="localhost", profile="UsernameToken"
 
     OPTIONS /Atom/0.3/Users!add
     X-WSSE: UsernameToken Username="guest", ...
 
-	200 OK
-	<entry>
-	  <content type="text/xml" mode="xml">
-	    <head Name="" EmailAddress="" ...>
-	      ...
-	    </head>
-	  </content>
+        200 OK
+        <entry>
+          <content type="text/xml" mode="xml">
+            <body Name=""
+                  EmailAddress=""
+                  ...>
+              ...
+            </body>
+          </content>
         </entry>
 
     POST /Atom/0.3/Users!add
     Name=autrijus&EmailAddress=autrijus at example.com
 
-	303 See Other
-	Location: /Atom/0.3/RT-Users/20
+        303 See Other
+        Location: /Atom/0.3/RT-Users/20
 
     GET /Atom/0.3/RT-Users/20
 
-	200 OK
-	<entry>
-	  <content type="text/xml" mode="xml">
-	    <head Name="autrijus" EmailAddress="autrijus at example.com" ...>
-	      ...
-	    </head>
-	  </content>
+        200 OK
+        <entry>
+          <content type="text/xml" mode="xml">
+            <body Name="autrijus"
+                  EmailAddress="autrijus at example.com"
+                  ...>
+              ...
+            </body>
+          </content>
         </entry>
 
     HEAD /Atom/0.3/Groups?query=HasMember%3D'root'&rows=all
 
-	200 OK
-	Content-Location: /Atom/0.3/RT-Groups/1,2,3,5,8,13
+        200 OK
+        Content-Location: /Atom/0.3/RT-Groups/1,2,3,5,8,13
 
     OPTIONS /Atom/0.3/RT-Groups/1,2,3,5,8,13
 
-	200 OK
-	<entry>
-	  <link rel="service.post" href="/Atom/0.3/RT-Groups/1,2,3,5,8,13!update" title="update" />
+        200 OK
+        <entry>
+          <link rel="service.post"
+                href="/Atom/0.3/RT-Groups/1,2,3,5,8,13!update"
+                title="update" />
         </entry>
 
     OPTIONS /Atom/0.3/RT-Groups/1,2,3,5,8,13!update
 
-	200 OK
-	<entry>
-	  <content type="text/xml" mode="xml">
-	    <head ...>
-	      ...
-	      <Members add="Members-add" remove="Members-remove" />
-	    </head>
-	  </content>
+        200 OK
+        <entry>
+          <content type="text/xml" mode="xml">
+            <body ...>
+              ...
+              <Members add="Members-add"
+                       remove="Members-remove" />
+            </body>
+          </content>
         </entry>
 
     POST /Atom/0.3/RT-Groups/1,2,3,5,8,13!update
     Members-add=30
-	
-	207 Multiple Status
-	...<status><code>200</code><text>Member added</text>...
+        
+        207 Multiple Status
+        ...<status><code>200</code><text>Member added</text>...
+
+=head2 Authentication
+
+The authentication algorithm uses the C<WWW-Authenticate>,
+C<Authorization>, and C<X-WSSE> headers as specified in the Atom
+Authentication Protocol.
+
+However, instead of using plaintext as the shared password between
+client and server, RT-Atom uses this digest function:
+
+    md5_hex(join(':', $username, $realm, md5_hex($password)));
+
+The RT server may choose to support other authentication methods, such
+as C<Basic> or C<Digest>.
+
+=head2 Content Negotiation
+
+The server understands C<Accept>, C<Accept-Charset>, C<Accept-Language>
+and C<X-RT-CurrentUser> headers.
+
+# XXX
+
+=head1 RESOURCE TYPES
+
+=head2 Container
+
+=head2 Object
+
+=head2 Property
+
+=head2 ResultSet
 
 =head1 OPERATIONS
 
-Here is a list of all operative I<verbs> supported by this API,
-including their possible response status codes and meanings:
+Here is a list of all operations supported by this API, including their
+possible response status codes and meanings:
 
 =head2 Search - I<GET FeedURI>
 
@@ -206,7 +222,7 @@
 On a container's PostURI, returns the schema of objects acceptable by this
 container.
 
-On an object's PostURI, returns the schema acceptable by the specified I<adverb>.
+On an object's PostURI, returns the schema acceptable by the specified I<verb>.
 
 On I<EditURI>, returns the schema of the object or the property, which is a
 I<GET> without actual contents.
@@ -231,13 +247,13 @@
 
 =head2 Update - I<POST PostURI> (Object)
 
-Updates an object, using an I<adverb> acceptable to that object's class.
+Updates an object, using an I<verb> acceptable to that object's class.
 
     207: Updated.  Body is the status code and messages for each update.
     400: Request failed.  Body is the error message.
-    404: The specific object is not found, or supports no such adverb.
+    404: The specific object is not found, or supports no such verb.
 
-=head1 LINK AUTO-DISCOVERY
+=head1 LINK DISCOVERY
 
 Methods, object membership and properties are all discovered via the
 C<link> tag inside I<AtomFeed> and I<AtomEntry> constructs.
@@ -250,17 +266,81 @@
 Whenever the client receives an Atom construct, it may look at each
 C<link> tag.  The C<title> attribute determines the type of link:
 
-    Prefixed with '_': back reference, eg. C<_up>.
-    Prefixed with '!': an operation, eg. C<!add>.
-    Otherwise: A member, eg. C<Tickets>.
+    ( MemberName )? ( "!" Verb )?  ( "_" backreference )? 
 
 The C<href> attribute is the target URI.  The C<rel> attribute determines
 the type of the link target:
 
-    "service.feed": a Container.
-    "service.edit": an Object or Property.
-    "service.post": an operation supported by the object that shares the same
-                    'title'.  If no such object is found, this operation
-		    applies to the object itself.
+=over 4
+
+=item service.feed
+
+A Container.
+
+=item service.edit
+
+An Object or Property.
+
+=item service.post
+
+An operation supported by the object that shares the same C<title>.
+If no such object is found, this operation applies to the object itself.
+
+=back
+
+For example, an object's Atom representation may have the following links:
+
+    <link title="Groups"
+          rel="service.feed"
+          href="/Atom/0.3/RT-Groups" />
+    <link title="Groups!add"
+          rel="service.post"
+          href="/Atom/0.3/RT-Groups!add" />
+
+The client may then infer the relationships:
+
+=over 4
+
+=item $obj has a member named I<Groups>.
+
+=item $obj->Groups is a I<Container>.
+
+=item $obj->Groups understands the verb I<add>.
+
+=item $obj->Groups->add( key => 'value' ) should be translated to:
+
+    POST /Atom/0.3/RT-Groups!add
+    key=value
+
+=back
+
+=cut
+
+=head1 SEE ALSO
+
+Atom Tutorial:
+L<http://www.atomenabled.org/developers/tutorials/api-quick-guide.php>
+
+Atom API Specification (definitions of I<FeedURI>, I<EditURI> and
+I<PostURI>): L<http://www.atomenabled.org/developers/api/atom-api-spec.php>
+
+Atom Format Specification (definitions of I<AtomFeed> and I<AtomEntry>):
+L<http://www.atomenabled.org/developers/syndication/atom-format-spec.php>
+
+Atom Authentication Protocol:
+L<http://www.xml.com/pub/a/2003/12/17/dive.html>
+
+HTTP 1.1 Status codes:
+L<http://www.w3.org/Protocols/rfc2616/rfc2616.html>.
+
+Paul Prescod's REST resources: L<http://www.prescod.net/rest/>
+
+The Atom Wiki: L<http://www.intertwingly.net/wiki/pie/FrontPage>
+
+The REST Wiki: L<http://internet.conveyor.com/RESTwiki/moin.cgi/FrontPage>
+
+=head1 AUTHORS
+
+Autrijus Tang E<lt>autrijus at autrijus.orgE<gt>
 
 =cut


More information about the Rt-commit mailing list