[Rt-commit] rt branch, 4.2/rest-search-refactor, created. rt-4.0.1-235-g70014ea

? sunnavy sunnavy at bestpractical.com
Thu Jun 23 04:03:58 EDT 2011


The branch, 4.2/rest-search-refactor has been created
        at  70014eab50519325698b0043654fa0ad20da0b67 (commit)

- Log -----------------------------------------------------------------
commit 97868186d976e87bcb6424bb9f82ece1741dcf36
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 12:02:13 2011 +0800

    refactor the orderby code: old code uses eval and is weird

diff --git a/share/html/REST/1.0/search/ticket b/share/html/REST/1.0/search/ticket
index 77160b3..ca82a73 100755
--- a/share/html/REST/1.0/search/ticket
+++ b/share/html/REST/1.0/search/ticket
@@ -88,24 +88,6 @@ my ($n, $s);
 eval {
     ($n, $s) = $tickets->FromSQL($query);
 };
-my $sortstring = "";
-if ($orderby) {
-    $sortstring = 'FIELD => ';
-    my $order = substr($orderby, 0, 1);
-    if ($order eq '+' || $order eq '-') {
-	$sortstring .= 'substr($orderby, 1)';
-	if ($order eq '+') {
-	    $sortstring .= ", ORDER => 'ASC'";
-	} elsif ($order eq '-') {
-	    $sortstring .= ", ORDER => 'DESC'";
-	}
-    } else {
-	$sortstring .= '$orderby';
-    }
-    my $foo = 'FIELD => ';
-    $foo .= '$orderby';
-    $tickets->OrderBy(eval $sortstring);
-}
 if ($@ || $n == 0) {
     $s ||= $@;
     $status = "400 Bad request";
@@ -113,6 +95,12 @@ if ($@ || $n == 0) {
     goto OUTPUT;
 }
 
+if ($orderby) {
+    my ($order, $field) = $orderby =~ /^([\+\-])?(.+)/;
+    $order = $order && $order eq '-' ? 'DESC' : 'ASC';
+    $tickets->OrderBy( FIELD => $field, ORDER => $order );
+}
+
 $n = 0;
 my @output;
 while (my $ticket = $tickets->Next) {

commit 5e4f1419bd5fc00bf7cafcbbdca23cd07c4305ed
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 12:56:28 2011 +0800

    prepare to support restful searches for queues, users and groups

diff --git a/bin/rt.in b/bin/rt.in
index 3bb5a37..625928d 100755
--- a/bin/rt.in
+++ b/bin/rt.in
@@ -327,32 +327,53 @@ sub list {
         $data{orderby} =~ s/^\+?(.*)/-$1/;
     }
 
-    if (!defined $q) {
-        $q = $config{query}; 
+    $type ||= "ticket";
+
+    if (!defined $q ) {
+        if ( $type eq 'ticket' ) {
+            $q = $config{query};
+        }
+        else {
+            $q = '';
+        }
     }
-    
-    $q =~ s/^#//; # get rid of leading hash
-    if ($q =~ /^\d+$/) {
-        # only digits, must be an id, formulate a correct query
-        $q = "id=$q" if $q =~ /^\d+$/;
-    } else {
-        # a string only, take it as an owner or requestor (quoting done later)
-        $q = "(Owner=$q or Requestor like $q) and $config{query}"
-             if $q =~ /^[\w\-]+$/;
-        # always add a query for a specific queue or (comma separated) queues
-        $queue =~ s/,/ or Queue=/g if $queue;
-        $q .= " and (Queue=$queue)" if $queue and $q and $q !~ /Queue\s*=/i
-            and $q !~ /id\s*=/i;
+
+    if ( $type ne 'ticket' ) {
+        $rawprint = 1;
     }
-    # correctly quote strings in a query
-    $q =~ s/(=|like\s)\s*([^'\d\s]\S*)\b/$1\'$2\'/g;
 
-    $type ||= "ticket";
-    unless ($type && defined $q) {
+    unless (defined $q) {
         my $item = $type ? "query string" : "object type";
         whine "No $item specified.";
         $bad = 1;
     }
+
+    $q =~ s/^#//; # get rid of leading hash
+    if ( $type eq 'ticket' ) {
+        if ( $q =~ /^\d+$/ ) {
+
+            # only digits, must be an id, formulate a correct query
+            $q = "id=$q" if $q =~ /^\d+$/;
+        }
+        else {
+
+          # a string only, take it as an owner or requestor (quoting done later)
+            $q = "(Owner=$q or Requestor like $q) and $config{query}"
+              if $q =~ /^[\w\-]+$/;
+
+           # always add a query for a specific queue or (comma separated) queues
+            $queue =~ s/,/ or Queue=/g if $queue;
+            $q .= " and (Queue=$queue)"
+              if $queue
+                  and $q
+                  and $q !~ /Queue\s*=/i
+                  and $q !~ /id\s*=/i;
+        }
+
+        # correctly quote strings in a query
+        $q =~ s/(=|like\s)\s*([^'\d\s]\S*)\b/$1\'$2\'/g;
+    }
+
     #return help("list", $type) if $bad;
     return suggest_help("list", $type, $bad) if $bad;
 
@@ -2164,13 +2185,14 @@ Text:
     Displays a list of objects matching the specified conditions.
     ("ls", "list", and "search" are synonyms.)
 
-    Conditions are expressed in the SQL-like syntax used internally by
-    RT. (For more information, see "rt help query".) The query string
-    must be supplied as one argument.
+    The query string must be supplied as one argument.
+
+    if on tickets, query is in the SQL-like syntax used internally by
+    RT. (For more information, see "rt help query".), otherwise, query
+    is plain string with format "FIELD OP VALUE", e.g. "Name = General".
 
-    (Right now, the server doesn't support listing anything but tickets.
-    Other types will be supported in future; this client will be able to
-    take advantage of that support without any changes.)
+    if query string is absent, we limit to privileged ones on users and
+    user defined ones on groups automatically.
 
     Options:
 
@@ -2201,6 +2223,9 @@ Text:
         rt ls -t ticket "Subject like '[PATCH]%'"
         rt ls -q systems
         rt ls -f owner,subject
+        rt ls -t queue 'Name = General'
+        rt ls -t user 'EmailAddress like foo at bar.com'
+        rt ls -t group 'Name like foo'
 
 --
 

commit b45e7e85cef3d307660ee1b25e067f01cb1479b5
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 13:19:30 2011 +0800

    restful search support for queues/users/groups

diff --git a/share/html/REST/1.0/Forms/group/default b/share/html/REST/1.0/Forms/group/default
index 13f589b..63fb119 100644
--- a/share/html/REST/1.0/Forms/group/default
+++ b/share/html/REST/1.0/Forms/group/default
@@ -58,7 +58,17 @@ my @comments;
 my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $group = RT::Group->new($session{CurrentUser});
-my @fields = qw(Name Description);
+
+my @fields;
+if ( $fields && %$fields ) {
+    @fields =
+      grep { exists $fields->{ lc $_ } }
+      qw(Name Description);
+}
+else {
+    @fields = qw(Name Description);
+}
+
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
@@ -109,31 +119,33 @@ if (%data == 0) {
     my @data;
 
     push @data, [ id => "group/".$group->Id ];
-    push @data, [ Name => $group->Name ];
-    push @data, [ Description => $group->Description ];
-
+    foreach my $key (@fields) {
+        push @data, [ $key => $group->$key ];
+    }
 
     # Members
-    my $gms = [];
-    my $GroupMembers = $group->MembersObj();
-    while ( my $mo = $GroupMembers->Next() ) {
-        if ( $mo->MemberObj->IsGroup ) {
-            my $us = $mo->MemberObj->Object->UserMembersObj();
-            my @users;
-            while ( my $u = $us->Next() ) {
-                push @users, $u->RealName . ' <' . $u->EmailAddress . '>';
+    unless ( $fields && !exists $fields->{members} ) {
+        my $gms = [];
+        my $GroupMembers = $group->MembersObj();
+        while ( my $mo = $GroupMembers->Next() ) {
+            if ( $mo->MemberObj->IsGroup ) {
+                my $us = $mo->MemberObj->Object->UserMembersObj();
+                my @users;
+                while ( my $u = $us->Next() ) {
+                    push @users, $u->RealName . ' <' . $u->EmailAddress . '>';
+                }
+                push @$gms,
+                    'GROUP ['
+                    . $mo->MemberObj->Object->Name . ']' . ' ('
+                    . join( ';', @users ) . ')';
+            } elsif ( $mo->MemberObj->IsUser ) {
+                push @$gms,
+                    $mo->MemberObj->Object->RealName . ' <'
+                    . $mo->MemberObj->Object->EmailAddress . '>';
             }
-            push @$gms,
-                'GROUP ['
-                . $mo->MemberObj->Object->Name . ']' . ' ('
-                . join( ';', @users ) . ')';
-        } elsif ( $mo->MemberObj->IsUser ) {
-            push @$gms,
-                $mo->MemberObj->Object->RealName . ' <'
-                . $mo->MemberObj->Object->EmailAddress . '>';
         }
+        push @data, [ Members => $gms ];
     }
-    push @data, [ Members => $gms ];
 
     # Custom fields
     my $CustomFields = $group->CustomFields;
diff --git a/share/html/REST/1.0/Forms/queue/default b/share/html/REST/1.0/Forms/queue/default
index 9fcd8b9..c651687 100755
--- a/share/html/REST/1.0/Forms/queue/default
+++ b/share/html/REST/1.0/Forms/queue/default
@@ -58,8 +58,17 @@ my @comments;
 my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $queue = RT::Queue->new($session{CurrentUser});
-my @fields = qw(Name Description CorrespondAddress CommentAddress
+
+my @fields;
+if ( $fields && %$fields ) {
+    @fields =
+      grep { exists $fields->{ lc $_ } }
+      qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn);
+}
+else {
+    @fields = qw(Name Description CorrespondAddress CommentAddress
                 InitialPriority FinalPriority DefaultDueIn);
+}
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
diff --git a/share/html/REST/1.0/Forms/user/default b/share/html/REST/1.0/Forms/user/default
index 997555a..2f5e6ab 100755
--- a/share/html/REST/1.0/Forms/user/default
+++ b/share/html/REST/1.0/Forms/user/default
@@ -51,17 +51,33 @@
 $id
 $format => 's'
 $changes => {}
+$fields => undef
 </%ARGS>
 <%perl>
 my @comments;
 my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $user = RT::User->new($session{CurrentUser});
-my @fields = qw(RealName NickName Gecos Organization Address1 Address2 City
-                State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
-                FreeformContactInfo Comments Signature Lang EmailEncoding
-                WebEncoding ExternalContactInfoId ContactInfoSystem
-                ExternalAuthId AuthSystem Privileged Disabled);
+
+my @fields;
+if ( $fields && %$fields ) {
+    @fields =
+      grep { exists $fields->{ lc $_ } }
+      qw(Name EmailAddress RealName NickName Gecos Organization Address1
+      Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+      FreeformContactInfo Comments Signature Lang EmailEncoding
+      WebEncoding ExternalContactInfoId ContactInfoSystem
+      ExternalAuthId AuthSystem Privileged Disabled);
+}
+else {
+    @fields =
+      qw(Name EmailAddress RealName NickName Gecos Organization Address1
+      Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+      FreeformContactInfo Comments Signature Lang EmailEncoding
+      WebEncoding ExternalContactInfoId ContactInfoSystem
+      ExternalAuthId AuthSystem Privileged Disabled);
+}
+
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
@@ -117,14 +133,17 @@ if (keys %data == 0) {
     my @data;
 
     push @data, [ id => "user/".$user->Id ];
-    push @data, [ Name => $user->Name ];
-    push @data, [ Password => '********' ];
-    push @data, [ EmailAddress => $user->EmailAddress ];
 
-    foreach my $key (@fields) {
-        my $val = $user->$key;
+    unless ( $fields && %$fields && !exists $fields->{'password'} ) {
+        push @data, [ Password => '********' ];
+    }
 
-        if ( (defined ($format) && $format eq 'l') || (defined $val && $val ne '')) {
+    for my $key (@fields) {
+        my $val = $user->$key;
+        if (   ( $fields && exists $fields->{ lc $key } )
+            || ( defined $format && $format eq 'l' )
+            || ( defined $val && $val ne '' ) )
+        {
             $key = "ContactInfo" if $key eq 'FreeformContactInfo';
             push @data, [ $key => $val ];
         }
diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 70b7999..905ce95 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -47,10 +47,153 @@
 %# END BPS TAGGED BLOCK }}}
 %# REST/1.0/search/dhandler
 %#
+<%ARGS>
+$query
+$format => undef
+$orderby => undef
+$fields => undef
+</%ARGS>
 <%INIT>
-my $status = "500 Server Error";
-my $output = "Unsupported object type.";
-</%INIT>
-RT/<% $RT::VERSION %> <% $status %>
+my $type = $m->dhandler_arg;
+my ( $status, $output );
+
+if ( $type =~ /^(queue|user|group)$/i ) {
+    $status = "200 Ok";
+    $output = '';
+    my $type = lc $1;
+    my $class = 'RT::' . ucfirst $type . 's';
+    my $objects = $class->new( $session{CurrentUser} );
+
+    # Parse and validate any field specifications.
+    require RT::Interface::REST;
+    my $field = RT::Interface::REST->field_spec;
+    my ( %fields, @fields );
+    if ($fields) {
+        $format ||= "l";
+        unless ( $fields =~ /^(?:$field,)*$field$/ ) {
+            $status = "400 Bad Request";
+            $output = "Invalid field specification: $fields";
+            goto OUTPUT;
+        }
+        @fields = map lc, split /\s*,\s*/, $fields;
+        @fields{@fields} = ();
+        unless ( exists $fields{id} ) {
+            unshift @fields, "id";
+            $fields{id} = ();
+        }
+    }
+
+    $format ||= "s";
+    if ( $format !~ /^[isl]$/ ) {
+        $status = "400 Bad request";
+        $output = "Unknown listing format: $format. (Use i, s, or l.)\n";
+        goto OUTPUT;
+    }
+
+    if ($orderby) {
+        my ( $order, $field ) = $orderby =~ /^([\+\-])?(.+)/;
+        $order = $order && $order eq '-' ? 'DESC' : 'ASC';
+        $objects->OrderBy( FIELD => $field, ORDER => $order );
+    }
+
+    my ( $n, $s );
+    $n = 0;
+    my @output;
+
+    if ( defined $query && length $query ) {
+        require Text::ParseWords;
+        my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
+        if ( $op !~ /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i ) {
+            $status = "400 Bad Request";
+            $output = "Invalid operator specification: $op";
+            goto OUTPUT;
+        }
 
-<% $output |n %>
+        if ( $field && $op && defined $value ) {
+            $objects->Limit(
+                FIELD    => $field,
+                OPERATOR => uc $op,
+                VALUE    => $value
+            );
+        }
+        else {
+            $output = "Invalid query specification: $query";
+            goto OUTPUT;
+        }
+    }
+    else {
+        if ( $type eq 'queue' ) {
+            $objects->UnLimit;
+        }
+        elsif ( $type eq 'group' ) {
+            $objects->LimitToUserDefinedGroups;
+        }
+        elsif ( $type eq 'user' ) {
+            $objects->LimitToPrivileged;
+        }
+    }
+
+    while ( my $object = $objects->Next ) {
+        $n++;
+
+        my $id = $object->Id;
+        if ( $format eq "i" ) {
+            $output .= "$type/" . $id . "\n";
+        }
+        elsif ( $format eq "s" ) {
+            if ($fields) {
+                my $result = $m->comp(
+                    "/REST/1.0/Forms/$type/default",
+                    id     => $id,
+                    format => $format,
+                    fields => \%fields
+                );
+                my ( $notes, $order, $key_values, $errors ) = @$result;
+
+                # If it's the first time through, add our header
+                if ( $n == 1 ) {
+                    $output .= join( "\t", @$order ) . "\n";
+                }
+
+                # Cut off the annoying $type/ before the id;
+                $key_values->{'id'} = $id;
+                $output .= join(
+                    "\t",
+                    map {
+                        ref $key_values->{$_} eq 'ARRAY'
+                          ? join( ', ', @{ $key_values->{$_} } )
+                          : $key_values->{$_}
+                      } @$order
+                ) . "\n";
+            }
+            else {
+                $output .= $object->Id . ": " . $object->Name . "\n";
+            }
+        }
+        else {
+            my $d = $m->comp(
+                "/REST/1.0/Forms/$type/default",
+                id     => $id,
+                format => $format,
+                fields => \%fields
+            );
+            my ( $c, $o, $k, $e ) = @$d;
+            push @output, [ $c, $o, $k ];
+        }
+    }
+    if ( $n == 0 && $format ne "i" ) {
+        $output = "No matching results.\n";
+    }
+
+    $output = form_compose( \@output ) if @output;
+}
+else {
+    $status = "500 Server Error";
+    $output = "Unsupported object type.";
+    goto OUTPUT;
+}
+
+OUTPUT:
+$m->out("RT/". $RT::VERSION . " " . $status ."\n\n");
+$m->out($output );
+</%INIT>

commit 70014eab50519325698b0043654fa0ad20da0b67
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 15:11:53 2011 +0800

    merge restful ticket search to dhandler to avoid replicated code

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 905ce95..7b128e7 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -57,7 +57,7 @@ $fields => undef
 my $type = $m->dhandler_arg;
 my ( $status, $output );
 
-if ( $type =~ /^(queue|user|group)$/i ) {
+if ( $type =~ /^(ticket|queue|user|group)$/i ) {
     $status = "200 Ok";
     $output = '';
     my $type = lc $1;
@@ -90,35 +90,43 @@ if ( $type =~ /^(queue|user|group)$/i ) {
         goto OUTPUT;
     }
 
-    if ($orderby) {
-        my ( $order, $field ) = $orderby =~ /^([\+\-])?(.+)/;
-        $order = $order && $order eq '-' ? 'DESC' : 'ASC';
-        $objects->OrderBy( FIELD => $field, ORDER => $order );
-    }
-
     my ( $n, $s );
     $n = 0;
     my @output;
 
     if ( defined $query && length $query ) {
-        require Text::ParseWords;
-        my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
-        if ( $op !~ /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i ) {
-            $status = "400 Bad Request";
-            $output = "Invalid operator specification: $op";
-            goto OUTPUT;
-        }
-
-        if ( $field && $op && defined $value ) {
-            $objects->Limit(
-                FIELD    => $field,
-                OPERATOR => uc $op,
-                VALUE    => $value
-            );
+        if ( $type eq 'ticket' ) {
+            my ( $n, $s );
+            eval { ( $n, $s ) = $objects->FromSQL($query); };
+            if ( $@ || $n == 0 ) {
+                $s ||= $@;
+                $status = "400 Bad request";
+                $output = "Invalid query: '$s'.\n";
+                goto OUTPUT;
+            }
         }
         else {
-            $output = "Invalid query specification: $query";
-            goto OUTPUT;
+            require Text::ParseWords;
+            my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
+            if ( $op !~
+                /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i )
+            {
+                $status = "400 Bad Request";
+                $output = "Invalid operator specification: $op";
+                goto OUTPUT;
+            }
+
+            if ( $field && $op && defined $value ) {
+                $objects->Limit(
+                    FIELD    => $field,
+                    OPERATOR => uc $op,
+                    VALUE    => $value
+                );
+            }
+            else {
+                $output = "Invalid query specification: $query";
+                goto OUTPUT;
+            }
         }
     }
     else {
@@ -133,6 +141,12 @@ if ( $type =~ /^(queue|user|group)$/i ) {
         }
     }
 
+    if ($orderby) {
+        my ( $order, $field ) = $orderby =~ /^([\+\-])?(.+)/;
+        $order = $order && $order eq '-' ? 'DESC' : 'ASC';
+        $objects->OrderBy( FIELD => $field, ORDER => $order );
+    }
+
     while ( my $object = $objects->Next ) {
         $n++;
 
@@ -167,7 +181,12 @@ if ( $type =~ /^(queue|user|group)$/i ) {
                 ) . "\n";
             }
             else {
-                $output .= $object->Id . ": " . $object->Name . "\n";
+                if ( $type eq 'ticket' ) {
+                    $output .= $object->Id . ": " . $object->Subject . "\n";
+                }
+                else {
+                    $output .= $object->Id . ": " . $object->Name . "\n";
+                }
             }
         }
         else {
diff --git a/share/html/REST/1.0/search/ticket b/share/html/REST/1.0/search/ticket
deleted file mode 100755
index ca82a73..0000000
--- a/share/html/REST/1.0/search/ticket
+++ /dev/null
@@ -1,148 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%#
-%# COPYRIGHT:
-%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
-%#                                          <sales at bestpractical.com>
-%#
-%# (Except where explicitly superseded by other copyright notices)
-%#
-%#
-%# LICENSE:
-%#
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%#
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%#
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-%#
-%#
-%# CONTRIBUTION SUBMISSION POLICY:
-%#
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%#
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%#
-%# END BPS TAGGED BLOCK }}}
-%# REST/1.0/search/ticket
-%#
-<%ARGS>
-$query
-$format => undef
-$orderby => undef
-$fields => undef
-</%ARGS>
-<%INIT>
-use RT::Interface::REST;
-my $output = "";
-my $status = "200 Ok";
-my $tickets = RT::Tickets->new($session{CurrentUser});
-
-# Parse and validate any field specifications.
-my $field  = RT::Interface::REST->field_spec;
-my (%fields, @fields);
-if ($fields) {
-    $format ||= "l";
-    unless ($fields =~ /^(?:$field,)*$field$/) {
-        $status = "400 Bad Request";
-        $output = "Invalid field specification: $fields";
-        goto OUTPUT;
-    }
-    @fields = map lc, split /\s*,\s*/, $fields;
-    @fields{@fields} = ();
-    unless (exists $fields{id}) {
-        unshift @fields, "id";
-        $fields{id} = ();
-    }
-}
-
-$format ||= "s";
-if ($format !~ /^[isl]$/) {
-    $status = "400 Bad request";
-    $output = "Unknown listing format: $format. (Use i, s, or l.)\n";
-    goto OUTPUT;
-}
-
-my ($n, $s);
-eval {
-    ($n, $s) = $tickets->FromSQL($query);
-};
-if ($@ || $n == 0) {
-    $s ||= $@;
-    $status = "400 Bad request";
-    $output = "Invalid query: '$s'.\n";
-    goto OUTPUT;
-}
-
-if ($orderby) {
-    my ($order, $field) = $orderby =~ /^([\+\-])?(.+)/;
-    $order = $order && $order eq '-' ? 'DESC' : 'ASC';
-    $tickets->OrderBy( FIELD => $field, ORDER => $order );
-}
-
-$n = 0;
-my @output;
-while (my $ticket = $tickets->Next) {
-    $n++;
-
-	my $id = $ticket->Id;
-    if ($format eq "i") {
-        $output .= "ticket/" . $id . "\n";
-    }
-    elsif ($format eq "s") {
-	if ($fields) {
-        	my $result = $m->comp("/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields);
-		my ($notes, $order, $key_values, $errors) = @$result;
-		# If it's the first time through, add our header
-		if ($n == 1) {
-			$output .= join("\t",@$order)."\n";
-		}
-		# Cut off the annoying ticket/ before the id;
-		$key_values->{'id'} = $id;
-		$output .= join("\t", map { ref $key_values->{$_} eq 'ARRAY' ?
-join( ', ', @{$key_values->{$_}} ) : $key_values->{$_} } @$order)."\n";
-
-
-	} else {
-        	$output .= $ticket->Id . ": ". $ticket->Subject . "\n";
-	}
-    }
-    else {
-        my $d = $m->comp("/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields);
-        my ($c, $o, $k, $e) = @$d;
-	push @output, [ $c, $o, $k ];
-    }
-}
-if ($n == 0 && $format ne "i") {
-    $output = "No matching results.\n";
-}
-
-$output = form_compose(\@output) if @output;
-
-OUTPUT:
-$m->out("RT/". $RT::VERSION . " " . $status ."\n\n");
-
-$m->out($output );
-return();
-</%INIT>

-----------------------------------------------------------------------


More information about the Rt-commit mailing list