daengine 0.5.13 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +5 -0
  3. data/app/controllers/digital_assets_controller.rb +29 -46
  4. data/app/helpers/digital_assets_helper.rb +11 -2
  5. data/app/models/content_service_resource.rb +15 -15
  6. data/app/models/digital_asset.rb +83 -94
  7. data/app/models/teamsite_digital_asset_shim.rb +253 -0
  8. data/app/service/digital_asset_lookup_service.rb +47 -47
  9. data/bin/process_assets +6 -7
  10. data/bin/process_availability +7 -8
  11. data/bin/process_taxonomy +7 -8
  12. data/config/routes.rb +7 -7
  13. data/lib/daengine.rb +1 -13
  14. data/lib/daengine/content_service_processor.rb +24 -24
  15. data/lib/daengine/digital_asset_processor.rb +4 -0
  16. data/lib/daengine/teamsite_metadata_parser.rb +3 -2
  17. data/lib/daengine/version.rb +1 -1
  18. data/lib/tasks/daengine_tasks.rake +0 -9
  19. data/spec/acceptance/digital_assets_spec.rb +116 -0
  20. data/spec/controllers/digital_assets_controller_spec.rb +14 -99
  21. data/spec/dummy/config/environments/test.rb +1 -1
  22. data/spec/dummy/log/development.log +0 -0
  23. data/spec/dummy/log/test.log +8802 -0
  24. data/spec/factories.rb +8 -32
  25. data/spec/lib/content_service_processor_spec.rb +30 -30
  26. data/spec/lib/teamsite_metadata_parser_spec.rb +26 -19
  27. data/spec/mock_data/bulk-ssc_deploy.xml +900 -900
  28. data/spec/mock_data/daengine.yml +1 -1
  29. data/spec/mock_data/digitalAssets/GK-66261382-96be-4a92-839a-73467e89e1b4.txt +289 -289
  30. data/spec/mock_data/digitalAssets/TEST_FINRA_DOC.doc +0 -0
  31. data/spec/mock_data/digitalAssets/m_gyt-709d8ae1-31f1-46ea-b448-33f43dd5140f.html +1008 -1008
  32. data/spec/mock_data/selective_new_package.xml +55 -2
  33. data/spec/mock_data/taxonomy/taxonomyengine.yml +1 -1
  34. data/spec/models/digital_asset_spec.rb +23 -28
  35. data/spec/service/digital_asset_lookup_service_spec.rb +75 -79
  36. data/spec/spec_helper.rb +18 -1
  37. metadata +23 -7
  38. data/lib/daengine/digital_asset_extension_processor.rb +0 -28
  39. data/spec/lib/digital_asset_extension_processor_spec.rb +0 -32
  40. data/spec/mock_data/merrill_lynch_extension.json +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebcd4cba573731d63a838c277fbfe4c1c215e41b
4
- data.tar.gz: 74a976fc90d02603798519425d07b5111cc65b77
3
+ metadata.gz: fa5de682d42dc3019a48e76744f587b5069cc9e3
4
+ data.tar.gz: 7faca1c4e9ae36521292defd53daf425ec6663c8
5
5
  SHA512:
6
- metadata.gz: c1b087c4e52e0ae3664e50c020cd313b1fe116f4195e7a3b7fbbe52b77c93730c008a76aa129b14fe9d5d4c86ebf556db84e63d36bd9785390bc4d25d9cf81fa
7
- data.tar.gz: 4d71a5b4bb3156dadfed0b4e4c97e21679f1017efa69c7cecb6d35fd619fc2495aaeeb125e185ad30d669cedc1dec88b0b765786b5fef4ee9307168091f08c14
6
+ metadata.gz: 48d2ae730ab81c8680fe78a1de0ca08a509309b43bf24f5b00b1b3a79ce2cad2c781b19a82df2a304e916d514a5354c22ba7c2920a6c1c00a2f5badb7217e445
7
+ data.tar.gz: 7e9e48c77c9dda6ae586a69a2f63968cebf3c30886997c4be0e83590b8e2f1a3f0a8539f9801c30ec2c1dc8a49ef6566265b31de4ea9dca27603a4f284e37dba
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ rescue LoadError
11
11
  require 'rake/rdoctask'
