tpac ac part 2
authorBill Erickson <berick@esilibrary.com>
Mon, 14 May 2012 20:52:50 +0000 (16:52 -0400)
committerBill Erickson <berick@esilibrary.com>
Mon, 14 May 2012 20:52:50 +0000 (16:52 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm
Open-ILS/src/templates/opac/parts/js.tt2
Open-ILS/src/templates/opac/parts/record/addedcontent.tt2

index bf38575..9e80bd7 100644 (file)
@@ -5,6 +5,8 @@ use OpenSRF::Utils::Logger qw/$logger/;
 use OpenILS::Utils::CStoreEditor qw/:funcs/;
 use OpenILS::Utils::Fieldmapper;
 use OpenILS::Application::AppUtils;
+use Net::HTTP::NB;
+use IO::Select;
 my $U = 'OpenILS::Application::AppUtils';
 
 our $ac_types = ['toc',  'anotes', 'excerpt', 'summary', 'reviews'];
@@ -17,6 +19,13 @@ sub load_record {
     $ctx->{page} = 'record';  
 
     $self->timelog("load_record() began");
+
+    my $rec_id = $ctx->{page_args}->[0]
+        or return Apache2::Const::HTTP_BAD_REQUEST;
+
+    $self->added_content_stage1($rec_id);
+    $self->timelog("past added content stage 1");
+
     my $org = $self->_get_search_lib();
     my $org_name = $ctx->{get_aou}->($org)->shortname;
     my $pref_ou = $self->_get_pref_lib();
@@ -31,9 +40,6 @@ sub load_record {
     my $copy_limit = int($self->cgi->param('copy_limit') || 10);
     my $copy_offset = int($self->cgi->param('copy_offset') || 0);
 
-    my $rec_id = $ctx->{page_args}->[0]
-        or return Apache2::Const::HTTP_BAD_REQUEST;
-
     $self->get_staff_search_settings;
     if ($ctx->{staff_saved_search_size}) {
         $ctx->{saved_searches} = ($self->staff_load_searches)[1];
@@ -128,6 +134,11 @@ sub load_record {
     }
 
     $self->timelog("past expandies");
+
+    $self->added_content_stage2($rec_id);
+
+    $self->timelog("past added content stage 2");
+
     return Apache2::Const::OK;
 }
 
@@ -400,26 +411,108 @@ sub load_email_record {
     return Apache2::Const::OK;
 }
 
-sub added_content_avail1 {
+# ctx.added_content.$type.status:
+#   1 == available
+#   2 == not available
+#   3 == unknown
+sub added_content_stage1 {
     my $self = shift;
+    my $rec_id = shift;
     my $ctx = $self->ctx;
-    $ctx->{added_content} = {
-        map {$_ => {status => 3, content => ''}} @$ac_types;
-    };
+    my $sel_type = $self->cgi->param('ac') || '';
+    my $key = $self->get_ac_key($rec_id);
+    ($key = $key->{value}) =~ s/^\s+//g if $key;
+
+    $ctx->{added_content} = {};
+    for my $type (@$ac_types) {
+        $ctx->{added_content}->{$type} = {content => ''};
+        $ctx->{added_content}->{$type}->{status} = $key ? 3 : 2;
+
+        if ($key) {
+            $logger->debug("tpac: starting added content request for $key => $type");
+
+            my $req = Net::HTTP::NB->new(Host => $self->apache->hostname);
+
+            if (!$req) {
+                $logger->warn("Unable to fetch added content from " . $self->apache->hostname . ": $@");
+                next;
+            }
 
-    # fire requests
+            my $http_type = ($type eq $sel_type) ? 'GET' : 'HEAD';
+            $req->write_request($http_type => "/opac/extras/ac/$type/html/$key");
+            $ctx->{added_content}->{$type}->{request} = $req;
+        }
+    }
 }
 
-sub added_content_avail2 {
+# check each outstanding request.  If it's ready to be read, read 
+# the HTTP status and use it to determine if content is available.
+sub added_content_stage2 {
     my $self = shift;
     my $ctx = $self->ctx;
+    my $sel_type = $self->cgi->param('ac') || '';
+
+    for my $type (keys %{$ctx->{added_content}}) {
+        my $content = $ctx->{added_content}->{$type};
+
+        if ($content->{status} == 3) {
+            $logger->debug("tpac: finishing added content request for $type");
+
+            my $req = $content->{request};
+            my $sel = IO::Select->new($req);
 
-    # collect requests
+            if ($sel->can_read(0)) {
+                my ($code) = $req->read_response_headers;
+                $content->{status} = $code eq '200' ? 1 : 2;
+                $logger->debug("tpac: added content request for $type returned $code");
+
+                if ($type eq $sel_type) {
+                    while (1) {
+                        my $buf;
+                        my $n = $req->read_entity_body($buf, 1024);
+                        last unless $n;
+                        $content->{content} .= $buf;
+                    }
+                }
+            }
+        }
+    }
 }
 
-sub added_content_get_type {
+# XXX this is copied directly from AddedContent.pm in 
+# working/user/jeff/ac_by_record_id_rebase.  When Jeff's
+# branch is merged and Evergreen gets added content 
+# lookup by ID, this can be removed.
+# returns [{tag => $tag, value => $value}, {tag => $tag2, value => $value2}]
+sub get_ac_key {
     my $self = shift;
-    my $ctx = $self->ctx;
+    my $rec_id = shift;
+    my $key_data = $self->editor->json_query({
+        select => {mfr => ['tag', 'value']},
+        from => 'mfr',
+        where => {
+            record => $rec_id,
+            '-or' => [
+                {
+                    '-and' => [
+                        {tag => '020'},
+                        {subfield => 'a'}
+                    ]
+                }, {
+                    '-and' => [
+                        {tag => '024'},
+                        {subfield => 'a'},
+                        {ind1 => 1}
+                    ]
+                }
+            ]
+        }
+    });
+
+    return (
+        grep {$_->{tag} eq '020'} @$key_data,
+        grep {$_->{tag} eq '024'} @$key_data
+    )[0];
 }
 
 1;
index 1b1fb8a..b29a0bc 100644 (file)
@@ -78,7 +78,7 @@
 [% END; # use_autosuggest %]
 
 <script type="text/javascript">
-    [% acTypes = ['toc',  'anotes', 'excerpt', 'summary', 'reviews'] %]
+    [% ac_types = ['toc',  'anotes', 'excerpt', 'summary', 'reviews'] %]
 
     /* Checks to see if a given type of added content has data to show.
      * The first arg to callback() is boolean indicating the presence of data.
@@ -98,7 +98,7 @@
             # XXX revisit when ident=ctx.bre_id
             ident = ctx.record_attrs.isbn_clean || ctx.record_attrs.upc; 
             IF ident; 
-                FOR type IN acTypes;
+                FOR type IN ac_types;
                     IF ctx.added_content.$type.status == '3' # status unknown %]
                         dojo.addOnLoad(function() {
                             var ident = '[% ident %]';
index f5ba965..60fb3a7 100644 (file)
@@ -9,33 +9,34 @@
         summary => l('Summary')
     };
 
-    tab_class = 'ac_tab';
+    selected_type = CGI.param('ac');
     
     # For each type of added content, render the link if it's known to have
     # content, do not render the link if it's known to not have content.  If 
     # the content status is unknown, render the link, but hide the link via CSS
     # if dojo is enabled.  If dojo is not enabled, render and display the link.
 
-    %]
+%]
 
     <div id='ac_tab_wrapper'>
-        [% FOR type IN ac_types.keys 
+        [% FOR type IN ac_types.keys;
+            tab_class = 'ac_tab';
             IF ctx.added_content.$type.status != '2'; # no content
                 IF ctx.added_content.$type.status == '3' AND want_dojo; # status unknown
-                    tab_class = tab_class _ 'hidden';
+                    tab_class = tab_class _ ' hidden';
                 END %]
             <div class="[% tab_class %]" id="ac:[% type %]">
                 <a href="[% mkurl('', {ac => type}) _ '#addedcontent' %]">[% ac_types.$type %]</a>
             </div>
-        [% END %]
+            [% END;
+        END %]
     </div>
 
     <div id='ac_content'>
         <hr/>
         [% 
-            ac_type = CGI.param('ac'); 
-            IF ac_type; 
-                content = ctx.added_content.$ac_type.content;
+            IF selected_type; 
+                content = ctx.added_content.$selected_type.content;
                 IF content;
                     content;
                 ELSE;