citygrid_api 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +28 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +21 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/citygrid_api.gemspec +87 -0
- data/lib/citygrid.rb +39 -0
- data/lib/citygrid/api.rb +3 -0
- data/lib/citygrid/api/base.rb +44 -0
- data/lib/citygrid/api/content.rb +3 -0
- data/lib/citygrid/api/content/offers.rb +15 -0
- data/lib/citygrid/api/content/places.rb +20 -0
- data/lib/citygrid/api/content/places/detail.rb +17 -0
- data/lib/citygrid/api/content/places/search.rb +47 -0
- data/lib/citygrid/api/content/reviews.rb +15 -0
- data/lib/citygrid/api/response.rb +18 -0
- data/lib/citygrid/listing.rb +108 -0
- data/lib/citygrid/listing/details.rb +21 -0
- data/lib/citygrid/listing/extend.rb +3 -0
- data/lib/citygrid/listing/extend/attribute.rb +18 -0
- data/lib/citygrid/listing/extend/attributes.rb +22 -0
- data/lib/citygrid/listing/extend/requestable.rb +51 -0
- data/lib/citygrid/listing/offers.rb +17 -0
- data/lib/citygrid/listing/reviews.rb +21 -0
- data/lib/citygrid/super_hash.rb +23 -0
- data/lib/citygrid_api.rb +1 -0
- data/test/helper.rb +16 -0
- data/test/publisher_helper.rb.sample +3 -0
- data/test/test_citygrid.rb +7 -0
- data/test/test_listing.rb +64 -0
- data/test/test_search.rb +21 -0
- data/test/test_super_hash.rb +33 -0
- metadata +192 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
gem "httparty", "~> 0.7.8"
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "awesome_print", "~> 0.4.0", :require => "ap"
|
11
|
+
gem "riot", "~> 0.12.4"
|
12
|
+
gem "bundler", "~> 1.0.0"
|
13
|
+
gem "jeweler", "~> 1.6.2"
|
14
|
+
gem "rcov", ">= 0"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
awesome_print (0.4.0)
|
5
|
+
crack (0.1.8)
|
6
|
+
git (1.2.5)
|
7
|
+
httparty (0.7.8)
|
8
|
+
crack (= 0.1.8)
|
9
|
+
jeweler (1.6.2)
|
10
|
+
bundler (~> 1.0)
|
11
|
+
git (>= 1.2.5)
|
12
|
+
rake
|
13
|
+
rake (0.9.2)
|
14
|
+
rcov (0.9.9)
|
15
|
+
riot (0.12.4)
|
16
|
+
rr
|
17
|
+
rr (1.0.2)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
awesome_print (~> 0.4.0)
|
24
|
+
bundler (~> 1.0.0)
|
25
|
+
httparty (~> 0.7.8)
|
26
|
+
jeweler (~> 1.6.2)
|
27
|
+
rcov
|
28
|
+
riot (~> 0.12.4)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Elpizo Choi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= citygrid
|
2
|
+
|
3
|
+
Don't use this. NOT PRODUCTION READY
|
4
|
+
|
5
|
+
Description goes here.
|
6
|
+
|
7
|
+
== Contributing to citygrid
|
8
|
+
|
9
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
10
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
11
|
+
* Fork the project
|
12
|
+
* Start a feature/bugfix branch
|
13
|
+
* Commit and push until you are happy with your contribution
|
14
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
15
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
16
|
+
|
17
|
+
== Copyright
|
18
|
+
|
19
|
+
Copyright (c) 2011 Elpizo Choi. See LICENSE.txt for
|
20
|
+
further details.
|
21
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "citygrid_api"
|
18
|
+
# gem.homepage = "http://github.com/fuJiin/citygrid"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Ruby wrapper for CityGrid APIs}
|
21
|
+
gem.description = %Q{Ruby wrapper for CityGrid APIs}
|
22
|
+
gem.email = "fu7iin@gmail.com"
|
23
|
+
gem.authors = ["Elpizo Choi"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
Rcov::RcovTask.new do |test|
|
37
|
+
test.libs << 'test'
|
38
|
+
test.pattern = 'test/**/test_*.rb'
|
39
|
+
test.verbose = true
|
40
|
+
test.rcov_opts << '--exclude "gems/*"'
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "citygrid #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{citygrid_api}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Elpizo Choi"]
|
12
|
+
s.date = %q{2011-06-24}
|
13
|
+
s.description = %q{Ruby wrapper for CityGrid APIs}
|
14
|
+
s.email = %q{fu7iin@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"citygrid_api.gemspec",
|
28
|
+
"lib/citygrid.rb",
|
29
|
+
"lib/citygrid/api.rb",
|
30
|
+
"lib/citygrid/api/base.rb",
|
31
|
+
"lib/citygrid/api/content.rb",
|
32
|
+
"lib/citygrid/api/content/offers.rb",
|
33
|
+
"lib/citygrid/api/content/places.rb",
|
34
|
+
"lib/citygrid/api/content/places/detail.rb",
|
35
|
+
"lib/citygrid/api/content/places/search.rb",
|
36
|
+
"lib/citygrid/api/content/reviews.rb",
|
37
|
+
"lib/citygrid/api/response.rb",
|
38
|
+
"lib/citygrid/listing.rb",
|
39
|
+
"lib/citygrid/listing/details.rb",
|
40
|
+
"lib/citygrid/listing/extend.rb",
|
41
|
+
"lib/citygrid/listing/extend/attribute.rb",
|
42
|
+
"lib/citygrid/listing/extend/attributes.rb",
|
43
|
+
"lib/citygrid/listing/extend/requestable.rb",
|
44
|
+
"lib/citygrid/listing/offers.rb",
|
45
|
+
"lib/citygrid/listing/reviews.rb",
|
46
|
+
"lib/citygrid/super_hash.rb",
|
47
|
+
"lib/citygrid_api.rb",
|
48
|
+
"test/helper.rb",
|
49
|
+
"test/publisher_helper.rb.sample",
|
50
|
+
"test/test_citygrid.rb",
|
51
|
+
"test/test_listing.rb",
|
52
|
+
"test/test_search.rb",
|
53
|
+
"test/test_super_hash.rb"
|
54
|
+
]
|
55
|
+
s.licenses = ["MIT"]
|
56
|
+
s.require_paths = ["lib"]
|
57
|
+
s.rubygems_version = %q{1.7.2}
|
58
|
+
s.summary = %q{Ruby wrapper for CityGrid APIs}
|
59
|
+
|
60
|
+
if s.respond_to? :specification_version then
|
61
|
+
s.specification_version = 3
|
62
|
+
|
63
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
64
|
+
s.add_runtime_dependency(%q<httparty>, ["~> 0.7.8"])
|
65
|
+
s.add_development_dependency(%q<awesome_print>, ["~> 0.4.0"])
|
66
|
+
s.add_development_dependency(%q<riot>, ["~> 0.12.4"])
|
67
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
68
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
|
69
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<httparty>, ["~> 0.7.8"])
|
72
|
+
s.add_dependency(%q<awesome_print>, ["~> 0.4.0"])
|
73
|
+
s.add_dependency(%q<riot>, ["~> 0.12.4"])
|
74
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
75
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
76
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
77
|
+
end
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<httparty>, ["~> 0.7.8"])
|
80
|
+
s.add_dependency(%q<awesome_print>, ["~> 0.4.0"])
|
81
|
+
s.add_dependency(%q<riot>, ["~> 0.12.4"])
|
82
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
83
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
84
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
data/lib/citygrid.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "citygrid/listing"
|
2
|
+
require "citygrid/api"
|
3
|
+
|
4
|
+
class CityGrid
|
5
|
+
class << self
|
6
|
+
def publisher= code
|
7
|
+
@@publisher = code
|
8
|
+
end
|
9
|
+
|
10
|
+
def publisher
|
11
|
+
raise PublisherNotConfigured if !defined?(@@publisher) || @@publisher.nil?
|
12
|
+
@@publisher
|
13
|
+
end
|
14
|
+
|
15
|
+
def places
|
16
|
+
API::Content::Places
|
17
|
+
end
|
18
|
+
|
19
|
+
def offers opts
|
20
|
+
API::Content::Offers.request opts
|
21
|
+
end
|
22
|
+
|
23
|
+
def reviews opts
|
24
|
+
API::Content::Reviews.request opts
|
25
|
+
end
|
26
|
+
|
27
|
+
def search opts = {}
|
28
|
+
places.search opts
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Errors
|
33
|
+
# --------------- #
|
34
|
+
class PublisherNotConfigured < StandardError
|
35
|
+
def initialize
|
36
|
+
super "Publisher hasn't been configured. Run 'CityGrid.publisher=<code>'"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/citygrid/api.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "httparty"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
module API
|
5
|
+
module Base
|
6
|
+
class << self
|
7
|
+
def included base
|
8
|
+
base.instance_eval do
|
9
|
+
include HTTParty
|
10
|
+
extend ClassMethods
|
11
|
+
base_uri "api.citygridmedia.com/content"
|
12
|
+
format :json
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def endpoint
|
19
|
+
# Specified for each API
|
20
|
+
end
|
21
|
+
|
22
|
+
def publisher
|
23
|
+
CityGrid.publisher
|
24
|
+
end
|
25
|
+
|
26
|
+
def request options = {}
|
27
|
+
query = options.merge :publisher => publisher, :format => "json"
|
28
|
+
response = get endpoint, :query => query
|
29
|
+
CityGrid::API::Response.new response
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def convert_to_querystring hash
|
35
|
+
hash.map do |k, v|
|
36
|
+
key = URI.escape k.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
37
|
+
val = URI.escape v.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
38
|
+
!value.empty? && !key.empty? ? "#{key}=#{value}" : nil
|
39
|
+
end.compact.join("&")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "citygrid/api/content/places/detail"
|
2
|
+
require "citygrid/api/content/places/search"
|
3
|
+
|
4
|
+
class CityGrid
|
5
|
+
module API
|
6
|
+
module Content
|
7
|
+
module Places
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def detail opts
|
11
|
+
Detail.request opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def search opts
|
15
|
+
Search.request opts
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class CityGrid
|
2
|
+
module API
|
3
|
+
module Content
|
4
|
+
module Places
|
5
|
+
module Search
|
6
|
+
include CityGrid::API::Base
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def endpoint
|
10
|
+
"/places/v2/search/where"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Overwrite to return Search::Response
|
14
|
+
def request options
|
15
|
+
query = options.merge :publisher => publisher, :format => "json"
|
16
|
+
response = get endpoint, :query => query
|
17
|
+
Response.new response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Holds array of Listings.
|
22
|
+
# HTTParty response can be accessed by #response
|
23
|
+
# ---------------------------------------------- #
|
24
|
+
class Response < Array
|
25
|
+
attr_reader :response, :errors
|
26
|
+
|
27
|
+
def self.new httparty_response
|
28
|
+
resp = httparty_response.parsed_response
|
29
|
+
|
30
|
+
if resp["errors"]
|
31
|
+
array = self.[]
|
32
|
+
array.instance_variable_set "@errors", resp["errors"]
|
33
|
+
else
|
34
|
+
array = self.[] *resp["results"]["locations"]
|
35
|
+
array.map! do |result|
|
36
|
+
CityGrid::Listing.new result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
array.instance_variable_set "@response", httparty_response
|
40
|
+
array
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "citygrid/super_hash"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
module API
|
5
|
+
# Creates SuperHash from parsed_response
|
6
|
+
# Stores response object in @response.
|
7
|
+
# ------------------------------------ #
|
8
|
+
class Response < CityGrid::SuperHash
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def self.new httparty_response
|
12
|
+
resp = super httparty_response.parsed_response
|
13
|
+
resp.instance_variable_set "@response", httparty_response
|
14
|
+
resp
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require "citygrid/super_hash"
|
2
|
+
require "citygrid/listing/extend"
|
3
|
+
require "citygrid/listing/details"
|
4
|
+
require "citygrid/listing/offers"
|
5
|
+
require "citygrid/listing/reviews"
|
6
|
+
|
7
|
+
class CityGrid
|
8
|
+
class Listing < SuperHash
|
9
|
+
|
10
|
+
def method_missing meth, *args, &block
|
11
|
+
load unless @loaded
|
12
|
+
send(meth, *args, &block) rescue super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def load
|
18
|
+
extend LoadedMethods
|
19
|
+
update_details
|
20
|
+
@loaded = true
|
21
|
+
end
|
22
|
+
|
23
|
+
module LoadedMethods
|
24
|
+
def listing_id
|
25
|
+
self["id"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def reset
|
29
|
+
@reviews = nil
|
30
|
+
@offers = nil
|
31
|
+
@categories = nil
|
32
|
+
@attributes = nil
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def avg_rating
|
37
|
+
review_info.overall_review_rating
|
38
|
+
end
|
39
|
+
|
40
|
+
# This is a really hacky way to do this - need to fix
|
41
|
+
def summary
|
42
|
+
(customer_content.customer_message.value rescue nil) ||
|
43
|
+
(editorials.first.editorial_review rescue nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
def categories
|
47
|
+
@categories ||= extract_categories details["categories"]
|
48
|
+
end
|
49
|
+
|
50
|
+
def special_features
|
51
|
+
categories.select do |k, v|
|
52
|
+
k.downcase.include? "special features"
|
53
|
+
end.map do |k, v|
|
54
|
+
v
|
55
|
+
end.flatten.uniq
|
56
|
+
end
|
57
|
+
|
58
|
+
def attributes
|
59
|
+
@attributes ||= extract_attributes details["attributes"]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Details
|
63
|
+
# ---------------- #
|
64
|
+
def update_details
|
65
|
+
update Details.new listing_id
|
66
|
+
end
|
67
|
+
|
68
|
+
# Offers
|
69
|
+
# -------------- #
|
70
|
+
def offers opts = {}
|
71
|
+
@offers ||= Offers.new listing_id
|
72
|
+
@offers.update_options opts
|
73
|
+
end
|
74
|
+
|
75
|
+
# Reviews
|
76
|
+
# -------------- #
|
77
|
+
def reviews opts = {}
|
78
|
+
@reviews ||= Reviews.new listing_id
|
79
|
+
@reviews.update_options opts
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Group categories by their group names
|
85
|
+
def extract_categories cats
|
86
|
+
cats.inject Hash.new do |hash, tag|
|
87
|
+
|
88
|
+
# iterate through groups if the tag belongs to multiple
|
89
|
+
tag["groups"].each do |group|
|
90
|
+
name = group["name"]
|
91
|
+
hash[name] ||= []
|
92
|
+
hash[name] << tag["name"]
|
93
|
+
end
|
94
|
+
hash
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def extract_attributes attrs
|
99
|
+
attrs.inject Hash.new do |hash, attrib|
|
100
|
+
key = attrib["name"]
|
101
|
+
val = attrib["value"]
|
102
|
+
hash[key] = val
|
103
|
+
hash
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "citygrid/listing/extend"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
class Listing < SuperHash
|
5
|
+
class Details < Extend::Attribute
|
6
|
+
def api
|
7
|
+
CityGrid::API::Content::Places::Detail
|
8
|
+
end
|
9
|
+
|
10
|
+
def request
|
11
|
+
api.request listing_options.merge(:client_ip => "192.168.0.1")
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def preprocess req
|
17
|
+
req.locations.first
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "citygrid/listing/extend/requestable"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
class Listing < SuperHash
|
5
|
+
module Extend
|
6
|
+
class Attribute < CityGrid::SuperHash
|
7
|
+
include Requestable
|
8
|
+
|
9
|
+
def self.new listing_id, opts = {}
|
10
|
+
hash = self[{}]
|
11
|
+
hash.instance_variable_set "@listing_id", listing_id
|
12
|
+
hash.instance_variable_set "@options", opts
|
13
|
+
hash.request_and_update
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "citygrid/listing/extend/requestable"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
class Listing < SuperHash
|
5
|
+
module Extend
|
6
|
+
class Attributes < Array
|
7
|
+
include Requestable
|
8
|
+
|
9
|
+
def self.new listing_id, opts = {}
|
10
|
+
hash = self[]
|
11
|
+
hash.instance_variable_set "@listing_id", listing_id
|
12
|
+
hash.instance_variable_set "@options", opts
|
13
|
+
hash.request_and_update
|
14
|
+
end
|
15
|
+
|
16
|
+
def update array
|
17
|
+
replace array
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class CityGrid
|
2
|
+
class Listing < SuperHash
|
3
|
+
module Extend
|
4
|
+
module Requestable
|
5
|
+
def self.included base
|
6
|
+
base.instance_eval do
|
7
|
+
attr_accessor :options
|
8
|
+
attr_reader :listing_id, :raw
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def api
|
13
|
+
# set corresponding API here
|
14
|
+
end
|
15
|
+
|
16
|
+
def request
|
17
|
+
api.request listing_options
|
18
|
+
end
|
19
|
+
|
20
|
+
# Run request, preprocess, and update.
|
21
|
+
# Write an update method if it doesn't already exist
|
22
|
+
#
|
23
|
+
# def update
|
24
|
+
#
|
25
|
+
# end
|
26
|
+
def request_and_update
|
27
|
+
@raw = request
|
28
|
+
update preprocess(@raw)
|
29
|
+
end
|
30
|
+
|
31
|
+
def listing_options
|
32
|
+
options.merge :listing_id => listing_id
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_options opts
|
36
|
+
return self if opts == @options
|
37
|
+
@options = opts
|
38
|
+
request_and_update
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Preprocess request.
|
44
|
+
# Overwrite this method to preprocess request before updating.
|
45
|
+
def preprocess req
|
46
|
+
req
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "citygrid/listing/extend"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
class Listing < SuperHash
|
5
|
+
class Offers < Extend::Attributes
|
6
|
+
def api
|
7
|
+
CityGrid::API::Content::Offers
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def preprocess req
|
13
|
+
req.results.offers
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "citygrid/listing/extend"
|
2
|
+
|
3
|
+
class CityGrid
|
4
|
+
class Listing < SuperHash
|
5
|
+
class Reviews < Extend::Attributes
|
6
|
+
def api
|
7
|
+
CityGrid::API::Content::Reviews
|
8
|
+
end
|
9
|
+
|
10
|
+
def total_hits
|
11
|
+
raw["results"]["total_hits"]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def preprocess req
|
17
|
+
req.results.reviews
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CityGrid
|
2
|
+
|
3
|
+
# Subset of Hash that provides following features:
|
4
|
+
# - create by SuperHash.new(<hash>)
|
5
|
+
# - can access values by method, instead of []
|
6
|
+
# -------------------------------------------- #
|
7
|
+
class SuperHash < Hash
|
8
|
+
def self.new attrs
|
9
|
+
self[attrs]
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing sym, *args, &block
|
13
|
+
val = self[sym] || self[sym.to_s]
|
14
|
+
|
15
|
+
# create new SuperHash if value is hash
|
16
|
+
if val.is_a? Hash
|
17
|
+
SuperHash.new val
|
18
|
+
else
|
19
|
+
val || super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/citygrid_api.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "citygrid"
|
data/test/helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require "ap"
|
11
|
+
require "riot"
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require "citygrid_api"
|
16
|
+
require "publisher_helper"
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
context "A Listing created from scratch" do
|
4
|
+
setup do
|
5
|
+
CityGrid::Listing.new "id" => 7117426
|
6
|
+
end
|
7
|
+
|
8
|
+
should "load details after first access" do
|
9
|
+
topic.tips
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "A Listing created from search" do
|
14
|
+
setup do
|
15
|
+
CityGrid.search(:what => "sushi", :where => "seattle").first
|
16
|
+
end
|
17
|
+
|
18
|
+
# Test loading
|
19
|
+
# ----------------- #
|
20
|
+
context "that has not been accessed" do
|
21
|
+
should "not be loaded" do
|
22
|
+
!topic.clone.instance_variable_get "@loaded"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "that has a method called on it for the first time" do
|
27
|
+
setup do
|
28
|
+
old = topic.clone
|
29
|
+
listing = topic.clone
|
30
|
+
listing.summary
|
31
|
+
[old, listing]
|
32
|
+
end
|
33
|
+
|
34
|
+
should "become loaded" do
|
35
|
+
topic.last.instance_variable_get "@loaded"
|
36
|
+
end
|
37
|
+
|
38
|
+
should "update details into itself" do
|
39
|
+
topic.first != topic.last
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Test offers, reviews
|
44
|
+
# -------------------- #
|
45
|
+
should "get offers" do
|
46
|
+
!topic.offers.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
# Test reviews
|
50
|
+
# -------------------- #
|
51
|
+
should "get reviews" do
|
52
|
+
!topic.reviews.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
context "updating reviews" do
|
56
|
+
setup do
|
57
|
+
[topic.reviews.clone, topic.reviews(:rpp => 2).clone]
|
58
|
+
end
|
59
|
+
|
60
|
+
should "not be the same" do
|
61
|
+
topic[0] != topic[-1]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/test/test_search.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
context "searching for a CityGrid listing" do
|
4
|
+
setup do
|
5
|
+
CityGrid.search :what => "sushi", :where => "Seattle"
|
6
|
+
end
|
7
|
+
|
8
|
+
should "create an array" do
|
9
|
+
topic.is_a? Array
|
10
|
+
end
|
11
|
+
|
12
|
+
should_not "be empty" do
|
13
|
+
topic.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
should "create an array containing Listing objects" do
|
17
|
+
topic.reject do |listing|
|
18
|
+
listing.is_a? CityGrid::Listing
|
19
|
+
end.empty?
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
context "A SuperHash" do
|
4
|
+
# Test creation
|
5
|
+
# ------------------------ #
|
6
|
+
context "created from #new" do
|
7
|
+
context "and given a hash" do
|
8
|
+
setup { CityGrid::SuperHash.new(:test => "wassup") }
|
9
|
+
should("return a hash") { topic.is_a? Hash }
|
10
|
+
should("its value can be accessible through its key") { topic[:test] == "wassup"}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Test accessing of values
|
15
|
+
# ------------------------ #
|
16
|
+
context "that's single level" do
|
17
|
+
context "with symbol as key" do
|
18
|
+
setup { CityGrid::SuperHash.new(:test => "wassup") }
|
19
|
+
should("can access key as method") { topic.test }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with string as key" do
|
23
|
+
setup { CityGrid::SuperHash.new("test" => "wasssup") }
|
24
|
+
should("can access key as method"){ topic.test }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "that has a subhash" do
|
29
|
+
setup { CityGrid::SuperHash.new(:test => {:wassup => "hows it going?"}) }
|
30
|
+
should("return another SuperHash") { topic.test.is_a? CityGrid::SuperHash }
|
31
|
+
should("return correct hash") { topic.test.wassup == "hows it going?" }
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: citygrid_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Elpizo Choi
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-06-24 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
type: :runtime
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 19
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 7
|
31
|
+
- 8
|
32
|
+
version: 0.7.8
|
33
|
+
version_requirements: *id001
|
34
|
+
name: httparty
|
35
|
+
prerelease: false
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
type: :development
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 15
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 4
|
47
|
+
- 0
|
48
|
+
version: 0.4.0
|
49
|
+
version_requirements: *id002
|
50
|
+
name: awesome_print
|
51
|
+
prerelease: false
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
type: :development
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 39
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
- 12
|
63
|
+
- 4
|
64
|
+
version: 0.12.4
|
65
|
+
version_requirements: *id003
|
66
|
+
name: riot
|
67
|
+
prerelease: false
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
type: :development
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 23
|
76
|
+
segments:
|
77
|
+
- 1
|
78
|
+
- 0
|
79
|
+
- 0
|
80
|
+
version: 1.0.0
|
81
|
+
version_requirements: *id004
|
82
|
+
name: bundler
|
83
|
+
prerelease: false
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
type: :development
|
86
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ~>
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 11
|
92
|
+
segments:
|
93
|
+
- 1
|
94
|
+
- 6
|
95
|
+
- 2
|
96
|
+
version: 1.6.2
|
97
|
+
version_requirements: *id005
|
98
|
+
name: jeweler
|
99
|
+
prerelease: false
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
type: :development
|
102
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 3
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
version: "0"
|
111
|
+
version_requirements: *id006
|
112
|
+
name: rcov
|
113
|
+
prerelease: false
|
114
|
+
description: Ruby wrapper for CityGrid APIs
|
115
|
+
email: fu7iin@gmail.com
|
116
|
+
executables: []
|
117
|
+
|
118
|
+
extensions: []
|
119
|
+
|
120
|
+
extra_rdoc_files:
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.rdoc
|
123
|
+
files:
|
124
|
+
- .document
|
125
|
+
- Gemfile
|
126
|
+
- Gemfile.lock
|
127
|
+
- LICENSE.txt
|
128
|
+
- README.rdoc
|
129
|
+
- Rakefile
|
130
|
+
- VERSION
|
131
|
+
- citygrid_api.gemspec
|
132
|
+
- lib/citygrid.rb
|
133
|
+
- lib/citygrid/api.rb
|
134
|
+
- lib/citygrid/api/base.rb
|
135
|
+
- lib/citygrid/api/content.rb
|
136
|
+
- lib/citygrid/api/content/offers.rb
|
137
|
+
- lib/citygrid/api/content/places.rb
|
138
|
+
- lib/citygrid/api/content/places/detail.rb
|
139
|
+
- lib/citygrid/api/content/places/search.rb
|
140
|
+
- lib/citygrid/api/content/reviews.rb
|
141
|
+
- lib/citygrid/api/response.rb
|
142
|
+
- lib/citygrid/listing.rb
|
143
|
+
- lib/citygrid/listing/details.rb
|
144
|
+
- lib/citygrid/listing/extend.rb
|
145
|
+
- lib/citygrid/listing/extend/attribute.rb
|
146
|
+
- lib/citygrid/listing/extend/attributes.rb
|
147
|
+
- lib/citygrid/listing/extend/requestable.rb
|
148
|
+
- lib/citygrid/listing/offers.rb
|
149
|
+
- lib/citygrid/listing/reviews.rb
|
150
|
+
- lib/citygrid/super_hash.rb
|
151
|
+
- lib/citygrid_api.rb
|
152
|
+
- test/helper.rb
|
153
|
+
- test/publisher_helper.rb.sample
|
154
|
+
- test/test_citygrid.rb
|
155
|
+
- test/test_listing.rb
|
156
|
+
- test/test_search.rb
|
157
|
+
- test/test_super_hash.rb
|
158
|
+
homepage:
|
159
|
+
licenses:
|
160
|
+
- MIT
|
161
|
+
post_install_message:
|
162
|
+
rdoc_options: []
|
163
|
+
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
hash: 3
|
172
|
+
segments:
|
173
|
+
- 0
|
174
|
+
version: "0"
|
175
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
+
none: false
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
hash: 3
|
181
|
+
segments:
|
182
|
+
- 0
|
183
|
+
version: "0"
|
184
|
+
requirements: []
|
185
|
+
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 1.7.2
|
188
|
+
signing_key:
|
189
|
+
specification_version: 3
|
190
|
+
summary: Ruby wrapper for CityGrid APIs
|
191
|
+
test_files: []
|
192
|
+
|