LP#1772680: Resolved multiple issues
authorJaswinder Singh <Jaswinder.Singh0011@gmail.com>
Wed, 25 Jul 2018 20:43:11 +0000 (16:43 -0400)
committerChris Sharp <csharp@georgialibraries.org>
Wed, 19 Dec 2018 19:03:46 +0000 (14:03 -0500)
Signed-off-by: Jaswinder Singh <jaswinder.singh0011@gmail.com>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/perlmods/live_t/101-ebookapi-rbdigital.t [new file with mode: 0755]
Open-ILS/src/templates/opac/ebook_api/rbdigital/parts/item_parser.tt2
Open-ILS/src/templates/opac/ebook_api/rbdigital/parts/result/table.tt2
Open-ILS/src/templates/opac/ebook_api/rbdigital/parts/searchbar.tt2
Open-ILS/src/templates/opac/parts/ebook_api/base_js.tt2
Open-ILS/src/templates/opac/parts/vendor_tabs.tt2
Open-ILS/web/js/ui/default/opac/ebook_api/ebook.js
title-7-2.txt [new file with mode: 0644]

diff --git a/Open-ILS/src/perlmods/live_t/101-ebookapi-rbdigital.t b/Open-ILS/src/perlmods/live_t/101-ebookapi-rbdigital.t
new file mode 100755 (executable)
index 0000000..0681d63
--- /dev/null
@@ -0,0 +1,419 @@
+#!perl
+
+use Test::More tests => 8;
+
+diag("Tests Ebook API: RBDigital Books");
+
+use strict; use warnings;
+
+use OpenILS::Application::EbookAPI;
+use OpenSRF::AppSession;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::TestUtils;
+use Scalar::Util 'blessed';
+use Data::Dumper; 
+use JSON;
+
+# ------------------------------------------------------------ 
+# 1. Set up test environment.
+# ------------------------------------------------------------ 
+
+use constant EBOOK_API_VENDOR => 'rbdigital';
+use constant EBOOK_API_OU => 1;
+
+# Patrons.
+use constant EBOOK_API_PATRON_USERNAME  => 'egadmin';
+use constant EBOOK_API_PATRON_PASSWORD  => 'password';
+use constant BARCODE => 'e29bc74e9d13243c861c1d209e9a2e20';
+
+my $script = OpenILS::Utils::TestUtils->new();
+$script->bootstrap;
+
+# Authenticate the user
+$script->authenticate({
+    username => EBOOK_API_PATRON_USERNAME,
+    password => EBOOK_API_PATRON_PASSWORD,
+    type => 'opac'});
+
+my $authtoken = $script->authtoken;
+
+my $editor = $script->editor(authtoken=>$script->authtoken);
+$editor->xact_begin;
+
+ok(
+    $authtoken,
+    'Have an authtoken'
+);
+
+print "User Authenticated: Auth Token: $authtoken\n";
+
+is(
+    $script->authtime,
+    #14400,
+    420,
+    'Default authtime for staff login is 7200 seconds. 14400 seconds are equal to 4 hours'
+);
+
+my $cached_obj = $script->cache()->get_cache("oils_auth_$authtoken");
+
+ok(
+    ref $cached_obj,
+    'Can retrieve authtoken from memcached'
+);
+
+# Create an instance of EbookAPI
+my $ebook_api = $script->session('open-ils.ebook_api');
+
+# ------------------------------------------------------------ 
+# 2. Sessions.
+# ------------------------------------------------------------ 
+
+# Initiate a new EbookAPI session and get a session ID.
+# Returns undef unless a new session was created.
+my $session_id_req = $ebook_api->request(
+    'open-ils.ebook_api.start_session', EBOOK_API_VENDOR, EBOOK_API_OU);
+my $session_id = $session_id_req->recv->content;
+ok($session_id, 'Initiated an EbookAPI session: '.$session_id);
+
+# Check that an EbookAPI session exists matching our session ID.
+my $ck_session_id_req = $ebook_api->request(
+        'open-ils.ebook_api.check_session', $session_id, EBOOK_API_VENDOR, EBOOK_API_OU);
+my $ck_session_id = $ck_session_id_req->recv->content;
+ok($ck_session_id eq $session_id, 'Validated existing EbookAPI session');
+my $isbn = '9781508252573';
+
+# my $get_details_req = $ebook_api->request('open-ils.ebook_api.title.details', $session_id, $isbn);
+# print Dumper($get_details_req->recv->content);
+
+# my $register_patron_req = $ebook_api->request('open-ils.ebook_api.register_patron', 
+#      $authtoken, $session_id);
+
+# print Dumper($register_patron_req->recv);
+
+my $pcrud = OpenSRF::AppSession->create('open-ils.pcrud');
+$pcrud->connect();
+
+# my $evergreen_textsearch_field_req = $pcrud->request('open-ils.pcrud.search.cmc.atomic',"ANONYMOUS",
+#     {
+#         name => {'!=' => undef}
+#     },
+#     {
+#         flesh => 1,
+#         flesh_fields => { cmc => ['name','label']},
+#         order_by => { cmc => 'name ASC' }
+#     }
+# )->recv();
+
+# print Dumper($evergreen_textsearch_field_req->content);
+
+
+#CStore example
+#  my $cstore = OpenSRF::AppSession->create( 'open-ils.cstore' );
+# my $evergreen_textsearch_field_req = $cstore->request('open-ils.cstore.direct.config.metabib_class.search.atomic',
+#     { name => { "!=" => undef } },
+#     {
+#         order_by => { cmc => 'name ASC' }
+#     }
+# )->recv();
+
+# print Dumper($evergreen_textsearch_field_req->content);
+
+#Save a record
+ my $xact;
+
+eval {
+    $xact = $pcrud->request(
+        'open-ils.pcrud.transaction.begin',
+        $authtoken
+    )->gather(1);
+};
+
+if ($@) {
+    undef($xact);
+}
+# The rest depends on there being a transaction.
+if ($xact) {
+    my $tmpl_rec = Fieldmapper::rbdigital::search_fields->new;
+    $tmpl_rec->digital_services_id(1);
+    $tmpl_rec->evergreen_field('mobile1');
+    $tmpl_rec->digital_services_field('mobile2');
+
+    $pcrud->request('open-ils.pcrud.create.ebook_rsf', $authtoken, $tmpl_rec )->gather(1);
+
+    $xact = $pcrud->request(
+            'open-ils.pcrud.transaction.commit',
+            $authtoken
+        )->gather(1);
+
+    print Dumper($xact);
+}
+
+# my $mapped_search_field_req = $pcrud->request('open-ils.pcrud.search.ebook_rsf.atomic', "ANONYMOUS",
+#     {
+#         digital_services_id => 1
+#     }
+# )->recv();
+
+
+# my $vendor_key = 'rbdigital';
+# $pcrud = OpenSRF::AppSession->create('open-ils.pcrud');
+# $pcrud->connect();
+
+# my $ctype = 'audience';
+# my $ccvm_req = $pcrud->request('open-ils.pcrud.search.ccvm.atomic', "ANONYMOUS",
+#     {
+#         opac_visible => 't',
+#         ctype => $ctype
+#     }
+    
+# )->recv();
+
+# print Dumper($ccvm_req->content);
+
+# my $eg_search_field = 'audience';
+# my $ds_search_field = 'audience';
+# my $ebook_rsf_req = $pcrud->request('open-ils.pcrud.search.ebook_rsf.atomic', "ANONYMOUS",
+#     { 
+#         evergreen_field =>  $eg_search_field,
+#         digital_services_field => $ds_search_field
+#     }
+# )->recv(); 
+
+# # print Dumper($ebook_rsf_req->content->[0]->evergreen_field);
+# if ($ebook_rsf_req && defined($ebook_rsf_req->content->[0]) ) {
+#     print "Duplicate entry found! Please try selecting different values"; 
+# }
+
+# Get Digital Services record based on vendo_key='rbdigital'
+# my $digital_services_req = $pcrud->request('open-ils.pcrud.search.ebook_rds.atomic', "ANONYMOUS",
+#     { vendor_key => $vendor_key }
+# )->recv();
+#  if ($digital_services_req) {
+#     print Dumper($digital_services_req->content->[0]->id);
+# }
+
+# Get RBDigital mapped field values bashed on search field id
+# my $search_fields_mapping_req = $pcrud->request('open-ils.pcrud.search.ebook_rsfm.atomic', "ANONYMOUS",
+#     { 
+#         search_fields_id => 1 
+#     }
+# )->recv();
+
+
+# print Dumper($search_fields_mapping_req->content);
+
+# print scalar(@ {$search_fields_mapping_req->content});
+
+# my $json = encode_json (\@{$search_fields_mapping_req->content});
+# print "$json";
+
+# my @contents = $search_fields_mapping_req->content;
+
+# my @search_field_values = ();
+# # Iterate over list of values and build an array for JS
+# foreach my $value (@ {$search_fields_mapping_req->content}) {
+#     push @search_field_values, [$value->id, $value->search_fields_id, $value->evergreen_field_value, $value->digital_services_field_value];
+# }
+# print Dumper([@search_field_values]);
+# my $search_fields_id = 7;
+# $pcrud->request('open-ils.pcrud.transaction.begin',$authtoken)->gather(1);
+
+# my $search_fields_req = $pcrud->request('open-ils.pcrud.delete.ebook_rsf', $authtoken, $search_fields_id)->recv(1);
+
+# $pcrud->request('open-ils.pcrud.transaction.commit',$authtoken)->gather(1);
+
+# print Dumper($digital_services_req->content);
+
+# my $user_card_req = $pcrud->request('open-ils.cstore.direct.actor.card.search', 
+#      { barcode => BARCODE }
+#  )->gather();
+
+# if ($user_card_req && defined ($user_card_req->usr)) {
+#     my $user_req = $pcrud->request('open-ils.cstore.direct.actor.user.search', 
+#         { id => $user_card_req->usr }
+#     )->gather();
+
+#    print "User Registration: ". $user_req->email;
+# }
+
+
+# ------------------------------------------------------------ 
+# 3. Call Recorded Books API to fetch patron_id
+# ------------------------------------------------------------ 
+my $get_patron_id_req = $ebook_api->request(
+    'open-ils.ebook_api.get_patron_id', $authtoken, $session_id, 1);
+my $patronid = $get_patron_id_req->recv->content;
+
+ok(
+    $patronid, 
+    'Patron ID Received: '.$patronid
+);
+
+# ------------------------------------------------------------ 
+# 4. Check if the User is authrorized to rbdigital library
+# ------------------------------------------------------------ 
+
+# my $is_authorized_patron_req = $ebook_api->request(
+#     'open-ils.ebook_api.is_authorized_patron', $authtoken, $session_id);
+
+# my $is_authorized_results = $is_authorized_patron_req->recv;
+# print Dumper($is_authorized_results);
+
+
+# ok(
+#     $is_authorized_results,
+#     'Authorized Result: '
+# );
+
+# my $pcrud = OpenSRF::AppSession->create('open-ils.pcrud');
+# $pcrud->connect();
+
+# my $ebook_rdsa_req = $pcrud->request('open-ils.pcrud.search.ebook_rdsa.atomic', "ANONYMOUS", 
+#     {
+#         #id => {">" => 0},
+#         "+ebook_rl" => {
+#             home_ou => 1
+#         },
+#         "+ebook_rds" => {
+#             is_enabled => 't'
+#         }
+#     },
+#     {
+#         flesh => 1,
+#         flesh_fields => { ebook_rdsa => ['digital_services_id']},
+#         order_by => { ebook_rds => 'display_order ASC' },
+#         join => {
+#             ebook_rds => {},
+#             ebook_rl => {}
+#         }
+#     }
+# )->gather();
+# print Dumper($ebook_rdsa_req);
+
+# my $ebook_rds_req = $pcrud->request('open-ils.pcrud.search.ebook_rds.atomic', "ANONYMOUS", 
+#     {
+#         is_enabled => 't',
+#         "+ebook_rl" => {
+#             home_ou => 1
+#         }
+#     },
+#     {
+#         flesh => 1,
+#         flesh_fields => { ebook_rds => ['id']},
+#         order_by => { ebook_rds => 'display_order ASC' },
+#         join => {
+#             ebook_rdsa => {},
+#             ebook_rdsa => { 
+#                 join => {
+#                      ebook_rl => {}
+#                 }
+#             }
+#         }
+#     }
+# )->gather();
+
+# print Dumper($ebook_rds_req);
+
+# Get vendor list
+# my $patron_id = 1;
+# my $get_vendors = $ebook_api->request(
+#     'open-ils.ebook_api.get_vendors', $authtoken, $session_id);
+# my $library_id_results = $get_vendors->recv->content;
+
+# foreach my $vendor (@$library_id_results) {
+#     foreach my $items (@$vendor) {
+#         print $items.' ';
+#     }
+#     print "\n";
+#     print @$vendor[0];
+# }
+
+
+#my $barcode = 'e29bc74e9d13243c861c1d209e9a2e20';
+# my $usr = OpenILS::Application::AppUtils->simplereq('open-ils.storage',  "open-ils.storage.biblio.record_entry.retrieve_by_barcode", $barcode);
+#my $usr = OpenILS::Application::AppUtils->simplereq('open-ils.actor', 'open-ils.actor.user.fleshed.retrieve_by_barcode', "$authtoken", $barcode);
+
+# my $new_user = 'jwiggins';
+# # Authenticate the user
+# $script->authenticate({
+#     username => $new_user,
+#     password => EBOOK_API_PATRON_PASSWORD,
+#     type => 'staff'});
+
+# my $new_authtoken = $script->authtoken;
+# $editor = $script->editor(authtoken=>$new_authtoken);
+# $editor->xact_begin;
+# $pcrud = OpenSRF::AppSession->create('open-ils.cstore');
+# $pcrud->connect();
+
+# my $username = 'jwiggins';
+# my $postal_code = '';
+# print "EbookAPI: Checking if a user is found from db.\n";
+# my $user_req = $pcrud->request('open-ils.cstore.direct.actor.user.search', 
+#     { usrname => $username }
+# )->gather();
+
+# print Dumper($user_req);
+
+# print "EbookAPI: User found on db.\n";
+# # Second, get the user postal_code information (if any)
+# if ($user_req && defined ($user_req->mailing_address) ) {
+#     print "EbookAPI: Calling CStore to retreive user mailing address postal code: " . $user_req->mailing_address."\n";
+#     #Get the mailing address id to retrieve postal code
+#         my $user_mailing_address_req = $pcrud->request('open-ils.cstore.direct.actor.user_address.search', 
+#         { id => $user_req->mailing_address }
+#     )->gather();
+
+#     if ( $user_mailing_address_req && defined($user_mailing_address_req->post_code) ) {
+#         $postal_code = $user_mailing_address_req->post_code;
+#         print "EbookAPI: Postal code received: $postal_code\n";
+#     }
+# } else {
+#     #Log user not found, this should not happen since the user is already authenticated
+#     print "EbookAPI: Postal code not found in db for patron registration.\n";
+# }
+
+
+# print "EbookAPI: Building a request for patron registration";
+# my $is_active = true;
+# my $library_id = 3925;
+
+# my $request_content = {
+#     firstName => $user_req->first_given_name,
+#     lastName => $user_req->family_name,
+#     userName => $user_req->usrname,
+#     password => $user_req->usrname . _get_current_year(),
+#     email => $user_req->email,
+#     postalCode => $postal_code,
+#     isActive => $is_active,
+#     libraryId => $library_id
+# };
+
+# my $req = {
+#     method => 'POST',
+#     uri    => "$base_uri/rpc/libraries/$library_id/patrons",
+#     content => OpenSRF::Utils::JSON->perl2JSON($request_content),
+#     headers => {
+#         'Authorization' => 'Basic ' . $self->{basic_token},
+#         'Content-Type'  => 'application/x-www-form-urlencoded;charset=UTF-8'
+#     }
+# };
+
+# $logger->info("EbookAPI: Calling an API to registering Patron: $username");
+# my $res = $self->request($req, $session_id);
+# if (defined ($res)) {
+#     if ($res->{content}->{patronId}) {
+#         $logger->info("EbookAPI: User $username successfully registered with RBDigital portal.");
+#         return $res->{content}->{patronId};
+#     } else {
+#         $logger->error("EbookAPI: Registration for $username to RBDigital failed!");
+#     }
+# }
+
+$script->logout();
+
+$cached_obj = $script->cache()->get_cache("oils_auth_$authtoken");
+ok(
+    ! $cached_obj,
+    'Authtoken is removed from memcached after logout'
+);
\ No newline at end of file
index 690e096..09074c8 100755 (executable)
@@ -6,7 +6,7 @@
     vendor_search_uri = '/ebook_api/rbdigital/results';
     vendor_record_uri = '/ebook_api/rbdigital/record/';
     
-    vendor_record_url = mkurl(ctx.opac_root _ vendor_record_uri _ ebook_record_item.isbn,{},['expand','summaryplus','recommendations']);
+    vendor_record_url = mkurl(ctx.opac_root _ vendor_record_uri _ ebook_record_item.isbn,{},[ 'detail_record_view', 'expand','summaryplus','recommendations']);
 
     ebook_item.title = ebook_record_item.title;
     ebook_item.isbn = ebook_record_item.isbn;
@@ -14,6 +14,7 @@
     ebook_item.shortDescription = ebook_record_item.shortDescription;
     ebook_item.language = ebook_record_item.language;
     ebook_item.authors = "";
+    ebook_item.authors_name = "";
     ebook_item.narrators = "";
     ebook_item.genres = "";
     ebook_item.series = "";
@@ -26,6 +27,7 @@
     ebook_item.image_xxl_url = '';
     ebook_item.mediaType = '';
     ebook_item.authors_detail = '';
+    ebook_item.narrators_detail = "";
 
     # Check title is available for Checkout Service
     ebook_item.isAvailable = ebook_record_item.interest.isAvailable;
     FOREACH item IN ebook_record_item.authors;
         IF item.text != '';
             author_search_url = ctx.opac_root _ vendor_search_uri _ '?' _ 'qtype=author&query=' _ item.text;
