Add support for PDF (with .jpeg cover).
authorChris Jaekl <cejaekl@yahoo.com>
Sat, 24 Jun 2017 11:11:45 +0000 (20:11 +0900)
committerChris Jaekl <cejaekl@yahoo.com>
Sat, 24 Jun 2017 11:11:45 +0000 (20:11 +0900)
book.rb
navigator.rb [new file with mode: 0644]
series.rb [new file with mode: 0644]
walkdir.rb

diff --git a/book.rb b/book.rb
index aa61930bc357fb89dcc861085eedd38921b1f654..e0ccc841eed4c86600d56e18b0373fc14a138ab2 100644 (file)
--- a/book.rb
+++ b/book.rb
@@ -20,12 +20,12 @@ class Book
     @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
@@ -37,6 +37,10 @@ class Book
       return true
     end
 
+    if lowerName.end_with?(".pdf")
+      return true
+    end
+
     return false
   end
 
@@ -204,8 +208,8 @@ class Book
   end
 
   protected
-  def parseFileName!(fileName)
-    parts = fileName.split('/')
+  def parse_file_name!(file_name)
+    parts = file_name.split('/')
     (series_code, @volume, @title) = processTitle(parts[-1])
     if parts.length > 1
       grouping = parts[-2]
@@ -215,8 +219,11 @@ class Book
       @series_id = @store.get_series(grouping, series_code)
     end
 
-    if fileName.downcase.end_with?(".epub")
-      scanEpub!(fileName)
+    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
   end
 
