citygrid_api 0.0.5 → 0.0.5.1
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/.sass-cache/7a5a675d951455410512a59af5ab2d160bd1735c/test.scssc +0 -0
- data/Gemfile +10 -8
- data/Gemfile.lock +24 -9
- data/README +21 -0
- data/citygrid_api.gemspec +77 -17
- data/citygrid_api.yml.sample +33 -0
- data/config.ru +2 -0
- data/dashboard.rb +110 -0
- data/lib/citygrid/abstraction/collection.rb +1 -1
- data/lib/citygrid/abstraction/super_hash.rb +2 -0
- data/lib/citygrid/api/ad_center/account.rb +26 -0
- data/lib/citygrid/api/ad_center/account_manager.rb +8 -0
- data/lib/citygrid/api/ad_center/ad_group.rb +8 -0
- data/lib/citygrid/api/ad_center/ad_group_ad.rb +8 -0
- data/lib/citygrid/api/ad_center/ad_group_criterion.rb +8 -0
- data/lib/citygrid/api/ad_center/ad_group_geo.rb +8 -0
- data/lib/citygrid/api/ad_center/authentication.rb +20 -0
- data/lib/citygrid/api/ad_center/billing.rb +8 -0
- data/lib/citygrid/api/ad_center/budget.rb +9 -0
- data/lib/citygrid/api/ad_center/call_detail.rb +25 -0
- data/lib/citygrid/api/ad_center/campaign.rb +8 -0
- data/lib/citygrid/api/ad_center/category.rb +9 -0
- data/lib/citygrid/api/ad_center/geolocation.rb +9 -0
- data/lib/citygrid/api/ad_center/image.rb +30 -0
- data/lib/citygrid/api/ad_center/method_of_payment.rb +10 -0
- data/lib/citygrid/api/ad_center/performance.rb +17 -0
- data/lib/citygrid/api/ad_center/places.rb +8 -0
- data/lib/citygrid/api/ad_center/user.rb +8 -0
- data/lib/citygrid/api/ad_center.rb +20 -0
- data/lib/citygrid/api/content/offers.rb +14 -9
- data/lib/citygrid/api/content/places/detail.rb +5 -11
- data/lib/citygrid/api/content/places/search.rb +5 -11
- data/lib/citygrid/api/content/places.rb +30 -14
- data/lib/citygrid/api/content/reviews.rb +5 -10
- data/lib/citygrid/api/content.rb +12 -3
- data/lib/citygrid/api/response.rb +2 -2
- data/lib/citygrid/api.rb +190 -3
- data/lib/citygrid/details.rb +1 -1
- data/lib/citygrid/listing.rb +7 -2
- data/lib/citygrid/offers.rb +4 -0
- data/lib/citygrid/reviews.rb +4 -0
- data/lib/citygrid/search.rb +6 -0
- data/lib/citygrid.rb +117 -12
- data/lib/dashboard/sinatra_partial.rb +17 -0
- data/lib/dashboard/stored_reporter.rb +101 -0
- data/lib/dashboard/test_result.rb +8 -0
- data/lib/request_ext.rb +32 -0
- data/public/javascript/dashboard.js +5 -0
- data/test/api/ad_center/test_account.rb +120 -0
- data/test/api/ad_center/test_ad_group.rb +50 -0
- data/test/api/ad_center/test_ad_group_ad.rb +27 -0
- data/test/api/ad_center/test_ad_group_criterion.rb +37 -0
- data/test/api/ad_center/test_ad_group_geo.rb +19 -0
- data/test/api/ad_center/test_authentication.rb +22 -0
- data/test/api/ad_center/test_billing.rb +14 -0
- data/test/api/ad_center/test_budget.rb +13 -0
- data/test/api/ad_center/test_call_detail.rb +36 -0
- data/test/api/ad_center/test_campaign.rb +27 -0
- data/test/api/ad_center/test_category.rb +37 -0
- data/test/api/ad_center/test_geolocation.rb +19 -0
- data/test/api/ad_center/test_image.rb +17 -0
- data/test/api/ad_center/test_method_of_payment.rb +51 -0
- data/test/api/ad_center/test_places.rb +79 -0
- data/test/api/ad_center/test_reports.rb +37 -0
- data/test/api/content/test_offers.rb +28 -0
- data/test/api/content/test_places.rb +66 -0
- data/test/helper.rb +67 -14
- data/test/test_config.rb +11 -0
- data/test/test_details.rb +14 -5
- data/test/test_img.jpg +0 -0
- data/test/test_img_big.png +0 -0
- data/test/test_listing.rb +64 -64
- data/test/test_search.rb +21 -1
- data/test/test_super_array.rb +1 -1
- data/test/test_super_hash.rb +1 -1
- data/views/_context_result.haml +25 -0
- data/views/_request.haml +3 -0
- data/views/_test_result.haml +4 -0
- data/views/stylesheets/test.scss +53 -0
- data/views/test.haml +8 -0
- metadata +145 -114
- data/lib/citygrid/api/base.rb +0 -60
- data/test/test_citygrid.rb +0 -7
@@ -0,0 +1,20 @@
|
|
1
|
+
class CityGrid
|
2
|
+
class API
|
3
|
+
class AdCenter < API
|
4
|
+
server :default
|
5
|
+
def self.initialize
|
6
|
+
puts "init adCenter"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
[
|
13
|
+
"account", "account_manager", "ad_group", "ad_group_ad", "ad_group_criterion", "ad_group_geo",
|
14
|
+
"authentication", "budget", "campaign", "category", "geolocation", "method_of_payment", "places", "performance",
|
15
|
+
"image", "user", "call_detail", "billing"
|
16
|
+
].each do |x|
|
17
|
+
require "citygrid/api/ad_center/#{x}"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
@@ -1,13 +1,18 @@
|
|
1
1
|
class CityGrid
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
class API
|
3
|
+
class Content
|
4
|
+
class Offers < Content
|
5
|
+
@base_endpoint = "http://api.citygridmedia.com/content/offers/v2/search"
|
6
|
+
endpoint @base_endpoint
|
7
|
+
|
8
|
+
def self.where options = {}
|
9
|
+
endpoint "#{@base_endpoint}/where"
|
10
|
+
request_with_publisher options
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.places options = {}
|
14
|
+
endpoint "#{@base_endpoint}/places"
|
15
|
+
request_with_publisher options
|
11
16
|
end
|
12
17
|
end
|
13
18
|
end
|
@@ -1,15 +1,9 @@
|
|
1
1
|
class CityGrid
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def endpoint
|
10
|
-
"/places/v2/detail"
|
11
|
-
end
|
12
|
-
end
|
2
|
+
class API
|
3
|
+
class Content
|
4
|
+
class Places
|
5
|
+
class Detail < Places
|
6
|
+
endpoint "/content/places/v2/detail"
|
13
7
|
end
|
14
8
|
end
|
15
9
|
end
|
@@ -1,15 +1,9 @@
|
|
1
1
|
class CityGrid
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def endpoint
|
10
|
-
"/places/v2/search/where"
|
11
|
-
end
|
12
|
-
end
|
2
|
+
class API
|
3
|
+
class Content
|
4
|
+
class Places
|
5
|
+
class Search < Places
|
6
|
+
endpoint "/content/places/v2/search/where"
|
13
7
|
end
|
14
8
|
end
|
15
9
|
end
|
@@ -1,20 +1,36 @@
|
|
1
|
-
require "citygrid/api/content/places/detail"
|
2
|
-
require "citygrid/api/content/places/search"
|
3
|
-
|
4
1
|
class CityGrid
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
2
|
+
class API
|
3
|
+
class Content
|
4
|
+
class Places < Content
|
5
|
+
base_uri "api.citygridmedia.com"
|
6
|
+
endpoint "/content/places/v2"
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def detail opts
|
10
|
+
Detail.request opts
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
13
|
+
def search opts
|
14
|
+
Search.request opts
|
15
|
+
end
|
16
|
+
|
17
|
+
def mutate options = {}
|
18
|
+
token = extract_auth_token options
|
19
|
+
request_and_handle :post,
|
20
|
+
"#{endpoint}/mutate",
|
21
|
+
:body => options.to_json,
|
22
|
+
:headers => merge_headers("authToken" => token)
|
23
|
+
end
|
24
|
+
|
16
25
|
end
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
20
|
-
end
|
29
|
+
end
|
30
|
+
|
31
|
+
[
|
32
|
+
"detail", "search"
|
33
|
+
].each do |x|
|
34
|
+
require "citygrid/api/content/places/#{x}"
|
35
|
+
end
|
36
|
+
|
@@ -1,14 +1,9 @@
|
|
1
1
|
class CityGrid
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
class << self
|
8
|
-
def endpoint
|
9
|
-
"/reviews/v2/search/where"
|
10
|
-
end
|
11
|
-
end
|
2
|
+
class API
|
3
|
+
class Content
|
4
|
+
class Reviews < Content
|
5
|
+
base_uri "api.citygridmedia.com"
|
6
|
+
endpoint "/content/reviews/v2/search/where"
|
12
7
|
end
|
13
8
|
end
|
14
9
|
end
|
data/lib/citygrid/api/content.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class CityGrid
|
2
|
+
class API
|
3
|
+
class Content < API
|
4
|
+
end
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
[
|
9
|
+
"offers", "places", "reviews"
|
10
|
+
].each do |x|
|
11
|
+
require "citygrid/api/content/#{x}"
|
12
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class CityGrid
|
2
|
-
|
2
|
+
class API
|
3
3
|
# Creates SuperHash from parsed_response
|
4
4
|
# Stores response object in @response.
|
5
5
|
# ------------------------------------ #
|
6
6
|
class Response < CityGrid::Abstraction::SuperHash
|
7
7
|
attr_reader :httparty
|
8
|
-
|
8
|
+
|
9
9
|
def self.new httparty_response
|
10
10
|
resp = super httparty_response.parsed_response
|
11
11
|
resp.instance_variable_set "@httparty", httparty_response
|
data/lib/citygrid/api.rb
CHANGED
@@ -1,3 +1,190 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require "httparty"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
class CityGrid
|
5
|
+
class API
|
6
|
+
include HTTParty
|
7
|
+
format :json
|
8
|
+
#debug_output $stderr
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# server setting - :default or :ssl
|
12
|
+
def server val=nil
|
13
|
+
return @server || (superclass.respond_to?(:server) ? superclass.server : nil) unless val
|
14
|
+
@server = val
|
15
|
+
end
|
16
|
+
|
17
|
+
def hostname val=nil
|
18
|
+
return @hostname || (superclass.respond_to?(:hostname) ? superclass.hostname : nil) unless val
|
19
|
+
@hostname = val
|
20
|
+
end
|
21
|
+
|
22
|
+
def endpoint val=nil
|
23
|
+
return @endpoint unless val
|
24
|
+
@endpoint = val
|
25
|
+
end
|
26
|
+
|
27
|
+
def publisher
|
28
|
+
CityGrid.publisher
|
29
|
+
end
|
30
|
+
|
31
|
+
def request options = {}
|
32
|
+
method = (options.delete(:method) || :get).to_sym
|
33
|
+
query = options.merge :format => :json
|
34
|
+
request_and_handle method, endpoint, :query => query
|
35
|
+
end
|
36
|
+
|
37
|
+
def request_with_publisher options = {}
|
38
|
+
request options.merge(:publisher => publisher)
|
39
|
+
end
|
40
|
+
|
41
|
+
def mutate options = {}
|
42
|
+
token = extract_auth_token options
|
43
|
+
request_and_handle :post,
|
44
|
+
"#{endpoint}/mutate",
|
45
|
+
:body => options.to_json,
|
46
|
+
:headers => merge_headers("authToken" => token)
|
47
|
+
end
|
48
|
+
|
49
|
+
def search options = {}
|
50
|
+
token = extract_auth_token options
|
51
|
+
request_and_handle :get,
|
52
|
+
"#{endpoint}/get",
|
53
|
+
:query => options,
|
54
|
+
:headers => merge_headers("authToken" => token)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def extract_auth_token options = {}
|
59
|
+
options.delete(:token) #|| raise(MissingAuthToken)
|
60
|
+
end
|
61
|
+
|
62
|
+
def merge_headers options = {}
|
63
|
+
{"Accept" => "application/json",
|
64
|
+
"Content-Type" => "Application/JSON"}.merge options
|
65
|
+
end
|
66
|
+
|
67
|
+
def convert_to_querystring hash
|
68
|
+
hash.map do |k, v|
|
69
|
+
key = URI.escape k.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
70
|
+
val = URI.escape v.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
71
|
+
!value.empty? && !key.empty? ? "#{key}=#{value}" : nil
|
72
|
+
end.compact.join("&")
|
73
|
+
end
|
74
|
+
|
75
|
+
HTTP_METHODS = {
|
76
|
+
"put" => Net::HTTP::Put,
|
77
|
+
"get" => Net::HTTP::Get,
|
78
|
+
"post" => Net::HTTP::Post,
|
79
|
+
"delete" => Net::HTTP::Delete,
|
80
|
+
"head" => Net::HTTP::Head,
|
81
|
+
"options" => Net::HTTP::Options
|
82
|
+
}
|
83
|
+
|
84
|
+
# Transform response into API::Response object
|
85
|
+
# or throw exception if an error exists
|
86
|
+
def request_and_handle http_method, path, options
|
87
|
+
if http_method.is_a?(String) || http_method.is_a?(Symbol)
|
88
|
+
http_method = HTTP_METHODS[http_method.to_s]
|
89
|
+
raise "Unknown http method: #{http_method}" unless http_method
|
90
|
+
end
|
91
|
+
|
92
|
+
req_options = default_options.dup
|
93
|
+
req_options = req_options.merge({:base_uri => CityGrid.config[server]}) if !base_uri && server
|
94
|
+
req_options = req_options.merge(options)
|
95
|
+
|
96
|
+
req = HTTParty::Request.new http_method, path, req_options
|
97
|
+
error = nil
|
98
|
+
|
99
|
+
begin
|
100
|
+
response = req.perform
|
101
|
+
rescue => ex
|
102
|
+
puts "Something went wrong with Request.perform"
|
103
|
+
error = StandardError.new "Internal Error"
|
104
|
+
rescue Psych::SyntaxError => ex
|
105
|
+
puts "Something went wrong with Request.perform, Psych:SyntaxError"
|
106
|
+
error = StandardError.new "Internal Error"
|
107
|
+
end
|
108
|
+
|
109
|
+
if defined?(Rails.logger)
|
110
|
+
Rails.logger.info req.to_curl
|
111
|
+
else
|
112
|
+
puts req.to_curl
|
113
|
+
end
|
114
|
+
|
115
|
+
unless error
|
116
|
+
if !response.parsed_response.is_a?(Hash)
|
117
|
+
error = InvalidResponseFormat.new response
|
118
|
+
elsif response["errors"]
|
119
|
+
error = Error.new response["errors"], response
|
120
|
+
else
|
121
|
+
return CityGrid::API::Response.new response
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if error
|
126
|
+
puts "an error happened"
|
127
|
+
puts req.to_json
|
128
|
+
#raise error
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# ERRORS
|
134
|
+
class GenericError < StandardError
|
135
|
+
attr_reader :httparty, :message
|
136
|
+
|
137
|
+
def initialize msg, response = nil
|
138
|
+
@message = msg
|
139
|
+
@httparty = response
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Error < GenericError
|
144
|
+
def initialize errors, response
|
145
|
+
super errors.first["error"], response
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class InvalidResponseFormat < GenericError
|
150
|
+
attr_accessor :server_msg, :description
|
151
|
+
def initialize response = nil
|
152
|
+
# parse Tomcat error report
|
153
|
+
if response.match /<title>Apache Tomcat.* - Error report<\/title>/
|
154
|
+
response.scan(/<p><b>(message|description)<\/b> *<u>(.*?)<\/u><\/p>/).each do |match|
|
155
|
+
case match[0]
|
156
|
+
when "message"
|
157
|
+
self.server_msg = match[1]
|
158
|
+
when "description"
|
159
|
+
self.description = match[1]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
error_body = response.match(/<body>(.*?)<\/body>/m)[1]
|
164
|
+
|
165
|
+
msg = <<-EOS
|
166
|
+
Unexpected response format. Expected response to be a hash, but was instead:\n#{error_body}\n
|
167
|
+
EOS
|
168
|
+
|
169
|
+
super msg, error_body
|
170
|
+
else
|
171
|
+
msg = <<-EOS
|
172
|
+
Unexpected response format. Expected response to be a hash, but was instead:\n#{response.parsed_response}\n
|
173
|
+
EOS
|
174
|
+
|
175
|
+
super msg, response
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
class MissingAuthToken < GenericError
|
181
|
+
def initialize
|
182
|
+
super message
|
183
|
+
end
|
184
|
+
|
185
|
+
def message
|
186
|
+
"Missing authToken - token is required"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
data/lib/citygrid/details.rb
CHANGED
data/lib/citygrid/listing.rb
CHANGED
@@ -12,8 +12,13 @@ class CityGrid
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def method_missing meth, *args, &block
|
15
|
-
|
16
|
-
|
15
|
+
if @loaded
|
16
|
+
super
|
17
|
+
else
|
18
|
+
@loaded = true
|
19
|
+
load
|
20
|
+
send(meth, *args, &block)
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
private
|
data/lib/citygrid/offers.rb
CHANGED
data/lib/citygrid/reviews.rb
CHANGED
data/lib/citygrid/search.rb
CHANGED
@@ -4,9 +4,15 @@ class CityGrid
|
|
4
4
|
CityGrid::API::Content::Places::Search
|
5
5
|
end
|
6
6
|
|
7
|
+
def request opts = {}
|
8
|
+
api.request_with_publisher opts
|
9
|
+
end
|
10
|
+
|
7
11
|
private
|
8
12
|
|
9
13
|
def preprocess response
|
14
|
+
return nil unless response && response.results && response.results.locations
|
15
|
+
|
10
16
|
response.results.locations.map do |attrs|
|
11
17
|
Listing.new attrs
|
12
18
|
end
|
data/lib/citygrid.rb
CHANGED
@@ -1,21 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require "citygrid/search"
|
5
|
-
require "citygrid/reviews"
|
6
|
-
require "citygrid/offers"
|
7
|
-
require "citygrid/details"
|
8
|
-
require "citygrid/listing"
|
1
|
+
# Ruby 1.9.2 has YAML::ENGINE and will blow up if you don't define yamler
|
2
|
+
# Ruby 1.8.7 doesn't have YAML::ENGINE, this should take care of both cases
|
3
|
+
YAML::ENGINE.yamler= 'syck' if defined?(YAML::ENGINE)
|
9
4
|
|
10
5
|
class CityGrid
|
11
6
|
class << self
|
12
7
|
def publisher= code
|
13
|
-
|
8
|
+
@publisher = code
|
14
9
|
end
|
15
|
-
|
10
|
+
|
16
11
|
def publisher
|
17
|
-
raise PublisherNotConfigured if !defined?(
|
18
|
-
|
12
|
+
raise PublisherNotConfigured if !defined?(@publisher) || @publisher.nil?
|
13
|
+
@publisher
|
19
14
|
end
|
20
15
|
|
21
16
|
def search opts = {}
|
@@ -33,6 +28,72 @@ class CityGrid
|
|
33
28
|
def reviews opts
|
34
29
|
Reviews.new opts
|
35
30
|
end
|
31
|
+
|
32
|
+
def authenticate params
|
33
|
+
API::AdCenter::Authentication.login params
|
34
|
+
end
|
35
|
+
alias_method :login, :authenticate
|
36
|
+
|
37
|
+
# config info
|
38
|
+
def load_config file_path, env = nil
|
39
|
+
config = YAML.load_file(file_path)
|
40
|
+
|
41
|
+
defaults = config["defaults"]
|
42
|
+
|
43
|
+
default_hostname = "http://#{defaults["hostname"]}"
|
44
|
+
ssl_hostname = "https://#{defaults["ssl_hostname"]}"
|
45
|
+
|
46
|
+
config["endpoints"].each do |k, v|
|
47
|
+
# camelcase classname
|
48
|
+
classname = k.gsub(/(_(.))/) { $2.upcase}.gsub(/^(.)/) { $1.upcase }
|
49
|
+
klass = API::AdCenter.const_get(classname)
|
50
|
+
if v.is_a? String
|
51
|
+
endpoint = v.start_with?("/") ? v : "/#{v}"
|
52
|
+
klass.endpoint endpoint
|
53
|
+
klass.base_uri default_hostname
|
54
|
+
elsif v.is_a? Hash
|
55
|
+
hostname = v["hostname"] || (v["ssl"] ? ssl_hostname : default_hostname)
|
56
|
+
|
57
|
+
endpoint = v["endpoint"].start_with?("/") ? v["endpoint"] : "/#{v["endpoint"]}"
|
58
|
+
klass.endpoint endpoint
|
59
|
+
klass.base_uri hostname
|
60
|
+
else
|
61
|
+
# should not get here
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def config
|
67
|
+
raise EndpointsNotConfigured unless @config && !@config.nil?
|
68
|
+
@config
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_endpoints config_file
|
72
|
+
File.open config_file, "r" do |file|
|
73
|
+
while line = file.gets
|
74
|
+
api, endpoint = line.split("=").map{|x| x.chomp}
|
75
|
+
endpoint = "/#{endpoint}" unless endpoint.start_with?("/")
|
76
|
+
klass = CLASS_MAPPING[api]
|
77
|
+
next unless klass
|
78
|
+
|
79
|
+
klass.endpoint endpoint
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_env config_file
|
85
|
+
File.open config_file, "r" do |file|
|
86
|
+
while line = file.gets
|
87
|
+
api, host = line.split("=").map{|x| x.chomp}
|
88
|
+
host = "http://#{host}" unless host.start_with?("http")
|
89
|
+
klass = CLASS_MAPPING[api]
|
90
|
+
next unless klass
|
91
|
+
|
92
|
+
klass.base_uri host
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
36
97
|
end
|
37
98
|
|
38
99
|
# Errors
|
@@ -42,4 +103,48 @@ class CityGrid
|
|
42
103
|
super "Publisher hasn't been configured. Run 'CityGrid.publisher=<code>'"
|
43
104
|
end
|
44
105
|
end
|
106
|
+
|
107
|
+
class EndpointsNotConfigured < StandardError
|
108
|
+
def initialize
|
109
|
+
super "Endpoints haven't been configured. Run 'CityGrid.load_config'"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
require "citygrid/abstraction"
|
115
|
+
require "citygrid/api"
|
116
|
+
|
117
|
+
require "citygrid/search"
|
118
|
+
require "citygrid/reviews"
|
119
|
+
require "citygrid/offers"
|
120
|
+
require "citygrid/details"
|
121
|
+
require "citygrid/listing"
|
122
|
+
|
123
|
+
require "citygrid/api/response"
|
124
|
+
require "citygrid/api/ad_center"
|
125
|
+
require "citygrid/api/content"
|
126
|
+
|
127
|
+
require "request_ext"
|
128
|
+
|
129
|
+
class CityGrid
|
130
|
+
CLASS_MAPPING = {
|
131
|
+
"account" => CityGrid::API::AdCenter::Account,
|
132
|
+
"accountmanager" => CityGrid::API::AdCenter::AccountManager,
|
133
|
+
"adgroup" => CityGrid::API::AdCenter::AdGroup,
|
134
|
+
"adgroupad" => CityGrid::API::AdCenter::AdGroupAd,
|
135
|
+
"adgroupgeo" => CityGrid::API::AdCenter::AdGroupGeo,
|
136
|
+
"billing" => CityGrid::API::AdCenter::Billing,
|
137
|
+
"adgroupcriterion" => CityGrid::API::AdCenter::AdGroupCriterion,
|
138
|
+
"authentication" => CityGrid::API::AdCenter::Authentication,
|
139
|
+
"budget" => CityGrid::API::AdCenter::Budget,
|
140
|
+
"campaign" => CityGrid::API::AdCenter::Campaign,
|
141
|
+
"category" => CityGrid::API::AdCenter::Category,
|
142
|
+
"geolocation" => CityGrid::API::AdCenter::GeoLocation,
|
143
|
+
"mop" => CityGrid::API::AdCenter::MethodOfPayment,
|
144
|
+
"image" => CityGrid::API::AdCenter::Image,
|
145
|
+
"places" => CityGrid::API::AdCenter::Places,
|
146
|
+
"performance" => CityGrid::API::AdCenter::Performance,
|
147
|
+
# "reviews" => CityGrid::API::AdCenter::Reviews
|
148
|
+
"user" => CityGrid::API::AdCenter::User
|
149
|
+
}
|
45
150
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sinatra::Partials
|
2
|
+
def partial(template, *args)
|
3
|
+
template_array = template.to_s.split('/')
|
4
|
+
template = template_array[0..-2].join('/') + "/_#{template_array[-1]}"
|
5
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
6
|
+
options.merge!(:layout => false)
|
7
|
+
if collection = options.delete(:collection) then
|
8
|
+
collection.inject([]) do |buffer, member|
|
9
|
+
buffer << haml(:"#{template}", options.merge(:layout =>
|
10
|
+
false, :locals => {template_array[-1].to_sym => member}))
|
11
|
+
|
12
|
+
end.join("\n")
|
13
|
+
else
|
14
|
+
haml(:"#{template}", options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|