Active 0.0.14 → 0.0.17

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/lib/services/ats.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'digest/sha1'
1
2
  module Active
2
3
  module Services
3
4
 
@@ -10,15 +11,16 @@ module Active
10
11
  # {"destinationID"=>"", "assetId"=>"A9EF9D79-F859-4443-A9BB-91E1833DF2D5", "substitutionUrl"=>"1878023", "city"=>"Antioch", "contactName"=>"City of Antioch", "trackbackurl"=>"http://www.active.com/page/Event_Details.htm?event_id=1878023&assetId=A9EF9D79-F859-4443-A9BB-91E1833DF2D5", "category"=>"Activities", "zip"=>"94531", "userCommentText"=>nil, "location"=>"Multi-use Room (prewett) - Prewett Family Park & Center", "latitude"=>"37.95761", :asset_id=>"A9EF9D79-F859-4443-A9BB-91E1833DF2D5", "searchWeight"=>"1", "country"=>"United States", "participationCriteria"=>"All", "dma"=>"San Francisco - Oakland - San Jose", "isSearchable"=>"true", :asset_name=>"Fitness, Pilates Mat Class (16 Yrs. & Up)", :substitution_url=>"1878023", :asset_type_id=>"EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65", "row"=>"1", "image1"=>"http://www.active.com/images/events/hotrace.gif", "startDate"=>"2010-09-13", "contactPhone"=>"925-779-7070", :asset_type_name=>"Active.com Event Registration", "onlineDonationAvailable"=>"0", "avgUserRating"=>nil, "market"=>"San Francisco - Oakland - San Jose", "assetTypeId"=>"EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65", "assetName"=>"Fitness, Pilates Mat Class (16 Yrs. & Up)", "channel"=>"Not Specified", "seourl"=>"http://www.active.com/not-specified-recware-activities/antioch-ca/fitness-pilates-mat-class-16-yrs-and-up-2010", :xmlns=>"http://api.asset.services.active.com", :url=>"http://www.active.com/page/Event_Details.htm?event_id=1878023", "mediaType"=>"Recware Activities", "startTime"=>"18:15:00", "endTime"=>"18:15:00", "contactEmail"=>"dadams@ci.antioch.ca.us", "eventResults"=>nil, "longitude"=>"-121.7936", "endDate"=>"2010-09-13", "onlineRegistrationAvailable"=>"true", "onlineMembershipAvailable"=>"0", "state"=>"California"}
11
12
  # {"destinationID"=>"", "assetId"=>"D9A22F33-8A14-4175-8D5B-D11578212A98", "substitutionUrl"=>"1847738", "city"=>"Encino", "contactName"=>"Lilliane Ballesteros", "trackbackurl"=>"http://www.active.com/page/Event_Details.htm?event_id=1847738&assetId=D9A22F33-8A14-4175-8D5B-D11578212A98", "category"=>"Activities", "zip"=>"91406", "userCommentText"=>nil, "location"=>"Balboa Park/Lake Balboa", "latitude"=>"34.19933", :asset_id=>"D9A22F33-8A14-4175-8D5B-D11578212A98", "searchWeight"=>"1", "country"=>"United States", "participationCriteria"=>"All", "dma"=>"Los Angeles", "isSearchable"=>"1", :asset_name=>"2nd Annual weSPARK 10K Run & 5K Run Walk", :substitution_url=>"1847738", :asset_type_id=>"EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65", "row"=>"1", "image1"=>"http://www.active.com/images/events/hotrace.gif", "startDate"=>"2010-11-14", "contactPhone"=>"818-906-3022", :asset_type_name=>"Active.com Event Registration", "onlineDonationAvailable"=>"0", "avgUserRating"=>nil, "market"=>"Los Angeles", "assetTypeId"=>"EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65", "assetName"=>"2nd Annual weSPARK 10K Run & 5K Run Walk", "channel"=>["Running", "Walking"], "seourl"=>"http://www.active.com/running/encino-ca/2nd-annual-wespark-10k-run-and-5k-run-walk-2010", :xmlns=>"http://api.asset.services.active.com", :url=>"http://www.active.com/page/Event_Details.htm?event_id=1847738", "mediaType"=>["Event", "Event\\10K", "Event\\5K"], "startTime"=>"8:00:00", "endTime"=>"8:00:00", "contactEmail"=>"lilliane@wespark.org", "eventResults"=>nil, "longitude"=>"-118.4924", "endDate"=>"2010-11-14", "onlineRegistrationAvailable"=>"1", "onlineMembershipAvailable"=>"0", "state"=>"California", "estParticipants"=>"1400", "eventURL"=>"http://www.wespark.org"}
12
13
 
13
- def initialize(data={})
14
+ def initialize(data={},preload_metadata=false)
14
15
  # need to hold on to original data
15
- @data = data || {}
16
- @asset_id = data[:asset_id]
17
- @url = data[:url]
18
- @asset_type_id = data[:asset_type_id]
19
- @title = data[:asset_name] if data[:asset_name]
16
+ @data = data
17
+ @asset_id = data[:asset_id]
18
+ @url = data[:url]
19
+ @asset_type_id = data[:asset_type_id]
20
+ @title = data[:asset_name] if data[:asset_name]
20
21
  @substitution_url = data[:substitution_url]
21
- @metadata_loaded = false
22
+ # @metadata_loaded = false
23
+ # load_metadata if preload_metadata
22
24
  end
23
25
 
24
26
  def source
@@ -27,16 +29,16 @@ module Active
27
29
 
28
30
 
29
31
  def title
30
- load_metadata unless @metadata_loaded
31
- if @data.has_key?("assetName")
32
+ # load_metadata unless @metadata_loaded
33
+ # if @data.has_key?("assetName")
32
34
  @data["assetName"]
33
- else
34
- @title
35
- end
35
+ # else
36
+ # @title
37
+ # end
36
38
  end
37
39
 
38
40
  def url
39
- load_metadata unless @metadata_loaded
41
+ # load_metadata unless @metadata_loaded
40
42
  if @data.has_key?("seourl")
41
43
  @data["seourl"]
42
44
  elsif @data.has_key?("trackbackurl")
@@ -47,7 +49,7 @@ module Active
47
49
  end
48
50
 
49
51
  def categories
50
- load_metadata unless @metadata_loaded
52
+ # load_metadata unless @metadata_loaded
51
53
  categories = @data["channel"]
52
54
  if categories.class==String
53
55
  [@data["channel"]]
@@ -57,8 +59,8 @@ module Active
57
59
  end
58
60
 
59
61
  def address
60
- load_metadata unless @metadata_loaded
61
- @address = {
62
+ # load_metadata unless @metadata_loaded
63
+ @address = Hash.new({
62
64
  :name => @data["location"],
63
65
  :address => @data["address"],
64
66
  :city => @data["city"],
@@ -67,11 +69,11 @@ module Active
67
69
  :lat => @data["latitude"],
68
70
  :lng => @data["longitude"],
69
71
  :country => @data["country"]
70
- }
72
+ })
71
73
  end
72
74
 
73
75
  def start_date
74
- load_metadata unless @metadata_loaded
76
+ # load_metadata unless @metadata_loaded
75
77
  if @data.has_key?("startDate")
76
78
  if @data.has_key?("startTime")
77
79
  (DateTime.parse "#{@data["startDate"]} #{@data["startTime"]}")
@@ -88,7 +90,7 @@ module Active
88
90
  end
89
91
 
90
92
  def end_date
91
- load_metadata unless @metadata_loaded
93
+ # load_metadata unless @metadata_loaded
92
94
  if @data.has_key?("endDate")
93
95
  if @data.has_key?("endTime")
94
96
  (DateTime.parse "#{@data["endDate"]} #{@data["endTime"]}")
@@ -110,13 +112,27 @@ module Active
110
112
  end
111
113
 
112
114
  def desc
113
- load_metadata unless @metadata_loaded
115
+ # load_metadata unless @metadata_loaded
114
116
  if @data.has_key?("allText")
115
117
  @data["allText"]
116
118
  elsif @data.has_key?("summary")
117
119
  @data["summary"]
118
120
  end
119
121
  end
122
+
123
+ def contact_name
124
+ # load_metadata unless @metadata_loaded
125
+ @data["contactName"] if @data.has_key?("contactName")
126
+ end
127
+
128
+ def contact_email
129
+ # load_metadata unless @metadata_loaded
130
+ @data["contactEmail"] if @data.has_key?("contactEmail")
131
+ end
132
+
133
+ def substitutionUrl
134
+ @data[:substitution_url]
135
+ end
120
136
 
121
137
 
122
138
  # EXAMPLE
@@ -128,42 +144,73 @@ module Active
128
144
 
129
145
  def self.find_by_id(id)
130
146
  begin
131
- r = self.get_asset_by_id(id)
132
- return ATS.new(r.to_hash[:get_asset_by_id_response][:out])
147
+
148
+ # return self.get_asset_by_id(id)
149
+ search_hash = Digest::SHA1.hexdigest("ats_m_#{id}")
150
+ if Active.CACHE
151
+ cached_version = Active.CACHE.get(search_hash)
152
+ return cached_version if cached_version
153
+ end
154
+
155
+ c = Savon::Client.new("http://api.amp.active.com/asset-service/services/AssetService")
156
+ c.request.headers["Api-Key"] = "6npky9t57235vps5cetm3s7k"
157
+ r = c.get_asset_metadata! do |soap|
158
+ soap.namespace = "http://api.asset.services.active.com"
159
+ soap.body = "<context><userId></userId><applicationId></applicationId></context><assetId>#{id}</assetId>"
160
+ end
161
+ ats = ATS.new(r.to_hash[:get_asset_metadata_response][:out])
162
+ Active.CACHE.set(search_hash, ats) if Active.CACHE
163
+ return ats
164
+
133
165
  rescue Savon::SOAPFault => e
134
- raise ATSError, "Couldn't find activity with the id of #{id}"
166
+ raise ATSError, "Couldn't find activity with the id of #{id} error #{e.inspect}"
135
167
  return
136
168
  end
137
169
  end
138
170
 
171
+ # def load_metadata
172
+ # metadata = ATS.get_asset_metadata(@asset_id)
173
+ # @data.merge! Hash.from_xml(metadata.to_hash[:get_asset_metadata_response][:out])["importSource"]["asset"]
174
+ # @metadata_loaded=true
175
+ # end
176
+
139
177
  private
140
178
  def self.get_asset_metadata(id)
141
- c = Savon::Client.new("http://api.amp.active.com/asset-service/services/AssetService?wsdl")
179
+ search_hash = Digest::SHA1.hexdigest("ats_m_#{id}")
180
+ if Active.CACHE
181
+ cached_version = Active.CACHE.get(search_hash)
182
+ return cached_version if cached_version
183
+ end
184
+
185
+ c = Savon::Client.new("http://api.amp.active.com/asset-service/services/AssetService")
142
186
  c.request.headers["Api-Key"] = "6npky9t57235vps5cetm3s7k"
143
- r = c.get_asset_metadata do |soap|
187
+ r = c.get_asset_metadata! do |soap|
144
188
  soap.namespace = "http://api.asset.services.active.com"
145
189
  soap.body = "<context><userId></userId><applicationId></applicationId></context><assetId>#{id}</assetId>"
146
190
  end
147
- puts "==========="
148
- puts r.to_hash[:get_asset_metadata_response][:out].inspect
149
- return r
191
+ ats = ATS.new(r.to_hash[:get_asset_metadata_response][:out])
192
+ Active.CACHE.set(search_hash, ats) if Active.CACHE
193
+ return ats
150
194
  end
151
195
 
152
196
  def self.get_asset_by_id(id)
197
+ search_hash = Digest::SHA1.hexdigest("ats_#{id}")
198
+ if Active.CACHE
199
+ cached_version = Active.CACHE.get(search_hash)
200
+ return cached_version if cached_version
201
+ end
202
+
153
203
  c = Savon::Client.new("http://api.amp.active.com/asset-service/services/AssetService")
154
204
  c.request.headers["Api-Key"] = "6npky9t57235vps5cetm3s7k"
155
205
  r = c.get_asset_by_id! do |soap|
156
206
  soap.namespace = "http://api.asset.services.active.com"
157
207
  soap.body = "<context><userId></userId><applicationId></applicationId></context><assetId>#{id}</assetId>"
158
208
  end
159
- return r
160
- end
161
-
162
- def load_metadata
163
- metadata = ATS.get_asset_metadata(@asset_id)
164
- @data.merge! Hash.from_xml(metadata.to_hash[:get_asset_metadata_response][:out])["importSource"]["asset"]
165
- @metadata_loaded=true
209
+ ats = ATS.new(r.to_hash[:get_asset_by_id_response][:out])
210
+ Active.CACHE.set(search_hash, ats) if Active.CACHE
211
+ return ats
166
212
  end
213
+
167
214
 
168
215
  end # end ats
169
216
  end
@@ -0,0 +1,153 @@
1
+ module Active
2
+ module Services
3
+
4
+ class GSAError < StandardError; end
5
+
6
+ class GSA < IActivity
7
+ require 'nokogiri'
8
+ require 'open-uri'
9
+ attr_accessor :asset_type_id
10
+
11
+ # EXAMPLE Data hash
12
+ # {"title"=>"Birds of a Feather Run | Ashland, Oregon 97520 | Thursday ...", "language"=>"en", "url"=>"http://www.active.com/running/ashland-or/birds-of-a-feather-run-2010", "escapedUrl"=>"http://www.active.com/running/ashland-or/birds-of-a-feather-run-2010", "meta"=>{"city"=>"Ashland", "assetId"=>["4365AF63-B2AE-4A98-A403-5E30EB6D2D69", "4365af63-b2ae-4a98-a403-5e30eb6d2d69"], "substitutionUrl"=>"1845585", "trackbackurl"=>"http://www.active.com/running/ashland-or/birds-of-a-feather-run-2010", "contactName"=>"Hal Koerner", "eventDate"=>"2010-09-23T00:00:00-07:00", "eventLongitude"=>"-122.5526", "eventId"=>"1845585", "zip"=>"97520", "category"=>"Activities", "latitude"=>"42.12607", "google-site-verification"=>"", "participationCriteria"=>"All", "dma"=>"Medford - Klamath Falls", "country"=>"United States", "sortDate"=>"2000-09-23", "tag"=>["event:10", "Running:10"], "lastModifiedDateTime"=>"2010-09-23 03:04:55.463", "lastModifiedDate"=>"2010-09-23", "startDate"=>"2010-09-23", "contactPhone"=>"541-201-0014", "eventState"=>"Oregon", "splitMediaType"=>"Event", "onlineDonationAvailable"=>"0", "market"=>"Medford - Klamath Falls", "assetName"=>["Birds of a Feather Run", "Birds of a Feather Run"], "seourl"=>"http://www.active.com/running/ashland-or/birds-of-a-feather-run-2010", "assetTypeId"=>"EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65", "channel"=>"Running", "endTime"=>"0:00:00", "mediaType"=>"Event", "startTime"=>"0:00:00", "description"=>"", "longitude"=>"-122.5526", "UpdateDateTime"=>"9/22/2010 11:46:24 AM", "endDate"=>"2010-09-23", "onlineMembershipAvailable"=>"0", "onlineRegistrationAvailable"=>"false", "eventZip"=>"97520", "state"=>"Oregon", "estParticipants"=>"2000", "eventURL"=>"http://sorunners.org/", "eventLatitude"=>"42.12607", "keywords"=>"Event"}, "summary"=>"... Similar Running Events. I Ran for Sudan - Maple Valley First Annual 10K/2Mile Kid's Run/Walk Maple Valley, Washington Sat, Oct 02, 2010; ... "}
13
+
14
+ def initialize(json={})
15
+ # need to hold on to original data
16
+ @data = HashWithIndifferentAccess.new(json) || HashWithIndifferentAccess.new
17
+ # self.title = @data['meta']['assetName'] || nil
18
+ self.title = @data['title'] || nil
19
+ end
20
+
21
+ def source
22
+ :gsa
23
+ end
24
+
25
+ def title=(value)
26
+ @title = value
27
+ if @title
28
+ @title = @title.split("|")[0].strip if @title.include?("|")
29
+ @title = @title.gsub(/<\/?[^>]*>/, "")
30
+ @title = @title.gsub("...", "")
31
+ end
32
+ end
33
+
34
+ def url
35
+ @data["url"]
36
+ end
37
+
38
+ def categories
39
+ if @data["meta"]["channel"].class==String
40
+ [@data["meta"]["channel"]]
41
+ else
42
+ @data["meta"]["channel"]
43
+ end
44
+ end
45
+
46
+ def asset_id
47
+ return nil unless @data["meta"] and @data["meta"]["assetId"]
48
+ value = @data["meta"]["assetId"]
49
+ @asset_id = (value.class==Array) ? value[0] : value
50
+ end
51
+
52
+ def asset_type_id
53
+ return nil unless @data["meta"] and @data["meta"]["assetTypeId"]
54
+ @data["meta"]["assetTypeId"]
55
+ end
56
+
57
+ def primary_category
58
+ categories.first
59
+ end
60
+
61
+ def address
62
+ @address = HashWithIndifferentAccess.new({
63
+ :name => @data["meta"]["location"],
64
+ :address => @data["meta"]["eventAddress"],
65
+ :city => @data["meta"]["city"],
66
+ :lat => @data["meta"]["latitude"],
67
+ :lng => @data["meta"]["longitude"],
68
+ :country => @data["meta"]["country"]
69
+ })
70
+ @address[:state] = @data["meta"]["eventState"] || @data["meta"]["state"]
71
+ @address[:zip] = @data["meta"]["eventZip"] || @data["meta"]["zip"]
72
+ @address
73
+ end
74
+
75
+ def start_date
76
+ if @data.has_key?("meta") and @data["meta"].has_key?("eventDate")
77
+ DateTime.parse @data["meta"]["eventDate"]
78
+ else
79
+ nil
80
+ end
81
+ end
82
+
83
+ def start_time
84
+ start_date
85
+ end
86
+
87
+ def end_date
88
+ if @data.has_key?("meta") and @data["meta"].has_key?("endDate")
89
+ DateTime.parse @data["meta"]["endDate"]
90
+ else
91
+ nil
92
+ end
93
+ end
94
+
95
+ def end_time
96
+ end_date
97
+ end
98
+
99
+ def category
100
+ primary_category
101
+ end
102
+
103
+ def contact_name
104
+ if @data["meta"].has_key?("contactName") && !@data["meta"]["contactName"].blank?
105
+ @data["meta"]["contactName"]
106
+ end
107
+ end
108
+
109
+ def last_modified
110
+ @data["meta"]["lastModifiedDateTime"] if @data["meta"].has_key?("lastModifiedDateTime")
111
+ end
112
+
113
+ def contact_email
114
+ if @data["meta"].has_key?("contactEmail") && !@data["meta"]["contactEmail"].blank?
115
+ @data["meta"]["contactEmail"]
116
+ end
117
+ end
118
+
119
+ def desc
120
+ if @data["meta"].has_key?("allText") && !@data["meta"]["allText"].blank?
121
+ @data["meta"]["allText"]
122
+ elsif @data["meta"].has_key?("summary") && !@data["meta"]["summary"].blank?
123
+ @data["meta"]["summary"]
124
+ elsif @data.has_key?("summary") && !@data["summary"].blank?
125
+ @data["summary"]
126
+ else
127
+ ""
128
+ end
129
+ end
130
+ # substitutionUrl could be formatted like this
131
+ # 1. "meta":{"substitutionUrl":"vistarecreation/registrationmain.sdi?source=showAsset.sdi&activity_id=4900"}
132
+ # 2. "meta":{"substitutionUrl":"4900"}
133
+ def substitutionUrl
134
+ if @data["meta"].has_key?("substitutionUrl")
135
+ if /activity_id=/ =~ @data["meta"]["substitutionUrl"]
136
+ @data["meta"]["substitutionUrl"].split("activity_id=")[1]
137
+ else
138
+ @data["meta"]["substitutionUrl"]
139
+ end
140
+ end
141
+ end
142
+ # TODO
143
+ def activeworks_id
144
+ 0
145
+ end
146
+ def regcenter_id
147
+ 0
148
+ end
149
+
150
+
151
+ end
152
+ end
153
+ end
@@ -6,6 +6,7 @@ module Active
6
6
  class RegCenter < IActivity
7
7
  require 'nokogiri'
8
8
  require 'open-uri'
9
+ require 'digest/sha1'
9
10
  attr_accessor :asset_type_id
10
11
 
11
12
  # attr_reader :metadata_loaded
@@ -15,15 +16,12 @@ module Active
15
16
  # :asset_type_id=>"EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65", :xmlns=>"http://api.asset.services.active.com"}
16
17
 
17
18
  def initialize(data={})
18
- # need to hold on to original data
19
19
  @data = HashWithIndifferentAccess.new(data) || HashWithIndifferentAccess.new
20
- @api_data_loaded = false
21
20
  @asset_type_id = "EA4E860A-9DCD-4DAA-A7CA-4A77AD194F65"
22
- get_app_api
23
21
  end
24
22
 
25
23
  def source
26
- :reg_center
24
+ :primary
27
25
  end
28
26
 
29
27
  def title
@@ -73,18 +71,18 @@ module Active
73
71
  channels.each do |c|
74
72
  return c["channelName"] if c.has_key?("primaryChannel") && c["primaryChannel"]=="true"
75
73
  end
74
+ nil
76
75
  else
77
76
  #hash
78
77
  return channels["channelName"] if channels.has_key?("primaryChannel") && channels["primaryChannel"]=="true"
78
+ return nil
79
79
  end
80
- #fallback
81
- return category
82
80
  end
83
81
  end
84
82
 
85
83
  def address
86
84
  if @data.has_key?("event") && @data["event"].has_key?("eventAddress") && !@data["event"]["eventAddress"].blank?
87
- @address = {
85
+ @address = validated_address({
88
86
  :name => @data["event"]["eventLocation"],
89
87
  :address => @data["event"]["eventAddress"],
90
88
  :city => @data["event"]["eventCity"],
@@ -93,7 +91,7 @@ module Active
93
91
  :lat => @data["event"]["latitude"],
94
92
  :lng => @data["event"]["longitude"],
95
93
  :country => @data["event"]["eventCountry"]
96
- }
94
+ } )
97
95
  end
98
96
  end
99
97
 
@@ -131,7 +129,9 @@ module Active
131
129
  ret +="<div><b>" + eventDetail["eventDetailsName"] + ":</b> " + cleanup_reg_string(eventDetail["eventDetailsValue"]) + "</div>"
132
130
  end
133
131
  end
134
- ret
132
+ return ret
133
+ elsif @data.has_key?("event") && @data["event"].has_key?("eventDescription")
134
+ return @data["event"]["eventDescription"]
135
135
  end
136
136
  end
137
137
 
@@ -139,6 +139,12 @@ module Active
139
139
  input.gsub("\r","").gsub("\n","").gsub("\"","""").gsub("\342\200\234","""").gsub("\342\200\235","""")
140
140
  end
141
141
 
142
+ def contact_email
143
+ if @data.has_key?("event") && @data["event"].has_key?("eventContactEmail")
144
+ return @data["event"]["eventContactEmail"]
145
+ end
146
+ end
147
+
142
148
 
143
149
  # EXAMPLE
144
150
  # lazy load the data for some_crazy_method
@@ -148,7 +154,23 @@ module Active
148
154
  # end
149
155
 
150
156
  def self.find_by_id(id) #local id
151
- return RegCenter.new({:id=>id})
157
+
158
+ search_hash = Digest::SHA1.hexdigest("reg_#{id}")
159
+ if Active.CACHE
160
+ cached_version = Active.CACHE.get(search_hash)
161
+ return cached_version if cached_version
162
+ end
163
+
164
+ begin
165
+ doc = Nokogiri::XML(open("http://apij.active.com/regcenter/event/#{id}"))
166
+ reg = RegCenter.new(Hash.from_xml(doc.to_s))
167
+ Active.CACHE.set(search_hash, reg) if Active.CACHE
168
+ rescue Exception => e
169
+ raise RegCenterError, "Couldn't find Reg Center activity with the id of #{id} - #{e.inspect}"
170
+ return
171
+ end
172
+
173
+ return reg
152
174
  end
153
175
 
154
176
  private
@@ -182,17 +204,17 @@ module Active
182
204
  # @metadata_loaded=true
183
205
  # end
184
206
 
185
- def get_app_api
186
- puts "loading reg center api"
187
- begin
188
- doc = Nokogiri::XML(open("http://apij.active.com/regcenter/event/#{@data[:id]}"))
189
- @data.merge! Hash.from_xml doc.to_s
190
- @api_data_loaded=true
191
- rescue
192
- raise RegCenterError, "Couldn't find Reg Center activity with the id of #{id}"
193
- return
194
- end
195
- end
207
+ # def get_app_api
208
+ # puts "loading reg center api"
209
+ # begin
210
+ # doc = Nokogiri::XML(open("http://apij.active.com/regcenter/event/#{@data[:id]}"))
211
+ # @data.merge! Hash.from_xml doc.to_s
212
+ # @api_data_loaded=true
213
+ # rescue
214
+ # raise RegCenterError, "Couldn't find Reg Center activity with the id of #{id}"
215
+ # return
216
+ # end
217
+ # end
196
218
 
197
219
  end # end ats
198
220
  end
@@ -0,0 +1,108 @@
1
+ # http://wonko.com/post/sanitize
2
+
3
+ # $Id: sanitize.rb 3 2005-04-05 12:51:14Z dwight $
4
+ #
5
+ # Copyright (c) 2005 Dwight Shih
6
+ # A derived work of the Perl version:
7
+ # Copyright (c) 2002 Brad Choate, bradchoate.com
8
+ #
9
+ # Permission is hereby granted, free of charge, to
10
+ # any person obtaining a copy of this software and
11
+ # associated documentation files (the "Software"), to
12
+ # deal in the Software without restriction, including
13
+ # without limitation the rights to use, copy, modify,
14
+ # merge, publish, distribute, sublicense, and/or sell
15
+ # copies of the Software, and to permit persons to
16
+ # whom the Software is furnished to do so, subject to
17
+ # the following conditions:
18
+ #
19
+ # The above copyright notice and this permission
20
+ # notice shall be included in all copies or
21
+ # substantial portions of the Software.
22
+ #
23
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
24
+ # OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25
+ # LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ # FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
28
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
29
+ # OR OTHER LIABILITY, WHETHER IN AN ACTION OF
30
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
31
+ # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32
+ # OTHER DEALINGS IN THE SOFTWARE.
33
+ #
34
+
35
+ def sanitize( html, okTags='a href, b, br, i, p' )
36
+ # no closing tag necessary for these
37
+ soloTags = ["br","hr"]
38
+
39
+ # Build hash of allowed tags with allowed attributes
40
+ tags = okTags.downcase().split(',').collect!{ |s| s.split(' ') }
41
+ allowed = Hash.new
42
+ tags.each do |s|
43
+ key = s.shift
44
+ allowed[key] = s
45
+ end
46
+
47
+ # Analyze all <> elements
48
+ stack = Array.new
49
+ result = html.gsub( /(<.*?>)/m ) do | element |
50
+ if element =~ /\A<\/(\w+)/ then
51
+ # </tag>
52
+ tag = $1.downcase
53
+ if allowed.include?(tag) && stack.include?(tag) then
54
+ # If allowed and on the stack
55
+ # Then pop down the stack
56
+ top = stack.pop
57
+ out = "</#{top}>"
58
+ until top == tag do
59
+ top = stack.pop
60
+ out << "</#{top}>"
61
+ end
62
+ out
63
+ end
64
+ elsif element =~ /\A<(\w+)\s*\/>/
65
+ # <tag />
66
+ tag = $1.downcase
67
+ if allowed.include?(tag) then
68
+ "<#{tag} />"
69
+ end
70
+ elsif element =~ /\A<(\w+)/ then
71
+ # <tag ...>
72
+ tag = $1.downcase
73
+ if allowed.include?(tag) then
74
+ if ! soloTags.include?(tag) then
75
+ stack.push(tag)
76
+ end
77
+ if allowed[tag].length == 0 then
78
+ # no allowed attributes
79
+ "<#{tag}>"
80
+ else
81
+ # allowed attributes?
82
+ out = "<#{tag}"
83
+ while ( $' =~ /(\w+)=("[^"]+")/ )
84
+ attr = $1.downcase
85
+ valu = $2
86
+ if allowed[tag].include?(attr) then
87
+ out << " #{attr}=#{valu}"
88
+ end
89
+ end
90
+ out << ">"
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # eat up unmatched leading >
97
+ while result.sub!(/\A([^<]*)>/m) { $1 } do end
98
+
99
+ # eat up unmatched trailing <
100
+ while result.sub!(/<([^>]*)\Z/m) { $1 } do end
101
+
102
+ # clean up the stack
103
+ if stack.length > 0 then
104
+ result << "</#{stack.reverse.join('></')}>"
105
+ end
106
+
107
+ result
108
+ end