upcoming-events 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Wynn Netherland
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,18 @@
1
+ # upcoming-events
2
+
3
+ Ruby wrapper for the Yahoo! Upcoming Events API.
4
+
5
+ ## Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ ## Copyright
17
+
18
+ Copyright (c) 2009 Wynn Netherland. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "upcoming-events"
8
+ gem.summary = %Q{Ruby wrapper for the Yahoo! Upcoming API}
9
+ gem.description = %Q{Find cool events and things to do.}
10
+ gem.email = "wynn@squeejee.com"
11
+ gem.homepage = "http://github.com/pengwynn/upcoming-events"
12
+ gem.authors = ["Wynn Netherland"]
13
+ gem.rubyforge_project = "upcoming-events"
14
+ gem.files = FileList["[A-Z]*", "{examples,lib,test}/**/*"]
15
+
16
+ gem.add_dependency('mash', '0.0.3')
17
+ gem.add_dependency('httparty', '0.4.3')
18
+
19
+ gem.add_development_dependency('thoughtbot-shoulda')
20
+ gem.add_development_dependency('jeremymcanally-matchy')
21
+ gem.add_development_dependency('mocha')
22
+ gem.add_development_dependency('fakeweb')
23
+ gem.add_development_dependency('mash')
24
+ end
25
+
26
+ rescue LoadError
27
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
28
+ end
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/*_test.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ begin
38
+ require 'rcov/rcovtask'
39
+ Rcov::RcovTask.new do |test|
40
+ test.libs << 'test'
41
+ test.pattern = 'test/**/*_test.rb'
42
+ test.verbose = true
43
+ end
44
+ rescue LoadError
45
+ task :rcov do
46
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
47
+ end
48
+ end
49
+
50
+
51
+
52
+
53
+ task :default => :test
54
+
55
+ require 'rake/rdoctask'
56
+ Rake::RDocTask.new do |rdoc|
57
+ if File.exist?('VERSION.yml')
58
+ config = YAML.load(File.read('VERSION.yml'))
59
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
60
+ else
61
+ version = ""
62
+ end
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "upcoming-events #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
69
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 1
3
+ :major: 0
4
+ :minor: 0
data/lib/upcoming.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+
3
+ gem 'mash', '~> 0.0.3'
4
+ require 'mash'
5
+
6
+ gem 'httparty', '~> 0.4.3'
7
+ require 'httparty'
8
+
9
+ module Upcoming
10
+ class APIKeyNotSet < StandardError; end
11
+ module Defaults
12
+ def self.included(base)
13
+ base.send :include, HTTParty
14
+ base.send(:base_uri, 'upcoming.yahooapis.com/services/rest')
15
+ base.send(:format, :json)
16
+ end
17
+ end
18
+
19
+ def self.api_key=(value)
20
+ @api_key = value
21
+ end
22
+
23
+ def self.api_key
24
+ @api_key
25
+ end
26
+
27
+ def self.default_options
28
+ raise Upcoming::APIKeyNotSet.new("Please get your API key from http://upcoming.yahoo.com/services/api/keygen.php") if self.api_key.blank?
29
+ {:api_key => self.api_key, :format => 'json'}
30
+ end
31
+ end
32
+
33
+ directory = File.expand_path(File.dirname(__FILE__))
34
+ require File.join(directory, 'upcoming', 'auth')
35
+ require File.join(directory, 'upcoming', 'user')
36
+ require File.join(directory, 'upcoming', 'group')
37
+ require File.join(directory, 'upcoming', 'metro')
38
+ require File.join(directory, 'upcoming', 'event')
39
+ require File.join(directory, 'upcoming', 'category')
40
+ require File.join(directory, 'upcoming', 'country')
41
+ require File.join(directory, 'upcoming', 'venue')
42
+ require File.join(directory, 'upcoming', 'watchlist')
43
+ require File.join(directory, 'upcoming', 'state')
@@ -0,0 +1,39 @@
1
+ module Upcoming
2
+ class Auth
3
+ include Upcoming::Defaults
4
+
5
+ # Retrieve a token from the site, after the user has given your app an authentication Frob
6
+ #
7
+ # +frob+ (Required)
8
+ # The frob passed back to your application.
9
+ #
10
+ def self.token(frob)
11
+ Mash.new(self.get('/', :query => {:method => 'auth.getToken', :frob => frob}.merge(Upcoming.default_options))).rsp.token.first
12
+ end
13
+
14
+ # Retrieve a full token from Upcoming, from just the token code.
15
+ # This method should also be called on saved tokens before proceeding to access user data,
16
+ # in order to verify that the token has not expired and is valid.
17
+ #
18
+ # +token+ (Required)
19
+ # The token code to check.
20
+ #
21
+ #
22
+ # Step 1: Set up your callback url: http://upcoming.yahoo.com/services/api/keygen.php
23
+ #
24
+ # Step 2: Call http://upcoming.yahoo.com/services/auth/?api_key=Your API Key
25
+ #
26
+ # Step 3: Catch the frob querystring parameter on your callback page and pass to Auth.token
27
+ #
28
+ def self.check_token(token)
29
+ token = Upcoming::Auth.token_code(token)
30
+ Mash.new(self.get('/', :query => {:method => 'auth.checkToken', :token => token}.merge(Upcoming.default_options))).rsp.token.first
31
+ end
32
+
33
+ # Extracts the token code from a token hash
34
+ #
35
+ def self.token_code(token)
36
+ token.is_a?(Hash) ? token['token'] : token
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ module Upcoming
2
+ class Category
3
+ include Upcoming::Defaults
4
+
5
+ # Retrieve a list of valid event categories.
6
+ #
7
+ def self.list
8
+ Mash.new(self.get('/', :query => {:method => 'category.getList'}.merge(Upcoming.default_options))).rsp.category
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Upcoming
2
+ class Country
3
+ include Upcoming::Defaults
4
+
5
+ # +country_id+ (Required)
6
+ # The country_id number of the country to look within. Country ID's are referred to within other API methods, such as metro.getStateList and state.getInfo. To run getInfo on multiple countries, simply pass an array or a comma-separated list of country_id numbers.
7
+ #
8
+ def self.info(country_id)
9
+ country_id = country_id.join(',') if country_id.is_a?(Array)
10
+ Mash.new(self.get('/', :query => {:method => 'country.getInfo', :country_id => country_id}.merge(Upcoming.default_options))).rsp.country
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,378 @@
1
+ module Upcoming
2
+ class Event
3
+ include Upcoming::Defaults
4
+
5
+ # Retrieve event information and metadata for public and private events.
6
+ #
7
+ # +event_id+ (Required)
8
+ # <em>The id number of the event. You can also pass multiple event_id's as an array or separated by commas to getInfo on multiple events.</em>
9
+ #
10
+ # +token+ (Optional)
11
+ # <em>An authentication token. Pass to see even private events.</em>
12
+ #
13
+ def self.info(event_id, token=nil)
14
+ token = token['token'] if token and token['token']
15
+ event_id = event_id.join(',') if event_id.is_a?(Array)
16
+ query = {:method => 'event.getInfo', :event_id => event_id}
17
+ query.merge!(:token => token) unless token.blank?
18
+ format :json
19
+ Mash.new(self.get('/', :query => query.merge(Upcoming.default_options))).rsp.event
20
+ end
21
+
22
+ # Add a new event to the database. This method requires authentication.
23
+ #
24
+ # +token+ (Required)
25
+ # <em>An authentication token. </em>
26
+ #
27
+ # +name+ (Required)
28
+ # <em>The name of the event.</em>
29
+ #
30
+ # +venue_id+ (Numeric, Required)
31
+ # <em>The venue_id of the event. To get a venue_id, try the venue.* series of functions.</em>
32
+ #
33
+ # +category_id+ (Numeric, Required)
34
+ # <em>The category_id of the event. To get a category_id, try the category.* series of functions.</em>
35
+ #
36
+ # +start_date+ (YYYY-MM-DD, Required)
37
+ # <em>The start date of the event, formatted as YYYY-MM-DD.</em>
38
+ #
39
+ # +end_date+ (YYYY-MM-DD, Optional)
40
+ # <em>The end date of the event, formatted as YYYY-MM-DD.</em>
41
+ #
42
+ # +start_time+ (HH:MM:SS, Optional)
43
+ # <em>The start time of the event, formatted as HH:MM:SS.</em>
44
+ #
45
+ # +end_time+ (HH:MM:SS, Optional)
46
+ # <em>The end time of the event, formatted as HH:MM:SS.</em>
47
+ #
48
+ # +description+ (Optional)
49
+ # <em>A textual description of the event.</em>
50
+ #
51
+ # +url+ (Optional)
52
+ # <em>The website URL for the event.</em>
53
+ #
54
+ # +personal+ (1 or 0, Optional, Defaults to 0)
55
+ # <em>A flag indicating whether the event should be public (0), or shown only to your friends (1).</em>
56
+ #
57
+ # +selfpromotion+ (1 or 0, Optional, Defaults to 0)
58
+ # <em>A flag indicating whether the event should be marked as a normal event (0), or as a self-promotional event (1).</em>
59
+ #
60
+ # +ticket_url+ (Optional)
61
+ # <em>The website URL for purchasing tickets to the event.</em>
62
+ #
63
+ # +ticket_price+ (Optional)
64
+ # <em>The price of a ticket to the event.</em>
65
+ #
66
+ # +ticket_free+ (1 or 0, Optional, Defaults to 0)
67
+ # <em>A flag indicating if the event is free (1) or not (0).</em>
68
+ #
69
+ def self.add(info, token)
70
+ token = Upcoming::Auth.token_code(token)
71
+ format :xml
72
+ body = {:method => 'event.add'}
73
+ body.merge!({:token => token})
74
+ body.merge!(info)
75
+ body.merge!(Upcoming.default_options)
76
+ body.merge!({:format => 'xml'})
77
+ event = Mash.new(self.post('/', :body => body)).rsp.event
78
+ self.info(event.id, token).first
79
+ end
80
+
81
+ # Edit an event in the database. Missing parameters will clear out their corresponding values in the event. You must authenticate as the user who added the event to do this. This method requires authentication.
82
+ #
83
+ # +token+ (Required)
84
+ # An authentication token.
85
+ #
86
+ # +event_id+ (Required)
87
+ # The id of the event to edit.
88
+ #
89
+ # +name+ (Required)
90
+ # The name of the event.
91
+ #
92
+ # +venue_id+ (Numeric, Required)
93
+ # The venue_id of the event. To get a venue_id, try the venue.* series of functions.
94
+ #
95
+ # +category_id+ (Numeric, Required)
96
+ # The category_id of the event. To get a category_id, try the category.* series of functions.
97
+ #
98
+ # +start_date+ (YYYY-MM-DD, Required)
99
+ # The start date of the event, formatted as YYYY-MM-DD.
100
+ #
101
+ # +end_date+ (YYYY-MM-DD, Optional)
102
+ # The end date of the event, formatted as YYYY-MM-DD.
103
+ #
104
+ # +start_time+ (HH:MM:SS, Optional)
105
+ # The start time of the event, formatted as HH:MM:SS.
106
+ #
107
+ # +end_time+ (HH:MM:SS, Optional)
108
+ # The end time of the event, formatted as HH:MM:SS.
109
+ #
110
+ # +description+ (Optional)
111
+ # A textual description of the event.
112
+ #
113
+ # +url+ (Optional)
114
+ # The website URL for the event.
115
+ #
116
+ # +personal+ (1 or 0, Optional, Defaults to 0)
117
+ # A flag indicating whether the event should be public (0), or shown only to your friends (1).
118
+ #
119
+ # +selfpromotion+ (1 or 0, Optional, Defaults to 0)
120
+ # A flag indicating whether the event should be marked as a normal event (0), or as a self-promotional event (1).
121
+ #
122
+ # +ticket_url+ (Optional)
123
+ # The website URL for purchasing tickets to the event.
124
+ #
125
+ # +ticket_price+ (Optional)
126
+ # The price of a ticket to the event.
127
+ #
128
+ # +ticket_free+ (1 or 0, Optional, Defaults to 0)
129
+ # A flag indicating if the event is free (1) or not (0).
130
+ #
131
+ def self.edit(event, token)
132
+ token = Upcoming::Auth.token_code(token)
133
+ format :xml
134
+ body = {:method => 'event.edit'}
135
+ body.merge!({:token => token})
136
+ body.merge!(event)
137
+ body.merge!(Upcoming.default_options)
138
+ body.merge!({:format => 'xml'})
139
+ event = Mash.new(self.post('/', :body => body)).rsp.event
140
+ self.info(event.id, token).first
141
+ end
142
+
143
+ # Add/Replace the user's current tags on an event. This method expects to receive a string with all the tags the user wishes to have on the object. It will replace the current set of user's tags on the event with the new list. This method requires authentication.
144
+ #
145
+ # +token+ (Required)
146
+ # An authentication token.
147
+ #
148
+ # +event_id+ (Numeric, Required)
149
+ # The event_id of the event. To get a event_id, try the event.search function.
150
+ #
151
+ # +tags+ (String, Required)
152
+ # A space-separated list of tags. Surround multi-word tags with quotes.
153
+ #
154
+ #
155
+ def self.add_tags(event_id, token, tags)
156
+ token = Upcoming::Auth.token_code(token)
157
+ format :xml
158
+ body = {:method => 'event.addTags'}
159
+ body.merge!({:token => token})
160
+ tag_list = tags.map{|t| "\"#{t}\""}.join(' ')
161
+ body.merge!({:event_id => event_id, :tags => tag_list})
162
+ body.merge!(Upcoming.default_options)
163
+ body.merge!({:format => 'xml'})
164
+ event = Mash.new(self.post('/', :body => body)).rsp.event
165
+ self.info(event.id, token).first
166
+ end
167
+
168
+ # Remove a single tag from an event. This method requires authentication.
169
+ #
170
+ #
171
+ # +token+ (Required)
172
+ # An authentication token.
173
+ #
174
+ # +event_id+ (Numeric, Required)
175
+ # The event_id of the event. To get a event_id, try the event.search function.
176
+ #
177
+ # +tag+ (String, Required)
178
+ # A single "raw" tag to remove. A raw tag is the original string provided to tag the object with that also appear in the Event Detail page on Upcoming. These are not the normalized form used for searches, or returned via the API event.getInfo method. Note: This might mean that you need to keep track of tags added by users in your application.
179
+ #
180
+ def self.remove_tag(event_id, token, tag)
181
+ token = Upcoming::Auth.token_code(token)
182
+ format :xml
183
+ body = {:method => 'event.removeTag'}
184
+ body.merge!({:token => token})
185
+ body.merge!({:event_id => event_id, :tag => tag})
186
+ body.merge!(Upcoming.default_options)
187
+ body.merge!({:format => 'xml'})
188
+ event = Mash.new(self.post('/', :body => body)).rsp.event
189
+ self.info(event.id, token).first
190
+ end
191
+
192
+ # Search Upcoming for public events by multiple facets.
193
+ # If optional authentication is provided, event.search also searches private events.
194
+ #
195
+ # +search_text+ (Optional)
196
+ # The search terms to be used to look for events. To collect all events with other filters applied, do not pass a search_text.
197
+ #
198
+ # +location+ (Optional)
199
+ # Only for use in proximity search within the US, the location parameter, if provided, will attempt to restrict search results to areas near that location. This may either be formatted as a comma-separated latitude and longitude (i.e. "37.821, -111.179"), or a fulltext location similar to the following:
200
+ #
201
+ # * City, State
202
+ # * City, State, Zip
203
+ # * Zip
204
+ # * Street, City, State
205
+ # * Street, City, State, Zip
206
+ # * Street, Zip
207
+ #
208
+ # Any search that uses the location parameter will add the additional data elements "distance" and "distance_units" to the result set.
209
+ #
210
+ # +radius+ (mi) (Optional, Default: 50mi., Max: 100mi.)
211
+ # If location is specified, then event.search will look for a radius parameter. Otherwise, it will use 50mi. as the radius of the search.
212
+ #
213
+ # +place_id+ (Optional)
214
+ # An string ID like 'kH8dL0ubBZrvX_YZ', denoting a specific named geographical area. These can be seen in Upcoming 'place' URLs such as <http://upcoming.yahoo.com/place/kH8dLOubBZRvX_YZ>, denoting the city of San Francisco, California, USA.
215
+ # Using a Place ID yields events from the exact boundaries of the place, and is not affected by the radius parameter. Eventually, Place IDs will replace the country_id, state_id, and metro_id parameters used below. However, those parameters are not deprecated yet.
216
+ #
217
+ # +country_id+ (Numeric, Optional)
218
+ # The country_id of the event, used to narrow down the responses. To get a country_id, try the metro.getCountryList function.
219
+ #
220
+ # +state_id+ (Numeric, Optional)
221
+ # The state_id of the event, used to narrow down the responses. To get a state_id, try the metro.getStateList function.
222
+ #
223
+ # +metro_id+ (Numeric, Optional)
224
+ # The metro_id of the event, used to narrow down the responses. To get a metro_id, try the metro.getList function.
225
+ #
226
+ # +venue_id+ (Numeric, Optional)
227
+ # A venue_id to search within. To get a venue_id, try the venue.* series of functions.
228
+ #
229
+ # +woeid+ (Optional)
230
+ # The WOEID of the place to which search results will be restricted.
231
+ #
232
+ # +category_id+ (CSV Numeric, Optional)
233
+ # A category_id integer or comma-separated list of category ids to search within. To get a category_id, try the category.getList function.
234
+ #
235
+ # +min_date+ (YYYY-MM-DD, Optional)
236
+ # Search all events after this date, formatted as YYYY-MM-DD.
237
+ #
238
+ # +max_date+ (YYYY-MM-DD, Optional)
239
+ # Search all events before this date, formatted as YYYY-MM-DD.
240
+ #
241
+ # +tags+ (Optional)
242
+ # A comma-separated list of tags. Events that have been tagged with any of the tags passed will be returned. 20 tags max.
243
+ #
244
+ # +per_page+ (Numeric, Optional, Default = 100)
245
+ # Number of results to return per page. Max is 100 per page.
246
+ #
247
+ # +page+ (Numeric, Optional, Default = 1)
248
+ # The page number of results to return.
249
+ #
250
+ # +sort+ (String, Optional, Default = start-date-asc) The field and direction on which to sort the results. Distance sorts must ONLY be used if location is specified.
251
+ # Meaningful values:
252
+ #
253
+ # * - distance-asc (Distance from provided location, ascending)
254
+ # * - name-asc (Event name, descending alphabetically)
255
+ # * - name-desc (Event name, ascending alphabetically)
256
+ # * - start-date-asc (Event's start date, in chronological order)
257
+ # * - start-date-desc (Event's start date, in reverse chronological order)
258
+ # * - posted-date-asc (The date the event was added to Upcoming, in chronological order)
259
+ # * - posted-date-desc (The date the event was added to Upcoming, in reverse chronological order)
260
+ #
261
+ #
262
+ #
263
+ # +backfill+ (String, Optional)
264
+ # If the first page of results returned has fewer than per_page results, try expanding the search.
265
+ # Meaningful values:
266
+ #
267
+ # * - later (Remove any limits on maximum starting date)
268
+ # * - further (Double the existing search radius, up to 200 miles)
269
+ #
270
+ #
271
+ #
272
+ # +variety+ (Boolean, Optional)
273
+ # Attempt to provide more varied results. Currently, this is implemented as not showing more than one event of each category. This will greatly reduce the amount of results returned. This feature is intended for situations where you want to show a great diversity of results in a small space.
274
+ # Meaningful values:
275
+ #
276
+ # * - 1 (that is, use parameter in URL as 'variety=1')
277
+ #
278
+ #
279
+ #
280
+ # +rollup+ (String, Optional)
281
+ # Used to display all future events of an event. By default only the last event of an event is displayed. This option provides the mechanism to override that behavior.
282
+ # Meaningful values:
283
+ #
284
+ # * - none (Display all future events of an event)
285
+ #
286
+ #
287
+ #
288
+ # +token+ (Optional)
289
+ # An authentication token.
290
+ #
291
+ def self.search(options={})
292
+ Mash.new(self.get('/', :query => {:method => 'event.search'}.merge(options).merge(Upcoming.default_options))).rsp.event
293
+ end
294
+
295
+ # Get a watchlist for an event. You must pass authentication parameters for this function.
296
+ # You will only be shown your own private events plus those of people who have marked you as a friend.
297
+ # Returns user nodes for each user on the watchlist. Returns either status="attend" or status="watch"
298
+ #
299
+ # +token+ (Required)
300
+ # An authentication token.
301
+ #
302
+ # +event_id+ (Required)
303
+ # The id of the event.
304
+ #
305
+ def self.watch_list(event_id, token)
306
+ query = {:method => 'event.getWatchList', :token => token, :event_id => event_id }
307
+ Mash.new(self.get('/', :query => query.merge(options).merge(Upcoming.default_options))).rsp.user
308
+ end
309
+
310
+ # For a given event_id, retrieve group information and metadata for
311
+ # public and private groups that include the event in their group calendar.
312
+ #
313
+ # +event_id+ (Required)
314
+ # The id number of the event.
315
+ #
316
+ # +token+ (Optional)
317
+ # An authentication token. Pass to see even private groups.
318
+ #
319
+ def self.groups(event_id, token)
320
+ query = {:method => 'event.getGroups', :token => token, :event_id => event_id }
321
+ Mash.new(self.get('/', :query => query.merge(options).merge(Upcoming.default_options))).rsp.group
322
+
323
+ end
324
+
325
+ # Search Upcoming for featured or popular events in a specified place
326
+ #
327
+ # +location+ (Optional)
328
+ # Only for use in proximity search within the US, the location parameter, if provided, will attempt to restrict search results to areas near that location. This may either be formatted as a comma-separated latitude and longitude (i.e. "37.821, -111.179"), or a fulltext location similar to the following:
329
+ #
330
+ # * City, State
331
+ # * City, State, Zip
332
+ # * Zip
333
+ # * Street, City, State
334
+ # * Street, City, State, Zip
335
+ # * Street, Zip
336
+ #
337
+ # Any search that uses the location parameter will add the additional data elements "distance" and "distance_units" to the result set.
338
+ #
339
+ # +radius+ (mi) (Optional, Default: 50mi., Max: 100mi.)
340
+ # If location is specified, then event.search will look for a radius parameter. Otherwise, it will use 50mi. as the radius of the search.
341
+ #
342
+ # +place_id+ (Optional)
343
+ # An string ID like 'kH8dL0ubBZrvX_YZ', denoting a specific named geographical area. These can be seen in Upcoming 'place' URLs such as <http://upcoming.yahoo.com/place/kH8dLOubBZRvX_YZ>, denoting the city of San Francisco, California, USA.
344
+ # Using a Place ID yields events from the exact boundaries of the place, and is not affected by the radius parameter. Eventually, Place IDs will replace the country_id, state_id, and metro_id parameters used below. However, those parameters are not deprecated yet.
345
+ #
346
+ # +country_id+ (Numeric, Optional)
347
+ # The country_id of the event, used to narrow down the responses. To get a country_id, try the metro.getCountryList function.
348
+ #
349
+ # +state_id+ (Numeric, Optional)
350
+ # The state_id of the event, used to narrow down the responses. To get a state_id, try the metro.getStateList function.
351
+ #
352
+ # +metro_id+ (Numeric, Optional)
353
+ # The metro_id of the event, used to narrow down the responses. To get a metro_id, try the metro.getList function.
354
+ #
355
+ # +woeid+ (Optional)
356
+ # The WOEID of the place to which search results will be restricted.
357
+ #
358
+ # +per_page+ (Numeric, Optional, Default = 10)
359
+ # Number of results to return per page. Max is 10 per page.
360
+ #
361
+ # +sort+ (String, Optional) The field and direction on which to sort the results.
362
+ # Meaningful values:
363
+ #
364
+ # * - score-asc (Relevance ascending)
365
+ # * - score-desc (Relevance descending)
366
+ #
367
+ # +filter+ (String, Optional, Default = popular)
368
+ # Use this to filter the search results to get the best type of events in the given place.
369
+ # Meaningful values:
370
+ #
371
+ # * - popular (Retrieve the events in my area that others in my area find interesting)
372
+ # * - featured (Retrieve the events in my area that look interesting)
373
+ #
374
+ def self.best_in_place(query={})
375
+ Mash.new(self.get('/', :query => {:method => 'event.getBestInPlace'}.merge(options).merge(Upcoming.default_options))).rsp.event
376
+ end
377
+ end
378
+ end