Add `arrived` attribute (file creation timestamp) to books table.
[quanlib.git] / walkdir.rb
1 # Walk the directory (and subdirectories), identifying books.
2 #
3 # Expected format:
4 #   .../AuthorName/Title_of_the_Awesome_Book.ext
5 #
6 # Author is given as FirstLast.  For example, 
7 # Robert Anson Heinlein is RobertHeinlein, and 
8 # JKRowling is JoanneRowling.
9 #
10 # Book titles have spaces replaced with underscores,
11 # and punctuation [,!?'] replaced with hyphens.
12 #
13 # If the book forms part of a series, then an all-capitals 
14 # series designator, followed by a numeric volume number, 
15 # followed by an underscore, is prefixed to the name.
16 # For example, Hardy Boys' volume 1, The Tower Treasure, 
17 # is rendered as .../FranklinDixon/HB001_The_Tower_Treasure.epub
18 # and Mrs. Pollifax volume 6, On the China Station, is
19 # .../DorothyGilman/P06_On_the_China_Station.epub.
20
21 require 'book'
22 require 'store'
23
24 class WalkDir
25   def initialize(store, root)
26     @root = root
27     @store = store
28     @files = walk(@root)
29   end
30
31   def books
32     result = []
33     @files = remove_duplicates(@files)
34     for file in @files.sort()
35       if Book.can_handle?(file) && (!is_duplicate?(file))
36         book = Book.new(@store)
37         book.load_from_file!(file)
38         id = @store.store_book(book)
39         result.push(id)
40       end
41     end
42     return result
43   end
44
45   # Duplicate versions of a text are named 
46   #   xxx_suffix.ext
47   # Where suffix is one of bis, ter, quater, quinquies
48   # for the 2nd, 3rd, 4th or 5th variant respectively.
49   def is_duplicate?(file)
50     s = file.to_s
51     suffix = ['_bis.', '_ter.', '_quater.', '_quinquies.']
52     suffix.each do |pat|
53       if s.include?(pat)
54         return true
55       end
56     end
57     
58     return false
59   end
60
61   def remove_duplicates(files)
62     unique = {}
63     for file in files
64       if Book.can_handle?(file)
65         key = File.dirname(file) + '/' + File.basename(file, '.*')
66         if unique.has_key?(key)
67           new_ext = File.extname(file)
68           old_ext = File.extname(unique[key])
69           if ('.pdf' == old_ext) && ('.epub' == new_ext)
70             # Prefer EPUB over PDF
71             puts 'REPLACED ' + unique[key].to_s + ' with ' + file.to_s
72             unique[key] = file
73           else
74             puts 'DROPPED ' + file.to_s + " because it's superceded by " + unique[key].to_s
75           end
76         else
77           unique[key] = file
78         end
79       end
80     end
81
82     return unique.values
83   end
84
85   def walk(path)
86     result = []
87     children = Dir.entries(path)
88     for child in children
89       fullName = (path.chomp("/")) + "/" + child
90       if (File.directory?(fullName)) and (child != ".") and (child != "..") and (!File.symlink?(fullName))
91         sub = walk(fullName)
92         if (sub != nil) and (sub.length > 0)
93           result.concat(sub)
94         end
95       elsif (! File.directory?(fullName))
96         result.push(fullName)
97       end
98     end
99     return result
100   end
101 end