class Alexandria::BookProviders
FIXME: Use delegation instead of inheritance.
Constants
- SEARCH_BY_KEYWORD
Attributes
abstract_classes[R]
Public Class Methods
abstract_classes()
click to toggle source
# File lib/alexandria/book_providers.rb, line 366 def self.abstract_classes instance.abstract_classes end
isbn_search(criterion)
click to toggle source
# File lib/alexandria/book_providers.rb, line 125 def self.isbn_search(criterion) search(criterion, SEARCH_BY_ISBN) end
list()
click to toggle source
# File lib/alexandria/book_providers.rb, line 362 def self.list instance end
new()
click to toggle source
# File lib/alexandria/book_providers.rb, line 304 def initialize @prefs = Alexandria::Preferences.instance @abstract_classes = [] update_priority end
search(criterion, type)
click to toggle source
# File lib/alexandria/book_providers.rb, line 50 def self.search(criterion, type) factory_n = 0 begin factory = instance[factory_n] log.debug { factory.fullname + " lookup" } unless factory.enabled log.debug { factory.fullname + " disabled!, skipping..." } raise ProviderSkippedError end instance.changed instance.notify_observers(:searching, factory.fullname) # new results = factory.search(criterion, type) # sanity check if at least one valid result is actually found results.delete_if { |book, _cover| book.nil? } if results.empty? instance.changed instance.notify_observers(:not_found, factory.fullname) # new raise NoResultsError else log.info { "found at " + factory.fullname } instance.changed instance.notify_observers(:found, factory.fullname) # new results end rescue StandardError => ex if ex.is_a? NoResultsError unless ex.instance_of? ProviderSkippedError instance.changed instance.notify_observers(:not_found, factory.fullname) # new Thread.new { sleep(0.5) }.join end else instance.changed instance.notify_observers(:error, factory.fullname) # new Thread.new { sleep(0.5) }.join # hrmmmm, to make readable... trace = ex.backtrace.join("\n >") log.warn { "Provider #{factory.name} encountered error: #{ex.message} #{trace}" } end if factory == instance.last log.warn { "Error while searching #{criterion}" } message = case ex when Timeout::Error _("Couldn't reach the provider '%s': timeout " \ "expired.") % factory.name when SocketError format(_("Couldn't reach the provider '%s': socket " \ "error (%s)."), factory.name, ex.message) when NoResultsError, ProviderSkippedError _("No results were found. Make sure your " \ "search criterion is spelled correctly, and " \ "try again.") when TooManyResultsError _("Too many results for that search.") when InvalidSearchTypeError _("Invalid search type.") else ex.message end log.debug { "raising empty error #{message}" } raise SearchEmptyError, message # rubocop:disable I18n/GetText/DecorateFunctionMessage else factory_n += 1 retry end end end
Public Instance Methods
update_priority()
click to toggle source
# File lib/alexandria/book_providers.rb, line 310 def update_priority # This is weird code that sorts through the list of classes brought # in by requires and sorts through whether they are 'Abstract' or not, # adding their names to @prefs. @abstract_classes.clear providers = {} self.class.constants.each do |constant| md = /(.+)Provider$/.match(constant) next unless md klass = self.class.module_eval(constant.to_s) if klass < AbstractProvider && (klass != GenericProvider) && (klass != WebsiteBasedProvider) if klass.abstract? @abstract_classes << klass else providers[md[1]] = klass.instance end end end if (ary = @prefs.get_variable :abstract_providers) ary.each do |name| md = /^(.+)_/.match(name) next unless md klass_name = md[1] + "Provider" klass = @abstract_classes.find { |x| x.name.include?(klass_name) } next unless klass fullname = @prefs.send(name.downcase + "_name") next unless fullname instance = klass.new instance.name = name instance.fullname = fullname instance.prefs.read providers[name] = instance end end clear rejig_providers_priority priority = (@prefs.providers_priority || []) priority.map!(&:strip) rest = providers.keys - priority priority.each { |pname| self << providers[pname] } rest.sort.each { |pname| self << providers[pname] } compact! end
Private Instance Methods
rejig_providers_priority()
click to toggle source
# File lib/alexandria/book_providers.rb, line 372 def rejig_providers_priority priority = (@prefs.providers_priority || []) return if priority.empty? changed = false if (worldcat_index = priority.index("Worldcat")) priority[worldcat_index] = "WorldCat" changed = true end @prefs.providers_priority = priority if changed end