Module: Bookflow::AppleBooks::Extract
- Defined in:
- lib/bookflow/apple_books/extract.rb
Class Method Summary collapse
- .blank_text_row?(row) ⇒ Boolean
- .build_annotation(row) ⇒ Object
- .build_books_lookup(rows) ⇒ Object
- .filtered_out?(book, book_filter) ⇒ Boolean
- .group_exports(annotation_rows:, book_rows:, book_filter:) ⇒ Object
- .parse_time(value) ⇒ Object
- .sort_annotations(annotations) ⇒ Object
- .unknown_book(asset_id) ⇒ Object
Class Method Details
.blank_text_row?(row) ⇒ Boolean
45 46 47 48 49 50 |
# File 'lib/bookflow/apple_books/extract.rb', line 45 def blank_text_row?(row) selected = row["ZANNOTATIONSELECTEDTEXT"].to_s representative = row["ZANNOTATIONREPRESENTATIVETEXT"].to_s note = row["ZANNOTATIONNOTE"].to_s selected.empty? && representative.empty? && note.empty? end |
.build_annotation(row) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/bookflow/apple_books/extract.rb', line 64 def build_annotation(row) selected_text = row["ZANNOTATIONSELECTEDTEXT"].to_s representative_text = row["ZANNOTATIONREPRESENTATIVETEXT"] highlight_text = selected_text.empty? ? representative_text : selected_text Annotation.new( annotation_id: row["Z_PK"], asset_id: row["ZANNOTATIONASSETID"], highlight_text: highlight_text, note_text: row["ZANNOTATIONNOTE"], created_at: parse_time(row["ZANNOTATIONCREATIONDATE"]), modified_at: parse_time(row["ZANNOTATIONMODIFICATIONDATE"]), absolute_location: row["ZPLABSOLUTEPHYSICALLOCATION"], range_start: row["ZPLLOCATIONRANGESTART"], range_end: row["ZPLLOCATIONRANGEEND"] ) end |
.build_books_lookup(rows) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/bookflow/apple_books/extract.rb', line 52 def build_books_lookup(rows) rows.each_with_object({}) do |row, memo| asset_id = row["ZASSETID"].to_s memo[asset_id] = Book.new( asset_id: asset_id, title: row["ZTITLE"], author: row["ZAUTHOR"], source_path: row["ZPATH"] ) end end |
.filtered_out?(book, book_filter) ⇒ Boolean
38 39 40 41 42 43 |
# File 'lib/bookflow/apple_books/extract.rb', line 38 def filtered_out?(book, book_filter) return false if book_filter.nil? || book_filter.strip.empty? haystack = "#{book.title} #{book.author}".downcase !haystack.include?(book_filter.downcase) end |
.group_exports(annotation_rows:, book_rows:, book_filter:) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/bookflow/apple_books/extract.rb', line 8 def group_exports(annotation_rows:, book_rows:, book_filter:) books_by_asset_id = build_books_lookup(book_rows) grouped_annotations = Hash.new { |hash, key| hash[key] = [] } annotation_rows.each do |row| next if blank_text_row?(row) asset_id = row["ZANNOTATIONASSETID"].to_s book = books_by_asset_id[asset_id] || unknown_book(asset_id) next if filtered_out?(book, book_filter) grouped_annotations[book] << build_annotation(row) end grouped_annotations.map do |book, annotations| BookExport.new(book: book, annotations: sort_annotations(annotations)) end.sort_by { |book_export| [book_export.book.title.to_s.downcase, book_export.book.asset_id.to_s] } end |
.parse_time(value) ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/bookflow/apple_books/extract.rb', line 82 def parse_time(value) return value if value.is_a?(Time) return nil if value.nil? || value.to_s.strip.empty? Time.parse(value.to_s) rescue ArgumentError nil end |
.sort_annotations(annotations) ⇒ Object
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/bookflow/apple_books/extract.rb', line 27 def sort_annotations(annotations) annotations.sort_by do |annotation| [ annotation.absolute_location || Float::INFINITY, annotation.range_start || Float::INFINITY, annotation.created_at || Time.at(0).utc, annotation.annotation_id || 0 ] end end |
.unknown_book(asset_id) ⇒ Object
91 92 93 |
# File 'lib/bookflow/apple_books/extract.rb', line 91 def unknown_book(asset_id) Book.new(asset_id: asset_id, title: "Unknown Book", author: nil, source_path: nil) end |