Last active
November 12, 2015 08:34
-
-
Save libsteve/90c77f9af6824172c05a to your computer and use it in GitHub Desktop.
Command line utility to convert an ISBN to a Library of Congress Column Number
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/osascript | |
on printLCCN(LCCN) | |
tell application "DYMO Label" | |
set paperOrientation to portrait | |
tell print object 1 | |
set object text to LCCN | |
end tell | |
printLabel2 of it | |
end tell | |
end printLCCN | |
-- taken from https://geert.vanderkelen.org/2010/splitting-as-string-and-joining-a-list-using-applescript/ | |
to joinList(aList, delimiter) | |
set retVal to "" | |
set prevDelimiter to AppleScript's text item delimiters | |
set AppleScript's text item delimiters to delimiter | |
set retVal to aList as string | |
set AppleScript's text item delimiters to prevDelimiter | |
return retVal | |
end joinList | |
on run argv | |
if (count of argv) is not 0 then | |
my printLCCN(joinList(argv, "\n")) | |
end if | |
end run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby | |
require 'open3' | |
iccn_list = if (ARGV.empty?) or (ARGV[0] == '-f' || ARGV[0] == '--file') then | |
ARGV.shift if not ARGV.empty? | |
ARGF | |
else | |
ARGV | |
end | |
begin | |
iccn_list.each do |isbn| | |
lccn = `./isbn2lccn.rb #{isbn}` | |
`./dymoPrintLCCN.applescript #{lccn}` | |
puts lccn | |
end | |
rescue Interrupt => e | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'open3' | |
class YazConnection | |
# reference: http://www.xml.com/pub/a/2004/06/02/dijalog.html | |
# reference: http://www.indexdata.com/yaz/doc/yaz-client.html | |
# reference: http://lists.indexdata.dk/pipermail/yazlist/2006-July/001668.html | |
# reference: https://gist.github.com/toroidal-code/6415977 | |
# you can install the yaz-client command with `brew install yaz`, | |
# or you can visit http://www.indexdata.com/yaz/ | |
attr_accessor :stdin, :stdout, :stderr | |
def initialize(server='z3950.loc.gov:7090/voyager') | |
self.stdin, self.stdout, self.stderr = | |
Open3.popen3('yaz-client', server) | |
# this is the URL, port, and datavase that everyone else uses | |
self.read_response_lines {|x|} | |
end | |
def close | |
self.stdin.close | |
self.stdout.close | |
self.stderr.close | |
end | |
def readprompt | |
3.times { self.stdout.readchar } # reads 'Z> ' | |
end | |
def read_response_lines | |
reading_is_done = false | |
until reading_is_done | |
line = self.stdout.readline | |
begin | |
if line.split(':')[0] == 'Elapsed' then | |
reading_is_done = true | |
else | |
yield line | |
end | |
rescue => exception | |
STDERR.puts exception | |
end | |
end | |
self.readprompt | |
end | |
def readmarc | |
3.times { self.stdout.readline } | |
lines = [] | |
self.read_response_lines { |l| lines << l } | |
Marc.new(lines) | |
end | |
def fetch_lccn(isbn) | |
self.stdin.puts "find @attr 1=7 #{isbn.gsub('-', '')}" | |
# the search query to find entries with that isbn | |
# from what I can tell, 1 means 'use this', and 7 means 'ISBN field' | |
3.times { self.stdout.readline } | |
line = self.stdout.readline | |
results = line.sub('Number of hits: ', '').to_i | |
2.times { self.stdout.readline } | |
self.readprompt | |
return nil unless results > 0 | |
self.stdin.puts "s 1" # request a USMARC result | |
return self.readmarc.lccn | |
end | |
end | |
class Marc | |
attr_accessor :lccn | |
def initialize(lines) | |
lines.each do |line| | |
self.lccn = LCCN.new(line) if LCCN.LCCN_line? line | |
end | |
end | |
end | |
class LCCN | |
# reference: http://www.loc.gov/marc/authority/ad050.html | |
attr_accessor :classification, :item, :volumes, :institution, :loc_official | |
def self.LCCN_line? (line) | |
line[0..2] == '050' # the infamous line 050 is where the LCCN is stored | |
end | |
def initialize(line050) | |
fields = line050[4..-1].split('$') # the line begins '050 ' | |
self.loc_official = (fields[0][1].to_i == 0) | |
# the format is '0#' where # is either 0 or 4 | |
fields = Hash[ fields[1..-1].map { |field| [field[0], field[2..-1].strip] } ] | |
self.classification = fields['a'] | |
self.item = fields['b'] | |
self.volumes = fields['d'] | |
self.institution = fields['5'] | |
end | |
def loc_official? | |
self.loc_official | |
end | |
def to_s | |
fields=[self.classification, self.item, self.volumes, self.institution] | |
string = fields.select { |x| not x.nil? }.join ' ' | |
lccn_regexp = /(^[A-Z]*) *([0-9]*.[0-9]+) *(.[A-Z]*[0-9]*) *(.[A-Z]*[0-9]*) *([0-9]*)/i | |
string.match(lccn_regexp).captures.map {|x| x.strip }.join ' ' | |
end | |
end | |
# command line script starts here | |
yaz = YazConnection.new | |
isbn_list = if (ARGV.empty?) or (ARGV[0] == '-f' || ARGV[0] == '--file') then | |
ARGV.shift if not ARGV.empty? | |
ARGF | |
else | |
ARGV | |
end | |
begin | |
isbn_list.each do |isbn| | |
lccn = yaz.fetch_lccn isbn | |
if lccn.nil? then | |
# servers from http://isbnsearch.sourceforge.net/servers.html | |
more_servers = ['albert.rit.edu:210/innopac', | |
'aleph.mcgill.ca:210/muse', | |
'catalog.bedfordlibrary.org:210/innopac', | |
'catalog.library.cornell.edu:7090/voyager', | |
'catalog.library.colostate.edu:210/innopac', | |
'catalog.mbln.org:210/horizon', | |
'catalog.princeton.edu:7090/voyager', | |
'catalog.wustl.edu:210/innopac', | |
'clio-db.cc.columbia.edu:7090/voyager', | |
'grammy.mit.edu:9909/mit01'] | |
while lccn.nil? && (not more_servers.empty?) | |
server = more_servers.shift | |
# STDERR.puts "trying #{server}" | |
yaz_c = YazConnection.new(server) | |
lccn = yaz_c.fetch_lccn isbn | |
yaz_c.close | |
end | |
end | |
puts lccn | |
end | |
rescue Interrupt => e | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment