app/models/calagator/source/parser.rb in calagator-1.0.0 vs app/models/calagator/source/parser.rb in calagator-1.1.0

- old
+ new

@@ -1,122 +1,119 @@ -require "net/http" -require "net/https" -require "open-uri" +require 'net/http' +require 'net/https' +require 'open-uri' # == Source::Parser # # A hierarchy of classes that provide a way to parse different source formats and return hCalendar events. # The base class for all format-specific parsers. Do not use instances of this class # directly, use a subclass of Parser to do the parsing instead. module Calagator + class Source::Parser < Struct.new(:url, :source) + # Return an Array of unsaved Event instances. + def self.to_events(url: nil, source: nil) + # Return events from the first parser that suceeds + events = matched_parsers(url).lazy.collect do |parser| + parser.new(url, source).to_events + end.detect(&:present?) -class Source::Parser < Struct.new(:url, :source) - # Return an Array of unsaved Event instances. - def self.to_events(url: nil, source: nil) - # Return events from the first parser that suceeds - events = matched_parsers(url).lazy.collect { |parser| - parser.new(url, source).to_events - }.detect(&:present?) + events || [] + end - events || [] - end - - def self.matched_parsers(url) - # start with the parser that matches the given URL - parsers.sort_by do |parser| - match = parser.url_pattern.present? && url.try(:match, parser.url_pattern) - match ? 0 : 1 + def self.matched_parsers(url) + # start with the parser that matches the given URL + parsers.sort_by do |parser| + match = parser.url_pattern.present? && url.try(:match, parser.url_pattern) + match ? 0 : 1 + end end - end - private_class_method :matched_parsers + private_class_method :matched_parsers - cattr_accessor(:parsers) { SortedSet.new } + cattr_accessor(:parsers) { SortedSet.new } - def self.inherited(subclass) - parsers << subclass - end + def self.inherited(subclass) + parsers << subclass + end - class_attribute :label, :url_pattern + class_attribute :label, :url_pattern - # Returns an Array of sorted string labels for the parsers. - def self.labels - parsers.map { |p| p.label.to_s }.sort_by(&:downcase) - end + # Returns an Array of sorted string labels for the parsers. + def self.labels + parsers.map { |p| p.label.to_s }.sort_by(&:downcase) + end - def self.read_url(url) - RestClient.get(url).to_str - rescue RestClient::Unauthorized - raise Source::Parser::HttpAuthenticationRequiredError.new - end + def self.read_url(url) + RestClient.get(url).to_str + rescue RestClient::Unauthorized + raise Source::Parser::HttpAuthenticationRequiredError + end - def to_events - raise NotImplementedError - end + def to_events + raise NotImplementedError + end - def self.<=>(other) - # use site-specific parsers first, then generics alphabetically - if self.url_pattern && !other.url_pattern - -1 - elsif !self.url_pattern && other.url_pattern - 1 - else - self.label <=> other.label + def self.<=>(other) + # use site-specific parsers first, then generics alphabetically + if url_pattern && !other.url_pattern + -1 + elsif !url_pattern && other.url_pattern + 1 + else + label <=> other.label + end end - end - private + private - def event_or_duplicate(event) - duplicates = event.find_exact_duplicates - if duplicates.present? - duplicates.first.progenitor - else - event + def event_or_duplicate(event) + duplicates = event.find_exact_duplicates + if duplicates.present? + duplicates.first.progenitor + else + event + end end - end - def venue_or_duplicate(venue) - duplicates = venue.find_exact_duplicates - if duplicates.present? - duplicates.first.progenitor - else - venue_machine_tag_name = venue.tag_list.find do |tag_name| - MachineTag.new(tag_name).venue? - end - matched_venue = Venue.tagged_with(venue_machine_tag_name).first - - if matched_venue.present? - matched_venue.progenitor + def venue_or_duplicate(venue) + duplicates = venue.find_exact_duplicates + if duplicates.present? + duplicates.first.progenitor else - venue + venue_machine_tag_name = venue.tag_list.find do |tag_name| + MachineTag.new(tag_name).venue? + end + matched_venue = Venue.tagged_with(venue_machine_tag_name).first + + if matched_venue.present? + matched_venue.progenitor + else + venue + end end end - end - def to_events_api_helper(url, error_key="error", &block) - # Extract +event_id+ from :url using +url_pattern+. - event_id = url[self.class.url_pattern, 1] - return false unless event_id # Give up unless we find the identifier. + def to_events_api_helper(url, error_key = 'error') + # Extract +event_id+ from :url using +url_pattern+. + event_id = url[self.class.url_pattern, 1] + return false unless event_id # Give up unless we find the identifier. - # Get URL and params for using the API. - url, params = *block.call(event_id) + # Get URL and params for using the API. + url, params = *yield(event_id) - # Get data from the API. - data = RestClient.get(url, params: params, accept: "json").to_str - data = JSON.parse(data) + # Get data from the API. + data = RestClient.get(url, params: params, accept: 'json').to_str + data = JSON.parse(data) - # Stop if API tells us there's an error. - raise Source::Parser::NotFound, error if error = data[error_key] + # Stop if API tells us there's an error. + raise Source::Parser::NotFound, error if error = data[error_key] - data['event_id'] = event_id - data + data['event_id'] = event_id + data + end end end -end - require 'calagator/source/parser/not_found' require 'calagator/source/parser/meetup' require 'calagator/source/parser/facebook' require 'calagator/source/parser/ical' require 'calagator/source/parser/hcal' -