12
12
  RDoc::Task = Rake::RDocTask
13
13
  end
14
+ require 'rspec/core/rake_task'
14
15
 
15
16
  RDoc::Task.new(:rdoc) do |rdoc|
16
17
  rdoc.rdoc_dir = 'rdoc'
@@ -23,6 +24,10 @@ end
23
24
  APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
25
  load 'rails/tasks/engine.rake'
25
26
 
27
+ RSpec::Core::RakeTask.new(:spec)
28
+ task :default => :spec
29
+ spec = Gem::Specification.find_by_name 'rspec_api_documentation'
30
+ load "#{spec.gem_dir}/lib/tasks/docs.rake"
26
31
 
27
32
 
28
33
  Bundler::GemHelper.install_tasks
@@ -7,10 +7,13 @@ class DigitalAssetsController < ApplicationController
7
7
  CACHE_LAST_PARSE_TIME = 'last_parse_time'
8
8
  # GET /digital_assets
9
9
  # GET /digital_assets.json
10
+ #/digital_assets/search/sami_code=92023
11
+ #/digital_assets/search/sami_code=NE00192&title=Fund%20Prospectus&fund_code=20293
10
12
  def index
11
- @digital_assets = DigitalAsset.all
13
+ @digital_assets = request.query_parameters.present? ? search_da(request.query_parameters) : DigitalAsset.all
12
14
  respond_with(@digital_assets)
13
15
  end
16
+ alias :search :index
14
17
 
15
18
  # GET /digital_assets/1
16
19
  # GET /digital_assets/1.json
@@ -19,13 +22,33 @@ class DigitalAssetsController < ApplicationController
19
22
  respond_with(@digital_asset)
20
23
  end
21
24
 
22
- #/digital_assets/search/sami_code=92023
23
- #/digital_assets/search/sami_code=NE00192&title=Fund%20Prospectus&fund_code=20293
24
- def search
25
- @digital_assets = search_da(params)
26
- respond_with(@digital_assets)
25
+ def update
26
+ da_passed = params[:digital_asset]
27
+ da = DigitalAsset.find_or_initialize_by(digital_asset_id: da_passed[:digital_asset_id])
28
+ da.update_attributes! da_passed
29
+ head :ok
27
30
  end
28
31
 
32
+ alias :create :update
33
+
34
+ def destroy
35
+ da = DigitalAsset.where(:digital_asset_id => params[:id])
36
+ da[0].delete if da.present?
37
+ head :ok
38
+ end
39
+
40
+ def updated_time
41
+ Daengine.log "updated_time params #{params.inspect}", "info"
42
+ ids = params[:ids]
43
+ updated_time = Hash.new
44
+ ids.each do |id|
45
+ da = DigitalAsset.where(:digital_asset_id => id)
46
+ updated_time[id] = da[0].doc_changed_at if da.present?
47
+ end
48
+ Daengine.log "updated_time result #{updated_time.inspect}", "info"
49
+ render json: updated_time.to_json, status: :ok
50
+ end
51
+
29
52
  def fund_docs
30
53
  @digital_assets = []