+            
+            ebook_item.authors = ebook_item.authors _ 
+                '<a title="' _ l("Perform an Author Search") _ '" class="record_author" href="' _ author_search_url _ '">' _ item.text _ '</a>';
+            
+            #Keep author's name into a variable to be displayed on summary page
+            ebook_item.authors_name = ebook_item.authors_name _ item.text;
+
             ebook_item.authors_detail = ebook_item.authors_detail _ 
-                        '<span class="rdetail-author-div" typeof="Person" property="author" resource="#schemacontrib1"><a href="'_
-                        author_search_url _
-                        '"><span resource="#schemacontrib1"><span property="name">'_ item.text _ '</span></span></a> (<span property="description">Author</span>).&nbsp;</span>';
-            ebook_item.authors = ebook_item.authors _ item.text;
+                '<span class="rdetail-author-div" typeof="Person" property="author" resource="#schemacontrib1"><a href="'_
+                author_search_url _
+                '"><span resource="#schemacontrib1"><span property="name">'_ item.text _ '</span></span></a> (<span property="description">Author</span>).&nbsp;</span>';
+            
             IF !loop.last();
                 ebook_item.authors = ebook_item.authors _ ", ";
+                ebook_item.authors_name = ebook_item.authors_name _ ", ";
+                #the detail is used inside a record (summary.tt2)
                 ebook_item.authors_detail = ebook_item.authors_detail _ ", ";
             END;
         END;
 
     # Loop over Narrators array
     FOREACH item IN ebook_record_item.narrators;
-        author_search_url = ctx.opac_root _ vendor_search_uri _ '?' _ 'qtype=author&query=' _ item.text;
-        ebook_item.authors_detail = ebook_item.authors_detail _ 
+        narrator_search_url = ctx.opac_root _ vendor_search_uri _ '?' _ 'qtype=narrator&query=' _ item.text;
+        ebook_item.narrators = ebook_item.narrators _ 
+                '<a title="' _ l("Perform an Narrator Search") _ '" class="record_author" href="' _ narrator_search_url _ '">' _ item.text _ '</a>';
+
+        ebook_item.narrators_detail = ebook_item.narrators_detail _ 
                     '<span class="rdetail-author-div" typeof="Person" property="author" resource="#schemacontrib1"><a href="'_
-                    author_search_url _
+                    narrator_search_url _
                     '"><span resource="#schemacontrib1"><span property="name">'_ item.text _ '</span></span></a> (<span property="description">Narrator</span>).&nbsp;</span>';
-        ebook_item.narrators = ebook_item.narrators _ item.text;
+        
         IF !loop.last();
             ebook_item.narrators = ebook_item.narrators _ ", ";
+            ebook_item.narrators_detail = ebook_item.narrators_detail _ ", ";
         END;
     END;
 
     # Get Extended Authors information
     ebook_item.authors_extended = '';
     IF ebook_item.authors != '';
-        ebook_item.authors_extended =  ' / ' _ ebook_item.authors_extended _ ebook_item.authors;
+        ebook_item.authors_extended =  ' / ' _ ebook_item.authors_extended _ ebook_item.authors_name;
     END;
 
     # Get Extended Title information
index 19aa9e9..1390ed9 100755 (executable)
                                                         [% html_text_attr('title', l('Display record details for "[_1]"', ebook_item.title)) %]>
                                                         [% ebook_item.title | html %]
                                                      </a>
-                                                     [% IF rec.mr_constituent_count.defined && rec.mr_constituent_count > 1 %]
-                                                     <span title="[% l('This group contains [_1] records', rec.mr_constituent_count) %]">
-                                                      ([% rec.mr_constituent_count %])
-                                                     </span>
-                                                     [% END %]
-
-[%-
-FOR entry IN ebook_item.graphic_titles;
-    FOR alt IN entry.graphic;
-        diratt = "";
-        IF alt.dir;
-            diratt = ' dir="' _ alt.dir _ '"';
-        END;
--%]
-<div class="graphic880"[% diratt %]>
-    [% alt.value | html %]
-</div>
-[%-
-    END;
-END;
--%]
  
