Skip to content

Instantly share code, notes, and snippets.

@ismasan
Created December 11, 2009 17:54
Show Gist options
  • Save ismasan/254379 to your computer and use it in GitHub Desktop.
Save ismasan/254379 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'sinatra/base'
# SINATRA APP :::::::::::::::::::::::::::::::::::::
#
class BooticProxy < Sinatra::Base
# POST /mi-tienda/to/tugar/product # => push new product/property to Tugar
# This would be a JSON representation of a Bootic product, something like:
# {
# model: 'iPhone',
# price: 100.0.
# description: 'foo'
# }
#
post '/:account/to/:service/:hook' do
authorize! # http basic, possibly
job = Job.new(JSON.parse(request.body), params)
halt 200, 'Ok!'
end
end
# CLASSES ::::::::::::::::::::::::::::::::::::::::::
class Job
attr_reader :data, :account, :service, :hook
# Create a Job object and send it to the queue
#
def initialize(data, args={})
raise ArgumentError, ':acount missing' unless args[:account]
raise ArgumentError, ':service missing' unless args[:service]
raise ArgumentError, ':hook missing' unless args[:hook]
@data, @account, @service, @hook = data, args[:account], args[:service], args[:hook]
# Send to the queue
Delayed::Job.enqueue self
end
# Fetch the service to use and POST to it. (ie. Tugar)
# This is called by DelayedJob at a later time
#
def perform
service = Service.factory(self.service, self.account)
service.post!(self.hook, self.data)
end
end
class Service
class FailedPostError < StandardError;end
attr_reader :acount_key
def initialize(account_key)
@account_key = account_key
end
# Get the subclass for the right service, instantiate with the acount key for auth, logging, etc.
# Use ActiveSupport here for brevity
#
def self.factory(service_name, account_key)
service_name.classify.constantize.new(account_key)
end
# POST to remote service. Raise on failure to make JobQueue retry
# Delegates actual posting to service classes
#
# post!(:product, data) delegates to post_product(data)
#
def post!(hook, data)
resp = send("post_#{hook}", data)
raise FailedPostError unless resp
true
end
# Concrete services: Tugar
#
class Tugar < Service
require 'httparty'
require 'builder'
URL = 'http://backend.tugar.cl'
# POST to Tugar. Should return Boolean
# Generates XML for Tugar API
#
def post_product(data)
out = ''
xml = Builder::XmlMarkup.new(:target => out)
xml.property do |xml|
xml.property_type data['product_type']['name']
xml.address data['meta_fields']['address']
xml.region data['meta_fields']['region']
xml.locality data['meta_fields']['locality']
xml.price data['price']
xml.square_feet data['meta_fields']['square-feet']
xml.link data['url']
end
end
response = HTTParty.post(URL+'/properties.xml',
:body => out,
:basic_auth => {:username => self.acount_key, :password => 'x'},
:headers => {'Content-Type' => 'application/xml'}
)
# returns boolean for response success
#
(200..299).include?(response.code.to_i)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment