cheapshark 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 845f882f1c716ed0233f3a66ffd8708001ad78ac
4
+ data.tar.gz: 8b552c4e4d38e11874ca63d3e9fa2fa70475fb21
5
+ SHA512:
6
+ metadata.gz: 8e24deb0199312b8cb60ff9809ec8248b3c852358c8a06177805b7c96d014e5eacb98731f359b267b0204412be856dd6bbe375e7110c1779e08fee97c69fef6d
7
+ data.tar.gz: e71f073b26d5964fdcf7c17479a68014ae86a8d67140c654ee166b55427fbb62f73a935646db3a6bc232f59c6b34791a3c59d8da1d18539132f4bfc11b0bc279
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/support/cassettes/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
16
+ coverage
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ script:
5
+ - bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ guard :rspec, cmd: 'bundle exec rspec' do
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Antonio Gurgel
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # CheapShark
2
+
3
+ [![Dependency Status](https://gemnasium.com/GA114/cheapshark.svg)](https://gemnasium.com/GA114/cheapshark) [![Code Climate](https://codeclimate.com/github/GA114/cheapshark/badges/gpa.svg)](https://codeclimate.com/github/GA114/cheapshark) [![Build Status](https://travis-ci.org/GA114/cheapshark.svg)](https://travis-ci.org/GA114/cheapshark)
4
+
5
+ Ruby wrapper for [CheapShark's API](http://www.cheapshark.com/api/).
6
+
7
+ ## Installation
8
+
9
+ Add this to your `Gemfile` and do a `bundle install`.
10
+
11
+ ```ruby
12
+ gem 'cheapshark'
13
+ ```
14
+
15
+ Or install it yourself:
16
+
17
+ $ gem install cheapshark
18
+
19
+ ## Usage
20
+
21
+ ``` ruby
22
+ require 'cheapshark'
23
+ CheapShark.games(title: 'Borderlands 2') # Returns an array of Game objects
24
+ CheapShark.games(title: 'Borderlands 2')[0] # Returns the likely most-relevant result
25
+ CheapShark.stores # Returns stores and their IDs
26
+ CheapShark.deals(storeID: 1, pageSize: 5) # Returns five best deals on Steam (CS sorts by deal rating by default)
27
+ CheapShark.deal(id: 'DCqsq6Hnmtzu2UVkBpD133kL1pG93Ovz4%2BEjTuJAx9c%3D') # Returns a specific deal.
28
+ ```
29
+
30
+ Keep in mind that option names **must be properly capitalized**. The API will respond to `storeID` but ignore `storeid`.
31
+
32
+ ``` ruby
33
+ CheapShark.deals(storeID: 1, pageSize: 5) # Right
34
+ CheapShark.deals(storeid: 1, pageSize: 5) # Wrong, will return five best deals from any store
35
+ CheapShark.deals(storeID: 1, pagesize: 5) # Wrong, will return the API default of sixty deals
36
+ CheapShark.deals(storeid: 1, pagesize: 5) # Very wrong, will return all deals
37
+
38
+ ```
39
+
40
+ ## To-dos
41
+
42
+ - Decide on garbage-input scenarios to handle (things like calling `CheapShark.games()` without params)
43
+ - Alert feature
44
+ - Complete [expectations.md](https://github.com/GA114/cheapshark/blob/master/expectations.md)
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it ( https://github.com/GA114/cheapshark/fork )
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cheapshark/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cheapshark"
8
+ spec.version = CheapShark::VERSION
9
+ spec.author = "Antonio Gurgel"
10
+ spec.email = "ag@antoniogurgel.com"
11
+ spec.summary = %q{Ruby wrapper gem for CheapShark's API.}
12
+ spec.description = %q{CheapShark aggregates sales from PC game stores.}
13
+ spec.homepage = "http://github.com/GA114/cheapshark"
14
+ spec.license = "MIT"
15
+ spec.platform = Gem::Platform::RUBY
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "webmock", "~> 1.20.4"
24
+ spec.add_development_dependency "sinatra", "~> 1.4.5"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "guard", "~> 2.12.4"
28
+ spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "guard-rspec", "~> 4.5.0"
30
+ spec.add_development_dependency "io-console", "~> 0.4.3"
31
+ spec.add_development_dependency "vcr", "~> 2.9.3"
32
+ spec.add_development_dependency "simplecov", "~> 0.10.0"
33
+ spec.add_development_dependency "yard", "~> 0.8.7.6"
34
+ spec.add_runtime_dependency "httparty", "~> 0.13"
35
+ spec.add_runtime_dependency "json"
36
+ end
@@ -0,0 +1,49 @@
1
+ # Questions
2
+
3
+ [x] Where can I find $GAME for the cheapest price?
4
+ [x] What sales does $STORE have at the moment?
5
+ [ ] Which store has the best overall deals right now?
6
+ [ ] Which store has the most unique deals?
7
+
8
+ # Answers
9
+
10
+ ## Find $GAME at lowest price
11
+
12
+ Search for games with single form input, which is just the name of the game.
13
+ Return a list of games, prices, and store link.
14
+
15
+ ``` ruby
16
+ CheapShark.games(title: 'Borderlands 2') # returns an array of Game objects
17
+ ```
18
+
19
+ Extra features (possibilities):
20
+ Search as you type (with Rails!)
21
+
22
+ ## List $STORE's sales
23
+
24
+ Have user select a store from a list populated with API's store fetcher.
25
+ Return top $LIMIT or 10 deals of that store.
26
+
27
+ ```ruby
28
+ CheapShark.deals(storeID: 1, pageSize: 5) # returns five best deals on Steam (CS sorts by deal rating by default)
29
+ ```
30
+
31
+ Extra features (possibilities):
32
+
33
+ ## Find store with best deals
34
+
35
+ Search all deals.
36
+ Return top $LIMIT or 10 deals.
37
+
38
+ ```ruby
39
+ CheapShark.deals(limit: 10)
40
+ ```
41
+
42
+ Extra features (possibilities):
43
+
44
+ ## Find best unique deals
45
+
46
+ (Meaning, no other store has $GAME on sale?)
47
+ ??
48
+
49
+ Extra features (possibilities):
@@ -0,0 +1,95 @@
1
+ require 'uri'
2
+ require_relative 'cheapshark/version'
3
+ require_relative 'cheapshark/fetchers/games_fetcher.rb'
4
+ require_relative 'cheapshark/fetchers/game_fetcher.rb'
5
+ require_relative 'cheapshark/fetchers/deal_fetcher.rb'
6
+ require_relative 'cheapshark/fetchers/deals_fetcher.rb'
7
+ require_relative 'cheapshark/fetchers/stores_fetcher.rb'
8
+
9
+ # Base object to handle interaction with API.
10
+ #
11
+ module CheapShark
12
+ extend self
13
+
14
+ # Gets info about a specific deal, by ID.
15
+ #
16
+ # @param options [{Symbol => String}]
17
+ # @option options [String] :id the ID of the deal
18
+ # @example Returns "Borderlands 2" on the Humble Store.
19
+ # CheapShark.deal(id: 'DCqsq6Hnmtzu2UVkBpD133kL1pG93Ovz4%2BEjTuJAx9c%3D')
20
+ # @return [CheapShark::Deal]
21
+ def deal(options={})
22
+ options[:id] = URI.unescape(options[:id])
23
+ CheapShark::DealFetcher.new(options).results
24
+ end
25
+
26
+ # Searches for deals matching each criterion supplied, and returns them in a paginated list.
27
+ #
28
+ # @param options [{Symbol => String}]
29
+ # @option options [String] :storeID Comma-separated list of stores; omit for any store.
30
+ # @option options [Integer] :pageSize (60) Number of deals to return
31
+ # @option options [Integer] :pageNumber (0) Page to start on
32
+ # @option options [String] :sortBy ("Deal Rating") Can be "Deal Rating", "Title", "Savings", "Price", "Metacritic", "Release", or "Store".
33
+ # @option options [Integer] :desc (0) Sort descending?
34
+ # @option options [Integer] :lowerPrice (0) Minimum deal price.
35
+ # @option options [Integer] :upperPrice Maximum deal price. 50 is the same as no limit.
36
+ # @option options [Integer] :metacritic (0) Minimum Metacritic score.
37
+ # @option options [String] :title Match the supplied string anywhere in the game's title.
38
+ # @option options [Integer] :exact (0) Match exact title string.
39
+ # @option options [Integer] :AAA (0) Finds games with RETAIL PRICE >$29
40
+ # @option options [Integer] :steamworks (0) Find games that redeem on Steam (API has best-guess policy).
41
+ # @option options [Integer] :onSale (0) Find games currently on sale.
42
+ #
43
+ # @example Returns five best deals on Steam (API sorts by deal rating by default)
44
+ # CheapShark.deals(storeID: 1, pageSize: 5)
45
+ # @example Returns all deals with titles containing the word "civilization"
46
+ # CheapShark.deals(title: 'civilization')
47
+ # @example Returns all deals for "Grand Theft Auto V"
48
+ # CheapShark.deals(title: 'Grand Theft Auto V', exact: 1)
49
+ # @return [Array<CheapShark::Deal>]
50
+ def deals(options={})
51
+ CheapShark::DealsFetcher.new(options).results
52
+ end
53
+
54
+ # Searches for games matching either the title or Steam ID supplied.
55
+ #
56
+ # @param options [{Symbol => String}]
57
+ # @option options [String] :title Title of the game.
58
+ # @option options [Integer] :steamAppID Steam ID of the game.
59
+ # @option options [Integer] :limit Limit the amount of games to return.
60
+ # @example Search for the "Max Payne" series.
61
+ # CheapShark.games(title: 'Max Payne')
62
+ # @example Returns "Portal 2" (and use it as a Game object rather than an Array).
63
+ # CheapShark.games(steamAppID: 620)[0]
64
+ # @return [Array<CheapShark::Game>]
65
+ def games(options={})
66
+ CheapShark::GamesFetcher.new(options).results
67
+ end
68
+
69
+
70
+ # Returns a game identified by CheapShark ID and all current deals associated with it.
71
+ # @note Game IDs are different from deal IDs; the game IDs take on the form of an integer, whereas deal IDs are encoded strings.
72
+ #
73
+ # @param options [{Symbol => String}]
74
+ # @option options [String] :id ID of the game.
75
+ # @example Returns "Batman: Arkham City" and all deals it's in.
76
+ # CheapShark.game(id: 14)
77
+ # @returns [CheapShark::Game]
78
+ def game(options={})
79
+ CheapShark::GameFetcher.new(options).results
80
+ end
81
+
82
+ # Returns all stores tracked by CheapShark, as well as their IDs.
83
+ #
84
+ # @example
85
+ # CheapShark.stores()
86
+ # @returns [Array<CheapShark::Store>]
87
+ def stores(options={})
88
+ CheapShark::StoresFetcher.new(options).results
89
+ end
90
+
91
+ # TODO
92
+ # def alerts(options={})
93
+ # end
94
+
95
+ end
@@ -0,0 +1,4 @@
1
+ module CheapShark
2
+ API_VERSION = '1.0'
3
+ BASE_URI = "http://www.cheapshark.com/api/#{API_VERSION}"
4
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'fetcher.rb'
2
+ require_relative '../models/deal.rb'
3
+
4
+ module CheapShark
5
+ class DealFetcher < CheapShark::Fetcher
6
+
7
+ FETCHER_ENDPOINT = '/deals'
8
+
9
+ def results
10
+ CheapShark::Deal.new :by_id, @results
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'fetcher.rb'
2
+ require_relative '../models/deal.rb'
3
+
4
+ module CheapShark
5
+ class DealsFetcher < CheapShark::Fetcher
6
+
7
+ FETCHER_ENDPOINT = '/deals'
8
+
9
+ def results
10
+ @results.map { |result| CheapShark::Deal.new :search, result }
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ require 'json'
2
+ require 'uri'
3
+ require 'httparty'
4
+
5
+ require_relative '../config'
6
+
7
+ module CheapShark
8
+
9
+ # Base fetcher class.
10
+ class Fetcher
11
+
12
+ include HTTParty
13
+
14
+ base_uri CheapShark::BASE_URI
15
+
16
+ def initialize(options)
17
+ @results = JSON.parse self.class.get( self.class::FETCHER_ENDPOINT, query: options ).body
18
+ end
19
+
20
+ def results
21
+ @results
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'fetcher.rb'
2
+ require_relative '../models/game.rb'
3
+
4
+ module CheapShark
5
+ class GameFetcher < CheapShark::Fetcher
6
+
7
+ FETCHER_ENDPOINT = '/games'
8
+
9
+ def results
10
+ CheapShark::Game.new :by_id, @results
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'fetcher.rb'
2
+ require_relative '../models/game.rb'
3
+
4
+ module CheapShark
5
+ class GamesFetcher < CheapShark::Fetcher
6
+
7
+ FETCHER_ENDPOINT = '/games'
8
+
9
+ def results
10
+ @results.map { |result| CheapShark::Game.new :search, result }
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'fetcher.rb'
2
+ require_relative '../models/store.rb'
3
+
4
+ module CheapShark
5
+ class StoresFetcher < CheapShark::Fetcher
6
+
7
+ FETCHER_ENDPOINT = '/stores'
8
+
9
+ def results
10
+ @results.map { |result| CheapShark::Store.new result }
11
+ end
12
+
13
+ end
14
+ end
File without changes
@@ -0,0 +1,48 @@
1
+ require 'uri'
2
+
3
+ module CheapShark
4
+ class Deal
5
+ attr_reader :store_id, :game_id, :name, :steam_app_id, :sale_price, :retail_price, :metacritic_score, :metacritic_link, :release_date, :publisher, :thumb, :cheaper_stores, :cheapest_price, :cheapest_date, :price, :internal_name, :deal_rating
6
+
7
+ # TODO: DRY up this abomination
8
+ def initialize(query_type, results)
9
+ case query_type
10
+ when :search
11
+ @internal_name = results['internalName']
12
+ @name = results['title']
13
+ @deal_id = results['dealID'].to_i
14
+ @store_id = results['storeID'].to_i
15
+ @game_id = results['gameID'].to_i
16
+ @sale_price = results['salePrice'].to_f
17
+ @retail_price = results['normalPrice'].to_f
18
+ @savings = results['savings'].to_f
19
+ @metacritic_score = results['metacriticScore'].to_i
20
+ @metacritic_link = results['metacriticLink']
21
+ @release_date = Time.at(results['releaseDate'].to_i)
22
+ @last_change = Time.at(results['lastChange'].to_i)
23
+ @deal_rating = results['dealRating'].to_f
24
+ @thumb = results['thumb']
25
+ when :by_id
26
+ @store_id = results['gameInfo']['storeID'].to_i
27
+ @game_id = results['gameInfo']['gameID'].to_i
28
+ @name = results['gameInfo']['name']
29
+ @steam_app_id = results['gameInfo']['steamAppID'].to_i
30
+ @sale_price = results['gameInfo']['salePrice'].to_f
31
+ @retail_price = results['gameInfo']['retailPrice'].to_f
32
+ @metacritic_score = results['gameInfo']['metacriticScore'].to_i
33
+ @metacritic_link = results['gameInfo']['metacriticLink']
34
+ @release_date = Time.at(results['gameInfo']['releaseDate'].to_i)
35
+ @publisher = results['gameInfo']['publisher']
36
+ @thumb = results['gameInfo']['thumb']
37
+ @cheaper_stores = results['cheaperStores'].map { |deal| Deal.new :game, deal }
38
+ @cheapest_price = results['cheapestPrice']['price'].to_f
39
+ @cheapest_date = Time.at(results['cheapestPrice']['date'].to_i)
40
+ when :game # derived from game object
41
+ @store_id = results['storeID']
42
+ @deal_id = results['dealID']
43
+ @price = results['price']
44
+ @retail_price = results['retailPrice']
45
+ end
46
+ end
47
+ end
48
+ end