Keith Vetter 2004-11-26 -- Are you like me and are always forgetting when library books are due?
Well, here's a short script I wrote a while ago that connects to your libraries web-based catalog, logs in as you, and produces either a text or RSS stream of all your checked out items. You'll need to either edit the script to add your username, password and library URL or supply them on the command line.
It was designed for libraries running a web-based system written by Dynix (also known as iPAC or oPAC), and it's only been tested on the libraries I use.
##+########################################################################## # # Dynix2RSS.tcl -- logs into a Dynix web-based library and produces # an RSS feed of all checked out items. # by Keith Vetter June 17, 2004 # ##+########################################################################## ############################################################################# package require http if {! [catch {package require autoproxy}]} { ::autoproxy::init } set username "" ;# Typically your library card number set password "" ;# PIN - try last four digits of your phone set dynix "" ;# Base URL of your library's Dynix catalog ;# for me its: http://66.213.81.15:8080/ipac20/ipac.jsp proc GetBooks {} { global username password dynix2 books whoami set books {} # # Get the authentication page which gives us the session variable # set url $dynix2 set token [::http::geturl $url] set page [::http::data $token] ; ::http::cleanup $token set n [regexp -nocase {[?&]session=(.*?)&} $page => session] if {! $n} {DIE "ERROR: cannot extract session ID from initial page"} # # Get the items out page # set url "$dynix2&session=$session&sec1=$username&sec2=$password" set token [::http::geturl $url] set page [::http::data $token] ; ::http::cleanup $token # # Now scrape this page for the books we have out # set whoami "?" regexp {Welcome(.*?)<} $page => whoami regsub -all { } $whoami " " whoami set whoami [string trim $whoami] set start 0 set bcnt 0 while {1} { set n [regexp -start $start -indices -nocase \ {<a[^>]*mediumboldanchor[^>]*>} $page idxs] if {! $n} break incr bcnt set anchor [eval string range [list $page] $idxs] set n [regexp {href="(.*?)"} $anchor => link] if {! $n} {DIE "Cannot parse book $bcnt"} set link [string map {& &} $link] regsub {session=.*?&} $link {} link # Extract title foreach {a b} $idxs break set n [regexp -start $b {.(.*?)</a>} $page => title] if {! $n} {DIE "Cannot parse title for book \#$bcnt"} set title [string trimright $title "/ "] # Extract checkout date set n [regexp -start $b -indices -nocase \ {normalBlackfont2.*?>(.*?)</a>} $page => idxs] if {! $n} {DIE "Cannot parse checkout date for book \#$bcnt"} set out [eval string range [list $page] $idxs] # Extract due date foreach {a b} $idxs break set n [regexp -start $b -indices -nocase \ {normalBlackfont2.*?>(.*?)</a>} $page => idxs] if {! $n} {DIE "Cannot parse due date for book \#$bcnt"} set due [eval string range [list $page] $idxs] set due2 [clock scan $due] # Extract times renewed foreach {a b} $idxs break set n [regexp -start $b -indices -nocase \ {normalBlackfont2.*?>(.*?)</a>} $page => idxs] if {! $n} {DIE "Cannot parse times renewed for book \#$bcnt"} set renewed [eval string range [list $page] $idxs] # Save the result lappend books [list $due2 $title $link $out $due $renewed] set start $b } set books [lsort -integer -index 0 $books] return } proc DIE {msg} {puts stderr $msg; exit} proc htmlQuote {s} { return [string map { & & < < > > } $s] } proc DoTxt {} { global books whoami set txt "Books checked out for $whoami" foreach book $books { foreach {. title link out due renewed} $book break puts "$title" puts " out: $out" puts " due: $due" } } proc DoRSS {} { global books whoami dynix2 date set title "Library books out" if {$whoami ne ""} { append title " for $whoami"} puts "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"yes\"?>" puts -nonewline "<!DOCTYPE rss PUBLIC " puts -nonewline "\"-//Netscape Communications//DTD RSS 0.91//EN\" " puts "\"http://my.netscape.com/publish/formats/rss-0.91.dtd\">" puts "<rss version=\"0.91\">" puts " <channel>" puts " <title>[htmlQuote $title]</title>" puts " <lastBuildDate>$date</lastBuildDate>" puts " <link>[htmlQuote $dynix2]</link>" puts " <description>Books checked out from the library</description>" foreach book $books { foreach {. title link out due renewed} $book break set txt "Checked out: $out Due back: $due" puts " <item>" puts " <title>[htmlQuote $title]</title>" puts " <link>[htmlQuote $link]</link>" puts " <description>$txt</description>" puts " </item>" } puts " </channel>" puts "</rss>" return } set rss 1 if {$argc > 0 && [lindex $argv 0] eq "-t"} { set rss 0 set argc [llength [set argv [lrange $argv 1 end]]] } if {$argc == 1} { foreach username $argv break} if {$argc == 2} { foreach {username password} $argv break} if {$argc == 3} { foreach {username password dynix} $argv break} set dynix2 "$dynix?profile=pac&menu=account&submenu=itemsout" set date [clock format [clock seconds] -format "%Y-%m-%dT%H:%M:%SZ"] GetBooks if {$rss} { DoRSS } else { DoTxt }