sensis 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +95 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +216 -0
- data/Rakefile +23 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/sensis.rb +320 -0
- data/lib/sensis/version.rb +3 -0
- data/sensis.gemspec +32 -0
- data/spec/dummy/Gemfile +7 -0
- data/spec/dummy/Gemfile.lock +90 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/javascripts/application.js +6 -0
- data/spec/dummy/app/assets/stylesheets/application.css +5 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +46 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +18 -0
- data/spec/dummy/config/environments/production.rb +52 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/sensis.yml.example +11 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/lib/search_spec.rb +33 -0
- data/spec/spec_helper.rb +24 -0
- data/uninstall.rb +1 -0
- metadata +246 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.8.7@sensis
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sensis (0.0.2)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
actionpack (3.1.1)
|
10
|
+
activemodel (= 3.1.1)
|
11
|
+
activesupport (= 3.1.1)
|
12
|
+
builder (~> 3.0.0)
|
13
|
+
erubis (~> 2.7.0)
|
14
|
+
i18n (~> 0.6)
|
15
|
+
rack (~> 1.3.2)
|
16
|
+
rack-cache (~> 1.1)
|
17
|
+
rack-mount (~> 0.8.2)
|
18
|
+
rack-test (~> 0.6.1)
|
19
|
+
sprockets (~> 2.0.2)
|
20
|
+
activemodel (3.1.1)
|
21
|
+
activesupport (= 3.1.1)
|
22
|
+
builder (~> 3.0.0)
|
23
|
+
i18n (~> 0.6)
|
24
|
+
activesupport (3.1.1)
|
25
|
+
multi_json (~> 1.0)
|
26
|
+
builder (3.0.0)
|
27
|
+
columnize (0.3.4)
|
28
|
+
diff-lcs (1.1.3)
|
29
|
+
erubis (2.7.0)
|
30
|
+
hike (1.2.1)
|
31
|
+
i18n (0.6.0)
|
32
|
+
json (1.6.1)
|
33
|
+
linecache (0.46)
|
34
|
+
rbx-require-relative (> 0.0.4)
|
35
|
+
multi_json (1.0.3)
|
36
|
+
nokogiri (1.5.0)
|
37
|
+
rack (1.3.5)
|
38
|
+
rack-cache (1.1)
|
39
|
+
rack (>= 0.4)
|
40
|
+
rack-mount (0.8.3)
|
41
|
+
rack (>= 1.0.0)
|
42
|
+
rack-ssl (1.3.2)
|
43
|
+
rack
|
44
|
+
rack-test (0.6.1)
|
45
|
+
rack (>= 1.0)
|
46
|
+
railties (3.1.1)
|
47
|
+
actionpack (= 3.1.1)
|
48
|
+
activesupport (= 3.1.1)
|
49
|
+
rack-ssl (~> 1.3.2)
|
50
|
+
rake (>= 0.8.7)
|
51
|
+
rdoc (~> 3.4)
|
52
|
+
thor (~> 0.14.6)
|
53
|
+
rake (0.9.2.2)
|
54
|
+
rbx-require-relative (0.0.5)
|
55
|
+
rcov (0.9.11)
|
56
|
+
rdoc (3.11)
|
57
|
+
json (~> 1.4)
|
58
|
+
rspec (2.7.0)
|
59
|
+
rspec-core (~> 2.7.0)
|
60
|
+
rspec-expectations (~> 2.7.0)
|
61
|
+
rspec-mocks (~> 2.7.0)
|
62
|
+
rspec-core (2.7.1)
|
63
|
+
rspec-expectations (2.7.0)
|
64
|
+
diff-lcs (~> 1.1.2)
|
65
|
+
rspec-mocks (2.7.0)
|
66
|
+
rspec-rails (2.7.0)
|
67
|
+
actionpack (~> 3.0)
|
68
|
+
activesupport (~> 3.0)
|
69
|
+
railties (~> 3.0)
|
70
|
+
rspec (~> 2.7.0)
|
71
|
+
ruby-debug (0.10.4)
|
72
|
+
columnize (>= 0.1)
|
73
|
+
ruby-debug-base (~> 0.10.4.0)
|
74
|
+
ruby-debug-base (0.10.4)
|
75
|
+
linecache (>= 0.3)
|
76
|
+
sprockets (2.0.3)
|
77
|
+
hike (~> 1.2)
|
78
|
+
rack (~> 1.0)
|
79
|
+
tilt (~> 1.1, != 1.3.0)
|
80
|
+
thor (0.14.6)
|
81
|
+
tilt (1.3.3)
|
82
|
+
tzinfo (0.3.31)
|
83
|
+
|
84
|
+
PLATFORMS
|
85
|
+
ruby
|
86
|
+
|
87
|
+
DEPENDENCIES
|
88
|
+
json
|
89
|
+
nokogiri
|
90
|
+
rcov
|
91
|
+
rspec-core
|
92
|
+
rspec-rails
|
93
|
+
ruby-debug
|
94
|
+
sensis!
|
95
|
+
tzinfo
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ben Wiseley wiseleyb@gmail.com
|
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.markdown
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
# Sensis Search
|
2
|
+
This is a pretty basic api wrapper for Sensis searching.
|
3
|
+
|
4
|
+
For more information on Sensis see their developer site: http://developers.sensis.com.au/
|
5
|
+
|
6
|
+
## Install
|
7
|
+
|
8
|
+
gem install sensis
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
You can get a free api key at http://developers.sensis.com.au/
|
12
|
+
|
13
|
+
Note - all methods (search, get_listing_by_id and report) all take an additional key: :env => "test" or "prod". This decides if the test endpoint or the production endpoint will be used. It defaults to "test". You can specify this in the config if you don't want to pass it.
|
14
|
+
|
15
|
+
All results can be accessed by their hash values or by method names... example:
|
16
|
+
|
17
|
+
res["code"] == res.code
|
18
|
+
res["results"].size == res.results.size
|
19
|
+
|
20
|
+
## Config
|
21
|
+
If you don't want to pass your api_key or endpoint env every time you can put it config/sensis.yml
|
22
|
+
|
23
|
+
development:
|
24
|
+
api_key: abcdefg
|
25
|
+
env: test
|
26
|
+
|
27
|
+
test:
|
28
|
+
api_key: abcdefg
|
29
|
+
env: test
|
30
|
+
|
31
|
+
production:
|
32
|
+
api_key: abcdefg
|
33
|
+
env: prod
|
34
|
+
|
35
|
+
### Search
|
36
|
+
|
37
|
+
res = Sensis.search(:key => "your api key", :query => "poker")
|
38
|
+
|
39
|
+
Or - if you are using the config...
|
40
|
+
|
41
|
+
res = Sensis.search(:query => "poker")
|
42
|
+
|
43
|
+
Sensis.search takes a hash of options defined here: http://developers.sensis.com.au/docs/endpoint_reference/Search
|
44
|
+
|
45
|
+
Sample Search result set: see http://developers.sensis.com.au/docs/endpoint_reference for more information
|
46
|
+
|
47
|
+
{
|
48
|
+
"results": [
|
49
|
+
{
|
50
|
+
"id": "999",
|
51
|
+
"name": "Bob's Hairdresser",
|
52
|
+
"categories": [
|
53
|
+
{
|
54
|
+
"name": "Hairdressers"
|
55
|
+
}
|
56
|
+
],
|
57
|
+
"primaryAddress" {
|
58
|
+
"addressLine": "123 Fitzroy Street",
|
59
|
+
...
|
60
|
+
}
|
61
|
+
...
|
62
|
+
}
|
63
|
+
...
|
64
|
+
],
|
65
|
+
...
|
66
|
+
"count": 20,
|
67
|
+
"totalResults": 19791,
|
68
|
+
"executedQuery": "hairdresser",
|
69
|
+
"originalQuery": "hairdresser",
|
70
|
+
"date": "2011-02-28T12:01:02.345+1000",
|
71
|
+
"time": 10,
|
72
|
+
"code": 200,
|
73
|
+
"message": "OK"
|
74
|
+
}
|
75
|
+
|
76
|
+
So - you could do something like:
|
77
|
+
|
78
|
+
res.results.first.name == res["results"][0]["name"]
|
79
|
+
|
80
|
+
#### Search paging
|
81
|
+
|
82
|
+
res = Sensis.search(:key => "your api key", :query => "poker")
|
83
|
+
pages = res.totalResults.to_i / 20
|
84
|
+
pages.times do |page|
|
85
|
+
res = Sensis.search(:key => "your api key", :query => "poker", :page => (page +1).to_s)
|
86
|
+
end
|
87
|
+
|
88
|
+
More on paging in the docs http://developers.sensis.com.au/docs/using_endpoints/Pagination
|
89
|
+
|
90
|
+
### Get Listing By ID
|
91
|
+
|
92
|
+
res = Sensis.get_listing_by_id(:key => "your api key", :query => "999")
|
93
|
+
|
94
|
+
Or - if you are using the config...
|
95
|
+
|
96
|
+
res = Sensis.get_listing_by_id(:query => "999")
|
97
|
+
|
98
|
+
Sample result set: see for more information
|
99
|
+
|
100
|
+
{
|
101
|
+
"results": [
|
102
|
+
{
|
103
|
+
"businessId": "999",
|
104
|
+
"businessName": "Hairdresser",
|
105
|
+
"categories": [
|
106
|
+
{
|
107
|
+
"name": "Hairdressers"
|
108
|
+
}
|
109
|
+
],
|
110
|
+
"primaryAddress": {
|
111
|
+
"addressLine": "123 Fitzroy Street",
|
112
|
+
},
|
113
|
+
...
|
114
|
+
}
|
115
|
+
],
|
116
|
+
"count": 1,
|
117
|
+
"totalResults": 1,
|
118
|
+
"executedQuery": "999",
|
119
|
+
"originalQuery": "999",
|
120
|
+
"date": "2011-02-28T12:01:02.345+1000",
|
121
|
+
"time": 10,
|
122
|
+
"code": 200,
|
123
|
+
"message": "OK"
|
124
|
+
}
|
125
|
+
|
126
|
+
### Report
|
127
|
+
|
128
|
+
res = Sensis.report(:key => "your api key", :userIp => "192.1.2.3", :userAgent => "Mozilla Firefox",
|
129
|
+
:userSessionId => "123467890",
|
130
|
+
:id => "VyY2UiOiJZRUxMT1ciLCJwcm9kdWN0SWQiOiIxMjM0IiwicHJvZHVjdFZlcnNpb24iOiI1Njc4In0")
|
131
|
+
|
132
|
+
Or - if you are using the config...
|
133
|
+
|
134
|
+
res = Sensis.report(:userIp => "192.1.2.3", :userAgent => "Mozilla Firefox",
|
135
|
+
:userSessionId => "123467890",
|
136
|
+
:id => "VyY2UiOiJZRUxMT1ciLCJwcm9kdWN0SWQiOiIxMjM0IiwicHJvZHVjdFZlcnNpb24iOiI1Njc4In0")
|
137
|
+
|
138
|
+
You can also include multiple ID's by passing an array
|
139
|
+
|
140
|
+
res = Sensis.report(:key => "your api key", :userIp => "192.1.2.3", :userAgent => "Mozilla Firefox",
|
141
|
+
:userSessionId => "123467890",
|
142
|
+
:id => ["1","2","3","4"])
|
143
|
+
|
144
|
+
|
145
|
+
Sample report result set: see http://developers.sensis.com.au/docs/endpoint_reference/Report for more information
|
146
|
+
|
147
|
+
{
|
148
|
+
"results": [
|
149
|
+
{
|
150
|
+
"id": "999",
|
151
|
+
"name": "Bob's Hairdresser",
|
152
|
+
"categories": [
|
153
|
+
{
|
154
|
+
"name": "Hairdressers"
|
155
|
+
}
|
156
|
+
],
|
157
|
+
"reportingId":"VyY2UiOiJZRUxMT1ciLCJwcm9kdWN0SWQiOiIx ⤶
|
158
|
+
MjM0IiwicHJvZHVjdFZlcnNpb24iOiI1Njc4In0",
|
159
|
+
...
|
160
|
+
},
|
161
|
+
{
|
162
|
+
"id": "1000",
|
163
|
+
"name": "Jill's Hairdresser",
|
164
|
+
"categories": [
|
165
|
+
{
|
166
|
+
"name": "Hairdressers"
|
167
|
+
}
|
168
|
+
],
|
169
|
+
"reportingId":"eyJib29rSWQiOiJTMDBXIiwibGlzdGluZ05hbW ⤶
|
170
|
+
UiOiJzdWJzY3JpYmVyTmFtZSIsInNvdXJjZSI6",
|
171
|
+
...
|
172
|
+
}
|
173
|
+
...
|
174
|
+
],
|
175
|
+
...
|
176
|
+
"count": 20,
|
177
|
+
"totalResults": 19791,
|
178
|
+
"executedQuery": "hairdresser",
|
179
|
+
"originalQuery": "hairdresser",
|
180
|
+
"date": "2011-02-28T12:01:02.345+1000",
|
181
|
+
"time": 10,
|
182
|
+
"code": 200,
|
183
|
+
"message": "OK"
|
184
|
+
}
|
185
|
+
|
186
|
+
## TODO
|
187
|
+
* add more tests
|
188
|
+
* add better examples for Get Listing By ID and Report. Haven't really used these yet.
|
189
|
+
|
190
|
+
## Testing
|
191
|
+
1. clone the code: git clone git://github.com/wiseleyb/Sensis.git
|
192
|
+
2. gem install bundler
|
193
|
+
3. bundle install
|
194
|
+
4. copy spec/dummy/config/sensis.yml.example to sensis.yml
|
195
|
+
5. fill in your api_key in sensis.yml
|
196
|
+
|
197
|
+
bundle exec rspec spec
|
198
|
+
|
199
|
+
## Console
|
200
|
+
If you're working on the gem you can muck around in console by
|
201
|
+
|
202
|
+
1. copy spec/dummy/config/sensis.yml.example to sensis.yml
|
203
|
+
2. fill in your api_key in sensis.yml
|
204
|
+
|
205
|
+
cd spec/dummy
|
206
|
+
bundle execute rails c
|
207
|
+
|
208
|
+
### Credits
|
209
|
+
|
210
|
+
Thank you to jdunwoody for some sample sensis code https://github.com/jdunwoody/SensisSearchApp/blob/master/lib/search_command.rb
|
211
|
+
|
212
|
+
Thank you to mikedemers for some cool json -> class method code (class ResponseData) https://github.com/mikedemers/rbing/blob/master/lib/rbing.rb
|
213
|
+
|
214
|
+
# Change log
|
215
|
+
0.0.1 - initial release
|
216
|
+
0.0.2 - adding sensis.yml support for storing api_keys and env setting. reverted to ruby -v 1.8.7
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the zemanta_fu plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the zemanta_fu plugin.'
|
17
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'ZemantaFu'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Include hook code here
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
data/lib/sensis.rb
ADDED
@@ -0,0 +1,320 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
module Sensis
|
6
|
+
|
7
|
+
def Sensis.config
|
8
|
+
if @config.nil?
|
9
|
+
config_file = "#{::Rails.root}/config/sensis.yml"
|
10
|
+
if File.exists?(config_file)
|
11
|
+
@config = YAML.load_file(config_file)
|
12
|
+
@api_key = @config[::Rails.env]["api_key"]
|
13
|
+
@env = @config[::Rails.env]["env"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
return @config
|
17
|
+
end
|
18
|
+
|
19
|
+
def Sensis.api_key
|
20
|
+
@api_key ||= Sensis.config[::Rails.env]["api_key"] unless Sensis.config.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def Sensis.env
|
24
|
+
@env ||= Sensis.config[::Rails.env]["env"] unless Sensis.config.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
# Search - http://developers.sensis.com.au/docs/endpoint_reference/Search
|
28
|
+
# options (from http://developers.sensis.com.au/docs/endpoint_reference/Search)
|
29
|
+
# key string API key (required) See Authenticating for details.
|
30
|
+
# query string What to search for (required unless location is given) See Search Query Tips for details.
|
31
|
+
# location string Location to search in (required unless query is given) See Location Tips for details.
|
32
|
+
# page number Page number to return. See Pagination for details.
|
33
|
+
# rows number Number of listings to return per page. See Pagination for details.
|
34
|
+
# sortBy string Listing sort order. See Sorting for details.
|
35
|
+
# sensitiveCategories boolean Filtering potentially unsafe content. See Filtering Unsafe Content for details.
|
36
|
+
# categoryId string Filter listings returned by category id See Category Filtering for details.
|
37
|
+
# postcode string Filter listings returned by postcode See Postcode Filtering for details.
|
38
|
+
# radius number Filter listings returned to those within the radius distance of the location. See Radius Filtering for details.
|
39
|
+
# suburb string Filter listings returned to those within the given suburb. Repeat the parameter to include multiple suburbs in the filter. See Suburb Filtering for details.
|
40
|
+
# state string Filter listings returned to those within the given state. Repeat the parameter to include multiple states in the filter. See State Filtering for details.
|
41
|
+
# boundingBox string Filter listings returned to those within a bounding box. See Bounding Box Filtering for details.
|
42
|
+
# content string Filter listings returned to only those with certain types of content. See Filtering by Content Type for details.
|
43
|
+
# productKeyword string Filter listings returned to only those containing certain product keywords. See Filtering by Product Keyword for details.
|
44
|
+
# mode string Default is "test" - values "test","prod" - decides which endpoint is used - test or production
|
45
|
+
# Example - Sensis.serch(:key => "key you got from developers.sensis.com.au", :query => "poker")
|
46
|
+
def Sensis.search(options = {})
|
47
|
+
options[:key] ||= Sensis.api_key
|
48
|
+
errors = []
|
49
|
+
errors << ":key (api key) is required" if options[:key].blank?
|
50
|
+
errors << ":query or :location is required" if options[:query].blank? && options[:location].blank?
|
51
|
+
raise errors.join("; ") unless errors.empty?
|
52
|
+
Sensis.execute("search", options)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Get Listing By ID - http://developers.sensis.com.au/docs/endpoint_reference/Get_by_Listing_ID
|
56
|
+
# options
|
57
|
+
# key string API key (required) See Authenticating for details.
|
58
|
+
# query string Unique ID of the listing to return (required) This is the id field of the listing. See Listing Schema for details.
|
59
|
+
# mode string Default is "test" - values "test","prod" - decides which endpoint is used - test or production
|
60
|
+
def Sensis.get_listing_by_id(options = {})
|
61
|
+
options[:key] ||= Sensis.api_key
|
62
|
+
errors = []
|
63
|
+
errors << ":key (api key) is required" if options[:key].blank?
|
64
|
+
errors << ":query is required" if options[:query].blank?
|
65
|
+
raise errors.join("; ") unless errors.empty?
|
66
|
+
Sensis.execute("getByListingId", options)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Report - http://developers.sensis.com.au/docs/endpoint_reference/Report
|
70
|
+
# key string API key (required) See Authenticating for details.
|
71
|
+
# userIp string IP address of user accessing your application (required) See Reporting Usage Events for details.
|
72
|
+
# id string or an array reportingId of listing associated with event (required) The reportingId field provided in each listing returned in a search response. Multiple id parameters can be added where the same event applies to each listing, except where the content parameter is specified. See Reporting Usage Events for details.
|
73
|
+
# userAgent string User agent of user accessing your application For example, from the user-agent HTTP header. See Reporting Usage Events for details.
|
74
|
+
# userSessionId string Session id of user accessing your application See Note below.
|
75
|
+
# content string Specific content to which the event applies (required) Only required for certain events. See Reporting Usage Events for details.
|
76
|
+
# mode string Default is "test" - values "test","prod" - decides which endpoint is used - test or production
|
77
|
+
def Sensis.report(options = {})
|
78
|
+
options[:key] ||= Sensis.api_key
|
79
|
+
errors = []
|
80
|
+
errors << ":key (api key) is required" if options[:key].blank?
|
81
|
+
errors << ":userIp is required" if options[:userIp].blank?
|
82
|
+
errors << ":id is required" if options[:id].blank?
|
83
|
+
raise errors.join("; ") unless errors.empty?
|
84
|
+
Sensis.execute("report", options)
|
85
|
+
end
|
86
|
+
|
87
|
+
def Sensis.execute(endpoint_type, options)
|
88
|
+
# location of the search endpoint
|
89
|
+
endpoint = Sensis.endpoint(endpoint_type, options)
|
90
|
+
|
91
|
+
# construct a URL with the query string, escaping any special characters.
|
92
|
+
url = "#{endpoint}?"
|
93
|
+
options.keys.each do |k|
|
94
|
+
if options[k].is_a?(Array)
|
95
|
+
options[k].each do |v|
|
96
|
+
url = "#{url}&#{k}=#{URI.encode(v)}"
|
97
|
+
end
|
98
|
+
else
|
99
|
+
url = "#{url}&#{k}=#{URI.encode(options[k].to_s)}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# call the endpoint, returning the HTTP response
|
104
|
+
response = Net::HTTP.get_response(URI.parse(url))
|
105
|
+
|
106
|
+
# raise an exception if not HTTP 200 (OK)
|
107
|
+
response.error! unless response.instance_of? Net::HTTPOK
|
108
|
+
|
109
|
+
# convert the response message in to a Hash object
|
110
|
+
result = JSON.parse(response.body)
|
111
|
+
|
112
|
+
res = ResponseData.new(result) if result
|
113
|
+
|
114
|
+
# ensure successful status code
|
115
|
+
case result["code"]
|
116
|
+
when 200 # success
|
117
|
+
return res
|
118
|
+
when 206 # spell-checker was run
|
119
|
+
puts "Note: #{result["message"]}"
|
120
|
+
return res
|
121
|
+
else
|
122
|
+
raise "API returned error: #{res.message}, code: #{result.code}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def Sensis.endpoint(endpoint_type, options)
|
127
|
+
env ||= options.delete(:env)
|
128
|
+
env ||= Sensis.env
|
129
|
+
env ||= "test"
|
130
|
+
endpoint = "http://api.sensis.com.au/ob-20110511/#{env}/#{endpoint_type}"
|
131
|
+
endpoint = "#{endpoint}/#{options[:eventName]}" if endpoint_type == "report"
|
132
|
+
return endpoint
|
133
|
+
end
|
134
|
+
|
135
|
+
# from https://github.com/mikedemers/rbing/blob/master/lib/rbing.rb
|
136
|
+
class ResponseData < Hash
|
137
|
+
private
|
138
|
+
def initialize(data={})
|
139
|
+
data.each_pair {|k,v| self[k.to_s] = deep_parse(v) }
|
140
|
+
end
|
141
|
+
def deep_parse(data)
|
142
|
+
case data
|
143
|
+
when Hash
|
144
|
+
self.class.new(data)
|
145
|
+
when Array
|
146
|
+
data.map {|v| deep_parse(v) }
|
147
|
+
else
|
148
|
+
data
|
149
|
+
end
|
150
|
+
end
|
151
|
+
def method_missing(*args)
|
152
|
+
name = args[0].to_s
|
153
|
+
return self[name] if has_key? name
|
154
|
+
camelname = name.split('_').map {|w| "#{w[0,1].upcase}#{w[1..-1]}" }.join("")
|
155
|
+
if has_key? camelname
|
156
|
+
self[camelname]
|
157
|
+
else
|
158
|
+
super *args
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
# def example()
|
167
|
+
# # perform a search for 'hairdresser'
|
168
|
+
# results = perform_search("hairdresser", "st kilda, vic")
|
169
|
+
#
|
170
|
+
# puts "Total results found: #{results["totalResults"]}"
|
171
|
+
#
|
172
|
+
# # the results member is an array containing each listings as a nested Hash object
|
173
|
+
# results["results"].each do |r|
|
174
|
+
# puts "#{r["name"]} (#{r["primaryAddress"]["addressLine"]})"
|
175
|
+
# end
|
176
|
+
# end
|
177
|
+
#
|
178
|
+
# # ZemantaFu
|
179
|
+
# require 'net/http'
|
180
|
+
# require 'rubygems'
|
181
|
+
# require 'xmlsimple'
|
182
|
+
#
|
183
|
+
# class ZemantaFu
|
184
|
+
#
|
185
|
+
# # refer to http://developer.zemanta.com/docs/suggest/ for valid options
|
186
|
+
# def self.search(text, options = {})
|
187
|
+
# # tags - keywords
|
188
|
+
# # in-text links
|
189
|
+
# # categories
|
190
|
+
#
|
191
|
+
# options[:method] ||= "zemanta.suggest"
|
192
|
+
# options[:format] ||= "xml"
|
193
|
+
# options[:return_categories] ||= "dmoz"
|
194
|
+
# options[:api_key] ||= "o26uvljcvr6q9l0zf155difg"
|
195
|
+
# # options[:return_images] ||= 0
|
196
|
+
# options[:markup_limit] ||= 1000
|
197
|
+
# options[:articles_limit] ||= 1000
|
198
|
+
#
|
199
|
+
# options[:text] = text
|
200
|
+
#
|
201
|
+
# [:api_key].each do |k|
|
202
|
+
# raise "Missing required key :#{k} in options." unless options.has_key?(k)
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# gateway = 'http://api.zemanta.com/services/rest/0.0/'
|
206
|
+
# res = Net::HTTP.post_form(URI.parse(gateway), options.stringify_keys)
|
207
|
+
# data = XmlSimple.xml_in(res.body)
|
208
|
+
# res = ResponseData.new(data)
|
209
|
+
#
|
210
|
+
# # clean up top level arrays so that we can do
|
211
|
+
# # search("poker").articles
|
212
|
+
# # instead of
|
213
|
+
# # search("poker"").articles[0].article
|
214
|
+
# res.keys.each do |k|
|
215
|
+
# ks = k.singularize
|
216
|
+
# if res[k][0] && res[k][0].is_a?(Hash) && res[k][0].keys.include?(ks)
|
217
|
+
# res[k] = res[k][0][ks]
|
218
|
+
# else
|
219
|
+
# res[k] = res[k][0]
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
# # ensure there's something there for everthing
|
223
|
+
# ["articles", "images", "keywords", "categories"].each do |k|
|
224
|
+
# res[k] ||= []
|
225
|
+
# end
|
226
|
+
# # fix markup section
|
227
|
+
# if res["markup"]["links"] == [{}]
|
228
|
+
# res["markup"]["links"] = []
|
229
|
+
# else
|
230
|
+
# res["markup"]["links"] = res.markup.links.first.link
|
231
|
+
# res["markup"]["links"].each_with_index do |link, index|
|
232
|
+
# res["markup"]["links"][index]["targets"] = res["markup"]["links"][index]["target"]
|
233
|
+
# end
|
234
|
+
# end
|
235
|
+
# return res
|
236
|
+
# end
|
237
|
+
#
|
238
|
+
# # ResponseData modified from the rbing project https://raw.github.com/mikedemers/rbing/master/lib/rbing.rb
|
239
|
+
# class ResponseData < Hash
|
240
|
+
#
|
241
|
+
# def save(filename)
|
242
|
+
# File.open(filename, 'w') do |out|
|
243
|
+
# YAML.dump(self, out)
|
244
|
+
# end
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# private
|
248
|
+
#
|
249
|
+
# def initialize(data={})
|
250
|
+
# data.each_pair {|k,v| self[k.to_s] = deep_parse(v) }
|
251
|
+
# end
|
252
|
+
#
|
253
|
+
# def deep_parse(data)
|
254
|
+
# case data
|
255
|
+
# when Hash
|
256
|
+
# self.class.new(data)
|
257
|
+
# when Array
|
258
|
+
# data.map {|v| deep_parse(v) }
|
259
|
+
# else
|
260
|
+
# data
|
261
|
+
# end
|
262
|
+
# end
|
263
|
+
#
|
264
|
+
# def method_missing(*args)
|
265
|
+
# name = args[0].to_s
|
266
|
+
# res = nil
|
267
|
+
# if has_key? name
|
268
|
+
# res = self[name]
|
269
|
+
# else
|
270
|
+
# camelname = name.split('_').map {|w| "#{w[0,1].upcase}#{w[1..-1]}" }.join("")
|
271
|
+
# if has_key? camelname
|
272
|
+
# res = self[camelname]
|
273
|
+
# else
|
274
|
+
# super *args
|
275
|
+
# end
|
276
|
+
# end
|
277
|
+
# if res.nil?
|
278
|
+
# super *args
|
279
|
+
# else
|
280
|
+
# # Zemanta returns all final values as arrays... get rid of this so, for example
|
281
|
+
# # res.status = "ok" and not ["ok"]
|
282
|
+
# if res.is_a?(Array) && res.size == 1 && res.first.is_a?(String) == true
|
283
|
+
# return res.first
|
284
|
+
# else
|
285
|
+
# return res
|
286
|
+
# end
|
287
|
+
# end
|
288
|
+
# end
|
289
|
+
#
|
290
|
+
# end
|
291
|
+
#
|
292
|
+
# #
|
293
|
+
# class Parameters
|
294
|
+
# OPTION_KEYS = [:parameter, :description, :required, :possible_values, :default_value]
|
295
|
+
# OPTIONS = [
|
296
|
+
# [:method, "Method on the server", true, "zemanta.suggest", "zemanta.suggest"],
|
297
|
+
# [:api_key, "Your API key", true, "string", nil],
|
298
|
+
# [:text, "Input text (clear text or HTML)", true, "string", nil],
|
299
|
+
# [:format, "requested output format", true, ["xml", "json", "wnjson", "rdfxml"], "xml"],
|
300
|
+
# [:return_rdf_links, "return URIs of Linking Open Data entities", false, [0, 1], nil],
|
301
|
+
# [:return_categories, "categorize into specified categorization scheme", false, ["dmoz","partner ID"], "dmoz"],
|
302
|
+
# [:return_images, "return related images (default is yes) This can cause dramatic performance improvements", false, [0, 1], "yes"],
|
303
|
+
# [:return_keywords, "return keywords (default is yes) This can affect performance slightly positively", false, [0, 1], "yes"],
|
304
|
+
# [:emphasis, %(terms to "emphasise", even when not present in text. All related articles are then required to have this term.), false, "string", nil],
|
305
|
+
# [:text_title, "[NEW since August 2010] Title of the text you are sending. Helps the text understanding algorithm.", false, "string", nil],
|
306
|
+
# [:personal_scope, "return only personalized related articles and images", false, [0, 1], nil],
|
307
|
+
# [:markup_limit, "Number of in-text links to return (default: depending on the number of input words, 1 per each 10 words, and it maxes out at 10)", false, "number", 10],
|
308
|
+
# [:images_limit, "Number of images to return (default:24)", false, "number", 24],
|
309
|
+
# [:articles_limit, "Number of articles to return (default:10)", false, "number", 10],
|
310
|
+
# [:articles_max_age_days, "Maximum age of returned articles (default: no limit)", false, "number", nil],
|
311
|
+
# [:articles_highlight, "[NEW since August 2010] Should a highlighted search snippet for each article be returned, where available (default: no)", false, "number", 0],
|
312
|
+
# [:image_max_w, "Maximum image width (default: 300)", false, "number", 300],
|
313
|
+
# [:image_max_h, "Maximum image height (default: 300)", false, "number", 300],
|
314
|
+
# [:sourcefeed_ids, "ID for personalized related articles", false, nil],
|
315
|
+
# [:flickr_user_id, "flickr ID of the user", false, nil],
|
316
|
+
# [:pixie, "the chosen Zemanta signature icon", false, nil]
|
317
|
+
# ]
|
318
|
+
# end
|
319
|
+
#
|
320
|
+
# end
|