[Rt-commit] [svn] r804 - in rt: . branches/rt-3.3/html/REST/2.0
branches/rt-3.3/html/REST/2.0/Elements
branches/rt-3.3/html/REST/2.0/Error
branches/rt-3.3/html/REST/2.0/Search
autrijus at pallas.eruditorum.org
autrijus at pallas.eruditorum.org
Sun May 2 11:58:17 EDT 2004
Author: autrijus
Date: Sun May 2 11:58:17 2004
New Revision: 804
Added:
rt/branches/rt-3.3/html/REST/2.0/Elements/Error
rt/branches/rt-3.3/html/REST/2.0/Elements/Introspect
Removed:
rt/branches/rt-3.3/html/REST/2.0/Error/
Modified:
rt/ (props changed)
rt/branches/rt-3.3/html/REST/2.0/Search/index
rt/branches/rt-3.3/html/REST/2.0/dhandler
rt/branches/rt-3.3/html/REST/2.0/index
Log:
----------------------------------------------------------------------
r4379 at not: autrijus | 2004-05-02T15:26:00.873038Z
* Do content negotiation with the browser and fallback on text/xml.
* Clean up namespaces a little.
----------------------------------------------------------------------
r4380 at not: autrijus | 2004-05-02T15:58:03.262688Z
* Move Error/index to Elements/Error since Error is not a verb.
* Refactor the Introspect part away to Elements/.
* Correctly redirects /Templates/ and /template/ to /templates/.
----------------------------------------------------------------------
Added: rt/branches/rt-3.3/html/REST/2.0/Elements/Error
==============================================================================
--- (empty file)
+++ rt/branches/rt-3.3/html/REST/2.0/Elements/Error Sun May 2 11:58:17 2004
@@ -0,0 +1,8 @@
+<%INIT>
+$r->content_type('text/html');
+$r->status($Status);
+$m->abort($Status) unless $ENV{FCGI_ROLE};
+</%INIT>
+<%ARGS>
+$Status => 500
+</%ARGS>
Added: rt/branches/rt-3.3/html/REST/2.0/Elements/Introspect
==============================================================================
--- (empty file)
+++ rt/branches/rt-3.3/html/REST/2.0/Elements/Introspect Sun May 2 11:58:17 2004
@@ -0,0 +1,50 @@
+<%INIT>
+my %collection_to_obj;
+my %collection_to_class;
+my %record_to_collection;
+foreach my $key (keys %INC) {
+ $key =~ m{^(RTx?(?:/.+)?/([^_/]+)).pm$}i or next;
+ my ($class, $type) = ($1, $2);
+ $class =~ s{/}{::}g;
+ $class->can('NewItem') or next;
+ my $obj = eval {$class->new($session{CurrentUser})->NewItem} or next;
+ $collection_to_obj{$type} = $obj;
+ $collection_to_class{$type} = $class;
+ $record_to_collection{$1} = $type if ref($obj) =~ /(\w+)$/;
+}
+
+my @collection = sort keys %collection_to_obj;
+my @record = (
+ map {($_, $_."Id")} (qw(Member PrincipalType Object),
+ sort keys %record_to_collection)
+);
+
+my %gone;
+foreach my $type (@collection) {
+ my $obj = $collection_to_obj{$type} or next;
+
+ # First, eliminate collections that can be inferred from other objects
+ foreach my $method (@collection) {
+ $gone{$method}++ if $obj->can($method) or $obj->can("_$method");
+ }
+
+ # Next, eliminate normalization records with multiple parent fields
+ my $score = 0;
+ foreach my $property (@record) {
+ $score++ if $obj->_Accessible($property, 'read');
+ }
+ $gone{$type}++ if $score > 1;
+}
+
+delete @collection_to_class{keys %gone};
+return {map {(lc($_) => $collection_to_class{$_})} keys %collection_to_class}
+ if $Want eq 'CollectionToClass';
+return {map {(lc($_) => $record_to_collection{$_})} keys %record_to_collection}
+ if $Want eq 'RecordToCollection';
+
+delete @collection_to_obj{keys %gone};
+return [sort keys %collection_to_obj];
+</%INIT>
+<%ARGS>
+$Want
+</%ARGS>
Modified: rt/branches/rt-3.3/html/REST/2.0/Search/index
==============================================================================
--- rt/branches/rt-3.3/html/REST/2.0/Search/index (original)
+++ rt/branches/rt-3.3/html/REST/2.0/Search/index Sun May 2 11:58:17 2004
@@ -20,12 +20,12 @@
% foreach my $entry (@entries) {
<entry>
<title mode="escaped"><% $entry->{Name} || "#$entry->{Id}" %></title>
+ <& $Link, Relation => "service.edit", URI => "$FeedURI/$entry->{Id}", Title => loc("Edit"). ": $entry->{Name}" &>
<summary mode="escaped"><% $entry->{Description} %></summary>
<modified><% $entry->{LastUpdated} %></modified>
<issued><% $entry->{Created} %></issued>
<created><% $entry->{Created} %></created>
<id><% $entry->{URI} %></id>
- <& $Link, Relation => "service.edit", URI => "$FeedURI/$entry->{Id}", Title => loc("Edit"). ": $entry->{Name}" &>
% if ($entry->{HTML_URL}) {
<& $Link, Type => 'text/html', URI => "$RT::WebURL$entry->{HTML_URL}", Title => $entry->{Name} &>
% }
Modified: rt/branches/rt-3.3/html/REST/2.0/dhandler
==============================================================================
--- rt/branches/rt-3.3/html/REST/2.0/dhandler (original)
+++ rt/branches/rt-3.3/html/REST/2.0/dhandler Sun May 2 11:58:17 2004
@@ -12,7 +12,9 @@
my $nonce = Digest::MD5::md5_hex($realm . rand());
my %methods = map {($_ => 1)} @RT::RESTAuthenticationMethods;
-my $atom_client = ($r->header_in('User-Agent') =~ /\batom\b/i);
+my %accept = map { $_ => 1 } $r->header_in('Accept') =~ m{([^\s,]+/[^;,]+)}g;
+my $atom_client = $accept{'application/x.atom+xml'};
+
my $header_out = sub {
$ENV{FCGI_ROLE} ? $r->header_out(@_) : $r->headers_out->add(@_);
};
@@ -126,25 +128,33 @@
}
if (!$CurrentUser or !$CurrentUser->Id) {
- return $m->comp('Error/index', Status => 401);
+ return $m->comp('Elements/Error', Status => 401);
}
$session{CurrentUser} = $CurrentUser;
-# TODO: Redirect /template to /templates
-
my $path = $m->dhandler_arg;
-my $type = lc($path);
+my $type = $path;
$type =~ s{/.*}{};
$type =~ s{-}{/};
-
-my $class;
-foreach my $key (keys %INC) {
- $key =~ m{^(RTx?(?:/.+)?/($type)).pm$}i or next;
- ($class, $type) = ($1, $2);
- $class =~ s{/}{::}g;
- $class->can('UnLimit') or (undef $class, next);
- last;
+if ($type ne lc($type)) {
+ $path =~ s{([^/]*)}{\L$type};
+ $r->header_out(Location => $path);
+ return $m->comp('Elements/Error', Status => 301);
+}
+
+my $map = $m->comp('Elements/Introspect', Want => 'CollectionToClass');
+my $class = $map->{$type};
+if ($class) {
+ $type = $1 if $class =~ m/([^:]+)$/;
+}
+else {
+ $map = $m->comp('Elements/Introspect', Want => 'RecordToCollection');
+ if (my $new_type = lc($map->{$type})) {
+ $path =~ s{([^/]*)}{$new_type};
+ $r->header_out(Location => $path);
+ return $m->comp('Elements/Error', Status => 301);
+ }
}
my $BaseURI = "$RT::WebPath/REST/2.0";
@@ -154,11 +164,23 @@
$ARGS{Now} = RT::Date->new($session{CurrentUser});
$ARGS{Now}->SetToNow;
-$r->content_type('text/xml; charset=utf-8');
+my @types = qw(
+ application/x.atom+xml
+ application/xhtml+xml
+ application/xml
+);
+my $content_type = 'text/xml'; # fallback
+foreach my $try_type (@types) {
+ $accept{$try_type} or next;
+ $content_type = $try_type;
+ last;
+}
+
+$r->content_type("$content_type; charset=utf-8");
if (!$class) {
return $m->comp('index', %ARGS) if $path =~ /index|^\W*$/i;
- return $m->comp('Error/index', Status => 404);
+ return $m->comp('Elements/Error', Status => 404);
}
$m->comp(
Modified: rt/branches/rt-3.3/html/REST/2.0/index
==============================================================================
--- rt/branches/rt-3.3/html/REST/2.0/index (original)
+++ rt/branches/rt-3.3/html/REST/2.0/index Sun May 2 11:58:17 2004
@@ -1,61 +1,20 @@
%# Put service links to all actions and objects here
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="<% $BaseURI %>/NoAuth/index.css"?>
-<feed version="0.3"
- xmlns="http://purl.org/atom/ns#"
- xmlns:html="http://www.w3.org/1999/xhtml"
->
+<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<title><&|/l&>Homepage</&></title>
<author>
<name><% $RT::Organization %></name>
<url><% $RT::WebURL %></url>
</author>
<& $Link, Type => 'text/html', URI => $RT::WebURL, Title => loc("Homepage") &>
-% foreach my $type (sort @types) {
+% foreach my $type (@{$m->comp('Elements/Introspect', Want => 'TopLevelCollections')}) {
<& $Link, Relation => 'service.feed', URI => "$BaseURI/\L$type", Title => loc($type) &>
<& $Link, Relation => 'service.post', URI => "$BaseURI/\L$type.new", Title => loc("Create") . ": " . loc($type) &>
% }
<modified><% $Now->W3CDTF %></modified>
<generator url="http://www.bestpractical.com/rt/" version="<% $RT::VERSION %>">RT</generator>
</feed>
-<%INIT>
-my %collection_to_obj;
-my %record_to_collection;
-foreach my $key (keys %INC) {
- $key =~ m{^(RTx?(?:/.+)?/([^_/]+)).pm$}i or next;
- my ($class, $type) = ($1, $2);
- $class =~ s{/}{::}g;
- $class->can('NewItem') or next;
- my $obj = eval {$class->new($session{CurrentUser})->NewItem} or next;
- $collection_to_obj{$type} = $obj;
- $record_to_collection{$1} = $type if ref($obj) =~ /(\w+)$/;
-}
-
-my @collection = sort keys %collection_to_obj;
-my @record = (
- map {($_, $_."Id")} (qw(Member PrincipalType Object),
- sort keys %record_to_collection)
-);
-
-my %gone;
-foreach my $type (@collection) {
- my $obj = $collection_to_obj{$type} or next;
-
- # First, eliminate collections that can be inferred from other objects
- foreach my $method (@collection) {
- $gone{$method}++ if $obj->can($method) or $obj->can("_$method");
- }
-
- # Next, eliminate normalization records with multiple parent fields
- my $score = 0;
- foreach my $property (@record) {
- $score++ if $obj->_Accessible($property, 'read');
- }
- $gone{$type}++ if $score > 1;
-}
-
-my @types = sort grep !$gone{$_}, keys %collection_to_obj;
-</%INIT>
<%ARGS>
$Path
$BaseURI
More information about the Rt-commit
mailing list