ArcaneBooks – PowerShell and the Advanced OpenLibrary ISBN API

Introduction

This post continues my series on my ArcaneBooks project. For a background see my post The ArcaneBooks Project – An Introduction.

For this project I am using the OpenLibrary.org website, which provides two web APIs to access book data based on the ISBN. OpenLibrary is sponsored by the InternetArchive.

In a previous post, ArcaneBooks – ISBN Overview, PowerShell, and the Simple OpenLibrary ISBN API, I covered the use of the first API which I nicknamed the Simple API as it is a bit easier to use and dissect the results. I also provided a background on what the ISBN is and how it is formed.

In this post I’ll dive into the more complex of the APIs, what I call the Advance API.

Be aware the use of Simple and Advance are my terms, so I can easily distinguish between the two. They are not terms used by the OpenLibrary.

The Advanced OpenLibrary API

The format of the Advanced API is slightly different from the simple. Here is template.

https://openlibrary.org/api/books?bibkeys=ISBN:[ISBN Goes Here]&jscmd=data&format=json"

You will replace the [ISBN Goes Here] text with the ISBN number you want to look up. Be aware this can only be digits, you must remove any spaces, dashes, or other characters.

Let’s look at a code example of calling the API and getting all its properties.

Calling The API with PowerShell

First, set an ISBN to lookup. We’ll include some dashes for the demo. The title of the book is "Your HF Digital Companion"

$ISBN = '0-87259-481-5'

Now remove any spaces or dashes, then create the URL.

$isbnFormatted = $ISBN.Replace('-', '').Replace(' ', '')
$baseURL = "https://openlibrary.org/api/books?bibkeys=ISBN:"
$urlParams = "&jscmd=data&format=json"
$url = "$($baseURL)$($isbnFormatted)$($urlParams)"

Now let’s call the URL and put the data into a variable.

$bookData = Invoke-RestMethod $url

If we look at the data held by the variable, we get back a single column. That column holds JSON formatted data. (Note I truncated the XML for readability purposes.)

$bookData

This is the output of displaying the variable.

