Created
January 18, 2009 11:56
-
-
Save nikosd/48624 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ItemFetcherWorker < BackgrounDRb::MetaWorker | |
set_worker_name :item_fetcher_worker | |
def create(args = nil) | |
end | |
def set_search(search) | |
@search = search | |
end | |
def fetch_query_and_items | |
times_tried = 0 | |
begin | |
times_tried = times_tried + 1 | |
@search.do! | |
rescue | |
times_tried < 4 ? retry : raise | |
end | |
fetch_items | |
end | |
def fetch_items | |
times_tried = 0 | |
begin | |
times_tried = times_tried + 1 | |
@search.items | |
rescue | |
times_tried < 4 ? retry : raise | |
end | |
end | |
def fetch_next_page_of_items(params = {}) | |
# query_options = params[:query_options] | |
total_pages = params[:total_pages].to_i || 1 | |
current_page = params[:current_page].to_i || 1 | |
depth = params[:depth] || 2 | |
if current_page < total_pages | |
new_params = @search.request.call_params.merge({:page_number => (current_page.to_i + 1).to_s}) | |
logger.info("---------------------------------\nSearch begun for:\n #{@search.request.call_params}\nwith new parameters:\n #{new_params}") | |
@search = Search.new(new_params) | |
@search.do! | |
@search.items | |
logger.info("Search finished!\n---------------------------------\n") | |
fetch_next_page_of_items(:total_pages => total_pages, :current_page => current_page, :depth => depth-1) if depth > 0 | |
end | |
rescue | |
logger.error("Search finished but something broke:\n #{$!}\n---------------------------------\n") | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Search | |
# Example: Search.new(:query_keywords => 'canon (450d, xti)', :"price_min.Value" => 400, :"price_max.Value" => 1100, :max_entries => 5) | |
# | |
# Also perfmorms the EbayShopping::Request. | |
# | |
# Raises hell of exceptions some of which are: | |
# SocketError (getaddrinfo: nodename nor servname provided, or not known) | |
# EbayShopping::TimeoutError | |
attr_reader :request | |
def initialize(params) | |
params_default = { | |
:max_entries => '5', | |
:include_selector =>'Details,SellerInfo', | |
:item_type => 'AllItemTypes', # includes "Store Inventory format" in addiction to auction items | |
:items_available_to => 'GR', | |
:item_sort => 'EndTime', # Maybe by best-match? | |
:payment_method => 'PayPal' | |
#:site_id => '3' # Ebay.co.uk | |
} | |
@request = EbayShopping::Request.new :find_items_advanced, params_default.merge(params) | |
@error = nil | |
end | |
def cached? | |
if @request.has_cached_response? | |
self.do! | |
true | |
end | |
end | |
def do! | |
@response = @request.response | |
end | |
# Returns an array of Items with the result set from the request/response. | |
def items(options = {}) | |
return nil if total_items == 0 | |
options = {:caclulate_shipping => true, :shipping_for_country_code => 'GR', :get_seller_details => false}.merge(options) | |
@items = @response.items.map{ |item| EbayItem.find_or_create_from_ebay_response(item, options) } | |
end | |
def total_items | |
@total_items ||= @response.total_items | |
end | |
def items_cached? | |
return true unless @response.items # Return true if items is empty | |
return EbayItem.count(:conditions => {:item_id => @response.items.map { |item| item.item_id } }) == @response.items.size | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SearchController < ApplicationController | |
layout 'default' | |
# GET / | |
# GET /search | |
# GET /search/index | |
def index; @pagetitle = 'simpleBay: Τί ψάχνεις σήμερα;'; end | |
# GET /search?q=''&max_price=''&... | |
# GET /search/search?q=''&max_price=''&... | |
# | |
# Required parameters: q | |
# Optional parameters: page, min_price, max_price, max_entries | |
def search | |
@repeat_request = false | |
if params[:q].nil? or (@q = params[:q]).empty? | |
render :text => 'Καλό θα ήταν να εισάγετε κάτι για αναζήτηση :)' and return | |
end | |
@pagetitle = "simpleBay: Αναζήτση για #{@q}" | |
parse_ebay_parameters | |
search = Search.new(@ebay_req_params) | |
fetcher = MiddleMan.worker(:item_fetcher_worker) | |
fetcher.set_search(:arg => search) | |
if search.cached? | |
@total_results = search.total_items | |
if search.items_cached? | |
@items = search.items | |
@current_page, @total_pages = (@ebay_req_params[:page_number] || 1).to_i, (@total_results / @ebay_req_params[:max_entries].to_f).ceil | |
if @total_results > (@current_page * @ebay_req_params[:max_entries].to_i) | |
fetcher.async_fetch_next_page_of_items(:arg => {:current_page => @current_page, :total_pages => @total_pages}) | |
end | |
else # if items are NOT cached. | |
@repeat_request = true | |
fetcher.async_fetch_items unless request.xhr? | |
end | |
else # if search is NOT cached. | |
@repeat_request = true | |
fetcher.async_fetch_query_and_items unless request.xhr? | |
end | |
# Setup params for periodically_call_remote in search view template if request is to be repeated. | |
@ajax_url_params = {:action => :search, | |
:q => @q, | |
:page => @ebay_req_params[:page_number], | |
:min_price => @min_price, | |
:max_price => @max_price, | |
:max_entries => @max_entries } if @repeat_request | |
rescue EbayShopping::TimeoutError | |
render :text => 'Ebay timeout error, please try again later' | |
end | |
protected | |
def parse_ebay_parameters | |
@ebay_req_params = { :query_keywords => @q } | |
@ebay_req_params[:page_number] = params[:page] || '1' | |
if @min_price = params[:min_price] and !@min_price.empty? | |
@ebay_req_params[:"price_min.Value"] = EbayShopping::Money.euros_to_dollars(@min_price) | |
end | |
if @max_price = params[:max_price] and !@max_price.empty? | |
@ebay_req_params[:"price_max.Value"] = EbayShopping::Money.euros_to_dollars(@max_price) | |
end | |
@ebay_req_params[:max_entries] = @max_entries = params[:max_entries] ? params[:max_entries] : 10 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment