Module: YorkBinCollection
- Defined in:
- lib/york-bin-collection.rb
Defined Under Namespace
Classes: CollectionDates
Constant Summary collapse
- VERSION =
'1.0.0'
- CALENDARS_ENDPOINT =
'https://doitonline.york.gov.uk/BinsApi/Calendars/Index'
- EXOR_ENDPOINT =
'https://doitonline.york.gov.uk/BinsApi/EXOR'
Class Method Summary collapse
-
.collection_types ⇒ Object
A hash of collection types, as keys in a CollectionDates object, to their ‘friendly’ names.
-
.get_collection_dates(uprn) ⇒ CollectionDates
Given a valid UPRN in the City of York, returns an CollectionDates struct of dates each bin will be collected.
-
.get_uprns_for_postcode(postcode) ⇒ Object
Given a postcode, returns a hash of UPRNs in that postcode to their house addresses.
-
.valid_uprn?(uprn) ⇒ Boolean
Checks if a UPRN is syntatically valid; that is, if is a string is alphanumeric.
Class Method Details
.collection_types ⇒ Object
A hash of collection types, as keys in a CollectionDates object, to their ‘friendly’ names.
29 30 31 32 33 34 35 |
# File 'lib/york-bin-collection.rb', line 29 def self.collection_types { recycling: 'Recycling', household: 'Household waste', garden: 'Garden waste' } end |
.get_collection_dates(uprn) ⇒ CollectionDates
Given a valid UPRN in the City of York, returns an CollectionDates struct of dates each bin will be collected. The keys are :recycling, :household and :garden.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/york-bin-collection.rb', line 43 def self.get_collection_dates(uprn) raise ArgumentError, 'invalid uprn' unless valid_uprn?(uprn) url = CALENDARS_ENDPOINT + "?uprn=#{uprn}" document = Nokogiri::HTML(open(url)) # The format of the document is: # body # div.container-fluid # ~header~ # div # div.col-xs-12 col-sm-3 # h2: December 2018 # div.row # div: Tue 04 # div: Household waste # ... # h2: January 2019 # ... # div.col-xs-12 col-sm-3 # h2: March 2019 # ... # ... # Let's start by getting the div which contains the columns, and flatten out # the structure to get rid of them collection_date_elements = [] document.css('body > div.container-fluid > div > div.col-xs-12.col-sm-3').each do |col| collection_date_elements.push(*col.children) end collection_dates = CollectionDates.new([], [], []) current_heading = nil collection_date_elements.each do |row_or_heading| if row_or_heading.name == "h2" current_heading = row_or_heading.text else raise 'format error: didn\'t encounter heading before date' unless current_heading day, kind = row_or_heading.children.map(&:text) date = Date.parse("#{day} #{current_heading}") key = collection_types.rassoc(kind)&.first raise "unknown collection kind #{kind}" unless kind collection_dates.send(key) << date end end collection_dates end |
.get_uprns_for_postcode(postcode) ⇒ Object
Given a postcode, returns a hash of UPRNs in that postcode to their house addresses.
101 102 103 104 105 106 |
# File 'lib/york-bin-collection.rb', line 101 def self.get_uprns_for_postcode(postcode) url = "#{EXOR_ENDPOINT}/getPropertiesForPostCode?postcode=#{CGI.escape(postcode)}" JSON.parse(open(url).read).map do |property| [property['Uprn'].to_s, property['ShortAddress']] end.to_h end |
.valid_uprn?(uprn) ⇒ Boolean
Checks if a UPRN is syntatically valid; that is, if is a string is alphanumeric. According to the Ordinance Survey, UPRNs can be alphanumeric, although I have yet to find an example with alphabetic characters in.
22 23 24 |
# File 'lib/york-bin-collection.rb', line 22 def self.valid_uprn?(uprn) /[A-Za-z0-9]+/ === uprn || up end |