Class: Beway::Auction

Inherits:
Object
  • Object
show all
Defined in:
lib/beway/auction.rb

Overview

Auction

Represents an ebay auction. Can only be instantiated for true auctions (no buy-it-now-only sales) and completed auctions.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ Auction

Returns a new instance of Auction.

Raises:



16
17
18
19
20
# File 'lib/beway/auction.rb', line 16

def initialize url
  @url = url
  refresh_doc
  raise InvalidUrlError unless valid_auction?
end

Instance Attribute Details

#docObject (readonly)

Returns the value of attribute doc.



14
15
16
# File 'lib/beway/auction.rb', line 14

def doc
  @doc
end

#last_updatedObject (readonly)

Returns the value of attribute last_updated.



14
15
16
# File 'lib/beway/auction.rb', line 14

def last_updated
  @last_updated
end

#urlObject (readonly)

Returns the value of attribute url.



14
15
16
# File 'lib/beway/auction.rb', line 14

def url
  @url
end

Instance Method Details

#auction_numberObject

parsing method, returns a string

Raises:



126
127
128
129
130
# File 'lib/beway/auction.rb', line 126

def auction_number
  canonical_url_node = @doc.at_css('link[@rel = "canonical"]')
  raise AuctionParseError, "Couldn't find canonical URL" unless canonical_url_node
  canonical_url_node.attr('href')[/\d+$/]
end

#complete?Boolean

has bidding ended yet?

Returns:

  • (Boolean)


29
30
31
32
# File 'lib/beway/auction.rb', line 29

def complete?
  complete_span = @doc.at_xpath('//span[contains(text(), "Bidding has ended on this item")]')
  return (complete_span.nil?) ? false : true
end

#current_bidObject

parsing method, returns a string

Raises:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/beway/auction.rb', line 41

def current_bid
  # list of ways to get the bid.
  xpaths = [
    "//th[contains(text(),'Current bid:')]",
    "//th[contains(text(),'Starting bid:')]",
    "//th[contains(text(),'Price:')]",
    "//td[contains(text(),'Starting bid:')]",
    "//td[contains(text(),'Winning bid:')]",
  ]

  bid_node = xpaths.reduce(nil) do |node, xpath|
    if node.nil?
      node = @doc.at_xpath(xpath)
      node = node.next_sibling unless node.nil?
    end
    node
  end

  raise AuctionParseError, "Couldn't find current/starting bid header in document" if bid_node.nil?
  bid_text = node_text(bid_node)
  bid_text = bid_text[/^[^\[]+/].strip if complete?
  return bid_text
end

#descriptionObject

parsing method, returns a string

Raises:



66
67
68
69
70
# File 'lib/beway/auction.rb', line 66

def description
  desc = @doc.at_css('h1.vi-is1-titleH1')
  raise AuctionParseError, "Couldn't find description in document" if desc.nil?
  desc.inner_text.strip
end

#end_timeObject

parsing method, returns a Time object

Raises:



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/beway/auction.rb', line 113

def end_time
  text = node_text(time_node)
  md = text.match(/\(([^)]*)\)/)
  if md
    time_str = md[1]
  else
    time_str = text
  end
  raise AuctionParseError unless time_str
  Time.parse(time_str)
end

#has_bid_button?Boolean

parsming method, returns boolean

Returns:

  • (Boolean)


133
134
135
136
# File 'lib/beway/auction.rb', line 133

def has_bid_button?
  place_bid_button = @doc.at_xpath('//form//input[@value="Place bid"]')
  return (place_bid_button.nil?) ? false : true
end

#min_bidObject

parsing method, returns a float

Raises:



102
103
104
105
106
107
108
109
110
# File 'lib/beway/auction.rb', line 102

def min_bid
  return nil if complete?

  min_bid_node = @doc.at_css('form.vi-is1-s4-eu span.vi-c-fsmt')
  raise AuctionParseError, "Couldn't find minimum bid in document" unless min_bid_node
  match_data = min_bid_node.inner_text.match(/Enter ([^)]*) or more/)
  raise AuctionParseError, "Min Bid data not in expected format. Got: #{min_bid_node.inner_text}" if match_data.nil?
  match_data[1]
end

#refresh_docObject

fetch the url again



35
36
37
38
# File 'lib/beway/auction.rb', line 35

def refresh_doc
  @doc = Nokogiri::HTML(open(@url))
  @last_updated = Time.now
end

#time_leftObject

parsing method, returns a string



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/beway/auction.rb', line 73

def time_left
  return nil if complete?

  time_str = node_text(time_node)
  time_str = time_str[/^[^(]*/].strip
  time_ar = time_str.split

  # time_ar comes to us looking like
  #   ["2d", "05h"] or ["0", "h", "12", "m", "5", "s"]
  # decide which, and roll with it...
  
  if time_ar[0][/^\d+d$/] and time_ar[1][/^\d+h$/]
    # ["2d", "05h"] style
    return time_ar.join(' ')
  elsif time_ar[1] =~ /^days?$/ and time_ar[3] =~ /^hours?$/
    # ["1", "day", "18", "hours"]
    return time_ar.join(' ')
  else
    # assume ["0", "h", "12", "m", "5", "s"] style
    raise AuctionParseError, "Didn't find hour marker where expected" unless time_ar[1] == 'h'
    raise AuctionParseError, "Didn't find minute marker where expected" unless time_ar[3] == 'm'
    raise AuctionParseError, "Didn't find second marker where expected" unless time_ar[5] == 's'
    return [ time_ar[0] + time_ar[1],
             time_ar[2] + time_ar[3],
             time_ar[4] + time_ar[5] ].join(' ')
  end
end

#valid_auction?Boolean

can we represent this auction?

Returns:

  • (Boolean)


23
24
25
26
# File 'lib/beway/auction.rb', line 23

def valid_auction?
  return true if complete? or has_bid_button?
  return false
end