X-Git-Url: http://jaekl.net/gitweb/?a=blobdiff_plain;f=book.rb;h=6d90c0e2947a0a243b3480758518159e075d8d85;hb=872d620121706ad345b7e667521be1c7326c2e00;hp=03a5f259beb0005d4250bd7988edab21729ba41d;hpb=4b53af822cda819dd82d0d3e7ed066c2966ae4bf;p=quanlib.git diff --git a/book.rb b/book.rb index 03a5f25..6d90c0e 100644 --- a/book.rb +++ b/book.rb @@ -1,29 +1,34 @@ require 'nokogiri' +require 'rubygems' require 'zip' require 'author' +require 'classification' require 'cover' +require 'store' class Book @@DC_NS_URL = 'http://purl.org/dc/elements/1.1/' - def initialize + def initialize(store) @author = nil + @classification_id = nil @cover = nil @description = nil @path = nil - @series = nil + @series_id = nil + @store = store @title = nil @volume = nil end - def loadFromFile(fileName) + def load_from_file!(fileName) @path = fileName - parseFileName!(fileName) + parse_file_name!(fileName) end - def self.canHandle?(fileName) + def self.can_handle?(fileName) if nil == fileName return false end @@ -35,6 +40,10 @@ class Book return true end + if lowerName.end_with?(".pdf") + return true + end + return false end @@ -42,14 +51,34 @@ class Book return @author end + def author=(value) + @author = value + end + + def classification_id + @classification_id + end + + def classification_id=(value) + @classification_id = value + end + def cover return @cover end + def cover=(value) + @cover = value + end + def description @description end + def description=(value) + @description = value + end + def heading result = [] @@ -63,8 +92,9 @@ class Book end seriesInfo = [] - if nil != @series - seriesInfo.push(@series.to_s) + series = @store.load_series(@series_id) + if nil != series and nil != series.descr + seriesInfo.push(series.descr.to_s) end if nil != @volume seriesInfo.push(@volume.to_s) @@ -73,6 +103,19 @@ class Book result.push(seriesInfo.join(' ')) end + classification = nil + if nil != @classification_id + classification = @store.load_classification(@classification_id) + end + if nil != classification + if nil != classification.ddc + result.push('Dewey: ' + classification.ddc.to_s) + end + if nil != classification.lcc + result.push('LCC: ' + classification.lcc.to_s) + end + end + return result.join('
') end @@ -81,8 +124,8 @@ class Book if nil != @author data.push('author="' + @author.inspect + '"') end - if nil != @series - data.push('series="' + @series + '"') + if nil != @series_id + data.push('series_id="' + @series_id.to_s() + '"') end if nil != @volume data.push('volume="' + @volume + '"') @@ -103,8 +146,16 @@ class Book @path end - def series - @series + def path=(value) + @path = value + end + + def series_id + @series_id + end + + def series_id=(value) + @series_id = value end def to_s @@ -115,10 +166,26 @@ class Book @title end + def title=(value) + @title = value + end + + def title_grouping + if nil == @path + return nil + end + + return File.basename(@path, '.*') + end + def volume @volume end + def volume=(value) + @volume = value + end + protected def isUpper?(c) return /[[:upper:]]/.match(c) @@ -173,18 +240,37 @@ class Book end protected - def parseFileName!(fileName) - parts = fileName.split('/') - (@series, @volume, @title) = processTitle(parts[-1]) + def parse_file_name!(file_name) + category = nil # e.g., non-fiction, fan-fiction + grouping = '' + + parts = file_name.split('/') + (series_code, @volume, @title) = processTitle(parts[-1]) if parts.length > 1 grouping = parts[-2] reading_order = massage_author(grouping) sort_order = nil @author = Author.new(grouping, reading_order, sort_order) + @series_id = @store.get_series(grouping, series_code) + end + if parts.length > 2 + category = parts[-3] + end + + lc_file_name = file_name.downcase + if lc_file_name.end_with?(".epub") + scanEpub!(file_name) + elsif lc_file_name.end_with?(".pdf") + scan_pdf!(file_name) end - if fileName.downcase.end_with?(".epub") - scanEpub!(fileName) + @classification_id = @store.find_classification(@author.grouping, File.basename(file_name, '.*')) + + # TODO: Fix horrible hard-coded strings and paths + if ('01_nonfic' == category) && (nil == classification_id) + open(Store.unclassified_csv, 'a') do |fd| + fd.puts('"' + grouping.to_s + '","' + path + '"') + end end end @@ -211,6 +297,25 @@ class Book end end + protected + def scan_pdf!(file_name) + #puts 'Scanning "' + file_name.to_s + '"...' + + pdf_path = File.expand_path(file_name).to_s + if ! pdf_path.end_with?('.pdf') + puts 'Unexpected internal error: path "' + file_name.to_s + '" does not end with ".pdf".' + return + end + + jpeg_path = pdf_path[0..-5] + '.jpeg' + if File.file?(jpeg_path) + File.open(jpeg_path, 'r') do |is| + @cover = Cover.new(is, jpeg_path, 'image/jpeg') + end + end + end + + protected def scanOpf!(zipfile, opfPath) coverId = nil @@ -274,7 +379,8 @@ class Book content = m['content'] if 'calibre:series' == name - @series = content + # TODO: Dynamically create a new series? + # @series_id = content elsif 'calibre:series-index' == name @volume = content elsif 'cover' == name @@ -286,11 +392,11 @@ class Book #--------------- # Load the cover - @cover = loadCover(zipfile, opfPath, opfDoc, coverId) + @cover = load_cover(zipfile, opfPath, opfDoc, coverId) end protected - def loadCover(zipfile, opfPath, opfDoc, coverId) + def load_cover(zipfile, opfPath, opfDoc, coverId) coverFile = nil if nil == coverId coverId = "cover-image"