livingsocial2 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.DS_Store ADDED
Binary file
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Livingsocial2
2
2
 
3
- TODO: Write a gem description
3
+ This is the official unoffical ruby gem for Livingsocial. The gem is a wrapper for livingsocial's atom feed. We scrape the atom feed every 3 hours, so the deals should be current. There are some inconsistency with info on some deals, but this stems from inconsistencies within the atom feed - not much we can do there! The gem is very lightweight with only two files - Mongo.rb and Deal.rb. Mongo creates a connection to the mongo db that stores the gathered deals and Deal returns deal instances based on your entered criteria.
4
+
4
5
 
5
6
  ## Installation
6
7
 
@@ -18,7 +19,35 @@ Or install it yourself as:
18
19
 
19
20
  ## Usage
20
21
 
21
- TODO: Write usage instructions here
22
+ There are currently 2 class level methods for interacting with the gem.
23
+ ### Method 1
24
+ Livingsocial2::Deal.find_by_ls_market(deal_type, market) #=> returns a collection of deals objects that match both the deal_type and the LS market of interest.
25
+
26
+ ### Example call
27
+ Livingsocial2::Deal.find_by_ls_market(:local, 'Buffalo')
28
+
29
+ ### Method 2
30
+ Livingsocial2::Deal.find_near(deal_type, lat, long, distance) #=> returns a collection of deal objects that match the deal type and that are within the specified distance of the lat and long passed in.
31
+
32
+ ### Example call
33
+ Livingsocial2::Deal.find_near(:all, 40.7518481, -73.97551399999999, 1)
34
+
35
+ Distance is the radius desired, measured in miles. For example, the above example is asking for all the deals within a 1 mile radius of the passed in location (Lexington, NY).
36
+
37
+ If no distance is specified - it will default to 3 miles.
38
+ ### What's the deal with deal_type
39
+ deal_type allows you to specify what LS vertical you are interested in. Currently, the atom feed supplies 4 types of deals.
40
+ #### 1. Local Deals
41
+ #### 2. At Home Deals
42
+ #### 3. Families Deals
43
+ #### 4. Gourmet Deals
44
+
45
+ ### To specify a deal_type pass in one of the following symbols
46
+ #### 1. :local #=> local deals
47
+ #### 2. :at_home #=> at home deals
48
+ #### 3. :family #=> family deals
49
+ #### 4. :gourmet #=> gourmet deals
50
+ #### 5. :all #=> combination of all the above
22
51
 
23
52
  ## Contributing
24
53
 
data/lib/.DS_Store ADDED
Binary file
@@ -0,0 +1,66 @@
1
+ module Livingsocial2
2
+ class Deal
3
+ DEAL_TYPES = { family: 'FamiliesDeal',
4
+ local: 'LocalDeal',
5
+ at_home: 'AtHomeDeal',
6
+ gourmet: 'GourmetDeal',
7
+ all: 'all' }
8
+
9
+ attr_accessor :ls_id, :published, :link, :title, :long_title, :deal_type,
10
+ :merchandise_type, :market_id, :market_name, :market_location,
11
+ :featureType, :country_code, :subtitle, :offer_ends_at,
12
+ :price, :value, :savings, :order_count, :merchant_type,
13
+ :image_url, :categories, :sold_out, :national, :description,
14
+ :details, :content, :merchant
15
+
16
+ def initialize(attributes)
17
+ self.ls_id = attributes['ls_id']
18
+ self.published = attributes['published']
19
+ self.link = attributes['link']
20
+ self.title = attributes['title']
21
+ self.long_title = attributes['long_title']
22
+ self.deal_type = attributes['deal_type']
23
+ self.merchandise_type = attributes['merchandise_type']
24
+ self.market_id = attributes['market_id']
25
+ self.market_name = attributes['market_name']
26
+ self.market_location = attributes['market_location']
27
+ self.featureType = attributes['featureType']
28
+ self.country_code = attributes['country_code']
29
+ self.subtitle = attributes['subtitle']
30
+ self.offer_ends_at = attributes['offer_ends_at']
31
+ self.price = attributes['price']
32
+ self.value = attributes['value']
33
+ self.savings = attributes['savings']
34
+ self.order_count = attributes['order_count']
35
+ self.merchant_type = attributes['merchant_type']
36
+ self.image_url = attributes['image_url']
37
+ self.categories = attributes['categories']
38
+ self.sold_out = attributes['sold_out']
39
+ self.national = attributes['national']
40
+ self.description = attributes['description']
41
+ self.details = attributes['details']
42
+ self.content = attributes['content']
43
+ self.merchant = attributes['merchant']
44
+ end
45
+
46
+ def self.find_deals_for(deal_type)
47
+ if deal_type == 'all'
48
+ LivingSocialDeal
49
+ else
50
+ LivingSocialDeal.where(deal_type: deal_type)
51
+ end
52
+ end
53
+
54
+ def self.find_by_ls_market(deal_type, market)
55
+ valid_deals = find_deals_for(DEAL_TYPES[deal_type]).where(title: market.capitalize)
56
+ valid_deals.map { |deal| new(deal.attributes) }
57
+ end
58
+
59
+ def self.find_near(deal_type, lat, long, distance=3)
60
+ valid_deals = find_deals_for(DEAL_TYPES[deal_type]).where(:market_location => { "$near" => [lat, long], "$maxDistance" => distance.fdiv(69) })
61
+ valid_deals.map { |deal| new(deal.attributes) }
62
+ end
63
+ end
64
+ end
65
+
66
+
@@ -0,0 +1,43 @@
1
+ require 'mongoid'
2
+ Mongoid::Config.from_hash({ "database" => 'app4574678',
3
+ 'host' => 'pearl.mongohq.com',
4
+ 'username' => 'ha',
5
+ 'password' => 'hungry',
6
+ 'port' => '27019' })
7
+
8
+ class LivingSocialDeal
9
+ include Mongoid::Document
10
+
11
+ field :ls_id
12
+ field :published
13
+ field :link
14
+ field :title
15
+ field :long_title
16
+ field :deal_type
17
+ field :merchandise_type
18
+ field :market_id
19
+ field :market_name
20
+ field :market_location, type: Array
21
+ field :featureType
22
+ field :country_code
23
+ field :subtitle
24
+ field :offer_ends_at
25
+ field :price
26
+ field :value
27
+ field :savings
28
+ field :order_count
29
+ field :merchant_type
30
+ field :image_url
31
+ field :categories
32
+ field :sold_out
33
+ field :national
34
+ field :description
35
+ field :details
36
+ field :content
37
+ field :merchant
38
+
39
+ index(
40
+ [[:market_location, Mongo::GEO2D]], background: true
41
+ )
42
+
43
+ end
@@ -1,3 +1,3 @@
1
1
  module Livingsocial2
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/livingsocial2.rb CHANGED
@@ -1,6 +1,5 @@
1
+ require "livingsocial2/mongo"
1
2
  require "livingsocial2/version"
2
- require "livingsocial2/client"
3
- require "livingsocial2/daily_deal"
4
- require "livingsocial2/national_deal"
5
- require 'faraday'
6
- require 'json'
3
+ require "livingsocial2/deal"
4
+ require 'mongoid'
5
+
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Livingsocial2::VERSION
17
17
 
18
- gem.add_runtime_dependency("faraday")
19
18
  gem.add_development_dependency('rspec')
19
+ gem.add_development_dependency('mongoid')
20
+ gem.add_development_dependency('bson_ext')
20
21
  end
data/spec/deal_spec.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Livingsocial2::Deal do
4
+ context 'When searching for a deal' do
5
+ describe '.find_deals_for(deal_type)' do
6
+ it 'returns an array of matching mongoid objects' do
7
+ deals = Livingsocial2::Deal.find_deals_for("AtHomeDeal")
8
+ deals.class.should be(Mongoid::Criteria)
9
+ end
10
+ end
11
+
12
+ describe '.find_by_ls_market(deal_type, market)' do
13
+ it 'returns an array of Livingsocial2::Deal objects' do
14
+ deals = Livingsocial2::Deal.find_by_ls_market(:all, 'Buffalo')
15
+ deals.first.class.should be(Livingsocial2::Deal)
16
+ end
17
+
18
+ it 'returns an empty array if invalide deal_type is entered' do
19
+ deals = Livingsocial2::Deal.find_by_ls_market(:happy_days, 'Buffalo')
20
+ deals.should be_empty
21
+ end
22
+
23
+ it 'returns an empty array if invalide market is entered' do
24
+ deals = Livingsocial2::Deal.find_by_ls_market(:all, 'Icelandia')
25
+ deals.should be_empty
26
+ end
27
+ end
28
+
29
+ describe '.find_near(deal_type, lat, long, distance)' do
30
+ it 'returns Livingsocial2::Deal instances that are within the given distance' do
31
+ deals = Livingsocial2::Deal.find_near(:all, 40.7518481, -73.97551399999999, 1)
32
+ deals.first.class.should be(Livingsocial2::Deal)
33
+ end
34
+
35
+ it 'returns an empty array if no deals match given criteria' do
36
+ deals = Livingsocial2::Deal.find_near(:all, 39.904214, 116.407413, 1)
37
+ deals.should be_empty
38
+ end
39
+
40
+ it 'returns an empty array if lat and long are passed in as strings' do
41
+ deals = Livingsocial2::Deal.find_near(:all, "40.7518481", "-73.97551399999999", 1)
42
+ deals.should be_empty
43
+ end
44
+
45
+ context "when no distance is given, it defaults to a radius of 3 miles" do
46
+ it 'returns an array of Livingsocial2::Deal objects' do
47
+ deals = Livingsocial2::Deal.find_near(:all, 40.7518481, -73.97551399999999)
48
+ deals.first.class.should be(Livingsocial2::Deal)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1 @@
1
+ require './lib/livingsocial2'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: livingsocial2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,33 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-30 00:00:00.000000000 Z
12
+ date: 2012-07-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: faraday
16
- requirement: &70196314032140 !ruby/object:Gem::Requirement
15
+ name: rspec
16
+ requirement: &70181352393960 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '0'
22
- type: :runtime
22
+ type: :development
23
23
  prerelease: false
24
- version_requirements: *70196314032140
24
+ version_requirements: *70181352393960
25
25
  - !ruby/object:Gem::Dependency
26
- name: rspec
27
- requirement: &70196314031340 !ruby/object:Gem::Requirement
26
+ name: mongoid
27
+ requirement: &70181352393280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70181352393280
36
+ - !ruby/object:Gem::Dependency
37
+ name: bson_ext
38
+ requirement: &70181352392840 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ! '>='
@@ -32,7 +43,7 @@ dependencies:
32
43
  version: '0'
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *70196314031340
46
+ version_requirements: *70181352392840
36
47
  description: Wrapper for the livingsocial atom feed
37
48
  email:
38
49
  - michael.v.verdi@gmail.com
@@ -40,17 +51,20 @@ executables: []
40
51
  extensions: []
41
52
  extra_rdoc_files: []
42
53
  files:
54
+ - .DS_Store
43
55
  - .gitignore
44
56
  - Gemfile
45
57
  - LICENSE
46
58
  - README.md
47
59
  - Rakefile
60
+ - lib/.DS_Store
48
61
  - lib/livingsocial2.rb
49
- - lib/livingsocial2/client.rb
50
- - lib/livingsocial2/daily_deal.rb
51
- - lib/livingsocial2/national_deal.rb
62
+ - lib/livingsocial2/deal.rb
63
+ - lib/livingsocial2/mongo.rb
52
64
  - lib/livingsocial2/version.rb
53
65
  - livingsocial2.gemspec
66
+ - spec/deal_spec.rb
67
+ - spec/spec_helper.rb
54
68
  homepage: ''
55
69
  licenses: []
56
70
  post_install_message:
@@ -75,4 +89,6 @@ rubygems_version: 1.8.17
75
89
  signing_key:
76
90
  specification_version: 3
77
91
  summary: Wrapper for the livingsocial atom feed
78
- test_files: []
92
+ test_files:
93
+ - spec/deal_spec.rb
94
+ - spec/spec_helper.rb
@@ -1,27 +0,0 @@
1
- require 'faraday'
2
- require 'json'
3
-
4
- module Livingsocial2Api
5
- class Client
6
- BASE_URL = "http://50.116.44.82:3000"
7
-
8
- attr_reader :connection
9
-
10
- def initialize
11
- @connection = Faraday.new(BASE_URL)
12
- end
13
-
14
- def data(location)
15
- response = @connection.get do |req|
16
- req.url "/api/v1/deals"
17
- req.headers['Accepts'] = 'application/json'
18
- req.params['division_name'] = clean_location(location)
19
- end
20
- JSON.parse(response.body)
21
- end
22
-
23
- def clean_location(location)
24
- location.gsub("-", " ")
25
- end
26
- end
27
- end
@@ -1,31 +0,0 @@
1
- module Livingsocial2Api
2
- class DailyDeal
3
- attr_accessor :image_url, :url, :description, :title, :deal_price, :original_price
4
-
5
- def initialize(attributes)
6
- self.image_url = attributes[:image_url]
7
- self.url = attributes[:url]
8
- self.description = attributes[:description]
9
- self.title = attributes[:title]
10
- self.deal_price = attributes[:deal_price]
11
- self.original_price = attributes[:original_price]
12
- end
13
-
14
- def self.client
15
- Livingsocial2Api::Client.new
16
- end
17
-
18
- def self.deal_for(location)
19
- client.data(location).map do |deal|
20
- attributes = { image_url: deal['image_url'],
21
- url: deal['original_url'],
22
- description: deal['subtitle'],
23
- title: deal['title'],
24
- deal_price: deal['price_cents'],
25
- original_price: deal['value_cents'],
26
- }
27
- new(attributes)
28
- end
29
- end
30
- end
31
- end
@@ -1,31 +0,0 @@
1
- module Livingsocial2Api
2
- class NationalDeal
3
- attr_accessor :image_url, :url, :description, :title, :deal_price, :original_price
4
-
5
- def initialize(attributes)
6
- self.image_url = attributes[:image_url]
7
- self.url = attributes[:url]
8
- self.description = attributes[:description]
9
- self.title = attributes[:title]
10
- self.deal_price = attributes[:deal_price]
11
- self.original_price = attributes[:original_price]
12
- end
13
-
14
- def self.client
15
- Livingsocial2Api::Client.new
16
- end
17
-
18
- def self.deal(location='Nationwide')
19
- client.data(location).map do |deal|
20
- attributes = { image_url: deal['image_url'],
21
- url: deal['original_url'],
22
- description: deal['subtitle'],
23
- title: deal['title'],
24
- deal_price: deal['price_cents'],
25
- original_price: deal['value_cents'],
26
- }
27
- new(attributes)
28
- end
29
- end
30
- end
31
- end