class Alexandria::SmartLibrary

Constants

ALL_RULES
ANY_RULE
EXT

Attributes

deleted_books[RW]
n_rated[R]
name[R]
predicate_operator_rule[RW]
rules[RW]

Public Class Methods

deleted_libraries() click to toggle source
# File lib/alexandria/smart_library.rb, line 186
def self.deleted_libraries
  @@deleted_libraries
end
from_hash(hash, store) click to toggle source
# File lib/alexandria/smart_library.rb, line 81
def self.from_hash(hash, store)
  SmartLibrary.new(hash[:name],
                   hash[:rules].map { |x| Rule.from_hash(x) },
                   hash[:predicate_operator_rule] == :all ? ALL_RULES : ANY_RULE,
                   store)
end
new(name, rules, predicate_operator_rule, store = nil) click to toggle source
Calls superclass method
# File lib/alexandria/smart_library.rb, line 24
def initialize(name, rules, predicate_operator_rule, store = nil)
  super()
  raise if name.nil? || rules.nil? || predicate_operator_rule.nil?

  @name = name.dup.force_encoding("UTF-8")
  @rules = rules
  @predicate_operator_rule = predicate_operator_rule
  @store = store
  libraries = LibraryCollection.instance
  libraries.add_observer(self)
  self.libraries = libraries.all_regular_libraries
  # carry deleted books over from libraries that are part of the smart library
  self.deleted_books = libraries.deleted_books
  @cache = {}
end
really_delete_deleted_libraries() click to toggle source
# File lib/alexandria/smart_library.rb, line 190
def self.really_delete_deleted_libraries
  @@deleted_libraries.each do |library|
    log.debug { "Deleting smart library file (#{yaml})" }
    FileUtils.rm_rf(library.yaml)
  end
end
sample_smart_libraries(store) click to toggle source
# File lib/alexandria/smart_library.rb, line 40
def self.sample_smart_libraries(store)
  a = []

  operands = Rule::Operands::LEFT

  # Favorite books.
  rule = Rule.new(operands.find { |x| x.book_selector == :rating },
                  Rule::Operators::IS,
                  Book::MAX_RATING_STARS.to_s)
  a << new(_("Favorite"), [rule], ALL_RULES, store)

  # Loaned books.
  rule = Rule.new(operands.find { |x| x.book_selector == :loaned },
                  Rule::Operators::IS_TRUE,
                  nil)
  a << new(_("Loaned"), [rule], ALL_RULES, store)

  # Redd books.
  rule = Rule.new(operands.find { |x| x.book_selector == :redd },
                  Rule::Operators::IS_TRUE,
                  nil)
  a << new(_("Read"), [rule], ALL_RULES, store)

  # Own books.
  rule = Rule.new(operands.find { |x| x.book_selector == :own },
                  Rule::Operators::IS_TRUE,
                  nil)
  a << new(_("Owned"), [rule], ALL_RULES, store)

  # Want books.
  rule = Rule.new(operands.find { |x| x.book_selector == :want },
                  Rule::Operators::IS_TRUE,
                  nil)
  rule2 = Rule.new(operands.find { |x| x.book_selector == :own },
                   Rule::Operators::IS_NOT_TRUE,
                   nil)
  a << new(_("Wishlist"), [rule, rule2], ALL_RULES, store)

  a
end

Public Instance Methods

==(other) click to toggle source
# File lib/alexandria/smart_library.rb, line 180
def ==(other)
  other.is_a?(self.class) && other.name == name
end
copy_covers(somewhere) click to toggle source
# File lib/alexandria/smart_library.rb, line 164
def copy_covers(somewhere)
  FileUtils.rm_rf(somewhere)
  FileUtils.mkdir(somewhere)
  each do |book|
    library = @cache[book]
    next unless File.exist?(library.cover(book))

    FileUtils.cp(File.join(library.path, book.ident + Library::EXT[:cover]),
                 File.join(somewhere, library.final_cover(book)))
  end