-                                                    <div>
-                                                        <a title="[% l("Perform an Author Search") %]"
-                                                                class="record_author"
-                                                                href="[%- 
-                                                                    authorquery = ebook_item.authors | replace('[#"^$\+\-,\.:;&|\[\]()]', ' ');
-                                                                    mkurl(ctx.opac_root _ vendor_search_uri, {qtype => 'author', query => authorquery}, 
-                                                                    general_search_parms.merge(expert_search_parms, browse_search_parms, facet_search_parms))
-                                                                    -%]" rel="nofollow" vocab="">[% ebook_item.authors | html %]</a>
-[%-
-FOR entry IN ebook_item.graphic_authors;
-    FOR alt IN entry.graphic;
-        diratt = "";
-        IF alt.dir;
-            diratt = ' dir="' _ alt.dir _ '"';
-        END;
--%]
-<div class="graphic880"[% diratt %]>
-    [% alt.value | html %]
-</div>
-[%-
-    END;
-END;
--%]
-
+                                                    <div id="author_search">
+                                                        [% ebook_item.authors; %]
                                                     </div>
                                                     [% IF ebook_item.narrators != ''; %]
                                                         <div class='result_narrators_cell'>
-                                                            Narrators: <a title="[% l("Perform an Narrator Search") %]"
-                                                                    class="record_author"
-                                                                    href="[%- 
-                                                                        authorquery = ebook_item.narrators | replace('[#"^$\+\-,\.:;&|\[\]()]', ' ');
-                                                                        mkurl(ctx.opac_root _ vendor_search_uri, {qtype => 'narrator', query => authorquery}, 
-                                                                        general_search_parms.merge(expert_search_parms, browse_search_parms, facet_search_parms))
-                                                                        -%]" rel="nofollow" vocab="">[% ebook_item.narrators | html %]
-                                                            </a>
+                                                            Narrators: [% ebook_item.narrators; %]
                                                         </div>
                                                     [% END; %]
                                                     <div class='result_table_title_cell'>
@@ -151,11 +101,7 @@ END;
                                                         END
                                                     -%]
                                                     </div>
-                                                    [% IF rec.popularity > 0.0 %]
-                                                      <div>
-                                                        <span><strong>[% l('Popularity:') %]</strong> [% rec.popularity %] / 5.0</span>
-                                                      </div>
-                                                    [% END %]
+                                                    
                                                     <table 
                                                        role="presentation"
                                                        title="[% l('Record Holdings Summary') %]"
index 37fbea8..b52dcbb 100755 (executable)
@@ -88,6 +88,8 @@ END;
             onclick='setTimeout(function(){$("search-submit-spinner").className=""; $("search-submit-go").className="hidden";}, 2000)'/>
         <img id='search-submit-spinner' src='[% ctx.media_prefix %]/opac/images/progressbar_green.gif[% ctx.cache_key %]' style='height:16px;width:16px;' class='hidden' alt='[% l("Search In Progress") %]'/>
     </span>
+    
+    <span> <a href="[% ctx.opac_root _ vendor_search_uri; %]" class="opac-button" >Clear</a> </span>
     </div>
     [% IF ctx.bookbag %]
     <div id="search-only-bookbag-container">
