From 3a3baf733c2e477b30d9c57ac589240045460445 Mon Sep 17 00:00:00 2001 From: Dave Date: Thu, 25 Oct 2012 19:21:03 -0600 Subject: [PATCH] Fletcher CLI --- Gemfile | 1 + Gemfile.lock | 4 ++ README.md | 36 ++++++++++++++++++ bin/fletcher | 69 ++++++++++++++++++++++++++++++++++ config/locales/fletcher.en.yml | 27 +++++++++++++ spec/bin/fletcher_spec.rb | 42 +++++++++++++++++++++ 6 files changed, 179 insertions(+) create mode 100644 bin/fletcher create mode 100644 config/locales/fletcher.en.yml create mode 100644 spec/bin/fletcher_spec.rb diff --git a/Gemfile b/Gemfile index 2ba8b97..eab7ffb 100755 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ source "http://rubygems.org" gem "hashie" gem "nokogiri" gem "money" +gem "commander" group :development do gem "shoulda", ">= 0" diff --git a/Gemfile.lock b/Gemfile.lock index 18966ee..8bd8cf4 100755 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,12 +4,15 @@ GEM activesupport (3.2.2) i18n (~> 0.6) multi_json (~> 1.0) + commander (4.1.2) + highline (~> 1.6.11) diff-lcs (1.1.3) factory_girl (2.6.4) activesupport (>= 2.3.9) fakeweb (1.3.0) git (1.2.5) hashie (1.2.0) + highline (1.6.15) i18n (0.6.0) jeweler (1.6.4) bundler (~> 1.0) @@ -39,6 +42,7 @@ PLATFORMS DEPENDENCIES bundler + commander factory_girl fakeweb hashie diff --git a/README.md b/README.md index 8de2e3c..a45dc2e 100755 --- a/README.md +++ b/README.md @@ -55,6 +55,42 @@ product.doc.class.name # => Nokogiri::HTML::Document Fletcher.models # => [:amazon, :ebay, :etsy, :thinkgeek, ...] ``` +### CLI + +Get Product Details (defaults to yaml output): + +```sh +$ fletcher fetch "http://www.amazon.com/Avenir-Deluxe-Unicycle-20-Inch-Wheel/dp/B00165Q9F8" + +--- +name: Avenir Deluxe Unicycle (20-Inch Wheel) +description: 'Amazon.com: Avenir Deluxe Unicycle (20-Inch Wheel): Sports & Outdoors' +price: $99.99 +image: + src: http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA280_.jpg +url: http://www.amazon.com/Avenir-Deluxe-Unicycle-20-Inch-Wheel/dp/B00165Q9F8 +``` + +Get a single attribute of a product: + +```sh +$ fletcher fetch --only name "http://www.amazon.com/Avenir-Deluxe-Unicycle-20-Inch-Wheel/dp/B00165Q9F8" +Avenir Deluxe Unicycle (20-Inch Wheel) +``` + +Get list of supported websites: + +```sh +$ fletcher websites +Amazon +ThinkGeek +... +``` + + + + + ## Attributes The following attributes/method are available for a product: diff --git a/bin/fletcher b/bin/fletcher new file mode 100644 index 0000000..b1c19c3 --- /dev/null +++ b/bin/fletcher @@ -0,0 +1,69 @@ +#!/usr/bin/env ruby + +require 'rubygems' +require 'commander/import' +require 'yaml' +require File.expand_path("../../lib/fletcher", __FILE__) +#require 'commander-foo' + +program :version, Fletcher.version #Commander-foo::VERSION +program :description, 'A cross-website product information fetcher' +program :help, 'Author', 'Dave Hulihan ' +#default_command :fetch + +command :fetch do |c| + c.syntax = 'fletcher fetch [URL]' + c.summary = 'Fetch product information' + c.description = '' + c.example 'Fetch an amazon product', 'fletcher "http://www.example.com/product-id"' + #c.option '--format [yaml|json]', String, 'The format of the product details' + #c.option '--timeout SECONDS', Integer, 'Timeout in seconds' + c.option '--only [name|description|price|image]', String, 'Fetch a single attribute from the product.' + c.action do |args, options| + # Do something or c.when_called Commander-foo::Commands::Hello + options.default :format => :yaml + + url = args.first + if url + product = Fletcher.fetch url + + # Prep output + output_hash = Hash.new + output_hash["name"] = product.name + output_hash["description"] = product.description if product.description + output_hash["price"] = product.price.format if product.price + if product.image + output_hash["image"] = { + "src" => product.image.src + } + end + output_hash["url"] = product.url + + # Get single attribute + if options.only + case options.only + when "image" + value = output_hash["image"]["src"] + else + value = output_hash[options.only] + end + value ? say(value.to_s) : say("Unknown attribute: #{options.only}") + else + say output_hash.to_yaml + end + else + puts c.syntax + end + end +end + +command :websites do |c| + c.syntax = 'fletcher websites' + c.summary = 'Get a list of supported websites' + c.action do |args, options| + say "Supported Websites:" + for model in Fletcher.models.sort + say "\t#{model.to_s.capitalize}" + end + end +end diff --git a/config/locales/fletcher.en.yml b/config/locales/fletcher.en.yml new file mode 100644 index 0000000..edaf7ab --- /dev/null +++ b/config/locales/fletcher.en.yml @@ -0,0 +1,27 @@ +en: + fletcher: + models: + amazon: + name: Amazon + url: http://www.amazon.com + ebay: + name: eBay + url: http://www.ebay.com + etsy: + name: Etsy + url: http://www.etsy.com + gamecouk: + name: Game.co.uk + url: http://www.game.co.uk + googleshopping: + name: Google Shopping + url: http://www.google.com/shopping + playcom: + name: Play.com + url: http://www.play.com + steam: + name: Steam + url: http://store.steampowered.com + thinkgeek: + name: ThinkGeek + url: http://www.thinkgeek.com diff --git a/spec/bin/fletcher_spec.rb b/spec/bin/fletcher_spec.rb new file mode 100644 index 0000000..87263c7 --- /dev/null +++ b/spec/bin/fletcher_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" +#bin_path = File.expand_path("../../../bin/fletcher", __FILE__) +load File.expand_path("../../../bin/fletcher", __FILE__) + +def mock_terminal + @input = StringIO.new + @output = StringIO.new + $terminal = HighLine.new @input, @output +end + +describe "Fletcher CLI" do + before :each do + mock_terminal + end + + describe "fetch command", :vcr do + before :each do + @command = command :fetch + end + + it "should return prompt without url" do + @command.run Factory(:amazon).url + # @output.to_s.should == @command.syntax + end + + it "works with valid product url" do + lambda{ + @command.run Factory(:amazon).url + }.should_not raise_error + end + end + + describe "websites command" do + before :each do + @command = command :websites + end + + it "should work without any errors" do + lambda{@command.run}.should_not raise_error + end + end +end \ No newline at end of file