Skip to content

Instantly share code, notes, and snippets.

@wvengen
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wvengen/e8b3386d9c6194c9a495 to your computer and use it in GitHub Desktop.
Save wvengen/e8b3386d9c6194c9a495 to your computer and use it in GitHub Desktop.
HTML Book matrix generator
#!/usr/bin/env ruby
#
# Basic script to retrieve book metadata.
#
# Usage: genbooks.rb <isbn> [<isbn> [...]] >books.json
# Outputs json file with book metadata, for use as input to genpage.rb
#
# TODO
# - add bol.com
# - add amazon.com books
#
# (c)2015 by wvengen, licensed under GPL version 3 or later
#
require 'uri'
require 'net/http'
require 'json'
require 'gisbn'
def book_worldcat(isbn)
url = "http://xisbn.worldcat.org/webservices/xid/isbn/#{isbn}?method=getMetadata&format=json&fl=*"
res = Net::HTTP.get(URI(url))
books = JSON.parse(res)['list'] or return
book = books[0] or return
book and return {
isbn: book['isbn'][0],
title: book['title'],
authors: book['author'],
year: book['year'],
publisher: book['publisher'],
links: {
worldcat: book['url'][0]
}
}
end
def book_google(isbn)
book = Gisbn::Book.new("#{isbn}")
book and return {
isbn: book.isbn_13 || book.isbn_10,
title: book.title,
authors: (book.authors rescue nil),
description: book.description,
pages: (book.page_count && book.page_count > 0) ? book.page_count : nil,
thumbnail: (book.thumbnail_small rescue nil),
links: {
google: book.preview_link
}
}
end
books = []
ARGV.each do |isbn|
isbn or next
datas = [book_google(isbn), book_worldcat(isbn), {isbn: isbn}]
datas.compact!
datas.each {|b| b.reject! {|k,v| v.nil?}}
book = datas.reverse.reduce({}) {|m,o| m.merge(o)}
book[:links] = datas.map{|b| b[:links]}.compact.reduce({}) {|m,o| m.merge(o)}
books << book
end
puts JSON.dump({books: books})
#!/usr/bin/ruby
#
# Quick & dirty script to generate an HTML page with a book matrix.
#
# Usage: genpage.rb <books.json >books.html
# Supply output of genbooks.rb as input. Outputs basic HTML page.
#
# TODO:
# - escape texts and urls (!)
# - sorting
# - split by category / ...
#
# (c)2015 by wvengen, licensed under GPL version 3 or later
#
require 'json'
books = JSON.parse(STDIN.read)
puts """
<html>
<head>
<title>Books</title>
<meta charset='utf-8'>
<style type='text/css'>
.items .item {
float: left;
width: 129px;
height: 192px;
padding: 2px;
margin: 2px;
position: relative;
}
.item img {
/* this may modify aspect-ratio of images, but I find it giving it a cleaner view */
width: 129px;
height: 192px;
}
.item .without-cover {
padding: 6px;
height: 182px;
text-align: center;
background: #e9e9e9;
overflow: hidden;
}
.item .title {
font-size: 13pt;
line-height: 15pt;
letter-spacing: -0.25px;
}
.item .authors {
padding-top: 1.2ex;
font-size: 11pt;
line-height: 12pt;
}
.item .links {
position: absolute;
bottom: 0;
right: 0;
margin-bottom: 5px;
margin-right: 3px;
}
.item .link {
background: rgba(255,255,255,0.8);
padding: 3px;
border-radius: 8px;
}
.item a.link, .item a.link:hover, .item a.link:active {
color: black;
}
</style>
</head>
<body>
"""
puts "<div class='items blocks'>"
books['books'].each do |book|
txt = [book['title'], "#{book['authors']}#{" (#{book['year']})" if book['year']}", "ISBN #{book['isbn']}"].join("\n")
puts " <div class='item'>"
puts " <div class='#{'without-' unless book['thumbnail']}cover' title='#{txt.gsub "'", "&#39;"}'>"
if book['thumbnail']
puts " <img src='#{book['thumbnail']}' alt=''>"
else
puts " <div class='title'>#{book['title']}</div>"
puts " <div class='authors'>#{book['authors']}</div>"
end
puts " </div>"
if book['links']
puts " <div class='links'>"
book['links'].keys.sort.each do |key|
link = book['links'][key]
puts " <a href='#{link}' class='link' title='#{key.capitalize}'>#{key[0].upcase}</a>" if link
end
puts " </div>"
end
puts " </div>"
end
puts "</div>"
puts "</body></html>"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment