daengine 0.5.13 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +5 -0
- data/app/controllers/digital_assets_controller.rb +29 -46
- data/app/helpers/digital_assets_helper.rb +11 -2
- data/app/models/content_service_resource.rb +15 -15
- data/app/models/digital_asset.rb +83 -94
- data/app/models/teamsite_digital_asset_shim.rb +253 -0
- data/app/service/digital_asset_lookup_service.rb +47 -47
- data/bin/process_assets +6 -7
- data/bin/process_availability +7 -8
- data/bin/process_taxonomy +7 -8
- data/config/routes.rb +7 -7
- data/lib/daengine.rb +1 -13
- data/lib/daengine/content_service_processor.rb +24 -24
- data/lib/daengine/digital_asset_processor.rb +4 -0
- data/lib/daengine/teamsite_metadata_parser.rb +3 -2
- data/lib/daengine/version.rb +1 -1
- data/lib/tasks/daengine_tasks.rake +0 -9
- data/spec/acceptance/digital_assets_spec.rb +116 -0
- data/spec/controllers/digital_assets_controller_spec.rb +14 -99
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +8802 -0
- data/spec/factories.rb +8 -32
- data/spec/lib/content_service_processor_spec.rb +30 -30
- data/spec/lib/teamsite_metadata_parser_spec.rb +26 -19
- data/spec/mock_data/bulk-ssc_deploy.xml +900 -900
- data/spec/mock_data/daengine.yml +1 -1
- data/spec/mock_data/digitalAssets/GK-66261382-96be-4a92-839a-73467e89e1b4.txt +289 -289
- data/spec/mock_data/digitalAssets/TEST_FINRA_DOC.doc +0 -0
- data/spec/mock_data/digitalAssets/m_gyt-709d8ae1-31f1-46ea-b448-33f43dd5140f.html +1008 -1008
- data/spec/mock_data/selective_new_package.xml +55 -2
- data/spec/mock_data/taxonomy/taxonomyengine.yml +1 -1
- data/spec/models/digital_asset_spec.rb +23 -28
- data/spec/service/digital_asset_lookup_service_spec.rb +75 -79
- data/spec/spec_helper.rb +18 -1
- metadata +23 -7
- data/lib/daengine/digital_asset_extension_processor.rb +0 -28
- data/spec/lib/digital_asset_extension_processor_spec.rb +0 -32
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa5de682d42dc3019a48e76744f587b5069cc9e3
|
4
|
+
data.tar.gz: 7faca1c4e9ae36521292defd53daf425ec6663c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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 =
|
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
|
data/app/models/digital_asset.rb
CHANGED
@@ -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 :
|
26
|
-
|
27
|
-
field :
|
28
|
-
|
29
|
-
|
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(:'
|
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
|
-
|
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(:'
|
52
|
-
scope :doctype_in, ->(types) {where(:'
|
53
|
-
scope :content_type_in, ->(types) {where(:'
|
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(:'
|
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 :
|
70
|
-
:expires_at, :audiences, :
|
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
|
-
#
|
75
|
-
|
76
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
112
|
-
end
|
109
|
+
# def doc_size
|
110
|
+
# first_non_finra.try(:size)
|
111
|
+
# end
|
113
112
|
|
114
|
-
def content_type_ids
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
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
|
-
|
133
|
-
|
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
|
-
|
158
|
-
|
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
|
-
|
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
|
-
|
172
|
+
:path
|
176
173
|
end
|
177
174
|
|
178
175
|
def primary_extension
|
179
|
-
|
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
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
190
|
+
# class DigitalAsset::Document
|
191
|
+
# include Mongoid::Document
|
195
192
|
|
196
|
-
|
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
|
-
|
195
|
+
# embedded_in :digital_asset
|
207
196
|
|
208
|
-
|
197
|
+
# key :path
|
209
198
|
|
210
|
-
|
199
|
+
# validates_uniqueness_of :path
|
211
200
|
|
212
|
-
|
213
|
-
|
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'
|