Permalink
Browse files

Converted to a gem.

  • Loading branch information...
0 parents commit 37afe02baf711f638cc24d87fceb4ccb52d1cc40 @tylerhunt committed Jun 17, 2010
@@ -0,0 +1,43 @@
+require 'active_support/core_ext'
+require 'curb'
+require 'sax-machine'
+
+module TicketNetwork
+ ROOT = 'tnwebservices.ticketnetwork.com/TNWebService/v3.1'.freeze
+ CATALOG = "http://#{ROOT}/TNWebServiceStringInputs.asmx".freeze
+ CHECKOUT = "https://#{ROOT}/TNCheckoutWebServiceStringInputs.asmx".freeze
+
+ Error = Class.new(StandardError)
+ AuthorizationError = Class.new(Error)
+ ParameterError = Class.new(Error)
+ NetworkError = Class.new(Error)
+
+ mattr_accessor :client_id
+
+ autoload :Base, 'ticket_network/base'
+ autoload :FormatHelper, 'ticket_network/format_helper'
+ autoload :ParseHelper, 'ticket_network/parse_helper'
+
+ module Catalog
+ autoload :Base, 'ticket_network/catalog/base'
+ autoload :Category, 'ticket_network/catalog/category'
+ autoload :Configuration, 'ticket_network/catalog/configuration'
+ autoload :Event, 'ticket_network/catalog/event'
+ autoload :Performance, 'ticket_network/catalog/performance'
+ autoload :Performer, 'ticket_network/catalog/performer'
+ autoload :PerformerRank, 'ticket_network/catalog/performer_rank'
+ autoload :Ticket, 'ticket_network/catalog/ticket'
+ autoload :Venue, 'ticket_network/catalog/venue'
+ end
+
+ module Checkout
+ autoload :Address, 'ticket_network/checkout/address'
+ autoload :AddressType, 'ticket_network/checkout/address_type'
+ autoload :Base, 'ticket_network/checkout/base'
+ autoload :CreditCard, 'ticket_network/checkout/credit_card'
+ autoload :Customer, 'ticket_network/checkout/customer'
+ autoload :Order, 'ticket_network/checkout/order'
+ autoload :PhoneNumber, 'ticket_network/checkout/phone_number'
+ autoload :PhoneNumberType, 'ticket_network/checkout/phone_number_type'
+ end
+end
@@ -0,0 +1,147 @@
+module TicketNetwork
+ class Base
+ class Action
+ attr_reader :name, :operation, :method, :service, :parser, :parameters
+
+ def initialize(operation, options={}, &block)
+ @name = options[:as] || operation
+ @operation = (operation || options[:as]).to_s.camelcase.sub(/Id/, 'ID')
+ @method = options[:method]
+ @service = options[:service]
+ @parser = options[:parser]
+ @parameters = {}
+
+ options[:defaults].each { |defaults| instance_eval(&defaults) }
+ instance_eval(&block) if block_given?
+ end
+
+ # Adds a parameter that the web service accepts.
+ def parameter(name, options={})
+ @parameters[name] = options
+ end
+
+ def execute(*args)
+ parameters = args.first || {}
+ Request.new(self, parameters).perform
+ end
+ end
+
+ class Request
+ include TicketNetwork::FormatHelper
+
+ def initialize(action, parameters)
+ @action = action
+ @parameters = HashWithIndifferentAccess.new(parameters)
+ end
+
+ # Executes the call to the web service.
+ def perform
+ response = Curl::Easy.new(url)
+
+ begin
+ case @action.method
+ when :get
+ response.http_get
+ when :post
+ response.http_post(query)
+ end
+ rescue Curl::Err::RecvError, Curl::Err::ConnectionFailedError, Curl::Err::HostResolutionError => e
+ raise NetworkError.new(e.to_s)
+ end
+
+ case body = response.body_str
+ when /^Authorization error: IP ([\d\.]+)/
+ raise AuthorizationError, "Unauthorized IP (#{$1})"
+ when /must be SSL/
+ raise AuthorizationError, 'SSL Required'
+ when /^Missing parameter: (.*)\./
+ raise ParameterError, "Missing #{$1}"
+ when /^Parameter error: (.*): (.*)\./
+ raise ParameterError, "Invalid #{$1} (#{$2})"
+ when /\A(?!<\?xml)/
+ raise Error, body.split(/\./).first
+ else
+ @action.parser.parse(body) if body
+ end
+ end
+
+ def endpoint(service)
+ case service
+ when :checkout then CHECKOUT
+ when :catalog then CATALOG
+ else raise Error.new("Unknown endpoint for service #{service}")
+ end
+ end
+ private :endpoint
+
+ # Builds the base URL from the endpoint and operation. If the method is
+ # GET, the query values are appended.
+ def url
+ base_url = "#{endpoint(@action.service)}/#{@action.operation}"
+ base_url << "?#{query}" if @action.method == :get
+ base_url
+ end
+ private :url
+
+ # Builds the query string from the specified parameter values.
+ def query
+ @action.parameters.collect do |key, options|
+ value = @parameters[options[:as] || key]
+ value ||= options[:default] if options.include?(:default)
+
+ "#{format_query_key(key)}=#{format_query_value(value)}"
+ end.join('&')
+ end
+ private :query
+ end
+
+ class << self
+ # Sets or returns the service.
+ def service(service=nil)
+ unless service
+ read_inheritable_attribute(:service)
+ else
+ write_inheritable_attribute(:service, service)
+ end
+ end
+
+ # Sets or returns action defaults.
+ def defaults(&block)
+ unless block
+ read_inheritable_attribute(:defaults)
+ else
+ write_inheritable_array(:defaults, [block])
+ end
+ end
+
+ # Creates a new GET operation.
+ def get(operation, options={}, &block)
+ action(operation, options.merge(:method => :get), &block)
+ end
+
+ # Creates a new POST operation.
+ def post(operation, options={}, &block)
+ action(operation, options.merge(:method => :post), &block)
+ end
+
+ # Creates a new operation.
+ def action(operation, options={}, &block)
+ options[:service] ||= service
+ options[:defaults] ||= defaults
+ options[:parser] ||= self::Parser
+ action = Action.new(operation, options, &block)
+
+ self.singleton_class.class_eval do
+ define_method(action.name) do |*args|
+ action.execute(*args)
+ end
+ end
+ end
+ private :action
+ end
+
+ defaults do
+ parameter :website_config_id, :default => TicketNetwork.client_id
+ end
+ end
+end
@@ -0,0 +1,7 @@
+module TicketNetwork::Catalog
+ class Base < TicketNetwork::Base
+ service :catalog
+ end
+
+ ParseHelper = TicketNetwork::ParseHelper
+end
@@ -0,0 +1,38 @@
+module TicketNetwork::Catalog
+ class Category < Base
+ class Parser
+ include ParseHelper
+
+ class Category
+ include ParseHelper
+
+ element :child_category_description, :as => :child_name
+ element :child_category_id, :as => :child_id
+ element :grandchild_category_description, :as => :grandchild_name
+ element :grandchild_category_id, :as => :grandchild_id
+ element :parent_category_description, :as => :parent_name
+ element :parent_category_id, :as => :parent_id
+ end
+
+ elements :category, :as => :categories, :class => Category
+ end
+
+ get :get_categories_master_list, :as => :fetch
+
+ class << self
+ def all(parameters={})
+ fetch(parameters).categories
+ end
+
+ def sanitize_name(name)
+ name = name.titleize
+ name.strip!
+ name.gsub!(/Div I A/, 'Div I-A')
+ name.gsub!(/Div I-Aa/, 'Div I-AA')
+ name.gsub!(/ And /, ' and ')
+ name
+ end
+ private :sanitize_name
+ end
+ end
+end
@@ -0,0 +1,46 @@
+module TicketNetwork::Catalog
+ class Configuration < Base
+ MAP_ROOT = 'http://maps.seatics.com/'.freeze
+
+ class Parser
+ include ParseHelper
+
+ class Configuration
+ include ParseHelper
+
+ element :capacity
+ element :id
+ element :map_site
+ element :map_url
+ element :type_description
+ element :type_id
+ element :venue_id
+ end
+
+ elements :venue_configuration, :as => :venue_configurations, :class => Configuration
+ end
+
+ get :get_venue_configurations, :as => :fetch do
+ parameter :venue_id
+ end
+
+ class << self
+ def all(parameters={})
+ fetch(parameters).venue_configurations
+ end
+
+ def map_url(venue_configuration)
+ unless venue_configuration.map_url.blank?
+ map_site = venue_configuration.map_site || MAP_ROOT
+ map_url = "#{map_site}/#{URI.escape(venue_configuration.map_url)}"
+ map_url.gsub!('[', '%5B')
+ map_url.gsub!(']', '%5D')
+ uri = URI.parse(map_url)
+ uri.path.gsub!(/\/\//, '/')
+ uri.to_s
+ end
+ end
+ private :find_map
+ end
+ end
+end
@@ -0,0 +1,63 @@
+module TicketNetwork::Catalog
+ class Event < Base
+ class Parser
+ include ParseHelper
+
+ class Event
+ include ParseHelper
+
+ element :child_category_id
+ element :city
+ element :clicks
+ element :date
+ element :display_date
+ element :grandchild_category_id
+ element :id
+ element :is_womens_event
+ element :map_url
+ element :name
+ element :parent_category_id
+ element :state_province
+ element :state_province_id
+ element :venue
+ element :venue_configuration_id
+ element :venue_id
+ end
+
+ elements :event, :as => :events, :class => Event
+ end
+
+ get :get_events, :as => :fetch do
+ parameter :begin_date
+ parameter :child_category_id
+ parameter :city_zip, :as => :locality_postal_code
+ parameter :end_date
+ parameter :event_date
+ parameter :event_id
+ parameter :event_name
+ parameter :grandchild_category_id
+ parameter :high_price
+ parameter :low_price
+ parameter :modification_date
+ parameter :near_zip, :as => :near_postal_code
+ parameter :no_performers
+ parameter :number_of_events, :as => :limit, :default => 100_000
+ parameter :only_mine
+ parameter :order_by_clause, :as => :order
+ parameter :parent_category_id
+ parameter :performer_id
+ parameter :performer_name
+ parameter :state_id
+ parameter :state_prov_desc, :as => :region
+ parameter :venue_id
+ parameter :venue_name
+ parameter :where_clause, :as => :where
+ end
+
+ class << self
+ def all(parameters={})
+ fetch(parameters).events
+ end
+ end
+ end
+end
@@ -0,0 +1,25 @@
+module TicketNetwork::Catalog
+ class EventPerformer < Base
+ class Parser
+ include ParseHelper
+
+ class Performer
+ include ParseHelper
+
+ element :event_id
+ element :performer_id, :as => :id
+ element :performer_name, :as => :name
+ end
+
+ elements :event_performer, :as => :performers, :class => Performer
+ end
+
+ get :get_event_performers, :as => :fetch
+
+ class << self
+ def all(parameters={})
+ fetch(parameters).performers
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 37afe02

Please sign in to comment.