index 6247bc0..7910c7e 100755 (executable)
@@ -90,10 +90,10 @@ dojo.addOnLoad(function() {
 
 [%- IF ctx.user %]
 <script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/ebook_api/relation.js[% ctx.cache_key %]"></script>
-<script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/ebook_api/loggedin.js?v=[% date.format; %]"></script>
+<script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/ebook_api/loggedin.js[% ctx.cache_key %]"></script>
 <script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/common/build/js/jquery.min.js[% ctx.cache_key %]"></script>
 <script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/staff/build/js/bootstrap.min.js[% ctx.cache_key %]"></script>
-<script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/staff/build/js/pnotify.custom.min.js?v=[% date.format; %]"></script>
+<script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/staff/build/js/pnotify.custom.min.js[% ctx.cache_key %]"></script>
 <script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/ebook_api/rbdigital.js?v=[% date.format; %]"></script>
 [%- END %]
 
index 1dd7e3b..48c0875 100755 (executable)
@@ -15,7 +15,7 @@
                         vendor_tab_class = "acct-tab-off";
                     END; %]
                 <a id="lnkSearchResults_[%  vendor.vendor_key %]" 
-                    href="[% mkurl(ctx.opac_root _ vendor.search_uri) %]" class="[% vendor_tab_class %]">[% vendor.name %]</a>
+                    href="[% ctx.opac_root _ vendor.search_uri; %]" class="[% vendor_tab_class %]">[% vendor.name %]</a>
             [% END; %]    
         </div>
     </div>
index f13a173..6a43274 100755 (executable)
@@ -117,6 +117,8 @@ Ebook.prototype.checkin = function(authtoken, patron_id, callback) {
                 var resp = r.recv();
                 if (resp) {
                     console.log('checkout response: ' + resp.content());
+                    //Clear dojo cache
+                    dojo.cookie('ebook_xact_cache', '' , {path: '/'});
                     return callback(resp.content());
                 }
             }
diff --git a/title-7-2.txt b/title-7-2.txt
new file mode 100644 (file)
index 0000000..03c5e48
--- /dev/null
@@ -0,0 +1,1284 @@
+{\r
+  "scopeId": 3925,\r
+  "pageIndex": 0,\r
+  "pageSize": 10,\r
+  "pageCount": 1,\r
+  "resultSetCount": 5,\r
+  "sort": "title",\r
+  "isSortByDesc": false,\r
+  "filters": [\r
+    {\r
+      "tokenLabel": "mediatype",\r
+      "tokenValue": "eaudio",\r
+      "count": 2,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "mediatype",\r
+      "tokenValue": "ebook",\r
+      "count": 3,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "hasdrm",\r
+      "tokenValue": "false",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "hasdrm",\r
+      "tokenValue": "true",\r
+      "count": 5,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "isfiction",\r
+      "tokenValue": "false",\r
+      "count": 2,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "isfiction",\r
+      "tokenValue": "true",\r
+      "count": 3,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "african-american-interest",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "arts-entertainment",\r
+      "count": 2,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "biography-autobiography-memoir",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "business-economics",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "classics",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "comics-graphic-novels",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "cooking",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "drama",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "fantasy",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "foreign-language-study",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "general-fiction",\r
+      "count": 1,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "general-nonfiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "historical-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "history",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "home-garden",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "horror",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "humor",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "humorous-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "inspirational-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "inspirational-nonfiction",\r
+      "count": 1,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "juvenile-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "juvenile-nonfiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "language-arts",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "lgbt-interest",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "literary-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "mystery",\r
+      "count": 1,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "non-classifiable",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "poetry",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "politics-and-current-events",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "politics-current-events",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "religion",\r
+      "count": 1,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "romance",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "science",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "sci-fi",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "self-help",\r
+      "count": 2,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "short-stories",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "social-science",\r
+      "count": 1,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "sports",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "suspense-thriller",\r
+      "count": 2,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "travel",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "true-crime",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "urban-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "western",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "genre",\r
+      "tokenValue": "womens-fiction",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "dutch-flemish",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "english",\r
+      "count": 5,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "french",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "german",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "irish",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "italian",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "norwegian",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "portuguese",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "spanish",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "language",\r
+      "tokenValue": "turkish",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "audience",\r
+      "tokenValue": "adult",\r
+      "count": 5,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "audience",\r
+      "tokenValue": "beginning-reader",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "audience",\r
+      "tokenValue": "childrens",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "audience",\r
+      "tokenValue": "young-adult",\r
+      "count": 0,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "availability",\r
+      "tokenValue": "available",\r
+      "count": 1,\r
+      "isSelected": false\r
+    },\r
+    {\r
+      "tokenLabel": "availability",\r
+      "tokenValue": "unavailable",\r
+      "count": 4,\r
+      "isSelected": false\r
+    }\r
+  ],\r
+  "acceptMediaType": "complete",\r
+  "items": [\r
+    {\r
+      "interest": {\r
+        "stateId": 3,\r
+        "isOwned": true,\r
+        "isAvailable": false,\r
+        "name": "library"\r
+      },\r
+      "item": {\r
+        "authors": [\r
+          {\r
+            "facet": "author",\r
+            "text": "Stephen King",\r
+            "token": "stephen-king",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "author",\r
+            "text": "Richard Chizmar",\r
+            "token": "richard-chizmar",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "narrators": [\r
+          {\r
+            "facet": "narrator",\r
+            "text": "Maggie Siff",\r
+            "token": "maggie-siff",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "images": [\r
+          {\r
+            "name": "medium",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100123506/Z100123506_image_95x140.jpg"\r
+          },\r
+          {\r
+            "name": "large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100123506/Z100123506_image_128x192.jpg"\r
+          },\r
+          {\r
+            "name": "x-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100123506/Z100123506_image_148x230.jpg"\r
+          },\r
+          {\r
+            "name": "xx-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100123506/Z100123506_image_512x512_iTunes.png"\r
+          }\r
+        ],\r
+        "id": "5b3dd0cc19bf353454a0d387",\r
+        "isbn": "9781508242062",\r
+        "subtitle": "Includes Bonus Story \"The Music Room\"",\r
+        "publisher": {\r
+          "facet": "publisher",\r
+          "text": "Simon & Schuster Audio",\r
+          "token": "simon-and-schuster-audio",\r
+          "order": 0\r
+        },\r
+        "genres": [\r
+          {\r
+            "facet": "genre",\r
+            "text": "General Fiction",\r
+            "token": "general-fiction",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "language": "English",\r
+        "audience": "Adult",\r
+        "mediaType": "eAudio",\r
+        "releasedDate": "2017-05-16T04:00:00Z",\r
+        "fileSize": "58655088",\r
+        "duration": "02:42:42",\r
+        "bookTitle": {\r
+          "facet": "title",\r
+          "text": "Gwendy's Button Box",\r
+          "token": "gwendys-button-box",\r
+          "order": 0\r
+        },\r
+        "title": "Gwendy's Button Box",\r
+        "isFiction": true,\r
+        "hasSubtitle": true,\r
+        "hasAttachments": false,\r
+        "hasDrm": true,\r
+        "preReleaseOn": "2017-03-23T04:00:00Z",\r
+        "scheduledReleaseOn": "2017-05-16T04:00:00Z",\r
+        "isPreRelease": false,\r
+        "shortDescription": "Set in the fictional town of Castle Rock, Maine INCLUDES A CONVERSATION BETWEEN STEPHEN KING & RICHARD CHIZMAR! Stephen King teams up with long-time friend and award-winning...",\r
+        "sortAuthor": "king stephen",\r
+        "sortTitle": "gwendys-button-box",\r
+        "sortNarrator": "siff maggie",\r
+        "audioFiles": [\r
+          {\r
+            "id": 3226981,\r
+            "display": "Introduction",\r
+            "filename": "Z100123506_0001_IN.mp3",\r
+            "minutes": 1.03,\r
+            "size": 372056,\r
+            "duration": "00:01:01"\r
+          },\r
+          {\r
+            "id": 3226982,\r
+            "display": "Chapter 1",\r
+            "filename": "Z100123506_0002_C0001.mp3",\r
+            "minutes": 23.55,\r
+            "size": 8481776,\r
+            "duration": "00:23:33"\r
+          },\r
+          {\r
+            "id": 3226983,\r
+            "display": "Chapter 2",\r
+            "filename": "Z100123506_0003_C0002.mp3",\r
+            "minutes": 8.50,\r
+            "size": 3061904,\r
+            "duration": "00:08:30"\r
+          },\r
+          {\r
+            "id": 3226984,\r
+            "display": "Chapter 3",\r
+            "filename": "Z100123506_0004_C0003.mp3",\r
+            "minutes": 1.91,\r
+            "size": 693680,\r
+            "duration": "00:01:54"\r
+          },\r
+          {\r
+            "id": 3226985,\r
+            "display": "Chapter 4",\r
+            "filename": "Z100123506_0005_C0004.mp3",\r
+            "minutes": 5.96,\r
+            "size": 2150168,\r
+            "duration": "00:05:57"\r
+          },\r
+          {\r
+            "id": 3226986,\r
+            "display": "Chapter 5",\r
+            "filename": "Z100123506_0006_C0005.mp3",\r
+            "minutes": 1.58,\r
+            "size": 572072,\r
+            "duration": "00:01:34"\r
+          },\r
+          {\r
+            "id": 3226987,\r
+            "display": "Chapter 6",\r
+            "filename": "Z100123506_0007_C0006.mp3",\r
+            "minutes": 5.80,\r
+            "size": 2091200,\r
+            "duration": "00:05:48"\r
+          },\r
+          {\r
+            "id": 3226988,\r
+            "display": "Chapter 7",\r
+            "filename": "Z100123506_0008_C0007.mp3",\r
+            "minutes": 5.33,\r
+            "size": 1923584,\r
+            "duration": "00:05:19"\r
+          },\r
+          {\r
+            "id": 3228882,\r
+            "display": "Chapter 8",\r
+            "filename": "Z100123506_0009_C0008.mp3",\r
+            "minutes": 4.83,\r
+            "size": 1741280,\r
+            "duration": "00:04:49"\r
+          },\r
+          {\r
+            "id": 3228883,\r
+            "display": "Chapter 9",\r
+            "filename": "Z100123506_0010_C0009.mp3",\r
+            "minutes": 1.68,\r
+            "size": 609224,\r
+            "duration": "00:01:40"\r
+          },\r
+          {\r
+            "id": 3228884,\r
+            "display": "Chapter 10",\r
+            "filename": "Z100123506_0011_C0010.mp3",\r
+            "minutes": 6.55,\r
+            "size": 2359904,\r
+            "duration": "00:06:33"\r
+          },\r
+          {\r
+            "id": 3228885,\r
+            "display": "Chapter 11",\r
+            "filename": "Z100123506_0012_C0011.mp3",\r
+            "minutes": 1.80,\r
+            "size": 647672,\r
+            "duration": "00:01:48"\r
+          },\r
+          {\r
+            "id": 3228886,\r
+            "display": "Chapter 12",\r
+            "filename": "Z100123506_0013_C0012.mp3",\r
+            "minutes": 3.35,\r
+            "size": 1209056,\r
+            "duration": "00:03:21"\r
+          },\r
+          {\r
+            "id": 3228887,\r
+            "display": "Chapter 13",\r
+            "filename": "Z100123506_0014_C0013.mp3",\r
+            "minutes": 2.10,\r
+            "size": 759992,\r
+            "duration": "00:02:06"\r
+          },\r
+          {\r
+            "id": 3228888,\r
+            "display": "Chapter 14",\r
+            "filename": "Z100123506_0015_C0014.mp3",\r
+            "minutes": 5.16,\r
+            "size": 1862240,\r
+            "duration": "00:05:09"\r
+          },\r
+          {\r
+            "id": 3228889,\r
+            "display": "Chapter 15",\r
+            "filename": "Z100123506_0016_C0015.mp3",\r
+            "minutes": 2.06,\r
+            "size": 747248,\r
+            "duration": "00:02:03"\r
+          },\r
+          {\r
+            "id": 3228890,\r
+            "display": "Chapter 16",\r
+            "filename": "Z100123506_0017_C0016.mp3",\r
+            "minutes": 8.31,\r
+            "size": 2997968,\r
+            "duration": "00:08:18"\r
+          },\r
+          {\r
+            "id": 3228891,\r
+            "display": "Chapter 17",\r
+            "filename": "Z100123506_0018_C0017.mp3",\r
+            "minutes": 2.81,\r
+            "size": 1016168,\r
+            "duration": "00:02:48"\r
+          },\r
+          {\r
+            "id": 3228892,\r
+            "display": "Chapter 18",\r
+            "filename": "Z100123506_0019_C0018.mp3",\r
+            "minutes": 3.30,\r
+            "size": 1187240,\r
+            "duration": "00:03:18"\r
+          },\r
+          {\r
+            "id": 3228893,\r
+            "display": "Chapter 19",\r
+            "filename": "Z100123506_0020_C0019.mp3",\r
+            "minutes": 3.43,\r
+            "size": 1238000,\r
+            "duration": "00:03:25"\r
+          },\r
+          {\r
+            "id": 3228894,\r
+            "display": "Chapter 20",\r
+            "filename": "Z100123506_0021_C0020.mp3",\r
+            "minutes": 1.35,\r
+            "size": 490640,\r
+            "duration": "00:01:21"\r
+          },\r
+          {\r
+            "id": 3228895,\r
+            "display": "Chapter 21",\r
+            "filename": "Z100123506_0022_C0021.mp3",\r
+            "minutes": 2.36,\r
+            "size": 852008,\r
+            "duration": "00:02:21"\r
+          },\r
+          {\r
+            "id": 3228896,\r
+            "display": "Chapter 22",\r
+            "filename": "Z100123506_0023_C0022.mp3",\r
+            "minutes": 1.25,\r
+            "size": 451328,\r
+            "duration": "00:01:15"\r
+          },\r
+          {\r
+            "id": 3228897,\r
+            "display": "Chapter 23",\r
+            "filename": "Z100123506_0024_C0023.mp3",\r
+            "minutes": 4.40,\r
+            "size": 1587056,\r
+            "duration": "00:04:24"\r
+          },\r
+          {\r
+            "id": 3228898,\r
+            "display": "Chapter 24",\r
+            "filename": "Z100123506_0025_C0024.mp3",\r
+            "minutes": 1.33,\r
+            "size": 482000,\r
+            "duration": "00:01:19"\r
+          },\r
+          {\r
+            "id": 3228899,\r
+            "display": "Chapter 25",\r
+            "filename": "Z100123506_0026_C0025.mp3",\r
+            "minutes": 3.55,\r
+            "size": 1281848,\r
+            "duration": "00:03:33"\r
+          },\r
+          {\r
+            "id": 3228900,\r
+            "display": "Chapter 26",\r
+            "filename": "Z100123506_0027_C0026.mp3",\r
+            "minutes": 1.05,\r
+            "size": 381560,\r
+            "duration": "00:01:03"\r
+          },\r
+          {\r
+            "id": 3228901,\r
+            "display": "Chapter 27",\r
+            "filename": "Z100123506_0028_C0027.mp3",\r
+            "minutes": 1.73,\r
+            "size": 625424,\r
+            "duration": "00:01:43"\r
+          },\r
+          {\r
+            "id": 3228902,\r
+            "display": "Chapter 28",\r
+            "filename": "Z100123506_0029_C0028.mp3",\r
+            "minutes": 3.25,\r
+            "size": 1173416,\r
+            "duration": "00:03:15"\r
+          },\r
+          {\r
+            "id": 3228903,\r
+            "display": "Chapter 29",\r
+            "filename": "Z100123506_0030_C0029.mp3",\r
+            "minutes": 8.81,\r
+            "size": 3177248,\r
+            "duration": "00:08:48"\r
+          },\r
+          {\r
+            "id": 3228904,\r
+            "display": "Chapter 30",\r
+            "filename": "Z100123506_0031_C0030.mp3",\r
+            "minutes": 1.61,\r
+            "size": 586112,\r
+            "duration": "00:01:36"\r
+          },\r
+          {\r
+            "id": 3228905,\r
+            "display": "Chapter 31",\r
+            "filename": "Z100123506_0032_C0031.mp3",\r
+            "minutes": 12.38,\r
+            "size": 4457264,\r
+            "duration": "00:12:22"\r
+          },\r
+          {\r
+            "id": 3228906,\r
+            "display": "Chapter 32",\r
+            "filename": "Z100123506_0033_C0032.mp3",\r
+            "minutes": 1.71,\r
+            "size": 618512,\r
+            "duration": "00:01:42"\r
+          },\r
+          {\r
+            "id": 3228907,\r
+            "display": "Chapter 33",\r
+            "filename": "Z100123506_0034_C0033.mp3",\r
+            "minutes": 11.48,\r
+            "size": 4135856,\r
+            "duration": "00:11:28"\r
+          },\r
+          {\r
+            "id": 3228908,\r
+            "display": "Chapter 34",\r
+            "filename": "Z100123506_0035_C0034.mp3",\r
+            "minutes": 1.23,\r
+            "size": 445712,\r
+            "duration": "00:01:13"\r
+          },\r
+          {\r
+            "id": 3228909,\r
+            "display": "Chapter 35",\r
+            "filename": "Z100123506_0036_C0035.mp3",\r
+            "minutes": 6.06,\r
+            "size": 2186672,\r
+            "duration": "00:06:03"\r
+          }\r
+        ],\r
+        "seriesPosition": "0",\r
+        "ratingCount": "0",\r
+        "hasFixedFormat": false\r
+      }\r
+    },\r
+    {\r
+      "interest": {\r
+        "stateId": 3,\r
+        "isOwned": true,\r
+        "isAvailable": false,\r
+        "name": "library"\r
+      },\r
+      "item": {\r
+        "authors": [\r
+          {\r
+            "facet": "author",\r
+            "text": "Michael Connelly",\r
+            "token": "michael-connelly",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "images": [\r
+          {\r
+            "name": "medium",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00276551/EB00276551_image_95x140.jpg"\r
+          },\r
+          {\r
+            "name": "large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00276551/EB00276551_image_128x192.jpg"\r
+          },\r
+          {\r
+            "name": "x-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00276551/EB00276551_image_148x230.jpg"\r
+          },\r
+          {\r
+            "name": "xx-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00276551/EB00276551_image_512x512_iTunes.png"\r
+          }\r
+        ],\r
+        "id": "5b3dd11819bf353454a31ad5",\r
+        "isbn": "9780316136167",\r
+        "subtitle": "Volume 2: The Last Coyote, Trunk Music, Angels Flight",\r
+        "publisher": {\r
+          "facet": "publisher",\r
+          "text": "Little, Brown and Company",\r
+          "token": "little-brown-and-company",\r
+          "order": 0\r
+        },\r
+        "genres": [\r
+          {\r
+            "facet": "genre",\r
+            "text": "Suspense Thriller",\r
+            "token": "suspense-thriller",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "language": "English",\r
+        "audience": "Adult",\r
+        "mediaType": "eBook",\r
+        "releasedDate": "2014-04-16T04:00:00Z",\r
+        "series": {\r
+          "count": 0,\r
+          "facet": "series",\r
+          "text": "Harry Bosch",\r
+          "token": "harry-bosch",\r
+          "order": 0\r
+        },\r
+        "bookTitle": {\r
+          "facet": "title",\r
+          "text": "The Harry Bosch Novels",\r
+          "token": "the-harry-bosch-novels",\r
+          "order": 0\r
+        },\r
+        "title": "The Harry Bosch Novels",\r
+        "isFiction": true,\r
+        "hasSubtitle": true,\r
+        "hasAttachments": false,\r
+        "hasDrm": true,\r
+        "preReleaseOn": "2014-04-04T04:00:00Z",\r
+        "scheduledReleaseOn": "2014-04-10T04:00:00Z",\r
+        "isPreRelease": false,\r
+        "shortDescription": "The Last Coyote: LAPD homicide detective Harry Bosch is suspended from the force for attacking his commanding officer. Unable to remain idle, he investigates the...",\r
+        "sortAuthor": "connelly michael",\r
+        "sortTitle": "harry-bosch-novels",\r
+        "seriesPosition": "21",\r
+        "ratingCount": "0",\r
+        "hasFixedFormat": false\r
+      }\r
+    },\r
+    {\r
+      "interest": {\r
+        "stateId": 3,\r
+        "isOwned": true,\r
+        "isAvailable": false,\r
+        "name": "library"\r
+      },\r
+      "item": {\r
+        "authors": [\r
+          {\r
+            "facet": "author",\r
+            "text": "Victor L. Wooten",\r
+            "token": "victor-l-wooten",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "narrators": [\r
+          {\r
+            "facet": "narrator",\r
+            "text": "Victor L. Wooten",\r
+            "token": "victor-l-wooten",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "images": [\r
+          {\r
+            "name": "medium",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100031458/Z100031458_image_95x140.jpg"\r
+          },\r
+          {\r
+            "name": "large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100031458/Z100031458_image_128x192.jpg"\r
+          },\r
+          {\r
+            "name": "x-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100031458/Z100031458_image_148x230.jpg"\r
+          },\r
+          {\r
+            "name": "xx-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/Z100031458/Z100031458_image_512x512_iTunes.png"\r
+          }\r
+        ],\r
+        "id": "5b3dd0d619bf353454a13d88",\r
+        "isbn": "9781400198177",\r
+        "subtitle": "A Spiritual Search For Growth Through Music",\r
+        "publisher": {\r
+          "facet": "publisher",\r
+          "text": "Tantor Media, Inc",\r
+          "token": "tantor-media-inc",\r
+          "order": 0\r
+        },\r
+        "genres": [\r
+          {\r
+            "facet": "genre",\r
+            "text": "Arts Entertainment",\r
+            "token": "arts-entertainment",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "genre",\r
+            "text": "Social Science",\r
+            "token": "social-science",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "genre",\r
+            "text": "Religion",\r
+            "token": "religion",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "genre",\r
+            "text": "Self Help",\r
+            "token": "self-help",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "genre",\r
+            "text": "Inspirational Nonfiction",\r
+            "token": "inspirational-nonfiction",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "language": "English",\r
+        "audience": "Adult",\r
+        "mediaType": "eAudio",\r
+        "releasedDate": "2012-11-28T05:00:00Z",\r
+        "fileSize": "160653072",\r
+        "duration": "07:26:07",\r
+        "bookTitle": {\r
+          "facet": "title",\r
+          "text": "The Music Lesson",\r
+          "token": "the-music-lesson",\r
+          "order": 0\r
+        },\r
+        "title": "The Music Lesson",\r
+        "isFiction": false,\r
+        "hasSubtitle": true,\r
+        "hasAttachments": false,\r
+        "hasDrm": true,\r
+        "preReleaseOn": "2010-06-07T04:00:00Z",\r
+        "scheduledReleaseOn": "2010-06-07T04:00:00Z",\r
+        "isPreRelease": false,\r
+        "shortDescription": "\"Boy, do I have a lot to learn!\" Anyone who's ever picked up a musical instrument of any kind-from the first caveman banging rocks to that little kid at the guitar...",\r
+        "sortAuthor": "wooten l",\r
+        "sortTitle": "music-lesson",\r
+        "sortNarrator": "wooten l",\r
+        "audioFiles": [\r
+          {\r
+            "id": 93299,\r
+            "display": "Introduction",\r
+            "filename": "Z100031458_001_IN.mp3",\r
+            "minutes": 15.56,\r
+            "size": 5607248,\r
+            "duration": "00:15:33"\r
+          },\r
+          {\r
+            "id": 93300,\r
+            "display": "Chapter 1",\r
+            "filename": "Z100031458_002_C001.mp3",\r
+            "minutes": 32.60,\r
+            "size": 11740784,\r
+            "duration": "00:32:36"\r
+          },\r
+          {\r
+            "id": 93301,\r
+            "display": "Chapter 2",\r
+            "filename": "Z100031458_003_C002.mp3",\r
+            "minutes": 22.81,\r
+            "size": 8214152,\r
+            "duration": "00:22:48"\r
+          },\r
+          {\r
+            "id": 93302,\r
+            "display": "Chapter 3",\r
+            "filename": "Z100031458_004_C003.mp3",\r
+            "minutes": 39.10,\r
+            "size": 14079416,\r
+            "duration": "00:39:06"\r
+          },\r
+          {\r
+            "id": 93303,\r
+            "display": "Chapter 4",\r
+            "filename": "Z100031458_005_C004.mp3",\r
+            "minutes": 36.76,\r
+            "size": 13236368,\r
+            "duration": "00:36:45"\r
+          },\r
+          {\r
+            "id": 93304,\r
+            "display": "Chapter 5",\r
+            "filename": "Z100031458_006_C005.mp3",\r
+            "minutes": 35.75,\r
+            "size": 12875216,\r
+            "duration": "00:35:45"\r
+          },\r
+          {\r
+            "id": 93305,\r
+            "display": "Chapter 6",\r
+            "filename": "Z100031458_007_C006.mp3",\r
+            "minutes": 45.28,\r
+            "size": 16306592,\r
+            "duration": "00:45:16"\r
+          },\r
+          {\r
+            "id": 93306,\r
+            "display": "Chapter 7",\r
+            "filename": "Z100031458_008_C007.mp3",\r
+            "minutes": 24.11,\r
+            "size": 8682224,\r
+            "duration": "00:24:06"\r
+          },\r
+          {\r
+            "id": 93307,\r
+            "display": "Chapter 8",\r
+            "filename": "Z100031458_009_C008.mp3",\r
+            "minutes": 29.10,\r
+            "size": 10480640,\r
+            "duration": "00:29:06"\r
+          },\r
+          {\r
+            "id": 93308,\r
+            "display": "Chapter 9",\r
+            "filename": "Z100031458_010_C009.mp3",\r
+            "minutes": 28.45,\r
+            "size": 10245848,\r
+            "duration": "00:28:27"\r
+          },\r
+          {\r
+            "id": 93309,\r
+            "display": "Chapter 10",\r
+            "filename": "Z100031458_011_C010.mp3",\r
+            "minutes": 32.06,\r
+            "size": 11547680,\r
+            "duration": "00:32:03"\r
+          },\r
+          {\r
+            "id": 93310,\r
+            "display": "Chapter 11",\r
+            "filename": "Z100031458_012_C011.mp3",\r
+            "minutes": 33.41,\r
+            "size": 12031952,\r
+            "duration": "00:33:24"\r
+          },\r
+          {\r
+            "id": 93311,\r
+            "display": "Chapter 12",\r
+            "filename": "Z100031458_013_C012.mp3",\r
+            "minutes": 20.96,\r
+            "size": 7549088,\r
+            "duration": "00:20:57"\r
+          },\r
+          {\r
+            "id": 93312,\r
+            "display": "Chapter 13",\r
+            "filename": "Z100031458_014_C013.mp3",\r
+            "minutes": 23.05,\r
+            "size": 8301848,\r
+            "duration": "00:23:03"\r
+          },\r
+          {\r
+            "id": 93313,\r
+            "display": "Chapter 14",\r
+            "filename": "Z100031458_015_C014.mp3",\r
+            "minutes": 27.08,\r
+            "size": 9754016,\r
+            "duration": "00:27:04"\r
+          }\r
+        ],\r
+        "seriesPosition": "0",\r
+        "ratingCount": "0",\r
+        "hasFixedFormat": false\r
+      }\r
+    },\r
+    {\r
+      "interest": {\r
+        "stateId": 3,\r
+        "isOwned": true,\r
+        "isAvailable": true,\r
+        "name": "library"\r
+      },\r
+      "item": {\r
+        "authors": [\r
+          {\r
+            "facet": "author",\r
+            "text": "Victor L. Wooten",\r
+            "token": "victor-l-wooten",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "images": [\r
+          {\r
+            "name": "medium",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00400981/EB00400981_image_95x140.jpg"\r
+          },\r
+          {\r
+            "name": "large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00400981/EB00400981_image_128x192.jpg"\r
+          },\r
+          {\r
+            "name": "x-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00400981/EB00400981_image_148x230.jpg"\r
+          },\r
+          {\r
+            "name": "xx-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00400981/EB00400981_image_512x512_iTunes.png"\r
+          }\r
+        ],\r
+        "id": "5b3dd12119bf353454a37f75",\r
+        "isbn": "9781440637698",\r
+        "subtitle": "A Spiritual Search For Growth Through Music",\r
+        "publisher": {\r
+          "facet": "publisher",\r
+          "text": "Berkley",\r
+          "token": "berkley",\r
+          "order": 0\r
+        },\r
+        "genres": [\r
+          {\r
+            "facet": "genre",\r
+            "text": "Arts Entertainment",\r
+            "token": "arts-entertainment",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "genre",\r
+            "text": "Self Help",\r
+            "token": "self-help",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "language": "English",\r
+        "audience": "Adult",\r
+        "mediaType": "eBook",\r
+        "releasedDate": "2014-06-11T04:00:00Z",\r
+        "bookTitle": {\r
+          "facet": "title",\r
+          "text": "The Music Lesson",\r
+          "token": "the-music-lesson",\r
+          "order": 0\r
+        },\r
+        "title": "The Music Lesson",\r
+        "isFiction": false,\r
+        "hasSubtitle": true,\r
+        "hasAttachments": false,\r
+        "hasDrm": true,\r
+        "preReleaseOn": "2014-06-04T04:00:00Z",\r
+        "scheduledReleaseOn": "2014-06-05T04:00:00Z",\r
+        "isPreRelease": false,\r
+        "shortDescription": "From Grammy-winning musical icon and legendary bassist Victor L. Wooten comes The Music Lesson, the story of a struggling young musician who wanted music to be his...",\r
+        "sortAuthor": "wooten l",\r
+        "sortTitle": "music-lesson",\r
+        "seriesPosition": "0",\r
+        "ratingCount": "0",\r
+        "hasFixedFormat": false\r
+      }\r
+    },\r
+    {\r
+      "interest": {\r
+        "stateId": 3,\r
+        "isOwned": true,\r
+        "isAvailable": false,\r
+        "name": "library"\r
+      },\r
+      "item": {\r
+        "authors": [\r
+          {\r
+            "facet": "author",\r
+            "text": "Michael Connelly",\r
+            "token": "michael-connelly",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "images": [\r
+          {\r
+            "name": "medium",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00283788/EB00283788_image_95x140.jpg"\r
+          },\r
+          {\r
+            "name": "large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00283788/EB00283788_image_128x192.jpg"\r
+          },\r
+          {\r
+            "name": "x-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00283788/EB00283788_image_148x230.jpg"\r
+          },\r
+          {\r
+            "name": "xx-large",\r
+            "url": "https://d2cv0ie6dlin9h.cloudfront.net/EB00283788/EB00283788_image_512x512_iTunes.png"\r
+          }\r
+        ],\r
+        "id": "5b3dd11a19bf353454a32b95",\r
+        "isbn": "9780316135870",\r
+        "publisher": {\r
+          "facet": "publisher",\r
+          "text": "Little, Brown and Company",\r
+          "token": "little-brown-and-company",\r
+          "order": 0\r
+        },\r
+        "genres": [\r
+          {\r
+            "facet": "genre",\r
+            "text": "Mystery",\r
+            "token": "mystery",\r
+            "order": 0\r
+          },\r
+          {\r
+            "facet": "genre",\r
+            "text": "Suspense Thriller",\r
+            "token": "suspense-thriller",\r
+            "order": 0\r
+          }\r
+        ],\r
+        "language": "English",\r
+        "audience": "Adult",\r
+        "mediaType": "eBook",\r
+        "releasedDate": "2014-05-01T04:00:00Z",\r
+        "series": {\r
+          "count": 0,\r
+          "facet": "series",\r
+          "text": "Harry Bosch",\r
+          "token": "harry-bosch",\r
+          "order": 0\r
+        },\r
+        "bookTitle": {\r
+          "facet": "title",\r
+          "text": "Trunk Music",\r
+          "token": "trunk-music",\r
+          "order": 0\r
+        },\r
+        "title": "Trunk Music",\r
+        "isFiction": true,\r
+        "hasSubtitle": false,\r
+        "hasAttachments": false,\r
+        "hasDrm": true,\r
+        "preReleaseOn": "2014-04-09T04:00:00Z",\r
+        "scheduledReleaseOn": "2014-04-15T04:00:00Z",\r
+        "isPreRelease": false,\r
+        "shortDescription": "Back on the job after an involuntary leave of absence, LAPD homicide detective Harry Bosch is ready for a challenge. But his first case is a little more than he...",\r
+        "sortAuthor": "connelly michael",\r
+        "sortTitle": "trunk-music",\r
+        "seriesPosition": "21",\r
+        "ratingCount": "0",\r
+        "hasFixedFormat": false\r
+      }\r
+    }\r
+  ]\r
+}
\ No newline at end of file