31
54
  fund_doctypes = {:doctype => [
@@ -43,45 +66,5 @@ class DigitalAssetsController < ApplicationController
43
66
  respond_with(@digital_assets)
44
67
  end
45
68
 
46
- def sync_assets
47
- time0 = Rails.cache.read(CACHE_LAST_PARSE_TIME)
48
- if time0.nil?
49
- time0 = 2.days.ago
50
- end
51
- logger.info "Last time when ssc deploy files were read: #{time0.inspect}"
52
- time1 = Time.new
53
- logger.info "Current time: #{time1.inspect}"
54
-
55
- Rails.cache.write(CACHE_LAST_PARSE_TIME, time1)
56
- deploy_files= []
57
-
58
- start_directory = EDIST['digital_assets_directory']
59
- logger.info "Reading digital asset deployment files from #{start_directory}"
60
- if (File::directory?(start_directory))
61
- Dir.foreach(start_directory) do |entry|
62
- if (!File::directory?(entry))
63
- filename = start_directory + entry
64
- difference0 = File.mtime(filename)- time0 #To-Do - We should be looking at created time - ctime
65
- difference1 = File.mtime(filename) - time1
66
- if ((difference0 >= 0) & (difference1 < 0))
67
- if(/bulk-ssc_|selective-ssc_/ =~ filename)
68
- deploy_files << filename
69
- end
70
- end
71
- end
72
- end
73
- end
74
-
75
- deploy_files.each do |filename|
76
- #parse the file and add content to database.
77
- logger.info "Processing file #{filename} found."
78
- file = File.expand_path(filename, __FILE__)
79
- open_file = open(file, 'rb')
80
- Etl::TeamsiteMetadataParser.parse_tuple_file(open_file)
81
- logger.info "Finished parsing #{filename}."
82
- end
83
-
84
- head :accepted
85
- end
86
69
 
87
70
  end
@@ -3,11 +3,20 @@ module DigitalAssetsHelper
3
3
  def search_da(params)
4
4
  digital_assets = []
5
5
  # loop thru each parameter that matches one of the method signatures
6
+ # x_is for singular, x_in for arrays, x_since for dates
6
7
  digital_assets = params.keys.select do |pk|
7
- DigitalAsset.respond_to?("#{pk}_is".to_sym) or DigitalAsset.respond_to?("#{pk}_in".to_sym)
8
+ DigitalAsset.respond_to?("#{pk}_is".to_sym) or DigitalAsset.respond_to?("#{pk}_in".to_sym) or DigitalAsset.respond_to?("#{pk}_since".to_sym)
8
9
  end.reduce(DigitalAsset) do |sum, key|
9
10
  # for each key, call the 'named query' method with the value given and chain...
10
- method = DigitalAsset.respond_to?("#{key}_in".to_sym) ? "#{key}_in".to_sym : "#{key}_is".to_sym
11
+ method = case
12
+ when DigitalAsset.respond_to?("#{key}_in".to_sym)
13
+ "#{key}_in".to_sym
14
+ when DigitalAsset.respond_to?("#{key}_since".to_sym)
15
+ "#{key}_since".to_sym
16
+ else
17
+ "#{key}_is".to_sym
18
+ end
19
+ # method = DigitalAsset.respond_to?("#{key}_in".to_sym) ? "#{key}_in".to_sym : "#{key}_is".to_sym
11
20
  sum.send(method, method.to_s.end_with?('in') ? params[key].to_a : params[key]) # should return result of the send call for chaining
12
21
  end
13
22
  digital_assets.respond_to?(:each) ? digital_assets : []
@@ -1,16 +1,16 @@
1
- require 'active_resource'
2
- require 'daengine'
3
- # Represents a generic piece of content for display on an OFI web property
4
- # This model represents the 'human edited' version of website content, final displayed
5
- # pages will be 'value added' with system-sourced data and 'mashed-in' data
6
- #
7
- class ContentServiceResource < ActiveResource::Base
8
-
9
- # self.site = Daengine.config[:content_service_url]
10
- self.prefix = "/litcenter-service/query/"
11
- self.element_name = "resource"
12
-
13
- def self.find_all
14
- ContentServiceResource.find(:all, :params => {:contentQuery => "audienceIds='490,5270';;expired='false'"})
15
- end
1
+ require 'active_resource'
2
+ require 'daengine'
3
+ # Represents a generic piece of content for display on an OFI web property
4
+ # This model represents the 'human edited' version of website content, final displayed
5
+ # pages will be 'value added' with system-sourced data and 'mashed-in' data
6
+ #
7
+ class ContentServiceResource < ActiveResource::Base
8
+
9
+ # self.site = Daengine.config[:content_service_url]
10
+ self.prefix = "/litcenter-service/query/"
11
+ self.element_name = "resource"
12
+
13
+ def self.find_all
14
+ ContentServiceResource.find(:all, :params => {:contentQuery => "audienceIds='490,5270';;expired='false'"})
15
+ end
16
16
  end
@@ -8,87 +8,86 @@ class DigitalAsset
8
8
  field :changed_at, type: Time
9
9
  field :audiences, type: Array, default: []
10
10
  field :sami_code, type: String
11
- field :product_ids, type: Array, default: []
12
11
  field :published_at, type: Time
13
12
  field :unpublished_at, type: Time
14
13
  field :expires_at, type: Time
15
14
  field :guid, type: String
16
- # field :fund_ids, type: Array, default: []
17
15
  field :business_owner, type: String
18
16
  field :summary, type: String
19
- field :content_organization_ids, type: Array, default: []
20
- field :program_ids, type: Array, default: []
21
-
22
17
  field :omniture_codes, type: Array, default: []
23
18
  field :orderable, :type => Boolean, default: false
24
-
25
- field :ml_category, type: String
26
- field :control_number, type: String
27
- field :key_accounts, type: Array, default: []
28
-
29
- key :guid
19
+ field :product_ids, type: Array, default: []
20
+ field :program_ids, type: Array, default: []
21
+ # refactor version:
22
+ field :path, type: String
23
+ field :legacy_path, type: String
24
+ field :doc_changed_at, type: Time
25
+ field :content_type, type: String
26
+ field :pages, type: Integer, default: 1
27
+ field :size, type: String
28
+ field :mime_type, type: String
29
+ field :subject, type: String
30
+ field :keywords, type: Array, default: []
31
+ field :author, type: String
32
+ field :finra_path, type: String
33
+ field :fund_codes, type: Array, default: []
34
+ field :digital_asset_id, type: String
35
+ key :digital_asset_id
30
36
 
31
37
  # field :documents, type: Hash
38
+ # embeds_many :documents, :class_name => 'DigitalAsset::Document'
39
+ # accepts_nested_attributes_for :documents
32
40
 
33
- embeds_many :documents, :class_name => 'DigitalAsset::Document'
34
-
35
- accepts_nested_attributes_for :documents
36
41
 
37
42
  #Exclude XBRL documents from all queries
38
- default_scope excludes(:'documents.content_type' => "LDJDCMAIK") #Had to use static value instead of a Constant
43
+ # default_scope excludes(:'content_type' => "LDJDCMAIK") #Had to use static value instead of a Constant
39
44
 
40
45
  scope :title_is, ->(title) { where(:title => title)}
41
46
  scope :business_owner_is, ->(business_owner) { where(:business_owner => business_owner)}
42
47
  scope :guid_is, ->(guid) { where(:guid => guid)}
43
- # scope :funds_in, ->(fund_id) { where(:fund_ids.in => fund_id)}
48
+ scope :digital_asset_id_is, ->(id) { where(:digital_asset_id => id)}
49
+ scope :fund_in, ->(fund_code) {where(:fund_codes.in => fund_code)}
44
50
  scope :audience_in, ->(audience_id) {where(:audiences.in => audience_id)}
45
51
  scope :audience_investor_approved, -> {where(:audiences.in => [Audience::INVESTOR_APPROVED])}
46
52
 
53
+ scope :published_since, ->(since) {where(:published_at.gte => since)}
47
54
  scope :content_organization_in, ->(content_organization_id) {where(:content_organization_ids.in => content_organization_id)}
48
55
  scope :program_id_in, ->(program_id) {where(:program_ids.in => program_id)}
49
56
  scope :sami_is, ->(sami_code) {where(:sami_code => sami_code)}
50
57
  scope :sami_in, ->(sami_codes) {where(:sami_code.in => sami_codes)}
51
- scope :path_is, ->(path) {where(:'documents.path' => path)}
52
- scope :doctype_in, ->(types) {where(:'documents.content_type'.in => types)}
53
- scope :content_type_in, ->(types) {where(:'documents.content_type'.in => types)}
58
+ scope :path_is, ->(path) {where(:'path' => path)}
59
+ scope :doctype_in, ->(types) {where(:'content_type'.in => types)}
60
+ scope :content_type_in, ->(types) {where(:'content_type'.in => types)}
54
61
  scope :product_in, ->(types) {where(:product_ids.in => types)}
55
62
  scope :stale, -> {where(:updated_at.lte => 2.minutes.ago)}
56
63
  scope :orderable_is, ->(orderable) {where(:orderable => orderable)}
57
64
  scope :orderable, -> {where(orderable: true)}
58
- scope :has_finra, -> {where(:'documents.content_type' => ContentType::FINRA)}
59
65
  scope :audience_in, ->(audience) {where(:audiences.in => audience)}
60
66
  scope :alphabetical, order_by(:title => :asc)
61
- scope :not_xbrl, -> {excludes(:'documents.content_type' => ContentType::XBRL_DOCUMENT)}
62
-
63
- scope :key_account_in, ->(key_account) {where(:key_accounts => key_account)}
64
-
65
- #scope :order_by_fund, order_by[[:product_ids, :asc]]
66
- #default_scope {not_in(:'documents.content_type' => ["LDJDCMAIK"])}
67
+ scope :not_xbrl, -> {excludes(:'content_type' => ContentType::XBRL_DOCUMENT)}
67
68
 
68
69
  # validations
69
- validates_presence_of :guid, :title, :changed_at, :published_at,
70
- :expires_at, :audiences, :documents
71
-
70
+ validates_presence_of :digital_asset_id, :title, :changed_at, :published_at,
71
+ :expires_at, :audiences, :path
72
+ validates_uniqueness_of :path, :digital_asset_id
72
73
  validate :validate_future_expiration
73
74
 
74
- # validates_uniqueness_of :guid
75
-
76
- def as_json(opts = {})
77
- super(opts).merge({:comp_fundcode => fund_code, :content_type_id => content_type_id, :latest_doc_changed_at => latest_doc_changed_at})
78
- end
75
+ # def as_json(opts = {})
76
+ # super(opts).merge({:comp_fundcode => fund_codes, :content_type_id => content_type_id, :latest_doc_changed_at => latest_doc_changed_at})
77
+ # end
79
78
 
80
79
  def self.purge!
81
- # last_update = DigitalAsset.desc(:updated_at).try(:first).try :updated_at
82
80
  DigitalAsset.stale.destroy_all if bulk_processed?
83
81
  end
84
82
 
85
83
  def latest_doc_changed_at
86
- documents.reduce(nil) do |latest_date, d|
87
- unless d.content_type == '549'
88
- latest_date = d.doc_changed_at if (latest_date == nil || latest_date < d.doc_changed_at)
89
- end
90
- latest_date
91
- end
84
+ doc_changed_at
85
+ # documents.reduce(nil) do |latest_date, d|
86
+ # unless d.content_type == '549'
87
+ # latest_date = d.doc_changed_at if (latest_date == nil || latest_date < d.doc_changed_at)
88
+ # end
89
+ # latest_date
90
+ # end
92
91
  end
93
92
 
94
93
  def validate_future_expiration
@@ -99,39 +98,39 @@ class DigitalAsset
99
98
  (stale.count.to_f / self.count) <= 0.05
100
99
  end
101
100
 
102
- def path_is(path)
103
- documents.where(path: path).first unless documents.blank?
104
- end
101
+ # def path_is(path)
102
+ # documents.where(path: path).first unless documents.blank?
103
+ # end
105
104
 
106
- def doc_changed_at(path)
107
- path_is(path).try(:doc_changed_at)
108
- end
105
+ # def doc_changed_at(path)
106
+ # path_is(path).try(:doc_changed_at)
107
+ # end
109
108
 
110
- def doc_size
111
- first_non_finra.try(:size)
112
- end
109
+ # def doc_size
110
+ # first_non_finra.try(:size)
111
+ # end
113
112
 
114
- def content_type_ids
115
- ids = []
116
- documents.try(:each) do |d|
117
- ids << d.content_type
118
- end
119
- ids
120
- end
121
- alias :doctype_ids :content_type_ids
113
+ # def content_type_ids
114
+ # ids = []
115
+ # documents.try(:each) do |d|
116
+ # ids << d.content_type
117
+ # end
118
+ # ids
119
+ # end
120
+ # alias :doctype_ids :content_type_ids
122
121
 
123
122
  def has_finra?
124
- finra_document != nil
123
+ finra_path.present?
125
124
  end
126
125
 
127
126
  def expired?
128
127
  expires_at < Time.now
129
128
  end
130
129
 
131
- def finra_document
132
- finra_idx = documents.index {|d| d.content_type == ContentType::FINRA}
133
- documents[finra_idx] if finra_idx
134
- end
130
+ # def finra_document
131
+ # finra_idx = documents.index {|d| d.content_type == ContentType::FINRA}
132
+ # documents[finra_idx] if finra_idx
133
+ # end
135
134
 
136
135
  def is_investor_approved?
137
136
  audiences.index(DigitalAsset::Audience::INVESTOR_APPROVED)
@@ -153,66 +152,56 @@ class DigitalAsset
153
152
  TaxonomyTerm.label_for_term(content_organization_ids[0])
154
153
  end
155
154
 
156
- def fund_code
157
- pid = product_ids.find {|pid| TaxonomyTerm.term_id_is(pid)[0].try(:fund_code)}
158
- pid and TaxonomyTerm.term_id_is(pid)[0].try(:fund_code).try(:rjust, 5, '0')
159
- end
155
+ # def fund_code
156
+ # pid = product_ids.find {|pid| TaxonomyTerm.term_id_is(pid)[0].try(:fund_code)}
157
+ # pid and TaxonomyTerm.term_id_is(pid)[0].try(:fund_code).try(:rjust, 5, '0')
158
+ # end
160
159
 
161
160
  def content_type
162
161
  TaxonomyTerm.label_for_term(content_type_id)
163
162
  end
164
163
  def content_type_id
165
- first_non_finra.try(:content_type)
164
+ :content_type
166
165
  end
167
166
 
168
- def pages; first_non_finra.pages end
169
-
170
167
  def audience
171
168
  TaxonomyTerm.label_for_term(audiences[0])
172
169
  end
173
170
 
174
171
  def primary_path
175
- first_non_finra.try(:path)
172
+ :path
176
173
  end
177
174
 
178
175
  def primary_extension
179
- first_non_finra.try(:path).try(:split,'.').try(:last).try(:upcase)
176
+ self.try(:path).try(:split,'.').try(:last).try(:upcase)
180
177
  end
181
178
 
182
179
  private
183
180
 
184
- def first_non_finra
185
- documents.try(:detect) do |d|
186
- d.content_type != ContentType::FINRA
187
- end
188
- end
181
+ # def first_non_finra
182
+ # documents.try(:detect) do |d|
183
+ # d.content_type != ContentType::FINRA
184
+ # end
185
+ # end
189
186
 
190
187
 
191
188
  end
192
189
 
193
- class DigitalAsset::Document
194
- include Mongoid::Document
190
+ # class DigitalAsset::Document
191
+ # include Mongoid::Document
195
192
 
196
- field :path, type: String
197
- field :doc_changed_at, type: Time
198
- field :content_type, type: String
199
- field :pages, type: Integer, default: 1
200
- field :size, type: String
201
- field :mime_type, type: String
202
- field :subject, type: String
203
- field :keywords, type: Array, default: []
204
- field :author, type: String
193
+
205
194
 
206
- embedded_in :digital_asset
195
+ # embedded_in :digital_asset
207
196
 
208
- key :path
197
+ # key :path
209
198
 
210
- validates_uniqueness_of :path
199
+ # validates_uniqueness_of :path
211
200
 
212
- validates_presence_of :path #, :doc_changed_at, :content_type
213
- validates_format_of :path, without: /\/manifest|archives\// # dont accept manifest files
201
+ # validates_presence_of :path #, :doc_changed_at, :content_type
202
+ # validates_format_of :path, without: /\/manifest|archives\// # dont accept manifest files
214
203
 
215
- end
204
+ # end
216
205
 
217
206
  class DigitalAsset::ContentType
218
207
  FINRA = '549'