Active 0.0.42 → 0.1.7
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/.gitignore +6 -0
- data/.irbrc +21 -0
- data/.rspec +1 -0
- data/.rvmrc +2 -0
- data/Active.gemspec +28 -29
- data/Gemfile +4 -0
- data/History.txt +5 -2
- data/{README.txt → README.md} +4 -20
- data/Rakefile +11 -17
- data/lib/Active.rb +11 -79
- data/lib/active/activity.rb +7 -0
- data/lib/active/article.rb +7 -0
- data/lib/active/asset.rb +205 -0
- data/lib/active/errors.rb +9 -0
- data/lib/active/query.rb +225 -0
- data/lib/active/result.rb +7 -0
- data/lib/active/results.rb +6 -0
- data/lib/active/training.rb +7 -0
- data/lib/active/version.rb +3 -0
- data/lib/ext/hash_extensions.rb +8 -0
- data/spec/asset_spec.rb +47 -0
- data/spec/search_spec.rb +383 -432
- data/spec/spec_helper.rb +23 -2
- metadata +113 -116
- data/bin/Active +0 -7
- data/lib/.DS_Store +0 -0
- data/lib/services/.DS_Store +0 -0
- data/lib/services/IActivity.rb +0 -39
- data/lib/services/_ats.rb +0 -215
- data/lib/services/active_works.rb +0 -167
- data/lib/services/activity.rb +0 -512
- data/lib/services/address.rb +0 -17
- data/lib/services/ats.rb +0 -229
- data/lib/services/dto/user.rb +0 -9
- data/lib/services/gsa.rb +0 -205
- data/lib/services/reg_center.rb +0 -270
- data/lib/services/sanitize.rb +0 -108
- data/lib/services/search.rb +0 -494
- data/lib/services/validators.rb +0 -124
- data/rspec-tm +0 -1
- data/rvmrc +0 -1
- data/spec/.DS_Store +0 -0
- data/spec/Active_spec.rb +0 -28
- data/spec/activeworks_spec.rb +0 -60
- data/spec/activity_spec.rb +0 -421
- data/spec/ats_spec.rb +0 -106
- data/spec/benchmark/search_bench.rb +0 -55
- data/spec/custom_matchers_spec.rb +0 -27
- data/spec/gsa_spec.rb +0 -210
- data/spec/reg_spec.rb +0 -173
- data/spec/search_memcached_spec.rb +0 -42
- data/spec/validators_spec.rb +0 -19
- data/test/test_Active.rb +0 -0
- data/version.txt +0 -1
data/.gitignore
ADDED
data/.irbrc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Project-specific .irbrc file
|
2
|
+
|
3
|
+
# In order for this file to be picked up automatically by irb, you need to add
|
4
|
+
# the following code (or equivalent) to your own ~/.irbrc file:
|
5
|
+
|
6
|
+
# if Dir.pwd != File.expand_path("~")
|
7
|
+
# local_irbrc = File.expand_path '.irbrc'
|
8
|
+
# if File.exist? local_irbrc
|
9
|
+
# puts "Loading #{local_irbrc}"
|
10
|
+
# load local_irbrc
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
|
14
|
+
# When irb is started within this project folder (read: during gem development)
|
15
|
+
# this file will add lib/ to the load_path and require the gem.
|
16
|
+
|
17
|
+
# Doesn't work if you have the Active Gem also installed
|
18
|
+
|
19
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
|
20
|
+
require 'lib/Active'
|
21
|
+
puts "Using Active v#{Active::VERSION}"
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/.rvmrc
ADDED
data/Active.gemspec
CHANGED
@@ -1,36 +1,35 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "active/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.version
|
6
|
-
|
7
|
-
s.
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.
|
6
|
+
s.name = "Active"
|
7
|
+
s.version = Active::VERSION
|
8
|
+
s.date = "2012-01-03"
|
9
|
+
s.authors = ["Jonathan Spooner, Marc Leglise"]
|
10
|
+
s.email = ["jspooner@gmail.com"]
|
11
|
+
s.homepage = "http://developer.active.com/docs/Activecom_Search_API_Reference"
|
12
|
+
s.summary = %q{Search api for Active Network}
|
11
13
|
s.description = %q{Search api for Active Network}
|
12
|
-
s.email = %q{jspooner [at] gmail.com}
|
13
|
-
s.executables = ["Active"]
|
14
|
-
s.extra_rdoc_files = ["History.txt", "README.txt", "bin/Active", "version.txt"]
|
15
|
-
s.files = [".bnsignore", "Active.gemspec", "History.txt", "README.txt", "Rakefile", "bin/Active", "lib/Active.rb", "lib/services/activity.rb", "lib/services/search.rb", "spec/.DS_Store", "spec/Active_spec.rb", "spec/activity_spec.rb", "spec/search_spec.rb", "spec/spec_helper.rb", "test/test_Active.rb", "version.txt"]
|
16
|
-
s.homepage = %q{http://developer.active.com/docs/Activecom_Search_API_Reference}
|
17
|
-
s.rdoc_options = ["--main", "README.txt"]
|
18
|
-
s.require_paths = ["lib"]
|
19
|
-
s.rubyforge_project = %q{Active}
|
20
|
-
s.rubygems_version = %q{1.3.7}
|
21
|
-
s.summary = %q{Search api for Active Network}
|
22
|
-
s.test_files = ["test/test_Active.rb"]
|
23
14
|
|
24
|
-
|
25
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
-
s.specification_version = 3
|
15
|
+
s.rubyforge_project = "Active"
|
27
16
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.extra_rdoc_files = ["History.txt", "README.md"]
|
23
|
+
s.rdoc_options = ["--main", "README.md"]
|
24
|
+
|
25
|
+
s.add_dependency "json", "~> 1"
|
26
|
+
s.add_dependency "hashie", "~> 1"
|
27
|
+
s.add_dependency "activesupport", "> 3"
|
28
|
+
s.add_dependency "htmlentities", "> 4"
|
29
|
+
# s.add_dependency "savon", "= 0.7.9"
|
30
|
+
# s.add_dependency "dalli", "= 0.9.8"
|
31
|
+
|
32
|
+
s.add_development_dependency "rspec", "~> 2"
|
33
|
+
s.add_development_dependency "metric_fu", "~> 2"
|
34
|
+
# s.add_development_dependency "mocha", "= 0.9.8"
|
36
35
|
end
|
data/Gemfile
ADDED
data/History.txt
CHANGED
data/{README.txt → README.md}
RENAMED
@@ -1,33 +1,17 @@
|
|
1
1
|
Active
|
2
|
-
by Jonathan Spooner and
|
2
|
+
by Jonathan Spooner and Marc Leglise
|
3
3
|
http://developer.active.com/docs/Activecom_Search_API_Reference
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
7
|
Search api for Active Network
|
8
8
|
|
9
|
-
|
9
|
+
For use with Ruby 1.9
|
10
10
|
|
11
|
-
|
11
|
+
== Development
|
12
12
|
|
13
|
-
|
13
|
+
To use in irb do `rake install` then `irb` and `require 'Active'`
|
14
14
|
|
15
|
-
Search.search( {:location => "San Diego, CA, US"} )
|
16
|
-
|
17
|
-
List all categories
|
18
|
-
Active::Services::Search.CHANNELS.each do |key, value|
|
19
|
-
puts key.to_s.humanize
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
== REQUIREMENTS:
|
25
|
-
|
26
|
-
* none
|
27
|
-
|
28
|
-
== INSTALL:
|
29
|
-
|
30
|
-
* sudo gem install Active
|
31
15
|
|
32
16
|
== LICENSE:
|
33
17
|
|
data/Rakefile
CHANGED
@@ -1,24 +1,18 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
rescue LoadError
|
4
|
+
abort '### Please install the "bundler" gem ###'
|
5
|
+
end
|
1
6
|
|
2
7
|
begin
|
3
|
-
require '
|
8
|
+
require 'metric_fu'
|
4
9
|
rescue LoadError
|
5
|
-
abort '### Please install the "bones" gem ###'
|
6
10
|
end
|
7
11
|
|
8
|
-
task :default => 'test:run'
|
9
|
-
task 'gem:release' => 'test:run'
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
url 'http://developer.active.com/docs/Activecom_Search_API_Reference'
|
16
|
-
gem.extras[:post_install_message] = <<-MSG
|
17
|
-
--------------------------
|
18
|
-
Welcome to Active Network
|
19
|
-
--------------------------
|
20
|
-
MSG
|
21
|
-
depend_on 'savon', '0.7.9'
|
22
|
-
depend_on 'dalli', '0.9.8'
|
23
|
-
}
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
15
|
+
# t.pattern = 'spec/search_spec.rb'
|
16
|
+
end
|
24
17
|
|
18
|
+
task :default => :spec
|
data/lib/Active.rb
CHANGED
@@ -1,80 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# attr_reader :CACHE
|
5
|
-
# attr_accessor :CACHE
|
6
|
-
|
7
|
-
# :stopdoc:
|
8
|
-
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
9
|
-
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
10
|
-
# :startdoc:
|
11
|
-
|
12
|
-
# Returns the version string for the library.
|
13
|
-
#
|
14
|
-
def self.version
|
15
|
-
@version ||= File.read(path('version.txt')).strip
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns the library path for the module. If any arguments are given,
|
19
|
-
# they will be joined to the end of the libray path using
|
20
|
-
# <tt>File.join</tt>.
|
21
|
-
#
|
22
|
-
def self.libpath( *args, &block )
|
23
|
-
rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
24
|
-
if block
|
25
|
-
begin
|
26
|
-
$LOAD_PATH.unshift LIBPATH
|
27
|
-
rv = block.call
|
28
|
-
ensure
|
29
|
-
$LOAD_PATH.shift
|
30
|
-
end
|
31
|
-
end
|
32
|
-
return rv
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns the lpath for the module. If any arguments are given,
|
36
|
-
# they will be joined to the end of the path using
|
37
|
-
# <tt>File.join</tt>.
|
38
|
-
#
|
39
|
-
def self.path( *args, &block )
|
40
|
-
rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
41
|
-
if block
|
42
|
-
begin
|
43
|
-
$LOAD_PATH.unshift PATH
|
44
|
-
rv = block.call
|
45
|
-
ensure
|
46
|
-
$LOAD_PATH.shift
|
47
|
-
end
|
48
|
-
end
|
49
|
-
return rv
|
50
|
-
end
|
1
|
+
require 'active/version'
|
2
|
+
require 'ext/hash_extensions.rb'
|
51
3
|
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Dir.glob(search_me).sort.each {|rb| require rb}
|
63
|
-
end
|
64
|
-
|
65
|
-
# Active.memcache_host = "localhost:11211"
|
66
|
-
def self.memcache_host(url)
|
67
|
-
require 'dalli'
|
68
|
-
@CACHE = Dalli::Client.new(url)
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.CACHE
|
72
|
-
@CACHE
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
end # module Active
|
77
|
-
|
78
|
-
Active.require_all_libs_relative_to(__FILE__)
|
79
|
-
Active.require_all_libs_relative_to(__FILE__, 'services')
|
80
|
-
require 'savon'
|
4
|
+
module Active
|
5
|
+
# require files in order!
|
6
|
+
[
|
7
|
+
:errors, :query, :asset, :results,
|
8
|
+
:activity, :article, :result, :training
|
9
|
+
].each do |constant|
|
10
|
+
require "active/#{constant.to_s}"
|
11
|
+
end
|
12
|
+
end
|
data/lib/active/asset.rb
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'json'
|
3
|
+
require 'htmlentities'
|
4
|
+
require 'active_support/multibyte/unicode'
|
5
|
+
|
6
|
+
module Active
|
7
|
+
class Asset < Hashie::Mash
|
8
|
+
|
9
|
+
# * No punctuation: Returns the value of the hash for that key, or nil if none exists.
|
10
|
+
# * Assignment (<tt>=</tt>): Sets the attribute of the given method name.
|
11
|
+
# * Existence (<tt>?</tt>): Returns true or false depending on whether that key has been set.
|
12
|
+
# * Bang (<tt>!</tt>): Forces the existence of this key, used for deep Mashes. Think of it as "touch" for mashes.
|
13
|
+
#
|
14
|
+
# == Basic Example
|
15
|
+
#
|
16
|
+
# mash = Mash.new
|
17
|
+
# mash.name? # => false
|
18
|
+
# mash.name = "Bob"
|
19
|
+
# mash.name # => "Bob"
|
20
|
+
# mash.name? # => true
|
21
|
+
#
|
22
|
+
# == Hash Conversion Example
|
23
|
+
#
|
24
|
+
# hash = {:a => {:b => 23, :d => {:e => "abc"}}, :f => [{:g => 44, :h => 29}, 12]}
|
25
|
+
# mash = Mash.new(hash)
|
26
|
+
# mash.a.b # => 23
|
27
|
+
# mash.a.d.e # => "abc"
|
28
|
+
# mash.f.first.g # => 44
|
29
|
+
# mash.f.last # => 12
|
30
|
+
#
|
31
|
+
# == Bang Example
|
32
|
+
#
|
33
|
+
# mash = Mash.new
|
34
|
+
# mash.author # => nil
|
35
|
+
# mash.author! # => <Mash>
|
36
|
+
#
|
37
|
+
# mash = Mash.new
|
38
|
+
# mash.author!.name = "Michael Bleigh"
|
39
|
+
# mash.author # => <Mash name="Michael Bleigh">
|
40
|
+
#
|
41
|
+
def title
|
42
|
+
return @title if @title
|
43
|
+
if self.title?
|
44
|
+
# Notice we have to use self['hash'] to get the original value so we don't stackoverflow
|
45
|
+
@title = ActiveSupport::Multibyte::Unicode.tidy_bytes(self['title'])
|
46
|
+
@title = @title.split("|")[0].strip if @title.include?("|")
|
47
|
+
@title = @title.gsub(/<\/?[^>]*>/, "")
|
48
|
+
@title = @title.gsub("...", "")
|
49
|
+
@title = ::HTMLEntities.new.decode( @title )
|
50
|
+
end
|
51
|
+
@title
|
52
|
+
end
|
53
|
+
|
54
|
+
def description
|
55
|
+
return @description if @description
|
56
|
+
if self.meta!.summary?
|
57
|
+
# Notice we have to use self['hash'] to get the original value so we don't stackoverflow
|
58
|
+
@description = ActiveSupport::Multibyte::Unicode.tidy_bytes( self.meta.summary )
|
59
|
+
@description = @description.gsub(/<\/?[^>]*>/, "")
|
60
|
+
@description = ::HTMLEntities.new.decode( @description )
|
61
|
+
end
|
62
|
+
@description
|
63
|
+
end
|
64
|
+
|
65
|
+
def start_date
|
66
|
+
if self.meta!.startDate?
|
67
|
+
if self.meta!.startTime?
|
68
|
+
Time.parse("#{self.meta.startDate} #{self.meta.startTime}")
|
69
|
+
else
|
70
|
+
Date.parse(self.meta.startDate)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def asset_id
|
78
|
+
aid = self.meta!.assetId
|
79
|
+
if aid.kind_of?(Array)
|
80
|
+
aid = aid.first
|
81
|
+
end
|
82
|
+
aid.upcase
|
83
|
+
end
|
84
|
+
|
85
|
+
def address
|
86
|
+
if self.meta['address']
|
87
|
+
return self.meta['address']
|
88
|
+
elsif self.meta['location']
|
89
|
+
return self.meta['location']
|
90
|
+
else
|
91
|
+
return "#{self.meta.city}, #{self.meta.state}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def zip
|
96
|
+
self.meta['zip'] # an inheritated object defines zip so we need to override it.
|
97
|
+
end
|
98
|
+
|
99
|
+
class << self
|
100
|
+
def factory(data)
|
101
|
+
begin
|
102
|
+
category = data['meta']['category']
|
103
|
+
rescue NoMethodError
|
104
|
+
category = nil
|
105
|
+
end
|
106
|
+
|
107
|
+
type = case category
|
108
|
+
when 'Activities'
|
109
|
+
Active::Activity
|
110
|
+
when 'Articles'
|
111
|
+
Active::Article
|
112
|
+
when 'Training plans'
|
113
|
+
Active::Training
|
114
|
+
else
|
115
|
+
Active::Asset
|
116
|
+
end
|
117
|
+
type.new(data)
|
118
|
+
end
|
119
|
+
|
120
|
+
# this code smells
|
121
|
+
def find(asset_ids=nil)
|
122
|
+
raise Active::InvalidOption, "Couldn't find Asset without an ID" if asset_ids.nil?
|
123
|
+
query = Active::Query.new
|
124
|
+
ids = asset_ids.kind_of?(Array) ? asset_ids : [asset_ids]
|
125
|
+
query.options[:meta][:assetId] = ids.collect{ |id| id.gsub("-","%2d") }
|
126
|
+
|
127
|
+
# Executes the actual search API call
|
128
|
+
res = query.search
|
129
|
+
|
130
|
+
# Ensure we have found all of the IDs requested, otherwise raise an error
|
131
|
+
# that includes which ID(s) are missing.
|
132
|
+
if res['numberOfResults'] != ids.length
|
133
|
+
missing_ids = Array.new(ids)
|
134
|
+
res['_results'].each do |r|
|
135
|
+
found_id = r['meta']['assetId'] & missing_ids
|
136
|
+
missing_ids -= found_id
|
137
|
+
end
|
138
|
+
raise Active::RecordNotFound, "Couldn't find record with asset_id: #{missing_ids.join(',')}"
|
139
|
+
end
|
140
|
+
|
141
|
+
a = []
|
142
|
+
res['_results'].collect do |d|
|
143
|
+
t = self.new(d)
|
144
|
+
a << t
|
145
|
+
end
|
146
|
+
|
147
|
+
if a.length == 1
|
148
|
+
return a.first
|
149
|
+
else
|
150
|
+
return a
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Active::Activity.find_by_url("http://www.active.com#{request.fullpath}")
|
155
|
+
# url = http://search.active.com/search?v=list&m=site:www.active.com/running/san-diego-ca/americas-finest-city-half-marathon-and-5k-2011
|
156
|
+
def find_by_url(url)
|
157
|
+
raise Active::InvalidOption, "Couldn't find Asset without a url" if url.nil?
|
158
|
+
query = Active::Query.new
|
159
|
+
query.options[:m] << "site:#{url}"
|
160
|
+
|
161
|
+
# Executes the actual search API call
|
162
|
+
res = query.search
|
163
|
+
if res['numberOfResults'].to_i < 1
|
164
|
+
raise Active::RecordNotFound, "Couldn't find record with asset_id: #{url}"
|
165
|
+
end
|
166
|
+
|
167
|
+
a = []
|
168
|
+
res['_results'].collect do |d|
|
169
|
+
t = self.new(d)
|
170
|
+
a << t
|
171
|
+
end
|
172
|
+
|
173
|
+
if a.length == 1
|
174
|
+
return a.first
|
175
|
+
else
|
176
|
+
return a
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Example
|
181
|
+
# Asset.zip("92121")
|
182
|
+
[
|
183
|
+
:sort, :order, :limit, :per_page, :page,
|
184
|
+
:category, :keywords, :channel, :splitMediaType,
|
185
|
+
:location, :state, :city, :zip, :zips, :bounding_box, :dma, :near,
|
186
|
+
:date_range, :future, :past, :today, :radius
|
187
|
+
].each do |method_name|
|
188
|
+
define_method(method_name) do |*val|
|
189
|
+
Active::Query.new(:facet => self.facet).send(method_name, *val)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# We have several different types of data in the Search index. To restrict a search to a particular type, use the facet parameter. The available values are:
|
194
|
+
# activities - things like running events or camps
|
195
|
+
# results - race results from results.active.com
|
196
|
+
# training - training plans
|
197
|
+
# articles - articles on active.com and ihoops.com
|
198
|
+
# This method should be overridden in child classes to return the appropriate type string.
|
199
|
+
def facet
|
200
|
+
''
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|