Gutenovox

Searches the Project Gutenberg catalog and shows which works have been recorded in Librivox. Some recordings do not show up, so double-check against the official LibriVox catalog to be sure. Click on column headings to sort.

 

Search categories:

Search last name:  


setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db_lv = new PDO ('sqlite:./librivox.sqlite3'); $db_lv -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt; if ($_GET['author'] !='') { // TODO: insert three character limit on searches $contributors = array(); // need to keep track so as to be able to combine ids for those that are both author and contributor $stmt_co = $db_gb->prepare ("select * from contributors where name like :author_name order by name"); $stmt_co->bindValue (':author_name', '%' . $_GET['author'] . '%'); $stmt_co->execute(); while ($row = $stmt_co->fetch(PDO::FETCH_ASSOC) ) { $contributors[$row['id']] = $row['name'];; $n++; } $stmt = $db_gb->prepare ("select * from creators where name like :author_name order by name"); $stmt->bindValue (':author_name', '%' . $_GET['author'] . '%'); $stmt->execute(); echo ""; $n=0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { $co_id = array_search ($row['name'], $contributors); // returns contributor key if it exists for this name, otherwise returns false if ( $co_id == false ) { $co_id = null; // no contributor, so putting blank for parameter } else { unset ($contributors[$co_id]); // we now have this persons id in $co_id, now remove from the $contributors array so they don't come up again in the contributors-only table } echo ""; $n++; } if ( $n == 0 ) echo "No authors found like '". $_GET['author'].".'"; echo "
Author
" . $row['name'] . "
"; // finding as contributors echo ""; $n=0; foreach ( $contributors as $co_id=>$co_name ) { echo ""; $n++; } if ( $n == 0 ) echo ""; echo "
Contributor
" . $co_name . "
No contributors found like '". $_GET['author'].".'
"; /* */ } // end author if ($_GET['lcsh'] != '' ) { $stmt = $db_gb->prepare ("SELECT * from lcsh_subjects WHERE id=:lcsh_id"); $stmt->bindValue(':lcsh_id', $_GET['lcsh']); $stmt->execute(); $category = "not found"; if ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { $category = $row['name']; } $stmt = $db_gb->prepare ("SELECT b.mtype_id, c.name, c.id, b.etext_id, b.data FROM books AS b JOIN lcsh2books AS l2b ON l2b.book_id = b.id JOIN creators AS c ON c2b.creator_id = c.id JOIN creators2books AS c2b ON c2b.book_id = b.id WHERE l2b.lcsh_id=:lcsh_id AND b.rights='G'"); $stmt->bindValue(':lcsh_id', $_GET['lcsh']); $stmt->execute(); $first = true; while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { if ( $first ) { echo "Category: $category

 

"; echo ""; echo ""; $first = false; } if ( $row['mtype_id'] != '') continue; // audiobooks $title = $row ['data']; $title = substr ( $title, strpos ( $title, '{"title":["') + 11 ); // sqlite database title capped to 255 chars but 'data' field isn't, so need to get title from data field $title = substr ( $title, 0, strpos ( $title, "\"]") ); $title = str_replace ( '\n', " - ", $title); $title = str_replace ( '\"', "\"", $title); // echo "" ; } echo "
AuthorTitleLibriVox RecordingsEst. Read Time
" . $row['name'] . " " . $title . " "; echo "
" . $row['name'] . " " . $title . " "; // to see gutenberg ids $recording_urls = getLVRecordingsByTitle ($title, $row['name']); if ( ! empty ($recording_urls) ) { $n = 1; foreach ( $recording_urls as $recording_url ) { echo "[" . $n . "] "; $n++; } } else echo "None found"; $times = getReadTimeForEtext ($row['etext_id']); echo " "; echo $times['readable'] . "
"; } if ($_GET['title'] != '' ) { } // end title if ($_GET['cat_search'] != '' ) { echo ""; $stmt = $db_gb->prepare ( "select * from lcsh_subjects where name like :subject"); $stmt->bindValue ( ':subject', "%" . $_GET['cat_search'] . "%" ); $stmt->execute (); $n = 0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { echo ""; $n++; } echo "
Categories like ".$_GET['cat_search']."
" . $row['name']. "
"; if ( $n == 0 ) echo "No categories found like '". $_GET['cat_search'].".'"; } if ( $_GET['author_gid'] !='' || $_GET['contrib_gid'] !='' ) { // getting all books for a gutenberg author id if ( $_GET['author_gid'] !='' ) { $stmt = $db_gb->prepare ("SELECT b.mtype_id, c.name, b.id, b.etext_id, b.data FROM books AS b JOIN creators2books AS c2b ON c2b.book_id = b.id JOIN creators AS c ON c2b.creator_id = c.id WHERE c2b.creator_id=:gid AND b.rights='G'"); $stmt->bindValue (':gid', $_GET['author_gid']); $stmt->execute(); $first = true; while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { if ( $row['mtype_id'] != '') continue; // audiobooks and other nonbook media if ( $first ) { echo ""; echo ""; // echo ""; echo ""; $first = false; if (strpos ( $row['name'], "," ) == false) { $author_last = $row['name']; } else { $author_last = substr ( $row['name'], 0, strpos ( $row['name'], "," ) ); } $librivox_retval = file_get_contents ('https://librivox.org/api/feed/audiobooks?author=' . $author_last . '&format=serialized&fields={id,title,authors,url_text_source,url_librivox}' ); $librivox_array = unserialize ($librivox_retval); $librivox_entries = $librivox_array['books']; } $title = $row ['data']; $title = substr ( $title, strpos ( $title, '{"title":["') + 11 ); // sqlite database title capped to 255 chars but 'data' field isn't, so need to get title from data field $title = substr ( $title, 0, strpos ( $title, "\"]") ); $title = str_replace ( '\n', " - ", $title); $title = str_replace ( '\"', "\"", $title); // echo ""; } echo "
Titles by ".$row['name']."   LibriVox recordings  Est. Read Timeetext_id
$title (".$row['etext_id'].")"; // " . $title . " echo "
" . $title . ""; $recording_urls = getLVRecordingsForGID ( $librivox_entries, $row['etext_id'], $title ); if ( ! empty ($recording_urls) ) { $n = 1; foreach ( $recording_urls as $recording_url ) { echo "[" . $n . "] "; $n++; } } else echo "None found"; $times = getReadTimeForEtext ($row['etext_id']); echo " "; echo $times['readable'] . "
"; } // end author table if ( $_GET['contrib_gid'] !='' ) { $stmt = $db_gb->prepare ("SELECT b.mtype_id, c.name, b.id, b.etext_id, b.data FROM books AS b JOIN contributors2books AS c2b ON c2b.book_id = b.id JOIN contributors AS c ON c2b.contributor_id = c.id WHERE c2b.contributor_id=:cid"); $stmt->bindValue (':cid', $_GET['contrib_gid']); $stmt->execute(); $first = true; while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { if ( $row['mtype_id'] != '') continue; // audiobooks and other nonbook media if ( $first ) { echo ""; echo ""; $first = false; if (strpos ( $row['name'], "," ) == false) { $author_last = $row['name']; } else { $author_last = substr ( $row['name'], 0, strpos ( $row['name'], "," ) ); } $librivox_retval = file_get_contents ('https://librivox.org/api/feed/audiobooks?author=' . $author_last . '&format=serialized&fields={id,title,authors,url_text_source,url_librivox}' ); $librivox_array = unserialize ($librivox_retval); $librivox_entries = $librivox_array['books']; // echo "Entries for $author_last:
"; print_r ( $librivox_entries );	echo "
"; // for API testing } $title = $row ['data']; $title = substr ( $title, strpos ( $title, '{"title":["') + 11 ); // sqlite database title capped to 255 chars but 'data' field isn't, so need to get title from data field $title = substr ( $title, 0, strpos ( $title, "\"]") ); $title = str_replace ( '\n', " - ", $title); $title = str_replace ( '\"', "\"", $title); echo "" ; } echo "
".$row['name']." as contributor   LibriVox recordingsEst. Read Time
" . $title . ""; $recording_urls = getLVRecordingsForGID ( $librivox_entries, $row['etext_id'], $row['title'] ); if ( ! empty ($recording_urls) ) { $n = 1; foreach ( $recording_urls as $recording_url ) { echo "[" . $n . "] "; $n++; } } else echo "None found"; $times = getReadTimeForEtext ($row['etext_id']); echo " "; echo $times['readable'] . "
"; } // end contrib table } // end author/contrib_gid if } /** $librovox_list is associative array from librivox API $ebook_id is Project Gutenberg ebook id $gb_title is Project Gutenberg title @return array of librivox recording URLs for the book with the $ebook_id */ function getLVRecordingsForGID ( $librivox_list, $ebook_id, $gb_title ) { global $db_lv; $recordings = array (); // echo " -- Checking ebook_id: " . $ebook_id . " against " . count ( $librivox_list ) . " entries -- "; foreach ( $librivox_list as $librivox_entry ) { // want to move this to sqlite $text_url = $librivox_entry['url_text_source']; if ( $text_url != null ) { $text_url = str_replace ( 'ebooks', 'etext', $text_url ); $lv_ebook_id = substr ( $text_url, strpos ( $text_url, '/etext/') + 7 ); if ( $lv_ebook_id == $ebook_id ) $recordings['$ebook_id'] = $librivox_entry['url_librivox']; } } $stmt = $db_lv->prepare ("select s.author,s.title,s.parent_id,a.url_librivox from sections AS s JOIN audiobooks as a ON s.parent_id=a.id WHERE s.title=:title COLLATE NOCASE" ); $stmt->bindValue ( ':title', $gb_title ); $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { $recordings[$row['parent_id']] = $row['url_librivox']; // if ( ! array_key_exists ($row['parent_id'], $recordings) ) $recordings[$row['parent_id']] = $row['url_librivox']; } return $recordings; } function getLVRecordingsByTitle ( $title, $author ) { global $db_lv; $recordings = array (); $author_last = substr ( $title, 0, strpos ($author, ',')); $stmt = $db_lv->prepare ( "SELECT id, url_librivox FROM audiobooks WHERE title=:title COLLATE NOCASE;" ); $stmt->bindValue ( ':title', $title ); $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { $recordings[$row['id']] = $row['url_librivox']; // need to do some kind of author based checking here } $stmt = $db_lv->prepare ("SELECT s.author,s.title,s.parent_id,a.url_librivox FROM sections AS s JOIN audiobooks AS a ON s.parent_id=a.id WHERE s.title=:title COLLATE NOCASE" ); $stmt->bindValue ( ':title', $title ); $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { $recordings[$row['parent_id']] = $row['url_librivox']; // need to do some kind of author based checking here } return $recordings; } function getReadTimeForEtext ( $etext_id ) { global $db_gb; $retval = array(); $stmt = $db_gb->prepare ("SELECT * FROM files WHERE etext_id=:id" ); $stmt->bindValue (':id', $etext_id); $stmt->execute(); $file_size = -1; while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) { if ( endsWith ( $row['url'], 'txt' ) ) $file_size = $row['size']; } $file_size -= 18233; // Not counting gutenberg license if ( $file_size < 0 ) $file_size = 0; $retval['filesize'] = $file_size; // return ( round ($file_size/1421) . " mins" ); // if ( $file_size < 85260 ) return ( (round ($file_size/1421) ) . " mins"); $hours = floor ( ($file_size/900)/60 ); $minutes = (round ( $file_size/900) ) % 60; $retval['readable'] = "$hours h $minutes min"; if ( $file_size == 0 ) $retval['readable'] = "Unknown"; return $retval; } function endsWith($haystack, $needle) { $length = strlen($needle); if ($length == 0) { return true; } return (substr($haystack, -$length) === $needle); } ?>

 

About   |   Source code   |   Email   |   Librivox data: October 3, 2016   |   Gutenberg data: April 2014