ISBN:0872594815
---------------
@{url=https://openlibrary.org/books/OL894295M/Your_HF_digital_companion; key=/books/OL894295M; title=Your HF digital companion; authors=System.Object[]; number_of_pages=197; …

We could address the data like:

$bookData.'ISBN:0872594815'.Title

Note we had to wrap the ISBN number in quotes since a colon : isn’t an allowed in property names. However, when we make the call the ISBN isn’t set in stone.

But we do have it in a variable, and we can use string interpolation to format the property.

$bookData."ISBN:$isbnformatted".title

This returns "Your HF digital companion". And yes, the words "digital" and "companion" should normally be capitalized, but this is the way the title comes from OpenLibrary.

Now that we have the formatting for the property name down, we can get the other properties. Note that not all properties that are returned will have data.

$ISBN10 = $bookData."ISBN:$isbnformatted".identifiers.isbn_10
$ISBN13 = $bookData."ISBN:$isbnformatted".identifiers.isbn_13
$Title = $bookData."ISBN:$isbnformatted".title
$LCCN = $bookData."ISBN:$isbnformatted".identifiers.lccn
$NumberOfPages = $bookData."ISBN:$isbnformatted".number_of_pages
$PublishDate = $bookData."ISBN:$isbnformatted".publish_date
$LibraryOfCongressClassification = $bookData."ISBN:$isbnformatted".classifications.lc_classifications
$DeweyDecimalClass = $bookData."ISBN:$isbnformatted".classifications.dewey_decimal_class
$Notes = $bookData."ISBN:$isbnformatted".notes
$CoverUrlSmall = $bookData."ISBN:$isbnformatted".cover.small
$CoverUrlMedium = $bookData."ISBN:$isbnformatted".cover.medium
$CoverUrlLarge = $bookData."ISBN:$isbnformatted".cover.large

The ByStatement sometimes begins with the word "By ". If so we want to remove it. However if we try and do a replace and the by_statement column is null, attempting to call the Replace method will result in an error. So first we have to check for null, and only if the by_statement isn’t null do we attempt to do a replace.

if ($null -eq $bookData."ISBN:$isbnformatted".by_statement)
  { $ByStatement = '' }
else
  { $ByStatement = $bookData."ISBN:$isbnformatted".by_statement.Replace('by ', '') }

For the remaining data, each item can have multiple entries attached. For example, a book could have multiple authors. For our purposes we will just combine into a single entry.

We’ll create a new variable of type StringBuilder, then loop over the list of items in the JSON, combining them into a single string.

In the if, we check to see if the string already has data, if so we append a comma before adding the second (or more) authors name.

Finally we use the ToString method of the StringBuilder class to convert the value back into a standard string data type.

Books can have multiple authors, as stated each is returned in its own item in an array. This code will combine them into a single string.

Note that when we call the Append method of the StringBuilder class, we need to prepend it with [void], otherwise it will send output to the console which we don’t want.

$authors = [System.Text.StringBuilder]::new()
foreach ($a in $bookData."ISBN:$isbnformatted".authors)
{
  if ($authors.Length -gt 1)
    { [void]$authors.Append(", $($a.name)") }
  else
    { [void]$authors.Append($a.name) }
}
$Author = $authors.ToString()

Subjects can be an array, let’s combine them into a single string.

$subjects = [System.Text.StringBuilder]::new()
foreach ($s in $bookData."ISBN:$isbnformatted".subjects)
{
  if ($subjects.Length -gt 1)
    { [void]$subjects.Append(", $($s.name)") }
  else
    { [void]$subjects.Append($s.name) }
}
$Subject = $subjects.ToString()

A book could have multiple publishers over time. The author could shift to a new publisher, or more likely a publishing house could be purchases and the new owners name used. The data is returned as an array, so combine them as we did with authors and subjects.

$thePublishers = [System.Text.StringBuilder]::new()
foreach ($p in $bookData."ISBN:$isbnformatted".publishers)
{
  if ($thePublishers.Length -gt 1)
    { [void]$thePublishers.Append(", $($p.name)") }
  else
    { [void]$thePublishers.Append($p.name) }
}
$Publishers = $thePublishers.ToString()

Since there could be multiple publishers, logically there could be multiple publishing locations. This will combine them into a single string.

$locations = [System.Text.StringBuilder]::new()
foreach ($l in $bookData."ISBN:$isbnformatted".publish_places)
{
  if ($locations.Length -gt 1)
    { [void]$locations.Append(", $($l.name)") }
  else
    { [void]$locations.Append($l.name) }
}
$PublisherLocation = $locations.ToString()

Now print out all the returned data.

$ISBN10
$ISBN13
$Title
$LCCN
$NumberOfPages
$PublishDate
$LibraryOfCongressClassification
$DeweyDecimalClass
$Notes
$CoverUrlSmall
$CoverUrlMedium
$CoverUrlLarge
$ByStatement
$Author
$Subject
$Publishers
$PublisherLocation

The Output

Here is the output, I put it into a table for easier reading.

Item Value
ISBN10 95185134
ISBN13 [Missing Value]
Title Your HF digital companion
LCCN [Missing Value]
Number of Pages 197
Publish Date 1995
LibraryOfCongressClassification TK5745 .F572 1995
DeweyDecimalClass 004.6/4
Notes Includes bibliographical references.
Based on Your RTTY/AMTOR companion. 1st ed. c1993.
CoverUrlSmall https://covers.openlibrary.org/b/id/12774631-S.jpg
CoverUrlMedium https://covers.openlibrary.org/b/id/12774631-M.jpg
CoverUrlLarge https://covers.openlibrary.org/b/id/12774631-L.jpg
ByStatement Steve Ford.
Author Steve Ford
Subject Radiotelegraph, Amateurs’ manuals
Publishers American Radio Relay League
PublisherLocation Newington, CT

See Also

The following operators and functions were used or mentioned in this article’s demos. You can learn more about them in some of my previous posts, linked below.

Fun With PowerShell Logic Branching

Fun With PowerShell Loops

Fun With PowerShell Strings

Fun With PowerShell String Formatting

Conclusion

In this post we saw how to use what I call the advanced API offered by OpenLibrary to retrieve book data based on the ISBN.

In the next post we’ll see how to get book data based on the Library Of Congress Catalog Number, using PowerShell and the Library of Congresses web API.

The demos in this series of blog posts was inspired by my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows, one of many PowerShell courses I have on Pluralsight. All of my courses are linked on my About Me page.

If you don’t have a Pluralsight subscription, just go to my list of courses on Pluralsight . At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site.

Advertisement

The ArcaneBooks Project – An Introduction

Introduction

As some of you may know, I’ve been a ham (amateur) radio operator since 1999, holding the call sign N4IXT. I’m a member of several clubs, including the Birmingham Amateur Radio Club, the Shelby County Amateur Radio Club (where I’m also the webmaster), and the Amateur Radio Relay League (ARRL), in which I am a life member.

More importantly for this post, I am a member of the Alabama Historical Radio Society. We are beginning a project to catalog our exhibits and library into cloud based software named PastPerfect. As part of this effort we’ll be entering data for our extensive library into the software.

Naturally we want to automate as much of this as possible, since the collection is rather extensive. Some of our books are so old they have neither an ISBN (International Standard Book Number) or a Library of Congress Catalog Number (LCCN for short). Others have only the LCCN, the newer books have an ISBN, and a very few have both.

In the process of meeting with other museums I learned this is a need for many other organizations. So I decided to do something about it.

I plan to create a PowerShell module with cmdlets that can retrieve book metadata, such as title, author, and the like. This module will then be made available as on open source project on my website so other groups can use it as well.

As a source a user can pass in either an ISBN or LCCN number, or better yet pipe in an entire list of numbers from a text file, and generate book data.

The sources we’ll use are the Library of Congress and the Open Library site, which is part of the Internet Archive. Both provide web APIs we can use to retrieve data, and we’ll document that information in upcoming posts.

Why PowerShell?

You may be wondering why I chose PowerShell for this project. There were several good reasons.

First, and people often forget this, PowerShell is multi-platform. It can run on Windows, MacOS, and Linux. If you want to learn more on this you should watch my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows.

Next, the PowerShell code is viewable by anyone. Any user can download the code and easily examine it before running. This should address security concerns by many organizations.

The third reason is readability. As many will point out, there are other languages such as Python that will meet the above needs. In general though, code from other languages can be hard to read and execute for people who aren’t developers. I’m imagining my module will be used by many people with only a basic understanding of tech. As such a simple command like Get-BookByISBN -ISBN 1234567890 will be much easier to use.

Finally, well hey I just love PowerShell! As I need to turn this project around quickly I wanted to use something I already know and love.

The Plan

In the next two posts I will cover what ISBNs and LCCNs are, and the web APIs (Application Programming Interface) that we’ll use to get the data.

I’ll then begin a series of posts documenting the PowerShell code needed to retrieve the book data, and how you can use the book data for your organization.

The series will wrap up with the creation of the ArcaneBooks PowerShell Module, and its publication to my Github site.

Kusto Will Return!

For those of you who have been following Kusto Query Language series over the last few years, don’t worry it will return! I’m just taking a short diversion for the next month or so to document this project. Then we’ll return to the world of Kusto.

Conclusion

In this post I established the groundwork for my new ArcaneBooks PowerShell project. In the next few posts we’ll cover terms and data sources, then look at the PowerShell code needed to achieve our results.

I have a long series of blog posts on PowerShell, you’ll find them listed at my Fun With PowerShell Roundup

If you want to take a deeper dive into PowerShell, I have many PowerShell courses at Pluralsight, you’ll find them listed on my About Me page.

One course that may be especially helpful is my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows, as it dives into the creation of functions, modules, and more.

If you don’t have a Pluralsight subscription, just go to my list of courses on Pluralsight . At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site.

Books That Changed My Career / Life – CodeStock 2011 Open Spaces

At this years CodeStock conference in Knoxville we had a very active open spaces area. The session I suggested and helped with was on “Books That Changed My Career / Life”. As a group we came up with a list of books that had made an impact on lives. Our only rule was it couldn’t be directly tech, for example a book like SQL Server MVP Deep Dives. (#shamelessplug)

The list was quite surprising. Of course there were some of the classics like the 7 Habits book, or tech related books such as Code by Charles Petzold, who was also the keynote speaker. Also not a surprise were some motivational books, such as those by Seth Godin.

The rest of the list had some surprises, at least for me. There were several works of fiction included, because the participants said it revealed new ways of thinking to them.

So without any more fanfare, here is the list in the order presented. When the author was known, I put their name next to the title after the dash. For any authors out there whose names I’ve misspelled, my apologies. Book titles were being flung out fast and furious and I may have missed the correct spelling. Also in some cases the book author wasn’t known at the time the list was being compiled.

At some point I hope to clean this list up, sort it into groups and add hyperlinks to sites where the book can be obtained. Since I didn’t want to delay publishing the list however, I present it below as it was created at the open spaces session. If you were in attendance, a big thanks! And if you have any corrections please feel free to leave a comment below, it’d be a big help to me and everyone who attended or sees this list.

Rework – Hasson & Fried

Tribes – Seth Godin

Linchpin – Seth Godin

Less – Mark Lesser

Zen and the Art of Motorcycle Maintenance – Robert Pirsig

The Tao of Pooh – Benjamin Hoff

Who Moved My Cheese

Aramis, or For the Love of Technology – Bruno Latour

Tick Tock – James Patterson

Crush It – Vaynerchuck

Secrets of a Buccaneer Scholar

In the Beginning Was The Command Line – Neil Stephenson

How to Win Friends and Influence People

Atlas Shrugged – Ayn Rand

Anthem – Ayn Rand

Libertarianism – Boaz

Leaves of Grass – Lewsky

Cuckoo’s Egg – Clifford Stole

Rouge Warriors Strategy Guide to Success – Richard Marcinko

Elements of Style – Strunk and White

The War of Art – Pressfield

Getting Real

The E-Myth

Enders Game

Griftopia – Taibbi

Last Lecture – Randy Pausch

On Writing – Stephen King

The Hardboiled Wonderland and the End Of The World

Here Comes Everybody

The Way of the Peaceful Warrior – Milman

7 Habits of Highly Successful People

Hackers

Hackers and Painters – Paul Graham

Slideology

Resonate

Beautiful Visualizations

Presentation Zen – Reynolds

The Romans – Richard Talbert

Influence – Cialdini

Socratic Selling

The God Who Was There – Francis Schaffer

The Shack

Hard Drive

The Goal – Elihayu Goldratt

Beyond the Goal – Elihayu Goldratt

Dreaming in Code

4 Hour Work Week

Cognitive Surplus

Do The Work – Pressfield

Pragmatic Thinking and Learning

Makers – Cory Doctorow

Down and Out in the Magic Kingdom– Cory Doctorow

Daemon – Daniel Suarez

Freedom – Daniel Suarez

Total Money Makeover – Dave Ramsey

Anathem – Neil Stephenson

The Second Son – Charles Sailor

Rich Dad Poor Dad

You Are Not A Gadget

Drive – Daniel Pink

Millionaire Mind

Code – Charles Petzold

 

Video mentions

In addition to the list of above books, two video series were recommended. These titles are below.

Business of Software by Kathy Sierra

Webstock – An Australian based conference that makes their videos available for later viewing