Skip to content

Instantly share code, notes, and snippets.

@purp
Created July 16, 2015 09:41
Show Gist options
  • Save purp/dc65e9040ebaea037e0f to your computer and use it in GitHub Desktop.
Save purp/dc65e9040ebaea037e0f to your computer and use it in GitHub Desktop.
Get the list of OpenStack-approved vendors from the OpenStack Marketplace
#!/usr/bin/env ruby
require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'uri'
class String
def titleize
humanize.split(' ').map(&:capitalize).join(' ')
end
def humanize
tr('-', ' ')
end
end
class OpenStackMarketplacePage
attr_accessor :category, :url, :html
BASE_URL = 'http://www.openstack.org'
def initialize(category, url)
@category = category
@url = url
end
def html
@html ||= Nokogiri.HTML(open(URI.join(BASE_URL, url))) if url
end
def urls(filter=nil)
urls = html.css('a').map {|i| i.attr('href')}
filter ? urls.select {|url| url =~ filter} : urls
end
def vendors
result = unless category == 'drivers' # there's always one ...
vendor_elem = category == 'distros' ? 4 : 3
urls(/^#{url}/).map {|url| url.split('/')[vendor_elem]}.compact
else
rows = html.css('table#releaseTable tr')
rows[1..-1].map {|row| row.css('td')[1]}.map(&:text)
end
result.compact.sort.uniq
end
def to_s
"%s\n%s\n%s" % [category.titleize, category_underbar, vendors.map(&:titleize).join("\n")]
end
private
def category_underbar
'-' * category.length
end
end
def item_id_and_url(item)
[item['id'], item.css('a').attribute('href').value]
end
MARKETPLACE_URL = "http://www.openstack.org/marketplace"
# Get category names and URLs from marketplace nav
marketplace = Nokogiri.HTML(open(MARKETPLACE_URL))
nav_items = marketplace.css('ul.marketplace-nav > li')
categories = nav_items.map {|item| item_id_and_url(item)}.to_h
# Walk each category page for links into category, pull vendor out of that
categories.each do |category, url|
puts ''
page = OpenStackMarketplacePage.new(category, url)
puts page.to_s
end
@purp
Copy link
Author

purp commented Jul 16, 2015

Yes, it's probably a sacrilege to write something related to OpenStack in Ruby. I'm okay with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment