actv 1.3.11 → 1.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e07617465c15e04efc739dcc8552c06ccebc28f6
4
- data.tar.gz: fe777ce6c000a0bb609b5feb84b4361738489c75
3
+ metadata.gz: 4b6d1154e322af7be0639d43605c20130d6ffe10
4
+ data.tar.gz: f1ebad5fce18ce111bf365c26f2155ddd9de8422
5
5
  SHA512:
6
- metadata.gz: d425cc25a0823c46f54eac3f5998a95f570097136027e0f710eb9652c52d2f33c9c05d7dfb438cc0b812a058c962261b2e74c4e077d2d010ae5de35362869387
7
- data.tar.gz: b18351861f6b85cfcc3fb401597ee42eac6a7cd344ac8a9011373434df082eaeeb363e1fb06046a72d4831755817611115d3bb5201cee6ceabd451be275c0b4b
6
+ metadata.gz: 931654c507096789427ba46aa67fe930689bf4f63fb7b0a6a948d062b243481861d1a0a39fc34e921a15488d642cf412878109358d6c6dec393082ca39430c97
7
+ data.tar.gz: 27c9e26e7b58d3b7c1ca66ce090bc6da191251883251be16b04596b7560022af57f7033fb9626fe882ee7cbba2b0ecc5518eabb3464de2a2c1d3be7b873ff4d6
@@ -1,42 +1,14 @@
1
1
  require 'actv/asset'
2
2
  require 'nokogiri'
3
+ require 'active_support/core_ext/module/delegation'
3
4
 
4
5
  module ACTV
5
- class Article < ACTV::Asset
6
+ class Article < Asset
7
+ attr_reader :author
8
+ delegate :image_url, :footer, :bio, :photo, :name_from_footer, to: :author, prefix: true
6
9
 
7
- def author_footer
8
- @author_footer ||= description_by_type 'authorFooter'
9
- end
10
-
11
- def by_line
12
- @author ||= description_by_type 'articleByLine'
13
- end
14
-
15
- def author_bio
16
- @author_bio ||= begin
17
- bio_node = get_from_author_footer('div.author-text')
18
- bio_node.inner_html unless bio_node.nil?
19
- end
20
- end
21
-
22
- def author_photo
23
- @author_photo ||= begin
24
- image = nil
25
-
26
- image_node = get_from_author_footer('div.signature-block-photo img')
27
- if !image_node.nil?
28
- image = ACTV::AssetImage.new({imageUrlAdr: image_node.attribute('src').text}) if image_node.attribute 'src'
29
- end
30
-
31
- image
32
- end
33
- end
34
-
35
- def author_name_from_footer
36
- @author_name_from_footer ||= begin
37
- name_node = get_from_author_footer('span.author-name')
38
- name_node.text unless name_node.nil?
39
- end
10
+ def self.valid? response
11
+ ACTV::ArticleValidator.new(response).valid?
40
12
  end
41
13
 
42
14
  def source
@@ -48,7 +20,7 @@ module ACTV
48
20
  end
49
21
 
50
22
  def media_gallery?
51
- self.type and self.type.downcase == "mediagallery"
23
+ type && type.downcase == "mediagallery"
52
24
  end
53
25
 
54
26
  def image
@@ -64,30 +36,49 @@ module ACTV
64
36
  end
65
37
 
66
38
  def inline_ad
67
- @inline_ad ||= begin
68
- val = tag_by_description 'inlinead'
69
- if val
70
- val.downcase == 'true'
71
- else
72
- true
73
- end
74
- end
39
+ @inline_ad ||= resolve_inline_ad_tag
75
40
  end
76
41
  alias inline_ad? inline_ad
77
42
 
78
- private
43
+ def author
44
+ @author ||= author_from_reference || author_from_article
45
+ end
79
46
 
80
- def get_from_author_footer(selector)
81
- node = nil
47
+ def by_line
48
+ @by_line ||= description_by_type 'articleByLine'
49
+ end
50
+
51
+ def is_article?
52
+ true
53
+ end
54
+
55
+ def author_name_from_by_line
56
+ author_name_regex = /by (.*)/i.match by_line
57
+ author_name_regex[1].strip if author_name_regex.present?
58
+ end
59
+
60
+ private
82
61
 
83
- if !author_footer.nil? && !author_footer.empty?
84
- doc = Nokogiri::HTML(author_footer)
85
- node = doc.css(selector).first
86
- end
62
+ def author_from_article
63
+ ACTV::Author.build_from_article self.to_hash
64
+ end
87
65
 
88
- node
66
+ def author_from_reference
67
+ if author_reference
68
+ ACTV.asset(author_reference.id).first
89
69
  end
90
- end
91
- end
70
+ rescue ACTV::Error::NotFound
71
+ nil
72
+ end
92
73
 
74
+ def author_reference
75
+ references.find { |reference| reference.type == "author" }
76
+ end
93
77
 
78
+ def resolve_inline_ad_tag
79
+ tag = tag_by_description 'inlinead'
80
+ return false if tag && tag.downcase != 'true'
81
+ true
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,8 @@
1
+ require 'actv/asset_validator'
2
+ module ACTV
3
+ class ArticleValidator < AssetValidator
4
+ def valid?
5
+ category_is?('articles') || taxonomy_has?('articles')
6
+ end
7
+ end
8
+ end
@@ -4,6 +4,7 @@ require 'actv/asset_description'
4
4
  require 'actv/asset_image'
5
5
  require 'actv/asset_legacy_data'
6
6
  require 'actv/asset_price'
7
+ require 'actv/asset_reference'
7
8
  require 'actv/asset_status'
8
9
  require 'actv/asset_tag'
9
10
  require 'actv/asset_topic'
@@ -14,6 +15,7 @@ require 'actv/recurrence'
14
15
 
15
16
  module ACTV
16
17
  class Asset < ACTV::Identity
18
+ @types = []
17
19
 
18
20
  attr_reader :assetGuid, :assetName, :assetDsc, :activityStartDate, :activityStartTime, :activityEndDate, :activityEndTime,
19
21
  :homePageUrlAdr, :isRecurring, :contactName, :contactEmailAdr, :contactPhone, :showContact, :publishDate, :createdDate, :modifiedDate,
@@ -43,6 +45,22 @@ module ACTV
43
45
  alias maximum_age regReqMaxAge
44
46
  alias required_gender regReqGenderCd
45
47
 
48
+ def self.inherited base
49
+ @types << base
50
+ end
51
+
52
+ def self.types
53
+ @types + Array(self)
54
+ end
55
+
56
+ def self.from_response response={}
57
+ AssetFactory.new(response[:body]).asset
58
+ end
59
+
60
+ def self.valid? response
61
+ AssetValidator.new(response).valid?
62
+ end
63
+
46
64
  def endurance_id
47
65
  if self.awendurance?
48
66
  query_values = Addressable::URI.parse(registrationUrlAdr.to_s).query_values
@@ -181,28 +199,11 @@ module ACTV
181
199
  end
182
200
 
183
201
  def is_event?
184
- self.assetCategories.each do |category|
185
- if category[:category][:categoryTaxonomy].downcase.start_with?('event')
186
- return true
187
- end
188
- end
189
202
  false
190
203
  end
191
204
 
192
205
  def is_article?
193
- is_article = false
194
- if self.assetCategories.any?
195
- self.assetCategories.each do |category|
196
- if category[:category][:categoryName].downcase == 'articles'
197
- is_article = true
198
- end
199
- end
200
- else
201
- # no categories so check the sourceSystem
202
- is_article = articles_source?
203
- end
204
-
205
- is_article
206
+ false
206
207
  end
207
208
 
208
209
  def has_location?
@@ -249,6 +250,10 @@ module ACTV
249
250
  self.sourceSystem[:legacyGuid].upcase == "B47B0828-23ED-4D85-BDF0-B22819F53332" rescue false
250
251
  end
251
252
 
253
+ def acm?
254
+ self.sourceSystem[:legacyGuid].upcase == "CA4EA0B1-7377-470D-B20D-BF6BEA23F040" rescue false
255
+ end
256
+
252
257
  def kids?
253
258
  kids_friendly_source_system? && kids_interest?
254
259
  end
@@ -348,7 +353,7 @@ module ACTV
348
353
  image = image_without_placeholder.imageUrlAdr rescue ""
349
354
 
350
355
  if image.empty? and (logoUrlAdr && logoUrlAdr != default_image && !(logoUrlAdr =~ URI::regexp).nil?)
351
- image = logoUrlAdr
356
+ image = logoUrlAdr
352
357
  end
353
358
 
354
359
  image
@@ -362,6 +367,12 @@ module ACTV
362
367
  image_without_placeholder
363
368
  end
364
369
 
370
+ def references
371
+ @references ||= Array(@attrs[:assetReferences]).map do |reference|
372
+ ACTV::AssetReference.new reference
373
+ end
374
+ end
375
+
365
376
  private
366
377
 
367
378
  def image_without_placeholder
@@ -395,20 +406,13 @@ module ACTV
395
406
  end
396
407
  end
397
408
 
398
- private
399
-
400
409
  def kids_interest?
401
410
  interests = meta_interests.to_a.map(&:downcase)
402
411
  ['kids', 'family'].any? { |tag| interests.include? tag }
403
412
  end
404
413
 
405
414
  def kids_friendly_source_system?
406
- activenet? || awcamps30? || articles_source? || researched?
407
- end
408
-
409
- def articles_source?
410
- # this guid is equal to the Active.com Articles
411
- self.sourceSystem.fetch(:legacyGuid, "").upcase == "CA4EA0B1-7377-470D-B20D-BF6BEA23F040"
415
+ activenet? || awcamps30? || acm? || researched?
412
416
  end
413
417
 
414
418
  end
@@ -0,0 +1,15 @@
1
+ module ACTV
2
+ class AssetFactory
3
+ attr_reader :response
4
+
5
+ def initialize response_body
6
+ @response = response_body
7
+ end
8
+
9
+ def asset
10
+ types = ACTV::Asset.types
11
+ klass = types.find { |type| type.valid? response }
12
+ klass.new response
13
+ end
14
+ end
15
+ end
@@ -1,6 +1,5 @@
1
1
  module ACTV
2
2
  class AssetImage < Base
3
-
4
3
  attr_reader :imageUrlAdr, :imageName, :imageCaptionTxt, :linkUrl, :linkTarget
5
4
 
6
5
  alias url imageUrlAdr
@@ -8,6 +7,5 @@ module ACTV
8
7
  alias caption imageCaptionTxt
9
8
  alias link linkUrl
10
9
  alias target linkTarget
11
-
12
10
  end
13
11
  end
@@ -0,0 +1,11 @@
1
+ module ACTV
2
+ class AssetReference < Base
3
+ def id
4
+ @attrs[:referenceAsset][:assetGuid]
5
+ end
6
+
7
+ def type
8
+ @attrs[:referenceType][:referenceTypeName]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ module ACTV
2
+ class AssetValidator
3
+ attr_reader :response
4
+
5
+ def initialize response
6
+ @response = response
7
+ end
8
+
9
+ def valid?
10
+ true
11
+ end
12
+
13
+ private
14
+
15
+ def asset_categories
16
+ response[:assetCategories] || []
17
+ end
18
+
19
+ def taxonomy_has? name
20
+ asset_categories.any? do |cat|
21
+ cat[:category][:categoryTaxonomy].downcase.include? name.downcase
22
+ end
23
+ end
24
+
25
+ def category_is? name
26
+ asset_categories.any? do |cat|
27
+ cat[:category][:categoryName].downcase == name.downcase
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,61 @@
1
+ require 'actv/asset'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ module ACTV
5
+ class Author < Asset
6
+ def self.build_from_article article_hash
7
+ new article_hash
8
+ end
9
+
10
+ def self.valid? response
11
+ ACTV::AuthorValidator.new(response).valid?
12
+ end
13
+
14
+ def name
15
+ name_from_footer.presence || self.author_name.presence
16
+ end
17
+
18
+ def footer
19
+ @footer ||= description_by_type 'authorFooter'
20
+ end
21
+
22
+ def bio
23
+ @bio ||= begin
24
+ bio_node = from_footer 'div.author-text'
25
+ bio_node.inner_html unless bio_node.nil?
26
+ end
27
+ end
28
+
29
+ def photo
30
+ @photo ||= begin
31
+ image_node = from_footer 'div.signature-block-photo img'
32
+ url = image_node.attribute('src').to_s
33
+ ACTV::AssetImage.new imageUrlAdr: url
34
+ end
35
+ end
36
+
37
+ def image_url
38
+ if photo.url && photo.url.start_with?("/")
39
+ "http://www.active.com#{photo.url}"
40
+ else
41
+ photo.url
42
+ end
43
+ end
44
+
45
+ def name_from_footer
46
+ @name_from_footer ||= begin
47
+ name_node = from_footer 'span.author-name'
48
+ name_node.text unless name_node.nil?
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def from_footer selector
55
+ if footer.present?
56
+ doc = Nokogiri::HTML footer
57
+ doc.css(selector).first
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,8 @@
1
+ require 'actv/author_validator'
2
+ module ACTV
3
+ class AuthorValidator < AssetValidator
4
+ def valid?
5
+ category_is?('author') || taxonomy_has?('author')
6
+ end
7
+ end
8
+ end
@@ -1,13 +1,10 @@
1
- require 'forwardable'
2
1
  require 'actv/null_object'
3
2
  require 'uri'
4
3
 
5
4
  module ACTV
6
5
  class Base
7
- extend Forwardable
8
6
  attr_reader :attrs
9
7
  alias body attrs
10
- def_delegators :attrs, :delete, :update
11
8
 
12
9
  # Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
13
10
  #
@@ -77,14 +74,22 @@ module ACTV
77
74
  end
78
75
  end
79
76
 
80
- def self.from_response(response={})
81
- new(response[:body])
77
+ def self.from_response response={}
78
+ new response[:body]
82
79
  end
83
80
 
84
- def initialize(attrs={})
81
+ def initialize attrs={}
85
82
  @attrs = attrs || {}
86
83
  end
87
84
 
85
+ def delete key
86
+ attrs.delete key
87
+ end
88
+
89
+ def update key
90
+ attrs.update key
91
+ end
92
+
88
93
  def [](method)
89
94
  send(method)
90
95
  rescue NoMethodError
@@ -145,4 +150,4 @@ module ACTV
145
150
  end
146
151
 
147
152
  end
148
- end
153
+ end