diff --git a/ImplementationGotchas.markdown b/ImplementationGotchas.markdown new file mode 100644 index 0000000..d740f8a --- /dev/null +++ b/ImplementationGotchas.markdown @@ -0,0 +1,44 @@ +Eventbrite's API is very poorly done. I've catalogued a list of +issues you'll likely encounter if you want to make your own integration with +their API. Most of the code in this library exists simply to fix these +issues - otherwise you could probably just use HTTParty directly. + + +API Gotchas +------------ + +A list of sticking points for anyone attempting their own integration with the Eventbrite API: + + +__/get => /update variable inconsistencies__ + +* event.id => event.event_id +* event.timezone (Olson format, ex: "US/Central") => event.timezone (GMT offset hours, ex: "GMT-05") +* event.privacy (String representing privacy "Private"|"Public") => event.privacy (Boolean 0 = public) +* event.url => event.personalized_url +* venue.address => venue.adress +* venue.address_2 => venue.adress_2 +* venue.name => venue.venue +* event.tickets.ticket.start_date => ticket.start_sales +* event.tickets.ticket.end_date => ticket.end_sales +* event.tickets.ticket.visible (1 is visible) => ticket.hide (y is hidden, n is visible) +* event.tickets.ticket.quantity_available => ticket.quantity + +__Fields you can't edit__ + +* event.category +* event.tags +* event.logo +* ticket.hide (on /ticket_new. You must save the ticket then call /ticket_update to hide) + +__Documentation errors__ + +* /venue_new and /venue_update does not throw an error if "venue" is invalid/non-unique/empty. +* Dates are not technically ISO 8601 (ISO 8601 specifies a "T" - not a space - between date and time, so passing perfectly formatted ISO 8601 datetime strings such as those a standard library would provide will cause errors) +* Error description for event Privacy Error:
"The privacy field must be equal to 0 (public) or 1 (private)"
-> This is the opposite of the actual case. 0 is private and 1 is public, as described in other places within the API. +* /ticket_new and /ticket_update do not throw errors if quantity not set + +__Other gotchas__ + +* Venue object included in event has extra "Lat-Long" attribute, along with "latitude" and "longitude". If you're turning a result into an object, this might cause an error if you don't suspect it. +* Timezones are weird (nothing EventBrite can do about this one): GMT offset for timezones is always computed in standard time (don't adjust for Daylight Savings, unlike UTC offset). This weirdness means that once you save the timezone the Olson description might not match what you think it should (ex. US/Eastern becomes GMT-5 which then becomes America/Bogota) diff --git a/README.markdown b/README.markdown index 065a8ee..0c67402 100644 --- a/README.markdown +++ b/README.markdown @@ -19,6 +19,20 @@ Usage Some basic (yardoc generated) documentation availabe at: http://therabidbanana.github.com/eventbrite/ +This library attempts to create an almost ActiveResource like wrapper +around the Eventbrite api. The following objects are available: + +* Attendee (can only be viewed, not edited) +* Discount +* Event (has many Tickets, Attendees, Discounts, has one Venue and + one Organizer) +* Organizer (has many Events) +* Ticket +* User (has many Events, Organizers, Venues) +* Venue + + + Authentication -------------- Many methods require user authentication. For these methods, you can pass a user object as an authentication token, and the user's api_key will automatically be used for the request. @@ -27,7 +41,7 @@ Example: Eventbrite::Event.new({"x" => "y"... , "user" => user}) -Known Bugs +Known Issues ---------- 1. This library's testing coverage is almost zero. @@ -46,43 +60,20 @@ Learn more about EventBrite's App Key policy here: [Terms of Service](http://www Register for your own app key here: [Request a Key](http://www.eventbrite.com/api/key/) -API Gotchas: --------------------- - -A list of sticking points for anyone attempting their own integration with the EventBrite API: - -__/get => /update variable inconsistencies__ - -* event.id => event.event_id -* event.timezone (Olson format, ex: "US/Central") => event.timezone (GMT offset hours, ex: "GMT-05") -* event.privacy (String representing privacy "Private"|"Public") => event.privacy (Boolean 0 = public) -* event.url => event.personalized_url -* venue.address => venue.adress -* venue.address_2 => venue.adress_2 -* venue.name => venue.venue -* event.tickets.ticket.start_date => ticket.start_sales -* event.tickets.ticket.end_date => ticket.end_sales -* event.tickets.ticket.visible (1 is visible) => ticket.hide (y is hidden, n is visible) -* event.tickets.ticket.quantity_available => ticket.quantity - -__Fields you can't edit__ - -* event.category -* event.tags -* event.logo -* ticket.hide (on /ticket_new. You must save the ticket then call /ticket_update to hide) +API Gotchas +------------ -__Documentation errors__ +I've compiled a list of issues developers may encounter with the poorly +designed Eventbrite API (in case you're writing your own integration +from scratch in Ruby or any other language). -* /venue_new and /venue_update does not throw an error if "venue" is invalid/non-unique/empty. -* Dates are not technically ISO 8601 (ISO 8601 specifies a "T" - not a space - between date and time, so passing perfectly formatted ISO 8601 datetime strings such as those a standard library would provide will cause errors) -* Error description for event Privacy Error:
"The privacy field must be equal to 0 (public) or 1 (private)"
-> This is the opposite of the actual case. 0 is private and 1 is public, as described in other places within the API. -* /ticket_new and /ticket_update do not throw errors if quantity not set +There are many places where variable names are misspelled, or format is +changed, and many places where the API documentation is flat out wrong +(dates are not ISO8601 anywhere in the eventbrite api, though they claim +they are). -__Other gotchas__ +Read the details at: http://therabidbanana.github.com/eventbrite/file.ImplementationGotchas.html -* Venue object included in event has extra "Lat-Long" attribute, along with "latitude" and "longitude". If you're turning a result into an object, this might cause an error if you don't suspect it. -* Timezones are weird (nothing EventBrite can do about this one): GMT offset for timezones is always computed in standard time (don't adjust for Daylight Savings, unlike UTC offset). This weirdness means that once you save the timezone the Olson description might not match what you think it should (ex. US/Eastern becomes GMT-5 which then becomes America/Bogota) Note on Patches/Pull Requests ----------------------------- diff --git a/lib/eventbrite/api_object.rb b/lib/eventbrite/api_object.rb index be75c68..3bab867 100644 --- a/lib/eventbrite/api_object.rb +++ b/lib/eventbrite/api_object.rb @@ -1,11 +1,18 @@ require 'eventbrite/api_object_class_methods' require 'eventbrite/api_object_relationships' module Eventbrite + # @private + # Class for generalizing API interactions class ApiObject extend Eventbrite::ApiObjectClassMethods include Eventbrite::ApiObjectRelationships + attr_accessor :id, :owner + # @private + # Individual attribute tracking attr_accessor :attributes, :relations, :collections + # @private + # Dirty tracking attr_accessor :dirty, :dirty_relations, :dirty_collections def initialize(owner = false, hash = {}) @@ -18,34 +25,51 @@ def initialize(owner = false, hash = {}) end end + # @private + # Initializes all attributes and dirtry tracking def preinit @attributes = @relations = @collections = {} @dirty = @dirty_relations = @dirty_collections = {} end + # @private + # Marks everything as clean. def clean! @dirty = @dirty_relations = @dirty_collections = {} end + # @private # Callback after initialization def init; end + # @private + # Standard getter for attributes array def attribute_get(key); @attributes[key]; end + # @private + # Standard setter for attributes, also tracking dirtiness def attribute_set(key, val, no_dirty = false) @dirty[key] = true if(@attributes[key] != val && !no_dirty) @attributes[key] = val after_attribute_set end + # @private + # Callback for when attributes are set. def after_attribute_set end - + # @private + # Convert id to integer def id=(new_id,*args) @id = new_id.to_i end + # Loads attributes and relations from a hash, + # or makes an API call to retrieve necessary data if load hash is empty + # + # The no_dirty attribute allows you to force a dirty tracking to recognize + # the object as clean. def load(hash = {}, no_dirty = false) if hash.nil? || hash.size == 0 response = Eventbrite.call("#{self.class.singlet_name}_get", prep_api_hash('get')) @@ -60,7 +84,8 @@ def load(hash = {}, no_dirty = false) after_load(hash) end - + # @private + # Loads all attributes from hash unless set to ignore. def init_with_hash(hash, no_dirty = false) @attributes ||= {} hash.each do |k, v| @@ -74,12 +99,13 @@ def init_with_hash(hash, no_dirty = false) end end - + # @private # A callback for after loads def after_load(hash = {}) hash end + # @private # A callback for methods to clean up the hash a bit # allowing subclasses to insert the user if necessary def prep_api_hash(method = 'get', hash = {}) @@ -90,28 +116,33 @@ def prep_api_hash(method = 'get', hash = {}) hash end + # @private # Callbacks for individual hash changes # These are added to the updatable_hash, if appropriate # These are called by prep_api_hash def api_hash; {:user => owner}; end + # @private def update_hash; {:id => id}; end + # @private def get_hash; {:id => id}; end + # @private def new_hash; {}; end + # @private def nested_hash; {:user => owner, :id => id}; end - # Forces a clean load from the remote API. Load can be passed a hash of local + # Forces a clean load from the remote API. #load can be passed a hash of local # values to avoid an API call, but this circumvents it. def load! load({}, true) end - + # @private # Callback that happens before saving. Allows modification of options def before_save(opts = {}); opts; end - # Save function. Can alter functionality by changing callbacks + # Save function. Individual objects can alter functionality by changing callbacks def save(opts = {}) return false unless dirty? opts.merge!(updatable_hash(self.class.requires)) @@ -133,14 +164,18 @@ def save(opts = {}) call end + # @private # After save callback, only called on a new call def after_new; end + # @private # After save callback, only called on an update call def after_update; end + # @private # After save callback def after_save; end - + # @private + # Creates a hash of attributes for an update def updatable_hash(always_dirty = []) updates = {} @attributes.each do |k, v| @@ -156,14 +191,17 @@ def updatable_hash(always_dirty = []) updates end + # @private def inspect "#<#{self.class.to_s}:#{self.id} @attributes=#{@attributes.inspect}>" end + # Returns a simple string representing the class and its attributes def to_s "#<#{self.class.to_s}:#{self.id} @attributes=#{@attributes.inspect}>" end + # Defines whether the object has been loaded from a remote source. If not, then # we assume it's new when saving. def loaded? @@ -171,7 +209,7 @@ def loaded? end # Something is dirty if it's never been loaded or if the @dirty - # hash contains something. + # hash contains something (which happens when an attribute is changed) def dirty? @dirty ||= {} @dirty.size > 0 || !loaded? diff --git a/lib/eventbrite/api_object_class_methods.rb b/lib/eventbrite/api_object_class_methods.rb index 4d2bb08..07021e3 100644 --- a/lib/eventbrite/api_object_class_methods.rb +++ b/lib/eventbrite/api_object_class_methods.rb @@ -1,27 +1,32 @@ module Eventbrite + # @private + # Extra methods for class level interactions (defining attributes and + # relationships) module ApiObjectClassMethods + # @private def singlet_name(name = false) @singlet_name = name if name @singlet_name || self.to_s.gsub('Eventbrite::', '').downcase end - + # @private def plural_name(name = false) @plural_name = name if name @plural_name || "#{self.singlet_name}s" end - + # @private def ignores(*args) @ignores ||= [] @ignores.concat(args) unless args.empty? @ignores end - + # @private def requires(*args) @requires ||= [] @requires.concat(args) unless args.empty? @requires end + # @private # Columns to reformat when sending outgoing data # (Reformatting is assumed to be done by calling the method with the # same name as the attribute, so to reformat foo, use def foo... with @@ -32,6 +37,7 @@ def reformats(*args) @reformats end + # @private # Columns to rename when sending outgoing data def renames(attrs = false) @renames ||= {} @@ -39,6 +45,8 @@ def renames(attrs = false) @renames end + # @private + # Declares updatable attributes def updatable(*args) args.each{|symbol| module_eval( "def #{symbol}(); attribute_get(:#{symbol}); end") @@ -46,6 +54,8 @@ def updatable(*args) } end + # @private + # Declares readable attributes def readable(*args) args.each{|symbol| @@ -54,6 +64,8 @@ def readable(*args) } end + # @private + # Declares updatable date attributes def updatable_date(*args) args.each{|symbol| @@ -62,6 +74,8 @@ def updatable_date(*args) } end + # @private + # Declares readable date attributes def readable_date(*args) args.each{|symbol| @@ -70,6 +84,7 @@ def readable_date(*args) } end + # @private # Columns that are the same as other columns. This is mainly useful # for incoming data with inconsistent naming. Args are passed as a hash, # where the key is the new method name, and the value is the target method name @@ -83,6 +98,7 @@ def remap(args = {}) } end + # @private # Defines a has 1 relation def has(args = {}) @class_relations ||= {} @@ -94,10 +110,13 @@ def has(args = {}) @class_relations[symbol] = klass } end + # @private + # Return a list of relations a class shares def relations @class_relations || {} end + # @private # Defines a has may relation def collection(args = {}) @class_collections ||= {} @@ -109,6 +128,7 @@ def collection(args = {}) @class_collections[symbol] = klass } end + # @private def collections @class_collections || {} end diff --git a/lib/eventbrite/api_object_collection.rb b/lib/eventbrite/api_object_collection.rb index 050b19d..a1270f4 100644 --- a/lib/eventbrite/api_object_collection.rb +++ b/lib/eventbrite/api_object_collection.rb @@ -1,4 +1,6 @@ module Eventbrite + # @private + # An API Object collection acts mostly as an array, but with dirty tracking. class ApiObjectCollection def initialize(owner = false, hash_array = [], parent = false) @@ -9,20 +11,24 @@ def initialize(owner = false, hash_array = [], parent = false) @array = @array.reject{|v| v.__send__(self.class.collection_for.requires.first).nil? || v.__send__(self.class.collection_for.requires.first) == ""} unless self.class.collection_for.requires.empty? end + # @private def inspect "#{@array.inspect}" end + # Returns an list of objects contained in this collection. def to_s "#{@array.inspect}" end + # Saves all objects that are dirty within a collection def save @array.each do |a| a.save if a.dirty? end end + # Returns true if any object in collection is dirty def dirty? is_dirty = false @array.each do |a| @@ -31,27 +37,36 @@ def dirty? is_dirty end + # All undefined methods are passed through to the standard Ruby Array of items + # (so you can call #map or #size) def method_missing(meth, *args, &block) @array.__send__(meth, *args, &block) end - + # @private + # Declares which class this is a collection for def self.collection_for(type = false) @collection_for = type if type @collection_for end + # @private + # Declares the singular name for this object def self.singlet_name(name = false) @singlet_name = name if name @singlet_name || @collection_for.singlet_name end + # @private + # Declares the plural name for this collection, defaulting to singular + s def self.plural_name(name = false) @plural_name = name if name @plural_name || @collection_for.plural_name || "#{self.singlet_name}s" end - + # @private + # Defines the API call to get the collection, defaulting to + # user_list_#{plural_name} def self.getter(name = false) @getter = name if name @getter || "user_list_#{self.plural_name}" diff --git a/lib/eventbrite/api_object_relationships.rb b/lib/eventbrite/api_object_relationships.rb index 4d14183..c08c306 100644 --- a/lib/eventbrite/api_object_relationships.rb +++ b/lib/eventbrite/api_object_relationships.rb @@ -1,6 +1,10 @@ module Eventbrite + # @private module ApiObjectRelationships + # @private def relation_get(key); @relations[key]; end + # @private + # Gets a collection for this relationship def collection_get(key); return @collections[key] unless @collections[key].nil? || collection_dirty?(key) klass = self.class.collections[key] @@ -19,41 +23,63 @@ def collection_get(key); collection_set(key, c, self) end - + # @private + # Force clean for relationship def collection_clean!(key); @dirty_collections[key] = false; end + # @private + # Force collection to be dirty def collection_dirty!(key); @dirty_collections[key] = true; end + # @private + # Returns true if collection is dirty def collection_dirty?(key); @dirty_collections[key] ? true : false; end + # @private + # Force relation to be clean def relation_clean!(key); @dirty_relations[key] = false; end + # @private + # Force relation to be dirty def relation_dirty!(key); @dirty_relations[key] = true; end + # @private + # Returns true if relation is dirty def relation_dirty?(key); @dirty_relations[key] ? true : false; end - + # @private + # Set a relationship to a value def relation_set(key, val, no_dirty = false) @dirty_relations[key] = true @relations[key] = val end + # @private + # Set a collection to a value def collection_set(key, val, no_dirty = false) @collections[key] = val end + # @private + # Unwraps XML response def unnest_child_response(response) response["#{self.class.singlet_name}"] end + # @private + # Load any existing relationships from a hash def load_relations_with_hash(hash, no_dirty = false) self.class.relations.each do |rel, klass| relation_set(rel, klass.new(owner, hash.delete(klass.singlet_name)), no_dirty) if hash[klass.singlet_name] end end + # @private + # Load any existing collections from a hash def load_collections_with_hash(hash, no_dirty = false) self.class.relations.each do |rel, klass| collection_set(rel, klass.new(owner, hash.delete(klass.plural_name)), false, self) if hash[klass.singlet_name] end end + # @private + # Saves all relationships (auto called by save) def relations_save(opts) self.class.relations.each do |rel, klass| relation_get(rel).save if relation_get(rel) && relation_get(rel).dirty? @@ -63,6 +89,8 @@ def relations_save(opts) opts end + # @private + # Saves all collections if dirty def collections_save self.class.collections.each do |col, klass| collection_get(col).save if collection_get(col) diff --git a/lib/eventbrite/api_objects/attendee.rb b/lib/eventbrite/api_objects/attendee.rb index 9a75fea..59821f9 100644 --- a/lib/eventbrite/api_objects/attendee.rb +++ b/lib/eventbrite/api_objects/attendee.rb @@ -1,6 +1,8 @@ require 'eventbrite/api_objects/ticket' module Eventbrite + # The Attendee object represents an attendee to the {Eventbrite::Event event}. + # Attendees can only be viewed, not modified. class Attendee < ApiObject readable :quantity, :currency, :amount_paid @@ -35,16 +37,25 @@ def initialize(event = nil, hash = {}) init_with_hash(hash, true) end + # @private + # Attendees can't be altered - overriding the ApiObject#save so it doesn't + # do anything. def save(*args) # noop. Attendees can't be altered via api end end + + # Represents a list of {Eventbrite::Attendee Attendees}. class AttendeeCollection < ApiObjectCollection collection_for Attendee getter :event_list_attendees def initialize(owner = false, hash_array = [], event = false) super(event, hash_array) end + + # @private + # Attendees can't be altered - overriding the ApiObjectCollection#save so it doesn't + # do anything. def save(*args) # noop. Attendees can't be altered via api end diff --git a/lib/eventbrite/api_objects/discount.rb b/lib/eventbrite/api_objects/discount.rb index 119e4ae..3bda924 100644 --- a/lib/eventbrite/api_objects/discount.rb +++ b/lib/eventbrite/api_objects/discount.rb @@ -1,5 +1,9 @@ module Eventbrite + # Discounts are available for events. You can set either amount_off or + # percent_off. + # + # A discount code must be set. class Discount < ApiObject updatable :code @@ -11,7 +15,10 @@ class Discount < ApiObject requires :code - # Tickets can't live outside events, so we override standard owner to be event. + # Discounts can't live outside {Eventbrite::Event events} - you must + # pass an event as the first argument. + # @raise [ArgumentError] raises an argument error unless an + # Eventbrite::Event is passed def initialize(event = nil, hash = {}) preinit raise ArgumentError unless event.is_a? Eventbrite::Event @@ -21,37 +28,51 @@ def initialize(event = nil, hash = {}) init_with_hash(hash, true) end + # Allows setting the id via discount_id def discount_id=(val, no_dirty = false) self.id = val end + # @private + # Discounts must have an attached event id to be created. def new_hash {:event_id => @event.id} end - + # @private + # Mark event as dirty if a discount is created def after_new @event.dirty_discounts! end + # @private + # Mark event as dirty if a discount is edited def after_save @event.dirty_discounts! end - + + # @private + # Mark event as dirty if a discount is edited def after_attribute_set @event.dirty_discounts! unless @event.nil? end + # Only one of amount_off and percent_off can be set. def amount_off=(val, no_dirty = false) attribute_set(:amount_off, val, no_dirty) attribute_set(:percent_off, "", no_dirty) end + + # Only one of amount_off and percent_off can be set. def percent_off=(val, no_dirty = false) attribute_set(:percent_off, val, no_dirty) attribute_set(:amount_off, "", no_dirty) end end + + # Represents a list of all {Eventbrite::Discount discounts} for an + # {Eventbrite::Event event}. class DiscountCollection < ApiObjectCollection collection_for Discount getter :event_list_discounts diff --git a/lib/eventbrite/api_objects/event.rb b/lib/eventbrite/api_objects/event.rb index af41136..1cb3b40 100644 --- a/lib/eventbrite/api_objects/event.rb +++ b/lib/eventbrite/api_objects/event.rb @@ -5,6 +5,13 @@ require 'eventbrite/api_objects/discount' require 'eventbrite/api_objects/attendee' module Eventbrite + + # The Event class is the main point of interaction for most Eventbrite api + # calls. Most objects have to be directly related to an Event. + # + # Events must have a Venue and an Organizer. + # + # Events have collections of Attendees, Tickets, and Discounts class Event < Eventbrite::ApiObject updatable :title, :description, :tags, :timezone @@ -31,6 +38,7 @@ class Event < Eventbrite::ApiObject collection :attendees => Eventbrite::AttendeeCollection collection :discounts => Eventbrite::DiscountCollection + # Returns privacy status of event def privacy case attribute_get(:privacy) when "Private" @@ -40,11 +48,13 @@ def privacy end attribute_get(:privacy) end - + + # Returns currency, setting to default of USD. def currency attribute_get(:currency) || attribute_set(:currency, "USD") end + # Returns timezone, reformatting to GMT offset if necessary. def timezone return attribute_get(:timezone) if attribute_get(:timezone) =~ /GMT[+-]\d{1,2}/ time = TZInfo::Timezone.get(attribute_get(:timezone)).current_period @@ -54,26 +64,37 @@ def timezone attribute_get(:timezone) end + # Returns true if event is private def private? privacy == 0 ? true : false end + # Returns true if event is not private def public? !private? end + # @private + # Handle differences in api - occasionally response is double + # wrapped in the XML. def unnest_child_response(response) response.has_key?('event') ? response['event'] : response end + # @private + # Mark the user's event collection as dirty def after_new @owner.dirty_events! end + # @private + # When requesting collections, request as many as possible. def nested_hash {:id => id, :count => 99999, :user => owner} # It's over 9000! end end + + # A collection of events. class EventCollection < ApiObjectCollection; collection_for Event; end end diff --git a/lib/eventbrite/api_objects/organizer.rb b/lib/eventbrite/api_objects/organizer.rb index 31231c7..3773307 100644 --- a/lib/eventbrite/api_objects/organizer.rb +++ b/lib/eventbrite/api_objects/organizer.rb @@ -1,10 +1,15 @@ module Eventbrite class Event < Eventbrite::ApiObject; end + + # Represents a collection of {Eventbrite::Event events} the + # {Eventbrite::Organizer organizer} owns. class OrganizerEventCollection < ApiObjectCollection collection_for Event getter :organizer_list_events end + # An organizer is the person organizing an {Eventbrite::Event event} (which is not necessarily + # the same as the {Eventbrite::User user}). Organizers are required for events. class Organizer < Eventbrite::ApiObject updatable :name, :description @@ -12,15 +17,20 @@ class Organizer < Eventbrite::ApiObject requires :name collection :events => Eventbrite::OrganizerEventCollection + + # @private + # Upon creating an organizer, the user is dirty. def after_new @owner.dirty_organizers! end - + # @private + # Organizers aren't double nested def unnest_child_response(response) response end end + # Represents a list of organizers class OrganizerCollection < ApiObjectCollection; collection_for Organizer; end end diff --git a/lib/eventbrite/api_objects/ticket.rb b/lib/eventbrite/api_objects/ticket.rb index 4b819a9..ea8dbae 100644 --- a/lib/eventbrite/api_objects/ticket.rb +++ b/lib/eventbrite/api_objects/ticket.rb @@ -1,5 +1,6 @@ module Eventbrite + # Each event may have multiple available tickets. class Ticket < ApiObject updatable :is_donation @@ -12,7 +13,8 @@ class Ticket < ApiObject readable :quantity_sold, :currency attr_accessor :event - # Remapping some API inconsistencies + # @private + # Remapping some API inconsistencies remap :type => :is_donation, :visible => :hide, :quantity_available => :quantity remap :end_date => :end_sales, :start_date => :start_sales diff --git a/lib/eventbrite/api_objects/venue.rb b/lib/eventbrite/api_objects/venue.rb index 340c3bd..d4464c7 100644 --- a/lib/eventbrite/api_objects/venue.rb +++ b/lib/eventbrite/api_objects/venue.rb @@ -12,8 +12,10 @@ class Venue < ApiObject renames :name => :venue, :address => :adress, :address_2 => :adress_2 ignores :"Lat-Long" - def state; region; end # Region is same as state in US - def state=(val); region= val; end # Region is same as state in US + # Region is same as state in US + def state; region; end + # Region is same as state in US + def state=(val); region= val; end end class VenueCollection < ApiObjectCollection; collection_for Venue; end end diff --git a/lib/eventbrite/main.rb b/lib/eventbrite/main.rb index 0309538..0acf2a1 100644 --- a/lib/eventbrite/main.rb +++ b/lib/eventbrite/main.rb @@ -1,16 +1,21 @@ require 'httparty' require 'tzinfo' +# Handles HTTParty interaction with eventbrite API module Eventbrite EVENTBRITE_TIME_STRING = '%Y-%m-%d %H:%M:%S' + # Sets up app to use an app key for interaction with API def self.setup(app_key = "YmRmMmMxMjYzNDYy", debug = false) @app_key = app_key @debug = debug end + # Enable debugging (to standard out) def self.debug! @debug = true end + # @private + # Makes HTTParty call def self.call(function, opts = {}) @app_key ||= "YmRmMmMxMjYzNDYy" opts[:app_key] = @app_key @@ -25,15 +30,19 @@ def self.call(function, opts = {}) response end - + # @private + # Does debugging def self.debug(msg) puts msg if debug? end + # Returns true if debug on. def self.debug? @debug.nil? ? false : @debug end + # @private + # Formats an Eventbrite date def self.formatted_time(date) case date when Time @@ -43,6 +52,7 @@ def self.formatted_time(date) end end + # @private class API include HTTParty base_uri "https://www.eventbrite.com/json/"