<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[653] trunk/alexandria/lib/alexandria: BACKUP LIBRARY FOR NOW</title>
</head>
<body>
<div id="msg">
<dl>
<dt>Revision</dt> <dd>653</dd>
<dt>Author</dt> <dd>method</dd>
<dt>Date</dt> <dd>2007-03-12 23:52:46 -0400 (Mon, 12 Mar 2007)</dd>
</dl>
<h3>Log Message</h3>
<pre>BACKUP LIBRARY FOR NOW
- Should be okay, but might lose a cover.
- Tries to coerce all books to ean
- Additional code that has been neutralized.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkalexandrialibalexandrialibraryrb">trunk/alexandria/lib/alexandria/library.rb</a></li>
<li><a href="#trunkalexandrialibalexandriauimain_apprb">trunk/alexandria/lib/alexandria/ui/main_app.rb</a></li>
<li><a href="#trunkalexandrialibalexandriauinew_book_dialogrb">trunk/alexandria/lib/alexandria/ui/new_book_dialog.rb</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkalexandrialibalexandrialibraryrb"></a>
<div class="modfile"><h4>Modified: trunk/alexandria/lib/alexandria/library.rb (652 => 653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/alexandria/lib/alexandria/library.rb        2007-03-12 09:31:13 UTC (rev 652)
+++ trunk/alexandria/lib/alexandria/library.rb        2007-03-13 03:52:46 UTC (rev 653)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> module Alexandria
</span><span class="cx"> class Library < Array
</span><span class="cx"> attr_reader :name
</span><ins>+ attr_accessor :ruined_books
</ins><span class="cx"> DIR = File.join(ENV['HOME'], '.alexandria')
</span><span class="cx"> EXT = { :book => '.yaml', :cover => '.cover' }
</span><span class="cx">
</span><span class="lines">@@ -62,7 +63,9 @@
</span><span class="cx">
</span><span class="cx"> FIX_BIGNUM_REGEX =
</span><span class="cx"> /loaned_since:\s*(\!ruby\/object\:Bignum\s*)?(\d+)\n/
</span><ins>+
</ins><span class="cx"> def self.load(name)
</span><ins>+         ruined_books = []
</ins><span class="cx"> library = Library.new(name)
</span><span class="cx"> FileUtils.mkdir_p(library.path) unless File.exists?(library.path)
</span><span class="cx"> Dir.chdir(library.path) do
</span><span class="lines">@@ -72,11 +75,13 @@
</span><span class="cx"> #Code to remove the mystery string in books imported from Amazon
</span><span class="cx"> # (In the past, still?) To allow ruby-amazon to be removed.
</span><span class="cx">
</span><ins>+ # The string is removed on load, but can't make it stick, maybe has to do with cache
+
</ins><span class="cx"> if /!str:Amazon::Search::Response/.match(text)
</span><del>-         puts text
</del><ins>+         puts text if $DEBUG
</ins><span class="cx">         text.gsub!("!str:Amazon::Search::Response", "")
</span><del>-         puts "got one!"
-         puts text
</del><ins>+         puts "got one!" if $DEBUG
+         puts text if $DEBUG
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> # Backward compatibility with versions <= 0.6.0, where the
</span><span class="lines">@@ -88,24 +93,47 @@
</span><span class="cx"> text.sub!(md[0], "loaned_since: #{new_yaml}\n")
</span><span class="cx"> end
</span><span class="cx"> book = YAML.load(text)
</span><del>-         begin
</del><ins>+ old_isbn = book.isbn
+         begin
+         book.isbn = self.canonicalise_ean(book.isbn).to_s unless book.isbn == nil
+
</ins><span class="cx"> raise "Not a book: #{text.inspect}" unless book.is_a?(Book)
</span><del>- rescue => e
-         puts e.message
- end
</del><ins>+ rescue InvalidISBNError => e
+         # ruined_books << [book, book.isbn, library]
+         puts e.message if $DEBUG
+         book.isbn = old_isbn
+                                         end
+                                 
</ins><span class="cx"> library << book
</span><span class="cx"> end
</span><del>-
</del><ins>+
</ins><span class="cx"> # Since 0.4.0 the cover files '_small.jpg' and
</span><span class="cx"> # '_medium.jpg' have been deprecated for a single medium
</span><span class="cx"> # cover file named '.cover'.
</span><ins>+
</ins><span class="cx"> Dir["*" + '_medium.jpg'].each do |medium_cover|
</span><span class="cx"> FileUtils.mv(medium_cover,
</span><span class="cx"> medium_cover.sub(/_medium\.jpg$/,
</span><span class="cx"> EXT[:cover]))
</span><span class="cx"> end
</span><ins>+
+
+
+ Dir["*" + EXT[:cover]].each do |cover|
+         md = /(.+)\.cover/.match(cover)
+         begin
+                 ean = self.canonicalise_ean(md[1])
+         rescue
+                 ean = md[1]
+         end
+                 FileUtils.mv(cover, ean + EXT[:cover]) unless cover == ean + EXT[:cover]
+ end
+
</ins><span class="cx"> FileUtils.rm_f(Dir['*_small.jpg'])
</span><span class="cx"> end
</span><ins>+ #puts ruined_books.inspect
+ library.ruined_books = ruined_books
+
</ins><span class="cx"> library
</span><span class="cx"> end
</span><span class="cx">
</span><span class="lines">@@ -119,14 +147,17 @@
</span><span class="cx"> next unless File.stat(File.join(DIR, file)).directory?
</span><span class="cx">
</span><span class="cx"> a << self.load(file)
</span><del>- end
</del><ins>+         end
+
</ins><span class="cx"> rescue Errno::ENOENT
</span><span class="cx"> FileUtils.mkdir_p(DIR)
</span><span class="cx"> end
</span><span class="cx"> # Create the default library if there is no library yet.
</span><ins>+
</ins><span class="cx"> if a.empty?
</span><span class="cx"> a << self.load(_("My Library"))
</span><span class="cx"> end
</span><ins>+
</ins><span class="cx"> return a
</span><span class="cx"> end
</span><span class="cx">
</span><span class="lines">@@ -238,7 +269,7 @@
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> def self.canonicalise_ean(code)
</span><del>- code = code.delete('- ')
</del><ins>+ code = code.to_s.delete('- ')
</ins><span class="cx"> if self.valid_ean?(code)
</span><span class="cx"> return code
</span><span class="cx"> elsif self.valid_isbn?(code)
</span><span class="lines">@@ -276,8 +307,8 @@
</span><span class="cx"> canonical.map { |x| x.to_s }.join()
</span><span class="cx"> end
</span><span class="cx">
</span><del>- def save(book)
- changed
</del><ins>+ def save(book, final=false)
+ changed unless final
</ins><span class="cx">
</span><span class="cx"> puts "Saving book #{book.title}..." if $DEBUG
</span><span class="cx">
</span><span class="lines">@@ -295,11 +326,12 @@
</span><span class="cx">
</span><span class="cx"> # Notify before updating the saved identifier, so the views
</span><span class="cx"> # can still use the old one to update their models.
</span><del>- notify_observers(self, BOOK_UPDATED, book)
</del><ins>+ notify_observers(self, BOOK_UPDATED, book) unless final
</ins><span class="cx"> book.saved_ident = book.ident
</span><span class="cx"> end
</span><span class="cx"> already_there = (File.exists?(yaml(book)) and
</span><span class="cx"> !@deleted_books.include?(book))
</span><ins>+
</ins><span class="cx"> puts "Doing the saving deed: #{book.title} -- #{book.isbn}" if $DEBUG
</span><span class="cx"> File.open(yaml(book), "w") { |io| io.puts book.to_yaml }
</span><span class="cx">
</span><span class="lines">@@ -354,7 +386,7 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx"> end
</span><del>-
</del><ins>+
</ins><span class="cx"> alias_method :old_delete, :delete
</span><span class="cx"> def delete(book=nil)
</span><span class="cx"> if book.nil?
</span><span class="lines">@@ -475,7 +507,7 @@
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> class Libraries
</span><del>- attr_reader :all_libraries
</del><ins>+ attr_reader :all_libraries, :ruined_books
</ins><span class="cx">
</span><span class="cx"> include Observable
</span><span class="cx"> include Singleton
</span><span class="lines">@@ -484,6 +516,13 @@
</span><span class="cx"> @all_libraries.clear
</span><span class="cx"> @all_libraries.concat(Library.loadall)
</span><span class="cx"> @all_libraries.concat(SmartLibrary.loadall)
</span><ins>+         ruined = []
+         last = []
+         all_regular_libraries.each {|library|
+                                                                 ruined += library.ruined_books
+                                                                 }        
+         #puts ruined.inspect
+         @ruined_books = ruined
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> def all_regular_libraries
</span><span class="lines">@@ -511,6 +550,12 @@
</span><span class="cx"> SmartLibrary.really_delete_deleted_libraries
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+ def really_save_all_books
+         all_regular_libraries.each do |library|
+                 library.each {|book| library.save(book, true)}        
+         end
+ end
+
</ins><span class="cx"> #######
</span><span class="cx"> private
</span><span class="cx"> #######
</span></span></pre></div>
<a id="trunkalexandrialibalexandriauimain_apprb"></a>
<div class="modfile"><h4>Modified: trunk/alexandria/lib/alexandria/ui/main_app.rb (652 => 653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/alexandria/lib/alexandria/ui/main_app.rb        2007-03-12 09:31:13 UTC (rev 652)
+++ trunk/alexandria/lib/alexandria/ui/main_app.rb        2007-03-13 03:52:46 UTC (rev 653)
</span><span class="lines">@@ -393,8 +393,46 @@
</span><span class="cx"> end
</span><span class="cx"> @libraries.reload
</span><span class="cx"> else
</span><del>- @libraries = Libraries.instance
</del><ins>+         #On start
+
+ @libraries = Libraries.instance
</ins><span class="cx"> @libraries.reload
</span><ins>+ unless @libraries.ruined_books.empty?
+         message = _("These books do not conform to the ISBN-13 standard. We will attempt to replace them from the book providers. Otherwise, we will turn them into manual entries.\n" )
+         @libraries.ruined_books.each {|bi| message += "\n#{bi[1] or bi[1].inspect}"}
+         bad_isbn_warn = Gtk::MessageDialog.new(@main_app, Gtk::Dialog::MODAL, Gtk::MessageDialog::WARNING, Gtk::MessageDialog::BUTTONS_CLOSE, message ).show
+         bad_isbn_warn.signal_connect('response') { bad_isbn_warn.destroy }
+         books_to_add = []
+         
+         #This is the restoration thread. We can come up with strategies for restoring 'bad' books here.
+         
+         Thread.new do
+                 #Needs a progress indicator.
+                 @libraries.ruined_books.each {|book, isbn, library|
+                                                                           begin
+                                                                           books_to_add << [Alexandria::BookProviders.isbn_search(isbn.to_s), library].flatten
+                                                                           puts book.title
+                                                                           rescue
+                                                                          
+                                                                           books_to_add << [book, nil, library]
+                                                                           puts "#{book.title} didn't make it."
+                                                                           end
+                                                                          }
+                 # Will crash here when it gets to it.
+                 books_to_add.each do |book, cover_uri, library|
+                 
+                 unless cover_uri.nil?
+                 library.save_cover(book, cover_uri)
+                 end
+                 
+                 library << book
+                 library.save(book)
+                 
+                 end
+         
+         end
+                 puts books_to_add if $DEBUG
+ end
</ins><span class="cx"> end
</span><span class="cx"> @libraries.all_regular_libraries.each do |library|
</span><span class="cx"> library.add_observer(self)
</span><span class="lines">@@ -411,7 +449,9 @@
</span><span class="cx"> ICON_WIDTH = 60
</span><span class="cx"> ICON_HEIGHT = 90 # pixels
</span><span class="cx"> REDUCE_TITLE_REGEX = /^(.{#{ICON_TITLE_MAXLEN}}).*$/
</span><ins>+
</ins><span class="cx"> def fill_iter_with_book(iter, book)
</span><ins>+         
</ins><span class="cx"> iter[Columns::IDENT] = book.ident.to_s
</span><span class="cx"> iter[Columns::TITLE] = book.title
</span><span class="cx"> title = book.title.sub(REDUCE_TITLE_REGEX, '\1...')
</span><span class="lines">@@ -443,7 +483,9 @@
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> def append_book(book, tail=nil)
</span><ins>+         #puts "Blah: #{@model.inspect}" if $DEBUG
</ins><span class="cx"> iter = tail ? @model.insert_after(tail) : @model.append
</span><ins>+ #puts iter
</ins><span class="cx"> fill_iter_with_book(iter, book)
</span><span class="cx"> return iter
</span><span class="cx"> end
</span><span class="lines">@@ -1265,6 +1307,7 @@
</span><span class="cx"> on_quit = proc do
</span><span class="cx"> save_preferences
</span><span class="cx"> Gtk.main_quit
</span><ins>+ @libraries.really_save_all_books
</ins><span class="cx"> @libraries.really_delete_deleted_libraries
</span><span class="cx"> @libraries.all_regular_libraries.each do |library|
</span><span class="cx"> library.really_delete_deleted_books
</span></span></pre></div>
<a id="trunkalexandrialibalexandriauinew_book_dialogrb"></a>
<div class="modfile"><h4>Modified: trunk/alexandria/lib/alexandria/ui/new_book_dialog.rb (652 => 653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/alexandria/lib/alexandria/ui/new_book_dialog.rb        2007-03-12 09:31:13 UTC (rev 652)
+++ trunk/alexandria/lib/alexandria/ui/new_book_dialog.rb        2007-03-13 03:52:46 UTC (rev 653)
</span><span class="lines">@@ -322,7 +322,7 @@
</span><span class="cx"> rescue
</span><span class="cx"> raise _("Couldn't validate the EAN/ISBN you " +
</span><span class="cx"> "provided. Make sure it is written " +
</span><del>- "correcty, and try again.")
</del><ins>+ "correctly, and try again.")
</ins><span class="cx"> end
</span><span class="cx"> assert_not_exist(library, @entry_isbn.text)
</span><span class="cx"> books_to_add << Alexandria::BookProviders.isbn_search(isbn)
</span></span></pre>
</div>
</div>
</body>
</html>