end
cover(book) click to toggle source
# File lib/alexandria/smart_library.rb, line 135
def cover(book)
  @cache[book].cover(book)
end
delete() click to toggle source
# File lib/alexandria/smart_library.rb, line 197
def delete
  if @@deleted_libraries.include?(self)
    log.info do
      "Already deleted a SmartLibrary with this name (this might mess up undeletes)"
    end
    FileUtils.rm_rf(yaml)
    # so we just delete the old smart library, and
    # 'pending' delete the new one of the same name...
    # urrr... yeah, that'll work!
  end
  @@deleted_libraries << self
end
deleted?() click to toggle source
# File lib/alexandria/smart_library.rb, line 210
def deleted?
  @@deleted_libraries.include?(self)
end
final_cover(book) click to toggle source
# File lib/alexandria/smart_library.rb, line 160
def final_cover(book)
  @cache[book].final_cover(book)
end
n_unrated() click to toggle source
# File lib/alexandria/smart_library.rb, line 176
def n_unrated
  length - n_rated
end
name=(new_name) click to toggle source
# File lib/alexandria/smart_library.rb, line 96
def name=(new_name)
  return unless @name != new_name

  old_yaml = yaml
  @name = new_name
  FileUtils.mv(old_yaml, yaml)
  save
end
refilter() click to toggle source
# File lib/alexandria/smart_library.rb, line 118
def refilter
  filters = @rules.map(&:filter_proc)
  selector = @predicate_operator_rule == ALL_RULES ? :all? : :any?

  clear
  @cache.clear

  @libraries.each do |library|
    filtered_library = library.select do |book|
      filters.send(selector) { |filter| filter.call(book) } # Problem here.
    end
    filtered_library.each { |x| @cache[x] = library }
    concat(filtered_library)
  end
  @n_rated = count { |x| !x.rating.nil? && x.rating > 0 }
end
save(book = nil) click to toggle source
# File lib/alexandria/smart_library.rb, line 147
def save(book = nil)
  if book
    @cache[book].save(book)
  else
    FileUtils.mkdir_p(base_dir)
    File.open(yaml, "w") { |io| io.puts to_hash.to_yaml }
  end
end
save_cover(book, _cover_uri) click to toggle source
# File lib/alexandria/smart_library.rb, line 156
def save_cover(book, _cover_uri)
  @cache[book].save_cover(book)
end
to_hash() click to toggle source
# File lib/alexandria/smart_library.rb, line 88
def to_hash
  {
    name: @name,
    predicate_operator_rule: @predicate_operator_rule == ALL_RULES ? :all : :any,
    rules: @rules.map(&:to_hash)
  }
end
undelete() click to toggle source
# File lib/alexandria/smart_library.rb, line 214
def undelete
  raise unless @@deleted_libraries.include?(self)

  @@deleted_libraries.delete(self)
end
update(*params) click to toggle source
# File lib/alexandria/smart_library.rb, line 105
def update(*params)
  case params.first
  when LibraryCollection
    libraries, _, library = params
    unless library.is_a?(self.class)
      self.libraries = libraries.all_libraries
      refilter
    end
  when Library
    refilter
  end
end
yaml(book = nil) click to toggle source
# File lib/alexandria/smart_library.rb, line 139
def yaml(book = nil)
  if book
    @cache[book].yaml(book)
  else
    File.join(base_dir, @name + EXT)
  end
end

Private Instance Methods

base_dir() click to toggle source
# File lib/alexandria/smart_library.rb, line 229
def base_dir
  @store.smart_library_dir
end
libraries=(ary) click to toggle source
# File lib/alexandria/smart_library.rb, line 222
def libraries=(ary)
  @libraries ||= []
  @libraries.each { |x| x.delete_observer(self) }
  @libraries = ary.select { |x| x.is_a?(Library) }
  @libraries.each { |x| x.add_observer(self) }
end