@@ -243,6 +250,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
diff --git a/navigator.rb b/navigator.rb
new file mode 100644 (file)
index 0000000..16da652
--- /dev/null
@@ -0,0 +1,142 @@
+require 'page'
+require 'store'
+
+class Navigator
+  def initialize(store)
+    @store = store
+  end
+
+  def write_atoz_pages
+    atoz_counts = {}
+
+    ('A'..'Z').each do |letter| 
+      atoz_counts[letter] = write_authors_starting_with(letter)
+    end
+
+    content = '<table><tr><th>Author</th><th>Books</th></tr>'
+    ('A'..'Z').each do |letter|
+      content += '  <tr><td><a href="../atoz/output_' + letter + '.html">Starting with ' + letter + '</a></td><td>' + atoz_counts[letter].to_s + '</td></tr>'
+    end
+    page = Page.new(@store)
+    page.output_dir = 'atoz'
+    page.special = content
+    page.up = ['../output/index.html', 'Up']
+
+    page.write_html( [] )
+  end
+
+  def write_authors_starting_with(letter)
+    book_ids = @store.query_books_by_author(letter + '%')
+    puts 'Authors starting with "' + letter + '":  ' + book_ids.length.to_s() + ' books.'
+
+    page = Page.new(@store)
+    if 'A' != letter
+      page.back = ['../atoz/output_' + (letter.ord - 1).chr + '.html', 'Prev']
+    end
+    if 'Z' != letter
+      page.forward = ['../atoz/output_' + (letter.ord + 1).chr + '.html', 'Next']
+    end
+    page.output_dir = 'atoz'
+    page.index_file = 'output_' + letter + '.html'
+    page.title = "Authors starting with '" + letter + "'"
+    page.up = ['../atoz/index.html', 'Up']
+
+    page.write_html(book_ids)
+    return book_ids.length
+  end
+
+  def write_series_for_age(age)
+    series_infos = []
+
+    series_ids = @store.query_series_by_age(age)
+
+    series_ids.each do |id|
+      series = @store.load_series(id)
+      book_ids = @store.query_books_by_series_id(id)
+      if nil != book_ids and book_ids.length > 0
+        series_infos.push( [series, book_ids] )
+      end
+    end
+
+    for idx in 0 .. (series_infos.length - 1) do 
+      #puts series.descr + ': ' + book_ids.length.to_s + ' books.'
+
+      back = nil
+      fwd = nil
+
+      if idx > 0
+        back = series_infos[idx-1]
+      end
+      if (idx + 1) < series_infos.length
+        fwd = series_infos[idx+1]
+      end
+
+      cur = series_infos[idx]
+      series = cur[0]
+      book_ids = cur[1]
+
+      page = Page.new(@store)
+      if nil != back
+        page.back = [back[0].key + '.html', 'Back']
+      end
+      if nil != fwd
+        page.forward = [fwd[0].key + '.html', 'Forward']
+      end
+      page.output_dir = 'series/series_' + age
+      page.index_file = series.key + '.html'
+      page.title = 'Series &ldquo;' + series.descr + '&rdquo; (' + book_ids.length.to_s + ' books)'
+      page.up = ['index.html', 'Up']
+  
+      page.write_html(book_ids)
+    end
+
+    content =  '<h1>&ldquo;' + age + '&rdquo; Series</h1>'
+    content += '<p><table><tr><th>Author</th><th>Series</th><th>Genre</th><th>Books</th></tr>'
+    series_infos.each do |cur|
+      series = cur[0]
+      book_ids = cur[1]
+
+      author = series.grouping
+      letter = author[0]
+
+      content += '  <tr>'
+      content += '<td><a href="../../atoz/output_' + letter + '.html">' + author + '</a></td>'
+      content += '<td><a href="' + series.key + '.html">' + series.descr + '</a></td>'
+      content += '<td>' + series.genre + '</td>'
+      content += '<td>' + book_ids.length.to_s + '</td>'
+      content += '</tr>'
+    end
+    content += '</table></p>'
+    page = Page.new(@store)
+    page.output_dir = 'series/series_' + age
+    page.special = content
+    page.up = ['../index.html', 'Up']
+    page.write_html( [] )
+
+    return series_infos.length
+  end
+
+  def write_series_listing
+    ages = ['beginner', 'junior', 'ya', 'adult']
+    series_counts = {}
+
+    ages.each do |age|
+      puts 'Series for "' + age + '" readers...'
+
+      series_counts[age] = write_series_for_age(age)
+    end
+
+    content = '<h1>Browse Books By Series</h1>'
+    content += '<p>'
+    content += '<table><tr><th>Age</th><th>Number of Series</th></tr>'
+    ages.each do |age|
+      content += '<tr><td><a href="series_' + age + '/index.html">' + age + '</a></td><td>' + series_counts[age].to_s + '</td></tr>'
+    end
+    content += '</table></p>'
+    page = Page.new(@store)
+    page.output_dir = 'series'
+    page.special = content
+    page.up = ['../output/index.html', 'Up']
+    page.write_html( [] )
+  end
+end
diff --git a/series.rb b/series.rb
new file mode 100644 (file)
index 0000000..0621876
--- /dev/null
+++ b/series.rb
@@ -0,0 +1,87 @@
+
+class Series
+  def initialize(id)
+    @age = nil
+    @genre = nil
+    @grouping = nil 
+    @code = nil
+    @descr = nil
+    @id = id
+  end
+
+  def age
+    @age
+  end
+
+  def age=(value)
+    @age = value
+  end
+
+  def code
+    @code
+  end
+
+  def code=(value)
+    @code = value
+  end
+
+  def descr
+    @descr
+  end
+
+  def descr=(value)
+    @descr = value
+  end
+
+  def genre
+    @genre
+  end
+
+  def genre=(value)
+    @genre = value
+  end
+
+  def grouping
+    @grouping
+  end
+
+  def grouping=(value)
+    @grouping = value
+  end
+
+  def id
+    @id
+  end
+
+  def inspect
+    data = []
+    if nil != @age
+      data.push('age="' + @age.inspect + '"')
+    end
+    if nil != @code
+      data.push('code="' + @code.inspect + '"')
+    end
+    if nil != @descr
+      data.push('descr="' + @descr + '"')
+    end
+    if nil != @genre
+      data.push('genre="' + @genre + '"')
+    end
+    if nil != @grouping
+      data.push('grouping="' + @grouping + '"')
+    end
+    return '(Series:' + data.join(',') + ')'
+  end
+
+  def key
+    if nil != grouping and nil != code
+      return grouping.to_s + '_' + code.to_s
+    end
+    return id.to_s
+  end
+
+  def to_s
+    return inspect()
+  end
+end
+
index 1dadd2e35b95974f81ad43366698c46b93dac7b9..236e3feaf7244852b4b58e780e9fdce456da6fc2 100644 (file)
@@ -31,9 +31,9 @@ class WalkDir
   def books
     result = []
     for file in @files.sort
-      if Book.canHandle?(file)
+      if Book.can_handle?(file) && (!is_duplicate?(file))
         book = Book.new(@store)
-        book.loadFromFile(file)
+        book.load_from_file(file)
         id = @store.store_book(book)
         result.push(id)
       end
@@ -41,6 +41,22 @@ class WalkDir
     return result
   end
 
+  # Duplicate versions of a text are named 
+  #   xxx_suffix.ext
+  # Where suffix is one of bis, ter, quater, quinquies
+  # for the 2nd, 3rd, 4th or 5th variant respectively.
+  def is_duplicate?(file)
+    s = file.to_s
+    suffix = ['_bis.', '_ter.', '_quater.', '_quinquies.']
+    suffix.each do |pat|
+      if s.include?(pat)
+        return true
+      end
+    end
+    
+    return false
+  end
+
   def walk(path)
     result = []
     children = Dir.entries(path)